This program calculate location of Wi-Fi receiver, by using AP beacon. Please check the Japanese magazine "Interface 2012/12".
WiFiScanner.h
- Committer:
- nakata
- Date:
- 2012-09-10
- Revision:
- 1:2f2f793fcf4f
- Parent:
- 0:4eaf38ccb19c
File content as of revision 1:2f2f793fcf4f:
#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]; } } } } };