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