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 Jun 27 17:12:35 2013 +0000
Revision:
10:a594fe035b36
Parent:
9:86105ba18d96
Child:
11:44563217d2b9
Refactoring a number of things, constructor, reset, acquisition of version information.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 5:cc0506dc3565 1 /* Copyright (C) 2012 mbed.org, MIT License
WiredHome 5:cc0506dc3565 2 *
WiredHome 5:cc0506dc3565 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
WiredHome 5:cc0506dc3565 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
WiredHome 5:cc0506dc3565 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
WiredHome 5:cc0506dc3565 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
WiredHome 5:cc0506dc3565 7 * furnished to do so, subject to the following conditions:
WiredHome 5:cc0506dc3565 8 *
WiredHome 5:cc0506dc3565 9 * The above copyright notice and this permission notice shall be included in all copies or
WiredHome 5:cc0506dc3565 10 * substantial portions of the Software.
WiredHome 5:cc0506dc3565 11 *
WiredHome 5:cc0506dc3565 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
WiredHome 5:cc0506dc3565 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
WiredHome 5:cc0506dc3565 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
WiredHome 5:cc0506dc3565 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
WiredHome 5:cc0506dc3565 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
WiredHome 5:cc0506dc3565 17 */
WiredHome 5:cc0506dc3565 18
WiredHome 5:cc0506dc3565 19 /* Modifications by David Smart
WiredHome 5:cc0506dc3565 20 * It is a lengthy set of small mods, including timeout, refactoring to flush the input
WiredHome 5:cc0506dc3565 21 * not store after a join, ability to kick up the baud rate, and many more.
WiredHome 5:cc0506dc3565 22 */
WiredHome 5:cc0506dc3565 23 #include "mbed.h"
WiredHome 5:cc0506dc3565 24 #include "Wifly.h"
WiredHome 5:cc0506dc3565 25 #include <string>
WiredHome 5:cc0506dc3565 26 #include <algorithm>
WiredHome 5:cc0506dc3565 27
WiredHome 5:cc0506dc3565 28 //Debug is disabled by default
WiredHome 10:a594fe035b36 29 #if (1 && !defined(TARGET_LPC11U24))
WiredHome 5:cc0506dc3565 30 #define DEBUG
WiredHome 5:cc0506dc3565 31 #define DBG(x, ...) std::printf("[DBG Wifly%4d] "x"\r\n", __LINE__, ##__VA_ARGS__);
WiredHome 5:cc0506dc3565 32 #define WARN(x, ...) std::printf("[WRN Wifly%4d] "x"\r\n", __LINE__, ##__VA_ARGS__);
WiredHome 5:cc0506dc3565 33 #define ERR(x, ...) std::printf("[ERR Wifly%4d] "x"\r\n", __LINE__, ##__VA_ARGS__);
WiredHome 5:cc0506dc3565 34 #define INFO(x, ...) std::printf("[INF Wifly%4d] "x"\r\n", __LINE__, ##__VA_ARGS__);
WiredHome 5:cc0506dc3565 35 #else
WiredHome 5:cc0506dc3565 36 #define DBG(x, ...)
WiredHome 5:cc0506dc3565 37 #define WARN(x, ...)
WiredHome 5:cc0506dc3565 38 #define ERR(x, ...)
WiredHome 5:cc0506dc3565 39 #define INFO(x, ...)
WiredHome 5:cc0506dc3565 40 #endif
WiredHome 5:cc0506dc3565 41
WiredHome 5:cc0506dc3565 42 #define MAX_TRY_JOIN 3
WiredHome 5:cc0506dc3565 43
WiredHome 5:cc0506dc3565 44 Wifly * Wifly::inst;
WiredHome 5:cc0506dc3565 45
WiredHome 10:a594fe035b36 46 Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * _ssid, const char * _phrase, Security sec):
WiredHome 5:cc0506dc3565 47 wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), buf_wifly(256)
WiredHome 5:cc0506dc3565 48 {
WiredHome 5:cc0506dc3565 49 memset(&state, 0, sizeof(state));
WiredHome 5:cc0506dc3565 50 state.sec = sec;
WiredHome 10:a594fe035b36 51 SetPhrase(&this->ssid, _ssid);
WiredHome 10:a594fe035b36 52 SetPhrase(&this->phrase, _phrase);
WiredHome 5:cc0506dc3565 53 inst = this;
WiredHome 5:cc0506dc3565 54 attach_rx(false);
WiredHome 5:cc0506dc3565 55 state.cmd_mode = false;
WiredHome 10:a594fe035b36 56 wiflyVersionString = NULL;
WiredHome 10:a594fe035b36 57 baudrate = 9600;
WiredHome 5:cc0506dc3565 58 reset();
WiredHome 10:a594fe035b36 59 }
WiredHome 10:a594fe035b36 60
WiredHome 10:a594fe035b36 61
WiredHome 10:a594fe035b36 62 void Wifly::SetPhrase(char ** dst, const char * src) {
WiredHome 10:a594fe035b36 63 // change all ' ' in '$' in the ssid and the passphrase
WiredHome 10:a594fe035b36 64 *dst = (char *)malloc(strlen(src)+1);
WiredHome 10:a594fe035b36 65 if (*dst) {
WiredHome 10:a594fe035b36 66 strcpy(*dst, src);
WiredHome 10:a594fe035b36 67 for (int i = 0; i < strlen(*dst); i++) {
WiredHome 10:a594fe035b36 68 if ((*dst)[i] == ' ')
WiredHome 10:a594fe035b36 69 (*dst)[i] = '$';
WiredHome 10:a594fe035b36 70 }
WiredHome 10:a594fe035b36 71 } else {
WiredHome 10:a594fe035b36 72 *dst = NULL;
WiredHome 10:a594fe035b36 73 }
WiredHome 5:cc0506dc3565 74 }
WiredHome 5:cc0506dc3565 75
WiredHome 5:cc0506dc3565 76
WiredHome 5:cc0506dc3565 77 void Wifly::flushIn(int timeout_ms)
WiredHome 5:cc0506dc3565 78 {
WiredHome 5:cc0506dc3565 79 Timer tmr;
WiredHome 10:a594fe035b36 80
WiredHome 5:cc0506dc3565 81 tmr.start();
WiredHome 5:cc0506dc3565 82 if (timeout_ms == 0) {
WiredHome 9:86105ba18d96 83 timeout_ms = 2 * 10000 / baudrate; // compute minimal timeout
WiredHome 5:cc0506dc3565 84 if (timeout_ms == 0)
WiredHome 5:cc0506dc3565 85 timeout_ms = 2;
WiredHome 5:cc0506dc3565 86 }
WiredHome 5:cc0506dc3565 87 while (wifi.readable() || (tmr.read_ms() < timeout_ms)) {
WiredHome 5:cc0506dc3565 88 if (wifi.readable()) {
WiredHome 5:cc0506dc3565 89 tmr.reset();
WiredHome 5:cc0506dc3565 90 tmr.start(); // start should not be necessary
WiredHome 10:a594fe035b36 91 #if 0 && defined(DEBUG)
WiredHome 5:cc0506dc3565 92 std::putchar(wifi.getc());
WiredHome 5:cc0506dc3565 93 #else
WiredHome 5:cc0506dc3565 94 wifi.getc();
WiredHome 5:cc0506dc3565 95 #endif
WiredHome 5:cc0506dc3565 96 }
WiredHome 5:cc0506dc3565 97 }
WiredHome 5:cc0506dc3565 98 }
WiredHome 5:cc0506dc3565 99
WiredHome 10:a594fe035b36 100 void Wifly::reset() {
WiredHome 10:a594fe035b36 101 reset_pin = 0;
WiredHome 10:a594fe035b36 102 wifi.baud(9600);
WiredHome 10:a594fe035b36 103 wait_ms(200);
WiredHome 10:a594fe035b36 104 reset_pin = 1;
WiredHome 10:a594fe035b36 105 GatherLogonInfo();
WiredHome 10:a594fe035b36 106 }
WiredHome 5:cc0506dc3565 107
WiredHome 10:a594fe035b36 108 void Wifly::GatherLogonInfo() {
WiredHome 10:a594fe035b36 109 Timer timer;
WiredHome 10:a594fe035b36 110 char logonText[200];
WiredHome 10:a594fe035b36 111 int i = 0;
WiredHome 10:a594fe035b36 112 char *p;
WiredHome 10:a594fe035b36 113
WiredHome 10:a594fe035b36 114 timer.start();
WiredHome 10:a594fe035b36 115 if (wiflyVersionString) {
WiredHome 10:a594fe035b36 116 free(wiflyVersionString);
WiredHome 10:a594fe035b36 117 wiflyVersionString = NULL;
WiredHome 10:a594fe035b36 118 }
WiredHome 10:a594fe035b36 119 logonText[i] = '\0';
WiredHome 10:a594fe035b36 120 while (timer.read_ms() < 500) {
WiredHome 10:a594fe035b36 121 while (wifi.readable()) {
WiredHome 10:a594fe035b36 122 logonText[i++] = wifi.getc();
WiredHome 10:a594fe035b36 123 }
WiredHome 10:a594fe035b36 124 }
WiredHome 10:a594fe035b36 125 logonText[i] = '\0';
WiredHome 10:a594fe035b36 126 p = strchr(logonText, '\r');
WiredHome 10:a594fe035b36 127 if (p)
WiredHome 10:a594fe035b36 128 *p = '\0';
WiredHome 10:a594fe035b36 129 wiflyVersionString = (char *)malloc(strlen(logonText)+1);
WiredHome 10:a594fe035b36 130 if (wiflyVersionString)
WiredHome 10:a594fe035b36 131 strcpy(wiflyVersionString, logonText);
WiredHome 10:a594fe035b36 132 p = strstr(logonText, "Ver ");
WiredHome 10:a594fe035b36 133 if (p) {
WiredHome 10:a594fe035b36 134 p += 4;
WiredHome 10:a594fe035b36 135 swVersion = atof(p);
WiredHome 10:a594fe035b36 136 }
WiredHome 10:a594fe035b36 137 }
WiredHome 10:a594fe035b36 138
WiredHome 10:a594fe035b36 139
WiredHome 10:a594fe035b36 140
WiredHome 10:a594fe035b36 141 bool Wifly::reboot()
WiredHome 5:cc0506dc3565 142 {
WiredHome 10:a594fe035b36 143 // if already in cmd mode, return
WiredHome 10:a594fe035b36 144 sendCommand("reboot\r");
WiredHome 10:a594fe035b36 145 wait_ms(300);
WiredHome 10:a594fe035b36 146 wifi.baud(9600); // After a reboot, it is back at 9600 baud because we don't store
WiredHome 10:a594fe035b36 147 baud(baudrate); // shift it up to where you want it
WiredHome 10:a594fe035b36 148 exit(); // exit command mode
WiredHome 10:a594fe035b36 149 return true;
WiredHome 10:a594fe035b36 150 }
WiredHome 10:a594fe035b36 151
WiredHome 10:a594fe035b36 152 #if 1
WiredHome 10:a594fe035b36 153 bool Wifly::baud(int _baudrate) {
WiredHome 5:cc0506dc3565 154 char cmd[20];
WiredHome 10:a594fe035b36 155 bool res = false;
WiredHome 10:a594fe035b36 156
WiredHome 5:cc0506dc3565 157 baudrate = _baudrate;
WiredHome 5:cc0506dc3565 158 sprintf(cmd, "set u i %d\r", baudrate);
WiredHome 5:cc0506dc3565 159 // set u i # causes it to exit command mode (manual 2.3.64)
WiredHome 5:cc0506dc3565 160 // but testing indicates that it does not exit command mode.
WiredHome 10:a594fe035b36 161 sendCommand(cmd); // may not see the answer (see 2.3.64)
WiredHome 10:a594fe035b36 162 wait_ms(10); // more than enough for even 2400 baud
WiredHome 10:a594fe035b36 163 flushIn();
WiredHome 10:a594fe035b36 164 // state.cmd_mode = false; // see note above why this is disabled
WiredHome 10:a594fe035b36 165 wifi.baud(baudrate);
WiredHome 10:a594fe035b36 166 res = true;
WiredHome 10:a594fe035b36 167 return res;
WiredHome 10:a594fe035b36 168 }
WiredHome 10:a594fe035b36 169 #else
WiredHome 10:a594fe035b36 170 bool Wifly::baud(int _baudrate) {
WiredHome 10:a594fe035b36 171 const int baudrates[] = {2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600};
WiredHome 10:a594fe035b36 172 #define BRCOUNT (sizeof(baudrates)/sizeof(baudrates[0]))
WiredHome 10:a594fe035b36 173 char cmd[20];
WiredHome 10:a594fe035b36 174 int test = 0;
WiredHome 10:a594fe035b36 175 bool res = false;
WiredHome 10:a594fe035b36 176
WiredHome 10:a594fe035b36 177 // set u i # causes it to exit command mode (manual 2.3.64)
WiredHome 10:a594fe035b36 178 // but testing indicates that it does not exit command mode.
WiredHome 10:a594fe035b36 179 while (test <= BRCOUNT) {
WiredHome 10:a594fe035b36 180 DBG("baud(%d) test:%d, count:%d", _baudrate, test, BRCOUNT);
WiredHome 10:a594fe035b36 181 flushIn();
WiredHome 10:a594fe035b36 182 sprintf(cmd, "set u i %d\r", _baudrate);
WiredHome 10:a594fe035b36 183 sendCommand(cmd); // may not see a response (see 2.3.64)
WiredHome 10:a594fe035b36 184 flushIn();
WiredHome 10:a594fe035b36 185 if (sendCommand("ver\r", "AOK")) {
WiredHome 10:a594fe035b36 186 // state.cmd_mode = false; // see note above why this is disabled
WiredHome 10:a594fe035b36 187 baudrate = _baudrate;
WiredHome 10:a594fe035b36 188 wifi.baud(baudrate);
WiredHome 10:a594fe035b36 189 DBG(" baud set to %d", baudrate);
WiredHome 10:a594fe035b36 190 res = true;
WiredHome 10:a594fe035b36 191 break;
WiredHome 10:a594fe035b36 192 }
WiredHome 10:a594fe035b36 193 DBG(" next");
WiredHome 10:a594fe035b36 194 // keep trying baudrates between ARM and WiFly
WiredHome 10:a594fe035b36 195 if (test < BRCOUNT) {
WiredHome 10:a594fe035b36 196 DBG("baud test %d", baudrates[test]);
WiredHome 10:a594fe035b36 197 wifi.baud(baudrates[test]);
WiredHome 10:a594fe035b36 198 }
WiredHome 10:a594fe035b36 199 test++;
WiredHome 5:cc0506dc3565 200 }
WiredHome 10:a594fe035b36 201 DBG(" res %d", res);
WiredHome 10:a594fe035b36 202 return res;
WiredHome 5:cc0506dc3565 203 }
WiredHome 10:a594fe035b36 204 #endif
WiredHome 5:cc0506dc3565 205
WiredHome 5:cc0506dc3565 206 bool Wifly::join()
WiredHome 5:cc0506dc3565 207 {
WiredHome 5:cc0506dc3565 208 char cmd[20];
WiredHome 5:cc0506dc3565 209
WiredHome 5:cc0506dc3565 210 for (int i= 0; i < MAX_TRY_JOIN; i++) {
WiredHome 5:cc0506dc3565 211 // no auto join
WiredHome 5:cc0506dc3565 212 if (!sendCommand("set w j 0\r", "AOK"))
WiredHome 5:cc0506dc3565 213 continue;
WiredHome 5:cc0506dc3565 214
WiredHome 5:cc0506dc3565 215 //no echo
WiredHome 5:cc0506dc3565 216 if (!sendCommand("set u m 1\r", "AOK"))
WiredHome 5:cc0506dc3565 217 continue;
WiredHome 5:cc0506dc3565 218
WiredHome 5:cc0506dc3565 219 // set time
WiredHome 5:cc0506dc3565 220 if (!sendCommand("set c t 30\r", "AOK"))
WiredHome 5:cc0506dc3565 221 continue;
WiredHome 5:cc0506dc3565 222
WiredHome 5:cc0506dc3565 223 // set size
WiredHome 5:cc0506dc3565 224 if (!sendCommand("set c s 1420\r", "AOK"))
WiredHome 5:cc0506dc3565 225 continue;
WiredHome 5:cc0506dc3565 226
WiredHome 5:cc0506dc3565 227 // red led on when tcp connection active
WiredHome 5:cc0506dc3565 228 if (!sendCommand("set s i 0x40\r", "AOK"))
WiredHome 5:cc0506dc3565 229 continue;
WiredHome 5:cc0506dc3565 230
WiredHome 5:cc0506dc3565 231 // no string sent to the tcp client
WiredHome 5:cc0506dc3565 232 if (!sendCommand("set c r 0\r", "AOK"))
WiredHome 5:cc0506dc3565 233 continue;
WiredHome 5:cc0506dc3565 234
WiredHome 5:cc0506dc3565 235 // tcp protocol
WiredHome 5:cc0506dc3565 236 if (!sendCommand("set i p 2\r", "AOK"))
WiredHome 5:cc0506dc3565 237 continue;
WiredHome 5:cc0506dc3565 238
WiredHome 5:cc0506dc3565 239 // tcp retry
WiredHome 5:cc0506dc3565 240 if (!sendCommand("set i f 0x7\r", "AOK"))
WiredHome 5:cc0506dc3565 241 continue;
WiredHome 5:cc0506dc3565 242
WiredHome 5:cc0506dc3565 243 // set dns server
WiredHome 5:cc0506dc3565 244 if (!sendCommand("set d n rn.microchip.com\r", "AOK"))
WiredHome 5:cc0506dc3565 245 continue;
WiredHome 5:cc0506dc3565 246
WiredHome 5:cc0506dc3565 247 //dhcp
WiredHome 5:cc0506dc3565 248 sprintf(cmd, "set i d %d\r", (state.dhcp) ? 1 : 0);
WiredHome 5:cc0506dc3565 249 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 250 continue;
WiredHome 5:cc0506dc3565 251
WiredHome 5:cc0506dc3565 252 // ssid
WiredHome 5:cc0506dc3565 253 sprintf(cmd, "set w s %s\r", ssid);
WiredHome 5:cc0506dc3565 254 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 255 continue;
WiredHome 5:cc0506dc3565 256
WiredHome 5:cc0506dc3565 257 //auth
WiredHome 5:cc0506dc3565 258 sprintf(cmd, "set w a %d\r", state.sec);
WiredHome 5:cc0506dc3565 259 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 260 continue;
WiredHome 5:cc0506dc3565 261
WiredHome 5:cc0506dc3565 262 // if no dhcp, set ip, netmask and gateway
WiredHome 5:cc0506dc3565 263 if (!state.dhcp) {
WiredHome 5:cc0506dc3565 264 DBG("not dhcp");
WiredHome 5:cc0506dc3565 265
WiredHome 5:cc0506dc3565 266 sprintf(cmd, "set i a %s\r\n", ip);
WiredHome 5:cc0506dc3565 267 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 268 continue;
WiredHome 5:cc0506dc3565 269
WiredHome 5:cc0506dc3565 270 sprintf(cmd, "set i n %s\r", netmask);
WiredHome 5:cc0506dc3565 271 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 272 continue;
WiredHome 5:cc0506dc3565 273
WiredHome 5:cc0506dc3565 274 sprintf(cmd, "set i g %s\r", gateway);
WiredHome 5:cc0506dc3565 275 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 276 continue;
WiredHome 5:cc0506dc3565 277 }
WiredHome 5:cc0506dc3565 278
WiredHome 5:cc0506dc3565 279 //key step
WiredHome 10:a594fe035b36 280 #if 1
WiredHome 10:a594fe035b36 281 cmd[0] = '\0';
WiredHome 10:a594fe035b36 282 switch (state.sec) {
WiredHome 10:a594fe035b36 283 case WPE_64: // google searching suggests this is a typo and should be WEP_64
WiredHome 10:a594fe035b36 284 case WEP_128:
WiredHome 10:a594fe035b36 285 sprintf(cmd, "set w k %s\r", phrase);
WiredHome 10:a594fe035b36 286 break;
WiredHome 10:a594fe035b36 287 case WPA1:
WiredHome 10:a594fe035b36 288 case WPA_MIXED: // alias WPA
WiredHome 10:a594fe035b36 289 case WPA2_PSK:
WiredHome 10:a594fe035b36 290 sprintf(cmd, "set w p %s\r", phrase);
WiredHome 10:a594fe035b36 291 break;
WiredHome 10:a594fe035b36 292 case ADHOC:
WiredHome 10:a594fe035b36 293 case NONE:
WiredHome 10:a594fe035b36 294 default:
WiredHome 10:a594fe035b36 295 break;
WiredHome 10:a594fe035b36 296 }
WiredHome 10:a594fe035b36 297 if (cmd[0] && !sendCommand(cmd, "AOK"))
WiredHome 10:a594fe035b36 298 continue;
WiredHome 10:a594fe035b36 299 #else // this replaced by what is above
WiredHome 5:cc0506dc3565 300 if (state.sec != NONE) {
WiredHome 5:cc0506dc3565 301 if (state.sec == WPA)
WiredHome 5:cc0506dc3565 302 sprintf(cmd, "set w p %s\r", phrase);
WiredHome 5:cc0506dc3565 303 else if (state.sec == WEP_128)
WiredHome 5:cc0506dc3565 304 sprintf(cmd, "set w k %s\r", phrase);
WiredHome 5:cc0506dc3565 305
WiredHome 5:cc0506dc3565 306 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 307 continue;
WiredHome 5:cc0506dc3565 308 }
WiredHome 10:a594fe035b36 309 #endif
WiredHome 10:a594fe035b36 310
WiredHome 5:cc0506dc3565 311 //join the network (10s timeout)
WiredHome 5:cc0506dc3565 312 if (state.dhcp) {
WiredHome 8:79415e982c32 313 if (!sendCommand("join\r", "DHCP=ON", NULL, 0, 10000))
WiredHome 5:cc0506dc3565 314 continue;
WiredHome 5:cc0506dc3565 315 } else {
WiredHome 8:79415e982c32 316 if (!sendCommand("join\r", "Associated", NULL, 0, 10000))
WiredHome 5:cc0506dc3565 317 continue;
WiredHome 5:cc0506dc3565 318 }
WiredHome 5:cc0506dc3565 319
WiredHome 5:cc0506dc3565 320 //do not store, so it is default on every start
WiredHome 5:cc0506dc3565 321 //if (!sendCommand("save\r", "Stor"))
WiredHome 5:cc0506dc3565 322 // continue;
WiredHome 5:cc0506dc3565 323 exit(); // exit command mode
WiredHome 5:cc0506dc3565 324
WiredHome 5:cc0506dc3565 325 state.associated = true;
WiredHome 5:cc0506dc3565 326 //INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, getStringSecurity());
WiredHome 5:cc0506dc3565 327 return true;
WiredHome 5:cc0506dc3565 328 }
WiredHome 5:cc0506dc3565 329 return false;
WiredHome 5:cc0506dc3565 330 }
WiredHome 5:cc0506dc3565 331
WiredHome 5:cc0506dc3565 332
WiredHome 5:cc0506dc3565 333 bool Wifly::setProtocol(Protocol p)
WiredHome 5:cc0506dc3565 334 {
WiredHome 5:cc0506dc3565 335 // use udp auto pairing
WiredHome 5:cc0506dc3565 336 char cmd[20];
WiredHome 5:cc0506dc3565 337 sprintf(cmd, "set i p %d\r", p);
WiredHome 5:cc0506dc3565 338 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 339 return false;
WiredHome 5:cc0506dc3565 340
WiredHome 5:cc0506dc3565 341 switch(p) {
WiredHome 5:cc0506dc3565 342 case TCP:
WiredHome 5:cc0506dc3565 343 // set ip flags: tcp retry enabled
WiredHome 5:cc0506dc3565 344 if (!sendCommand("set i f 0x07\r", "AOK"))
WiredHome 5:cc0506dc3565 345 return false;
WiredHome 5:cc0506dc3565 346 break;
WiredHome 5:cc0506dc3565 347 case UDP:
WiredHome 5:cc0506dc3565 348 // set ip flags: udp auto pairing enabled
WiredHome 5:cc0506dc3565 349 if (!sendCommand("set i h 0.0.0.0\r", "AOK"))
WiredHome 5:cc0506dc3565 350 return false;
WiredHome 5:cc0506dc3565 351 if (!sendCommand("set i f 0x40\r", "AOK"))
WiredHome 5:cc0506dc3565 352 return false;
WiredHome 5:cc0506dc3565 353 break;
WiredHome 5:cc0506dc3565 354 }
WiredHome 5:cc0506dc3565 355 state.proto = p;
WiredHome 5:cc0506dc3565 356 return true;
WiredHome 5:cc0506dc3565 357 }
WiredHome 5:cc0506dc3565 358
WiredHome 9:86105ba18d96 359
WiredHome 5:cc0506dc3565 360 char * Wifly::getStringSecurity()
WiredHome 5:cc0506dc3565 361 {
WiredHome 5:cc0506dc3565 362 switch(state.sec) {
WiredHome 9:86105ba18d96 363 case NONE: // 0
WiredHome 5:cc0506dc3565 364 return "NONE";
WiredHome 9:86105ba18d96 365 case WEP_128: // 1
WiredHome 5:cc0506dc3565 366 return "WEP_128";
WiredHome 9:86105ba18d96 367 case WPA1: // 2
WiredHome 9:86105ba18d96 368 return "WPA1";
WiredHome 9:86105ba18d96 369 case WPA: // 3
WiredHome 5:cc0506dc3565 370 return "WPA";
WiredHome 9:86105ba18d96 371 case WPA2_PSK: // 4
WiredHome 9:86105ba18d96 372 return "WPA2_PSK";
WiredHome 9:86105ba18d96 373 case ADHOC: // 6
WiredHome 9:86105ba18d96 374 return "ADHOC";
WiredHome 9:86105ba18d96 375 case WPE_64: // 8
WiredHome 9:86105ba18d96 376 return "WPE_64";
WiredHome 9:86105ba18d96 377 default: // ?
WiredHome 9:86105ba18d96 378 return "UNKNOWN";
WiredHome 5:cc0506dc3565 379 }
WiredHome 5:cc0506dc3565 380 }
WiredHome 5:cc0506dc3565 381
WiredHome 5:cc0506dc3565 382 bool Wifly::connect(const char * host, int port)
WiredHome 5:cc0506dc3565 383 {
WiredHome 5:cc0506dc3565 384 char rcv[20];
WiredHome 5:cc0506dc3565 385 char cmd[20];
WiredHome 5:cc0506dc3565 386
WiredHome 5:cc0506dc3565 387 // try to open
WiredHome 8:79415e982c32 388 #if defined(DEBUG)
WiredHome 5:cc0506dc3565 389 printf("Wifly::connect(%s,%d)\r\n", host, port);
WiredHome 8:79415e982c32 390 #endif
WiredHome 5:cc0506dc3565 391 sprintf(cmd, "open %s %d\r", host, port);
WiredHome 8:79415e982c32 392 if (sendCommand(cmd, "OPEN", NULL, 0, 10000)) {
WiredHome 5:cc0506dc3565 393 state.tcp = true;
WiredHome 5:cc0506dc3565 394 state.cmd_mode = false;
WiredHome 5:cc0506dc3565 395 return true;
WiredHome 5:cc0506dc3565 396 }
WiredHome 5:cc0506dc3565 397
WiredHome 5:cc0506dc3565 398 // if failed, retry and parse the response
WiredHome 8:79415e982c32 399 if (sendCommand(cmd, NULL, rcv, sizeof(rcv), 5000)) {
WiredHome 5:cc0506dc3565 400 if (strstr(rcv, "OPEN") == NULL) {
WiredHome 5:cc0506dc3565 401 if (strstr(rcv, "Connected") != NULL) {
WiredHome 6:9b25f2bc3b03 402 //wait_ms(250); //DS This should be unnecessary
WiredHome 5:cc0506dc3565 403 if (!sendCommand("close\r", "CLOS"))
WiredHome 5:cc0506dc3565 404 return false;
WiredHome 6:9b25f2bc3b03 405 //wait_ms(250); //DS This should be unnecessary
WiredHome 8:79415e982c32 406 if (!sendCommand(cmd, "OPEN", NULL, 0, 10000))
WiredHome 5:cc0506dc3565 407 return false;
WiredHome 5:cc0506dc3565 408 } else {
WiredHome 5:cc0506dc3565 409 return false;
WiredHome 5:cc0506dc3565 410 }
WiredHome 5:cc0506dc3565 411 }
WiredHome 5:cc0506dc3565 412 } else {
WiredHome 5:cc0506dc3565 413 return false;
WiredHome 5:cc0506dc3565 414 }
WiredHome 5:cc0506dc3565 415 state.tcp = true;
WiredHome 5:cc0506dc3565 416 state.cmd_mode = false;
WiredHome 5:cc0506dc3565 417 return true;
WiredHome 5:cc0506dc3565 418 }
WiredHome 5:cc0506dc3565 419
WiredHome 5:cc0506dc3565 420 void Wifly::setConnectionState(bool value) {
WiredHome 5:cc0506dc3565 421 state.tcp = value;
WiredHome 5:cc0506dc3565 422 }
WiredHome 5:cc0506dc3565 423
WiredHome 5:cc0506dc3565 424
WiredHome 10:a594fe035b36 425 float Wifly::getWiflyVersion() {
WiredHome 10:a594fe035b36 426 return swVersion;
WiredHome 10:a594fe035b36 427 }
WiredHome 5:cc0506dc3565 428
WiredHome 10:a594fe035b36 429
WiredHome 10:a594fe035b36 430 char * Wifly::getWiflyVersionString() {
WiredHome 10:a594fe035b36 431 return wiflyVersionString;
WiredHome 9:86105ba18d96 432 }
WiredHome 9:86105ba18d96 433
WiredHome 5:cc0506dc3565 434 bool Wifly::gethostbyname(const char * host, char * ip, int sizeof_ip)
WiredHome 5:cc0506dc3565 435 {
WiredHome 5:cc0506dc3565 436 string h = host;
WiredHome 9:86105ba18d96 437 char rcv[100]; // This we hope is generous enough for the "lookup" response
WiredHome 9:86105ba18d96 438 char * cmd;
WiredHome 9:86105ba18d96 439 const char lookup[] = "lookup %s\r";
WiredHome 5:cc0506dc3565 440 int l = 0;
WiredHome 5:cc0506dc3565 441 char * point;
WiredHome 5:cc0506dc3565 442 int nb_digits = 0;
WiredHome 5:cc0506dc3565 443
WiredHome 5:cc0506dc3565 444 // no dns needed
WiredHome 5:cc0506dc3565 445 int pos = h.find(".");
WiredHome 5:cc0506dc3565 446 if (pos != string::npos) {
WiredHome 5:cc0506dc3565 447 string sub = h.substr(0, h.find("."));
WiredHome 5:cc0506dc3565 448 nb_digits = atoi(sub.c_str());
WiredHome 5:cc0506dc3565 449 }
WiredHome 5:cc0506dc3565 450 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) {
WiredHome 5:cc0506dc3565 451 strcpy(ip, host);
WiredHome 5:cc0506dc3565 452 }
WiredHome 5:cc0506dc3565 453 // dns needed
WiredHome 5:cc0506dc3565 454 else {
WiredHome 5:cc0506dc3565 455 nb_digits = 0;
WiredHome 9:86105ba18d96 456 cmd = (char *)malloc(strlen(lookup) + strlen(host));
WiredHome 9:86105ba18d96 457 if (cmd) {
WiredHome 9:86105ba18d96 458 bool ok;
WiredHome 9:86105ba18d96 459 sprintf(cmd, lookup, host);
WiredHome 9:86105ba18d96 460 ok = sendCommand(cmd, NULL, rcv, sizeof(rcv));
WiredHome 9:86105ba18d96 461 free(cmd); // cleanup the allocation when done with the cmd
WiredHome 9:86105ba18d96 462 if (!ok)
WiredHome 9:86105ba18d96 463 return false;
WiredHome 9:86105ba18d96 464 // look for the ip address
WiredHome 9:86105ba18d96 465 char * begin = strstr(rcv, "=") + 1;
WiredHome 9:86105ba18d96 466 for (int i = 0; i < 3; i++) {
WiredHome 9:86105ba18d96 467 point = strstr(begin + l, ".");
WiredHome 9:86105ba18d96 468 DBG("str: %s", begin + l);
WiredHome 9:86105ba18d96 469 l += point - (begin + l) + 1;
WiredHome 9:86105ba18d96 470 }
WiredHome 5:cc0506dc3565 471 DBG("str: %s", begin + l);
WiredHome 9:86105ba18d96 472 while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') {
WiredHome 9:86105ba18d96 473 DBG("digit: %c", *(begin + l + nb_digits));
WiredHome 9:86105ba18d96 474 nb_digits++;
WiredHome 9:86105ba18d96 475 }
WiredHome 9:86105ba18d96 476 if (l + nb_digits <= sizeof_ip) {
WiredHome 9:86105ba18d96 477 memcpy(ip, begin, l + nb_digits);
WiredHome 9:86105ba18d96 478 ip[l+nb_digits] = '\0';
WiredHome 9:86105ba18d96 479 DBG("ip from dns: %s", ip);
WiredHome 9:86105ba18d96 480 } else {
WiredHome 9:86105ba18d96 481 return false;
WiredHome 9:86105ba18d96 482 }
WiredHome 5:cc0506dc3565 483 } else {
WiredHome 9:86105ba18d96 484 return false; // malloc failed
WiredHome 5:cc0506dc3565 485 }
WiredHome 5:cc0506dc3565 486 }
WiredHome 5:cc0506dc3565 487 return true;
WiredHome 5:cc0506dc3565 488 }
WiredHome 5:cc0506dc3565 489
WiredHome 5:cc0506dc3565 490
WiredHome 5:cc0506dc3565 491 void Wifly::flush()
WiredHome 5:cc0506dc3565 492 {
WiredHome 5:cc0506dc3565 493 buf_wifly.flush();
WiredHome 5:cc0506dc3565 494 }
WiredHome 5:cc0506dc3565 495
WiredHome 8:79415e982c32 496 bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int resSize, int timeout)
WiredHome 5:cc0506dc3565 497 {
WiredHome 10:a594fe035b36 498 int tries = 2; // how many tries
WiredHome 10:a594fe035b36 499
WiredHome 5:cc0506dc3565 500 if (!state.cmd_mode) {
WiredHome 5:cc0506dc3565 501 cmdMode();
WiredHome 5:cc0506dc3565 502 }
WiredHome 10:a594fe035b36 503 while (tries--) {
WiredHome 10:a594fe035b36 504 if (send(cmd, strlen(cmd), ack, res, resSize, timeout) >=0 ) {
WiredHome 10:a594fe035b36 505 return true;
WiredHome 10:a594fe035b36 506 }
WiredHome 10:a594fe035b36 507 ERR("sendCommand: cannot '%s'\r\n", cmd);
WiredHome 5:cc0506dc3565 508 }
WiredHome 10:a594fe035b36 509 return false;
WiredHome 5:cc0506dc3565 510 }
WiredHome 5:cc0506dc3565 511
WiredHome 5:cc0506dc3565 512 bool Wifly::cmdMode()
WiredHome 5:cc0506dc3565 513 {
WiredHome 5:cc0506dc3565 514 // if already in cmd mode, return
WiredHome 5:cc0506dc3565 515 if (state.cmd_mode)
WiredHome 5:cc0506dc3565 516 return true;
WiredHome 5:cc0506dc3565 517
WiredHome 5:cc0506dc3565 518 wait_ms(250); // manual 1.2.1 (250 msec before and after)
WiredHome 5:cc0506dc3565 519 if (send("$$$", 3, "CMD") == -1) {
WiredHome 5:cc0506dc3565 520 ERR("cannot enter in cmd mode\r\n");
WiredHome 5:cc0506dc3565 521 exit();
WiredHome 5:cc0506dc3565 522 return false;
WiredHome 5:cc0506dc3565 523 }
WiredHome 5:cc0506dc3565 524 state.cmd_mode = true;
WiredHome 5:cc0506dc3565 525 return true;
WiredHome 5:cc0506dc3565 526 }
WiredHome 5:cc0506dc3565 527
WiredHome 5:cc0506dc3565 528 bool Wifly::disconnect()
WiredHome 5:cc0506dc3565 529 {
WiredHome 5:cc0506dc3565 530 // if already disconnected, return
WiredHome 5:cc0506dc3565 531 if (!state.associated)
WiredHome 5:cc0506dc3565 532 return true;
WiredHome 5:cc0506dc3565 533
WiredHome 5:cc0506dc3565 534 if (!sendCommand("leave\r", "DeAuth"))
WiredHome 5:cc0506dc3565 535 return false;
WiredHome 5:cc0506dc3565 536 exit();
WiredHome 5:cc0506dc3565 537
WiredHome 5:cc0506dc3565 538 state.associated = false;
WiredHome 5:cc0506dc3565 539 return true;
WiredHome 5:cc0506dc3565 540
WiredHome 5:cc0506dc3565 541 }
WiredHome 5:cc0506dc3565 542
WiredHome 5:cc0506dc3565 543 bool Wifly::is_connected()
WiredHome 5:cc0506dc3565 544 {
WiredHome 5:cc0506dc3565 545 return (tcp_status.read() == 1) ? true : false;
WiredHome 5:cc0506dc3565 546 }
WiredHome 5:cc0506dc3565 547
WiredHome 5:cc0506dc3565 548
WiredHome 5:cc0506dc3565 549 bool Wifly::close()
WiredHome 5:cc0506dc3565 550 {
WiredHome 5:cc0506dc3565 551 if (!state.tcp)
WiredHome 5:cc0506dc3565 552 return true;
WiredHome 5:cc0506dc3565 553
WiredHome 5:cc0506dc3565 554 if (!sendCommand("close\r", "CLOS"))
WiredHome 5:cc0506dc3565 555 return false;
WiredHome 5:cc0506dc3565 556 exit();
WiredHome 5:cc0506dc3565 557
WiredHome 5:cc0506dc3565 558 state.tcp = false;
WiredHome 5:cc0506dc3565 559 return true;
WiredHome 5:cc0506dc3565 560 }
WiredHome 5:cc0506dc3565 561
WiredHome 5:cc0506dc3565 562
WiredHome 5:cc0506dc3565 563 int Wifly::putc(char c)
WiredHome 5:cc0506dc3565 564 {
WiredHome 5:cc0506dc3565 565 while (!wifi.writeable())
WiredHome 5:cc0506dc3565 566 ;
WiredHome 5:cc0506dc3565 567 return wifi.putc(c);
WiredHome 5:cc0506dc3565 568 }
WiredHome 5:cc0506dc3565 569
WiredHome 5:cc0506dc3565 570
WiredHome 5:cc0506dc3565 571 bool Wifly::exit()
WiredHome 5:cc0506dc3565 572 {
WiredHome 5:cc0506dc3565 573 flush();
WiredHome 5:cc0506dc3565 574 if (!state.cmd_mode)
WiredHome 5:cc0506dc3565 575 return true;
WiredHome 5:cc0506dc3565 576 if (!sendCommand("exit\r", "EXIT"))
WiredHome 5:cc0506dc3565 577 return false;
WiredHome 5:cc0506dc3565 578 state.cmd_mode = false;
WiredHome 5:cc0506dc3565 579 flush();
WiredHome 5:cc0506dc3565 580 return true;
WiredHome 5:cc0506dc3565 581 }
WiredHome 5:cc0506dc3565 582
WiredHome 5:cc0506dc3565 583
WiredHome 5:cc0506dc3565 584 int Wifly::readable()
WiredHome 5:cc0506dc3565 585 {
WiredHome 5:cc0506dc3565 586 return buf_wifly.available();
WiredHome 5:cc0506dc3565 587 }
WiredHome 5:cc0506dc3565 588
WiredHome 5:cc0506dc3565 589 int Wifly::writeable()
WiredHome 5:cc0506dc3565 590 {
WiredHome 5:cc0506dc3565 591 return wifi.writeable();
WiredHome 5:cc0506dc3565 592 }
WiredHome 5:cc0506dc3565 593
WiredHome 5:cc0506dc3565 594 char Wifly::getc()
WiredHome 5:cc0506dc3565 595 {
WiredHome 5:cc0506dc3565 596 char c;
WiredHome 5:cc0506dc3565 597 while (!buf_wifly.available())
WiredHome 5:cc0506dc3565 598 ;
WiredHome 5:cc0506dc3565 599 buf_wifly.dequeue(&c);
WiredHome 5:cc0506dc3565 600 return c;
WiredHome 5:cc0506dc3565 601 }
WiredHome 5:cc0506dc3565 602
WiredHome 5:cc0506dc3565 603 void Wifly::handler_rx(void)
WiredHome 5:cc0506dc3565 604 {
WiredHome 5:cc0506dc3565 605 //read characters
WiredHome 5:cc0506dc3565 606 while (wifi.readable())
WiredHome 5:cc0506dc3565 607 buf_wifly.queue(wifi.getc());
WiredHome 5:cc0506dc3565 608 }
WiredHome 5:cc0506dc3565 609
WiredHome 5:cc0506dc3565 610 void Wifly::attach_rx(bool callback)
WiredHome 5:cc0506dc3565 611 {
WiredHome 5:cc0506dc3565 612 if (!callback)
WiredHome 5:cc0506dc3565 613 wifi.attach(NULL);
WiredHome 5:cc0506dc3565 614 else
WiredHome 5:cc0506dc3565 615 wifi.attach(this, &Wifly::handler_rx);
WiredHome 5:cc0506dc3565 616 }
WiredHome 5:cc0506dc3565 617
WiredHome 5:cc0506dc3565 618
WiredHome 8:79415e982c32 619 int Wifly::send(const char * str, int len, const char * ACK, char * res, int resSize, int timeout)
WiredHome 5:cc0506dc3565 620 {
WiredHome 5:cc0506dc3565 621 char read;
WiredHome 5:cc0506dc3565 622 size_t found = string::npos;
WiredHome 5:cc0506dc3565 623 string checking;
WiredHome 5:cc0506dc3565 624 Timer tmr;
WiredHome 5:cc0506dc3565 625 int result = 0;
WiredHome 5:cc0506dc3565 626
WiredHome 5:cc0506dc3565 627 attach_rx(false);
WiredHome 5:cc0506dc3565 628
WiredHome 5:cc0506dc3565 629 //We flush the buffer
WiredHome 5:cc0506dc3565 630 flushIn();
WiredHome 5:cc0506dc3565 631
WiredHome 5:cc0506dc3565 632 #ifdef DEBUG
WiredHome 5:cc0506dc3565 633 char dbuf[100];
WiredHome 5:cc0506dc3565 634 strcpy(dbuf, str);
WiredHome 5:cc0506dc3565 635 char * p = dbuf;
WiredHome 5:cc0506dc3565 636 while (*p && *p >= ' ')
WiredHome 5:cc0506dc3565 637 *p++;
WiredHome 5:cc0506dc3565 638 *p = '\0';
WiredHome 5:cc0506dc3565 639 DBG("send(%s,%d,%s,...,%d)",dbuf,len,ACK,timeout);
WiredHome 5:cc0506dc3565 640 #endif
WiredHome 5:cc0506dc3565 641
WiredHome 5:cc0506dc3565 642 if (!ACK || !strcmp(ACK, "NO")) {
WiredHome 5:cc0506dc3565 643 for (int i = 0; i < len; i++)
WiredHome 5:cc0506dc3565 644 result = (putc(str[i]) == str[i]) ? result + 1 : result;
WiredHome 5:cc0506dc3565 645 } else {
WiredHome 5:cc0506dc3565 646 tmr.start();
WiredHome 5:cc0506dc3565 647 for (int i = 0; i < len; i++)
WiredHome 5:cc0506dc3565 648 result = (putc(str[i]) == str[i]) ? result + 1 : result;
WiredHome 5:cc0506dc3565 649 while (1) {
WiredHome 5:cc0506dc3565 650 if (tmr.read_ms() > timeout) {
WiredHome 5:cc0506dc3565 651 DBG(" timeout");
WiredHome 5:cc0506dc3565 652 flushIn();
WiredHome 5:cc0506dc3565 653 //DBG("check: %s", checking.c_str());
WiredHome 5:cc0506dc3565 654 result = -1;
WiredHome 5:cc0506dc3565 655 break;
WiredHome 5:cc0506dc3565 656 } else if (wifi.readable()) {
WiredHome 5:cc0506dc3565 657 read = wifi.getc();
WiredHome 5:cc0506dc3565 658 if ( read != '\r' && read != '\n') {
WiredHome 5:cc0506dc3565 659 checking += read;
WiredHome 5:cc0506dc3565 660 found = checking.find(ACK);
WiredHome 5:cc0506dc3565 661 if (found != string::npos) {
WiredHome 5:cc0506dc3565 662 wait_ms(10);
WiredHome 5:cc0506dc3565 663 flushIn();
WiredHome 5:cc0506dc3565 664 break;
WiredHome 5:cc0506dc3565 665 }
WiredHome 5:cc0506dc3565 666 // We can "early out" if we got an error response
WiredHome 5:cc0506dc3565 667 found = checking.find("ERR: ");
WiredHome 5:cc0506dc3565 668 if (found != string::npos) {
WiredHome 5:cc0506dc3565 669 wait_ms(10);
WiredHome 5:cc0506dc3565 670 ERR(" response: %s", checking.c_str());
WiredHome 5:cc0506dc3565 671 flushIn();
WiredHome 5:cc0506dc3565 672 result = -1;
WiredHome 5:cc0506dc3565 673 break;
WiredHome 5:cc0506dc3565 674 }
WiredHome 5:cc0506dc3565 675 }
WiredHome 5:cc0506dc3565 676 }
WiredHome 5:cc0506dc3565 677 }
WiredHome 5:cc0506dc3565 678 attach_rx(true);
WiredHome 5:cc0506dc3565 679 return result;
WiredHome 5:cc0506dc3565 680 }
WiredHome 5:cc0506dc3565 681
WiredHome 8:79415e982c32 682 //the user wants the result from the command (ACK == NULL, res != NULL, resSize > 0)
WiredHome 8:79415e982c32 683 if ( res != NULL && resSize > 0) {
WiredHome 5:cc0506dc3565 684 int i = 0;
WiredHome 5:cc0506dc3565 685 Timer timeout;
WiredHome 5:cc0506dc3565 686 timeout.start();
WiredHome 5:cc0506dc3565 687 tmr.reset();
WiredHome 8:79415e982c32 688 while (i < resSize) {
WiredHome 5:cc0506dc3565 689 if (timeout.read() > 2) {
WiredHome 5:cc0506dc3565 690 if (i == 0) {
WiredHome 5:cc0506dc3565 691 res = NULL;
WiredHome 5:cc0506dc3565 692 break;
WiredHome 5:cc0506dc3565 693 }
WiredHome 5:cc0506dc3565 694 res[i] = '\0';
WiredHome 5:cc0506dc3565 695 break;
WiredHome 5:cc0506dc3565 696 } else {
WiredHome 5:cc0506dc3565 697 if (tmr.read_ms() > 300) {
WiredHome 5:cc0506dc3565 698 res[i] = '\0';
WiredHome 5:cc0506dc3565 699 break;
WiredHome 5:cc0506dc3565 700 }
WiredHome 5:cc0506dc3565 701 if (wifi.readable()) {
WiredHome 5:cc0506dc3565 702 tmr.start();
WiredHome 5:cc0506dc3565 703 read = wifi.getc();
WiredHome 5:cc0506dc3565 704
WiredHome 5:cc0506dc3565 705 // we drop \r and \n
WiredHome 5:cc0506dc3565 706 if ( read != '\r' && read != '\n') {
WiredHome 5:cc0506dc3565 707 res[i++] = read;
WiredHome 8:79415e982c32 708 res[i] = '\0';
WiredHome 5:cc0506dc3565 709 }
WiredHome 5:cc0506dc3565 710 }
WiredHome 5:cc0506dc3565 711 }
WiredHome 5:cc0506dc3565 712 }
WiredHome 5:cc0506dc3565 713 DBG("user str: %s", res);
WiredHome 5:cc0506dc3565 714 }
WiredHome 5:cc0506dc3565 715
WiredHome 5:cc0506dc3565 716 //We flush the buffer
WiredHome 5:cc0506dc3565 717 flushIn();
WiredHome 5:cc0506dc3565 718
WiredHome 5:cc0506dc3565 719 attach_rx(true);
WiredHome 5:cc0506dc3565 720 return result;
WiredHome 5:cc0506dc3565 721 }
WiredHome 8:79415e982c32 722