Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of WiflyInterface by
Wifly.cpp
00001 /* Copyright (C) 2012 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "mbed.h" 00020 #include "Wifly.h" 00021 #include <string> 00022 #include <algorithm> 00023 00024 //Debug is disabled by default 00025 #if (0 && !defined(TARGET_LPC11U24)) 00026 #define DBG(x, ...) std::printf("[Wifly : DBG]"x"\r\n", ##__VA_ARGS__); 00027 #define WARN(x, ...) std::printf("[Wifly : WARN]"x"\r\n", ##__VA_ARGS__); 00028 #define ERR(x, ...) std::printf("[Wifly : ERR]"x"\r\n", ##__VA_ARGS__); 00029 #else 00030 #define DBG(x, ...) 00031 #define WARN(x, ...) 00032 #define ERR(x, ...) 00033 #endif 00034 00035 #if !defined(TARGET_LPC11U24) 00036 #define INFO(x, ...) printf("[Wifly : INFO]"x"\r\n", ##__VA_ARGS__); 00037 #else 00038 #define INFO(x, ...) 00039 #endif 00040 00041 #define MAX_TRY_JOIN 3 00042 00043 Wifly * Wifly::inst; 00044 00045 Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec): 00046 wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), buf_wifly(256) 00047 { 00048 memset(&state, 0, sizeof(state)); 00049 state.sec = sec; 00050 00051 // change all ' ' in '$' in the ssid and the passphrase 00052 strcpy(this->ssid, ssid); 00053 for (int i = 0; i < strlen(ssid); i++) { 00054 if (this->ssid[i] == ' ') 00055 this->ssid[i] = '$'; 00056 } 00057 strcpy(this->phrase, phrase); 00058 for (int i = 0; i < strlen(phrase); i++) { 00059 if (this->phrase[i] == ' ') 00060 this->phrase[i] = '$'; 00061 } 00062 00063 inst = this; 00064 attach_rx(false); 00065 state.cmd_mode = false; 00066 } 00067 00068 bool Wifly::join() 00069 { 00070 char cmd[75]; 00071 00072 for (int i= 0; i < MAX_TRY_JOIN; i++) { 00073 00074 // force auto join 00075 if (!sendCommand("set w j 1\r", "AOK")) 00076 continue; 00077 00078 //no echo 00079 if (!sendCommand("set u m 1\r", "AOK")) 00080 continue; 00081 00082 // set time 00083 if (!sendCommand("set c t 30\r", "AOK")) 00084 continue; 00085 00086 // set size 00087 if (!sendCommand("set c s 1420\r", "AOK")) 00088 continue; 00089 00090 // red led on when tcp connection active 00091 if (!sendCommand("set s i 0x40\r", "AOK")) 00092 continue; 00093 00094 // no string sent to the tcp client 00095 if (!sendCommand("set c r 0\r", "AOK")) 00096 continue; 00097 00098 // tcp protocol 00099 if (!sendCommand("set i p 2\r", "AOK")) 00100 continue; 00101 00102 // tcp retry 00103 if (!sendCommand("set i f 0x7\r", "AOK")) 00104 continue; 00105 00106 // set dns server 00107 if (!sendCommand("set d n rn.microchip.com\r", "AOK")) 00108 continue; 00109 00110 //dhcp 00111 sprintf(cmd, "set i d %d\r", (state.dhcp) ? 1 : 0); 00112 if (!sendCommand(cmd, "AOK")) 00113 continue; 00114 00115 // ssid 00116 sprintf(cmd, "set w s %s\r", ssid); 00117 if (!sendCommand(cmd, "AOK")) 00118 continue; 00119 00120 //auth 00121 sprintf(cmd, "set w a %d\r", state.sec); 00122 if (!sendCommand(cmd, "AOK")) 00123 continue; 00124 00125 //tcp 00126 sprintf(cmd, "set comm idle 5%d\r", state.sec); 00127 if (!sendCommand(cmd, "AOK")) 00128 continue; 00129 00130 // if no dhcp, set ip, netmask and gateway 00131 if (!state.dhcp) { 00132 DBG("not dhcp\r"); 00133 00134 sprintf(cmd, "set i a %s\r\n", ip); 00135 if (!sendCommand(cmd, "AOK")) 00136 continue; 00137 00138 sprintf(cmd, "set i n %s\r", netmask); 00139 if (!sendCommand(cmd, "AOK")) 00140 continue; 00141 00142 sprintf(cmd, "set i g %s\r", gateway); 00143 if (!sendCommand(cmd, "AOK")) 00144 continue; 00145 } 00146 00147 //key step 00148 if (state.sec != NONE) { 00149 if (state.sec == WPA) 00150 sprintf(cmd, "set w p %s\r", phrase); 00151 else if (state.sec == WEP_128) 00152 sprintf(cmd, "set w k %s\r", phrase); 00153 00154 if (!sendCommand(cmd, "AOK")) 00155 continue; 00156 } 00157 00158 //join the network (10s timeout) 00159 if (state.dhcp) { 00160 if (!sendCommand("join\r", "DHCP=ON", NULL, 10000)) 00161 continue; 00162 } else { 00163 if (!sendCommand("join\r", "Associated", NULL, 10000)) 00164 continue; 00165 } 00166 00167 if (!sendCommand("save\r", "Stor")) 00168 continue; 00169 00170 exit(); 00171 00172 state.associated = true; 00173 INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, getStringSecurity()); 00174 return true; 00175 } 00176 return false; 00177 } 00178 00179 00180 bool Wifly::setProtocol(Protocol p) 00181 { 00182 // use udp auto pairing 00183 char cmd[20]; 00184 sprintf(cmd, "set i p %d\r", p); 00185 if (!sendCommand(cmd, "AOK")) 00186 return false; 00187 00188 switch(p) { 00189 case TCP: 00190 // set ip flags: tcp retry enabled 00191 if (!sendCommand("set i f 0x07\r", "AOK")) 00192 return false; 00193 break; 00194 case UDP: 00195 // set ip flags: udp auto pairing enabled 00196 if (!sendCommand("set i h 0.0.0.0\r", "AOK")) 00197 return false; 00198 if (!sendCommand("set i f 0x40\r", "AOK")) 00199 return false; 00200 break; 00201 } 00202 state.proto = p; 00203 return true; 00204 } 00205 00206 char * Wifly::getStringSecurity() 00207 { 00208 switch(state.sec) { 00209 case NONE: 00210 return "NONE"; 00211 case WEP_128: 00212 return "WEP_128"; 00213 case WPA: 00214 return "WPA"; 00215 } 00216 return "UNKNOWN"; 00217 } 00218 00219 bool Wifly::connect(const char * host, int port) 00220 { 00221 char rcv[20]; 00222 char cmd[20]; 00223 00224 // try to open 00225 sprintf(cmd, "open %s %d\r", host, port); 00226 if (sendCommand(cmd, "OPEN", NULL, 10000)) { 00227 state.tcp = true; 00228 state.cmd_mode = false; 00229 return true; 00230 } 00231 00232 // if failed, retry and parse the response 00233 if (sendCommand(cmd, NULL, rcv, 5000)) { 00234 if (strstr(rcv, "OPEN") == NULL) { 00235 if (strstr(rcv, "Connected") != NULL) { 00236 wait(0.25); 00237 if (!sendCommand("close\r", "CLOS")) 00238 return false; 00239 wait(0.25); 00240 if (!sendCommand(cmd, "OPEN", NULL, 10000)) 00241 return false; 00242 } else { 00243 return false; 00244 } 00245 } 00246 } else { 00247 return false; 00248 } 00249 00250 state.tcp = true; 00251 state.cmd_mode = false; 00252 00253 return true; 00254 } 00255 00256 00257 bool Wifly::gethostbyname(const char * host, char * ip) 00258 { 00259 string h = host; 00260 char cmd[30], rcv[100]; 00261 int l = 0; 00262 char * point; 00263 int nb_digits = 0; 00264 00265 // no dns needed 00266 int pos = h.find("."); 00267 if (pos != string::npos) { 00268 string sub = h.substr(0, h.find(".")); 00269 nb_digits = atoi(sub.c_str()); 00270 } 00271 //printf("substrL %s\r\n", sub.c_str()); 00272 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) { 00273 strcpy(ip, host); 00274 } 00275 // dns needed 00276 else { 00277 nb_digits = 0; 00278 sprintf(cmd, "lookup %s\r", host); 00279 if (!sendCommand(cmd, NULL, rcv)) 00280 return false; 00281 00282 // look for the ip address 00283 char * begin = strstr(rcv, "=") + 1; 00284 for (int i = 0; i < 3; i++) { 00285 point = strstr(begin + l, "."); 00286 DBG("str: %s", begin + l); 00287 l += point - (begin + l) + 1; 00288 } 00289 DBG("str: %s", begin + l); 00290 while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') { 00291 DBG("digit: %c", *(begin + l + nb_digits)); 00292 nb_digits++; 00293 } 00294 memcpy(ip, begin, l + nb_digits); 00295 ip[l+nb_digits] = 0; 00296 DBG("ip from dns: %s", ip); 00297 } 00298 return true; 00299 } 00300 00301 00302 void Wifly::flush() 00303 { 00304 buf_wifly.flush(); 00305 } 00306 00307 bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout) 00308 { 00309 if (!state.cmd_mode) { 00310 cmdMode(); 00311 } 00312 if (send(cmd, strlen(cmd), ack, res, timeout) == -1) { 00313 ERR("sendCommand: cannot %s\r\n", cmd); 00314 exit(); 00315 return false; 00316 } 00317 return true; 00318 } 00319 00320 bool Wifly::cmdMode() 00321 { 00322 // if already in cmd mode, return 00323 if (state.cmd_mode) 00324 return true; 00325 00326 if (send("$$$", 3, "CMD") == -1) { 00327 ERR("cannot enter in cmd mode\r\n"); 00328 exit(); 00329 return false; 00330 } 00331 state.cmd_mode = true; 00332 return true; 00333 } 00334 00335 bool Wifly::disconnect() 00336 { 00337 // if already disconnected, return 00338 if (!state.associated) 00339 return true; 00340 00341 if (!sendCommand("leave\r", "DeAuth")) 00342 return false; 00343 exit(); 00344 00345 state.associated = false; 00346 return true; 00347 00348 } 00349 00350 bool Wifly::is_associated() 00351 { 00352 bool flag=sendCommand("show c\r", "8630", NULL, 1000); 00353 exit(); 00354 return flag; 00355 } 00356 00357 bool Wifly::is_connected() 00358 { 00359 return (tcp_status.read() == 1) ? true : false; 00360 } 00361 00362 00363 void Wifly::reset() 00364 { 00365 reset_pin = 0; 00366 wait(0.2); 00367 reset_pin = 1; 00368 wait(0.2); 00369 } 00370 00371 bool Wifly::reboot() 00372 { 00373 // if already in cmd mode, return 00374 if (!sendCommand("reboot\r")) 00375 return false; 00376 00377 wait(0.3); 00378 00379 state.cmd_mode = false; 00380 return true; 00381 } 00382 00383 bool Wifly::close() 00384 { 00385 // if not connected, return 00386 if (!state.tcp) 00387 return true; 00388 00389 wait(0.25); 00390 if (!sendCommand("close\r", "CLOS")) 00391 return false; 00392 exit(); 00393 00394 state.tcp = false; 00395 return true; 00396 } 00397 00398 00399 int Wifly::putc(char c) 00400 { 00401 while (!wifi.writeable()); 00402 return wifi.putc(c); 00403 } 00404 00405 00406 bool Wifly::exit() 00407 { 00408 flush(); 00409 if (!state.cmd_mode) 00410 return true; 00411 if (!sendCommand("exit\r", "EXIT")) 00412 return false; 00413 state.cmd_mode = false; 00414 flush(); 00415 return true; 00416 } 00417 00418 00419 int Wifly::readable() 00420 { 00421 return buf_wifly.available(); 00422 } 00423 00424 int Wifly::writeable() 00425 { 00426 return wifi.writeable(); 00427 } 00428 00429 char Wifly::getc() 00430 { 00431 char c; 00432 while (!buf_wifly.available()); 00433 buf_wifly.dequeue(&c); 00434 return c; 00435 } 00436 00437 void Wifly::handler_rx(void) 00438 { 00439 //read characters 00440 while (wifi.readable()) 00441 buf_wifly.queue(wifi.getc()); 00442 } 00443 00444 void Wifly::attach_rx(bool callback) 00445 { 00446 if (!callback) 00447 wifi.attach(NULL); 00448 else 00449 wifi.attach(this, &Wifly::handler_rx); 00450 } 00451 00452 00453 int Wifly::send(const char * str, int len, const char * ACK, char * res, int timeout) 00454 { 00455 char read; 00456 size_t found = string::npos; 00457 string checking; 00458 Timer tmr; 00459 int result = 0; 00460 00461 DBG("will send: %s\r\n",str); 00462 00463 attach_rx(false); 00464 00465 //We flush the buffer 00466 while (wifi.readable()) 00467 wifi.getc(); 00468 00469 if (!ACK || !strcmp(ACK, "NO")) { 00470 for (int i = 0; i < len; i++) 00471 result = (putc(str[i]) == str[i]) ? result + 1 : result; 00472 } else { 00473 //We flush the buffer 00474 while (wifi.readable()) 00475 wifi.getc(); 00476 00477 tmr.start(); 00478 for (int i = 0; i < len; i++) 00479 result = (putc(str[i]) == str[i]) ? result + 1 : result; 00480 00481 while (1) { 00482 if (tmr.read_ms() > timeout) { 00483 //We flush the buffer 00484 while (wifi.readable()) 00485 wifi.getc(); 00486 00487 DBG("check: %s\r\n", checking.c_str()); 00488 00489 attach_rx(true); 00490 return -1; 00491 } else if (wifi.readable()) { 00492 read = wifi.getc(); 00493 if ( read != '\r' && read != '\n') { 00494 checking += read; 00495 found = checking.find(ACK); 00496 if (found != string::npos) { 00497 wait(0.01); 00498 00499 //We flush the buffer 00500 while (wifi.readable()) 00501 wifi.getc(); 00502 00503 break; 00504 } 00505 } 00506 } 00507 } 00508 DBG("check: %s\r\n", checking.c_str()); 00509 00510 attach_rx(true); 00511 return result; 00512 } 00513 00514 //the user wants the result from the command (ACK == NULL, res != NULL) 00515 if ( res != NULL) { 00516 int i = 0; 00517 Timer timeout; 00518 timeout.start(); 00519 tmr.reset(); 00520 while (1) { 00521 if (timeout.read() > 2) { 00522 if (i == 0) { 00523 res = NULL; 00524 break; 00525 } 00526 res[i] = '\0'; 00527 DBG("user str 1: %s\r\n", res); 00528 00529 break; 00530 } else { 00531 if (tmr.read_ms() > 300) { 00532 res[i] = '\0'; 00533 DBG("user str: %s\r\n", res); 00534 00535 break; 00536 } 00537 if (wifi.readable()) { 00538 tmr.start(); 00539 read = wifi.getc(); 00540 00541 // we drop \r and \n 00542 if ( read != '\r' && read != '\n') { 00543 res[i++] = read; 00544 } 00545 } 00546 } 00547 } 00548 DBG("user str: %s\r\n", res); 00549 } 00550 00551 //We flush the buffer 00552 while (wifi.readable()) 00553 wifi.getc(); 00554 00555 attach_rx(true); 00556 DBG("result: %d\r\n", result) 00557 return result; 00558 }
Generated on Wed Jul 13 2022 07:41:28 by
