This program calculate location of Wi-Fi receiver, by using AP beacon. Please check the Japanese magazine "Interface 2012/12".
WiFiScanner.h
00001 #include <string.h> 00002 00003 #define BAUD_RATE 115200 00004 00005 #define MULTI_CHANNEL 00006 #ifdef MULTI_CHANNEL 00007 #define TOTAL_CHANNELS 13 00008 #else 00009 #define TOTAL_CHANNELS 1 00010 #endif 00011 #define MAX_AP_COUNT (10 * TOTAL_CHANNELS) 00012 //#define PASSIVE_SCAN // uncommnet here when you need passive scan 00013 00014 #define CR '\r' 00015 #define SHORT_WAIT 0.00032 00016 #define BUFF_LEN 4096 00017 #define ESSID_LEN 33 00018 #define MACADDR_LEN 6 00019 00020 struct apinfo { 00021 unsigned char essid[ESSID_LEN]; 00022 unsigned char bssid[MACADDR_LEN]; 00023 int power; 00024 }; 00025 00026 struct apinfo apinfos[MAX_AP_COUNT]; 00027 int apinfo_count; 00028 00029 Serial wifi(p13, p14); 00030 00031 DigitalOut PRST(p15); 00032 00033 class WiFiScanner { 00034 private: 00035 int sequence; 00036 unsigned char buff[BUFF_LEN]; 00037 00038 void wifiPutc(int c) 00039 { 00040 wifi.putc(c); 00041 } 00042 00043 int wifiGetc() 00044 { 00045 return wifi.getc(); 00046 } 00047 00048 int num2hex(int i) 00049 { 00050 static const char hexadecimal[] = "0123456789ABCDEF"; 00051 00052 if ( i < 0 || i > 15 ) 00053 return '0'; 00054 00055 return ((int)hexadecimal[i]); 00056 } 00057 00058 int hex2num(int i) 00059 { 00060 switch (i) { 00061 case '0': 00062 case '1': 00063 case '2': 00064 case '3': 00065 case '4': 00066 case '5': 00067 case '6': 00068 case '7': 00069 case '8': 00070 case '9': 00071 return (i - '0'); 00072 case 'A': 00073 case 'B': 00074 case 'C': 00075 case 'D': 00076 case 'E': 00077 case 'F': 00078 return ( i - 'A' + 10); 00079 case 'a': 00080 case 'b': 00081 case 'c': 00082 case 'd': 00083 case 'e': 00084 case 'f': 00085 return ( i - 'a' + 10); 00086 } 00087 return (-1); 00088 } 00089 00090 void delayedPutc(unsigned char c) 00091 { 00092 wifiPutc(c); 00093 wait(SHORT_WAIT); 00094 } 00095 00096 00097 void wifiWrite(unsigned char *data) 00098 { 00099 int i; 00100 int len = ((int)data[3]) * 256 + data[2]; 00101 00102 delayedPutc('*'); 00103 delayedPutc(num2hex((len >> 4) & 0xf)); 00104 delayedPutc(num2hex(len & 0xf)); 00105 delayedPutc('4'); 00106 delayedPutc(num2hex((len >> 8) & 0xf)); 00107 for ( i = 0; i < len; i++ ) { 00108 if ( i == 1 ) { 00109 delayedPutc(num2hex((sequence >> 4) & 0x0f)); 00110 delayedPutc(num2hex(sequence & 0x0f)); 00111 } else { 00112 delayedPutc(num2hex((data[i] >> 4) & 0x0f)); 00113 delayedPutc(num2hex(data[i] & 0x0f)); 00114 } 00115 } 00116 delayedPutc(CR); 00117 sequence++; 00118 } 00119 00120 int wifiRead() 00121 { 00122 int len = 0; 00123 int index = 0; 00124 int c; 00125 00126 while (true) { 00127 c = wifiGetc(); 00128 if ( c == CR ) { 00129 if ( (index - 5) >= len * 2 ) { 00130 break; 00131 } 00132 00133 len = 0; 00134 index = 0; 00135 continue; 00136 } 00137 if ( index == 0 ) { 00138 if ( c == '*' ) { 00139 index++; 00140 } else { 00141 while (wifiGetc() != CR) 00142 ; //empty loop body 00143 } 00144 continue; 00145 } 00146 00147 c = hex2num(c); 00148 if ( c < 0 ) { 00149 while (wifiGetc() != CR) 00150 ; // empty loop body 00151 len = 0; 00152 index = 0; 00153 continue; 00154 } 00155 if ( index == 1 ) { 00156 len = c << 4; 00157 } else if ( index == 2 ) { 00158 len |= c; 00159 } else if ( index == 3 ) { 00160 if ( c != 3 ) { 00161 return -3; 00162 } 00163 } else if ( index == 4 ) { 00164 len |= c << 8; 00165 } else if ( index & 1 ) { 00166 buff[(index - 5)/2] = c << 4; 00167 } else { 00168 buff[(index - 5)/2] |= c; 00169 } 00170 index++; 00171 } 00172 return len; 00173 } 00174 00175 public: 00176 WiFiScanner() 00177 { 00178 sequence = 0; 00179 } 00180 00181 void reset() 00182 { 00183 wifi.baud(BAUD_RATE); 00184 wifi.format(8, Serial::None, 1); 00185 00186 sequence = 0; 00187 PRST = 0; // reset BP3591 00188 wait(1.0); // perhaps needs 1 sec 00189 PRST = 1; 00190 } 00191 00192 void serialInit() 00193 { 00194 int i; 00195 int c = 0; 00196 00197 while (true) { 00198 wifiPutc('A'); 00199 if (wifi.readable()) { 00200 if ( c == '*' ) { 00201 c = wifiGetc(); 00202 if ( c == CR ) { 00203 break; 00204 } 00205 } else { 00206 c = wifiGetc(); 00207 } 00208 } 00209 wait(SHORT_WAIT); // this wait is important 00210 } 00211 00212 while (wifi.readable()) 00213 wifiGetc(); 00214 for ( i = 0; i < 8; i++ ) { 00215 delayedPutc(0xf1); 00216 } 00217 c = 0; 00218 while (true) { 00219 if (wifi.readable()) { 00220 if ( c == '*' ) { 00221 c = wifiGetc(); 00222 if ( c == CR ) { 00223 break; 00224 } 00225 } else { 00226 c = wifiGetc(); 00227 } 00228 } 00229 } 00230 } 00231 00232 void waitStartup() 00233 { 00234 int i; 00235 int len = 0; 00236 bool loopFlag = true; 00237 for (i = 0; loopFlag || len <= 0 || wifi.readable(); i++) { 00238 len = wifiRead(); 00239 if ( len == 8 && buff[5] == 0x00 && buff[4] == 0x3d) { 00240 loopFlag = false; 00241 } 00242 lcd.putc('+'); 00243 } 00244 } 00245 00246 void scanMode() 00247 { 00248 // WID_SSID 00249 unsigned char cmd0[] = { 0x57, 0x00, 0x08, 0x00, 0x00, 0x30, 0x01, 0x00 }; 00250 wifiWrite(cmd0); 00251 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00252 wait(SHORT_WAIT); 00253 00254 // WID_BSS_TYPE 00255 unsigned char cmd1[] = { 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00 }; 00256 wifiWrite(cmd1); 00257 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00258 wait(SHORT_WAIT); 00259 00260 // WID_BCAST_SSID 00261 unsigned char cmd2[] = { 0x57, 0x00, 0x08, 0x00, 0x15, 0x00, 0x01, 0x01 }; 00262 wifiWrite(cmd2); 00263 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00264 wait(SHORT_WAIT); 00265 00266 // WID_SCAN_TYPE 00267 #ifdef PASSIVE_SCAN 00268 unsigned char cmd3[] = { 0x57, 0x00, 0x08, 0x00, 0x07, 0x00, 0x01, 0x00 }; 00269 #else 00270 unsigned char cmd3[] = { 0x57, 0x00, 0x08, 0x00, 0x07, 0x00, 0x01, 0x01 }; 00271 #endif 00272 wifiWrite(cmd3); 00273 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00274 wait(SHORT_WAIT); 00275 00276 // WID_ENABLE_CHANNEL 00277 unsigned char cmd4[] = { 0x57, 0x02, 0x0b, 0x00, 0x24, 0x20, 0x04, 0xff, 0x1f, 0x00, 0x00 }; 00278 wifiWrite(cmd4); 00279 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00280 wait(SHORT_WAIT); 00281 00282 // WID_SITE_SURVEY 00283 #ifdef MULTI_CHANNEL 00284 unsigned char cmd5[] = { 0x57, 0x01, 0x08, 0x00, 0x0e, 0x00, 0x01, 0x11 }; 00285 #else 00286 unsigned char cmd5[] = { 0x57, 0x01, 0x08, 0x00, 0x0e, 0x00, 0x01, 0x01 }; 00287 #endif 00288 wifiWrite(cmd5); 00289 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00290 wait(SHORT_WAIT); 00291 00292 // WID_SCAN_FILTER 00293 #ifdef MULTI_CHANNEL 00294 unsigned char cmd6[] = { 0x57, 0x02, 0x08, 0x00, 0x36, 0x00, 0x01, 0x00 }; 00295 #else 00296 unsigned char cmd6[] = { 0x57, 0x02, 0x08, 0x00, 0x36, 0x00, 0x01, 0x00 }; 00297 #endif 00298 wifiWrite(cmd6); 00299 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00300 wait(SHORT_WAIT); 00301 00302 #ifdef PASSIVE_SCAN 00303 // WID_SITE_SURVEY_SCAN_TIME 00304 unsigned char cmd7[] = { 0x57, 0x00, 0x09, 0x00, 0x0e, 0x10, 0x02, 0x00, 0x02 }; 00305 wifiWrite(cmd7); 00306 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00307 wait(SHORT_WAIT); 00308 #endif 00309 } 00310 00311 void doScan() 00312 { 00313 int i, len, channel; 00314 int count, write_index; 00315 00316 apinfo_count = 0; 00317 for (channel = 0; channel < TOTAL_CHANNELS; channel++ ) { 00318 myled1 = (channel >> 3) & 1; 00319 myled2 = (channel >> 2) & 1; 00320 myled3 = (channel >> 1) & 1; 00321 myled4 = channel & 1; 00322 00323 // WID_CURRENT_CHANNEL 00324 #ifdef MULTI_CHANNEL 00325 unsigned char cmd8[] = { 0x57, 0x02, 0x08, 0x00, 0x02, 0x00, 0x01, 0x10 }; 00326 cmd8[7] = channel + 1; // 1 origin 00327 wifiWrite(cmd8); 00328 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00329 wait(SHORT_WAIT); 00330 #endif 00331 // WID_START_SCAN_REQ 00332 unsigned char cmd9[] = { 0x57, 0x02, 0x08, 0x00, 0x1e, 0x00, 0x01, 0x01 }; 00333 wifiWrite(cmd9); 00334 while ( wifiRead() <= 0 || (buff[5] != 0x00 || buff[4] != 0x05 || buff[7] != 1)) 00335 wait(SHORT_WAIT); 00336 00337 #ifdef PASSIVE_SCAN 00338 wait(0.5); 00339 #else 00340 wait(0.02); 00341 #endif 00342 00343 // WID_SITE_SURVER_RESULTS 00344 unsigned char cmd10[] = { 0x51, 0x03, 0x06, 0x00, 0x12, 0x30 }; 00345 wifiWrite(cmd10); 00346 while ( (len = wifiRead()) <= 0 || (buff[5] != 0x30 || buff[4] != 0x12)) 00347 wait(SHORT_WAIT); 00348 if ( len < 10 ) { 00349 continue; 00350 } 00351 count = (buff[7] - 2) / 44; 00352 for ( i = 0; i < count; i++ ) { 00353 for ( write_index = 0; write_index < apinfo_count; write_index++) { 00354 if ( memcmp(apinfos[write_index].essid, buff + (9 + i *44), 33) == 0 && 00355 memcmp(apinfos[write_index].bssid, buff + (9 + i * 44 + 36), 6) == 0 ) { 00356 break; // already recorded 00357 } 00358 } 00359 if ( write_index == apinfo_count ) { 00360 memcpy(apinfos[write_index].essid, buff + (9 + i * 44), 33); 00361 memcpy(apinfos[write_index].bssid, buff + (9 + i * 44 + 36), 6); 00362 apinfos[write_index].power = (signed char)buff[9 + i * 44 + 42]; 00363 apinfo_count++; 00364 } else if ( apinfos[write_index].power < (signed char)buff[9 + i * 44 + 42] ) { 00365 apinfos[write_index].power = (signed char)buff[9 + i * 44 + 42]; 00366 } 00367 } 00368 } 00369 } 00370 };
Generated on Tue Jul 12 2022 20:37:42 by 1.7.2