From: Jean Tourrilhes 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 Signed-off-by: Andrew Morton --- /dev/null | 0 25-akpm/include/net/irda/timer.h | 10 +++++---- 25-akpm/net/irda/irlap_event.c | 40 ++++++++++++++++++++++++++------------- 25-akpm/net/irda/timer.c | 21 +++++++++++++++++++- 4 files changed, 53 insertions(+), 18 deletions(-) diff -L include/net/irda/timer.d0.h -puN /dev/null /dev/null diff -puN include/net/irda/timer.h~irda-adaptive-discovery-query-timer include/net/irda/timer.h --- 25/include/net/irda/timer.h~irda-adaptive-discovery-query-timer Wed Oct 20 15:50:21 2004 +++ 25-akpm/include/net/irda/timer.h Wed Oct 20 15:50:21 2004 @@ -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(stru 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); diff -puN net/irda/irlap_event.c~irda-adaptive-discovery-query-timer net/irda/irlap_event.c --- 25/net/irda/irlap_event.c~irda-adaptive-discovery-query-timer Wed Oct 20 15:50:21 2004 +++ 25-akpm/net/irda/irlap_event.c Wed Oct 20 15:50:21 2004 @@ -433,10 +433,11 @@ static int irlap_state_ndm(struct irlap_ 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_ * 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 irla 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 irla 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; - - irlap_send_discovery_xid_frame(self, info->S, - self->slot, FALSE, - discovery_rsp); + } 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); + + 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); - self->frame_sent = TRUE; - irlap_next_state(self, LAP_REPLY); + /* Keep state */ + //irlap_next_state(self, LAP_REPLY); } break; default: diff -L net/irda/irlap_event.d0.c -puN /dev/null /dev/null diff -puN net/irda/timer.c~irda-adaptive-discovery-query-timer net/irda/timer.c --- 25/net/irda/timer.c~irda-adaptive-discovery-query-timer Wed Oct 20 15:50:21 2004 +++ 25-akpm/net/irda/timer.c Wed Oct 20 15:50:21 2004 @@ -34,6 +34,8 @@ #include #include +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 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); } diff -L net/irda/timer.d0.c -puN /dev/null /dev/null _