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 mbed official

Resources

Derivative from mbed Official

  • Documentation update, improved consistency, documented parameters that were inadvertently omitted.
  • Avoid c++ string handling, which causes dynamic allocation and free, side effect, fewer CPU cycles spent for same purpose.
  • Fixed socket APIs to support non-blocking mode.
  • Increase communication baud-rate to Wifly module
  • sendCommand - added retries for improved robustness.
  • setConnectionState - method to force the connection state (used by TCPSocketServer)
  • gethostbyname - added a length parameter to the size of the buffer being written
  • flushIn - a private method to flush the input buffer
  • Changed the timeout from 500 to 2500 msec for commands - measured some at 700 to 850 msec.
  • Performance improvements - reduced some unnecessary delays.
  • Added additional security options for the wi-fi connection (that are supported by the WiFly module).
  • Added setSecurity API which permits revising the security when connecting to, or selecting from, one of several access points.
  • Improved DEBUG interface (slightly more consistent printout).
  • gathers information from the Wifly module on reboot (SW version info), which permits customizing behavior based on Wifly capabilities (like the improved security).
  • Avoid potential for recursive crash (if exit fails, it calls sendcommand, which calls exit...)
  • Update to support permissible SSID and PassCode lengths.

Robustness testing

I've had some mixed behavior with the Wifly module, some of which seems to be traceable to the module itself, and some in my derivative code. The result, after running for minutes, hours, sometimes days, it hangs and I have to reset the module.

To test, I created a fairly simple test program -

  • check for Watchdog induced reset and count it.
  • initialize the Watchdog for 60 sec timeout.
  • Init the Wifly interface and connect to my network.
  • Wait 10 seconds and force mbed_reset().

If the Watchdog induces the restart, then it is pretty clear that either:

  • The communications hung with the Wifly module causing the failure.
  • The Wifly module decided to go unresponsive.

If it gets to the end, it typically takes about 4 to 6 seconds for the boot and connect, then the 10 second delay.

But I can't really pin down the root cause easily. My strongest theory is that the Wifly module has rebooted, and since I don't store the high baud rate I configure it for, it resets back to 9600.

Also, one of the objectives for my revised send( ) is to avoid the c++ string, as that can fragment memory, and it wasn't very well bounded in behavior.

Latest tests:

Warm BootsWatchdog EventsNotes
100's30An early version of my derivative WiflyInterface, including my derivative of "send( )" API. Let's call this version 0.1.
26684My derivative WiflyInterface, but with the mbed official "send( )" API. Much improved. This was over the course of about 12 hours.
24003Most recent derivative - incremental change to "send( )", but this relative number does not rule out the Wifly module itself.

I think with these numbers, +/- 1 means that the changes have had no measurable effect. Which is good, since this incremental change eliminates the c++ string handling.

Test Software

This is pieces of a test program, clipped and copied to here. What I have compiled and run for hours and hours is almost exactly what you see. This uses this simple Watchdog library.

#include "mbed.h"
#include "WiflyInterface.h"
#include "Watchdog.h"

Serial pc(USBTX, USBRX);

Watchdog wd;
extern "C" void mbed_reset();

// Pinout for SmartBoard
WiflyInterface wifly(p9, p10, p30, p29, "ssid", "pass", WPA);

