Browse Source

Plan 9 from Bell Labs 2003-01-18

David du Colombier 21 years ago
parent
commit
25561f55b9
6 changed files with 138 additions and 24 deletions
  1. 4 4
      dist/replica/plan9.db
  2. 4 0
      dist/replica/plan9.log
  3. 89 19
      sys/src/9/pc/wavelan.c
  4. 19 1
      sys/src/9/pc/wavelan.h
  5. 19 0
      sys/src/9/port/netif.c
  6. 3 0
      sys/src/9/port/netif.h

+ 4 - 4
dist/replica/plan9.db

@@ -5189,8 +5189,8 @@ sys/src/9/pc/vgatvp3020.c - 664 sys sys 1015014528 4491
 sys/src/9/pc/vgatvp3026.c - 664 sys sys 1015014528 3940
 sys/src/9/pc/vgavmware.c - 664 sys sys 1020284822 6334
 sys/src/9/pc/vgax.c - 664 sys sys 1015014528 1655
-sys/src/9/pc/wavelan.c - 664 sys sys 1036812833 25627
-sys/src/9/pc/wavelan.h - 664 sys sys 1026860150 5684
+sys/src/9/pc/wavelan.c - 664 sys sys 1042855781 27095
+sys/src/9/pc/wavelan.h - 664 sys sys 1042855780 6228
 sys/src/9/port - 20000000775 sys sys 1018469625 0
 sys/src/9/port/alarm.c - 664 sys sys 1026847545 1733
 sys/src/9/port/alloc.c - 664 sys sys 1019663885 5328
@@ -5246,8 +5246,8 @@ sys/src/9/port/mkerrstr - 775 sys sys 1015278340 75
 sys/src/9/port/mkextract - 775 sys sys 1039753334 435
 sys/src/9/port/mkroot - 775 sys sys 1039753334 235
 sys/src/9/port/mksystab - 664 sys sys 1014931176 783
-sys/src/9/port/netif.c - 664 sys sys 1026847549 12722
-sys/src/9/port/netif.h - 664 sys sys 1014931176 2748
+sys/src/9/port/netif.c - 664 sys sys 1042855805 13131
+sys/src/9/port/netif.h - 664 sys sys 1042855799 2908
 sys/src/9/port/nulledf.c - 664 sys sys 1037669300 821
 sys/src/9/port/page.c - 664 sys sys 1014931177 8086
 sys/src/9/port/parse.c - 664 sys sys 1014931177 2026

+ 4 - 0
dist/replica/plan9.log

@@ -17072,3 +17072,7 @@
 1042641175 4 c 386/bin/fossil/fossil - 775 sys sys 1042640744 332102
 1042641175 5 c 386/bin/ip/httpd/httpd - 775 sys sys 1042640745 283885
 1042641175 6 c sys/src/cmd/pcc.c - 664 sys sys 1042640611 5937
+1042857047 0 c sys/src/9/pc/wavelan.c - 664 sys sys 1042855781 27095
+1042857047 1 c sys/src/9/pc/wavelan.h - 664 sys sys 1042855780 6228
+1042857047 2 c sys/src/9/port/netif.c - 664 sys sys 1042855805 13131
+1042857047 3 c sys/src/9/port/netif.h - 664 sys sys 1042855799 2908

+ 89 - 19
sys/src/9/pc/wavelan.c

@@ -28,6 +28,11 @@
 #include "etherif.h"
 #include "wavelan.h"
 
