From e4bb8fb68f00d88f5362f278abb4cd2e326285f7 Mon Sep 17 00:00:00 2001 From: sam Date: Fri, 22 Jul 2005 21:11:26 +0000 Subject: split xmit of probe request frame out into a separate routine that takes explicit parameters; this will be needed when scanning is decoupled from the state machine to do bg scanning MFC after: 3 days --- sys/net80211/ieee80211_node.c | 15 ----- sys/net80211/ieee80211_output.c | 118 +++++++++++++++++++++++++++++----------- sys/net80211/ieee80211_proto.c | 7 ++- sys/net80211/ieee80211_proto.h | 6 ++ 4 files changed, 96 insertions(+), 50 deletions(-) (limited to 'sys') diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index a2fe867..29b8d99 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -335,22 +335,7 @@ ieee80211_next_scan(struct ieee80211com *ic) ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan), ieee80211_chan2ieee(ic, chan)); ieee80211_set_chan(ic, ic->ic_bss, chan); -#ifdef notyet - /* XXX driver state change */ - /* - * Scan next channel. If doing an active scan - * and the channel is not marked passive-only - * then send a probe request. Otherwise just - * listen for beacons on the channel. - */ - if ((ic->ic_flags & IEEE80211_F_ASCAN) && - (ni->ni_chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) { - IEEE80211_SEND_MGMT(ic, ni, - IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0); - } -#else ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); -#endif return 1; } } while (chan != ic->ic_bss->ni_chan); diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index d92603d..eb558a5 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -945,6 +945,91 @@ ieee80211_add_wme_param(u_int8_t *frm, struct ieee80211_wme_state *wme) #undef WME_OUI_BYTES /* + * Send a probe request frame with the specified ssid + * and any optional information element data. + */ +int +ieee80211_send_probereq(struct ieee80211_node *ni, + const u_int8_t sa[IEEE80211_ADDR_LEN], + const u_int8_t da[IEEE80211_ADDR_LEN], + const u_int8_t bssid[IEEE80211_ADDR_LEN], + const u_int8_t *ssid, size_t ssidlen, + const void *optie, size_t optielen) +{ + struct ieee80211com *ic = ni->ni_ic; + enum ieee80211_phymode mode; + struct ieee80211_frame *wh; + struct mbuf *m; + u_int8_t *frm; + + /* + * Hold a reference on the node so it doesn't go away until after + * the xmit is complete all the way in the driver. On error we + * will remove our reference. + */ + IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE, + "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", + __func__, __LINE__, + ni, ether_sprintf(ni->ni_macaddr), + ieee80211_node_refcnt(ni)+1); + ieee80211_ref_node(ni); + + /* + * prreq frame format + * [tlv] ssid + * [tlv] supported rates + * [tlv] extended supported rates + * [tlv] user-specified ie's + */ + m = ieee80211_getmgtframe(&frm, + 2 + IEEE80211_NWID_LEN + + 2 + IEEE80211_RATE_SIZE + + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + + (optie != NULL ? optielen : 0) + ); + if (m == NULL) { + ic->ic_stats.is_tx_nobuf++; + ieee80211_free_node(ni); + return ENOMEM; + } + + frm = ieee80211_add_ssid(frm, ssid, ssidlen); + mode = ieee80211_chan2mode(ic, ni->ni_chan); + frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]); + frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]); + + if (optie != NULL) { + memcpy(frm, optie, optielen); + frm += optielen; + } + m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *); + + M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT); + if (m == NULL) + return ENOMEM; + KASSERT(m->m_pkthdr.rcvif == NULL, ("rcvif not null")); + m->m_pkthdr.rcvif = (void *)ni; + + wh = mtod(m, struct ieee80211_frame *); + ieee80211_send_setup(ic, ni, wh, + IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ, + sa, da, bssid); + /* XXX power management? */ + + IEEE80211_NODE_STAT(ni, tx_probereq); + IEEE80211_NODE_STAT(ni, tx_mgmt); + + IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS, + "[%s] send probe req on channel %u\n", + ether_sprintf(wh->i_addr1), + ieee80211_chan2ieee(ic, ni->ni_chan)); + + IF_ENQUEUE(&ic->ic_mgtq, m); + if_start(ic->ic_ifp); + return 0; +} + +/* * Send a management frame. The node is for the destination (or ic_bss * when in station mode). Nodes other than ic_bss have their reference * count bumped to reflect our use for an indeterminant time. @@ -956,7 +1041,6 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni, #define senderr(_x, _v) do { ic->ic_stats._v++; ret = _x; goto bad; } while (0) struct mbuf *m; u_int8_t *frm; - enum ieee80211_phymode mode; u_int16_t capinfo; int has_challenge, is_shared_key, ret, timer, status; @@ -976,38 +1060,6 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni, timer = 0; switch (type) { - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - /* - * prreq frame format - * [tlv] ssid - * [tlv] supported rates - * [tlv] extended supported rates - * [tlv] user-specified ie's - */ - m = ieee80211_getmgtframe(&frm, - 2 + IEEE80211_NWID_LEN - + 2 + IEEE80211_RATE_SIZE - + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) - + (ic->ic_opt_ie != NULL ? ic->ic_opt_ie_len : 0) - ); - if (m == NULL) - senderr(ENOMEM, is_tx_nobuf); - - frm = ieee80211_add_ssid(frm, ic->ic_des_essid, ic->ic_des_esslen); - mode = ieee80211_chan2mode(ic, ni->ni_chan); - frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]); - frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]); - if (ic->ic_opt_ie != NULL) { - memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len); - frm += ic->ic_opt_ie_len; - } - m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *); - - IEEE80211_NODE_STAT(ni, tx_probereq); - if (ic->ic_opmode == IEEE80211_M_STA) - timer = IEEE80211_TRANS_WAIT; - break; - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: /* * probe response frame format diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 0288b0d..b76d576 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -923,8 +923,11 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg */ if ((ic->ic_flags & IEEE80211_F_ASCAN) && (ni->ni_chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) { - IEEE80211_SEND_MGMT(ic, ni, - IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0); + ieee80211_send_probereq(ni, + ic->ic_myaddr, ifp->if_broadcastaddr, + ifp->if_broadcastaddr, + ic->ic_des_essid, ic->ic_des_esslen, + ic->ic_opt_ie, ic->ic_opt_ie_len); } break; case IEEE80211_S_RUN: diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 6e14824..18a4211 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -64,6 +64,12 @@ int ieee80211_setup_rates(struct ieee80211_node *ni, void ieee80211_recv_mgmt(struct ieee80211com *, struct mbuf *, struct ieee80211_node *, int, int, u_int32_t); int ieee80211_send_nulldata(struct ieee80211_node *); +int ieee80211_send_probereq(struct ieee80211_node *ni, + const u_int8_t sa[IEEE80211_ADDR_LEN], + const u_int8_t da[IEEE80211_ADDR_LEN], + const u_int8_t bssid[IEEE80211_ADDR_LEN], + const u_int8_t *ssid, size_t ssidlen, + const void *optie, size_t optielen); int ieee80211_send_mgmt(struct ieee80211com *, struct ieee80211_node *, int, int); int ieee80211_classify(struct ieee80211com *, struct mbuf *, -- cgit v1.1