This program calculate location of Wi-Fi receiver, by using AP beacon. Please check the Japanese magazine "Interface 2012/12".
Diff: WiFiScanner.h
- Revision:
- 0:4eaf38ccb19c
- Child:
- 1:2f2f793fcf4f
diff -r 000000000000 -r 4eaf38ccb19c WiFiScanner.h --- /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