📄 gupnp-control-point.c
字号:
doc, element, udn, description_url, url_base); control_point->priv->devices = g_list_prepend (control_point->priv->devices, proxy); g_signal_emit (control_point, signals[DEVICE_PROXY_AVAILABLE], 0, proxy); } }}/* * Called when the description document is loaded. */static voiddescription_loaded (GUPnPControlPoint *control_point, XmlDocWrapper *doc, const char *udn, const char *service_type, const char *description_url){ xmlNode *element; SoupURI *url_base; /* Save the URL base, if any */ element = xml_util_get_element ((xmlNode *) doc->doc, "root", NULL); url_base = xml_util_get_child_element_content_uri (element, "URLBase", NULL); if (!url_base) url_base = soup_uri_new (description_url); /* Iterate matching devices */ process_device_list (element, control_point, doc, udn, service_type, description_url, url_base); /* Cleanup */ soup_uri_free (url_base);}/* * Description URL downloaded. */static voidgot_description_url (SoupSession *session, SoupMessage *msg, GetDescriptionURLData *data){ XmlDocWrapper *doc; if (msg->status_code == SOUP_STATUS_CANCELLED) return; /* Now, make sure again this document is not already cached. If it is, * we re-use the cached one. */ doc = g_hash_table_lookup (data->control_point->priv->doc_cache, data->description_url); if (doc) { /* Doc was cached */ description_loaded (data->control_point, doc, data->udn, data->service_type, data->description_url); get_description_url_data_free (data); return; } /* Not cached */ if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { xmlDoc *xml_doc; /* Parse response */ xml_doc = xmlParseMemory (msg->response_body->data, msg->response_body->length); if (xml_doc) { doc = xml_doc_wrapper_new (xml_doc); description_loaded (data->control_point, doc, data->udn, data->service_type, data->description_url); /* Insert into document cache */ g_hash_table_insert (data->control_point->priv->doc_cache, g_strdup (data->description_url), doc); /* Make sure the document is removed from the cache * once finalized. */ g_object_weak_ref (G_OBJECT (doc), doc_finalized, data->control_point); /* If no proxy was created, make sure doc is freed. */ g_object_ref_sink (doc); g_object_unref (doc); } else g_warning ("Failed to parse %s", data->description_url); } else g_warning ("Failed to GET %s", data->description_url); get_description_url_data_free (data);}/* * Downloads and parses (or takes from cache) @description_url, * creating: * - A #GUPnPDeviceProxy for the device specified by @udn if @service_type * is %NULL. * - A #GUPnPServiceProxy for the service of type @service_type from the device * specified by @udn if @service_type is not %NULL. */static voidload_description (GUPnPControlPoint *control_point, const char *description_url, const char *udn, const char *service_type){ XmlDocWrapper *doc; doc = g_hash_table_lookup (control_point->priv->doc_cache, description_url); if (doc) { /* Doc was cached */ description_loaded (control_point, doc, udn, service_type, description_url); } else { /* Asynchronously download doc */ GUPnPContext *context; SoupSession *session; GetDescriptionURLData *data; context = gupnp_control_point_get_context (control_point); session = _gupnp_context_get_session (context); data = g_slice_new (GetDescriptionURLData); data->message = soup_message_new (SOUP_METHOD_GET, description_url); if (data->message == NULL) { g_warning ("Invalid description URL: %s", description_url); g_slice_free (GetDescriptionURLData, data); return; } http_request_set_user_agent (data->message); http_request_set_accept_language (data->message); data->control_point = control_point; data->udn = g_strdup (udn); data->service_type = g_strdup (service_type); data->description_url = g_strdup (description_url); control_point->priv->pending_gets = g_list_prepend (control_point->priv->pending_gets, data); soup_session_queue_message (session, data->message, (SoupSessionCallback) got_description_url, data); }}static gbooleanparse_usn (const char *usn, char **udn, char **service_type){ gboolean ret; char **bits; guint count, i; ret = FALSE; *udn = *service_type = NULL; /* Verify we have a valid USN */ if (strncmp (usn, "uuid:", strlen ("uuid:"))) { g_warning ("Invalid USN: %s", usn); return FALSE; } /* Parse USN */ bits = g_strsplit (usn, "::", -1); /* Count elements */ for (count = 0; bits[count]; count++); if (count == 1) { /* uuid:device-UUID */ *udn = bits[0]; ret = TRUE; } else if (count == 2) { char **second_bits; second_bits = g_strsplit (bits[1], ":", -1); if (!strcmp (second_bits[0], "upnp") && !strcmp (second_bits[1], "rootdevice")) { /* uuid:device-UUID::upnp:rootdevice */ *udn = bits[0]; ret = TRUE; } else if (!strcmp (second_bits[0], "urn")) { /* uuid:device-UIID::urn:domain-name:service/device: * type:v */ if (!strcmp (second_bits[2], "device")) { *udn = bits[0]; ret = TRUE; } else if (!strcmp (second_bits[2], "service")) { *udn = bits[0]; *service_type = bits[1]; ret = TRUE; } } g_strfreev (second_bits); } if (*udn == NULL) g_warning ("Invalid USN: %s", usn); for (i = 0; i < count; i++) { if ((bits[i] != *udn) && (bits[i] != *service_type)) g_free (bits[i]); } g_free (bits); return ret;}static voidgupnp_control_point_resource_available (GSSDPResourceBrowser *resource_browser, const char *usn, const GList *locations){ GUPnPControlPoint *control_point; char *udn, *service_type; control_point = GUPNP_CONTROL_POINT (resource_browser); /* Verify we have a location */ if (!locations) { g_warning ("No Location header for device with USN %s", usn); return; } /* Parse USN */ if (!parse_usn (usn, &udn, &service_type)) return; load_description (control_point, locations->data, udn, service_type); g_free (udn); g_free (service_type);}static voidgupnp_control_point_resource_unavailable (GSSDPResourceBrowser *resource_browser, const char *usn){ GUPnPControlPoint *control_point; char *udn, *service_type; GList *l, *cur_l; control_point = GUPNP_CONTROL_POINT (resource_browser); /* Parse USN */ if (!parse_usn (usn, &udn, &service_type)) return; /* Find proxy */ if (service_type) { l = control_point->priv->services; while (l) { GUPnPServiceInfo *info; GUPnPServiceProxy *proxy; info = GUPNP_SERVICE_INFO (l->data); if ((strcmp (udn, gupnp_service_info_get_udn (info)) != 0) || (strcmp (service_type, gupnp_service_info_get_service_type (info)) != 0)) { l = l->next; continue; } /* Remove proxy */ proxy = GUPNP_SERVICE_PROXY (info); cur_l = l; l = l->next; control_point->priv->services =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -