Re: [PATCH 2/2] Send alive/byebye announcements three times.



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]