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 1024\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 0%d\r", state.sec); 00127 if (!sendCommand(cmd, "AOK")) 00128 00129 // if no dhcp, set ip, netmask and gateway 00130 if (!state.dhcp) { 00131 DBG("not dhcp\r"); 00132 00133 sprintf(cmd, "set i a %s\r\n", ip); 00134 if (!sendCommand(cmd, "AOK")) 00135 continue; 00136 00137 sprintf(cmd, "set i n %s\r", netmask); 00138 if (!sendCommand(cmd, "AOK")) 00139 continue; 00140 00141 sprintf(cmd, "set i g %s\r", gateway); 00142 if (!sendCommand(cmd, "AOK")) 00143 continue; 00144 } 00145 00146 //key step 00147 if (state.sec != NONE) { 00148 if (state.sec == WPA) 00149 sprintf(cmd, "set w p %s\r", phrase); 00150 else if (state.sec == WEP_128) 00151 sprintf(cmd, "set w k %s\r", phrase); 00152 00153 if (!sendCommand(cmd, "AOK")) 00154 continue; 00155 } 00156 00157 //join the network (10s timeout) 00158 if (state.dhcp) { 00159 if (!sendCommand("join\r", "DHCP=ON", NULL, 10000)) 00160 continue; 00161 } else { 00162 if (!sendCommand("join\r", "Associated", NULL, 10000)) 00163 continue; 00164 } 00165 00166 if (!sendCommand("save\r", "Stor")) 00167 continue; 00168 00169 exit(); 00170 00171 state.associated = true; 00172 INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, getStringSecurity()); 00173 return true; 00174 } 00175 return false; 00176 } 00177 00178 00179 bool Wifly::setProtocol(Protocol p) 00180 { 00181 // use udp auto pairing 00182 char cmd[20]; 00183 sprintf(cmd, "set i p %d\r", p); 00184 if (!sendCommand(cmd, "AOK")) 00185 return false; 00186 00187 switch(p) { 00188 case TCP: 00189 // set ip flags: tcp retry enabled 00190 if (!sendCommand("set i f 0x07\r", "AOK")) 00191 return false; 00192 break; 00193 case UDP: 00194 // set ip flags: udp auto pairing enabled 00195 if (!sendCommand("set i h 0.0.0.0\r", "AOK")) 00196 return false; 00197 if (!sendCommand("set i f 0x40\r", "AOK")) 00198 return false; 00199 break; 00200 } 00201 state.proto = p; 00202 return true; 00203 } 00204 00205 char * Wifly::getStringSecurity() 00206 { 00207 switch(state.sec) { 00208 case NONE: 00209 return "NONE"; 00210 case WEP_128: 00211 return "WEP_128"; 00212 case WPA: 00213 return "WPA"; 00214 } 00215 return "UNKNOWN"; 00216 } 00217 00218 bool Wifly::connect(const char * host, int port) 00219 { 00220 char rcv[20]; 00221 char cmd[20]; 00222 00223 // try to open 00224 sprintf(cmd, "open %s %d\r", host, port); 00225 if (sendCommand(cmd, "OPEN", NULL, 10000)) { 00226 state.tcp = true; 00227 state.cmd_mode = false; 00228 return true; 00229 } 00230 00231 // if failed, retry and parse the response 00232 if (sendCommand(cmd, NULL, rcv, 5000)) { 00233 if (strstr(rcv, "OPEN") == NULL) { 00234 if (strstr(rcv, "Connected") != NULL) { 00235 wait(0.25); 00236 if (!sendCommand("close\r", "CLOS")) 00237 return false; 00238 wait(0.25); 00239 if (!sendCommand(cmd, "OPEN", NULL, 10000)) 00240 return false; 00241 } else { 00242 return false; 00243 } 00244 } 00245 } else { 00246 return false; 00247 } 00248 00249 state.tcp = true; 00250 state.cmd_mode = false; 00251 00252 return true; 00253 } 00254 00255 00256 bool Wifly::gethostbyname(const char * host, char * ip) 00257 { 00258 string h = host; 00259 char cmd[30], rcv[100]; 00260 int l = 0; 00261 char * point; 00262 int nb_digits = 0; 00263 00264 // no dns needed 00265 int pos = h.find("."); 00266 if (pos != string::npos) { 00267 string sub = h.substr(0, h.find(".")); 00268 nb_digits = atoi(sub.c_str()); 00269 } 00270 //printf("substrL %s\r\n", sub.c_str()); 00271 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) { 00272 strcpy(ip, host); 00273 } 00274 // dns needed 00275 else { 00276 nb_digits = 0; 00277 sprintf(cmd, "lookup %s\r", host); 00278 if (!sendCommand(cmd, NULL, rcv)) 00279 return false; 00280 00281 // look for the ip address 00282 char * begin = strstr(rcv, "=") + 1; 00283 for (int i = 0; i < 3; i++) { 00284 point = strstr(begin + l, "."); 00285 DBG("str: %s", begin + l); 00286 l += point - (begin + l) + 1; 00287 } 00288 DBG("str: %s", begin + l); 00289 while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') { 00290 DBG("digit: %c", *(begin + l + nb_digits)); 00291 nb_digits++; 00292 } 00293 memcpy(ip, begin, l + nb_digits); 00294 ip[l+nb_digits] = 0; 00295 DBG("ip from dns: %s", ip); 00296 } 00297 return true; 00298 } 00299 00300 00301 void Wifly::flush() 00302 { 00303 buf_wifly.flush(); 00304 } 00305 00306 bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout) 00307 { 00308 if (!state.cmd_mode) { 00309 cmdMode(); 00310 } 00311 if (send(cmd, strlen(cmd), ack, res, timeout) == -1) { 00312 ERR("sendCommand: cannot %s\r\n", cmd); 00313 exit(); 00314 return false; 00315 } 00316 return true; 00317 } 00318 00319 bool Wifly::cmdMode() 00320 { 00321 // if already in cmd mode, return 00322 if (state.cmd_mode) 00323 return true; 00324 00325 if (send("$$$", 3, "CMD") == -1) { 00326 ERR("cannot enter in cmd mode\r\n"); 00327 exit(); 00328 return false; 00329 } 00330 state.cmd_mode = true; 00331 return true; 00332 } 00333 00334 bool Wifly::disconnect() 00335 { 00336 // if already disconnected, return 00337 if (!state.associated) 00338 return true; 00339 00340 if (!sendCommand("leave\r", "DeAuth")) 00341 return false; 00342 exit(); 00343 00344 state.associated = false; 00345 return true; 00346 00347 } 00348 00349 bool Wifly::is_connected() 00350 { 00351 return (tcp_status.read() == 1) ? true : false; 00352 } 00353 00354 00355 void Wifly::reset() 00356 { 00357 reset_pin = 0; 00358 wait(0.2); 00359 reset_pin = 1; 00360 wait(0.2); 00361 } 00362 00363 bool Wifly::reboot() 00364 { 00365 // if already in cmd mode, return 00366 if (!sendCommand("reboot\r")) 00367 return false; 00368 00369 wait(0.3); 00370 00371 state.cmd_mode = false; 00372 return true; 00373 } 00374 00375 bool Wifly::close() 00376 { 00377 // if not connected, return 00378 if (!state.tcp) 00379 return true; 00380 00381 wait(0.25); 00382 if (!sendCommand("close\r", "CLOS")) 00383 return false; 00384 exit(); 00385 00386 state.tcp = false; 00387 return true; 00388 } 00389 00390 00391 int Wifly::putc(char c) 00392 { 00393 while (!wifi.writeable()); 00394 return wifi.putc(c); 00395 } 00396 00397 bool Wifly::associated() 00398 { 00399 bool flag=sendCommand("show c\r", "8630", NULL, 1000); 00400 exit(); 00401 return flag; 00402 } 00403 00404 bool Wifly::exit() 00405 { 00406 flush(); 00407 if (!state.cmd_mode) 00408 return true; 00409 if (!sendCommand("exit\r", "EXIT")) 00410 return false; 00411 state.cmd_mode = false; 00412 flush(); 00413 return true; 00414 } 00415 00416 00417 int Wifly::readable() 00418 { 00419 return buf_wifly.available(); 00420 } 00421 00422 int Wifly::writeable() 00423 { 00424 return wifi.writeable(); 00425 } 00426 00427 char Wifly::getc() 00428 { 00429 char c; 00430 while (!buf_wifly.available()); 00431 buf_wifly.dequeue(&c); 00432 return c; 00433 } 00434 00435 void Wifly::handler_rx(void) 00436 { 00437 //read characters 00438 while (wifi.readable()) 00439 buf_wifly.queue(wifi.getc()); 00440 } 00441 00442 void Wifly::attach_rx(bool callback) 00443 { 00444 if (!callback) 00445 wifi.attach(NULL); 00446 else 00447 wifi.attach(this, &Wifly::handler_rx); 00448 } 00449 00450 00451 int Wifly::send(const char * str, int len, const char * ACK, char * res, int timeout) 00452 { 00453 char read; 00454 size_t found = string::npos; 00455 string checking; 00456 Timer tmr; 00457 int result = 0; 00458 00459 DBG("will send: %s\r\n",str); 00460 00461 attach_rx(false); 00462 00463 //We flush the buffer 00464 while (wifi.readable()) 00465 wifi.getc(); 00466 00467 if (!ACK || !strcmp(ACK, "NO")) { 00468 for (int i = 0; i < len; i++) 00469 result = (putc(str[i]) == str[i]) ? result + 1 : result; 00470 } else { 00471 //We flush the buffer 00472 while (wifi.readable()) 00473 wifi.getc(); 00474 00475 tmr.start(); 00476 for (int i = 0; i < len; i++) 00477 result = (putc(str[i]) == str[i]) ? result + 1 : result; 00478 00479 while (1) { 00480 if (tmr.read_ms() > timeout) { 00481 //We flush the buffer 00482 while (wifi.readable()) 00483 wifi.getc(); 00484 00485 DBG("check: %s\r\n", checking.c_str()); 00486 00487 attach_rx(true); 00488 return -1; 00489 } else if (wifi.readable()) { 00490 read = wifi.getc(); 00491 if ( read != '\r' && read != '\n') { 00492 checking += read; 00493 found = checking.find(ACK); 00494 if (found != string::npos) { 00495 wait(0.01); 00496 00497 //We flush the buffer 00498 while (wifi.readable()) 00499 wifi.getc(); 00500 00501 break; 00502 } 00503 } 00504 } 00505 } 00506 DBG("check: %s\r\n", checking.c_str()); 00507 00508 attach_rx(true); 00509 return result; 00510 } 00511 00512 //the user wants the result from the command (ACK == NULL, res != NULL) 00513 if ( res != NULL) { 00514 int i = 0; 00515 Timer timeout; 00516 timeout.start(); 00517 tmr.reset(); 00518 while (1) { 00519 if (timeout.read() > 2) { 00520 if (i == 0) { 00521 res = NULL; 00522 break; 00523 } 00524 res[i] = '\0'; 00525 DBG("user str 1: %s\r\n", res); 00526 00527 break; 00528 } else { 00529 if (tmr.read_ms() > 300) { 00530 res[i] = '\0'; 00531 DBG("user str: %s\r\n", res); 00532 00533 break; 00534 } 00535 if (wifi.readable()) { 00536 tmr.start(); 00537 read = wifi.getc(); 00538 00539 // we drop \r and \n 00540 if ( read != '\r' && read != '\n') { 00541 res[i++] = read; 00542 } 00543 } 00544 } 00545 } 00546 DBG("user str: %s\r\n", res); 00547 } 00548 00549 //We flush the buffer 00550 while (wifi.readable()) 00551 wifi.getc(); 00552 00553 attach_rx(true); 00554 DBG("result: %d\r\n", result) 00555 return result; 00556 }
Generated on Fri Jul 15 2022 14:44:13 by
1.7.2
