예제 #1
0
파일: icons.c 프로젝트: GNOME/gupnp-tools
/**
 * Icon downloaded.
 **/
static void
got_icon_url (SoupSession    *session,
              SoupMessage    *msg,
              GetIconURLData *data)
{
        if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
                GdkPixbuf *pixbuf;
                GError    *error;

                error = NULL;
                pixbuf = get_icon_from_message (msg, data, &error);

                if (error) {
                        g_warning ("Failed to create icon for '%s': %s",
                                   gupnp_device_info_get_udn (data->info),
                                   error->message);
                        g_error_free (error);
                } else if (pixbuf) {
                        data->callback (data->info, pixbuf);
                } else {
                        g_warning ("Failed to create icon for '%s'",
                                   gupnp_device_info_get_udn (data->info));
                }
        }

        pending_gets = g_list_remove (pending_gets, data);
        get_icon_url_data_free (data);
}
예제 #2
0
static void prv_remove_sub_device(dld_upnp_t *upnp, GUPnPDeviceProxy *sub_proxy,
				  GUPnPServiceProxy *bms_proxy,
				  const gchar *ip_address)
{
	const char *udn;

	DLEYNA_LOG_DEBUG("Enter");

	udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)sub_proxy);

	if (!udn)
		goto on_error;

	DLEYNA_LOG_DEBUG("UDN %s", udn);
	DLEYNA_LOG_DEBUG("IP Address %s", ip_address);

	prv_remove_device(upnp, ip_address, udn);

