When we receive an AUTH or ASSOC event even though we have already
authorpatrick <patrick@openbsd.org>
Fri, 5 Jan 2018 19:06:37 +0000 (19:06 +0000)
committerpatrick <patrick@openbsd.org>
Fri, 5 Jan 2018 19:06:37 +0000 (19:06 +0000)
reached the RUN state, this probably means that we have roamed to
a different AP.  In that case throw us back into SCAN mode and let
the stack look for a new AP to connect to.  In the future it might
be worthwhile to use the ROAM event information to read the new AP
information to adjust our stack, but that is further down the road.

sys/dev/ic/bwfm.c

index 400f064..b140486 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwfm.c,v 1.25 2018/01/04 23:34:06 patrick Exp $ */
+/* $OpenBSD: bwfm.c,v 1.26 2018/01/05 19:06:37 patrick Exp $ */
 /*
  * Copyright (c) 2010-2016 Broadcom Corporation
  * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
@@ -346,6 +346,8 @@ bwfm_init(struct ifnet *ifp)
        evmask[BWFM_E_LINK / 8] |= 1 << (BWFM_E_LINK % 8);
        evmask[BWFM_E_AUTH / 8] |= 1 << (BWFM_E_AUTH % 8);
        evmask[BWFM_E_ASSOC / 8] |= 1 << (BWFM_E_ASSOC % 8);
+       evmask[BWFM_E_DEAUTH / 8] |= 1 << (BWFM_E_DEAUTH % 8);
+       evmask[BWFM_E_DISASSOC / 8] |= 1 << (BWFM_E_DISASSOC % 8);
        evmask[BWFM_E_SET_SSID / 8] |= 1 << (BWFM_E_SET_SSID % 8);
        evmask[BWFM_E_ESCAN_RESULT / 8] |= 1 << (BWFM_E_ESCAN_RESULT % 8);
        if (bwfm_fwvar_var_set_data(sc, "event_msgs", evmask, sizeof(evmask))) {
@@ -1472,17 +1474,23 @@ bwfm_rx_event(struct bwfm_softc *sc, char *buf, size_t len)
                        ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                break;
        case BWFM_E_AUTH:
-               if (ntohl(e->msg.status) == BWFM_E_STATUS_SUCCESS)
+               if (ntohl(e->msg.status) == BWFM_E_STATUS_SUCCESS &&
+                   ic->ic_state == IEEE80211_S_AUTH)
                        ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
                else
                        ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                break;
        case BWFM_E_ASSOC:
-               if (ntohl(e->msg.status) == BWFM_E_STATUS_SUCCESS)
+               if (ntohl(e->msg.status) == BWFM_E_STATUS_SUCCESS &&
+                   ic->ic_state == IEEE80211_S_ASSOC)
                        ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
                else
                        ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                break;
+       case BWFM_E_DEAUTH:
+       case BWFM_E_DISASSOC:
+               ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+               break;
        case BWFM_E_LINK:
                if (ntohl(e->msg.status) == BWFM_E_STATUS_SUCCESS &&
                    ntohl(e->msg.reason) == 0)