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.
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
 1.7.2 
    