Date: Thu, 2 Dec 2004 03:23:31 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 66236 for review Message-ID: <200412020323.iB23NVcF040023@repoman.freebsd.org>
index | next in thread | raw e-mail
http://perforce.freebsd.org/chv.cgi?CH=66236 Change 66236 by sam@sam_ebb on 2004/12/02 03:22:43 replace direct walking of the station/scan tables with ieee80211_iterate_nodes Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#21 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#21 (text+ko) ==== @@ -78,6 +78,110 @@ * with wicontrol(8). */ +struct wi_read_ap_args { + int i; /* result count */ + struct wi_apinfo *ap; /* current entry in result buffer */ + caddr_t max; /* result buffer bound */ +}; + +static void +wi_read_ap_result(void *arg, struct ieee80211_node *ni) +{ + struct ieee80211com *ic = ni->ni_ic; + struct wi_read_ap_args *sa = arg; + struct wi_apinfo *ap = sa->ap; + struct ieee80211_rateset *rs; + int j; + + if ((caddr_t)(ap + 1) > sa->max) + return; + memset(ap, 0, sizeof(struct wi_apinfo)); + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + IEEE80211_ADDR_COPY(ap->bssid, ni->ni_macaddr); + ap->namelen = ic->ic_des_esslen; + if (ic->ic_des_esslen) + memcpy(ap->name, ic->ic_des_essid, + ic->ic_des_esslen); + } else { + IEEE80211_ADDR_COPY(ap->bssid, ni->ni_bssid); + ap->namelen = ni->ni_esslen; + if (ni->ni_esslen) + memcpy(ap->name, ni->ni_essid, + ni->ni_esslen); + } + ap->channel = ieee80211_chan2ieee(ic, ni->ni_chan); + ap->signal = ic->ic_node_getrssi(ni); + ap->capinfo = ni->ni_capinfo; + ap->interval = ni->ni_intval; + rs = &ni->ni_rates; + for (j = 0; j < rs->rs_nrates; j++) { + if (rs->rs_rates[j] & IEEE80211_RATE_BASIC) { + ap->rate = (rs->rs_rates[j] & + IEEE80211_RATE_VAL) * 5; /* XXX */ + } + } + sa->i++; + sa->ap++; +} + +struct wi_read_prism2_args { + int i; /* result count */ + struct wi_scan_res *res;/* current entry in result buffer */ + caddr_t max; /* result buffer bound */ +}; + +static void +wi_read_prism2_result(void *arg, struct ieee80211_node *ni) +{ + struct ieee80211com *ic = ni->ni_ic; + struct wi_read_prism2_args *sa = arg; + struct wi_scan_res *res = sa->res; + + if ((caddr_t)(res + 1) > sa->max) + return; + res->wi_chan = ieee80211_chan2ieee(ic, ni->ni_chan); + res->wi_noise = 0; + res->wi_signal = ic->ic_node_getrssi(ni); + IEEE80211_ADDR_COPY(res->wi_bssid, ni->ni_bssid); + res->wi_interval = ni->ni_intval; + res->wi_capinfo = ni->ni_capinfo; + res->wi_ssid_len = ni->ni_esslen; + memcpy(res->wi_ssid, ni->ni_essid, IEEE80211_NWID_LEN); + /* NB: assumes wi_srates holds <= ni->ni_rates */ + memcpy(res->wi_srates, ni->ni_rates.rs_rates, + sizeof(res->wi_srates)); + if (ni->ni_rates.rs_nrates < 10) + res->wi_srates[ni->ni_rates.rs_nrates] = 0; + res->wi_rate = ni->ni_rates.rs_rates[ni->ni_txrate]; + res->wi_rsvd = 0; + + sa->i++; + sa->res++; +} + +struct wi_read_sigcache_args { + int i; /* result count */ + struct wi_sigcache *wsc;/* current entry in result buffer */ + caddr_t max; /* result buffer bound */ +}; + +static void +wi_read_sigcache(void *arg, struct ieee80211_node *ni) +{ + struct ieee80211com *ic = ni->ni_ic; + struct wi_read_sigcache_args *sa = arg; + struct wi_sigcache *wsc = sa->wsc; + + if ((caddr_t)(wsc + 1) > sa->max) + return; + memset(wsc, 0, sizeof(struct wi_sigcache)); + IEEE80211_ADDR_COPY(wsc->macsrc, ni->ni_macaddr); + wsc->signal = ic->ic_node_getrssi(ni); + + sa->wsc++; + sa->i++; +} + int ieee80211_cfgget(struct ieee80211com *ic, u_long cmd, caddr_t data) { @@ -86,13 +190,6 @@ struct ifreq *ifr = (struct ifreq *)data; struct wi_req wreq; struct wi_ltv_keys *keys; - struct wi_apinfo *ap; - struct ieee80211_node_table *nt; - struct ieee80211_node *ni; - struct ieee80211_rateset *rs; - struct wi_sigcache wsc; - struct wi_scan_p2_hdr *p2; - struct wi_scan_res *res; error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); if (error) @@ -270,107 +367,53 @@ /* * Don't return results until active scan completes. */ - if (ic->ic_state == IEEE80211_S_SCAN && - (ic->ic_flags & IEEE80211_F_ASCAN)) { + if ((ic->ic_flags & (IEEE80211_F_SCAN|IEEE80211_F_ASCAN)) == 0) { + struct wi_read_ap_args args; + + args.i = 0; + args.ap = (void *)((char *)wreq.wi_val + sizeof(i)); + args.max = (void *)(&wreq + 1); + ieee80211_iterate_nodes(&ic->ic_scan, + wi_read_ap_result, &args); + memcpy(wreq.wi_val, &args.i, sizeof(args.i)); + wreq.wi_len = (sizeof(int) + + sizeof(struct wi_apinfo) * args.i) / 2; + } else error = EINPROGRESS; - break; - } - i = 0; - ap = (void *)((char *)wreq.wi_val + sizeof(i)); - nt = &ic->ic_scan; - TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - if ((caddr_t)(ap + 1) > (caddr_t)(&wreq + 1)) - break; - memset(ap, 0, sizeof(*ap)); - if (ic->ic_opmode == IEEE80211_M_HOSTAP) { - IEEE80211_ADDR_COPY(ap->bssid, ni->ni_macaddr); - ap->namelen = ic->ic_des_esslen; - if (ic->ic_des_esslen) - memcpy(ap->name, ic->ic_des_essid, - ic->ic_des_esslen); - } else { - IEEE80211_ADDR_COPY(ap->bssid, ni->ni_bssid); - ap->namelen = ni->ni_esslen; - if (ni->ni_esslen) - memcpy(ap->name, ni->ni_essid, - ni->ni_esslen); - } - ap->channel = ieee80211_chan2ieee(ic, ni->ni_chan); - ap->signal = ic->ic_node_getrssi(ni); - ap->capinfo = ni->ni_capinfo; - ap->interval = ni->ni_intval; - rs = &ni->ni_rates; - for (j = 0; j < rs->rs_nrates; j++) { - if (rs->rs_rates[j] & IEEE80211_RATE_BASIC) { - ap->rate = (rs->rs_rates[j] & - IEEE80211_RATE_VAL) * 5; /* XXX */ - } - } - i++; - ap++; - } - memcpy(wreq.wi_val, &i, sizeof(i)); - wreq.wi_len = (sizeof(int) + sizeof(*ap) * i) / 2; break; case WI_RID_PRISM2: - wreq.wi_val[0] = 1; /* XXX lie so SCAN_RES can give rates */ + /* NB: we lie so WI_RID_SCAN_RES can include rates */ + wreq.wi_val[0] = 1; wreq.wi_len = sizeof(u_int16_t) / 2; break; case WI_RID_SCAN_RES: /* compatibility interface */ - if (ic->ic_state == IEEE80211_S_SCAN && - (ic->ic_flags & IEEE80211_F_ASCAN)) { + if ((ic->ic_flags & (IEEE80211_F_SCAN|IEEE80211_F_ASCAN)) == 0) { + struct wi_read_prism2_args args; + struct wi_scan_p2_hdr *p2; + + /* NB: use Prism2 format so we can include rate info */ + p2 = (struct wi_scan_p2_hdr *)wreq.wi_val; + args.i = 0; + args.res = (void *)&p2[1]; + args.max = (void *)(&wreq + 1); + ieee80211_iterate_nodes(&ic->ic_scan, + wi_read_prism2_result, &args); + p2->wi_rsvd = 0; + p2->wi_reason = args.i; + wreq.wi_len = (sizeof(*p2) + + sizeof(struct wi_scan_res) * args.i) / 2; + } else error = EINPROGRESS; - break; - } - /* NB: we use the Prism2 format so we can return rate info */ - p2 = (struct wi_scan_p2_hdr *)wreq.wi_val; - res = (void *)&p2[1]; - i = 0; - nt = &ic->ic_scan; - TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - if ((caddr_t)(res + 1) > (caddr_t)(&wreq + 1)) - break; - res->wi_chan = ieee80211_chan2ieee(ic, ni->ni_chan); - res->wi_noise = 0; - res->wi_signal = ic->ic_node_getrssi(ni); - IEEE80211_ADDR_COPY(res->wi_bssid, ni->ni_bssid); - res->wi_interval = ni->ni_intval; - res->wi_capinfo = ni->ni_capinfo; - res->wi_ssid_len = ni->ni_esslen; - memcpy(res->wi_ssid, ni->ni_essid, IEEE80211_NWID_LEN); - /* NB: assumes wi_srates holds <= ni->ni_rates */ - memcpy(res->wi_srates, ni->ni_rates.rs_rates, - sizeof(res->wi_srates)); - if (ni->ni_rates.rs_nrates < 10) - res->wi_srates[ni->ni_rates.rs_nrates] = 0; - res->wi_rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - res->wi_rsvd = 0; - res++, i++; - } - p2->wi_rsvd = 0; - p2->wi_reason = i; - wreq.wi_len = (sizeof(*p2) + sizeof(*res) * i) / 2; break; - case WI_RID_READ_CACHE: - i = 0; - nt = &ic->ic_scan; - TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - if (i == (WI_MAX_DATALEN/sizeof(struct wi_sigcache))-1) - break; - IEEE80211_ADDR_COPY(wsc.macsrc, ni->ni_macaddr); - memset(&wsc.ipsrc, 0, sizeof(wsc.ipsrc)); - wsc.signal = ic->ic_node_getrssi(ni); - wsc.noise = 0; - wsc.quality = 0; - memcpy((caddr_t)wreq.wi_val + sizeof(wsc) * i, - &wsc, sizeof(wsc)); - i++; - } - wreq.wi_len = sizeof(wsc) * i / 2; + case WI_RID_READ_CACHE: { + struct wi_read_sigcache_args args; + args.i = 0; + args.wsc = (struct wi_sigcache *) wreq.wi_val; + args.max = (void *)(&wreq + 1); + ieee80211_iterate_nodes(&ic->ic_scan, wi_read_sigcache, &args); + wreq.wi_len = sizeof(struct wi_sigcache) * args.i / 2; break; - case WI_RID_SCAN_APS: - error = EINVAL; - break; + } default: error = EINVAL; break; @@ -1094,7 +1137,7 @@ int error, space; u_int8_t *p, *cp; - nt = ic->ic_sta; + nt = ic->ic_sta; if (nt == NULL) return EINVAL; p = ireq->i_data;help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200412020323.iB23NVcF040023>
