MODIFIED from mbed official WiflyInterface (interface for Roving Networks Wifly modules). Numerous performance and reliability improvements (see the detailed documentation). Also, tracking changes in mbed official version to retain functional parity.
Dependents: Smart-WiFly-WebServer PUB_WiflyInterface_Demo
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 #include <ctype.h> 00024 00025 // Defined to disable remote configuration via telnet which increases security of this device. 00026 // Available in Wifly module SW 2.27 and higher. If you want to retain remote telnet, undefine 00027 // or comment this. 00028 #define INCREASE_SECURITY 00029 00030 00031 //#define DEBUG "WiFi" //Debug is disabled by default 00032 00033 // How to use this debug macro 00034 // 00035 // ... 00036 // INFO("Stuff to show %d", var); // new-line is automatically appended 00037 // [I myfile 23] Stuff to show 23\r\n 00038 // 00039 #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) 00040 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00041 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00042 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00043 #else 00044 #define INFO(x, ...) 00045 #define WARN(x, ...) 00046 #define ERR(x, ...) 00047 #endif 00048 00049 00050 #define MAX_TRY_JOIN 3 00051 00052 Wifly * Wifly::inst; 00053 00054 Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec): 00055 wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), baudrate(9600), buf_wifly(256) 00056 { 00057 INFO("Wifly constructor"); 00058 SetSecurity(ssid, phrase, sec); 00059 inst = this; 00060 attach_rx(false); 00061 state.cmd_mode = false; 00062 wiflyVersionString = NULL; 00063 INFO(" const. exit"); 00064 } 00065 00066 Wifly::~Wifly() 00067 { 00068 INFO("~Wifly()"); 00069 if (wiflyVersionString) { 00070 free(wiflyVersionString); 00071 wiflyVersionString = NULL; 00072 } 00073 } 00074 00075 00076 void Wifly::SetSecurity(const char * ssid, const char * phrase, Security sec) 00077 { 00078 memset(&state, 0, sizeof(state)); 00079 state.sec = sec; 00080 FixPhrase(this->ssid, sizeof(this->ssid), ssid); 00081 FixPhrase(this->phrase, sizeof(this->phrase), phrase); 00082 } 00083 00084 00085 bool Wifly::configure() 00086 { 00087 char cmd[80]; // room for command with maximum ssid or passphrase 00088 00089 INFO("configure"); 00090 for (int i= 0; i < MAX_TRY_JOIN; i++) { 00091 00092 // no auto join 00093 if (!sendCommand("set w j 0\r", "AOK")) 00094 continue; 00095 00096 // no echo 00097 if (!sendCommand("set u m 1\r", "AOK")) 00098 continue; 00099 00100 // set comm time to flush (ms) 00101 if (!sendCommand("set c t 30\r", "AOK")) 00102 continue; 00103 00104 // set comm size to auto-send 00105 if (!sendCommand("set c s 1420\r", "AOK")) 00106 continue; 00107 00108 // set comm idle time to auto-close (sec) 00109 //if (!sendCommand("set c i 5\r", "AOK")) 00110 // continue; 00111 00112 // red led on when tcp connection active 00113 if (!sendCommand("set s i 0x40\r", "AOK")) 00114 continue; 00115 00116 // no hello string sent to the tcp client 00117 if (!sendCommand("set c r 0\r", "AOK")) 00118 continue; 00119 00120 // tcp protocol 00121 if (!sendCommand("set i p 2\r", "AOK")) 00122 continue; 00123 00124 // tcp retry (retry enabled, Nagle alg, retain link) 00125 if (!sendCommand("set i f 0x7\r", "AOK")) 00126 continue; 00127 00128 #ifdef INCREASE_SECURITY 00129 // tcp-mode 0x10 = disable remote configuration 00130 // only in SW 2.27 and higher (see 2.3.39) 00131 if ((swVersion >= 2.27) && (!sendCommand("set i t 0x10\r", "AOK"))) 00132 continue; 00133 #endif 00134 00135 // set dns server 00136 if (!sendCommand("set d n rn.microchip.com\r", "AOK")) 00137 continue; 00138 00139 //dhcp 00140 sprintf(cmd, "set i d %d\r", (state.dhcp) ? 1 : 0); 00141 if (!sendCommand(cmd, "AOK")) 00142 continue; 00143 00144 // ssid 00145 sprintf(cmd, "set w s %s\r", ssid); 00146 if (!sendCommand(cmd, "AOK")) 00147 continue; 00148 00149 //auth 00150 sprintf(cmd, "set w a %d\r", state.sec); 00151 if (!sendCommand(cmd, "AOK")) 00152 continue; 00153 00154 // if no dhcp, set ip, netmask and gateway 00155 if (!state.dhcp) { 00156 INFO("not dhcp"); 00157 sprintf(cmd, "set i a %s\r", ip); 00158 if (!sendCommand(cmd, "AOK")) 00159 continue; 00160 00161 sprintf(cmd, "set i n %s\r", netmask); 00162 if (!sendCommand(cmd, "AOK")) 00163 continue; 00164 00165 sprintf(cmd, "set i g %s\r", gateway); 00166 if (!sendCommand(cmd, "AOK")) 00167 continue; 00168 } 00169 00170 //key step 00171 cmd[0] = '\0'; 00172 switch (state.sec) { 00173 case WPE_64: // google searching suggests this is a typo and should be WEP_64 00174 case WEP_128: 00175 sprintf(cmd, "set w k %s\r", phrase); 00176 break; 00177 case WPA1: 00178 case WPA_MIXED: // alias WPA 00179 case WPA2_PSK: 00180 sprintf(cmd, "set w p %s\r", phrase); 00181 break; 00182 case ADHOC: 00183 case NONE: 00184 default: 00185 break; 00186 } 00187 if (cmd[0] && !sendCommand(cmd, "AOK")) 00188 continue; 00189 00190 if (!sendCommand("save\r", "Stor", NULL, 5000)) 00191 continue; 00192 00193 exit(); 00194 return true; 00195 } 00196 return false; 00197 } 00198 00199 00200 bool Wifly::join() 00201 { 00202 INFO("join"); 00203 //join the network (10s timeout) 00204 if (state.dhcp && swVersion < 4.75) { 00205 if (!sendCommand("join\r", "DHCP=ON", NULL, 10000)) // possibly older SW did this 00206 return false; 00207 } else { 00208 if (!sendCommand("join\r", "Associated!", NULL, 10000)) // This for most uses 00209 return false; 00210 } 00211 INFO(" join exit"); 00212 exit(); 00213 INFO(" join end."); 00214 state.associated = true; 00215 return true; 00216 } 00217 00218 00219 bool Wifly::setProtocol(Protocol p) 00220 { 00221 // use udp auto pairing 00222 char cmd[20]; 00223 sprintf(cmd, "set i p %d\r", p); 00224 if (!sendCommand(cmd, "AOK")) 00225 return false; 00226 00227 switch(p) { 00228 case TCP: 00229 // set ip flags: tcp retry enabled 00230 if (!sendCommand("set i f 0x07\r", "AOK")) 00231 return false; 00232 break; 00233 case UDP: 00234 // set ip flags: udp auto pairing enabled 00235 if (!sendCommand("set i h 0.0.0.0\r", "AOK")) 00236 return false; 00237 if (!sendCommand("set i f 0x40\r", "AOK")) 00238 return false; 00239 break; 00240 } 00241 state.proto = p; 00242 return true; 00243 } 00244 00245 00246 char * Wifly::getStringSecurity() 00247 { 00248 switch(state.sec) { 00249 case NONE: // 0 00250 return "NONE"; 00251 case WEP_128: // 1 00252 return "WEP_128"; 00253 case WPA1: // 2 00254 return "WPA1"; 00255 case WPA: // 3 00256 return "WPA"; 00257 case WPA2_PSK: // 4 00258 return "WPA2_PSK"; 00259 case ADHOC: // 6 00260 return "ADHOC"; 00261 case WPE_64: // 8 00262 return "WPE_64"; 00263 default: // ? 00264 return "UNKNOWN"; 00265 } 00266 } 00267 00268 00269 bool Wifly::connect(const char * host, int port) 00270 { 00271 char rcv[20]; 00272 char cmd[20]; 00273 00274 // try to open 00275 sprintf(cmd, "open %s %d\r", host, port); 00276 if (sendCommand(cmd, "OPEN", NULL, 10000)) { 00277 setConnectionState(true); 00278 exit(); 00279 return true; 00280 } 00281 00282 // if failed, retry and parse the response 00283 if (sendCommand(cmd, NULL, rcv, 5000)) { 00284 if (strstr(rcv, "OPEN") == NULL) { 00285 if (strstr(rcv, "Connected") != NULL) { 00286 if (!sendCommand("close\r", "CLOS")) 00287 return false; 00288 if (!sendCommand(cmd, "OPEN", NULL, 10000)) 00289 return false; 00290 } else { 00291 return false; 00292 } 00293 } 00294 } else { 00295 return false; 00296 } 00297 00298 setConnectionState(true); 00299 exit(); 00300 return true; 00301 } 00302 00303 00304 bool Wifly::gethostbyname(const char * host, char * ip) 00305 { 00306 string h = host; 00307 char cmd[30], rcv[100]; 00308 int l = 0; 00309 char * point; 00310 int nb_digits = 0; 00311 00312 // no dns needed 00313 int pos = h.find("."); 00314 if (pos != string::npos) { 00315 string sub = h.substr(0, h.find(".")); 00316 nb_digits = atoi(sub.c_str()); 00317 } 00318 //printf("substrL %s\r\n", sub.c_str()); 00319 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) { 00320 strcpy(ip, host); 00321 } 00322 // dns needed 00323 else { 00324 nb_digits = 0; 00325 sprintf(cmd, "lookup %s\r", host); 00326 if (!sendCommand(cmd, NULL, rcv)) 00327 return false; 00328 00329 // look for the ip address 00330 char * begin = strstr(rcv, "=") + 1; 00331 for (int i = 0; i < 3; i++) { 00332 point = strstr(begin + l, "."); 00333 INFO("str: %s", begin + l); 00334 l += point - (begin + l) + 1; 00335 } 00336 INFO("str: %s", begin + l); 00337 while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') { 00338 INFO("digit: %c", *(begin + l + nb_digits)); 00339 nb_digits++; 00340 } 00341 memcpy(ip, begin, l + nb_digits); 00342 ip[l+nb_digits] = 0; 00343 INFO("ip from dns: %s", ip); 00344 } 00345 return true; 00346 } 00347 00348 00349 void Wifly::flush() 00350 { 00351 #if 0 and defined(DEBUG) 00352 char chatter[500]; 00353 int count = 0; 00354 char c; 00355 00356 while (buf_wifly.available()) { 00357 buf_wifly.dequeue(&c); 00358 chatter[count++] = c; 00359 } 00360 chatter[count] = '\0'; 00361 if (count) 00362 DBG("Wifly::flush {%s}", chatter); 00363 #endif 00364 buf_wifly.flush(); 00365 } 00366 00367 00368 bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout) 00369 { 00370 int tries = 1; 00371 Timer t; 00372 00373 INFO("sendCommand"); 00374 t.start(); 00375 while (tries <= 3) { 00376 if (cmdMode()) { // some influences to the wifi module sometimes kick it out 00377 if (send(cmd, strlen(cmd), ack, res, timeout) >= 0) { 00378 INFO(" sendCommand - success"); 00379 t.stop(); 00380 INFO(" sendCommand - success in %f", t.read()); 00381 return true; 00382 } 00383 } 00384 state.cmd_mode = false; // must not really be in cmd mode 00385 ERR("sendCommand: failure %d when sending: %s", tries, cmd); 00386 tries++; 00387 } 00388 INFO(" sendCommand - failure in %f", t.read()); 00389 send("exit\r", 5, "EXIT"); 00390 return false; 00391 } 00392 00393 00394 bool Wifly::cmdMode() 00395 { 00396 char buf[200]; 00397 // if already in cmd mode, return 00398 if (state.cmd_mode) { 00399 INFO(" is cmdMode"); 00400 #if 0 00401 return true; 00402 #else // for deeper debugging 00403 // Quick verify to ensure we really are in cmd mode 00404 //flushIn(0); 00405 //INFO(" send \\r to test for cmdMode"); 00406 if (send("\r", 1, ">") == 1) { 00407 //INFO(" is cmdMode"); 00408 return true; 00409 } else { 00410 ERR(" failed to detect command mode"); 00411 state.cmd_mode = false; 00412 } 00413 #endif 00414 } else { 00415 wait_ms(460); // manual 1.2.1 (250 msec before and after) 00416 #if 1 00417 if (send("$$$", 3, NULL, buf, 1500)) { 00418 INFO("Resp: [%s]", buf); 00419 if ( ! strstr(buf, "CMD")) { 00420 WARN("cannot enter cmd mode"); 00421 send("exit\r", 5, "EXIT", NULL, 100); 00422 return false; 00423 } 00424 } 00425 #else 00426 if (send("$$$", 3, "CMD") == -1) { // the module controls the 'after' delay 00427 ERR("cannot enter in cmd mode"); 00428 00429 return false; 00430 } 00431 #endif 00432 state.cmd_mode = true; 00433 } 00434 return true; 00435 } 00436 00437 00438 bool Wifly::disconnect() 00439 { 00440 // if already disconnected, return 00441 if (!state.associated) 00442 return true; 00443 00444 if (!sendCommand("leave\r", "DeAuth")) 00445 return false; 00446 exit(); 00447 00448 state.associated = false; 00449 return true; 00450 } 00451 00452 00453 uint16_t Wifly::hextoi(char *p) 00454 { 00455 uint16_t res = 0; 00456 00457 while ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F')) { 00458 if (*p >= '0' && *p <= '9') 00459 res = (res * 16) + (*p - '0'); 00460 else if (*p >= 'a' && *p <= 'f') 00461 res = (res * 16) + (*p - 'a' + 10); 00462 else if (*p >= 'A' && *p <= 'F') 00463 res = (res * 16) + (*p - 'A' + 10); 00464 p++; 00465 } 00466 return res; 00467 } 00468 00469 00470 bool Wifly::is_connected() 00471 { 00472 char buf[30]; 00473 uint16_t connectionStatus = 0; 00474 bool cnxStatus = false; 00475 00476 if (sendCommand("show connection\r", NULL, buf)) { 00477 connectionStatus = hextoi(buf); 00478 exit(); 00479 } 00480 //return (tcp_status.read() == 1) ? true : false; // hw pin 00481 if (connectionStatus & 0x0010) { // associated 00482 cnxStatus = true; 00483 } else { 00484 state.associated = false; 00485 cnxStatus = false; 00486 } 00487 return cnxStatus; 00488 } 00489 00490 00491 void Wifly::reset() 00492 { 00493 reset_pin = 0; 00494 INFO("RESET ACTIVATED"); 00495 wifi.baud(9600); 00496 wait_ms(400); 00497 reset_pin = 1; 00498 GatherLogonInfo(); 00499 INFO("swver %3.2f, {%s}", getWiflyVersion(), getWiflyVersionString()); 00500 } 00501 00502 00503 bool Wifly::reboot() 00504 { 00505 if (sendCommand("reboot\r", "Reboot")) { 00506 state.cmd_mode = false; 00507 wait_ms(500); 00508 wifi.baud(9600); 00509 baud(baudrate); 00510 exit(); 00511 return true; 00512 } else { 00513 return false; 00514 } 00515 } 00516 00517 00518 bool Wifly::close() 00519 { 00520 if (!state.tcp) { 00521 return true; // already closed 00522 } 00523 if (!sendCommand("close\r", "*CLOS*")) { 00524 return false; // failed to close 00525 } 00526 #if 1 00527 // It appears that the close exits cmd mode 00528 // so we won't bother trying to close which 00529 // could cause it to open command mode to 00530 // send the close (which add more 0.5s delays). 00531 state.cmd_mode = false; 00532 #else 00533 flushIn(); 00534 exit(); 00535 #endif 00536 setConnectionState(false); 00537 return true; // succeeded to close 00538 } 00539 00540 00541 int Wifly::putc(char c) 00542 { 00543 while (!wifi.writeable()) 00544 ; 00545 return wifi.putc(c); 00546 } 00547 00548 00549 bool Wifly::exit() 00550 { 00551 INFO("exit()"); 00552 if (!sendCommand("exit\r", "EXIT")) { 00553 ERR(" failed to exit."); 00554 return false; 00555 } 00556 state.cmd_mode = false; 00557 return true; 00558 } 00559 00560 00561 int Wifly::readable() 00562 { 00563 return buf_wifly.available(); 00564 } 00565 00566 00567 int Wifly::writeable() 00568 { 00569 return wifi.writeable(); 00570 } 00571 00572 00573 char Wifly::getc() 00574 { 00575 char c = 0xCC; // avoid compiler warning of uninitialized var. 00576 00577 while (!buf_wifly.available()) 00578 ; 00579 buf_wifly.dequeue(&c); 00580 return c; 00581 } 00582 00583 00584 void Wifly::handler_rx(void) 00585 { 00586 //read characters 00587 while (wifi.readable()) 00588 buf_wifly.queue(wifi.getc()); 00589 } 00590 00591 00592 void Wifly::attach_rx(bool callback) 00593 { 00594 if (!callback) 00595 wifi.attach(NULL); 00596 else 00597 wifi.attach(this, &Wifly::handler_rx); 00598 } 00599 00600 int Wifly::send(const char * str, int len, const char * ACK, char * res, int timeout) 00601 { 00602 char read; 00603 int ackIndex = 0; 00604 Timer tmr; 00605 int result = 0; 00606 00607 INFO("will send: %s",str); 00608 attach_rx(false); 00609 flushIn(); 00610 00611 for (int i = 0; i < len; i++) 00612 result = (putc(str[i]) == str[i]) ? result + 1 : result; 00613 INFO(" data sent."); 00614 tmr.start(); 00615 if (ACK) { 00616 while (1) { 00617 if (tmr.read_ms() > timeout) { 00618 //flushIn(); 00619 WARN("timeout awaiting '%s' in (%f)", ACK, tmr.read()); 00620 attach_rx(true); 00621 return -1; 00622 } else if (wifi.readable()) { 00623 read = wifi.getc(); 00624 if (tolower(read) != tolower(ACK[ackIndex])) 00625 ackIndex = 0; 00626 if (tolower(read) == tolower(ACK[ackIndex])) { 00627 ackIndex++; 00628 if (ackIndex == strlen(ACK)) { 00629 //flushIn(); 00630 break; 00631 } 00632 } 00633 } 00634 } 00635 INFO("check: ACK '%s' received in (%f)", ACK, tmr.read()); 00636 if (strcmp(str,"exit") != 0) 00637 flushIn(); 00638 attach_rx(true); 00639 return result; 00640 } 00641 00642 // the user wants the result from the command (ACK == NULL, res != NULL) 00643 if ( res != NULL) { 00644 int i = 0; 00645 int lastStamp = tmr.read_ms(); 00646 //Timer timeout; 00647 //timeout.start(); 00648 //tmr.reset(); 00649 while (1) { 00650 if (tmr.read_ms() > timeout) { // crash and burn timeout... 00651 if (i == 0) { 00652 res = NULL; 00653 break; 00654 } 00655 res[i] = '\0'; 00656 WARN(" hit user %d msec timeout: %s", timeout, res); 00657 break; 00658 } else { 00659 if ((tmr.read_ms() - lastStamp) > 300) { // timeout since last char suggests done... 00660 res[i] = '\0'; 00661 //WARN("user str: %s", res); 00662 break; 00663 } 00664 while (wifi.readable()) { 00665 lastStamp = tmr.read_ms(); 00666 read = wifi.getc(); 00667 res[i++] = read; 00668 } 00669 } 00670 } 00671 INFO("user str: %s", res); 00672 } 00673 flushIn(); 00674 attach_rx(true); 00675 INFO("result: %d in (%f)", result, tmr.read()) 00676 return result; 00677 } 00678 00679 void Wifly::flushIn(int timeout_ms) 00680 { 00681 Timer tmr; 00682 int lastStamp; 00683 #if 1 and defined(DEBUG) 00684 char chatter[500]; 00685 int count = 0; 00686 int c; 00687 #endif 00688 00689 if (timeout_ms <= 0) { 00690 timeout_ms = 30; // 2 * 10000 / baudrate; // compute minimal timeout 00691 } 00692 tmr.start(); 00693 lastStamp = tmr.read_ms(); 00694 while (wifi.readable() || ((tmr.read_ms() - lastStamp) < timeout_ms)) { 00695 if (wifi.readable()) { 00696 #if 1 and defined(DEBUG) 00697 c = wifi.getc(); 00698 //printf("%02X ", c); 00699 if (count < sizeof(chatter)-1) // guard overflow 00700 chatter[count++] = c; 00701 #else 00702 wifi.getc(); 00703 #endif 00704 lastStamp = tmr.read_ms(); 00705 } 00706 } 00707 #if 1 and defined(DEBUG) 00708 chatter[count] = '\0'; 00709 if (count && (count > 2 || chatter[0] != '\r' || chatter[1] != '\n')) { 00710 INFO("Wifly::flushIn(%d) {%s} in (%f)", count, chatter, tmr.read()); 00711 } else { 00712 INFO("Wifly::flushIn() empty in [%d] (%f)", lastStamp, tmr.read()); 00713 } 00714 #endif 00715 } 00716 00717 00718 // The ARM uart and the Wifly uart have to be in sync or we get 00719 // no meaningful response, so then have to try the possibilities. 00720 // 00721 // First try is at the currently configured ARM uart baud, if 00722 // that fails then it shifts the ARM uart baud through the probable 00723 // speeds, trying to establish contact with the Wifly module. 00724 // Once contact is demonstrated (by response to the 'ver' command), 00725 // then it sets the Wifly module and then the ARM uart. 00726 bool Wifly::baud(int _targetBaud) 00727 { 00728 // in testing, 460800 and 921600 may change the Wifly module where you can't 00729 // change it back w/o a reset. So, we won't even permit those speeds. 00730 const int baudrates[] = {2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}; //, 460800, 921600}; 00731 #define BRCOUNT (sizeof(baudrates)/sizeof(baudrates[0])) 00732 char cmd[26]; // sized for "set u i 460800\r" [15+1], plus margin [4] 00733 int tryIndex = 0; 00734 bool res = false; 00735 int userIndex; 00736 00737 sprintf(cmd, "set uart instant %d\r", _targetBaud); 00738 // set u i # should cause it to exit command mode (manual 2.3.64), 00739 // but testing indicates that it does not. 00740 for (userIndex=0; userIndex < BRCOUNT; userIndex++) { 00741 if (_targetBaud == baudrates[userIndex]) { 00742 while (tryIndex <= BRCOUNT) { 00743 //INFO("baud() try: %d: %d", tryIndex, _targetBaud); 00744 sendCommand(cmd); // shift Wifly to desired speed [it may not respond (see 2.3.64)] 00745 flushIn(10); 00746 //state.cmd_mode = false; // see note above why this is disabled 00747 wifi.baud(_targetBaud); // shift the ARM uart to match 00748 if (sendCommand("ver\r", "wifly", NULL, 125)) { // use this to verify communications 00749 baudrate = _targetBaud; 00750 res = true; 00751 break; // success 00752 } 00753 // keep trying baudrates between ARM and WiFly 00754 if (tryIndex < BRCOUNT) { 00755 //INFO(" baud() set to %d", baudrates[tryIndex]); 00756 wifi.baud(baudrates[tryIndex]); 00757 } 00758 tryIndex++; 00759 } 00760 break; // if they selected a legitimate baud, try no others 00761 } 00762 } 00763 //INFO(" baud() result: %d", res); 00764 return res; 00765 } 00766 00767 00768 bool Wifly::FixPhrase(char * dst, size_t dstLen, const char * src) 00769 { 00770 if (strlen(src) < dstLen) { 00771 strcpy(dst, src); 00772 // change all ' ' to '$' in ssid or passphrase 00773 for (int i = 0; i < strlen(dst); i++) { 00774 if ((dst)[i] == ' ') 00775 (dst)[i] = '$'; 00776 } 00777 INFO("phrase: {%s} fr {%s}", dst, src); 00778 return true; 00779 } else { 00780 ERR("Source {%s} is too long for destination buffer of %d bytes", src, dstLen); 00781 return false; 00782 } 00783 } 00784 00785 00786 void Wifly::GatherLogonInfo() 00787 { 00788 Timer timer; 00789 char logonText[200]; 00790 int i = 0; 00791 char *p; 00792 00793 timer.start(); 00794 if (wiflyVersionString) { 00795 free(wiflyVersionString); 00796 wiflyVersionString = NULL; 00797 } 00798 logonText[i] = '\0'; 00799 while (timer.read_ms() < 500) { 00800 while (wifi.readable() && (i <sizeof(logonText)-1)) { 00801 logonText[i++] = wifi.getc(); 00802 } 00803 } 00804 logonText[i] = '\0'; 00805 p = strchr(logonText, '\r'); 00806 if (p) 00807 *p = '\0'; 00808 wiflyVersionString = (char *)malloc(strlen(logonText)+1); 00809 if (wiflyVersionString) { 00810 strcpy(wiflyVersionString, logonText); 00811 } 00812 p = strstr(logonText, "Ver "); // "Ver 4.00" for ver <= 4.00 00813 if (!p) p = strstr(logonText, "Ver: "); // "Ver: 4.40" new in ver 4.40 00814 if (p) { 00815 while (*p && (*p < '0' || *p > '9')) 00816 p++; 00817 swVersion = atof(p); 00818 } 00819 WARN("swVersion: %3.2f,\r\nverString: {%s}", swVersion, wiflyVersionString); 00820 } 00821 00822 00823 float Wifly::getWiflyVersion() 00824 { 00825 INFO("swVersion: %3.2f", swVersion); 00826 return swVersion; 00827 } 00828 00829 00830 char * Wifly::getWiflyVersionString() 00831 { 00832 INFO("version string: %s", wiflyVersionString); 00833 return wiflyVersionString; 00834 } 00835 00836 bool Wifly::SWUpdateWifly(const char * file) 00837 { 00838 bool success = false; 00839 char buf[80]; 00840 00841 INFO("\r\n\r\n\r\n"); 00842 INFO("SWUpdateWifly %s", file); 00843 if (strlen(file) < (80 - 13)) { 00844 sprintf(buf, "ftp update %s\r", file); 00845 if (is_connected()) { 00846 // once connected, send command to update firmware 00847 if (sendCommand("set ftp address 0\r", "AOK")) { 00848 if (sendCommand("set dns name rn.microchip.com\r", "AOK")) { 00849 if (sendCommand("save\r", "Stor", NULL, 5000)) { 00850 if (sendCommand(buf, "UPDATE OK", NULL, 50000)) { 00851 if (sendCommand("factory RESET\r")) { 00852 if (reboot()) { 00853 success = true; 00854 } 00855 } 00856 } 00857 } 00858 } 00859 } 00860 } 00861 } 00862 return success; 00863 } 00864 00865 00866 void Wifly::setConnectionState(bool value) 00867 { 00868 state.tcp = value; 00869 }
Generated on Tue Jul 12 2022 16:14:58 by 1.7.2