ref: 445fc8e5a7ab20dc0613a6b1faedfe7f5183e7a9
parent: eb1be5b4df533c4e5100296fb042e274da435b5b
parent: abe463b931338e77095586052b66daade0428c95
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Aug 6 19:14:59 EDT 2018
merge
--- a/sys/src/9/port/wifi.c
+++ b/sys/src/9/port/wifi.c
@@ -173,7 +173,7 @@
uchar *a, *p;
for(a = wn->maxrate, p = wifi->rates; *p; p++){
- if(*p < *a && *p > *wn->actrate)
+ if(*p < *a && *p > *wn->actrate && (wn->validrates & (1UL << p-wifi->rates)) != 0)
a = p;
}
wn->actrate = a;
@@ -229,7 +229,7 @@
uchar *a, *p;
for(a = wn->minrate, p = wifi->rates; *p; p++){
- if(*p > *a && *p < *wn->actrate)
+ if(*p > *a && *p < *wn->actrate && (wn->validrates & (1UL << p-wifi->rates)) != 0)
a = p;
}
wn->actrate = a;
@@ -237,25 +237,59 @@
}
static uchar*
-putrates(uchar *p, uchar *rates)
+putrates(uchar *p, uchar *rates, ulong valid, ulong basic)
{
- int n, m;
+ int n, i, j;
- n = m = strlen((char*)rates);
- if(n > 8)
- n = 8;
- /* supported rates */
- *p++ = 1;
- *p++ = n;
- memmove(p, rates, n);
- p += n;
- if(m > 8){
+ valid |= basic;
+
+ for(i = n = 0; i < 32 && rates[i] != 0; i++)
+ if(valid & (1UL<<i))
+ n++;
+
+ valid &= ~basic;
+
+ if(n > 0){
+ /* supported rates */
+ *p++ = 1;
+ *p++ = n;
+ for(i = j = 0; j < n; i++){
+ if(basic & (1UL<<i)){
+ *p++ = rates[i] | 0x80;
+ j++;
+ }
+ }
+ for(i = 0; j < n; i++){
+ if(valid & (1UL<<i)){
+ *p++ = rates[i] & 0x7f;
+ j++;
+ }
+ }
+ }
+
+ if(n > 8){
+ /* truncate supported rates element */
+ p -= n;
+ p[-1] = 8;
+ p += 8;
+
/* extended supported rates */
*p++ = 50;
- *p++ = m;
- memmove(p, rates, m);
- p += m;
+ *p++ = n;
+ for(i = j = 0; j < n; i++){
+ if(basic & (1UL<<i)){
+ *p++ = rates[i] | 0x80;
+ j++;
+ }
+ }
+ for(i = 0; j < n; i++){
+ if(valid & (1UL<<i)){
+ *p++ = rates[i] & 0x7f;
+ j++;
+ }
+ }
}
+
return p;
}
@@ -289,7 +323,7 @@
memmove(p, wifi->essid, n);
p += n;
- p = putrates(p, wifi->rates);
+ p = putrates(p, wifi->rates, wn->validrates, wn->basicrates);
*p++ = 3; /* ds parameter set */
*p++ = 1;
@@ -363,7 +397,7 @@
memmove(p, bss->ssid, n);
p += n;
- p = putrates(p, wifi->rates);
+ p = putrates(p, wifi->rates, bss->validrates, bss->basicrates);
n = bss->rsnelen;
if(n > 0){
@@ -454,12 +488,15 @@
break;
case 1: /* supported rates */
case 50: /* extended rates */
- if(wn->actrate != nil || wifi->rates == nil)
- break; /* already set */
+ if(wifi->rates == nil)
+ break;
while(d < x){
- t = *d++ | 0x80;
+ t = *d | 0x80;
for(p = wifi->rates; *p != 0; p++){
if(*p == t){
+ wn->validrates |= 1UL << p-wifi->rates;
+ if(*d & 0x80)
+ wn->basicrates |= 1UL << p-wifi->rates;
if(wn->minrate == nil || t < *wn->minrate)
wn->minrate = p;
if(wn->maxrate == nil || t > *wn->maxrate)
@@ -467,8 +504,10 @@
break;
}
}
- wn->actrate = wn->maxrate;
+ d++;
}
+ if(wn->actrate == nil)
+ wn->actrate = wn->maxrate;
break;
case 3: /* DSPARAMS */
if(d != x)
--- a/sys/src/9/port/wifi.h
+++ b/sys/src/9/port/wifi.h
@@ -43,6 +43,9 @@
uchar *maxrate;
uchar *actrate;
+ ulong validrates; /* bitmap on wifi->rates */
+ ulong basicrates;
+
ulong txcount; /* statistics for rate adaption */
ulong txerror;