int main() {
    pc.baud(460800);                         // I like a snappy terminal
    
    wd.Configure(60.0);                     // Set time limit for the test to 1 minute
    LPC_RTC->GPREG0++;                      // Count boots here
    if (wd.WatchdogCausedReset()) {
        LPC_RTC->GPREG1++;                  // Count Watchdog events here
        pc.printf("\r\n\r\nWatchdog event.\r\n");
    }
    pc.printf("\r\nWifly Test: %d boots, %d watchdogs. %s %s\r\n", LPC_RTC->GPREG0, LPC_RTC->GPREG1, __DATE__, __TIME__);
    
    wifly.init(); // use DHCP
    pc.printf("Connect...  ");
    while (!wifly.connect());               // join the network
    pc.printf("Address is %s.  ", wifly.getIPAddress());
    pc.printf("Disconnect...  ");
    wifly.disconnect();
    pc.printf("OK. Reset in 10 sec...\r\n");
    wait(10);
    if (pc.readable()) {
        if (pc.getc() == 'r') {             // secret 'r'eset of the counters
            LPC_RTC->GPREG0 = 0;
            LPC_RTC->GPREG1 = 0;
            pc.printf("counters reset\r\n");
        }
    }
    mbed_reset();                           // reset here indicates successful communication
}
Committer:
WiredHome
Date:
Fri May 02 00:10:34 2014 +0000
Revision:
69:a4064f7e3529
Parent:
67:557ea7ad15c1
Child:
70:83e420b0d3e1
Child:
71:59936f711b80
Revised the ssid and passcode to be simple char arrays, simplifying the storage and management, but also meeting the required size.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 1:fb4494783863 1 /* Copyright (C) 2012 mbed.org, MIT License
samux 1:fb4494783863 2 *
samux 1:fb4494783863 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
samux 1:fb4494783863 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
samux 1:fb4494783863 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
samux 1:fb4494783863 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
samux 1:fb4494783863 7 * furnished to do so, subject to the following conditions:
samux 1:fb4494783863 8 *
samux 1:fb4494783863 9 * The above copyright notice and this permission notice shall be included in all copies or
samux 1:fb4494783863 10 * substantial portions of the Software.
samux 1:fb4494783863 11 *
samux 1:fb4494783863 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
samux 1:fb4494783863 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
samux 1:fb4494783863 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
samux 1:fb4494783863 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
samux 1:fb4494783863 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
samux 1:fb4494783863 17 */
samux 1:fb4494783863 18
samux 1:fb4494783863 19 #include "mbed.h"
samux 1:fb4494783863 20 #include "Wifly.h"
samux 1:fb4494783863 21 #include <string>
samux 1:fb4494783863 22 #include <algorithm>
WiredHome 35:2dc12224cbd6 23 #include <ctype.h>
samux 1:fb4494783863 24
WiredHome 58:f49aab8072ec 25 // Defined to disable remote configuration via telnet which increases security of this device.
WiredHome 58:f49aab8072ec 26 // Available in Wifly module SW 2.27 and higher. If you want to retain remote telnet, undefine
WiredHome 58:f49aab8072ec 27 // or comment this.
WiredHome 51:a4831b1cb9a4 28 #define INCREASE_SECURITY
WiredHome 25:a740eb74a86a 29
WiredHome 58:f49aab8072ec 30
WiredHome 61:288691545d03 31 //#define DEBUG "WiFi" //Debug is disabled by default
WiredHome 20:906b0f951bc3 32
WiredHome 58:f49aab8072ec 33 // How to use this debug macro
WiredHome 58:f49aab8072ec 34 //
WiredHome 58:f49aab8072ec 35 // #define DEBUG "myfile"
WiredHome 58:f49aab8072ec 36 // #include "Utility.h"
WiredHome 58:f49aab8072ec 37 // ...
WiredHome 58:f49aab8072ec 38 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 58:f49aab8072ec 39 // [I myfile 23] Stuff to show 23\r\n
WiredHome 58:f49aab8072ec 40 //
WiredHome 20:906b0f951bc3 41 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 58:f49aab8072ec 42 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 58:f49aab8072ec 43 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 58:f49aab8072ec 44 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
samux 1:fb4494783863 45 #else
WiredHome 58:f49aab8072ec 46 #define INFO(x, ...)
samux 1:fb4494783863 47 #define WARN(x, ...)
samux 1:fb4494783863 48 #define ERR(x, ...)
samux 1:fb4494783863 49 #endif
samux 1:fb4494783863 50
WiredHome 58:f49aab8072ec 51
samux 1:fb4494783863 52 #define MAX_TRY_JOIN 3
samux 1:fb4494783863 53
samux 1:fb4494783863 54 Wifly * Wifly::inst;
samux 1:fb4494783863 55
samux 1:fb4494783863 56 Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec):
WiredHome 20:906b0f951bc3 57 wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), baudrate(9600), buf_wifly(256)
samux 1:fb4494783863 58 {
WiredHome 58:f49aab8072ec 59 INFO("Wifly constructor");
WiredHome 69:a4064f7e3529 60 SetSecurity(ssid, phrase, sec);
samux 1:fb4494783863 61 inst = this;
samux 1:fb4494783863 62 attach_rx(false);
WiredHome 58:f49aab8072ec 63 state.cmd_mode = false;
WiredHome 25:a740eb74a86a 64 wiflyVersionString = NULL;
WiredHome 58:f49aab8072ec 65 INFO(" const. exit");
samux 1:fb4494783863 66 }
samux 1:fb4494783863 67
WiredHome 25:a740eb74a86a 68 Wifly::~Wifly()
WiredHome 25:a740eb74a86a 69 {
WiredHome 58:f49aab8072ec 70 INFO("~Wifly()");
WiredHome 25:a740eb74a86a 71 if (wiflyVersionString) {
WiredHome 25:a740eb74a86a 72 free(wiflyVersionString);
WiredHome 25:a740eb74a86a 73 wiflyVersionString = NULL;
WiredHome 25:a740eb74a86a 74 }
WiredHome 25:a740eb74a86a 75 }
WiredHome 25:a740eb74a86a 76
WiredHome 67:557ea7ad15c1 77
WiredHome 45:21b7bbaad62b 78 void Wifly::SetSecurity(const char * ssid, const char * phrase, Security sec)
WiredHome 45:21b7bbaad62b 79 {
WiredHome 62:f1484c792c0e 80 memset(&state, 0, sizeof(state));
WiredHome 45:21b7bbaad62b 81 state.sec = sec;
WiredHome 69:a4064f7e3529 82 FixPhrase(this->ssid, sizeof(this->ssid), ssid);
WiredHome 69:a4064f7e3529 83 FixPhrase(this->phrase, sizeof(this->phrase), phrase);
WiredHome 45:21b7bbaad62b 84 }
WiredHome 25:a740eb74a86a 85
WiredHome 67:557ea7ad15c1 86
WiredHome 67:557ea7ad15c1 87 bool Wifly::configure()
samux 1:fb4494783863 88 {
WiredHome 58:f49aab8072ec 89 char cmd[80]; // room for command with maximum ssid or passphrase
samux 1:fb4494783863 90
WiredHome 67:557ea7ad15c1 91 INFO("configure");
samux 1:fb4494783863 92 for (int i= 0; i < MAX_TRY_JOIN; i++) {
samux 2:8e54830d0df7 93
samux 2:8e54830d0df7 94 // no auto join
samux 2:8e54830d0df7 95 if (!sendCommand("set w j 0\r", "AOK"))
samux 2:8e54830d0df7 96 continue;
samux 2:8e54830d0df7 97
WiredHome 27:8509ec4a0a0a 98 // no echo
samux 2:8e54830d0df7 99 if (!sendCommand("set u m 1\r", "AOK"))
samux 2:8e54830d0df7 100 continue;
samux 2:8e54830d0df7 101
WiredHome 27:8509ec4a0a0a 102 // set comm time to flush (ms)
samux 4:0bcec6272784 103 if (!sendCommand("set c t 30\r", "AOK"))
samux 1:fb4494783863 104 continue;
samux 1:fb4494783863 105
WiredHome 27:8509ec4a0a0a 106 // set comm size to auto-send
WiredHome 27:8509ec4a0a0a 107 if (!sendCommand("set c s 1420\r", "AOK"))
samux 1:fb4494783863 108 continue;
samux 1:fb4494783863 109
WiredHome 29:49876a8c445b 110 // set comm idle time to auto-close (sec)
WiredHome 29:49876a8c445b 111 //if (!sendCommand("set c i 5\r", "AOK"))
WiredHome 29:49876a8c445b 112 // continue;
WiredHome 29:49876a8c445b 113
samux 1:fb4494783863 114 // red led on when tcp connection active
samux 1:fb4494783863 115 if (!sendCommand("set s i 0x40\r", "AOK"))
samux 1:fb4494783863 116 continue;
samux 1:fb4494783863 117
WiredHome 27:8509ec4a0a0a 118 // no hello string sent to the tcp client
samux 1:fb4494783863 119 if (!sendCommand("set c r 0\r", "AOK"))
samux 1:fb4494783863 120 continue;
samux 1:fb4494783863 121
samux 1:fb4494783863 122 // tcp protocol
samux 1:fb4494783863 123 if (!sendCommand("set i p 2\r", "AOK"))
samux 1:fb4494783863 124 continue;
samux 1:fb4494783863 125
WiredHome 27:8509ec4a0a0a 126 // tcp retry (retry enabled, Nagle alg, retain link)
samux 1:fb4494783863 127 if (!sendCommand("set i f 0x7\r", "AOK"))
samux 1:fb4494783863 128 continue;
WiredHome 20:906b0f951bc3 129
WiredHome 25:a740eb74a86a 130 #ifdef INCREASE_SECURITY
WiredHome 25:a740eb74a86a 131 // tcp-mode 0x10 = disable remote configuration
WiredHome 25:a740eb74a86a 132 // only in SW 2.27 and higher (see 2.3.39)
WiredHome 25:a740eb74a86a 133 if ((swVersion >= 2.27) && (!sendCommand("set i t 0x10\r", "AOK")))
WiredHome 25:a740eb74a86a 134 continue;
WiredHome 25:a740eb74a86a 135 #endif
WiredHome 25:a740eb74a86a 136
samux 2:8e54830d0df7 137 // set dns server
samux 2:8e54830d0df7 138 if (!sendCommand("set d n rn.microchip.com\r", "AOK"))
samux 1:fb4494783863 139 continue;
samux 1:fb4494783863 140
samux 1:fb4494783863 141 //dhcp
samux 1:fb4494783863 142 sprintf(cmd, "set i d %d\r", (state.dhcp) ? 1 : 0);
samux 1:fb4494783863 143 if (!sendCommand(cmd, "AOK"))
samux 1:fb4494783863 144 continue;
samux 1:fb4494783863 145
samux 1:fb4494783863 146 // ssid
samux 1:fb4494783863 147 sprintf(cmd, "set w s %s\r", ssid);
samux 1:fb4494783863 148 if (!sendCommand(cmd, "AOK"))
samux 1:fb4494783863 149 continue;
samux 1:fb4494783863 150
samux 1:fb4494783863 151 //auth
samux 1:fb4494783863 152 sprintf(cmd, "set w a %d\r", state.sec);
samux 1:fb4494783863 153 if (!sendCommand(cmd, "AOK"))
samux 1:fb4494783863 154 continue;
samux 1:fb4494783863 155
samux 1:fb4494783863 156 // if no dhcp, set ip, netmask and gateway
samux 1:fb4494783863 157 if (!state.dhcp) {
WiredHome 58:f49aab8072ec 158 INFO("not dhcp");
WiredHome 67:557ea7ad15c1 159 sprintf(cmd, "set i a %s\r", ip);
samux 1:fb4494783863 160 if (!sendCommand(cmd, "AOK"))
samux 1:fb4494783863 161 continue;
samux 1:fb4494783863 162
samux 1:fb4494783863 163 sprintf(cmd, "set i n %s\r", netmask);
samux 1:fb4494783863 164 if (!sendCommand(cmd, "AOK"))
samux 1:fb4494783863 165 continue;
samux 1:fb4494783863 166
samux 1:fb4494783863 167 sprintf(cmd, "set i g %s\r", gateway);
samux 1:fb4494783863 168 if (!sendCommand(cmd, "AOK"))
samux 1:fb4494783863 169 continue;
samux 1:fb4494783863 170 }
samux 1:fb4494783863 171
samux 1:fb4494783863 172 //key step
WiredHome 30:f500260463b7 173 cmd[0] = '\0';
WiredHome 30:f500260463b7 174 switch (state.sec) {
WiredHome 30:f500260463b7 175 case WPE_64: // google searching suggests this is a typo and should be WEP_64
WiredHome 30:f500260463b7 176 case WEP_128:
samux 1:fb4494783863 177 sprintf(cmd, "set w k %s\r", phrase);
WiredHome 30:f500260463b7 178 break;
WiredHome 30:f500260463b7 179 case WPA1:
WiredHome 30:f500260463b7 180 case WPA_MIXED: // alias WPA
WiredHome 30:f500260463b7 181 case WPA2_PSK:
WiredHome 30:f500260463b7 182 sprintf(cmd, "set w p %s\r", phrase);
WiredHome 30:f500260463b7 183 break;
WiredHome 30:f500260463b7 184 case ADHOC:
WiredHome 30:f500260463b7 185 case NONE:
WiredHome 30:f500260463b7 186 default:
WiredHome 30:f500260463b7 187 break;
samux 1:fb4494783863 188 }
WiredHome 30:f500260463b7 189 if (cmd[0] && !sendCommand(cmd, "AOK"))
WiredHome 30:f500260463b7 190 continue;
samux 1:fb4494783863 191
WiredHome 59:8e15d2ca7bd5 192 if (!sendCommand("save\r", "Stor", NULL, 5000))
samux 2:8e54830d0df7 193 continue;
samux 2:8e54830d0df7 194
samux 1:fb4494783863 195 exit();
samux 1:fb4494783863 196 return true;
samux 1:fb4494783863 197 }
samux 1:fb4494783863 198 return false;
samux 1:fb4494783863 199 }
samux 1:fb4494783863 200
samux 1:fb4494783863 201
WiredHome 67:557ea7ad15c1 202 bool Wifly::join()
WiredHome 67:557ea7ad15c1 203 {
WiredHome 67:557ea7ad15c1 204 INFO("join");
WiredHome 67:557ea7ad15c1 205 //join the network (10s timeout)
WiredHome 67:557ea7ad15c1 206 if (state.dhcp) {
WiredHome 67:557ea7ad15c1 207 if (!sendCommand("join\r", "DHCP=ON", NULL, 10000))
WiredHome 67:557ea7ad15c1 208 return false;
WiredHome 67:557ea7ad15c1 209 } else {
WiredHome 67:557ea7ad15c1 210 if (!sendCommand("join\r", "Associated", NULL, 10000))
WiredHome 67:557ea7ad15c1 211 return false;
WiredHome 67:557ea7ad15c1 212 }
WiredHome 67:557ea7ad15c1 213 exit();
WiredHome 67:557ea7ad15c1 214 state.associated = true;
WiredHome 67:557ea7ad15c1 215 return true;
WiredHome 67:557ea7ad15c1 216 }
WiredHome 67:557ea7ad15c1 217
WiredHome 67:557ea7ad15c1 218
samux 1:fb4494783863 219 bool Wifly::setProtocol(Protocol p)
samux 1:fb4494783863 220 {
samux 1:fb4494783863 221 // use udp auto pairing
samux 1:fb4494783863 222 char cmd[20];
samux 1:fb4494783863 223 sprintf(cmd, "set i p %d\r", p);
samux 1:fb4494783863 224 if (!sendCommand(cmd, "AOK"))
samux 1:fb4494783863 225 return false;
samux 1:fb4494783863 226
samux 1:fb4494783863 227 switch(p) {
samux 1:fb4494783863 228 case TCP:
samux 1:fb4494783863 229 // set ip flags: tcp retry enabled
samux 1:fb4494783863 230 if (!sendCommand("set i f 0x07\r", "AOK"))
samux 1:fb4494783863 231 return false;
samux 1:fb4494783863 232 break;
samux 1:fb4494783863 233 case UDP:
samux 1:fb4494783863 234 // set ip flags: udp auto pairing enabled
samux 1:fb4494783863 235 if (!sendCommand("set i h 0.0.0.0\r", "AOK"))
samux 1:fb4494783863 236 return false;
samux 4:0bcec6272784 237 if (!sendCommand("set i f 0x40\r", "AOK"))
samux 1:fb4494783863 238 return false;
samux 1:fb4494783863 239 break;
samux 1:fb4494783863 240 }
samux 1:fb4494783863 241 state.proto = p;
samux 1:fb4494783863 242 return true;
samux 1:fb4494783863 243 }
samux 1:fb4494783863 244
WiredHome 25:a740eb74a86a 245
samux 1:fb4494783863 246 char * Wifly::getStringSecurity()
samux 1:fb4494783863 247 {
samux 1:fb4494783863 248 switch(state.sec) {
WiredHome 30:f500260463b7 249 case NONE: // 0
samux 1:fb4494783863 250 return "NONE";
WiredHome 30:f500260463b7 251 case WEP_128: // 1
samux 1:fb4494783863 252 return "WEP_128";
WiredHome 30:f500260463b7 253 case WPA1: // 2
WiredHome 30:f500260463b7 254 return "WPA1";
WiredHome 30:f500260463b7 255 case WPA: // 3
samux 1:fb4494783863 256 return "WPA";
WiredHome 30:f500260463b7 257 case WPA2_PSK: // 4
WiredHome 30:f500260463b7 258 return "WPA2_PSK";
WiredHome 30:f500260463b7 259 case ADHOC: // 6
WiredHome 30:f500260463b7 260 return "ADHOC";
WiredHome 30:f500260463b7 261 case WPE_64: // 8
WiredHome 30:f500260463b7 262 return "WPE_64";
WiredHome 30:f500260463b7 263 default: // ?
WiredHome 30:f500260463b7 264 return "UNKNOWN";
samux 1:fb4494783863 265 }
samux 1:fb4494783863 266 }
samux 1:fb4494783863 267
WiredHome 25:a740eb74a86a 268
samux 1:fb4494783863 269 bool Wifly::connect(const char * host, int port)
samux 1:fb4494783863 270 {
samux 1:fb4494783863 271 char rcv[20];
samux 1:fb4494783863 272 char cmd[20];
samux 1:fb4494783863 273
samux 2:8e54830d0df7 274 // try to open
samux 2:8e54830d0df7 275 sprintf(cmd, "open %s %d\r", host, port);
samux 2:8e54830d0df7 276 if (sendCommand(cmd, "OPEN", NULL, 10000)) {
WiredHome 64:6202428f37ec 277 setConnectionState(true);
WiredHome 25:a740eb74a86a 278 exit();
samux 2:8e54830d0df7 279 return true;
samux 1:fb4494783863 280 }
samux 1:fb4494783863 281
samux 2:8e54830d0df7 282 // if failed, retry and parse the response
samux 2:8e54830d0df7 283 if (sendCommand(cmd, NULL, rcv, 5000)) {
samux 1:fb4494783863 284 if (strstr(rcv, "OPEN") == NULL) {
samux 1:fb4494783863 285 if (strstr(rcv, "Connected") != NULL) {
samux 1:fb4494783863 286 if (!sendCommand("close\r", "CLOS"))
samux 1:fb4494783863 287 return false;
samux 2:8e54830d0df7 288 if (!sendCommand(cmd, "OPEN", NULL, 10000))
samux 1:fb4494783863 289 return false;
samux 1:fb4494783863 290 } else {
samux 1:fb4494783863 291 return false;
samux 1:fb4494783863 292 }
samux 1:fb4494783863 293 }
samux 1:fb4494783863 294 } else {
samux 1:fb4494783863 295 return false;
samux 1:fb4494783863 296 }
samux 2:8e54830d0df7 297
WiredHome 64:6202428f37ec 298 setConnectionState(true);
WiredHome 25:a740eb74a86a 299 exit();
samux 1:fb4494783863 300 return true;
samux 1:fb4494783863 301 }
samux 1:fb4494783863 302
samux 1:fb4494783863 303
samux 1:fb4494783863 304 bool Wifly::gethostbyname(const char * host, char * ip)
samux 1:fb4494783863 305 {
samux 1:fb4494783863 306 string h = host;
samux 1:fb4494783863 307 char cmd[30], rcv[100];
samux 1:fb4494783863 308 int l = 0;
samux 1:fb4494783863 309 char * point;
samux 1:fb4494783863 310 int nb_digits = 0;
samux 1:fb4494783863 311
samux 1:fb4494783863 312 // no dns needed
samux 1:fb4494783863 313 int pos = h.find(".");
samux 1:fb4494783863 314 if (pos != string::npos) {
samux 1:fb4494783863 315 string sub = h.substr(0, h.find("."));
samux 1:fb4494783863 316 nb_digits = atoi(sub.c_str());
samux 1:fb4494783863 317 }
samux 1:fb4494783863 318 //printf("substrL %s\r\n", sub.c_str());
samux 1:fb4494783863 319 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) {
samux 1:fb4494783863 320 strcpy(ip, host);
samux 1:fb4494783863 321 }
samux 1:fb4494783863 322 // dns needed
samux 1:fb4494783863 323 else {
samux 1:fb4494783863 324 nb_digits = 0;
samux 1:fb4494783863 325 sprintf(cmd, "lookup %s\r", host);
samux 1:fb4494783863 326 if (!sendCommand(cmd, NULL, rcv))
samux 1:fb4494783863 327 return false;
samux 1:fb4494783863 328
samux 1:fb4494783863 329 // look for the ip address
samux 1:fb4494783863 330 char * begin = strstr(rcv, "=") + 1;
samux 1:fb4494783863 331 for (int i = 0; i < 3; i++) {
samux 1:fb4494783863 332 point = strstr(begin + l, ".");
WiredHome 29:49876a8c445b 333 INFO("str: %s", begin + l);
samux 1:fb4494783863 334 l += point - (begin + l) + 1;
samux 1:fb4494783863 335 }
WiredHome 29:49876a8c445b 336 INFO("str: %s", begin + l);
samux 1:fb4494783863 337 while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') {
WiredHome 29:49876a8c445b 338 INFO("digit: %c", *(begin + l + nb_digits));
samux 1:fb4494783863 339 nb_digits++;
samux 1:fb4494783863 340 }
samux 1:fb4494783863 341 memcpy(ip, begin, l + nb_digits);
samux 1:fb4494783863 342 ip[l+nb_digits] = 0;
WiredHome 29:49876a8c445b 343 INFO("ip from dns: %s", ip);
samux 1:fb4494783863 344 }
samux 1:fb4494783863 345 return true;
samux 1:fb4494783863 346 }
samux 1:fb4494783863 347
samux 1:fb4494783863 348
samux 1:fb4494783863 349 void Wifly::flush()
samux 1:fb4494783863 350 {
WiredHome 51:a4831b1cb9a4 351 #if 0 and defined(DEBUG)
WiredHome 29:49876a8c445b 352 char chatter[500];
WiredHome 29:49876a8c445b 353 int count = 0;
WiredHome 29:49876a8c445b 354 char c;
WiredHome 29:49876a8c445b 355
WiredHome 29:49876a8c445b 356 while (buf_wifly.available()) {
WiredHome 29:49876a8c445b 357 buf_wifly.dequeue(&c);
WiredHome 29:49876a8c445b 358 chatter[count++] = c;
WiredHome 29:49876a8c445b 359 }
WiredHome 29:49876a8c445b 360 chatter[count] = '\0';
WiredHome 29:49876a8c445b 361 if (count)
WiredHome 29:49876a8c445b 362 DBG("Wifly::flush {%s}", chatter);
WiredHome 29:49876a8c445b 363 #endif
samux 1:fb4494783863 364 buf_wifly.flush();
samux 1:fb4494783863 365 }
samux 1:fb4494783863 366
WiredHome 25:a740eb74a86a 367
samux 1:fb4494783863 368 bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout)
samux 1:fb4494783863 369 {
WiredHome 20:906b0f951bc3 370 int tries = 1;
WiredHome 29:49876a8c445b 371
WiredHome 67:557ea7ad15c1 372 INFO("sendCommand");
WiredHome 20:906b0f951bc3 373 while (tries <= 2) {
WiredHome 53:3dd2e7f9edc0 374 if (cmdMode()) { // some influences to the wifi module sometimes kick it out
WiredHome 53:3dd2e7f9edc0 375 if (send(cmd, strlen(cmd), ack, res, timeout) >= 0) {
WiredHome 59:8e15d2ca7bd5 376 INFO(" sendCommand - success");
WiredHome 53:3dd2e7f9edc0 377 return true;
WiredHome 53:3dd2e7f9edc0 378 }
WiredHome 20:906b0f951bc3 379 }
WiredHome 58:f49aab8072ec 380 state.cmd_mode = false; // must not really be in cmd mode
WiredHome 29:49876a8c445b 381 ERR("sendCommand: failure %d when sending: %s", tries, cmd);
WiredHome 20:906b0f951bc3 382 tries++;
samux 1:fb4494783863 383 }
WiredHome 59:8e15d2ca7bd5 384 INFO(" sendCommand - failure");
WiredHome 67:557ea7ad15c1 385 send("exit\r", 5, "EXIT");
WiredHome 17:213844a1864f 386 return false;
samux 1:fb4494783863 387 }
samux 1:fb4494783863 388
WiredHome 25:a740eb74a86a 389
samux 1:fb4494783863 390 bool Wifly::cmdMode()
samux 1:fb4494783863 391 {
WiredHome 67:557ea7ad15c1 392 char buf[200];
samux 1:fb4494783863 393 // if already in cmd mode, return
WiredHome 29:49876a8c445b 394 if (state.cmd_mode) {
WiredHome 67:557ea7ad15c1 395 INFO(" is cmdMode");
WiredHome 67:557ea7ad15c1 396 #if 0
WiredHome 58:f49aab8072ec 397 return true;
WiredHome 58:f49aab8072ec 398 #else // for deeper debugging
WiredHome 29:49876a8c445b 399 // Quick verify to ensure we really are in cmd mode
WiredHome 29:49876a8c445b 400 flushIn(0);
WiredHome 51:a4831b1cb9a4 401 //INFO(" send \\r to test for cmdMode");
WiredHome 29:49876a8c445b 402 if (send("\r", 1, ">") == 1) {
WiredHome 51:a4831b1cb9a4 403 //INFO(" is cmdMode");
WiredHome 29:49876a8c445b 404 return true;
WiredHome 34:52e4eec8b790 405 } else {
WiredHome 58:f49aab8072ec 406 ERR(" failed to detect command mode");
WiredHome 58:f49aab8072ec 407 state.cmd_mode = false;
WiredHome 34:52e4eec8b790 408 }
WiredHome 58:f49aab8072ec 409 #endif
WiredHome 58:f49aab8072ec 410 } else {
WiredHome 67:557ea7ad15c1 411 wait_ms(460); // manual 1.2.1 (250 msec before and after)
WiredHome 67:557ea7ad15c1 412 #if 1
WiredHome 67:557ea7ad15c1 413 if (send("$$$", 3, NULL, buf, 1500)) {
WiredHome 67:557ea7ad15c1 414 INFO("Resp: [%s]", buf);
WiredHome 67:557ea7ad15c1 415 if ( ! strstr(buf, "CMD")) {
WiredHome 67:557ea7ad15c1 416 WARN("cannot enter cmd mode");
WiredHome 67:557ea7ad15c1 417 send("exit\r", 5, "EXIT", NULL, 100);
WiredHome 67:557ea7ad15c1 418 return false;
WiredHome 67:557ea7ad15c1 419 }
WiredHome 67:557ea7ad15c1 420 }
WiredHome 67:557ea7ad15c1 421 #else
WiredHome 58:f49aab8072ec 422 if (send("$$$", 3, "CMD") == -1) { // the module controls the 'after' delay
WiredHome 58:f49aab8072ec 423 ERR("cannot enter in cmd mode");
WiredHome 67:557ea7ad15c1 424
WiredHome 58:f49aab8072ec 425 return false;
WiredHome 58:f49aab8072ec 426 }
WiredHome 67:557ea7ad15c1 427 #endif
WiredHome 58:f49aab8072ec 428 state.cmd_mode = true;
WiredHome 29:49876a8c445b 429 }
samux 1:fb4494783863 430 return true;
samux 1:fb4494783863 431 }
samux 1:fb4494783863 432
WiredHome 25:a740eb74a86a 433
samux 1:fb4494783863 434 bool Wifly::disconnect()
samux 1:fb4494783863 435 {
samux 1:fb4494783863 436 // if already disconnected, return
samux 1:fb4494783863 437 if (!state.associated)
samux 1:fb4494783863 438 return true;
samux 2:8e54830d0df7 439
samux 1:fb4494783863 440 if (!sendCommand("leave\r", "DeAuth"))
samux 1:fb4494783863 441 return false;
samux 1:fb4494783863 442 exit();
samux 2:8e54830d0df7 443
samux 1:fb4494783863 444 state.associated = false;
samux 1:fb4494783863 445 return true;
samux 1:fb4494783863 446 }
samux 1:fb4494783863 447
WiredHome 25:a740eb74a86a 448
WiredHome 64:6202428f37ec 449 uint16_t Wifly::hextoi(char *p)
WiredHome 64:6202428f37ec 450 {
WiredHome 64:6202428f37ec 451 uint16_t res = 0;
WiredHome 64:6202428f37ec 452
WiredHome 64:6202428f37ec 453 while ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F')) {
WiredHome 64:6202428f37ec 454 if (*p >= '0' && *p <= '9')
WiredHome 64:6202428f37ec 455 res = (res * 16) + (*p - '0');
WiredHome 64:6202428f37ec 456 else if (*p >= 'a' && *p <= 'f')
WiredHome 64:6202428f37ec 457 res = (res * 16) + (*p - 'a' + 10);
WiredHome 64:6202428f37ec 458 else if (*p >= 'A' && *p <= 'F')
WiredHome 64:6202428f37ec 459 res = (res * 16) + (*p - 'A' + 10);
WiredHome 64:6202428f37ec 460 p++;
WiredHome 64:6202428f37ec 461 }
WiredHome 64:6202428f37ec 462 return res;
WiredHome 64:6202428f37ec 463 }
WiredHome 64:6202428f37ec 464
WiredHome 64:6202428f37ec 465
samux 1:fb4494783863 466 bool Wifly::is_connected()
samux 1:fb4494783863 467 {
WiredHome 64:6202428f37ec 468 char buf[30];
WiredHome 64:6202428f37ec 469 uint16_t connectionStatus = 0;
WiredHome 67:557ea7ad15c1 470 bool cnxStatus = false;
WiredHome 64:6202428f37ec 471
WiredHome 64:6202428f37ec 472 if (sendCommand("show connection\r", NULL, buf)) {
WiredHome 64:6202428f37ec 473 connectionStatus = hextoi(buf);
WiredHome 64:6202428f37ec 474 exit();
WiredHome 64:6202428f37ec 475 }
WiredHome 64:6202428f37ec 476 //return (tcp_status.read() == 1) ? true : false; // hw pin
WiredHome 67:557ea7ad15c1 477 if (connectionStatus & 0x0010) { // associated
WiredHome 67:557ea7ad15c1 478 cnxStatus = true;
WiredHome 67:557ea7ad15c1 479 } else {
WiredHome 67:557ea7ad15c1 480 state.associated = false;
WiredHome 67:557ea7ad15c1 481 cnxStatus = false;
WiredHome 67:557ea7ad15c1 482 }
WiredHome 67:557ea7ad15c1 483 return cnxStatus;
samux 1:fb4494783863 484 }
samux 1:fb4494783863 485
samux 1:fb4494783863 486
samux 1:fb4494783863 487 void Wifly::reset()
samux 1:fb4494783863 488 {
samux 1:fb4494783863 489 reset_pin = 0;
WiredHome 25:a740eb74a86a 490 wifi.baud(9600);
WiredHome 55:0729959263b7 491 wait_ms(400);
samux 1:fb4494783863 492 reset_pin = 1;
WiredHome 25:a740eb74a86a 493 GatherLogonInfo();
WiredHome 58:f49aab8072ec 494 INFO("swver %3.2f, {%s}", getWiflyVersion(), getWiflyVersionString());
samux 1:fb4494783863 495 }
samux 1:fb4494783863 496
WiredHome 25:a740eb74a86a 497
samux 3:9aa05e19c62e 498 bool Wifly::reboot()
samux 3:9aa05e19c62e 499 {
WiredHome 26:78a1a09afdc9 500 if (sendCommand("reboot\r", "Reboot")) {
WiredHome 58:f49aab8072ec 501 state.cmd_mode = false;
WiredHome 26:78a1a09afdc9 502 wait_ms(500);
WiredHome 26:78a1a09afdc9 503 wifi.baud(9600);
WiredHome 26:78a1a09afdc9 504 baud(baudrate);
WiredHome 26:78a1a09afdc9 505 exit();
WiredHome 26:78a1a09afdc9 506 return true;
WiredHome 26:78a1a09afdc9 507 } else {
samux 3:9aa05e19c62e 508 return false;
WiredHome 26:78a1a09afdc9 509 }
samux 3:9aa05e19c62e 510 }
samux 3:9aa05e19c62e 511
WiredHome 25:a740eb74a86a 512
samux 1:fb4494783863 513 bool Wifly::close()
samux 1:fb4494783863 514 {
WiredHome 50:cc173c24a316 515 if (!state.tcp) {
WiredHome 34:52e4eec8b790 516 return true; // already closed
WiredHome 50:cc173c24a316 517 }
WiredHome 50:cc173c24a316 518 if (!sendCommand("close\r", "*CLOS*")) {
WiredHome 34:52e4eec8b790 519 return false; // failed to close
WiredHome 50:cc173c24a316 520 }
WiredHome 45:21b7bbaad62b 521 #if 1
WiredHome 34:52e4eec8b790 522 // It appears that the close exits cmd mode
WiredHome 50:cc173c24a316 523 // so we won't bother trying to close which
WiredHome 34:52e4eec8b790 524 // could cause it to open command mode to
WiredHome 50:cc173c24a316 525 // send the close (which add more 0.5s delays).
WiredHome 58:f49aab8072ec 526 state.cmd_mode = false;
WiredHome 45:21b7bbaad62b 527 #else
WiredHome 34:52e4eec8b790 528 flushIn();
WiredHome 34:52e4eec8b790 529 exit();
WiredHome 45:21b7bbaad62b 530 #endif
WiredHome 64:6202428f37ec 531 setConnectionState(false);
WiredHome 34:52e4eec8b790 532 return true; // succeeded to close
samux 1:fb4494783863 533 }
samux 1:fb4494783863 534
samux 1:fb4494783863 535
samux 1:fb4494783863 536 int Wifly::putc(char c)
samux 1:fb4494783863 537 {
WiredHome 25:a740eb74a86a 538 while (!wifi.writeable())
WiredHome 25:a740eb74a86a 539 ;
samux 1:fb4494783863 540 return wifi.putc(c);
samux 1:fb4494783863 541 }
samux 1:fb4494783863 542
samux 1:fb4494783863 543
samux 1:fb4494783863 544 bool Wifly::exit()
samux 1:fb4494783863 545 {
WiredHome 34:52e4eec8b790 546 if (!sendCommand("exit\r", "EXIT")) {
WiredHome 34:52e4eec8b790 547 ERR(" failed to exit.");
samux 1:fb4494783863 548 return false;
WiredHome 34:52e4eec8b790 549 }
WiredHome 58:f49aab8072ec 550 state.cmd_mode = false;
samux 1:fb4494783863 551 return true;
samux 1:fb4494783863 552 }
samux 1:fb4494783863 553
samux 1:fb4494783863 554
samux 1:fb4494783863 555 int Wifly::readable()
samux 1:fb4494783863 556 {
samux 1:fb4494783863 557 return buf_wifly.available();
samux 1:fb4494783863 558 }
samux 1:fb4494783863 559
WiredHome 25:a740eb74a86a 560
samux 1:fb4494783863 561 int Wifly::writeable()
samux 1:fb4494783863 562 {
samux 1:fb4494783863 563 return wifi.writeable();
samux 1:fb4494783863 564 }
samux 1:fb4494783863 565
WiredHome 25:a740eb74a86a 566
samux 1:fb4494783863 567 char Wifly::getc()
samux 1:fb4494783863 568 {
WiredHome 58:f49aab8072ec 569 char c = 0xCC; // avoid compiler warning of uninitialized var.
WiredHome 58:f49aab8072ec 570
WiredHome 25:a740eb74a86a 571 while (!buf_wifly.available())
WiredHome 25:a740eb74a86a 572 ;
samux 1:fb4494783863 573 buf_wifly.dequeue(&c);
samux 1:fb4494783863 574 return c;
samux 1:fb4494783863 575 }
samux 1:fb4494783863 576
WiredHome 25:a740eb74a86a 577
samux 1:fb4494783863 578 void Wifly::handler_rx(void)
samux 1:fb4494783863 579 {
samux 1:fb4494783863 580 //read characters
samux 1:fb4494783863 581 while (wifi.readable())
samux 1:fb4494783863 582 buf_wifly.queue(wifi.getc());
samux 1:fb4494783863 583 }
samux 1:fb4494783863 584
WiredHome 25:a740eb74a86a 585
samux 1:fb4494783863 586 void Wifly::attach_rx(bool callback)
samux 1:fb4494783863 587 {
samux 1:fb4494783863 588 if (!callback)
samux 1:fb4494783863 589 wifi.attach(NULL);
samux 1:fb4494783863 590 else
samux 1:fb4494783863 591 wifi.attach(this, &Wifly::handler_rx);
samux 1:fb4494783863 592 }
samux 1:fb4494783863 593
samux 1:fb4494783863 594 int Wifly::send(const char * str, int len, const char * ACK, char * res, int timeout)
samux 1:fb4494783863 595 {
samux 1:fb4494783863 596 char read;
WiredHome 34:52e4eec8b790 597 int ackIndex = 0;
samux 1:fb4494783863 598 Timer tmr;
samux 1:fb4494783863 599 int result = 0;
samux 1:fb4494783863 600
WiredHome 59:8e15d2ca7bd5 601 INFO("will send: %s\r\n",str);
samux 1:fb4494783863 602 attach_rx(false);
WiredHome 59:8e15d2ca7bd5 603 flushIn();
WiredHome 59:8e15d2ca7bd5 604
samux 1:fb4494783863 605 if (!ACK || !strcmp(ACK, "NO")) {
WiredHome 59:8e15d2ca7bd5 606 for (int i = 0; i < len; i++)
WiredHome 59:8e15d2ca7bd5 607 result = (putc(str[i]) == str[i]) ? result + 1 : result;
samux 1:fb4494783863 608 } else {
WiredHome 59:8e15d2ca7bd5 609 flushIn();
WiredHome 59:8e15d2ca7bd5 610 tmr.start();
WiredHome 59:8e15d2ca7bd5 611 for (int i = 0; i < len; i++)
WiredHome 59:8e15d2ca7bd5 612 result = (putc(str[i]) == str[i]) ? result + 1 : result;
samux 1:fb4494783863 613 while (1) {
samux 1:fb4494783863 614 if (tmr.read_ms() > timeout) {
WiredHome 18:18ab3993d00d 615 flushIn();
WiredHome 67:557ea7ad15c1 616 WARN("timeout awaiting '%s'", ACK);
samux 1:fb4494783863 617 attach_rx(true);
samux 1:fb4494783863 618 return -1;
samux 1:fb4494783863 619 } else if (wifi.readable()) {
samux 1:fb4494783863 620 read = wifi.getc();
WiredHome 67:557ea7ad15c1 621 //printf("%02X ", read);
WiredHome 36:8d868fea6fe6 622 if (tolower(read) != tolower(ACK[ackIndex]))
WiredHome 36:8d868fea6fe6 623 ackIndex = 0;
WiredHome 35:2dc12224cbd6 624 if (tolower(read) == tolower(ACK[ackIndex])) {
WiredHome 34:52e4eec8b790 625 ackIndex++;
WiredHome 59:8e15d2ca7bd5 626 if (ackIndex == strlen(ACK)) {
WiredHome 59:8e15d2ca7bd5 627 flushIn();
WiredHome 34:52e4eec8b790 628 break;
WiredHome 59:8e15d2ca7bd5 629 }
WiredHome 34:52e4eec8b790 630 }
samux 1:fb4494783863 631 }
samux 1:fb4494783863 632 }
WiredHome 67:557ea7ad15c1 633 INFO("check: ACK '%s' received", ACK);
samux 1:fb4494783863 634 attach_rx(true);
samux 1:fb4494783863 635 return result;
samux 1:fb4494783863 636 }
samux 1:fb4494783863 637
samux 1:fb4494783863 638 //the user wants the result from the command (ACK == NULL, res != NULL)
WiredHome 59:8e15d2ca7bd5 639 if ( res != NULL) {
samux 1:fb4494783863 640 int i = 0;
WiredHome 59:8e15d2ca7bd5 641 Timer timeout;
WiredHome 59:8e15d2ca7bd5 642 timeout.start();
WiredHome 59:8e15d2ca7bd5 643 tmr.reset();
samux 1:fb4494783863 644 while (1) {
WiredHome 59:8e15d2ca7bd5 645 if (timeout.read() > 2) {
samux 1:fb4494783863 646 if (i == 0) {
samux 1:fb4494783863 647 res = NULL;
WiredHome 59:8e15d2ca7bd5 648 break;
samux 1:fb4494783863 649 }
WiredHome 59:8e15d2ca7bd5 650 res[i] = '\0';
WiredHome 67:557ea7ad15c1 651 WARN("2 sec timeout: %s", res);
samux 1:fb4494783863 652 break;
samux 1:fb4494783863 653 } else {
WiredHome 59:8e15d2ca7bd5 654 if (tmr.read_ms() > 300) {
WiredHome 59:8e15d2ca7bd5 655 res[i] = '\0';
WiredHome 67:557ea7ad15c1 656 //WARN("user str: %s", res);
WiredHome 59:8e15d2ca7bd5 657 break;
WiredHome 59:8e15d2ca7bd5 658 }
samux 1:fb4494783863 659 if (wifi.readable()) {
WiredHome 59:8e15d2ca7bd5 660 tmr.start();
samux 1:fb4494783863 661 read = wifi.getc();
WiredHome 67:557ea7ad15c1 662 //printf("%02X ", read);
WiredHome 59:8e15d2ca7bd5 663 // we drop \r and \n
WiredHome 67:557ea7ad15c1 664 //if ( read != '\r' && read != '\n') {
WiredHome 59:8e15d2ca7bd5 665 res[i++] = read;
WiredHome 67:557ea7ad15c1 666 //}
samux 1:fb4494783863 667 }
samux 1:fb4494783863 668 }
samux 1:fb4494783863 669 }
WiredHome 67:557ea7ad15c1 670 INFO("user str: %s", res);
samux 1:fb4494783863 671 }
WiredHome 18:18ab3993d00d 672 flushIn();
samux 1:fb4494783863 673 attach_rx(true);
WiredHome 67:557ea7ad15c1 674 INFO("result: %d", result)
samux 1:fb4494783863 675 return result;
WiredHome 18:18ab3993d00d 676 }
WiredHome 18:18ab3993d00d 677
WiredHome 18:18ab3993d00d 678 void Wifly::flushIn(int timeout_ms)
WiredHome 18:18ab3993d00d 679 {
WiredHome 18:18ab3993d00d 680 Timer tmr;
WiredHome 59:8e15d2ca7bd5 681 #if 1 and defined(DEBUG)
WiredHome 18:18ab3993d00d 682 char chatter[500];
WiredHome 18:18ab3993d00d 683 int count = 0;
WiredHome 18:18ab3993d00d 684 int c;
WiredHome 18:18ab3993d00d 685 #endif
WiredHome 18:18ab3993d00d 686
WiredHome 34:52e4eec8b790 687 if (timeout_ms <= 0) {
WiredHome 34:52e4eec8b790 688 timeout_ms = 1; // 2 * 10000 / baudrate; // compute minimal timeout
WiredHome 18:18ab3993d00d 689 }
WiredHome 18:18ab3993d00d 690 tmr.start();
WiredHome 18:18ab3993d00d 691 while (wifi.readable() || (tmr.read_ms() < timeout_ms)) {
WiredHome 18:18ab3993d00d 692 if (wifi.readable()) {
WiredHome 59:8e15d2ca7bd5 693 #if 1 and defined(DEBUG)
WiredHome 29:49876a8c445b 694 c = wifi.getc();
WiredHome 67:557ea7ad15c1 695 //printf("%02X ", c);
WiredHome 34:52e4eec8b790 696 if (count < sizeof(chatter)-1) // guard overflow
WiredHome 34:52e4eec8b790 697 chatter[count++] = c;
WiredHome 18:18ab3993d00d 698 #else
WiredHome 29:49876a8c445b 699 wifi.getc();
WiredHome 18:18ab3993d00d 700 #endif
WiredHome 18:18ab3993d00d 701 tmr.reset();
WiredHome 18:18ab3993d00d 702 tmr.start(); // start should not be necessary
WiredHome 18:18ab3993d00d 703 }
WiredHome 18:18ab3993d00d 704 }
WiredHome 59:8e15d2ca7bd5 705 #if 1 and defined(DEBUG)
WiredHome 18:18ab3993d00d 706 chatter[count] = '\0';
WiredHome 67:557ea7ad15c1 707 if (count && (count > 2 || chatter[0] != '\r' || chatter[1] != '\n')) {
WiredHome 51:a4831b1cb9a4 708 INFO("Wifly::flushIn(%d) {%s}", count, chatter);
WiredHome 67:557ea7ad15c1 709 }
WiredHome 18:18ab3993d00d 710 #endif
WiredHome 18:18ab3993d00d 711 }
WiredHome 20:906b0f951bc3 712
WiredHome 20:906b0f951bc3 713
WiredHome 20:906b0f951bc3 714 // The ARM uart and the Wifly uart have to be in sync or we get
WiredHome 20:906b0f951bc3 715 // no meaningful response, so then have to try the possibilities.
WiredHome 20:906b0f951bc3 716 //
WiredHome 20:906b0f951bc3 717 // First try is at the currently configured ARM uart baud, if
WiredHome 20:906b0f951bc3 718 // that fails then it shifts the ARM uart baud through the probable
WiredHome 20:906b0f951bc3 719 // speeds, trying to establish contact with the Wifly module.
WiredHome 43:df984bf61580 720 // Once contact is demonstrated (by response to the 'ver' command),
WiredHome 20:906b0f951bc3 721 // then it sets the Wifly module and then the ARM uart.
WiredHome 20:906b0f951bc3 722 bool Wifly::baud(int _targetBaud)
WiredHome 20:906b0f951bc3 723 {
WiredHome 20:906b0f951bc3 724 // in testing, 460800 and 921600 may change the Wifly module where you can't
WiredHome 20:906b0f951bc3 725 // change it back w/o a reset. So, we won't even permit those speeds.
WiredHome 43:df984bf61580 726 const int baudrates[] = {2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}; //, 460800, 921600};
WiredHome 20:906b0f951bc3 727 #define BRCOUNT (sizeof(baudrates)/sizeof(baudrates[0]))
WiredHome 51:a4831b1cb9a4 728 char cmd[26]; // sized for "set u i 460800\r" [15+1], plus margin [4]
WiredHome 20:906b0f951bc3 729 int tryIndex = 0;
WiredHome 20:906b0f951bc3 730 bool res = false;
WiredHome 20:906b0f951bc3 731 int userIndex;
WiredHome 20:906b0f951bc3 732
WiredHome 51:a4831b1cb9a4 733 sprintf(cmd, "set uart instant %d\r", _targetBaud);
WiredHome 20:906b0f951bc3 734 // set u i # should cause it to exit command mode (manual 2.3.64),
WiredHome 20:906b0f951bc3 735 // but testing indicates that it does not.
WiredHome 20:906b0f951bc3 736 for (userIndex=0; userIndex < BRCOUNT; userIndex++) {
WiredHome 20:906b0f951bc3 737 if (_targetBaud == baudrates[userIndex]) {
WiredHome 20:906b0f951bc3 738 while (tryIndex <= BRCOUNT) {
WiredHome 51:a4831b1cb9a4 739 //INFO("baud() try: %d: %d", tryIndex, _targetBaud);
WiredHome 20:906b0f951bc3 740 sendCommand(cmd); // shift Wifly to desired speed [it may not respond (see 2.3.64)]
WiredHome 51:a4831b1cb9a4 741 flushIn(10);
WiredHome 58:f49aab8072ec 742 //state.cmd_mode = false; // see note above why this is disabled
WiredHome 20:906b0f951bc3 743 wifi.baud(_targetBaud); // shift the ARM uart to match
WiredHome 51:a4831b1cb9a4 744 if (sendCommand("ver\r", "wifly", NULL, 125)) { // use this to verify communications
WiredHome 20:906b0f951bc3 745 baudrate = _targetBaud;
WiredHome 20:906b0f951bc3 746 res = true;
WiredHome 20:906b0f951bc3 747 break; // success
WiredHome 20:906b0f951bc3 748 }
WiredHome 20:906b0f951bc3 749 // keep trying baudrates between ARM and WiFly
WiredHome 20:906b0f951bc3 750 if (tryIndex < BRCOUNT) {
WiredHome 51:a4831b1cb9a4 751 //INFO(" baud() set to %d", baudrates[tryIndex]);
WiredHome 20:906b0f951bc3 752 wifi.baud(baudrates[tryIndex]);
WiredHome 20:906b0f951bc3 753 }
WiredHome 20:906b0f951bc3 754 tryIndex++;
WiredHome 20:906b0f951bc3 755 }
WiredHome 20:906b0f951bc3 756 break; // if they selected a legitimate baud, try no others
WiredHome 20:906b0f951bc3 757 }
WiredHome 20:906b0f951bc3 758 }
WiredHome 51:a4831b1cb9a4 759 //INFO(" baud() result: %d", res);
WiredHome 20:906b0f951bc3 760 return res;
WiredHome 20:906b0f951bc3 761 }
WiredHome 20:906b0f951bc3 762
WiredHome 25:a740eb74a86a 763
WiredHome 69:a4064f7e3529 764 bool Wifly::FixPhrase(char * dst, size_t dstLen, const char * src)
WiredHome 24:5012a535b1d5 765 {
WiredHome 69:a4064f7e3529 766 if (strlen(src) < dstLen) {
WiredHome 69:a4064f7e3529 767 strcpy(dst, src);
WiredHome 46:4722f7d72aab 768 // change all ' ' to '$' in ssid or passphrase
WiredHome 69:a4064f7e3529 769 for (int i = 0; i < strlen(dst); i++) {
WiredHome 69:a4064f7e3529 770 if ((dst)[i] == ' ')
WiredHome 69:a4064f7e3529 771 (dst)[i] = '$';
WiredHome 24:5012a535b1d5 772 }
WiredHome 69:a4064f7e3529 773 INFO("phrase: {%s} fr {%s}", dst, src);
WiredHome 69:a4064f7e3529 774 return true;
WiredHome 24:5012a535b1d5 775 } else {
WiredHome 69:a4064f7e3529 776 ERR("Source {%s} is too long for destination buffer of %d bytes", src, dstLen);
WiredHome 69:a4064f7e3529 777 return false;
WiredHome 24:5012a535b1d5 778 }
WiredHome 24:5012a535b1d5 779 }
WiredHome 25:a740eb74a86a 780
WiredHome 25:a740eb74a86a 781
WiredHome 25:a740eb74a86a 782 void Wifly::GatherLogonInfo()
WiredHome 25:a740eb74a86a 783 {
WiredHome 25:a740eb74a86a 784 Timer timer;
WiredHome 25:a740eb74a86a 785 char logonText[200];
WiredHome 25:a740eb74a86a 786 int i = 0;
WiredHome 25:a740eb74a86a 787 char *p;
WiredHome 25:a740eb74a86a 788
WiredHome 25:a740eb74a86a 789 timer.start();
WiredHome 25:a740eb74a86a 790 if (wiflyVersionString) {
WiredHome 25:a740eb74a86a 791 free(wiflyVersionString);
WiredHome 25:a740eb74a86a 792 wiflyVersionString = NULL;
WiredHome 25:a740eb74a86a 793 }
WiredHome 25:a740eb74a86a 794 logonText[i] = '\0';
WiredHome 25:a740eb74a86a 795 while (timer.read_ms() < 500) {
WiredHome 56:eba4aabaad3e 796 while (wifi.readable() && (i <sizeof(logonText)-1)) {
WiredHome 25:a740eb74a86a 797 logonText[i++] = wifi.getc();
WiredHome 25:a740eb74a86a 798 }
WiredHome 25:a740eb74a86a 799 }
WiredHome 25:a740eb74a86a 800 logonText[i] = '\0';
WiredHome 25:a740eb74a86a 801 p = strchr(logonText, '\r');
WiredHome 25:a740eb74a86a 802 if (p)
WiredHome 25:a740eb74a86a 803 *p = '\0';
WiredHome 25:a740eb74a86a 804 wiflyVersionString = (char *)malloc(strlen(logonText)+1);
WiredHome 51:a4831b1cb9a4 805 if (wiflyVersionString) {
WiredHome 25:a740eb74a86a 806 strcpy(wiflyVersionString, logonText);
WiredHome 51:a4831b1cb9a4 807 }
WiredHome 51:a4831b1cb9a4 808 p = strstr(logonText, "Ver "); // "Ver 4.00" for ver <= 4.00
WiredHome 51:a4831b1cb9a4 809 if (!p) p = strstr(logonText, "Ver: "); // "Ver: 4.40" new in ver 4.40
WiredHome 25:a740eb74a86a 810 if (p) {
WiredHome 51:a4831b1cb9a4 811 while (*p && (*p < '0' || *p > '9'))
WiredHome 51:a4831b1cb9a4 812 p++;
WiredHome 25:a740eb74a86a 813 swVersion = atof(p);
WiredHome 25:a740eb74a86a 814 }
WiredHome 58:f49aab8072ec 815 WARN("swVersion: %3.2f,\r\nverString: {%s}", swVersion, wiflyVersionString);
WiredHome 25:a740eb74a86a 816 }
WiredHome 25:a740eb74a86a 817
WiredHome 25:a740eb74a86a 818
WiredHome 25:a740eb74a86a 819 float Wifly::getWiflyVersion()
WiredHome 25:a740eb74a86a 820 {
WiredHome 58:f49aab8072ec 821 INFO("swVersion: %3.2f", swVersion);
WiredHome 25:a740eb74a86a 822 return swVersion;
WiredHome 25:a740eb74a86a 823 }
WiredHome 25:a740eb74a86a 824
WiredHome 25:a740eb74a86a 825
WiredHome 25:a740eb74a86a 826 char * Wifly::getWiflyVersionString()
WiredHome 25:a740eb74a86a 827 {
WiredHome 58:f49aab8072ec 828 INFO("version string: %s", wiflyVersionString);
WiredHome 25:a740eb74a86a 829 return wiflyVersionString;
WiredHome 25:a740eb74a86a 830 }
WiredHome 25:a740eb74a86a 831
WiredHome 58:f49aab8072ec 832 bool Wifly::SWUpdateWifly()
WiredHome 58:f49aab8072ec 833 {
WiredHome 58:f49aab8072ec 834 bool success = false;
WiredHome 58:f49aab8072ec 835
WiredHome 58:f49aab8072ec 836 if (is_connected()) {
WiredHome 58:f49aab8072ec 837 // once connected, send command to update firmware
WiredHome 58:f49aab8072ec 838 if (sendCommand("set ftp address 0\r", "AOK")) {
WiredHome 58:f49aab8072ec 839 if (sendCommand("set dns name rn.microchip.com\r", "AOK")) {
WiredHome 59:8e15d2ca7bd5 840 if (sendCommand("save\r", "Stor", NULL, 5000)) {
WiredHome 58:f49aab8072ec 841 if (sendCommand("ftp update\r", "FTP OK", NULL, 30000)) {
WiredHome 58:f49aab8072ec 842 if (sendCommand("factory RESET\r")) {
WiredHome 58:f49aab8072ec 843 if (reboot()) {
WiredHome 58:f49aab8072ec 844 success = true;
WiredHome 58:f49aab8072ec 845 }
WiredHome 58:f49aab8072ec 846 }
WiredHome 58:f49aab8072ec 847 }
WiredHome 58:f49aab8072ec 848 }
WiredHome 58:f49aab8072ec 849 }
WiredHome 58:f49aab8072ec 850 }
WiredHome 58:f49aab8072ec 851 }
WiredHome 58:f49aab8072ec 852 return success;
WiredHome 58:f49aab8072ec 853 }
WiredHome 58:f49aab8072ec 854
WiredHome 26:78a1a09afdc9 855
WiredHome 26:78a1a09afdc9 856 void Wifly::setConnectionState(bool value)
WiredHome 26:78a1a09afdc9 857 {
WiredHome 26:78a1a09afdc9 858 state.tcp = value;
WiredHome 26:78a1a09afdc9 859 }