⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gupnp-control-point.c

📁 另一 UPNP SDK 支持在UNIX/LINUX上运行。 UPnP是一种网络协议
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd. * * Author: Jorn Baayen <jorn@openedhand.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//** * SECTION:gupnp-control-point * @short_description: Class for resource discovery. * * #GUPnPControlPoint handles device and service discovery. After creating * a control point and activating it using gssdp_resource_browser_set_active(), * the ::device-proxy-available, ::service-proxy-available, * ::device-proxy-unavailable and ::service-proxy-unavailable signals will * be emitted whenever the availability of a device or service matching * the specified discovery target changes. */#include <string.h>#include "gupnp-control-point.h"#include "gupnp-context-private.h"#include "gupnp-resource-factory-private.h"#include "http-headers.h"#include "xml-util.h"G_DEFINE_TYPE (GUPnPControlPoint,               gupnp_control_point,               GSSDP_TYPE_RESOURCE_BROWSER);struct _GUPnPControlPointPrivate {        GUPnPResourceFactory *factory;        GList *devices;        GList *services;        GHashTable *doc_cache;        GList *pending_gets;};enum {        PROP_0,        PROP_RESOURCE_FACTORY,};enum {        DEVICE_PROXY_AVAILABLE,        DEVICE_PROXY_UNAVAILABLE,        SERVICE_PROXY_AVAILABLE,        SERVICE_PROXY_UNAVAILABLE,        SIGNAL_LAST};static guint signals[SIGNAL_LAST];typedef struct {        GUPnPControlPoint *control_point;        char *udn;        char *service_type;        char *description_url;        SoupMessage *message;} GetDescriptionURLData;static voidget_description_url_data_free (GetDescriptionURLData *data){        data->control_point->priv->pending_gets =                g_list_remove (data->control_point->priv->pending_gets, data);        g_free (data->udn);        g_free (data->service_type);        g_free (data->description_url);        g_slice_free (GetDescriptionURLData, data);}static voidgupnp_control_point_init (GUPnPControlPoint *control_point){        control_point->priv =                G_TYPE_INSTANCE_GET_PRIVATE (control_point,                                             GUPNP_TYPE_CONTROL_POINT,                                             GUPnPControlPointPrivate);        control_point->priv->doc_cache =                g_hash_table_new_full (g_str_hash,                                       g_str_equal,                                       g_free,                                       NULL);}/* Return TRUE if value == user_data */static gbooleanfind_doc (gpointer key,          gpointer value,          gpointer user_data){        return (value == user_data);}/* xmlDoc wrapper finalized */static voiddoc_finalized (gpointer user_data,               GObject *where_the_object_was){        GUPnPControlPoint *control_point;        control_point = GUPNP_CONTROL_POINT (user_data);        g_hash_table_foreach_remove (control_point->priv->doc_cache,                                     find_doc,                                     where_the_object_was);}/* Release weak reference on xmlDoc wrapper */static voidweak_unref_doc (gpointer key,                gpointer value,                gpointer user_data){        g_object_weak_unref (G_OBJECT (value), doc_finalized, user_data);}static voidgupnp_control_point_dispose (GObject *object){        GUPnPControlPoint *control_point;        GObjectClass *object_class;        control_point = GUPNP_CONTROL_POINT (object);        if (control_point->priv->factory) {                g_object_unref (control_point->priv->factory);                control_point->priv->factory = NULL;        }        while (control_point->priv->devices) {                g_object_unref (control_point->priv->devices->data);                control_point->priv->devices =                        g_list_delete_link (control_point->priv->devices,                                            control_point->priv->devices);        }        while (control_point->priv->services) {                g_object_unref (control_point->priv->services->data);                control_point->priv->services =                        g_list_delete_link (control_point->priv->services,                                            control_point->priv->services);        }        /* Cancel any pending description file GETs */        while (control_point->priv->pending_gets) {                GetDescriptionURLData *data;                GUPnPContext *context;                SoupSession *session;                data = control_point->priv->pending_gets->data;                context = gupnp_control_point_get_context (control_point);                session = _gupnp_context_get_session (context);                soup_session_cancel_message (session,                                             data->message,                                             SOUP_STATUS_CANCELLED);                get_description_url_data_free (data);        }        /* Release weak references on remaining cached documents */        g_hash_table_foreach (control_point->priv->doc_cache,                              weak_unref_doc,                              control_point);        /* Call super */        object_class = G_OBJECT_CLASS (gupnp_control_point_parent_class);        object_class->dispose (object);}static voidgupnp_control_point_finalize (GObject *object){        GUPnPControlPoint *control_point;        GObjectClass *object_class;        control_point = GUPNP_CONTROL_POINT (object);        g_hash_table_destroy (control_point->priv->doc_cache);        /* Call super */        object_class = G_OBJECT_CLASS (gupnp_control_point_parent_class);        object_class->finalize (object);}/* Search @element for matching services */static voidprocess_service_list (xmlNode           *element,                      GUPnPControlPoint *control_point,                      XmlDocWrapper     *doc,                      const char        *udn,                      const char        *service_type,                      const char        *description_url,                      SoupURI           *url_base){        for (element = element->children; element; element = element->next) {                xmlChar *prop;                gboolean match;                GUPnPContext *context;                GUPnPServiceProxy *proxy;                if (strcmp ((char *) element->name, "service") != 0)                        continue;                /* See if this is a matching service */                prop = xml_util_get_child_element_content (element,                                                           "serviceType");                if (!prop)                        continue;                match = (strcmp ((char *) prop, service_type) == 0);                xmlFree (prop);                if (!match)                        continue;                /* Match */                /* Get context */                context = gupnp_control_point_get_context (control_point);                /* Create proxy */                proxy = gupnp_resource_factory_create_service_proxy                                                 (control_point->priv->factory,                                                  context,                                                  doc,                                                  element,                                                  udn,                                                  service_type,                                                  description_url,                                                  url_base);                control_point->priv->services =                        g_list_prepend (control_point->priv->services,                                        proxy);                g_signal_emit (control_point,                               signals[SERVICE_PROXY_AVAILABLE],                               0,                               proxy);        }}/* Recursively search @element for matching devices */static voidprocess_device_list (xmlNode           *element,                     GUPnPControlPoint *control_point,                     XmlDocWrapper     *doc,                     const char        *udn,                     const char        *service_type,                     const char        *description_url,                     SoupURI           *url_base){        for (element = element->children; element; element = element->next) {                xmlNode *children;                xmlChar *prop;                gboolean match;                GUPnPContext *context;                if (strcmp ((char *) element->name, "device") != 0)                        continue;                /* Recurse into children */                children = xml_util_get_element (element,                                                 "deviceList",                                                 NULL);                if (children) {                        process_device_list (children,                                             control_point,                                             doc,                                             udn,                                             service_type,                                             description_url,                                             url_base);                }                /* See if this is a matching device */                prop = xml_util_get_child_element_content (element, "UDN");                if (!prop)                        continue;                match = (strcmp ((char *) prop, udn) == 0);                xmlFree (prop);                if (!match)                        continue;                /* Match */                /* Get context */                context = gupnp_control_point_get_context (control_point);                if (service_type) {                        /* Dive into serviceList */                        children = xml_util_get_element (element,                                                         "serviceList",                                                         NULL);                        if (children) {                                process_service_list (children,                                                      control_point,                                                      doc,                                                      udn,                                                      service_type,                                                      description_url,                                                      url_base);                        }                } else {                        /* Create device proxy */                        GUPnPDeviceProxy *proxy;                        proxy = gupnp_resource_factory_create_device_proxy                                        (control_point->priv->factory,                                         context,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -