Re: [PATCH 2/2] Send alive/byebye announcements three times.
- From: Sven Neumann <s neumann raumfeld com>
- To: Jens Georg <mail jensge org>
- Cc: gupnp-list gnome org
- Subject: Re: [PATCH 2/2] Send alive/byebye announcements three times.
- Date: Wed, 15 Jun 2011 09:18:25 +0200
On Tue, 2011-06-14 at 09:00 +0200, Jens Georg wrote:
> On Di, 2011-06-14 at 08:57 +0200, Jens Georg wrote:
> > UPnP recommends to send the whole batch of announcements more than
> > once "due to the unreliable nature of UDP".
>
> Since I have a really unreliable wireless and do have problems with not
> seeing announcements due to packet loss, I think it's a good thing to
> have.
We've been using a patch for quite a while that does something similar.
I believe though that it is closer to what the spec suggests as it
actually delays the duplicate advertisement sets a little.
You will find the patch attached to this mail. Sorry for not suggesting
this change earlier. I totally missed that I never submitted this patch
before.
Regards,
Sven
--
Sven Neumann
Head of RAUMFELD Software Development
Lautsprecher Teufel GmbH | Bülowstr. 66 | 10783 Berlin | Germany
Tel: +49 (0)30-300 930 153 | s neumann raumfeld com
--- gssdp-0.6.4-orig/libgssdp/gssdp-resource-group.c 2009-01-06 15:44:15.000000000 +0100
+++ gssdp-0.6.4/libgssdp/gssdp-resource-group.c 2010-02-09 12:07:24.000000000 +0100
@@ -35,6 +35,14 @@
#include <libsoup/soup.h>
+/* UPnP devices must send each advertisment set more than once on a
+ * single network interface. It is recommended that UPnP devices send
+ * a total of 2 or three advertisement sets within a 10 second
+ * transmission window.
+ */
+#define NUM_DUPLICATE_ADVERTISEMENT_SETS 2
+#define DUPLICATE_ADVERTISEMENT_TIMEOUT 4 /* in seconds */
+
#include "gssdp-resource-group.h"
#include "gssdp-resource-browser.h"
#include "gssdp-client-private.h"
@@ -56,6 +64,8 @@
gulong message_received_id;
GSource *timeout_src;
+ GSource *duplicate_src;
+ guint duplicates_sent;
guint last_resource_id;
@@ -103,6 +113,8 @@
GSSDPClient *client);
static gboolean
resource_group_timeout (gpointer user_data);
+static gboolean
+resource_group_duplicate_timeout(gpointer user_data);
static void
message_received_cb (GSSDPClient *client,
const char *from_ip,
@@ -243,6 +255,11 @@
priv->message_src_id = 0;
}
+ if (priv->duplicate_src) {
+ g_source_destroy (priv->duplicate_src);
+ priv->duplicate_src = NULL;
+ }
+
if (priv->timeout_src) {
g_source_destroy (priv->timeout_src);
priv->timeout_src = NULL;
@@ -515,14 +532,19 @@
g_source_unref (resource_group->priv->timeout_src);
- /* Announce all resources */
- for (l = resource_group->priv->resources; l; l = l->next)
- resource_alive (l->data);
+ /* Call the callback to announce all resources */
+ resource_group_timeout (resource_group);
} else {
/* Unannounce all resources */
for (l = resource_group->priv->resources; l; l = l->next)
resource_byebye (l->data);
+ /* Remove duplicate advertisment timer */
+ if (resource_group->priv->duplicate_src) {
+ g_source_destroy (resource_group->priv->duplicate_src);
+ resource_group->priv->duplicate_src = NULL;
+ }
+
/* Remove re-announcement timer */
g_source_destroy (resource_group->priv->timeout_src);
resource_group->priv->timeout_src = NULL;
@@ -676,6 +698,29 @@
}
/**
+ * Called to send duplicates of the ssdp:alive messages
+ **/
+static gboolean
+resource_group_duplicate_timeout (gpointer user_data)
+{
+ GSSDPResourceGroup *resource_group;
+ GList *l;
+
+ resource_group = GSSDP_RESOURCE_GROUP (user_data);
+
+ /* Re-announce all resources */
+ for (l = resource_group->priv->resources; l; l = l->next)
+ resource_alive (l->data);
+
+ if (++resource_group->priv->duplicates_sent == NUM_DUPLICATE_ADVERTISEMENT_SETS) {
+ resource_group->priv->duplicate_src = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
* Called to re-announce all resources periodically
**/
static gboolean
@@ -690,6 +735,29 @@
for (l = resource_group->priv->resources; l; l = l->next)
resource_alive (l->data);
+ /* Remove duplicate timer before installing a new one */
+ if (resource_group->priv->duplicate_src) {
+ g_source_destroy (resource_group->priv->duplicate_src);
+ resource_group->priv->duplicate_src = NULL;
+ }
+
+ /* Add timer for advertisement duplicates */
+ if (NUM_DUPLICATE_ADVERTISEMENT_SETS) {
+ GSSDPClient *client = resource_group->priv->client;
+ GMainContext *context = gssdp_client_get_main_context (client);
+
+ resource_group->priv->duplicates_sent = 0;
+ resource_group->priv->duplicate_src =
+ g_timeout_source_new_seconds (DUPLICATE_ADVERTISEMENT_TIMEOUT);
+ g_source_set_callback (resource_group->priv->duplicate_src,
+ resource_group_duplicate_timeout,
+ resource_group, NULL);
+
+ g_source_attach (resource_group->priv->duplicate_src,
+ context);
+ g_source_unref (resource_group->priv->duplicate_src);
+ }
+
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]