Esempio n. 1
0
static const dleyna_task_queue_key_t *prv_create_device_queue(
						prv_device_new_ct_t **priv_t)
{
	const dleyna_task_queue_key_t *queue_id;

	*priv_t = g_new0(prv_device_new_ct_t, 1);

	queue_id = dleyna_task_processor_add_queue(
			dls_server_get_task_processor(),
			dleyna_service_task_create_source(),
			DLS_SERVER_SINK,
			DLEYNA_TASK_QUEUE_FLAG_AUTO_REMOVE,
			dleyna_service_task_process_cb,
			dleyna_service_task_cancel_cb,
			dleyna_service_task_delete_cb);
	dleyna_task_queue_set_finally(queue_id, prv_device_chain_end);
	dleyna_task_queue_set_user_data(queue_id, *priv_t);


	return queue_id;
}
Esempio n. 2
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;
}
Esempio n. 3
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);
	if (!udn)
		goto on_error;

	ip_address = gupnp_context_get_host_ip(
		gupnp_control_point_get_context(cp));

	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();

		priv_t = g_new0(prv_device_new_ct_t, 1);

		queue_id = dleyna_task_processor_add_queue(
				dls_server_get_task_processor(),
				dleyna_service_task_create_source(),
				DLS_SERVER_SINK,
				DLEYNA_TASK_QUEUE_FLAG_AUTO_REMOVE,
				dleyna_service_task_process_cb,
				dleyna_service_task_cancel_cb,
				dleyna_service_task_delete_cb);
		dleyna_task_queue_set_finally(queue_id, prv_device_chain_end);
		dleyna_task_queue_set_user_data(queue_id, priv_t);

		device = dls_device_new(upnp->connection, proxy, ip_address,
					upnp->interface_info,
					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 {
		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;
}
Esempio n. 4
0
static void prv_remove_device(dld_upnp_t *upnp, const gchar *ip_address,
			      const char *udn)
{
	dld_device_t *device;
	unsigned int i;
	dld_device_context_t *context;
	gboolean subscribed;
	gboolean under_construction = FALSE;
	prv_device_new_ct_t *priv_t;
	gboolean construction_ctx = FALSE;
	const dleyna_task_queue_key_t *queue_id;

	DLEYNA_LOG_DEBUG("Enter");

	device = g_hash_table_lookup(upnp->device_udn_map, udn);

	if (!device) {
		priv_t = g_hash_table_lookup(upnp->device_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) {
		subscribed = (context->bms.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_device(device->path);
				g_hash_table_remove(upnp->device_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->device_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 = dld_device_get_context(device);
			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 */
			dld_device_construct(device, context, upnp->connection,
					     upnp->interface_info, 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_service_changes,
					device);
		}
	}

on_error:

	DLEYNA_LOG_DEBUG("Exit");

	return;
}