+enum
+{
+	MSperTick=	50,	/* ms between ticks of kproc */
+};
+
 /*
  * When we're using a PCI device and memory-mapped I/O, 
  * the registers are spaced out as though each takes 32 bits,
@@ -381,7 +386,7 @@ w_enable(Ether* ether)
 
 	ltv_outs(ctlr, WTyp_Prom, (ether->prom?1:0));
 
-	if(ctlr->hascrypt){
+	if(ctlr->hascrypt && ctlr->crypt){
 		ltv_outs(ctlr, WTyp_Crypt, ctlr->crypt);
 		ltv_outs(ctlr, WTyp_TxKey, ctlr->txkey);
 		w_outltv(ctlr, &ctlr->keys);
@@ -528,30 +533,90 @@ w_txdone(Ctlr* ctlr, int sts)
 		ctlr->ntx++;
 }
 
-static int
-w_stats(Ctlr* ctlr)
+/* save the stats info in the ctlr struct */
+static void
+w_stats(Ctlr* ctlr, int len)
 {
-	int i, rc, sp;
-	Wltv ltv;
+	int i, rc;
 	ulong* p = (ulong*)&ctlr->WStats;
 	ulong* pend = (ulong*)&ctlr->end;
 
+	for (i = 0; i < len && p < pend; i++){
+		rc = csr_ins(ctlr, WR_Data1);
+		if(rc > 0xf000)
+			rc = ~rc & 0xffff;
+		p[i] += rc;
+	}
+}
+
+/* send the base station scan info to any readers */
+static void
+w_scaninfo(Ether* ether, Ctlr *ctlr, int len)
+{
+	int i, j;
+	Netfile **ep, *f, **fp;
+	Block *bp;
+	WScan *wsp;
+
+	for (i = 0; i < len ; i++)
+		ctlr->scanbuf[i] = csr_ins(ctlr, WR_Data1);
+
+	len *= 2;
+	i = ether->scan;
+	ep = &ether->f[Ntypes];
+	for(fp = ether->f; fp < ep && i > 0; fp++){
+		f = *fp;
+		if(f == nil || f->scan == 0)
+			continue;
+
+		bp = iallocb(2048);
+		if(bp == nil)
+			break;
+		for(j = 0; j < len/(2*25); j++){
+			wsp = (WScan*)(&ctlr->scanbuf[j*25]);
+			if(wsp->ssid_len > 32)
+				wsp->ssid_len = 32;
+			bp->wp += snprint((char*)bp->wp, 2048,
+				"ssid=%.*s;bssid=%E;signal=%d;noise=%d;chan=%d%s\n",
+				wsp->ssid_len, wsp->ssid, wsp->bssid, wsp->signal,
+				wsp->noise, wsp->chan, (wsp->capinfo&(1<<4))?";wep":"");
+		}
+		qpass(f->in, bp);
+		i--;
+	}
+}
+
+static int
+w_info(Ether *ether, Ctlr* ctlr)
+{
+	int sp;
+	Wltv ltv;
+
 	sp = csr_ins(ctlr, WR_InfoId);
 	ltv.len = ltv.type = 0;
 	w_read(ctlr, sp, 0, &ltv, 4);
-	if(ltv.type == WTyp_Stats){
-		ltv.len--;
-		for (i = 0; i < ltv.len && p < pend; i++){
-			rc = csr_ins(ctlr, WR_Data1);
-			if(rc > 0xf000)
-				rc = ~rc & 0xffff;
-			p[i] += rc;
-		}
+	ltv.len--;
+	switch(ltv.type){
+	case WTyp_Stats:
+		w_stats(ctlr, ltv.len);
+		return 0;
+	case WTyp_Scan:
+		w_scaninfo(ether, ctlr, ltv.len);
 		return 0;
 	}
 	return -1;
 }
 
+/* set scanning interval */
+static void
+w_scanbs(void *a, uint secs)
+{
+	Ether *ether = a;
+	Ctlr* ctlr = (Ctlr*) ether->ctlr;
+
+	ctlr->scanticks = secs*(1000/MSperTick);
+}
+
 static void
 w_intr(Ether *ether)
 {
@@ -588,7 +653,7 @@ w_intr(Ether *ether)
 	}
 	if(rc & WInfoEv){
 		ctlr->ninfo++;
-		w_stats(ctlr);
+		w_info(ether, ctlr);
 		csr_ack(ctlr, WInfoEv);
 	}
 	if(rc & WTxErrEv){
@@ -614,7 +679,7 @@ w_timer(void* arg)
 
 	ctlr->timerproc = up;
 	for(;;){
-		tsleep(&ctlr->timer, return0, 0, 50);
+		tsleep(&ctlr->timer, return0, 0, MSperTick);
 		ctlr = (Ctlr*)ether->ctlr;
 		if(ctlr == 0)
 			break;
@@ -655,7 +720,11 @@ w_timer(void* arg)
 			}
 			if((ctlr->ticks % 120) == 0)
 			if(ctlr->txbusy == 0)
-				w_cmd(ctlr, WCmdAskStats, WTyp_Stats);
+				w_cmd(ctlr, WCmdEnquire, WTyp_Stats);
+			if(ctlr->scanticks > 0)
+			if((ctlr->ticks % ctlr->scanticks) == 0)
+			if(ctlr->txbusy == 0)
+				w_cmd(ctlr, WCmdEnquire, WTyp_Scan);
 		}
 		iunlock(ctlr);
 	}
