/*
 * 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);
        }
}
Exemple #2
0
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;
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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);
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #10
0
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;
}