on_error:

	DLEYNA_LOG_DEBUG("Exit");
	DLEYNA_LOG_DEBUG_NL();

	return;
}
예제 #3
0
void
append_device (GUPnPDeviceInfo *info)
{
        GtkTreeModel *model;
        GtkTreeIter   root_iter;
        GtkTreeIter   iter;
        const char   *udn;

        model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
        g_assert (model != NULL);

        udn = gupnp_device_info_get_udn (info);

        if (!gtk_tree_model_get_iter_first (model, &root_iter))
                return;

        if (!find_device (model, udn, &root_iter, &iter)) {

                append_device_tree (info, model, &root_iter);

                if (!expanded) {
                        GtkTreePath *first_row;

                        first_row = gtk_tree_model_get_path (
                                        model,
                                        &root_iter);
                        expanded = gtk_tree_view_expand_row (
                                        GTK_TREE_VIEW (treeview),
                                        first_row,
                                        FALSE);
                        gtk_tree_path_free (first_row);
                }
        }
}
예제 #4
0
static void
on_device_icon_available (GUPnPDeviceInfo *info,
                          GdkPixbuf       *icon)
{
        GtkTreeModel *model;
        GtkTreeIter   root_iter;
        GtkTreeIter   device_iter;
        const char   *udn;

        model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
        g_assert (model != NULL);

        udn = gupnp_device_info_get_udn (info);

        if (!gtk_tree_model_get_iter_first (model, &root_iter))
                return;

        if (find_device (model, udn, &root_iter, &device_iter))
                gtk_tree_store_set (GTK_TREE_STORE (model),
                                    &device_iter,
                                    0, icon,
                                    -1);

        g_object_unref (icon);
}
예제 #5
0
static GUPnPServiceInfo *
gupnp_device_proxy_get_service (GUPnPDeviceInfo *info,
                                xmlNode         *element)
{
        GUPnPResourceFactory *factory;
        GUPnPServiceProxy    *service;
        GUPnPContext         *context;
        GUPnPXMLDoc          *doc;
        const char           *location, *udn;
        const SoupURI        *url_base;

        factory = gupnp_device_info_get_resource_factory (info);
        context = gupnp_device_info_get_context (info);
        doc = _gupnp_device_info_get_document (info);
        udn = gupnp_device_info_get_udn (info);
        location = gupnp_device_info_get_location (info);
        url_base = gupnp_device_info_get_url_base (info);

        service = gupnp_resource_factory_create_service_proxy (factory,
                                                               context,
                                                               doc,
                                                               element,
                                                               udn,
                                                               NULL,
                                                               location,
                                                               url_base);

        return GUPNP_SERVICE_INFO (service);
}
예제 #6
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;
}
예제 #7
0
void
show_device_details (GUPnPDeviceInfo *info)
{
        char          *details[32];
        const SoupURI *uri;
        const char    *str;
        int            i = 0;

        details[i++] = _("Location");
        str = gupnp_device_info_get_location (info);
        if (str)
                details[i++] = g_strdup (str);

        details[i++] = _("UDN");
        str = gupnp_device_info_get_udn (info);
        if (str)
                details[i++] = g_strdup (str);

        details[i++] = _("Type");
        str = gupnp_device_info_get_device_type (info);
        if (str)
                details[i++] = g_strdup (str);

        details[i++] = _("Base URL");
        uri = gupnp_device_info_get_url_base (info);
        if (uri)
                details[i++] = soup_uri_to_string ((SoupURI *) uri, FALSE);

        details[i++] = _("Friendly Name");
        details[i++] = gupnp_device_info_get_friendly_name (info);
        details[i++] = _("Manufacturer");
        details[i++] = gupnp_device_info_get_manufacturer (info);
        details[i++] = _("Manufacturer URL");
        details[i++] = gupnp_device_info_get_manufacturer_url (info);
        details[i++] = _("Model Description");
        details[i++] = gupnp_device_info_get_model_description (info);
        details[i++] = _("Model Name");
        details[i++] = gupnp_device_info_get_model_name (info);
        details[i++] = _("Model Number");
        details[i++] = gupnp_device_info_get_model_number (info);
        details[i++] = _("Model URL");
        details[i++] = gupnp_device_info_get_model_url (info);
        details[i++] = _("Serial Number");
        details[i++] = gupnp_device_info_get_serial_number (info);
        details[i++] = _("UPC");
        details[i++] = gupnp_device_info_get_upc (info);
        details[i++] = _("Presentation URL");
        details[i++] = gupnp_device_info_get_presentation_url (info);
        details[i] = NULL;

        update_details ((const char **) details);

        /* Only free the values */
        for (i = 1; details[i - 1]; i += 2) {
                if (details[i])
                        g_free (details[i]);
        }
}
예제 #8
0
파일: upnp.c 프로젝트: christophjaeger/yasc
static void on_zone_player_unavailable(GUPnPControlPoint  *control_point,
                                       GUPnPDeviceProxy   *device_proxy,
                                       gpointer            user_data)
{
	g_return_if_fail(YASC_IS_ZONE_PLAYER(device_proxy));

	g_message("Device %s (%s) now unavailable.",
	          gupnp_device_info_get_model_name(GUPNP_DEVICE_INFO(device_proxy)),
	          gupnp_device_info_get_udn(GUPNP_DEVICE_INFO(device_proxy)));
}
예제 #9
0
gboolean
find_device (GtkTreeModel *model,
             const char   *udn,
             GtkTreeIter  *root_iter,
             GtkTreeIter  *iter)
{
        gboolean found = FALSE;
        gboolean more = TRUE;

        if (udn == NULL || root_iter == NULL)
                return found;

        more = gtk_tree_model_iter_children (model, iter, root_iter);

        while (more) {
                GUPnPDeviceInfo *info;
                GtkTreeIter      tmp;
                guint            icon_type;

                gtk_tree_model_get (model, iter,
                                    2, &info,
                                    5, &icon_type, -1);

                if (info) {
                        if (icon_type == ICON_DEVICE) {
                                const char *device_udn;

                                device_udn = gupnp_device_info_get_udn (info);

                                if (device_udn &&
                                    strcmp (device_udn, udn) == 0)
                                        found = TRUE;
                        }

                        g_object_unref (info);

                        if (found)
                                break;

                        if (icon_type == ICON_DEVICE) {
                                /* recurse into embedded-devices */
                                found = find_device (model, udn, iter, &tmp);
                                if (found) {
                                        *iter = tmp;
                                        break;
                                }
                        }
                }

                more = gtk_tree_model_iter_next (model, iter);
        }

        return found;
}
예제 #10
0
파일: upnp.c 프로젝트: 01org/dleyna-server
void dls_upnp_delete_sleeping_device(dls_upnp_t *upnp, dls_device_t *device)
{
	const char *udn;
	dls_device_context_t *ctx = device->sleeping_context;

	udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)ctx->device_proxy);

	upnp->lost_server(device->path, upnp->user_data);

	g_hash_table_remove(upnp->sleeping_device_udn_map, udn);
}
예제 #11
0
파일: icons.c 프로젝트: GNOME/gupnp-tools
void
unschedule_icon_update (GUPnPDeviceInfo *info)
{
        GList *gets;

        for (gets = pending_gets; gets; gets = gets->next) {
                GetIconURLData *data;
                const char *udn1;
                const char *udn2;

                data = gets->data;
                udn1 = gupnp_device_info_get_udn (info);
                udn2 = gupnp_device_info_get_udn (data->info);

                if (udn1 && udn2 && strcmp (udn1, udn2) == 0) {
                        soup_session_cancel_message (download_session,
                                                     data->message,
                                                     SOUP_STATUS_CANCELLED);
                        break;
                }
        }
}
예제 #12
0
파일: icons.c 프로젝트: GNOME/gupnp-tools
void
schedule_icon_update (GUPnPDeviceInfo            *info,
                      DeviceIconAvailableCallback callback)
{
        GetIconURLData *data;
        char           *icon_url;

        data = g_slice_new (GetIconURLData);

        icon_url = gupnp_device_info_get_icon_url
                        (info,
                         NULL,
                         PREFERED_DEPTH,
                         PREFERED_WIDTH,
                         PREFERED_HEIGHT,
                         TRUE,
                         &data->mime_type,
                         NULL,
                         &data->width,
                         &data->height);
        if (icon_url == NULL)
                return;

        data->message = soup_message_new (SOUP_METHOD_GET, icon_url);

        if (data->message == NULL) {
                g_warning ("Invalid URL icon for device '%s': %s",
                           gupnp_device_info_get_udn (info),
                           icon_url);

                g_free (icon_url);
                g_free (data->mime_type);
                g_slice_free (GetIconURLData, data);

                return;
        }

        data->info = g_object_ref (info);
        data->callback = callback;

        pending_gets = g_list_prepend (pending_gets, data);
        soup_session_queue_message (download_session,
                                    data->message,
                                    (SoupSessionCallback) got_icon_url,
                                    data);

        g_free (icon_url);
}
예제 #13
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;
}
예제 #14
0
void
remove_device (GUPnPDeviceInfo *info)
{
        GtkTreeModel *model;
        GtkTreeIter   root_iter;
        GtkTreeIter   iter;
        const char   *udn;

        model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
        g_assert (model != NULL);

        udn = gupnp_device_info_get_udn (info);

        if (!gtk_tree_model_get_iter_first (model, &root_iter))
                return;

        if (find_device (model, udn, &root_iter, &iter)) {
                unschedule_icon_update (info);
                gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
        }
}
예제 #15
0
static GList *
find_device_node (GUPnPControlPoint *control_point,
                  const char        *udn)
{
        GList *l;

        l = control_point->priv->devices;

        while (l) {
                GUPnPDeviceInfo *info;

                info = GUPNP_DEVICE_INFO (l->data);

                if (strcmp (udn, gupnp_device_info_get_udn (info)) == 0)
                        break;

                l = l->next;
        }

        return l;
}
예제 #16
0
static void
gupnp_device_info_get_property (GObject    *object,
                                guint       property_id,
                                GValue     *value,
                                GParamSpec *pspec)
{
        GUPnPDeviceInfo *info;

        info = GUPNP_DEVICE_INFO (object);

        switch (property_id) {
        case PROP_RESOURCE_FACTORY:
                g_value_set_object (value,
                                    info->priv->factory);
                break;
        case PROP_CONTEXT:
                g_value_set_object (value,
                                    info->priv->context);
                break;
        case PROP_LOCATION:
                g_value_set_string (value,
                                    info->priv->location);
                break;
        case PROP_UDN:
                g_value_set_string (value,
                                    gupnp_device_info_get_udn (info));
                break;
        case PROP_DEVICE_TYPE:
                g_value_set_string (value,
                                    gupnp_device_info_get_device_type (info));
                break;
        case PROP_URL_BASE:
                g_value_set_pointer (value,
                                     info->priv->url_base);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
        }
}
예제 #17
0
static GUPnPServiceInfo *
gupnp_device_get_service (GUPnPDeviceInfo *info,
                          xmlNode         *element)
{
        GUPnPDevice          *device;
        GUPnPService         *service;
        GUPnPResourceFactory *factory;
        GUPnPContext         *context;
        GUPnPDevice          *root_device;
        const char           *location, *udn;
        const SoupURI        *url_base;

        device = GUPNP_DEVICE (info);

        root_device = GUPNP_IS_ROOT_DEVICE (device) ? device :
                      GUPNP_DEVICE (device->priv->root_device);
        if (root_device == NULL) {
                g_warning ("Root device not found.");

                return NULL;
        }

        factory = gupnp_device_info_get_resource_factory (info);
        context = gupnp_device_info_get_context (info);
        udn = gupnp_device_info_get_udn (info);
        location = gupnp_device_info_get_location (info);
        url_base = gupnp_device_info_get_url_base (info);

        service = gupnp_resource_factory_create_service (factory,
                                                         context,
                                                         root_device,
                                                         element,
                                                         udn,
                                                         location,
                                                         url_base);

        return GUPNP_SERVICE_INFO (service);
}
예제 #18
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;
}
예제 #19
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;
}
예제 #20
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;
}
예제 #21
0
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;
}
예제 #22
0
파일: upnp.c 프로젝트: 01org/dleyna-server
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;
}