diff options
author | Jens Georg <mail@jensge.org> | 2019-01-28 22:04:16 +0100 |
---|---|---|
committer | Jens Georg <mail@jensge.org> | 2019-01-28 22:04:39 +0100 |
commit | 7c8675e065019016946c4b84115072a19ca8820b (patch) | |
tree | 32674b1cd6f6c8b3e5c32c7622a5e60d92cbc34d | |
parent | ed5a017c5ed26a3c887c0d100ee0239dec563ade (diff) | |
download | gssdp-7c8675e065019016946c4b84115072a19ca8820b.tar.gz |
resource-browser: Implement ssdp:update handling
-rw-r--r-- | libgssdp/gssdp-resource-browser.c | 89 | ||||
-rw-r--r-- | libgssdp/gssdp-resource-browser.h | 7 |
2 files changed, 95 insertions, 1 deletions
diff --git a/libgssdp/gssdp-resource-browser.c b/libgssdp/gssdp-resource-browser.c index ebe501a..1b3966c 100644 --- a/libgssdp/gssdp-resource-browser.c +++ b/libgssdp/gssdp-resource-browser.c @@ -85,6 +85,7 @@ enum { enum { RESOURCE_AVAILABLE, RESOURCE_UNAVAILABLE, + RESOURCE_UPDATE, LAST_SIGNAL }; @@ -384,6 +385,30 @@ gssdp_resource_browser_class_init (GSSDPResourceBrowserClass *klass) G_TYPE_NONE, 1, G_TYPE_STRING); + + /** + * GSSDPResourceBrowser::resource-update: + * @resource_browser: The #GSSDPResourceBrowser that received the + * signal + * @usn: The USN of the resource + * @boot_id: The current boot-id + * @next_boot_id : The next boot-id + * + * The ::resource-update signal is emitted whenever an UPnP 1.1 + * device is about to change it's BOOTID. + **/ + signals[RESOURCE_UPDATE] = + g_signal_new ("resource-update", + GSSDP_TYPE_RESOURCE_BROWSER, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GSSDPResourceBrowserClass, + resource_update), + NULL, NULL, NULL, + G_TYPE_NONE, + 3, + G_TYPE_STRING, + G_TYPE_UINT, + G_TYPE_UINT); } /** @@ -910,6 +935,66 @@ resource_available (GSSDPResourceBrowser *resource_browser, } static void +resource_update (GSSDPResourceBrowser *resource_browser, + SoupMessageHeaders *headers) +{ + GSSDPResourceBrowserPrivate *priv; + const char *usn; + const char *boot_id_header; + const char *next_boot_id_header; + char *canonical_usn; + guint boot_id; + guint next_boot_id; + gint64 out; + + priv = gssdp_resource_browser_get_instance_private (resource_browser); + usn = soup_message_headers_get_one (headers, "USN"); + boot_id_header = soup_message_headers_get_one (headers, "BOOTID.UPNP.ORG"); + next_boot_id_header = soup_message_headers_get_one (headers, "NEXTBOOTID.UPNP.ORG"); + + if (!usn) + return; /* No USN specified */ + + if (!boot_id_header) + return; + + if (!next_boot_id_header) + return; + + if (!g_ascii_string_to_signed (boot_id_header, 10, 0, G_MAXINT32, &out, NULL)) + return; + boot_id = out; + + if (!g_ascii_string_to_signed (next_boot_id_header, 10, 0, G_MAXINT32, &out, NULL)) + return; + next_boot_id = out; + + if (priv->version > 0) { + char *version; + version = g_strrstr (usn, ":"); + canonical_usn = g_strndup (usn, version - usn); + } else { + canonical_usn = g_strdup (usn); + } + + /* Only continue if we know about this. if not, there will be an + * announcement afterwards anyway */ + if (!g_hash_table_lookup (priv->resources, + canonical_usn)) + goto out; + + g_signal_emit (resource_browser, + signals[RESOURCE_UPDATE], + 0, + usn, + boot_id, + next_boot_id); +out: + g_free (canonical_usn); + +} + +static void resource_unavailable (GSSDPResourceBrowser *resource_browser, SoupMessageHeaders *headers) { @@ -1037,6 +1122,10 @@ received_announcement (GSSDPResourceBrowser *resource_browser, SSDP_BYEBYE_NTS, strlen (SSDP_BYEBYE_NTS)) == 0) resource_unavailable (resource_browser, headers); + else if (strncmp (header, + SSDP_UPDATE_NTS, + strlen (SSDP_UPDATE_NTS)) == 0) + resource_update (resource_browser, headers); } /* diff --git a/libgssdp/gssdp-resource-browser.h b/libgssdp/gssdp-resource-browser.h index 78a646b..f04c429 100644 --- a/libgssdp/gssdp-resource-browser.h +++ b/libgssdp/gssdp-resource-browser.h @@ -43,7 +43,12 @@ struct _GSSDPResourceBrowserClass { void (* resource_available) (GSSDPResourceBrowser *resource_browser, const char *usn, const GList *locations); - + + void (* resource_update) (GSSDPResourceBrowser *resource_browser, + const char *usn, + guint boot_id, + guint next_boot_id); + void (* resource_unavailable) (GSSDPResourceBrowser *resource_browser, const char *usn); |