/* * Copyright (C) 2007 OpenedHand Ltd. * * Author: Jorn Baayen * * SPDX-License-Identifier: LGPL-2.1-or-later * */ #define G_LOG_DOMAIN "gupnp-device" #include #include #include "gupnp-device.h" #include "gupnp-service.h" #include "gupnp-root-device.h" #include "gupnp-resource-factory-private.h" #include "xml-util.h" struct _GUPnPDevicePrivate { GUPnPRootDevice *root_device; }; typedef struct _GUPnPDevicePrivate GUPnPDevicePrivate; /** * GUPnPDevice: * * Base class for UPnP device implementations. * * #GUPnPDevice allows for retrieving a device's sub-devices * and services. #GUPnPDevice implements the #GUPnPDeviceInfo * interface. */ G_DEFINE_TYPE_WITH_PRIVATE (GUPnPDevice, gupnp_device, GUPNP_TYPE_DEVICE_INFO) enum { PROP_0, PROP_ROOT_DEVICE }; static GUPnPDeviceInfo * gupnp_device_get_device (GUPnPDeviceInfo *info, xmlNode *element) { GUPnPDevice *device; GUPnPDevicePrivate *priv; GUPnPResourceFactory *factory; GUPnPContext *context; GUPnPDevice *root_device; const char *location; const GUri *url_base; device = GUPNP_DEVICE (info); priv = gupnp_device_get_instance_private (device); root_device = GUPNP_IS_ROOT_DEVICE (device) ? device : GUPNP_DEVICE (priv->root_device); if (root_device == NULL) { g_warning ("Root device not found."); return NULL; } factory = gupnp_device_info_get_resource_factory (info); context = gupnp_device_info_get_context (info); location = gupnp_device_info_get_location (info); url_base = gupnp_device_info_get_url_base (info); device = gupnp_resource_factory_create_device (factory, context, root_device, element, NULL, location, url_base); return GUPNP_DEVICE_INFO (device); } static GUPnPServiceInfo * gupnp_device_get_service (GUPnPDeviceInfo *info, xmlNode *element) { GUPnPDevice *device; GUPnPDevicePrivate *priv; GUPnPService *service; GUPnPResourceFactory *factory; GUPnPContext *context; GUPnPDevice *root_device; const char *location, *udn; const GUri *url_base; device = GUPNP_DEVICE (info); priv = gupnp_device_get_instance_private (device); root_device = GUPNP_IS_ROOT_DEVICE (device) ? device : GUPNP_DEVICE (priv->root_device); if (root_device == NULL) { g_warning ("Root device not found."); return NULL; } factory = gupnp_device_info_get_resource_factory (info); context = gupnp_device_info_get_context (info); udn = gupnp_device_info_get_udn (info); location = gupnp_device_info_get_location (info); url_base = gupnp_device_info_get_url_base (info); service = gupnp_resource_factory_create_service (factory, context, root_device, element, udn, location, url_base); return GUPNP_SERVICE_INFO (service); } static void gupnp_device_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GUPnPDevice *device; GUPnPDevicePrivate *priv; device = GUPNP_DEVICE (object); priv = gupnp_device_get_instance_private (device); switch (property_id) { case PROP_ROOT_DEVICE: priv->root_device = g_value_get_object (value); /* This can be NULL in which case *this* is the root device */ if (priv->root_device) { GUPnPRootDevice **dev = &(priv->root_device); g_object_add_weak_pointer (G_OBJECT (priv->root_device), (gpointer *) dev); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gupnp_device_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { GUPnPDevice *device; GUPnPDevicePrivate *priv; device = GUPNP_DEVICE (object); priv = gupnp_device_get_instance_private (device); switch (property_id) { case PROP_ROOT_DEVICE: g_value_set_object (value, priv->root_device); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gupnp_device_dispose (GObject *object) { GUPnPDevice *device; GObjectClass *object_class; GUPnPDevicePrivate *priv; device = GUPNP_DEVICE (object); priv = gupnp_device_get_instance_private (device); if (priv->root_device) { GUPnPRootDevice **dev = &(priv->root_device); g_object_remove_weak_pointer (G_OBJECT (priv->root_device), (gpointer *) dev); priv->root_device = NULL; } /* Call super */ object_class = G_OBJECT_CLASS (gupnp_device_parent_class); object_class->dispose (object); } static void gupnp_device_init (GUPnPDevice *device) { } static void gupnp_device_class_init (GUPnPDeviceClass *klass) { GObjectClass *object_class; GUPnPDeviceInfoClass *info_class; object_class = G_OBJECT_CLASS (klass); object_class->set_property = gupnp_device_set_property; object_class->get_property = gupnp_device_get_property; object_class->dispose = gupnp_device_dispose; info_class = GUPNP_DEVICE_INFO_CLASS (klass); info_class->create_device_instance = gupnp_device_get_device; info_class->create_service_instance = gupnp_device_get_service; /** * GUPnPDevice:root-device: * * The containing #GUPnPRootDevice, or NULL if this is the root * device. **/ g_object_class_install_property (object_class, PROP_ROOT_DEVICE, g_param_spec_object ("root-device", "Root device", "The GUPnPRootDevice", GUPNP_TYPE_ROOT_DEVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); }