tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

RE: detecting loss of access point (link status monitoring fix?)



> That sounds like it will work.  The idea of a driver using the
net80211
> stats in that way doesn't sit well, but I cannot think of a better
> solution that is also as parsimonious.
> 
> Dave
> 
> --
> David Young             OJC Technologies
> dyoung%ojctech.com@localhost      Urbana, IL * (217) 278-3933

Hello Dave, 

I agree, using the stats in such was way didn't seem right, so I came up
with another approach to detecting an AP disconnect. Now I pass in a
timestamp to the ieee80211_input function via the currently unused
rstamp parameter. This in turn populates the ni_rstamp iee80211node
structure member with the last received timestamp.  

In the link monitor, if this timestamp isn't updated, as it should with
every incoming packet, and the timestamp is the same as it was last time
the link monitor ran the connection is considered stale and a scan is
initiated. 

The change is below. This seems like an improvement over using the stats
counter, any thoughts?


Regards, 
Eric

Index: if_rum.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_rum.c,v
retrieving revision 1.23
diff -u -r1.23 if_rum.c
--- if_rum.c    21 Oct 2008 12:21:46 -0000      1.23
+++ if_rum.c    27 Apr 2010 17:53:42 -0000
@@ -38,6 +38,7 @@
 #include <sys/malloc.h>
 #include <sys/conf.h>
 #include <sys/device.h>
+#include <sys/time.h>
 
 #include <sys/bus.h>
 #include <machine/endian.h>
@@ -203,6 +204,7 @@
 Static void            rum_amrr_timeout(void *);
 Static void            rum_amrr_update(usbd_xfer_handle,
usbd_private_handle,
                            usbd_status status);
+Static void            rum_linkmon(void *);
 
 /*
  * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
@@ -360,6 +362,7 @@
        sc->amrr.amrr_min_success_threshold =  1;
        sc->amrr.amrr_max_success_threshold = 10;
        usb_callout_init(sc->sc_amrr_ch);
+       usb_callout_init(sc->sc_link_mon);
 
        /* retrieve RT2573 rev. no */
        for (ntries = 0; ntries < 1000; ntries++) {
@@ -491,6 +494,7 @@
        usb_rem_task(sc->sc_udev, &sc->sc_task);
        usb_uncallout(sc->sc_scan_ch, rum_next_scan, sc);
        usb_uncallout(sc->sc_amrr_ch, rum_amrr_timeout, sc);
+       usb_uncallout(sc->sc_link_mon, rum_linkmon, sc);
 
        if (sc->amrr_xfer != NULL) {
                usbd_free_xfer(sc->amrr_xfer);
@@ -745,6 +749,7 @@
                                rum_amrr_start(sc, ni);
                }
 
+               usb_callout(sc->sc_link_mon, hz*3, rum_linkmon, sc);
                break;
        }
 
@@ -759,6 +764,7 @@
        usb_rem_task(sc->sc_udev, &sc->sc_task);
        usb_uncallout(sc->sc_scan_ch, rum_next_scan, sc);
        usb_uncallout(sc->sc_amrr_ch, rum_amrr_timeout, sc);
+       usb_uncallout(sc->sc_link_mon, rum_linkmon, NULL);
 
        /* do it in a process context */
        sc->sc_state = nstate;
@@ -823,6 +829,7 @@
        struct ieee80211_frame *wh;
        struct ieee80211_node *ni;
        struct mbuf *mnew, *m;
+       struct timeval tstamp;
        int s, len;
 
        if (status != USBD_NORMAL_COMPLETION) {
@@ -902,7 +909,8 @@
        ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min
*)wh);
 
        /* send the frame to the 802.11 layer */
-       ieee80211_input(ic, m, ni, desc->rssi, 0);
+       microtime(&tstamp);     
+       ieee80211_input(ic, m, ni, desc->rssi, tstamp.tv_sec);
 
        /* node is no longer needed */
        ieee80211_free_node(ni);
@@ -2286,3 +2294,23 @@
 
        return 0;
 }
+
+static int last_rx_tstamp = 0;
+static int rx_tstamp_init = 0;
+void rum_linkmon(void *arg) 
+{
+       struct rum_softc *sc = arg;
+       struct ieee80211com *ic = &sc->sc_ic;
+
+       if ((rx_tstamp_init) && (ic->ic_bss->ni_rstamp ==
last_rx_tstamp)) {
+               DPRINTF(("Current AP stale: initiating scan\n"));
+               ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+       }
+
+       rx_tstamp_init = 1;
+       last_rx_tstamp = ic->ic_bss->ni_rstamp;
+
+       if (sc->sc_ic.ic_state == IEEE80211_S_RUN) {
+               usb_callout(sc->sc_link_mon, hz*3, rum_linkmon, sc);
+       }
+}
Index: if_rumvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_rumvar.h,v
retrieving revision 1.4
diff -u -r1.4 if_rumvar.h
--- if_rumvar.h 25 Nov 2007 09:30:10 -0000      1.4
+++ if_rumvar.h 27 Apr 2010 17:53:42 -0000
@@ -110,6 +110,7 @@
 
        usb_callout_t                   sc_scan_ch;
        usb_callout_t                   sc_amrr_ch;
+       usb_callout_t                   sc_link_mon;
 
        int                             sc_tx_timer;



Home | Main Index | Thread Index | Old Index