📄 gupnp-service-proxy.c
字号:
g_list_append (proxy->priv->pending_notifies, doc); if (!proxy->priv->notify_idle_id) proxy->priv->notify_idle_id = g_idle_add (emit_notifications, proxy); /* Everything went OK */ soup_message_set_status (msg, SOUP_STATUS_OK);}/* * Generates a timeout header for the subscription timeout specified * in our GUPnPContext. */static char *make_timeout_header (GUPnPContext *context){ guint timeout; timeout = gupnp_context_get_subscription_timeout (context); if (timeout > 0) return g_strdup_printf ("Second-%d", timeout); else return g_strdup ("infinite");}/* * Subscription expired. */static gbooleansubscription_expire (gpointer user_data){ GUPnPServiceProxy *proxy; GUPnPContext *context; SoupMessage *msg; SoupSession *session; char *sub_url, *timeout; proxy = GUPNP_SERVICE_PROXY (user_data); /* Reset timeout ID */ proxy->priv->subscription_timeout_id = 0; /* Send renewal message */ context = gupnp_service_info_get_context (GUPNP_SERVICE_INFO (proxy)); /* Create subscription message */ sub_url = gupnp_service_info_get_event_subscription_url (GUPNP_SERVICE_INFO (proxy)); msg = soup_message_new (GENA_METHOD_SUBSCRIBE, sub_url); g_free (sub_url); g_assert (msg != NULL); /* Add headers */ soup_message_headers_append (msg->request_headers, "SID", proxy->priv->sid); timeout = make_timeout_header (context); soup_message_headers_append (msg->request_headers, "Timeout", timeout); g_free (timeout); /* And send it off */ proxy->priv->pending_messages = g_list_prepend (proxy->priv->pending_messages, msg); session = _gupnp_context_get_session (context); soup_session_queue_message (session, msg, (SoupSessionCallback) subscribe_got_response, proxy); return FALSE;}/* * Received subscription response. */static voidsubscribe_got_response (SoupSession *session, SoupMessage *msg, GUPnPServiceProxy *proxy){ GError *error; /* Cancelled? */ if (msg->status_code == SOUP_STATUS_CANCELLED) return; /* Remove from pending messages list */ proxy->priv->pending_messages = g_list_remove (proxy->priv->pending_messages, msg); /* Check whether the subscription is still wanted */ if (!proxy->priv->subscribed) return; /* Reset SID */ g_free (proxy->priv->sid); proxy->priv->sid = NULL; /* Check message status */ if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { /* Success. */ const char *hdr; int timeout; /* Save SID. */ hdr = soup_message_headers_get (msg->response_headers, "SID"); if (hdr == NULL) { error = g_error_new (GUPNP_EVENTING_ERROR, GUPNP_EVENTING_ERROR_SUBSCRIPTION_LOST, "No SID in SUBSCRIBE response"); goto ERROR; } proxy->priv->sid = g_strdup (hdr); /* Figure out when the subscription times out */ hdr = soup_message_headers_get (msg->response_headers, "Timeout"); if (hdr == NULL) { g_warning ("No Timeout in SUBSCRIBE response."); return; } if (strncmp (hdr, "Second-", strlen ("Second-")) == 0) { /* We have a finite timeout */ timeout = atoi (hdr + strlen ("Second-")); /* We want to resubscribe before the subscription * expires. */ timeout -= GENA_TIMEOUT_DELTA; if (timeout < 0) { g_warning ("Invalid time-out specified. " "Assuming default value of %d.", GENA_DEFAULT_TIMEOUT); timeout = GENA_DEFAULT_TIMEOUT; } /* Add actual timeout */ proxy->priv->subscription_timeout_id = g_timeout_add_seconds (timeout, subscription_expire, proxy); } } else { GUPnPContext *context; SoupServer *server; /* Subscription failed. */ error = g_error_new (GUPNP_EVENTING_ERROR, GUPNP_EVENTING_ERROR_SUBSCRIPTION_FAILED, msg->reason_phrase); ERROR: proxy->priv->subscribed = FALSE; g_object_notify (G_OBJECT (proxy), "subscribed"); /* Emit subscription-lost */ g_signal_emit (proxy, signals[SUBSCRIPTION_LOST], 0, error); g_error_free (error); /* Remove listener */ context = gupnp_service_info_get_context (GUPNP_SERVICE_INFO (proxy)); server = gupnp_context_get_server (context); soup_server_remove_handler (server, proxy->priv->path); }}/* * Subscribe to this service. */static voidsubscribe (GUPnPServiceProxy *proxy){ GUPnPContext *context; SoupMessage *msg; SoupSession *session; SoupServer *server; const char *server_url; char *sub_url, *delivery_url, *timeout; context = gupnp_service_info_get_context (GUPNP_SERVICE_INFO (proxy)); /* Create subscription message */ sub_url = gupnp_service_info_get_event_subscription_url (GUPNP_SERVICE_INFO (proxy)); msg = NULL; if (sub_url != NULL) { msg = soup_message_new (GENA_METHOD_SUBSCRIBE, sub_url); g_free (sub_url); } if (msg == NULL) { GError *error; /* Subscription failed. */ proxy->priv->subscribed = FALSE; g_object_notify (G_OBJECT (proxy), "subscribed"); /* Emit subscription-lost */ error = g_error_new (GUPNP_SERVER_ERROR, GUPNP_SERVER_ERROR_INVALID_URL, "No valid subscription URL defined"); g_signal_emit (proxy, signals[SUBSCRIPTION_LOST], 0, error); g_error_free (error); return; } /* Add headers */ server_url = _gupnp_context_get_server_url (context); delivery_url = g_strdup_printf ("<%s%s>", server_url, proxy->priv->path); soup_message_headers_append (msg->request_headers, "Callback", delivery_url); g_free (delivery_url); soup_message_headers_append (msg->request_headers, "NT", "upnp:event"); timeout = make_timeout_header (context); soup_message_headers_append (msg->request_headers, "Timeout", timeout); g_free (timeout); /* Listen for events */ server = gupnp_context_get_server (context); soup_server_add_handler (server, proxy->priv->path, server_handler, proxy, NULL); /* And send our subscription message off */ proxy->priv->pending_messages = g_list_prepend (proxy->priv->pending_messages, msg); session = _gupnp_context_get_session (context); soup_session_queue_message (session, msg, (SoupSessionCallback) subscribe_got_response, proxy);}/* * Unsubscribe from this service. */static voidunsubscribe (GUPnPServiceProxy *proxy){ GUPnPContext *context; SoupMessage *msg; SoupSession *session; SoupServer *server; char *sub_url; if (proxy->priv->sid == NULL) return; /* No SID: nothing to unsubscribe */ context = gupnp_service_info_get_context (GUPNP_SERVICE_INFO (proxy)); /* Create unsubscription message */ sub_url = gupnp_service_info_get_event_subscription_url (GUPNP_SERVICE_INFO (proxy)); msg = soup_message_new (GENA_METHOD_UNSUBSCRIBE, sub_url); g_free (sub_url); g_assert (msg != NULL); /* Add headers */ soup_message_headers_append (msg->request_headers, "SID", proxy->priv->sid); /* And queue it */ session = _gupnp_context_get_session (context); soup_session_queue_message (session, msg, NULL, NULL); /* Reset SID */ g_free (proxy->priv->sid); proxy->priv->sid = NULL; /* Reset sequence number */ proxy->priv->seq = 0; /* Remove subscription timeout */ if (proxy->priv->subscription_timeout_id) { g_source_remove (proxy->priv->subscription_timeout_id); proxy->priv->subscription_timeout_id = 0; } /* Remove server handler */ server = gupnp_context_get_server (context); soup_server_remove_handler (server, proxy->priv->path);}/** * gupnp_service_proxy_set_subscribed * @proxy: A #GUPnPServiceProxy * @subscribed: %TRUE to subscribe to this service * * (Un)subscribes to this service. * * Note that the relevant messages are not immediately sent but queued. * If you want to unsubcribe from this service because the application * is quitting, rely on automatic synchronised unsubscription on object * destruction instead. **/voidgupnp_service_proxy_set_subscribed (GUPnPServiceProxy *proxy, gboolean subscribed){ g_return_if_fail (GUPNP_IS_SERVICE_PROXY (proxy)); if (proxy->priv->subscribed == subscribed) return; proxy->priv->subscribed = subscribed; if (subscribed) subscribe (proxy); else unsubscribe (proxy); g_object_notify (G_OBJECT (proxy), "subscribed");}/** * gupnp_service_proxy_get_subscribed * @proxy: A #GUPnPServiceProxy * * Returns if we are subscribed to this service. * * Return value: %TRUE if we are subscribed to this service, otherwise %FALSE. **/gbooleangupnp_service_proxy_get_subscribed (GUPnPServiceProxy *proxy){ g_return_val_if_fail (GUPNP_IS_SERVICE_PROXY (proxy), FALSE); return proxy->priv->subscribed;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -