]> git.hungrycats.org Git - linux/commitdiff
[IRDA]: Adaptive discovery query timer
authorJean Tourrilhes <jt@bougret.hpl.hp.com>
Thu, 21 Oct 2004 15:09:38 +0000 (08:09 -0700)
committerDavid S. Miller <davem@nuts.davemloft.net>
Thu, 21 Oct 2004 15:09:38 +0000 (08:09 -0700)
o [FEATURE] Adapt to the rate of the peer discovery (passive discovery)
o [FEATURE] Add extra safety margin in passive discovery
Allow to interoperate properly with device performing slow discovery

Signed-off-by: Jean Tourrilhes <jt@hpl.hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/irda/timer.h
net/irda/irlap_event.c
net/irda/timer.c

index 9d24d6c033dc13c80a2f910d0aa2384c5f3e135f..2c5d8864ab775871f5520c94d9277572118ef007 100644 (file)
@@ -58,14 +58,16 @@ struct lap_cb;
  *  Slot timer must never exceed 85 ms, and must always be at least 25 ms, 
  *  suggested to  75-85 msec by IrDA lite. This doesn't work with a lot of
  *  devices, and other stackes uses a lot more, so it's best we do it as well
+ *  (Note : this is the default value and sysctl overides it - Jean II)
  */
 #define SLOT_TIMEOUT            (90*HZ/1000)
 
 /* 
- *  We set the query timeout to 100 ms and then expect the value to be 
- *  multiplied with the number of slots to product the actual timeout value
+ *  The latest discovery frame (XID) is longer due to the extra discovery
+ *  information (hints, device name...). This is its extra length.
+ *  We use that when setting the query timeout. Jean II
  */
-#define QUERY_TIMEOUT           (HZ/10)       
+#define XIDEXTRA_TIMEOUT        (34*HZ/1000)  /* 34 msec */
 
 #define WATCHDOG_TIMEOUT        (20*HZ)       /* 20 sec */
 
@@ -85,7 +87,7 @@ static inline void irda_start_timer(struct timer_list *ptimer, int timeout,
 
 
 void irlap_start_slot_timer(struct irlap_cb *self, int timeout);
-void irlap_start_query_timer(struct irlap_cb *self, int timeout);
+void irlap_start_query_timer(struct irlap_cb *self, int S, int s);
 void irlap_start_final_timer(struct irlap_cb *self, int timeout);
 void irlap_start_wd_timer(struct irlap_cb *self, int timeout);
 void irlap_start_backoff_timer(struct irlap_cb *self, int timeout);
index a58bb70d57fd6d62ebcfb737f045ada68d23a778..97ed757b844f476b2633a3aa7cd907be5ccecfcb 100644 (file)
@@ -433,10 +433,11 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
                                self->frame_sent = FALSE;
 
                        /*
-                        * Remember to multiply the query timeout value with
-                        * the number of slots used
+                        * Go to reply state until end of discovery to
+                        * inhibit our own transmissions. Set the timer
+                        * to not stay forever there... Jean II
                         */
-                       irlap_start_query_timer(self, QUERY_TIMEOUT*info->S);
+                       irlap_start_query_timer(self, info->S, info->s);
                        irlap_next_state(self, LAP_REPLY);
                } else {
                /* This is the final slot. How is it possible ?
@@ -452,6 +453,9 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
                 * Not much. It's too late to answer those discovery frames,
                 * so we just pass the info to IrLMP who will put it in the
                 * log (and post an event).
+                * Another cause would be devices that do discovery much
+                * slower than us, however the latest fixes should minimise
+                * those cases...
                 * Jean II
                 */
                        IRDA_DEBUG(1, "%s(), Receiving final discovery request, missed the discovery slots :-(\n", __FUNCTION__);
@@ -691,7 +695,7 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event,
 
        switch (event) {
        case QUERY_TIMER_EXPIRED:
-               IRDA_DEBUG(2, "%s(), QUERY_TIMER_EXPIRED <%ld>\n",
+               IRDA_DEBUG(0, "%s(), QUERY_TIMER_EXPIRED <%ld>\n",
                           __FUNCTION__, jiffies);
                irlap_next_state(self, LAP_NDM);
                break;
@@ -707,16 +711,26 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event,
                        irlap_next_state(self, LAP_NDM);
 
                        irlap_discovery_indication(self, info->discovery);
-               } else if ((info->s >= self->slot) && (!self->frame_sent)) {
-                       discovery_rsp = irlmp_get_discovery_response();
-                       discovery_rsp->data.daddr = info->daddr;
+               } else {
+                       /* If it's our slot, send our reply */
+                       if ((info->s >= self->slot) && (!self->frame_sent)) {
+                               discovery_rsp = irlmp_get_discovery_response();
+                               discovery_rsp->data.daddr = info->daddr;
 
-                       irlap_send_discovery_xid_frame(self, info->S,
-                                                      self->slot, FALSE,
-                                                      discovery_rsp);
+                               irlap_send_discovery_xid_frame(self, info->S,
+                                                              self->slot,
+                                                              FALSE,
+                                                              discovery_rsp);
 
-                       self->frame_sent = TRUE;
-                       irlap_next_state(self, LAP_REPLY);
+                               self->frame_sent = TRUE;
+                       }
+                       /* Readjust our timer to accomodate devices
+                        * doing faster or slower discovery than us...
+                        * Jean II */
+                       irlap_start_query_timer(self, info->S, info->s);
+
+                       /* Keep state */
+                       //irlap_next_state(self, LAP_REPLY);
                }
                break;
        default:
index f05b94250ffa6112253657a56fc948c6aacd1182..0b2811834fa33ac67bd291a99ab06a9732bd78cf 100644 (file)
@@ -34,6 +34,8 @@
 #include <net/irda/irlap.h>
 #include <net/irda/irlmp.h>
 
+extern int  sysctl_slot_timeout;
+
 static void irlap_slot_timer_expired(void* data);
 static void irlap_query_timer_expired(void* data);
 static void irlap_final_timer_expired(void* data);
@@ -47,8 +49,25 @@ void irlap_start_slot_timer(struct irlap_cb *self, int timeout)
                         irlap_slot_timer_expired);
 }
 
-void irlap_start_query_timer(struct irlap_cb *self, int timeout)
+void irlap_start_query_timer(struct irlap_cb *self, int S, int s)
 {
+       int timeout;
+
+       /* Calculate when the peer discovery should end. Normally, we
+        * get the end-of-discovery frame, so this is just in case
+        * we miss it.
+        * Basically, we multiply the number of remaining slots by our
+        * slot time, plus add some extra time to properly receive the last
+        * discovery packet (which is longer due to extra discovery info),
+        * to avoid messing with for incomming connections requests and
+        * to accomodate devices that perform discovery slower than us.
+        * Jean II */
+       timeout = ((sysctl_slot_timeout * HZ / 1000) * (S - s)
+                  + XIDEXTRA_TIMEOUT + SMALLBUSY_TIMEOUT);
+
+       /* Set or re-set the timer. We reset the timer for each received
+        * discovery query, which allow us to automatically adjust to
+        * the speed of the peer discovery (faster or slower). Jean II */
        irda_start_timer( &self->query_timer, timeout, (void *) self, 
                          irlap_query_timer_expired);
 }