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

Dependencies:   TextLCD mbed

Revision:
0:4eaf38ccb19c
Child:
1:2f2f793fcf4f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WiFiScanner.h	Fri Aug 24 03:21:43 2012 +0000
@@ -0,0 +1,393 @@
+#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];
+                }
+            }
+        }
+    }
+};
\ No newline at end of file