shithub: riscv

Download patch

ref: a87b6909bc209e04a9660b9b2bacea84151fb15d
parent: cf5316a402140556a618a55b59a1d77849a0e35d
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Sep 6 12:51:02 EDT 2020

wifi: add packet timestamping support

--- a/sys/src/9/port/wifi.c
+++ b/sys/src/9/port/wifi.c
@@ -85,6 +85,19 @@
 	return n;
 }
 
+static uvlong
+getts(uchar *d)
+{
+	return	(uvlong)d[0] |
+		(uvlong)d[1]<<8 |
+		(uvlong)d[2]<<16 |
+		(uvlong)d[3]<<24 |
+		(uvlong)d[4]<<32 |
+		(uvlong)d[5]<<40 |
+		(uvlong)d[6]<<48 |
+		(uvlong)d[7]<<56;
+}
+
 void
 wifiiq(Wifi *wifi, Block *b)
 {
@@ -93,6 +106,8 @@
 	Etherpkt *e;
 	int hdrlen;
 
+	if(b->flag & Btimestamp)
+		assert(b->rp - b->base >= 8);
 	if(BLEN(b) < WIFIHDRSIZE)
 		goto drop;
 	w = (Wifipkt*)b->rp;
@@ -115,6 +130,7 @@
 	case 0x04:	/* control */
 		break;
 	case 0x08:	/* data */
+		b->flag &= ~Btimestamp;
 		b->rp += hdrlen;
 		switch(w->fc[0] & 0xf0){
 		default:
@@ -136,9 +152,7 @@
 		memmove(e->d, dstaddr(&h), Eaddrlen);
 		memmove(e->s, srcaddr(&h), Eaddrlen);
 		memmove(e->type, s.type, 2);
-
 		dmatproxy(b, 0, wifi->ether->ea, &wifi->dmat);
-
 		etheriq(wifi->ether, b);
 		return;
 	}
@@ -310,6 +324,7 @@
 
 	b = allocb(WIFIHDRSIZE + 512);
 	w = (Wifipkt*)b->wp;
+
 	w->fc[0] = 0x40;	/* probe request */
 	w->fc[1] = 0x00;	/* STA->STA */
 	memmove(w->a1, wifi->ether->bcast, Eaddrlen);	/* ??? */
@@ -377,6 +392,7 @@
 	memmove(w->a1, bss->bssid, Eaddrlen);	/* ??? */
 	memmove(w->a2, wifi->ether->ea, Eaddrlen);
 	memmove(w->a3, bss->bssid, Eaddrlen);
+
 	b->wp += WIFIHDRSIZE;
 	p = b->wp;
 
@@ -461,12 +477,17 @@
 	if(len < 0)
 		return;
 
-	d += 8;	/* timestamp */
+	/* timestamp */
+	wn->ts = getts(d);
+	d += 8;
 	wn->ival = d[0] | d[1]<<8;
 	d += 2;
 	wn->cap = d[0] | d[1]<<8;
 	d += 2;
 
+	wn->dtimcount = 0;
+	wn->dtimperiod = 1;
+
 	rsnset = 0;
 	for(e = d + len; d+2 <= e; d = x){
 		d += 2;
@@ -513,6 +534,13 @@
 			if(d != x)
 				wn->channel = d[0];
 			break;
+		case 5:
+			if(x - d < 2)
+				break;
+			wn->dtimcount = d[0];
+			if(d[1] > 0)
+				wn->dtimperiod = d[1];
+			break;
 		case 221:	/* vendor specific */
 			len = x - d;
 			if(rsnset || len < sizeof(wpa1oui) || memcmp(d, wpa1oui, sizeof(wpa1oui)) != 0)
@@ -619,6 +647,7 @@
 				w = (Wifipkt*)b->rp;
 				if(w->fc[1] & 0x40)
 					continue;
+				b->flag &= ~Btimestamp;
 				wifiiq(wifi, b);
 				b = nil;
 			}
@@ -637,6 +666,8 @@
 			if((wn = nodelookup(wifi, w->a3, 1)) == nil)
 				continue;
 			wn->lastseen = MACHP(0)->ticks;
+			if(b->flag & Btimestamp)
+				wn->rs = getts(b->rp - 8);
 			b->rp += wifihdrlen(w);
 			recvbeacon(wifi, wn, b->rp, BLEN(b));
 
@@ -655,6 +686,8 @@
 		if((wn = nodelookup(wifi, w->a3, 0)) == nil)
 			continue;
 		wn->lastseen = MACHP(0)->ticks;
+		if(b->flag & Btimestamp)
+			wn->rs = getts(b->rp - 8);
 		switch(w->fc[0] & 0xf0){
 		case 0x10:	/* assoc response */
 		case 0x30:	/* reassoc response */
@@ -804,8 +837,9 @@
 				wifideauth(wifi, wn);	/* stuck in auth, start over */
 			if(wn->status == Sconn || wn->status == Sunauth)
 				sendauth(wifi, wn);
-			if(wn->status == Sauth)
+			if(wn->status == Sauth){
 				sendassoc(wifi, wn);
+			}
 		}
 		tsleep(&up->sleep, return0, 0, 500);
 	}
--- a/sys/src/9/port/wifi.h
+++ b/sys/src/9/port/wifi.h
@@ -50,6 +50,10 @@
 	ulong	txerror;
 
 	/* stuff from beacon */
+	uvlong	rs;
+	uvlong	ts;
+	uchar	dtimcount;
+	uchar	dtimperiod;
 	int	ival;
 	int	cap;
 	int	channel;
@@ -107,6 +111,10 @@
 	uchar	a3[Eaddrlen];
 	uchar	seq[2];
 	uchar	a4[Eaddrlen];
+};
+
+enum {
+	Btimestamp = 1<<15,
 };
 
 Wifi *wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*));