diff options
author | sam <sam@FreeBSD.org> | 2003-07-20 21:36:08 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2003-07-20 21:36:08 +0000 |
commit | 51c8bf1aebf18e644d2c3354aa5e0e5048baab1e (patch) | |
tree | 6b4b08b659abfee0261b08146037555ec5351239 /sys/net80211 | |
parent | 6d201c6f71fac3e288a6c52e28186f84237bdb36 (diff) | |
download | FreeBSD-src-51c8bf1aebf18e644d2c3354aa5e0e5048baab1e.zip FreeBSD-src-51c8bf1aebf18e644d2c3354aa5e0e5048baab1e.tar.gz |
o change ieee80211_new_state handling to use a proper method that drivers
override in their sub-class; this eliminates the hack of interpreting the
EINPROGRESS return value to mean "don't do any of the normal work"
o correct active scanning so the first channel is only scanned once and so
per-channel passive mode is properly honored
o expose 802.11 FSM state names so every driver doesn't keep a private copy
o eliminate node parameter to ieee80211_begin_scan; it was not being used
Diffstat (limited to 'sys/net80211')
-rw-r--r-- | sys/net80211/ieee80211.c | 2 | ||||
-rw-r--r-- | sys/net80211/ieee80211_input.c | 16 | ||||
-rw-r--r-- | sys/net80211/ieee80211_ioctl.c | 4 | ||||
-rw-r--r-- | sys/net80211/ieee80211_node.c | 42 | ||||
-rw-r--r-- | sys/net80211/ieee80211_node.h | 3 | ||||
-rw-r--r-- | sys/net80211/ieee80211_proto.c | 41 | ||||
-rw-r--r-- | sys/net80211/ieee80211_proto.h | 16 | ||||
-rw-r--r-- | sys/net80211/ieee80211_var.h | 3 |
8 files changed, 70 insertions, 57 deletions
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index 1e0db22..de56d17 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -558,7 +558,7 @@ ieee80211_watchdog(struct ifnet *ifp) struct ieee80211com *ic = (void *)ifp; if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0) - ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1); + ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); if (ic->ic_inact_timer && --ic->ic_inact_timer == 0) ieee80211_timeout_nodes(ic); diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 2777ac9..dc4f462 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -592,7 +592,11 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, } IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE); IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); - if (chan > IEEE80211_CHAN_MAX || isclr(ic->ic_chan_active, chan)) { + if ( +#if IEEE80211_CHAN_MAX < 255 + chan > IEEE80211_CHAN_MAX || +#endif + isclr(ic->ic_chan_active, chan)) { IEEE80211_DPRINTF(("%s: ignore %s with invalid channel " "%u\n", __func__, ISPROBE(subtype) ? "probe response" : "beacon", @@ -775,7 +779,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, case IEEE80211_M_IBSS: if (ic->ic_state != IEEE80211_S_RUN || seq != 1) return; - ieee80211_new_state(&ic->ic_if, IEEE80211_S_AUTH, + ieee80211_new_state(ic, IEEE80211_S_AUTH, wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); break; @@ -822,7 +826,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, } return; } - ieee80211_new_state(&ic->ic_if, IEEE80211_S_ASSOC, + ieee80211_new_state(ic, IEEE80211_S_ASSOC, wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); break; } @@ -1011,7 +1015,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); if (ni->ni_rates.rs_nrates != 0) - ieee80211_new_state(ifp, IEEE80211_S_RUN, + ieee80211_new_state(ic, IEEE80211_S_RUN, wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); break; } @@ -1026,7 +1030,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, reason = le16toh(*(u_int16_t *)frm); switch (ic->ic_opmode) { case IEEE80211_M_STA: - ieee80211_new_state(&ic->ic_if, IEEE80211_S_AUTH, + ieee80211_new_state(ic, IEEE80211_S_AUTH, wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); break; case IEEE80211_M_HOSTAP: @@ -1055,7 +1059,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, reason = le16toh(*(u_int16_t *)frm); switch (ic->ic_opmode) { case IEEE80211_M_STA: - ieee80211_new_state(&ic->ic_if, IEEE80211_S_ASSOC, + ieee80211_new_state(ic, IEEE80211_S_ASSOC, wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); break; case IEEE80211_M_HOSTAP: diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index 46c015c..4ae0401 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -659,7 +659,7 @@ ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data) if (ic->ic_opmode == IEEE80211_M_HOSTAP) break; /* NB: ignore channel list and tx rate parameters */ - error = ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1); + error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); break; case WI_RID_SCAN_APS: if (ic->ic_opmode == IEEE80211_M_HOSTAP) @@ -703,7 +703,7 @@ ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data) if (wreq.wi_type == WI_RID_CHANNEL_LIST) error = ENETRESET; else - error = ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1); + error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); break; default: error = EINVAL; diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 9176ea7..a05c838 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -110,42 +110,48 @@ ieee80211_node_detach(struct ifnet *ifp) * Initialize the active channel set based on the set * of available channels and the current PHY mode. */ -void +static void ieee80211_reset_scan(struct ifnet *ifp) { struct ieee80211com *ic = (void *)ifp; memcpy(ic->ic_chan_scan, ic->ic_chan_active, sizeof(ic->ic_chan_active)); + /* NB: hack, setup so next_scan starts with the first channel */ + if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC) + ic->ic_bss->ni_chan = &ic->ic_channels[IEEE80211_CHAN_MAX]; } /* * Begin an active scan. */ void -ieee80211_begin_scan(struct ifnet *ifp, struct ieee80211_node *ni) +ieee80211_begin_scan(struct ifnet *ifp) { struct ieee80211com *ic = (void *)ifp; + /* + * In all but hostap mode scanning starts off in + * an active mode before switching to passive. + */ + if (ic->ic_opmode != IEEE80211_M_HOSTAP) + ic->ic_flags |= IEEE80211_F_ASCAN; if (ifp->if_flags & IFF_DEBUG) if_printf(ifp, "begin %s scan\n", - ic->ic_opmode != IEEE80211_M_HOSTAP ? + (ic->ic_flags & IEEE80211_F_ASCAN) ? "active" : "passive"); - - ieee80211_reset_scan(ifp); /* - * Flush any previously seen AP's. Note that this - * assumes we don't act as both an AP and a station, - * otherwise we'll potentially flush state of stations - * associated with us. + * Clear scan state and flush any previously seen + * AP's. Note that the latter assumes we don't act + * as both an AP and a station, otherwise we'll + * potentially flush state of stations associated + * with us. */ + ieee80211_reset_scan(ifp); ieee80211_free_allnodes(ic); - clrbit(ic->ic_chan_scan, ieee80211_chan2ieee(ic, ni->ni_chan)); - if (ic->ic_opmode != IEEE80211_M_HOSTAP) { - ic->ic_flags |= IEEE80211_F_ASCAN; - IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0); - } + /* Scan the next channel. */ + ieee80211_next_scan(ifp); } /* @@ -180,7 +186,7 @@ ieee80211_next_scan(struct ifnet *ifp) ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan), ieee80211_chan2ieee(ic, chan))); ic->ic_bss->ni_chan = chan; - ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1); + ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); } void @@ -213,7 +219,7 @@ ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan) ni->ni_fhdwell = 200; /* XXX */ ni->ni_fhindex = 1; } - ieee80211_new_state(ifp, IEEE80211_S_RUN, -1); + ieee80211_new_state(ic, IEEE80211_S_RUN, -1); } /* @@ -368,10 +374,10 @@ ieee80211_end_scan(struct ifnet *ifp) goto notfound; } ieee80211_unref_node(&selbs); - ieee80211_new_state(ifp, IEEE80211_S_RUN, -1); + ieee80211_new_state(ic, IEEE80211_S_RUN, -1); } else { ieee80211_unref_node(&selbs); - ieee80211_new_state(ifp, IEEE80211_S_AUTH, -1); + ieee80211_new_state(ic, IEEE80211_S_AUTH, -1); } } diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index 9085d47..49993b9 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -123,8 +123,7 @@ struct ieee80211com; extern void ieee80211_node_attach(struct ifnet *); extern void ieee80211_node_detach(struct ifnet *); -extern void ieee80211_reset_scan(struct ifnet *); -extern void ieee80211_begin_scan(struct ifnet *, struct ieee80211_node *); +extern void ieee80211_begin_scan(struct ifnet *); extern void ieee80211_next_scan(struct ifnet *); extern void ieee80211_end_scan(struct ifnet *); extern struct ieee80211_node *ieee80211_alloc_node(struct ieee80211com *, diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 7445dae..5520597 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -78,6 +78,15 @@ const char *ieee80211_mgt_subtype_name[] = { "beacon", "atim", "disassoc", "auth", "deauth", "reserved#13", "reserved#14", "reserved#15" }; +const char *ieee80211_state_name[IEEE80211_S_MAX] = { + "INIT", /* IEEE80211_S_INIT */ + "SCAN", /* IEEE80211_S_SCAN */ + "AUTH", /* IEEE80211_S_AUTH */ + "ASSOC", /* IEEE80211_S_ASSOC */ + "RUN" /* IEEE80211_S_RUN */ +}; + +static int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int); void ieee80211_proto_attach(struct ifnet *ifp) @@ -96,6 +105,9 @@ ieee80211_proto_attach(struct ifnet *ifp) mtx_init(&ic->ic_mgtq.ifq_mtx, ifp->if_name, "mgmt send q", MTX_DEF); + /* protocol state change handler */ + ic->ic_newstate = ieee80211_newstate; + /* initialize management frame handlers */ ic->ic_recv_mgmt = ieee80211_recv_mgmt; ic->ic_send_mgmt = ieee80211_send_mgmt; @@ -275,30 +287,17 @@ ieee80211_fix_rate(struct ieee80211com *ic, struct ieee80211_node *ni, int flags #undef RV } -int -ieee80211_new_state(struct ifnet *ifp, enum ieee80211_state nstate, int mgt) +static int +ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int mgt) { - struct ieee80211com *ic = (void *)ifp; + struct ifnet *ifp = &ic->ic_if; struct ieee80211_node *ni; - int error, ostate; -#ifdef IEEE80211_DEBUG - static const char *stname[] = - { "INIT", "SCAN", "AUTH", "ASSOC", "RUN" }; -#endif + enum ieee80211_state ostate; ostate = ic->ic_state; IEEE80211_DPRINTF(("%s: %s -> %s\n", __func__, - stname[ostate], stname[nstate])); - if (ic->ic_newstate) { - error = (*ic->ic_newstate)(ic->ic_softc, nstate); - if (error == EINPROGRESS) - return 0; - if (error != 0) - return error; - } - - /* state transition */ - ic->ic_state = nstate; + ieee80211_state_name[ostate], ieee80211_state_name[nstate])); + ic->ic_state = nstate; /* state transition */ ni = ic->ic_bss; /* NB: no reference held */ switch (nstate) { case IEEE80211_S_INIT: @@ -378,7 +377,7 @@ ieee80211_new_state(struct ifnet *ifp, enum ieee80211_state nstate, int mgt) */ ieee80211_create_ibss(ic, ic->ic_des_chan); } else { - ieee80211_begin_scan(ifp, ni); + ieee80211_begin_scan(ifp); } break; case IEEE80211_S_SCAN: @@ -406,7 +405,7 @@ ieee80211_new_state(struct ifnet *ifp, enum ieee80211_state nstate, int mgt) ni->ni_fails++; ieee80211_unref_node(&ni); } - ieee80211_begin_scan(ifp, ic->ic_bss); + ieee80211_begin_scan(ifp); break; } break; diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 490e4ac..81627ff 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -39,12 +39,13 @@ */ enum ieee80211_state { - IEEE80211_S_INIT, /* default state */ - IEEE80211_S_SCAN, /* scanning */ - IEEE80211_S_AUTH, /* try to authenticate */ - IEEE80211_S_ASSOC, /* try to assoc */ - IEEE80211_S_RUN /* associated */ + IEEE80211_S_INIT = 0, /* default state */ + IEEE80211_S_SCAN = 1, /* scanning */ + IEEE80211_S_AUTH = 2, /* try to authenticate */ + IEEE80211_S_ASSOC = 3, /* try to assoc */ + IEEE80211_S_RUN = 4, /* associated */ }; +#define IEEE80211_S_MAX (IEEE80211_S_RUN+1) #define IEEE80211_SEND_MGMT(_ic,_ni,_type,_arg) \ ((*(_ic)->ic_send_mgmt)(_ic, _ni, _type, _arg)) @@ -66,9 +67,12 @@ extern struct mbuf *ieee80211_encap(struct ifnet *, struct mbuf *); extern struct mbuf *ieee80211_decap(struct ifnet *, struct mbuf *); extern u_int8_t *ieee80211_add_rates(u_int8_t *frm, const struct ieee80211_rateset *); +#define ieee80211_new_state(_ic, _nstate, _arg) \ + (((_ic)->ic_newstate)((_ic), (_nstate), (_arg))) extern u_int8_t *ieee80211_add_xrates(u_int8_t *frm, const struct ieee80211_rateset *); -extern int ieee80211_new_state(struct ifnet *, enum ieee80211_state, int); extern void ieee80211_print_essid(u_int8_t *, int); extern void ieee80211_dump_pkt(u_int8_t *, int, int, int); + +extern const char *ieee80211_state_name[IEEE80211_S_MAX]; #endif /* _NET80211_IEEE80211_PROTO_H_ */ diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 6956c37..2b2f0b0 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -137,7 +137,8 @@ struct ieee80211com { struct mbuf *, int, int, u_int32_t, u_int); int (*ic_send_mgmt)(struct ieee80211com *, struct ieee80211_node *, int, int); - int (*ic_newstate)(void *, enum ieee80211_state); + int (*ic_newstate)(struct ieee80211com *, + enum ieee80211_state, int); void (*ic_newassoc)(struct ieee80211com *, struct ieee80211_node *, int); u_int8_t ic_myaddr[IEEE80211_ADDR_LEN]; |