/* * Called when the description document is loaded. */ static void description_loaded (GUPnPControlPoint *control_point, GUPnPXMLDoc *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); if (element == NULL) { g_warning ("No 'root' element found in description document" " '%s'. Ignoring device '%s'\n", description_url, udn); return; } if (element == NULL) return; 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); }
/* Recursively search @element for matching devices */ static void process_device_list (xmlNode *element, GUPnPControlPoint *control_point, GUPnPXMLDoc *doc, const char *udn, const char *service_type, const char *description_url, SoupURI *url_base) { g_object_ref (control_point); for (element = element->children; element; element = element->next) { xmlNode *children; xmlChar *prop; gboolean match; 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 */ 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_and_report_device_proxy (control_point, doc, element, udn, description_url, url_base); } g_object_unref (control_point); }