/* * 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 void load_description (GUPnPControlPoint *control_point, const char *description_url, const char *udn, const char *service_type) { GUPnPXMLDoc *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 void prv_device_unavailable_cb(GUPnPControlPoint *cp, GUPnPDeviceProxy *proxy, gpointer user_data) { dld_upnp_t *upnp = user_data; const char *udn; const gchar *ip_address; DLEYNA_LOG_DEBUG("Enter"); udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)proxy); ip_address = gupnp_context_get_host_ip( gupnp_control_point_get_context(cp)); if (!udn || !ip_address) goto on_error; DLEYNA_LOG_DEBUG("UDN %s", udn); DLEYNA_LOG_DEBUG("IP Address %s", ip_address); (void) prv_remove_bm_service_sub_devices((GUPnPDeviceInfo *)proxy, upnp, ip_address); prv_remove_device(upnp, ip_address, udn); on_error: return; }
static void gupnp_control_point_dispose (GObject *object) { GUPnPControlPoint *control_point; GSSDPResourceBrowser *browser; GObjectClass *object_class; control_point = GUPNP_CONTROL_POINT (object); browser = GSSDP_RESOURCE_BROWSER (control_point); gssdp_resource_browser_set_active (browser, FALSE); if (control_point->priv->factory) { g_object_unref (control_point->priv->factory); control_point->priv->factory = NULL; } /* 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 void prv_device_available_cb(GUPnPControlPoint *cp, GUPnPDeviceProxy *proxy, gpointer user_data) { dld_upnp_t *upnp = user_data; const char *udn; const gchar *ip_address; GUPnPServiceProxy *bms_proxy; DLEYNA_LOG_DEBUG("Enter"); udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)proxy); ip_address = gupnp_context_get_host_ip( gupnp_control_point_get_context(cp)); if (!udn || !ip_address) goto on_error; DLEYNA_LOG_DEBUG("UDN %s", udn); DLEYNA_LOG_DEBUG("IP Address %s", ip_address); bms_proxy = (GUPnPServiceProxy *) gupnp_device_info_get_service( (GUPnPDeviceInfo *)proxy, DLD_BASIC_MANAGEMENT_SERVICE_TYPE); if (bms_proxy != NULL) prv_add_device(upnp, proxy, bms_proxy, ip_address, udn); (void) prv_add_bm_service_sub_devices((GUPnPDeviceInfo *)proxy, upnp, ip_address); on_error: DLEYNA_LOG_DEBUG("Exit"); DLEYNA_LOG_DEBUG_NL(); return; }
static void create_and_report_service_proxy (GUPnPControlPoint *control_point, GUPnPXMLDoc *doc, xmlNode *element, const char *udn, const char *service_type, const char *description_url, SoupURI *url_base) { GUPnPServiceProxy *proxy; GUPnPResourceFactory *factory; GUPnPContext *context; if (find_service_node (control_point, udn, service_type) != NULL) /* We already have a proxy for this service */ return; factory = gupnp_control_point_get_resource_factory (control_point); context = gupnp_control_point_get_context (control_point); /* Create proxy */ proxy = gupnp_resource_factory_create_service_proxy (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); }
static void prv_server_unavailable_cb(GUPnPControlPoint *cp, GUPnPDeviceProxy *proxy, gpointer user_data) { dls_upnp_t *upnp = user_data; const char *udn; dls_device_t *device; const gchar *ip_address; unsigned int i; dls_device_context_t *context; gboolean subscribed; gboolean construction_ctx = FALSE; gboolean under_construction = FALSE; prv_device_new_ct_t *priv_t; const dleyna_task_queue_key_t *queue_id; DLEYNA_LOG_DEBUG("Enter"); udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)proxy); ip_address = gupnp_context_get_host_ip( gupnp_control_point_get_context(cp)); if (!udn || !ip_address) goto on_error; DLEYNA_LOG_DEBUG("UDN %s", udn); DLEYNA_LOG_DEBUG("IP Address %s", ip_address); device = g_hash_table_lookup(upnp->server_udn_map, udn); if (!device) { priv_t = g_hash_table_lookup(upnp->server_uc_map, udn); if (priv_t) { device = priv_t->device; under_construction = TRUE; } } if (!device) { DLEYNA_LOG_WARNING("Device not found. Ignoring"); goto on_error; } for (i = 0; i < device->contexts->len; ++i) { context = g_ptr_array_index(device->contexts, i); if (!strcmp(context->ip_address, ip_address)) break; } if (i >= device->contexts->len) goto on_error; subscribed = context->subscribed; if (under_construction) construction_ctx = !strcmp(context->ip_address, priv_t->ip_address); (void) g_ptr_array_remove_index(device->contexts, i); if (device->contexts->len == 0) { if (!under_construction) { DLEYNA_LOG_DEBUG("Last Context lost. Delete device"); upnp->lost_server(device->path, upnp->user_data); g_hash_table_remove(upnp->server_udn_map, udn); } else { DLEYNA_LOG_WARNING( "Device under construction. Cancelling"); dleyna_task_processor_cancel_queue(priv_t->queue_id); } } else if (under_construction && construction_ctx) { DLEYNA_LOG_WARNING( "Device under construction. Switching context"); /* Cancel previous contruction task chain */ g_hash_table_remove(priv_t->upnp->server_uc_map, priv_t->udn); dleyna_task_queue_set_finally(priv_t->queue_id, prv_device_context_switch_end); dleyna_task_processor_cancel_queue(priv_t->queue_id); /* Create a new construction task chain */ context = dls_device_get_context(device, NULL); queue_id = prv_create_device_queue(&priv_t); prv_update_device_context(priv_t, upnp, udn, device, context->ip_address, queue_id); /* Start tasks from current construction step */ dls_device_construct(device, context, upnp->connection, upnp->interface_info, upnp->property_map, queue_id); } else if (subscribed && !device->timeout_id) { DLEYNA_LOG_DEBUG("Subscribe on new context"); device->timeout_id = g_timeout_add_seconds(1, prv_subscribe_to_contents_change, device); } on_error: DLEYNA_LOG_DEBUG("Exit"); DLEYNA_LOG_DEBUG_NL(); return; }
static void prv_server_available_cb(GUPnPControlPoint *cp, GUPnPDeviceProxy *proxy, gpointer user_data) { dls_upnp_t *upnp = user_data; const char *udn; dls_device_t *device; const gchar *ip_address; dls_device_context_t *context; const dleyna_task_queue_key_t *queue_id; unsigned int i; prv_device_new_ct_t *priv_t; udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)proxy); ip_address = gupnp_context_get_host_ip( gupnp_control_point_get_context(cp)); if (!udn || !ip_address) goto on_error; DLEYNA_LOG_DEBUG("UDN %s", udn); DLEYNA_LOG_DEBUG("IP Address %s", ip_address); device = g_hash_table_lookup(upnp->server_udn_map, udn); if (!device) { priv_t = g_hash_table_lookup(upnp->server_uc_map, udn); if (priv_t) device = priv_t->device; } if (!device) { DLEYNA_LOG_DEBUG("Device not found. Adding"); DLEYNA_LOG_DEBUG_NL(); queue_id = prv_create_device_queue(&priv_t); device = dls_device_new(upnp->connection, proxy, ip_address, upnp->interface_info, upnp->property_map, upnp->counter, queue_id); prv_update_device_context(priv_t, upnp, udn, device, ip_address, queue_id); upnp->counter++; } else { DLEYNA_LOG_DEBUG("Device Found"); for (i = 0; i < device->contexts->len; ++i) { context = g_ptr_array_index(device->contexts, i); if (!strcmp(context->ip_address, ip_address)) break; } if (i == device->contexts->len) { DLEYNA_LOG_DEBUG("Adding Context"); (void) dls_device_append_new_context(device, ip_address, proxy); } DLEYNA_LOG_DEBUG_NL(); } on_error: return; }
static void prv_device_available_cb(GUPnPControlPoint *cp, GUPnPDeviceProxy *proxy, gpointer user_data) { dls_upnp_t *upnp = user_data; const char *udn; dls_device_t *device; const gchar *ip_address; dls_device_context_t *context; const dleyna_task_queue_key_t *queue_id; unsigned int i; prv_device_new_ct_t *priv_t; GUPnPDeviceInfo *device_proxy = (GUPnPDeviceInfo *)proxy; GUPnPDeviceInfo *device_info = NULL; const gchar *device_type; gboolean subscribe = FALSE; gpointer key; gpointer val; udn = gupnp_device_info_get_udn(device_proxy); ip_address = gssdp_client_get_host_ip( GSSDP_CLIENT(gupnp_control_point_get_context(cp))); if (!udn || !ip_address) goto on_error; DLEYNA_LOG_DEBUG("UDN %s", udn); DLEYNA_LOG_DEBUG("IP Address %s", ip_address); device_type = gupnp_device_info_get_device_type(device_proxy); if (!g_str_has_prefix(device_type, DLS_DMS_DEVICE_TYPE)) { device_info = prv_lookup_dms_child_device(device_proxy); if (device_info == NULL) goto on_error; } else { device_info = device_proxy; } device = g_hash_table_lookup(upnp->device_udn_map, udn); if (!device) { device = g_hash_table_lookup(upnp->sleeping_device_udn_map, udn); if (device != NULL) { if (g_hash_table_lookup_extended( upnp->sleeping_device_udn_map, udn, &key, &val)) { g_hash_table_steal( upnp->sleeping_device_udn_map, udn); g_free(key); } g_hash_table_insert(upnp->device_udn_map, g_strdup(udn), device); if (device->wake_on_timeout_id) { DLEYNA_LOG_DEBUG("Stop WAKE-ON watcher..."); (void) g_source_remove( device->wake_on_timeout_id); device->wake_on_timeout_id = 0; } dls_device_delete_context(device->sleeping_context); device->sleeping_context = NULL; device->sleeping = FALSE; subscribe = TRUE; } } if (!device) { priv_t = g_hash_table_lookup(upnp->device_uc_map, udn); if (priv_t) device = priv_t->device; } if (!device) { DLEYNA_LOG_DEBUG("Device not found. Adding"); DLEYNA_LOG_DEBUG_NL(); queue_id = prv_create_device_queue(&priv_t); device = dls_device_new(upnp->connection, proxy, device_info, ip_address, upnp->interface_info, upnp->property_map, udn, queue_id); prv_update_device_context(priv_t, upnp, udn, device, ip_address, queue_id); } else { DLEYNA_LOG_DEBUG("Device Found"); for (i = 0; i < device->contexts->len; ++i) { context = g_ptr_array_index(device->contexts, i); if (!strcmp(context->ip_address, ip_address)) break; } if (i == device->contexts->len) { DLEYNA_LOG_DEBUG("Adding Context"); (void) dls_device_append_new_context(device, ip_address, proxy, device_info); if (subscribe) dls_device_subscribe_to_service_changes(device); } DLEYNA_LOG_DEBUG_NL(); } on_error: return; }
static void prv_server_unavailable_cb(GUPnPControlPoint *cp, GUPnPDeviceProxy *proxy, gpointer user_data) { msu_upnp_t *upnp = user_data; const char *udn; msu_device_t *device; const gchar *ip_address; unsigned int i; msu_device_context_t *context; gboolean subscribed; gboolean under_construction = FALSE; prv_device_new_ct_t *priv_t; MSU_LOG_DEBUG("Enter"); udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)proxy); if (!udn) goto on_error; ip_address = gupnp_context_get_host_ip( gupnp_control_point_get_context(cp)); MSU_LOG_DEBUG("UDN %s", udn); MSU_LOG_DEBUG("IP Address %s", ip_address); device = g_hash_table_lookup(upnp->server_udn_map, udn); if (!device) { priv_t = g_hash_table_lookup(upnp->server_uc_map, udn); if (priv_t) { device = priv_t->device; under_construction = TRUE; } } if (!device) { MSU_LOG_WARNING("Device not found. Ignoring"); goto on_error; } for (i = 0; i < device->contexts->len; ++i) { context = g_ptr_array_index(device->contexts, i); if (!strcmp(context->ip_address, ip_address)) break; } if (i >= device->contexts->len) goto on_error; subscribed = context->subscribed; (void) g_ptr_array_remove_index(device->contexts, i); if (device->contexts->len == 0) { if (!under_construction) { MSU_LOG_DEBUG("Last Context lost. Delete device"); upnp->lost_server(device->path, upnp->user_data); g_hash_table_remove(upnp->server_udn_map, udn); } else { MSU_LOG_WARNING( "Device under construction. Cancelling"); msu_task_processor_cancel_queue(priv_t->queue_id); } } else if (subscribed && !device->timeout_id) { MSU_LOG_DEBUG("Subscribe on new context"); device->timeout_id = g_timeout_add_seconds(1, prv_subscribe_to_contents_change, device); } on_error: MSU_LOG_DEBUG("Exit"); MSU_LOG_DEBUG_NL(); return; }
static void prv_server_available_cb(GUPnPControlPoint *cp, GUPnPDeviceProxy *proxy, gpointer user_data) { msu_upnp_t *upnp = user_data; const char *udn; msu_device_t *device; const gchar *ip_address; msu_device_context_t *context; const msu_task_queue_key_t *queue_id; unsigned int i; prv_device_new_ct_t *priv_t; udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)proxy); if (!udn) goto on_error; ip_address = gupnp_context_get_host_ip( gupnp_control_point_get_context(cp)); MSU_LOG_DEBUG("UDN %s", udn); MSU_LOG_DEBUG("IP Address %s", ip_address); device = g_hash_table_lookup(upnp->server_udn_map, udn); if (!device) { priv_t = g_hash_table_lookup(upnp->server_uc_map, udn); if (priv_t) device = priv_t->device; } if (!device) { MSU_LOG_DEBUG("Device not found. Adding"); MSU_LOG_DEBUG_NL(); priv_t = g_new0(prv_device_new_ct_t, 1); queue_id = msu_task_processor_add_queue( msu_media_service_get_task_processor(), msu_service_task_create_source(), MSU_SINK, MSU_TASK_QUEUE_FLAG_AUTO_REMOVE, msu_service_task_process_cb, msu_service_task_cancel_cb, msu_service_task_delete_cb); msu_task_queue_set_finally(queue_id, prv_device_chain_end); msu_task_queue_set_user_data(queue_id, priv_t); device = msu_device_new(upnp->connection, proxy, ip_address, &gSubtreeVtable, upnp, upnp->property_map, upnp->counter, queue_id); upnp->counter++; priv_t->upnp = upnp; priv_t->udn = g_strdup(udn); priv_t->queue_id = queue_id; priv_t->device = device; g_hash_table_insert(upnp->server_uc_map, g_strdup(udn), priv_t); } else { MSU_LOG_DEBUG("Device Found"); for (i = 0; i < device->contexts->len; ++i) { context = g_ptr_array_index(device->contexts, i); if (!strcmp(context->ip_address, ip_address)) break; } if (i == device->contexts->len) { MSU_LOG_DEBUG("Adding Context"); (void) msu_device_append_new_context(device, ip_address, proxy); } MSU_LOG_DEBUG_NL(); } on_error: return; }