This program calculate location of Wi-Fi receiver, by using AP beacon. Please check the Japanese magazine "Interface 2012/12".
Revision 1:2f2f793fcf4f, committed 2012-09-10
- Comitter:
- nakata
- Date:
- Mon Sep 10 07:15:35 2012 +0000
- Parent:
- 0:4eaf38ccb19c
- Commit message:
- for Interface
Changed in this revision
WiFiScanner.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 4eaf38ccb19c -r 2f2f793fcf4f WiFiScanner.h --- 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