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:
Thu Sep 25 03:01:07 2014 +0000
Revision:
71:59936f711b80
Parent:
69:a4064f7e3529
Changes to more closely match the EthernetInterface APIs for improve interchangeability.; Increased the timeout in the FlushIn call after sending a command - this helps it clean up the response from a slow command.

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 71:59936f711b80 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 71:59936f711b80 245 Protocol Wifly::getProtocol(void)
WiredHome 71:59936f711b80 246 {
WiredHome 71:59936f711b80 247 return state.proto;
WiredHome 71:59936f711b80 248 }
WiredHome 25:a740eb74a86a 249
samux 1:fb4494783863 250 char * Wifly::getStringSecurity()
samux 1:fb4494783863 251 {
samux 1:fb4494783863 252 switch(state.sec) {
WiredHome 30:f500260463b7 253 case NONE: // 0
samux 1:fb4494783863 254 return "NONE";
WiredHome 30:f500260463b7 255 case WEP_128: // 1
samux 1:fb4494783863 256 return "WEP_128";
WiredHome 30:f500260463b7 257 case WPA1: // 2
WiredHome 30:f500260463b7 258 return "WPA1";
WiredHome 30:f500260463b7 259 case WPA: // 3
samux 1:fb4494783863 260 return "WPA";
WiredHome 30:f500260463b7 261 case WPA2_PSK: // 4
WiredHome 30:f500260463b7 262 return "WPA2_PSK";
WiredHome 30:f500260463b7 263 case ADHOC: // 6
WiredHome 30:f500260463b7 264 return "ADHOC";
WiredHome 30:f500260463b7 265 case WPE_64: // 8
WiredHome 30:f500260463b7 266 return "WPE_64";
WiredHome 30:f500260463b7 267 default: // ?
WiredHome 30:f500260463b7 268 return "UNKNOWN";
samux 1:fb4494783863 269 }
samux 1:fb4494783863 270 }
samux 1:fb4494783863 271
WiredHome 25:a740eb74a86a 272
samux 1:fb4494783863 273 bool Wifly::connect(const char * host, int port)
samux 1:fb4494783863 274 {
samux 1:fb4494783863 275 char rcv[20];
samux 1:fb4494783863 276 char cmd[20];
samux 1:fb4494783863 277
samux 2:8e54830d0df7 278 // try to open
samux 2:8e54830d0df7 279 sprintf(cmd, "open %s %d\r", host, port);
samux 2:8e54830d0df7 280 if (sendCommand(cmd, "OPEN", NULL, 10000)) {
WiredHome 64:6202428f37ec 281 setConnectionState(true);
WiredHome 25:a740eb74a86a 282 exit();
samux 2:8e54830d0df7 283 return true;
samux 1:fb4494783863 284 }
samux 1:fb4494783863 285
samux 2:8e54830d0df7 286 // if failed, retry and parse the response
samux 2:8e54830d0df7 287 if (sendCommand(cmd, NULL, rcv, 5000)) {
samux 1:fb4494783863 288 if (strstr(rcv, "OPEN") == NULL) {
samux 1:fb4494783863 289 if (strstr(rcv, "Connected") != NULL) {
samux 1:fb4494783863 290 if (!sendCommand("close\r", "CLOS"))
samux 1:fb4494783863 291 return false;
samux 2:8e54830d0df7 292 if (!sendCommand(cmd, "OPEN", NULL, 10000))
samux 1:fb4494783863 293 return false;
samux 1:fb4494783863 294 } else {
samux 1:fb4494783863 295 return false;
samux 1:fb4494783863 296 }
samux 1:fb4494783863 297 }
samux 1:fb4494783863 298 } else {
samux 1:fb4494783863 299 return false;
samux 1:fb4494783863 300 }
samux 2:8e54830d0df7 301
WiredHome 64:6202428f37ec 302 setConnectionState(true);
WiredHome 25:a740eb74a86a 303 exit();
samux 1:fb4494783863 304 return true;
samux 1:fb4494783863 305 }
samux 1:fb4494783863 306
samux 1:fb4494783863 307
samux 1:fb4494783863 308 bool Wifly::gethostbyname(const char * host, char * ip)
samux 1:fb4494783863 309 {
samux 1:fb4494783863 310 string h = host;
samux 1:fb4494783863 311 char cmd[30], rcv[100];
samux 1:fb4494783863 312 int l = 0;
samux 1:fb4494783863 313 char * point;
samux 1:fb4494783863 314 int nb_digits = 0;
samux 1:fb4494783863 315
samux 1:fb4494783863 316 // no dns needed
samux 1:fb4494783863 317 int pos = h.find(".");
samux 1:fb4494783863 318 if (pos != string::npos) {
samux 1:fb4494783863 319 string sub = h.substr(0, h.find("."));
samux 1:fb4494783863 320 nb_digits = atoi(sub.c_str());
samux 1:fb4494783863 321 }
samux 1:fb4494783863 322 //printf("substrL %s\r\n", sub.c_str());
samux 1:fb4494783863 323 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) {
samux 1:fb4494783863 324 strcpy(ip, host);
samux 1:fb4494783863 325 }
samux 1:fb4494783863 326 // dns needed
samux 1:fb4494783863 327 else {
samux 1:fb4494783863 328 nb_digits = 0;
samux 1:fb4494783863 329 sprintf(cmd, "lookup %s\r", host);
samux 1:fb4494783863 330 if (!sendCommand(cmd, NULL, rcv))
samux 1:fb4494783863 331 return false;
samux 1:fb4494783863 332
samux 1:fb4494783863 333 // look for the ip address
samux 1:fb4494783863 334 char * begin = strstr(rcv, "=") + 1;
samux 1:fb4494783863 335 for (int i = 0; i < 3; i++) {
samux 1:fb4494783863 336 point = strstr(begin + l, ".");
WiredHome 29:49876a8c445b 337 INFO("str: %s", begin + l);
samux 1:fb4494783863 338 l += point - (begin + l) + 1;
samux 1:fb4494783863 339 }
WiredHome 29:49876a8c445b 340 INFO("str: %s", begin + l);
samux 1:fb4494783863 341 while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') {
WiredHome 29:49876a8c445b 342 INFO("digit: %c", *(begin + l + nb_digits));
samux 1:fb4494783863 343 nb_digits++;
samux 1:fb4494783863 344 }
samux 1:fb4494783863 345 memcpy(ip, begin, l + nb_digits);
samux 1:fb4494783863 346 ip[l+nb_digits] = 0;
WiredHome 29:49876a8c445b 347 INFO("ip from dns: %s", ip);
samux 1:fb4494783863 348 }
samux 1:fb4494783863 349 return true;
samux 1:fb4494783863 350 }
samux 1:fb4494783863 351
samux 1:fb4494783863 352
samux 1:fb4494783863 353 void Wifly::flush()
samux 1:fb4494783863 354 {
WiredHome 51:a4831b1cb9a4 355 #if 0 and defined(DEBUG)
WiredHome 29:49876a8c445b 356 char chatter[500];
WiredHome 29:49876a8c445b 357 int count = 0;
WiredHome 29:49876a8c445b 358 char c;
WiredHome 29:49876a8c445b 359
WiredHome 29:49876a8c445b 360 while (buf_wifly.available()) {
WiredHome 29:49876a8c445b 361 buf_wifly.dequeue(&c);
WiredHome 29:49876a8c445b 362 chatter[count++] = c;
WiredHome 29:49876a8c445b 363 }
WiredHome 29:49876a8c445b 364 chatter[count] = '\0';
WiredHome 29:49876a8c445b 365 if (count)
WiredHome 29:49876a8c445b 366 DBG("Wifly::flush {%s}", chatter);
WiredHome 29:49876a8c445b 367 #endif
samux 1:fb4494783863 368 buf_wifly.flush();
samux 1:fb4494783863 369 }
samux 1:fb4494783863 370
WiredHome 25:a740eb74a86a 371
samux 1:fb4494783863 372 bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout)
samux 1:fb4494783863 373 {
WiredHome 20:906b0f951bc3 374 int tries = 1;
WiredHome 29:49876a8c445b 375
WiredHome 67:557ea7ad15c1 376 INFO("sendCommand");
WiredHome 20:906b0f951bc3 377 while (tries <= 2) {
WiredHome 53:3dd2e7f9edc0 378 if (cmdMode()) { // some influences to the wifi module sometimes kick it out
WiredHome 53:3dd2e7f9edc0 379 if (send(cmd, strlen(cmd), ack, res, timeout) >= 0) {
WiredHome 59:8e15d2ca7bd5 380 INFO(" sendCommand - success");
WiredHome 53:3dd2e7f9edc0 381 return true;
WiredHome 53:3dd2e7f9edc0 382 }
WiredHome 20:906b0f951bc3 383 }
WiredHome 58:f49aab8072ec 384 state.cmd_mode = false; // must not really be in cmd mode
WiredHome 29:49876a8c445b 385 ERR("sendCommand: failure %d when sending: %s", tries, cmd);
WiredHome 20:906b0f951bc3 386 tries++;
samux 1:fb4494783863 387 }
WiredHome 59:8e15d2ca7bd5 388 INFO(" sendCommand - failure");
WiredHome 67:557ea7ad15c1 389 send("exit\r", 5, "EXIT");
WiredHome 17:213844a1864f 390 return false;
samux 1:fb4494783863 391 }
samux 1:fb4494783863 392
WiredHome 25:a740eb74a86a 393
samux 1:fb4494783863 394 bool Wifly::cmdMode()
samux 1:fb4494783863 395 {
WiredHome 67:557ea7ad15c1 396 char buf[200];
samux 1:fb4494783863 397 // if already in cmd mode, return
WiredHome 29:49876a8c445b 398 if (state.cmd_mode) {
WiredHome 67:557ea7ad15c1 399 INFO(" is cmdMode");
WiredHome 67:557ea7ad15c1 400 #if 0
WiredHome 58:f49aab8072ec 401 return true;
WiredHome 58:f49aab8072ec 402 #else // for deeper debugging
WiredHome 29:49876a8c445b 403 // Quick verify to ensure we really are in cmd mode
WiredHome 29:49876a8c445b 404 flushIn(0);
WiredHome 51:a4831b1cb9a4 405 //INFO(" send \\r to test for cmdMode");
WiredHome 29:49876a8c445b 406 if (send("\r", 1, ">") == 1) {
WiredHome 51:a4831b1cb9a4 407 //INFO(" is cmdMode");
WiredHome 29:49876a8c445b 408 return true;
WiredHome 34:52e4eec8b790 409 } else {
WiredHome 58:f49aab8072ec 410 ERR(" failed to detect command mode");
WiredHome 58:f49aab8072ec 411 state.cmd_mode = false;
WiredHome 34:52e4eec8b790 412 }
WiredHome 58:f49aab8072ec 413 #endif
WiredHome 58:f49aab8072ec 414 } else {
WiredHome 67:557ea7ad15c1 415 wait_ms(460); // manual 1.2.1 (250 msec before and after)
WiredHome 67:557ea7ad15c1 416 #if 1
WiredHome 67:557ea7ad15c1 417 if (send("$$$", 3, NULL, buf, 1500)) {
WiredHome 67:557ea7ad15c1 418 INFO("Resp: [%s]", buf);
WiredHome 67:557ea7ad15c1 419 if ( ! strstr(buf, "CMD")) {
WiredHome 67:557ea7ad15c1 420 WARN("cannot enter cmd mode");
WiredHome 67:557ea7ad15c1 421 send("exit\r", 5, "EXIT", NULL, 100);
WiredHome 67:557ea7ad15c1 422 return false;
WiredHome 67:557ea7ad15c1 423 }
WiredHome 67:557ea7ad15c1 424 }
WiredHome 67:557ea7ad15c1 425 #else
WiredHome 58:f49aab8072ec 426 if (send("$$$", 3, "CMD") == -1) { // the module controls the 'after' delay
WiredHome 58:f49aab8072ec 427 ERR("cannot enter in cmd mode");
WiredHome 67:557ea7ad15c1 428
WiredHome 58:f49aab8072ec 429 return false;
WiredHome 58:f49aab8072ec 430 }
WiredHome 67:557ea7ad15c1 431 #endif
WiredHome 58:f49aab8072ec 432 state.cmd_mode = true;
WiredHome 29:49876a8c445b 433 }
samux 1:fb4494783863 434 return true;
samux 1:fb4494783863 435 }
samux 1:fb4494783863 436
WiredHome 25:a740eb74a86a 437
samux 1:fb4494783863 438 bool Wifly::disconnect()
samux 1:fb4494783863 439 {
samux 1:fb4494783863 440 // if already disconnected, return
samux 1:fb4494783863 441 if (!state.associated)
samux 1:fb4494783863 442 return true;
samux 2:8e54830d0df7 443
samux 1:fb4494783863 444 if (!sendCommand("leave\r", "DeAuth"))
samux 1:fb4494783863 445 return false;
samux 1:fb4494783863 446 exit();
samux 2:8e54830d0df7 447
samux 1:fb4494783863 448 state.associated = false;
samux 1:fb4494783863 449 return true;
samux 1:fb4494783863 450 }
samux 1:fb4494783863 451
WiredHome 25:a740eb74a86a 452
WiredHome 64:6202428f37ec 453 uint16_t Wifly::hextoi(char *p)
WiredHome 64:6202428f37ec 454 {
WiredHome 64:6202428f37ec 455 uint16_t res = 0;
WiredHome 64:6202428f37ec 456
WiredHome 64:6202428f37ec 457 while ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F')) {
WiredHome 64:6202428f37ec 458 if (*p >= '0' && *p <= '9')
WiredHome 64:6202428f37ec 459 res = (res * 16) + (*p - '0');
WiredHome 64:6202428f37ec 460 else if (*p >= 'a' && *p <= 'f')
WiredHome 64:6202428f37ec 461 res = (res * 16) + (*p - 'a' + 10);
WiredHome 64:6202428f37ec 462 else if (*p >= 'A' && *p <= 'F')
WiredHome 64:6202428f37ec 463 res = (res * 16) + (*p - 'A' + 10);
WiredHome 64:6202428f37ec 464 p++;
WiredHome 64:6202428f37ec 465 }
WiredHome 64:6202428f37ec 466 return res;
WiredHome 64:6202428f37ec 467 }
WiredHome 64:6202428f37ec 468
WiredHome 64:6202428f37ec 469
samux 1:fb4494783863 470 bool Wifly::is_connected()
samux 1:fb4494783863 471 {
WiredHome 64:6202428f37ec 472 char buf[30];
WiredHome 64:6202428f37ec 473 uint16_t connectionStatus = 0;
WiredHome 67:557ea7ad15c1 474 bool cnxStatus = false;
WiredHome 64:6202428f37ec 475
WiredHome 64:6202428f37ec 476 if (sendCommand("show connection\r", NULL, buf)) {
WiredHome 64:6202428f37ec 477 connectionStatus = hextoi(buf);
WiredHome 64:6202428f37ec 478 exit();
WiredHome 64:6202428f37ec 479 }
WiredHome 64:6202428f37ec 480 //return (tcp_status.read() == 1) ? true : false; // hw pin
WiredHome 67:557ea7ad15c1 481 if (connectionStatus & 0x0010) { // associated
WiredHome 67:557ea7ad15c1 482 cnxStatus = true;
WiredHome 67:557ea7ad15c1 483 } else {
WiredHome 67:557ea7ad15c1 484 state.associated = false;
WiredHome 67:557ea7ad15c1 485 cnxStatus = false;
WiredHome 67:557ea7ad15c1 486 }
WiredHome 67:557ea7ad15c1 487 return cnxStatus;
samux 1:fb4494783863 488 }
samux 1:fb4494783863 489
samux 1:fb4494783863 490
samux 1:fb4494783863 491 void Wifly::reset()
samux 1:fb4494783863 492 {
samux 1:fb4494783863 493 reset_pin = 0;
WiredHome 25:a740eb74a86a 494 wifi.baud(9600);
WiredHome 55:0729959263b7 495 wait_ms(400);
samux 1:fb4494783863 496 reset_pin = 1;
WiredHome 25:a740eb74a86a 497 GatherLogonInfo();
WiredHome 58:f49aab8072ec 498 INFO("swver %3.2f, {%s}", getWiflyVersion(), getWiflyVersionString());
samux 1:fb4494783863 499 }
samux 1:fb4494783863 500
WiredHome 25:a740eb74a86a 501
samux 3:9aa05e19c62e 502 bool Wifly::reboot()
samux 3:9aa05e19c62e 503 {
WiredHome 26:78a1a09afdc9 504 if (sendCommand("reboot\r", "Reboot")) {
WiredHome 58:f49aab8072ec 505 state.cmd_mode = false;
WiredHome 26:78a1a09afdc9 506 wait_ms(500);
WiredHome 26:78a1a09afdc9 507 wifi.baud(9600);
WiredHome 26:78a1a09afdc9 508 baud(baudrate);
WiredHome 26:78a1a09afdc9 509 exit();
WiredHome 26:78a1a09afdc9 510 return true;
WiredHome 26:78a1a09afdc9 511 } else {
samux 3:9aa05e19c62e 512 return false;
WiredHome 26:78a1a09afdc9 513 }
samux 3:9aa05e19c62e 514 }
samux 3:9aa05e19c62e 515
WiredHome 25:a740eb74a86a 516
samux 1:fb4494783863 517 bool Wifly::close()
samux 1:fb4494783863 518 {
WiredHome 50:cc173c24a316 519 if (!state.tcp) {
WiredHome 34:52e4eec8b790 520 return true; // already closed
WiredHome 50:cc173c24a316 521 }
WiredHome 50:cc173c24a316 522 if (!sendCommand("close\r", "*CLOS*")) {
WiredHome 34:52e4eec8b790 523 return false; // failed to close
WiredHome 50:cc173c24a316 524 }
WiredHome 45:21b7bbaad62b 525 #if 1
WiredHome 34:52e4eec8b790 526 // It appears that the close exits cmd mode
WiredHome 50:cc173c24a316 527 // so we won't bother trying to close which
WiredHome 34:52e4eec8b790 528 // could cause it to open command mode to
WiredHome 50:cc173c24a316 529 // send the close (which add more 0.5s delays).
WiredHome 58:f49aab8072ec 530 state.cmd_mode = false;
WiredHome 45:21b7bbaad62b 531 #else
WiredHome 34:52e4eec8b790 532 flushIn();
WiredHome 34:52e4eec8b790 533 exit();
WiredHome 45:21b7bbaad62b 534 #endif
WiredHome 64:6202428f37ec 535 setConnectionState(false);
WiredHome 34:52e4eec8b790 536 return true; // succeeded to close
samux 1:fb4494783863 537 }
samux 1:fb4494783863 538
samux 1:fb4494783863 539
samux 1:fb4494783863 540 int Wifly::putc(char c)
samux 1:fb4494783863 541 {
WiredHome 25:a740eb74a86a 542 while (!wifi.writeable())
WiredHome 25:a740eb74a86a 543 ;
samux 1:fb4494783863 544 return wifi.putc(c);
samux 1:fb4494783863 545 }
samux 1:fb4494783863 546
samux 1:fb4494783863 547
samux 1:fb4494783863 548 bool Wifly::exit()
samux 1:fb4494783863 549 {
WiredHome 34:52e4eec8b790 550 if (!sendCommand("exit\r", "EXIT")) {
WiredHome 34:52e4eec8b790 551 ERR(" failed to exit.");
samux 1:fb4494783863 552 return false;
WiredHome 34:52e4eec8b790 553 }
WiredHome 58:f49aab8072ec 554 state.cmd_mode = false;
samux 1:fb4494783863 555 return true;
samux 1:fb4494783863 556 }
samux 1:fb4494783863 557
samux 1:fb4494783863 558
samux 1:fb4494783863 559 int Wifly::readable()
samux 1:fb4494783863 560 {
samux 1:fb4494783863 561 return buf_wifly.available();
samux 1:fb4494783863 562 }
samux 1:fb4494783863 563
WiredHome 25:a740eb74a86a 564
samux 1:fb4494783863 565 int Wifly::writeable()
samux 1:fb4494783863 566 {
samux 1:fb4494783863 567 return wifi.writeable();
samux 1:fb4494783863 568 }
samux 1:fb4494783863 569
WiredHome 25:a740eb74a86a 570
samux 1:fb4494783863 571 char Wifly::getc()
samux 1:fb4494783863 572 {
WiredHome 58:f49aab8072ec 573 char c = 0xCC; // avoid compiler warning of uninitialized var.
WiredHome 58:f49aab8072ec 574
WiredHome 25:a740eb74a86a 575 while (!buf_wifly.available())
WiredHome 25:a740eb74a86a 576 ;
samux 1:fb4494783863 577 buf_wifly.dequeue(&c);
samux 1:fb4494783863 578 return c;
samux 1:fb4494783863 579 }
samux 1:fb4494783863 580
WiredHome 25:a740eb74a86a 581
samux 1:fb4494783863 582 void Wifly::handler_rx(void)
samux 1:fb4494783863 583 {
samux 1:fb4494783863 584 //read characters
samux 1:fb4494783863 585 while (wifi.readable())
samux 1:fb4494783863 586 buf_wifly.queue(wifi.getc());
samux 1:fb4494783863 587 }
samux 1:fb4494783863 588
WiredHome 25:a740eb74a86a 589
samux 1:fb4494783863 590 void Wifly::attach_rx(bool callback)
samux 1:fb4494783863 591 {
samux 1:fb4494783863 592 if (!callback)
samux 1:fb4494783863 593 wifi.attach(NULL);
samux 1:fb4494783863 594 else
samux 1:fb4494783863 595 wifi.attach(this, &Wifly::handler_rx);
samux 1:fb4494783863 596 }
samux 1:fb4494783863 597
samux 1:fb4494783863 598 int Wifly::send(const char * str, int len, const char * ACK, char * res, int timeout)
samux 1:fb4494783863 599 {
samux 1:fb4494783863 600 char read;
WiredHome 34:52e4eec8b790 601 int ackIndex = 0;
samux 1:fb4494783863 602 Timer tmr;
samux 1:fb4494783863 603 int result = 0;
samux 1:fb4494783863 604
WiredHome 59:8e15d2ca7bd5 605 INFO("will send: %s\r\n",str);
samux 1:fb4494783863 606 attach_rx(false);
WiredHome 59:8e15d2ca7bd5 607 flushIn();
WiredHome 59:8e15d2ca7bd5 608
samux 1:fb4494783863 609 if (!ACK || !strcmp(ACK, "NO")) {
WiredHome 59:8e15d2ca7bd5 610 for (int i = 0; i < len; i++)
WiredHome 59:8e15d2ca7bd5 611 result = (putc(str[i]) == str[i]) ? result + 1 : result;
samux 1:fb4494783863 612 } else {
WiredHome 59:8e15d2ca7bd5 613 flushIn();
WiredHome 59:8e15d2ca7bd5 614 tmr.start();
WiredHome 59:8e15d2ca7bd5 615 for (int i = 0; i < len; i++)
WiredHome 59:8e15d2ca7bd5 616 result = (putc(str[i]) == str[i]) ? result + 1 : result;
samux 1:fb4494783863 617 while (1) {
samux 1:fb4494783863 618 if (tmr.read_ms() > timeout) {
WiredHome 18:18ab3993d00d 619 flushIn();
WiredHome 67:557ea7ad15c1 620 WARN("timeout awaiting '%s'", ACK);
samux 1:fb4494783863 621 attach_rx(true);
samux 1:fb4494783863 622 return -1;
samux 1:fb4494783863 623 } else if (wifi.readable()) {
samux 1:fb4494783863 624 read = wifi.getc();
WiredHome 67:557ea7ad15c1 625 //printf("%02X ", read);
WiredHome 36:8d868fea6fe6 626 if (tolower(read) != tolower(ACK[ackIndex]))
WiredHome 36:8d868fea6fe6 627 ackIndex = 0;
WiredHome 35:2dc12224cbd6 628 if (tolower(read) == tolower(ACK[ackIndex])) {
WiredHome 34:52e4eec8b790 629 ackIndex++;
WiredHome 59:8e15d2ca7bd5 630 if (ackIndex == strlen(ACK)) {
WiredHome 71:59936f711b80 631 flushIn(5); // this small delay let's is remove trailing parts of a command
WiredHome 34:52e4eec8b790 632 break;
WiredHome 59:8e15d2ca7bd5 633 }
WiredHome 34:52e4eec8b790 634 }
samux 1:fb4494783863 635 }
samux 1:fb4494783863 636 }
WiredHome 67:557ea7ad15c1 637 INFO("check: ACK '%s' received", ACK);
samux 1:fb4494783863 638 attach_rx(true);
samux 1:fb4494783863 639 return result;
samux 1:fb4494783863 640 }
samux 1:fb4494783863 641
samux 1:fb4494783863 642 //the user wants the result from the command (ACK == NULL, res != NULL)
WiredHome 59:8e15d2ca7bd5 643 if ( res != NULL) {
samux 1:fb4494783863 644 int i = 0;
WiredHome 59:8e15d2ca7bd5 645 Timer timeout;
WiredHome 59:8e15d2ca7bd5 646 timeout.start();
WiredHome 59:8e15d2ca7bd5 647 tmr.reset();
samux 1:fb4494783863 648 while (1) {
WiredHome 59:8e15d2ca7bd5 649 if (timeout.read() > 2) {
samux 1:fb4494783863 650 if (i == 0) {
samux 1:fb4494783863 651 res = NULL;
WiredHome 59:8e15d2ca7bd5 652 break;
samux 1:fb4494783863 653 }
WiredHome 59:8e15d2ca7bd5 654 res[i] = '\0';
WiredHome 67:557ea7ad15c1 655 WARN("2 sec timeout: %s", res);
samux 1:fb4494783863 656 break;
samux 1:fb4494783863 657 } else {
WiredHome 59:8e15d2ca7bd5 658 if (tmr.read_ms() > 300) {
WiredHome 59:8e15d2ca7bd5 659 res[i] = '\0';
WiredHome 67:557ea7ad15c1 660 //WARN("user str: %s", res);
WiredHome 59:8e15d2ca7bd5 661 break;
WiredHome 59:8e15d2ca7bd5 662 }
samux 1:fb4494783863 663 if (wifi.readable()) {
WiredHome 59:8e15d2ca7bd5 664 tmr.start();
samux 1:fb4494783863 665 read = wifi.getc();
WiredHome 67:557ea7ad15c1 666 //printf("%02X ", read);
WiredHome 59:8e15d2ca7bd5 667 // we drop \r and \n
WiredHome 67:557ea7ad15c1 668 //if ( read != '\r' && read != '\n') {
WiredHome 59:8e15d2ca7bd5 669 res[i++] = read;
WiredHome 67:557ea7ad15c1 670 //}
samux 1:fb4494783863 671 }
samux 1:fb4494783863 672 }
samux 1:fb4494783863 673 }
WiredHome 67:557ea7ad15c1 674 INFO("user str: %s", res);
samux 1:fb4494783863 675 }
WiredHome 18:18ab3993d00d 676 flushIn();
samux 1:fb4494783863 677 attach_rx(true);
WiredHome 67:557ea7ad15c1 678 INFO("result: %d", result)
samux 1:fb4494783863 679 return result;
WiredHome 18:18ab3993d00d 680 }
WiredHome 18:18ab3993d00d 681
WiredHome 18:18ab3993d00d 682 void Wifly::flushIn(int timeout_ms)
WiredHome 18:18ab3993d00d 683 {
WiredHome 18:18ab3993d00d 684 Timer tmr;
WiredHome 59:8e15d2ca7bd5 685 #if 1 and defined(DEBUG)
WiredHome 18:18ab3993d00d 686 char chatter[500];
WiredHome 18:18ab3993d00d 687 int count = 0;
WiredHome 18:18ab3993d00d 688 int c;
WiredHome 18:18ab3993d00d 689 #endif
WiredHome 71:59936f711b80 690 // Attempts to define the timeout based on baudrate didn't work as
WiredHome 71:59936f711b80 691 // expected, so disabled.
WiredHome 34:52e4eec8b790 692 if (timeout_ms <= 0) {
WiredHome 34:52e4eec8b790 693 timeout_ms = 1; // 2 * 10000 / baudrate; // compute minimal timeout
WiredHome 18:18ab3993d00d 694 }
WiredHome 18:18ab3993d00d 695 tmr.start();
WiredHome 18:18ab3993d00d 696 while (wifi.readable() || (tmr.read_ms() < timeout_ms)) {
WiredHome 18:18ab3993d00d 697 if (wifi.readable()) {
WiredHome 59:8e15d2ca7bd5 698 #if 1 and defined(DEBUG)
WiredHome 29:49876a8c445b 699 c = wifi.getc();
WiredHome 67:557ea7ad15c1 700 //printf("%02X ", c);
WiredHome 34:52e4eec8b790 701 if (count < sizeof(chatter)-1) // guard overflow
WiredHome 34:52e4eec8b790 702 chatter[count++] = c;
WiredHome 18:18ab3993d00d 703 #else
WiredHome 29:49876a8c445b 704 wifi.getc();
WiredHome 18:18ab3993d00d 705 #endif
WiredHome 18:18ab3993d00d 706 tmr.reset();
WiredHome 18:18ab3993d00d 707 tmr.start(); // start should not be necessary
WiredHome 18:18ab3993d00d 708 }
WiredHome 18:18ab3993d00d 709 }
WiredHome 59:8e15d2ca7bd5 710 #if 1 and defined(DEBUG)
WiredHome 18:18ab3993d00d 711 chatter[count] = '\0';
WiredHome 67:557ea7ad15c1 712 if (count && (count > 2 || chatter[0] != '\r' || chatter[1] != '\n')) {
WiredHome 51:a4831b1cb9a4 713 INFO("Wifly::flushIn(%d) {%s}", count, chatter);
WiredHome 67:557ea7ad15c1 714 }
WiredHome 18:18ab3993d00d 715 #endif
WiredHome 18:18ab3993d00d 716 }
WiredHome 20:906b0f951bc3 717
WiredHome 20:906b0f951bc3 718
WiredHome 20:906b0f951bc3 719 // The ARM uart and the Wifly uart have to be in sync or we get
WiredHome 20:906b0f951bc3 720 // no meaningful response, so then have to try the possibilities.
WiredHome 20:906b0f951bc3 721 //
WiredHome 20:906b0f951bc3 722 // First try is at the currently configured ARM uart baud, if
WiredHome 20:906b0f951bc3 723 // that fails then it shifts the ARM uart baud through the probable
WiredHome 20:906b0f951bc3 724 // speeds, trying to establish contact with the Wifly module.
WiredHome 43:df984bf61580 725 // Once contact is demonstrated (by response to the 'ver' command),
WiredHome 20:906b0f951bc3 726 // then it sets the Wifly module and then the ARM uart.
WiredHome 20:906b0f951bc3 727 bool Wifly::baud(int _targetBaud)
WiredHome 20:906b0f951bc3 728 {
WiredHome 20:906b0f951bc3 729 // in testing, 460800 and 921600 may change the Wifly module where you can't
WiredHome 20:906b0f951bc3 730 // change it back w/o a reset. So, we won't even permit those speeds.
WiredHome 43:df984bf61580 731 const int baudrates[] = {2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}; //, 460800, 921600};
WiredHome 20:906b0f951bc3 732 #define BRCOUNT (sizeof(baudrates)/sizeof(baudrates[0]))
WiredHome 51:a4831b1cb9a4 733 char cmd[26]; // sized for "set u i 460800\r" [15+1], plus margin [4]
WiredHome 20:906b0f951bc3 734 int tryIndex = 0;
WiredHome 20:906b0f951bc3 735 bool res = false;
WiredHome 20:906b0f951bc3 736 int userIndex;
WiredHome 20:906b0f951bc3 737
WiredHome 51:a4831b1cb9a4 738 sprintf(cmd, "set uart instant %d\r", _targetBaud);
WiredHome 20:906b0f951bc3 739 // set u i # should cause it to exit command mode (manual 2.3.64),
WiredHome 20:906b0f951bc3 740 // but testing indicates that it does not.
WiredHome 20:906b0f951bc3 741 for (userIndex=0; userIndex < BRCOUNT; userIndex++) {
WiredHome 20:906b0f951bc3 742 if (_targetBaud == baudrates[userIndex]) {
WiredHome 20:906b0f951bc3 743 while (tryIndex <= BRCOUNT) {
WiredHome 51:a4831b1cb9a4 744 //INFO("baud() try: %d: %d", tryIndex, _targetBaud);
WiredHome 20:906b0f951bc3 745 sendCommand(cmd); // shift Wifly to desired speed [it may not respond (see 2.3.64)]
WiredHome 51:a4831b1cb9a4 746 flushIn(10);
WiredHome 58:f49aab8072ec 747 //state.cmd_mode = false; // see note above why this is disabled
WiredHome 20:906b0f951bc3 748 wifi.baud(_targetBaud); // shift the ARM uart to match
WiredHome 51:a4831b1cb9a4 749 if (sendCommand("ver\r", "wifly", NULL, 125)) { // use this to verify communications
WiredHome 20:906b0f951bc3 750 baudrate = _targetBaud;
WiredHome 20:906b0f951bc3 751 res = true;
WiredHome 20:906b0f951bc3 752 break; // success
WiredHome 20:906b0f951bc3 753 }
WiredHome 20:906b0f951bc3 754 // keep trying baudrates between ARM and WiFly
WiredHome 20:906b0f951bc3 755 if (tryIndex < BRCOUNT) {
WiredHome 51:a4831b1cb9a4 756 //INFO(" baud() set to %d", baudrates[tryIndex]);
WiredHome 20:906b0f951bc3 757 wifi.baud(baudrates[tryIndex]);
WiredHome 20:906b0f951bc3 758 }
WiredHome 20:906b0f951bc3 759 tryIndex++;
WiredHome 20:906b0f951bc3 760 }
WiredHome 20:906b0f951bc3 761 break; // if they selected a legitimate baud, try no others
WiredHome 20:906b0f951bc3 762 }
WiredHome 20:906b0f951bc3 763 }
WiredHome 51:a4831b1cb9a4 764 //INFO(" baud() result: %d", res);
WiredHome 20:906b0f951bc3 765 return res;
WiredHome 20:906b0f951bc3 766 }
WiredHome 20:906b0f951bc3 767
WiredHome 25:a740eb74a86a 768
WiredHome 69:a4064f7e3529 769 bool Wifly::FixPhrase(char * dst, size_t dstLen, const char * src)
WiredHome 24:5012a535b1d5 770 {
WiredHome 69:a4064f7e3529 771 if (strlen(src) < dstLen) {
WiredHome 69:a4064f7e3529 772 strcpy(dst, src);
WiredHome 46:4722f7d72aab 773 // change all ' ' to '$' in ssid or passphrase
WiredHome 69:a4064f7e3529 774 for (int i = 0; i < strlen(dst); i++) {
WiredHome 69:a4064f7e3529 775 if ((dst)[i] == ' ')
WiredHome 69:a4064f7e3529 776 (dst)[i] = '$';
WiredHome 24:5012a535b1d5 777 }
WiredHome 69:a4064f7e3529 778 INFO("phrase: {%s} fr {%s}", dst, src);
WiredHome 69:a4064f7e3529 779 return true;
WiredHome 24:5012a535b1d5 780 } else {
WiredHome 69:a4064f7e3529 781 ERR("Source {%s} is too long for destination buffer of %d bytes", src, dstLen);
WiredHome 69:a4064f7e3529 782 return false;
WiredHome 24:5012a535b1d5 783 }
WiredHome 24:5012a535b1d5 784 }
WiredHome 25:a740eb74a86a 785
WiredHome 25:a740eb74a86a 786
WiredHome 25:a740eb74a86a 787 void Wifly::GatherLogonInfo()
WiredHome 25:a740eb74a86a 788 {
WiredHome 25:a740eb74a86a 789 Timer timer;
WiredHome 25:a740eb74a86a 790 char logonText[200];
WiredHome 25:a740eb74a86a 791 int i = 0;
WiredHome 25:a740eb74a86a 792 char *p;
WiredHome 25:a740eb74a86a 793
WiredHome 25:a740eb74a86a 794 timer.start();
WiredHome 25:a740eb74a86a 795 if (wiflyVersionString) {
WiredHome 25:a740eb74a86a 796 free(wiflyVersionString);
WiredHome 25:a740eb74a86a 797 wiflyVersionString = NULL;
WiredHome 25:a740eb74a86a 798 }
WiredHome 25:a740eb74a86a 799 logonText[i] = '\0';
WiredHome 25:a740eb74a86a 800 while (timer.read_ms() < 500) {
WiredHome 56:eba4aabaad3e 801 while (wifi.readable() && (i <sizeof(logonText)-1)) {
WiredHome 25:a740eb74a86a 802 logonText[i++] = wifi.getc();
WiredHome 25:a740eb74a86a 803 }
WiredHome 25:a740eb74a86a 804 }
WiredHome 25:a740eb74a86a 805 logonText[i] = '\0';
WiredHome 25:a740eb74a86a 806 p = strchr(logonText, '\r');
WiredHome 25:a740eb74a86a 807 if (p)
WiredHome 25:a740eb74a86a 808 *p = '\0';
WiredHome 25:a740eb74a86a 809 wiflyVersionString = (char *)malloc(strlen(logonText)+1);
WiredHome 51:a4831b1cb9a4 810 if (wiflyVersionString) {
WiredHome 25:a740eb74a86a 811 strcpy(wiflyVersionString, logonText);
WiredHome 51:a4831b1cb9a4 812 }
WiredHome 51:a4831b1cb9a4 813 p = strstr(logonText, "Ver "); // "Ver 4.00" for ver <= 4.00
WiredHome 51:a4831b1cb9a4 814 if (!p) p = strstr(logonText, "Ver: "); // "Ver: 4.40" new in ver 4.40
WiredHome 25:a740eb74a86a 815 if (p) {
WiredHome 51:a4831b1cb9a4 816 while (*p && (*p < '0' || *p > '9'))
WiredHome 51:a4831b1cb9a4 817 p++;
WiredHome 25:a740eb74a86a 818 swVersion = atof(p);
WiredHome 25:a740eb74a86a 819 }
WiredHome 58:f49aab8072ec 820 WARN("swVersion: %3.2f,\r\nverString: {%s}", swVersion, wiflyVersionString);
WiredHome 25:a740eb74a86a 821 }
WiredHome 25:a740eb74a86a 822
WiredHome 25:a740eb74a86a 823
WiredHome 25:a740eb74a86a 824 float Wifly::getWiflyVersion()
WiredHome 25:a740eb74a86a 825 {
WiredHome 58:f49aab8072ec 826 INFO("swVersion: %3.2f", swVersion);
WiredHome 25:a740eb74a86a 827 return swVersion;
WiredHome 25:a740eb74a86a 828 }
WiredHome 25:a740eb74a86a 829
WiredHome 25:a740eb74a86a 830
WiredHome 25:a740eb74a86a 831 char * Wifly::getWiflyVersionString()
WiredHome 25:a740eb74a86a 832 {
WiredHome 58:f49aab8072ec 833 INFO("version string: %s", wiflyVersionString);
WiredHome 25:a740eb74a86a 834 return wiflyVersionString;
WiredHome 25:a740eb74a86a 835 }
WiredHome 25:a740eb74a86a 836
WiredHome 58:f49aab8072ec 837 bool Wifly::SWUpdateWifly()
WiredHome 58:f49aab8072ec 838 {
WiredHome 58:f49aab8072ec 839 bool success = false;
WiredHome 58:f49aab8072ec 840
WiredHome 58:f49aab8072ec 841 if (is_connected()) {
WiredHome 58:f49aab8072ec 842 // once connected, send command to update firmware
WiredHome 58:f49aab8072ec 843 if (sendCommand("set ftp address 0\r", "AOK")) {
WiredHome 58:f49aab8072ec 844 if (sendCommand("set dns name rn.microchip.com\r", "AOK")) {
WiredHome 59:8e15d2ca7bd5 845 if (sendCommand("save\r", "Stor", NULL, 5000)) {
WiredHome 58:f49aab8072ec 846 if (sendCommand("ftp update\r", "FTP OK", NULL, 30000)) {
WiredHome 58:f49aab8072ec 847 if (sendCommand("factory RESET\r")) {
WiredHome 58:f49aab8072ec 848 if (reboot()) {
WiredHome 58:f49aab8072ec 849 success = true;
WiredHome 58:f49aab8072ec 850 }
WiredHome 58:f49aab8072ec 851 }
WiredHome 58:f49aab8072ec 852 }
WiredHome 58:f49aab8072ec 853 }
WiredHome 58:f49aab8072ec 854 }
WiredHome 58:f49aab8072ec 855 }
WiredHome 58:f49aab8072ec 856 }
WiredHome 58:f49aab8072ec 857 return success;
WiredHome 58:f49aab8072ec 858 }
WiredHome 58:f49aab8072ec 859
WiredHome 26:78a1a09afdc9 860
WiredHome 26:78a1a09afdc9 861 void Wifly::setConnectionState(bool value)
WiredHome 26:78a1a09afdc9 862 {
WiredHome 26:78a1a09afdc9 863 state.tcp = value;
WiredHome 26:78a1a09afdc9 864 }