+STATIC char* _rygel_find_id_for_index (dev_ctx_T* dev_ctx_c, char *raw, unsigned int index) {
+
+ char *found = raw;
+ char id[33];
+ int i;
+
+ for (i = 0; i <= index; i++) {
+ found = strstr (found, "item id=");
+ found += 9;
+
+ if (i == index) {
+ /* IDs are 32-bit numbers */
+ strncpy (id, found, 32);
+ id[32] = '\0';
+ }
+ }
+
+ return strdup(id);
+}
+
+STATIC char* _rygel_find_metadata_for_id (dev_ctx_T* dev_ctx_c, char *id) {
+
+ GUPnPServiceProxy *content_dir_proxy;
+ struct timeval tv_start, tv_now;
+
+ dev_ctx_c->content_res = NULL;
+
+ content_dir_proxy = GUPNP_SERVICE_PROXY (dev_ctx_c->content_dir);
+
+ gupnp_service_proxy_begin_action (content_dir_proxy, "Browse", _rygel_metadata_cb, dev_ctx_c,
+ "ObjectID", G_TYPE_STRING, id,
+ "BrowseFlag", G_TYPE_STRING, "BrowseMetadata",
+ "Filter", G_TYPE_STRING, "*",
+ "StartingIndex", G_TYPE_UINT, 0,
+ "RequestedCount", G_TYPE_UINT, 0,
+ "SortCriteria", G_TYPE_STRING, "",
+ NULL);
+
+ gettimeofday (&tv_start, NULL);
+ gettimeofday (&tv_now, NULL);
+ while (tv_now.tv_sec - tv_start.tv_sec <= 5) {
+
+ g_main_context_iteration (dev_ctx_c->loop, FALSE);
+
+ if (dev_ctx_c->content_res)
+ break;
+ gettimeofday (&tv_now, NULL);
+ }
+
+ return dev_ctx_c->content_res;
+}
+
+STATIC char* _rygel_find_uri_for_metadata (dev_ctx_T* dev_ctx_c, char *metadata) {
+
+ char *start, *end, *uri = NULL;
+ int length;
+
+ /* position ourselves after the first "<res " tag */
+ start = strstr (metadata, "<res ");
+
+ while (start) {
+ start = strstr (start, "http://");
+ if (!start) break;
+ end = strstr (start, "</res>");
+ length = end - start;
+
+
+ uri = (char *)malloc (length + 1);
+ strncpy (uri, start, length);
+ uri[length] = '\0';
+ /* if the URI contains "primary_http", it is the main one ; stop here...*/
+ if (strstr (uri, "primary_http"))
+ break;
+
+ free (uri); start = end;
+ }
+
+ return uri;
+}
+
+STATIC unsigned char _rygel_start_doing (dev_ctx_T* dev_ctx_c, char *uri, char *metadata, State state) {
+
+ GUPnPServiceProxy *av_transport_proxy;
+ struct timeval tv_start, tv_now;
+
+ if (!dev_ctx_c->av_transport) {
+ if (!_rygel_find_av_transport (dev_ctx_c))
+ return 0;
+ }
+ dev_ctx_c->target_state = state;
+
+ av_transport_proxy = GUPNP_SERVICE_PROXY (dev_ctx_c->av_transport);
+
+ gupnp_service_proxy_begin_action (av_transport_proxy, "SetAVTransportURI", _rygel_select_cb, dev_ctx_c,
+ "InstanceID", G_TYPE_UINT, 0,
+ "CurrentURI", G_TYPE_STRING, uri,
+ "CurrentURIMetaData", G_TYPE_STRING, metadata,
+ NULL);
+
+ gettimeofday (&tv_start, NULL);
+ gettimeofday (&tv_now, NULL);
+ while (tv_now.tv_sec - tv_start.tv_sec <= 5) {
+
+ g_main_context_iteration (dev_ctx_c->loop, FALSE);
+
+ if (dev_ctx_c->state == state)
+ break;
+ gettimeofday (&tv_now, NULL);
+ }
+ if (dev_ctx_c->state != state)
+ return 0;
+
+ return 1;
+}
+
+STATIC unsigned char _rygel_find_av_transport (dev_ctx_T* dev_ctx_c) {
+
+ GUPnPControlPoint *control_point;
+ gint handler_cb;
+ struct timeval tv_start, tv_now;
+
+ control_point = gupnp_control_point_new (dev_ctx_c->context, URN_MEDIA_RENDERER);
+
+ handler_cb = g_signal_connect (control_point, "device-proxy-available",
+ G_CALLBACK (_rygel_av_transport_cb), dev_ctx_c);
+
+ gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (control_point), TRUE);
+
+ gettimeofday (&tv_start, NULL);
+ gettimeofday (&tv_now, NULL);
+ while (tv_now.tv_sec - tv_start.tv_sec <= 5) {
+
+ g_main_context_iteration (dev_ctx_c->loop, FALSE);
+
+ if (dev_ctx_c->av_transport)
+ break;
+ gettimeofday (&tv_now, NULL);
+ }
+ g_signal_handler_disconnect (control_point, handler_cb);
+
+ if (!dev_ctx_c->av_transport)
+ return 0;
+
+ return 1;
+}
+
+