PERFORCE change 66236 for review
Sam Leffler
sam at FreeBSD.org
Wed Dec 1 19:23:32 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=66236
Change 66236 by sam at 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;
More information about the p4-projects
mailing list