This program calculate location of Wi-Fi receiver, by using AP beacon. Please check the Japanese magazine "Interface 2012/12".

Dependencies:   TextLCD mbed

Revision:
1:2f2f793fcf4f
Parent:
0:4eaf38ccb19c
--- a/WiFiScanner.h	Fri Aug 24 03:21:43 2012 +0000
+++ b/WiFiScanner.h	Mon Sep 10 07:15:35 2012 +0000
@@ -1,393 +1,370 @@
-#include <string.h>
-
-#define BAUD_RATE 115200
-
-#define MULTI_CHANNEL
-#ifdef  MULTI_CHANNEL
-#define TOTAL_CHANNELS  13
-#else
-#define TOTAL_CHANNELS  1
-#endif
-#define MAX_AP_COUNT    (10 * TOTAL_CHANNELS)
-//#define PASSIVE_SCAN  // uncommnet here when you need passive scan
-
-#define CR  '\r'
-#define SHORT_WAIT  0.00032
-#define BUFF_LEN    4096
-#define ESSID_LEN   33
-#define MACADDR_LEN 6
-
-struct apinfo {
-    unsigned char essid[ESSID_LEN];
-    unsigned char bssid[MACADDR_LEN];
-    int power;
-};
-
-struct apinfo apinfos[MAX_AP_COUNT];
-int apinfo_count;
-
-Serial wifi(p13, p14);
-
-DigitalOut PRST(p15);
-DigitalOut UART_CTS(p16);
-DigitalIn  UART_RTS(p17);
-
-class WiFiScanner {
-private:
-    int sequence;
-    unsigned char buff[BUFF_LEN];
-        
-    void wifiReadWait()
-    {
-        UART_CTS = 0;
-    }
-
-    void wifiReadEnd()
-    {
-        UART_CTS = 1;
-    }
-
-    void wifiPutc(int c)
-    {
-        while (!wifi.writeable())
-            ; // empty loop body
-        wifi.putc(c);
-    }
-
-    int wifiGetc()
-    {
-        while (!wifi.readable())
-            ; // empty loop body
-        return wifi.getc();
-    }
-
-    int num2hex(int i)
-    {
-        static const char hexadecimal[] = "0123456789ABCDEF";
-    
-        if ( i < 0 || i > 15 )
-            return '0';
-
-        return ((int)hexadecimal[i]);
-    }
-
-    int hex2num(int i)
-    {
-        switch (i) {
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-            return (i - '0');
-        case 'A':
-        case 'B':
-        case 'C':
-        case 'D':
-        case 'E':
-        case 'F':
-            return ( i - 'A' + 10);
-        case 'a':
-        case 'b':
-        case 'c':
-        case 'd':
-        case 'e':
-        case 'f':
-            return ( i - 'a' + 10);
-        }
-        return (-1);
-    }
-
-    void delayedPutc(unsigned char c)
-    {
-        wifiPutc(c);
-        wait(SHORT_WAIT);
-    }
-
- 
-    void wifiWrite(unsigned char *data)
-    {
-        int i;
-        int len = ((int)data[3]) * 256 + data[2];
-
-        delayedPutc('*');
-        delayedPutc(num2hex((len >> 4) & 0xf));
-        delayedPutc(num2hex(len & 0xf));
-        delayedPutc('4');
-        delayedPutc(num2hex((len >> 8) & 0xf)); 
-        for ( i = 0; i < len; i++ ) {
-            if ( i == 1 ) {
-                delayedPutc(num2hex((sequence >> 4) & 0x0f));
-                delayedPutc(num2hex(sequence & 0x0f));
-            } else {
-                delayedPutc(num2hex((data[i] >> 4) & 0x0f));
-                delayedPutc(num2hex(data[i] & 0x0f));
-            }
-        }
-        delayedPutc(CR);
-        sequence++;
-    }
-
-    int wifiRead()
-    {
-        int len = 0;
-        int index = 0;
-        int c;
-    
-        wifiReadWait();
-        while (true) {
-            c = wifiGetc();
-            if ( c == CR ) {
-                if ( (index - 5) >= len * 2 ) {
-                    break;
-                }
-
-                len = 0;
-                index = 0;
-                continue;
-            }
-            if ( index == 0 ) {
-                if ( c == '*' ) {
-                    index++;
-                } else {
-                    while (wifiGetc() != CR)
-                        ;   //empty loop body
-                }
-                continue;
-            }
-
-            c = hex2num(c);
-            if ( c < 0 ) {
-                while (wifiGetc() != CR)
-                    ;   // empty loop body
-                len = 0;
-                index = 0;
-                continue;
-            }
-            if ( index == 1 ) {
-                len = c << 4;
-            } else if ( index == 2 ) {
-                len |= c;
-            } else if ( index == 3 ) {
-                if ( c != 3 ) {
-                    wifiReadEnd();
-                    return -3;
-                }
-            } else if ( index == 4 ) {
-                len |= c << 8;
-            } else if ( index & 1 ) {
-                buff[(index - 5)/2] = c << 4;
-            } else {
-                buff[(index - 5)/2] |= c;
-            }
-            index++;
-        }
-        wifiReadEnd();
-        return len;
-    }
-
-public:
-    WiFiScanner()
-    {
-        sequence = 0;
-    }
-    
-    void reset()
-    {
-        wifi.baud(BAUD_RATE);
-        wifi.format(8, Serial::None, 1);
-    
-        sequence = 0;
-        PRST = 0;       // reset BP3591
-        wait(1.0);    // perhaps needs 1 sec
-        PRST = 1;
-        UART_CTS = 1;
-    }
-
-    void serialInit()
-    {
-        int i;
-        int c = 0;
-    
-        wifiReadWait();
-        while (true) {
-            if (wifi.writeable())
-                wifiPutc('A');
-            if (wifi.readable()) {
-               if ( c == '*' ) {
-                    c = wifiGetc();
-                    if ( c == CR ) {
-                        break;
-                    }
-                } else {
-                    c = wifiGetc();
-                }
-            }
-            wait(SHORT_WAIT);  // this wait is important
-        }
-
-        while (wifi.readable())
-            wifiGetc();
-        for ( i = 0; i < 8; i++ ) {
-            delayedPutc(0xf1);
-        }
-        c = 0;
-        while (true) {
-            if (wifi.readable()) {
-                if ( c == '*' ) {
-                    c = wifiGetc();
-                    if ( c == CR ) {
-                        break;
-                    }
-                } else {
-                    c = wifiGetc();
-                }
-            }
-        }
-        wifiReadEnd();
-    }
-
-    void waitStartup()
-    {
-        int i;
-        int len = 0;
-        bool loopFlag = true;
-        for (i = 0; loopFlag || len <= 0 || wifi.readable(); i++) {
-            len = wifiRead();
-            if ( len == 8 && buff[5] == 0x00 && buff[4] == 0x3d) {
-                loopFlag = false;
-            }
-            lcd.putc('+');
-        }
-    }
-
-    void scanMode()
-    {
-        // WID_SSID
-        unsigned char cmd0[] = { 0x57, 0x00, 0x08, 0x00, 0x00, 0x30, 0x01, 0x00 };
-        wifiWrite(cmd0);
-        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-            wait(SHORT_WAIT);
-        
-        // WID_BSS_TYPE
-        unsigned char cmd1[] = { 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00 };
-        wifiWrite(cmd1);
-        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-            wait(SHORT_WAIT);
-        
-        // WID_BCAST_SSID
-        unsigned char cmd2[] = { 0x57, 0x00, 0x08, 0x00, 0x15, 0x00, 0x01, 0x01 };
-        wifiWrite(cmd2);
-        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-            wait(SHORT_WAIT);
-        
-        // WID_SCAN_TYPE
-#ifdef  PASSIVE_SCAN
-        unsigned char cmd3[] = { 0x57, 0x00, 0x08, 0x00, 0x07, 0x00, 0x01, 0x00 };
-#else
-        unsigned char cmd3[] = { 0x57, 0x00, 0x08, 0x00, 0x07, 0x00, 0x01, 0x01 };
-#endif
-        wifiWrite(cmd3);
-        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-            wait(SHORT_WAIT);
-
-        // WID_ENABLE_CHANNEL
-        unsigned char cmd4[] = { 0x57, 0x02, 0x0b, 0x00, 0x24, 0x20, 0x04, 0xff, 0x1f, 0x00, 0x00 };
-        wifiWrite(cmd4);
-        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-            wait(SHORT_WAIT);
-
-        // WID_SITE_SURVEY
-#ifdef  MULTI_CHANNEL
-        unsigned char cmd5[] = { 0x57, 0x01, 0x08, 0x00, 0x0e, 0x00, 0x01, 0x11 };
-#else
-        unsigned char cmd5[] = { 0x57, 0x01, 0x08, 0x00, 0x0e, 0x00, 0x01, 0x01 };
-#endif
-        wifiWrite(cmd5);
-        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-            wait(SHORT_WAIT);
-        
-        // WID_SCAN_FILTER
-#ifdef  MULTI_CHANNEL
-        unsigned char cmd6[] = { 0x57, 0x02, 0x08, 0x00, 0x36, 0x00, 0x01, 0x00 };
-#else
-        unsigned char cmd6[] = { 0x57, 0x02, 0x08, 0x00, 0x36, 0x00, 0x01, 0x00 };
-#endif
-        wifiWrite(cmd6);
-        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-            wait(SHORT_WAIT);
-
-#ifdef  PASSIVE_SCAN
-        // WID_SITE_SURVEY_SCAN_TIME
-        unsigned char cmd7[] = { 0x57, 0x00, 0x09, 0x00, 0x0e, 0x10, 0x02, 0x00, 0x02 };
-        wifiWrite(cmd7);
-        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-            wait(SHORT_WAIT);
-#endif
-    }
-
-    void doScan()
-    {
-        int i, len, channel;
-        int count, write_index;
-    
-        apinfo_count = 0;
-        for (channel = 0; channel < TOTAL_CHANNELS; channel++ ) {
-            myled1 = (channel >> 3) & 1;
-            myled2 = (channel >> 2) & 1;
-            myled3 = (channel >> 1) & 1;
-            myled4 = channel & 1;
-        
-            // WID_CURRENT_CHANNEL
-#ifdef  MULTI_CHANNEL
-            unsigned char cmd8[] = { 0x57, 0x02, 0x08, 0x00, 0x02, 0x00, 0x01, 0x10 };
-            cmd8[7] = channel + 1; // 1 origin
-            wifiWrite(cmd8);
-            while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-                wait(SHORT_WAIT);
-#endif
-            // WID_START_SCAN_REQ
-            unsigned char cmd9[] = { 0x57, 0x02, 0x08, 0x00, 0x1e, 0x00, 0x01, 0x01 };
-            wifiWrite(cmd9);
-            while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
-                wait(SHORT_WAIT);
-
-#ifdef  PASSIVE_SCAN
-            wait(0.5);
-#else
-            wait(0.02);
-#endif
-    
-            // WID_SITE_SURVER_RESULTS
-            unsigned char cmd10[] = { 0x51, 0x03, 0x06, 0x00, 0x12, 0x30 };
-            wifiWrite(cmd10);
-            while ( (len = wifiRead()) <= 0 || (buff[5] != 0x30 || buff[4] != 0x12))
-                wait(SHORT_WAIT);
-            if ( len < 10 ) {
-                continue;
-            }
-            count = (buff[7] - 2) / 44;
-            for ( i = 0; i < count; i++ ) {
-                for ( write_index = 0; write_index < apinfo_count; write_index++) {
-                    if ( memcmp(apinfos[write_index].essid, buff + (9 + i *44), 33) == 0 &&
-                         memcmp(apinfos[write_index].bssid, buff + (9 + i * 44 + 36), 6) == 0 ) {
-                        break;  // already recorded
-                    }
-                }
-                if ( write_index == apinfo_count ) {
-                    memcpy(apinfos[write_index].essid, buff + (9 + i * 44), 33);
-                    memcpy(apinfos[write_index].bssid, buff + (9 + i * 44 + 36), 6);
-                    apinfos[write_index].power = (signed char)buff[9 + i * 44 + 42];
-                    apinfo_count++;
-                } else if ( apinfos[write_index].power < (signed char)buff[9 + i * 44 + 42] ) {
-                    apinfos[write_index].power = (signed char)buff[9 + i * 44 + 42];
-                }
-            }
-        }
-    }
+#include <string.h>
+
+#define BAUD_RATE 115200
+
+#define MULTI_CHANNEL
+#ifdef  MULTI_CHANNEL
+#define TOTAL_CHANNELS  13
+#else
+#define TOTAL_CHANNELS  1
+#endif
+#define MAX_AP_COUNT    (10 * TOTAL_CHANNELS)
+//#define PASSIVE_SCAN  // uncommnet here when you need passive scan
+
+#define CR  '\r'
+#define SHORT_WAIT  0.00032
+#define BUFF_LEN    4096
+#define ESSID_LEN   33
+#define MACADDR_LEN 6
+
+struct apinfo {
+    unsigned char essid[ESSID_LEN];
+    unsigned char bssid[MACADDR_LEN];
+    int power;
+};
+
+struct apinfo apinfos[MAX_AP_COUNT];
+int apinfo_count;
+
+Serial wifi(p13, p14);
+
+DigitalOut PRST(p15);
+
+class WiFiScanner {
+private:
+    int sequence;
+    unsigned char buff[BUFF_LEN];
+        
+    void wifiPutc(int c)
+    {
+        wifi.putc(c);
+    }
+
+    int wifiGetc()
+    {
+        return wifi.getc();
+    }
+
+    int num2hex(int i)
+    {
+        static const char hexadecimal[] = "0123456789ABCDEF";
+    
+        if ( i < 0 || i > 15 )
+            return '0';
+
+        return ((int)hexadecimal[i]);
+    }
+
+    int hex2num(int i)
+    {
+        switch (i) {
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+            return (i - '0');
+        case 'A':
+        case 'B':
+        case 'C':
+        case 'D':
+        case 'E':
+        case 'F':
+            return ( i - 'A' + 10);
+        case 'a':
+        case 'b':
+        case 'c':
+        case 'd':
+        case 'e':
+        case 'f':
+            return ( i - 'a' + 10);
+        }
+        return (-1);
+    }
+
+    void delayedPutc(unsigned char c)
+    {
+        wifiPutc(c);
+        wait(SHORT_WAIT);
+    }
+
+ 
+    void wifiWrite(unsigned char *data)
+    {
+        int i;
+        int len = ((int)data[3]) * 256 + data[2];
+
+        delayedPutc('*');
+        delayedPutc(num2hex((len >> 4) & 0xf));
+        delayedPutc(num2hex(len & 0xf));
+        delayedPutc('4');
+        delayedPutc(num2hex((len >> 8) & 0xf)); 
+        for ( i = 0; i < len; i++ ) {
+            if ( i == 1 ) {
+                delayedPutc(num2hex((sequence >> 4) & 0x0f));
+                delayedPutc(num2hex(sequence & 0x0f));
+            } else {
+                delayedPutc(num2hex((data[i] >> 4) & 0x0f));
+                delayedPutc(num2hex(data[i] & 0x0f));
+            }
+        }
+        delayedPutc(CR);
+        sequence++;
+    }
+
+    int wifiRead()
+    {
+        int len = 0;
+        int index = 0;
+        int c;
+    
+        while (true) {
+            c = wifiGetc();
+            if ( c == CR ) {
+                if ( (index - 5) >= len * 2 ) {
+                    break;
+                }
+
+                len = 0;
+                index = 0;
+                continue;
+            }
+            if ( index == 0 ) {
+                if ( c == '*' ) {
+                    index++;
+                } else {
+                    while (wifiGetc() != CR)
+                        ;   //empty loop body
+                }
+                continue;
+            }
+
+            c = hex2num(c);
+            if ( c < 0 ) {
+                while (wifiGetc() != CR)
+                    ;   // empty loop body
+                len = 0;
+                index = 0;
+                continue;
+            }
+            if ( index == 1 ) {
+                len = c << 4;
+            } else if ( index == 2 ) {
+                len |= c;
+            } else if ( index == 3 ) {
+                if ( c != 3 ) {
+                    return -3;
+                }
+            } else if ( index == 4 ) {
+                len |= c << 8;
+            } else if ( index & 1 ) {
+                buff[(index - 5)/2] = c << 4;
+            } else {
+                buff[(index - 5)/2] |= c;
+            }
+            index++;
+        }
+        return len;
+    }
+
+public:
+    WiFiScanner()
+    {
+        sequence = 0;
+    }
+    
+    void reset()
+    {
+        wifi.baud(BAUD_RATE);
+        wifi.format(8, Serial::None, 1);
+    
+        sequence = 0;
+        PRST = 0;       // reset BP3591
+        wait(1.0);    // perhaps needs 1 sec
+        PRST = 1;
+    }
+
+    void serialInit()
+    {
+        int i;
+        int c = 0;
+    
+        while (true) {
+            wifiPutc('A');
+            if (wifi.readable()) {
+               if ( c == '*' ) {
+                    c = wifiGetc();
+                    if ( c == CR ) {
+                        break;
+                    }
+                } else {
+                    c = wifiGetc();
+                }
+            }
+            wait(SHORT_WAIT);  // this wait is important
+        }
+
+        while (wifi.readable())
+            wifiGetc();
+        for ( i = 0; i < 8; i++ ) {
+            delayedPutc(0xf1);
+        }
+        c = 0;
+        while (true) {
+            if (wifi.readable()) {
+                if ( c == '*' ) {
+                    c = wifiGetc();
+                    if ( c == CR ) {
+                        break;
+                    }
+                } else {
+                    c = wifiGetc();
+                }
+            }
+        }
+    }
+
+    void waitStartup()
+    {
+        int i;
+        int len = 0;
+        bool loopFlag = true;
+        for (i = 0; loopFlag || len <= 0 || wifi.readable(); i++) {
+            len = wifiRead();
+            if ( len == 8 && buff[5] == 0x00 && buff[4] == 0x3d) {
+                loopFlag = false;
+            }
+            lcd.putc('+');
+        }
+    }
+
+    void scanMode()
+    {
+        // WID_SSID
+        unsigned char cmd0[] = { 0x57, 0x00, 0x08, 0x00, 0x00, 0x30, 0x01, 0x00 };
+        wifiWrite(cmd0);
+        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+            wait(SHORT_WAIT);
+        
+        // WID_BSS_TYPE
+        unsigned char cmd1[] = { 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00 };
+        wifiWrite(cmd1);
+        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+            wait(SHORT_WAIT);
+        
+        // WID_BCAST_SSID
+        unsigned char cmd2[] = { 0x57, 0x00, 0x08, 0x00, 0x15, 0x00, 0x01, 0x01 };
+        wifiWrite(cmd2);
+        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+            wait(SHORT_WAIT);
+        
+        // WID_SCAN_TYPE
+#ifdef  PASSIVE_SCAN
+        unsigned char cmd3[] = { 0x57, 0x00, 0x08, 0x00, 0x07, 0x00, 0x01, 0x00 };
+#else
+        unsigned char cmd3[] = { 0x57, 0x00, 0x08, 0x00, 0x07, 0x00, 0x01, 0x01 };
+#endif
+        wifiWrite(cmd3);
+        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+            wait(SHORT_WAIT);
+
+        // WID_ENABLE_CHANNEL
+        unsigned char cmd4[] = { 0x57, 0x02, 0x0b, 0x00, 0x24, 0x20, 0x04, 0xff, 0x1f, 0x00, 0x00 };
+        wifiWrite(cmd4);
+        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+            wait(SHORT_WAIT);
+
+        // WID_SITE_SURVEY
+#ifdef  MULTI_CHANNEL
+        unsigned char cmd5[] = { 0x57, 0x01, 0x08, 0x00, 0x0e, 0x00, 0x01, 0x11 };
+#else
+        unsigned char cmd5[] = { 0x57, 0x01, 0x08, 0x00, 0x0e, 0x00, 0x01, 0x01 };
+#endif
+        wifiWrite(cmd5);
+        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+            wait(SHORT_WAIT);
+        
+        // WID_SCAN_FILTER
+#ifdef  MULTI_CHANNEL
+        unsigned char cmd6[] = { 0x57, 0x02, 0x08, 0x00, 0x36, 0x00, 0x01, 0x00 };
+#else
+        unsigned char cmd6[] = { 0x57, 0x02, 0x08, 0x00, 0x36, 0x00, 0x01, 0x00 };
+#endif
+        wifiWrite(cmd6);
+        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+            wait(SHORT_WAIT);
+
+#ifdef  PASSIVE_SCAN
+        // WID_SITE_SURVEY_SCAN_TIME
+        unsigned char cmd7[] = { 0x57, 0x00, 0x09, 0x00, 0x0e, 0x10, 0x02, 0x00, 0x02 };
+        wifiWrite(cmd7);
+        while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+            wait(SHORT_WAIT);
+#endif
+    }
+
+    void doScan()
+    {
+        int i, len, channel;
+        int count, write_index;
+    
+        apinfo_count = 0;
+        for (channel = 0; channel < TOTAL_CHANNELS; channel++ ) {
+            myled1 = (channel >> 3) & 1;
+            myled2 = (channel >> 2) & 1;
+            myled3 = (channel >> 1) & 1;
+            myled4 = channel & 1;
+        
+            // WID_CURRENT_CHANNEL
+#ifdef  MULTI_CHANNEL
+            unsigned char cmd8[] = { 0x57, 0x02, 0x08, 0x00, 0x02, 0x00, 0x01, 0x10 };
+            cmd8[7] = channel + 1; // 1 origin
+            wifiWrite(cmd8);
+            while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+                wait(SHORT_WAIT);
+#endif
+            // WID_START_SCAN_REQ
+            unsigned char cmd9[] = { 0x57, 0x02, 0x08, 0x00, 0x1e, 0x00, 0x01, 0x01 };
+            wifiWrite(cmd9);
+            while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1))
+                wait(SHORT_WAIT);
+
+#ifdef  PASSIVE_SCAN
+            wait(0.5);
+#else
+            wait(0.02);
+#endif
+    
+            // WID_SITE_SURVER_RESULTS
+            unsigned char cmd10[] = { 0x51, 0x03, 0x06, 0x00, 0x12, 0x30 };
+            wifiWrite(cmd10);
+            while ( (len = wifiRead()) <= 0 || (buff[5] != 0x30 || buff[4] != 0x12))
+                wait(SHORT_WAIT);
+            if ( len < 10 ) {
+                continue;
+            }
+            count = (buff[7] - 2) / 44;
+            for ( i = 0; i < count; i++ ) {
+                for ( write_index = 0; write_index < apinfo_count; write_index++) {
+                    if ( memcmp(apinfos[write_index].essid, buff + (9 + i *44), 33) == 0 &&
+                         memcmp(apinfos[write_index].bssid, buff + (9 + i * 44 + 36), 6) == 0 ) {
+                        break;  // already recorded
+                    }
+                }
+                if ( write_index == apinfo_count ) {
+                    memcpy(apinfos[write_index].essid, buff + (9 + i * 44), 33);
+                    memcpy(apinfos[write_index].bssid, buff + (9 + i * 44 + 36), 6);
+                    apinfos[write_index].power = (signed char)buff[9 + i * 44 + 42];
+                    apinfo_count++;
+                } else if ( apinfos[write_index].power < (signed char)buff[9 + i * 44 + 42] ) {
+                    apinfos[write_index].power = (signed char)buff[9 + i * 44 + 42];
+                }
+            }
+        }
+    }
 };
\ No newline at end of file