@@ -793,7 +862,7 @@ w_ifstat(Ether* ether, void* a, long n, ulong offset)
 	k = ((ctlr->state & Attached) ? "attached" : "not attached");
 	PRINTSTAT("Card %s", k);
 	k = ((ctlr->state & Power) ? "on" : "off");
-	PRINTSTAT("PCardower %s", k);
+	PRINTSTAT(", power %s", k);
 	k = ((ctlr->txbusy)? ", txbusy" : "");
 	PRINTSTAT("%s\n", k);
 
@@ -823,7 +892,7 @@ w_ifstat(Ether* ether, void* a, long n, ulong offset)
 	PRINTSTAT("Channel: %d\n", ltv_ins(ctlr, WTyp_Chan));
 	PRINTSTAT("AP density: %d\n", ltv_ins(ctlr, WTyp_ApDens));
 	PRINTSTAT("Promiscuous mode: %d\n", ltv_ins(ctlr, WTyp_Prom));
-	if(i == 3)
+	if(i == WPTypeAdHoc)
 		PRINTSTAT("SSID name: %s\n", ltv_inname(ctlr, WTyp_NetName));
 	else {
 		Wltv ltv;
@@ -899,7 +968,7 @@ w_option(Ctlr* ctlr, char* buf, long n)
 			p = "";
 		else
 			p = cb->f[1];
-		if(ctlr->ptype == 3){
+		if(ctlr->ptype == WPTypeAdHoc){
 			memset(ctlr->netname, 0, sizeof(ctlr->netname));
 			strncpy(ctlr->netname, p, WNameLen);
 		}
@@ -1125,6 +1194,7 @@ wavelanreset(Ether* ether, Ctlr *ctlr)
 	ether->power = w_power;
 	ether->promiscuous = w_promiscuous;
 	ether->multicast = w_multicast;
+	ether->scanbs = w_scanbs;
 	ether->arg = ether;
 
 	DEBUG("#l%d: irq %ld port %lx type %s",

+ 19 - 1
sys/src/9/pc/wavelan.h

@@ -7,6 +7,8 @@
 enum
 {
 	WTyp_Stats	= 0xf100,
+	WTyp_Scan	= 0xf101,
+	WTyp_Link	= 0xf200,
 	WTyp_Ptype	= 0xfc00,
 	WTyp_Mac	= 0xfc01,
 	WTyp_WantName	= 0xfc02,
@@ -69,7 +71,7 @@ enum
 		WCmdDis		= 0x0002,
 		WCmdTx		= 0x000b,
 		WCmdMalloc	= 0x000a,
-		WCmdAskStats	= 0x0011,
+		WCmdEnquire	= 0x0011,
 		WCmdMsk		= 0x003f,
 		WCmdAccRd	= 0x0021,
 		WCmdReclaim	= 0x0100,
@@ -134,6 +136,7 @@ typedef struct Wltv	Wltv;
 typedef struct WFrame	WFrame;
 typedef struct Stats	Stats;
 typedef struct WStats	WStats;
+typedef struct WScan	WScan;
 typedef struct WKey	WKey;
 
 struct WStats
@@ -162,6 +165,18 @@ struct WStats
 	ulong	end;
 };
 
+struct WScan
+{
+	ushort	chan;			/* dss channel */
+	ushort	noise;			/* average noise in the air */
+	ushort	signal;			/* signal strength */
+	uchar	bssid[Eaddrlen];	/* MAC address of the ap */
+	ushort	interval;		/* beacon transmit interval */
+	ushort	capinfo;		/* capability bits (0-ess, 1-ibss, 4-privacy [wep]) */
+	ushort	ssid_len;		/* ssid length */
+	char	ssid[WNameLen];		/* ssid (ap name) */
+};
+
 struct WFrame
 {
 	ushort	sts;
@@ -266,6 +281,7 @@ struct Ctlr
 	int	pmwait;
 
 	Proc	*timerproc;
+	int	scanticks;
 
 	char	netname[WNameLen];
 	char	wantname[WNameLen];
@@ -289,6 +305,8 @@ struct Ctlr
 
 	Stats;
 	WStats;
+
+	ushort	scanbuf[25*4];		// buffer for base station scan info
 };
 
 extern char* wavenames[];

+ 19 - 0
sys/src/9/port/netif.c

@@ -308,6 +308,17 @@ netifwrite(Netif *nif, Chan *c, void *a, long n)
 			f->prom = 1;
 			nif->prom++;
 		}
+	} else if((p = matchtoken(buf, "scanbs")) != 0){
+		/* scan for base stations */
+		if(f->scan == 0){
+			type = atoi(p);
+			if(type < 5)
+				type = 5;
+			if(nif->scanbs != nil)
+				nif->scanbs(nif->arg, type);
+			f->scan = type;
+			nif->scan++;
+		}
 	} else if(matchtoken(buf, "bridge")){
 		f->bridge = 1;
 	} else if(matchtoken(buf, "headersonly")){
@@ -389,6 +400,14 @@ netifclose(Netif *nif, Chan *c)
 			qunlock(nif);
 			f->prom = 0;
 		}
+		if(f->scan){
+			qlock(nif);
+			if(--(nif->scan) == 0 && nif->scanbs != nil)
+				nif->scanbs(nif->arg, 0);
+			qunlock(nif);
+			f->prom = 0;
+			f->scan = 0;
+		}
 		if(f->nmaddr){
 			qlock(nif);
 			t = 0;

+ 3 - 0
sys/src/9/port/netif.h

@@ -39,6 +39,7 @@ struct Netfile
 
 	int	type;			/* multiplexor type */
 	int	prom;			/* promiscuous mode */
+	int	scan;			/* base station scanning interval */
 	int	bridge;			/* bridge mode */
 	int	headersonly;		/* headers only - no data */
 	uchar	maddr[8];		/* bitmask of multicast addresses requested */
@@ -79,6 +80,7 @@ struct Netif
 	int	nmaddr;			/* number of known multicast addresses */
 	Netaddr *mhash[Nmhash];		/* hash table of multicast addresses */
 	int	prom;			/* number of promiscuous opens */
+	int	scan;			/* number of base station scanners */
 	int	all;			/* number of -1 multiplexors */
 
 	/* statistics */
@@ -96,6 +98,7 @@ struct Netif
 	void	*arg;
 	void	(*promiscuous)(void*, int);
 	void	(*multicast)(void*, uchar*, int);
+	void	(*scanbs)(void*, uint);	/* scan for base stations */
 };
 
 void	netifinit(Netif*, char*, int, ulong);