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:
Tue Jun 25 18:04:21 2013 +0000
Revision:
9:86105ba18d96
Parent:
8:79415e982c32
Child:
10:a594fe035b36
Reduction in memory allocated requirement
; Add API to get the Wifly module version string.

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 5:cc0506dc3565 29 #if (0 && !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 5:cc0506dc3565 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 5:cc0506dc3565 51
WiredHome 5:cc0506dc3565 52 // change all ' ' in '$' in the ssid and the passphrase
WiredHome 9:86105ba18d96 53 this->ssid = (char *)malloc(strlen(ssid)+1);
WiredHome 9:86105ba18d96 54 if (this->ssid) {
WiredHome 9:86105ba18d96 55 strcpy(this->ssid, ssid);
WiredHome 9:86105ba18d96 56 for (int i = 0; i < strlen(ssid); i++) {
WiredHome 9:86105ba18d96 57 if (this->ssid[i] == ' ')
WiredHome 9:86105ba18d96 58 this->ssid[i] = '$';
WiredHome 9:86105ba18d96 59 }
WiredHome 9:86105ba18d96 60 } else {
WiredHome 9:86105ba18d96 61 this->ssid = NULL;
WiredHome 5:cc0506dc3565 62 }
WiredHome 9:86105ba18d96 63 this->phrase = (char *)malloc(strlen(phrase)+1);
WiredHome 9:86105ba18d96 64 if (this->phrase) {
WiredHome 9:86105ba18d96 65 strcpy(this->phrase, phrase);
WiredHome 9:86105ba18d96 66 for (int i = 0; i < strlen(phrase); i++) {
WiredHome 9:86105ba18d96 67 if (this->phrase[i] == ' ')
WiredHome 9:86105ba18d96 68 this->phrase[i] = '$';
WiredHome 9:86105ba18d96 69 }
WiredHome 9:86105ba18d96 70 } else {
WiredHome 9:86105ba18d96 71 this->phrase = NULL;
WiredHome 5:cc0506dc3565 72 }
WiredHome 9:86105ba18d96 73
WiredHome 5:cc0506dc3565 74 inst = this;
WiredHome 5:cc0506dc3565 75 attach_rx(false);
WiredHome 5:cc0506dc3565 76 state.cmd_mode = false;
WiredHome 9:86105ba18d96 77 wiflyVer = NULL;
WiredHome 5:cc0506dc3565 78 reset();
WiredHome 5:cc0506dc3565 79 baudrate = 9600;
WiredHome 5:cc0506dc3565 80 }
WiredHome 5:cc0506dc3565 81
WiredHome 5:cc0506dc3565 82
WiredHome 5:cc0506dc3565 83 void Wifly::flushIn(int timeout_ms)
WiredHome 5:cc0506dc3565 84 {
WiredHome 5:cc0506dc3565 85 Timer tmr;
WiredHome 5:cc0506dc3565 86 tmr.start();
WiredHome 5:cc0506dc3565 87 if (timeout_ms == 0) {
WiredHome 9:86105ba18d96 88 timeout_ms = 2 * 10000 / baudrate; // compute minimal timeout
WiredHome 5:cc0506dc3565 89 if (timeout_ms == 0)
WiredHome 5:cc0506dc3565 90 timeout_ms = 2;
WiredHome 5:cc0506dc3565 91 }
WiredHome 5:cc0506dc3565 92 while (wifi.readable() || (tmr.read_ms() < timeout_ms)) {
WiredHome 5:cc0506dc3565 93 if (wifi.readable()) {
WiredHome 5:cc0506dc3565 94 tmr.reset();
WiredHome 5:cc0506dc3565 95 tmr.start(); // start should not be necessary
WiredHome 7:b3d740f89f27 96 #if defined(DEBUG)
WiredHome 5:cc0506dc3565 97 std::putchar(wifi.getc());
WiredHome 5:cc0506dc3565 98 #else
WiredHome 5:cc0506dc3565 99 wifi.getc();
WiredHome 5:cc0506dc3565 100 #endif
WiredHome 5:cc0506dc3565 101 }
WiredHome 5:cc0506dc3565 102 }
WiredHome 5:cc0506dc3565 103 }
WiredHome 5:cc0506dc3565 104
WiredHome 5:cc0506dc3565 105
WiredHome 5:cc0506dc3565 106 void Wifly::baud(int _baudrate)
WiredHome 5:cc0506dc3565 107 {
WiredHome 5:cc0506dc3565 108 char cmd[20];
WiredHome 5:cc0506dc3565 109
WiredHome 5:cc0506dc3565 110 baudrate = _baudrate;
WiredHome 5:cc0506dc3565 111 sprintf(cmd, "set u i %d\r", baudrate);
WiredHome 5:cc0506dc3565 112 // set u i # causes it to exit command mode (manual 2.3.64)
WiredHome 5:cc0506dc3565 113 // but testing indicates that it does not exit command mode.
WiredHome 8:79415e982c32 114 if (sendCommand(cmd)) {
WiredHome 5:cc0506dc3565 115 // state.cmd_mode = false; // see note above why this is disabled
WiredHome 5:cc0506dc3565 116 wifi.baud(baudrate);
WiredHome 5:cc0506dc3565 117 }
WiredHome 5:cc0506dc3565 118 }
WiredHome 5:cc0506dc3565 119
WiredHome 5:cc0506dc3565 120 bool Wifly::join()
WiredHome 5:cc0506dc3565 121 {
WiredHome 5:cc0506dc3565 122 char cmd[20];
WiredHome 5:cc0506dc3565 123
WiredHome 5:cc0506dc3565 124 for (int i= 0; i < MAX_TRY_JOIN; i++) {
WiredHome 5:cc0506dc3565 125 // no auto join
WiredHome 5:cc0506dc3565 126 if (!sendCommand("set w j 0\r", "AOK"))
WiredHome 5:cc0506dc3565 127 continue;
WiredHome 5:cc0506dc3565 128
WiredHome 5:cc0506dc3565 129 //no echo
WiredHome 5:cc0506dc3565 130 if (!sendCommand("set u m 1\r", "AOK"))
WiredHome 5:cc0506dc3565 131 continue;
WiredHome 5:cc0506dc3565 132
WiredHome 5:cc0506dc3565 133 // set time
WiredHome 5:cc0506dc3565 134 if (!sendCommand("set c t 30\r", "AOK"))
WiredHome 5:cc0506dc3565 135 continue;
WiredHome 5:cc0506dc3565 136
WiredHome 5:cc0506dc3565 137 // set size
WiredHome 5:cc0506dc3565 138 if (!sendCommand("set c s 1420\r", "AOK"))
WiredHome 5:cc0506dc3565 139 continue;
WiredHome 5:cc0506dc3565 140
WiredHome 5:cc0506dc3565 141 // red led on when tcp connection active
WiredHome 5:cc0506dc3565 142 if (!sendCommand("set s i 0x40\r", "AOK"))
WiredHome 5:cc0506dc3565 143 continue;
WiredHome 5:cc0506dc3565 144
WiredHome 5:cc0506dc3565 145 // no string sent to the tcp client
WiredHome 5:cc0506dc3565 146 if (!sendCommand("set c r 0\r", "AOK"))
WiredHome 5:cc0506dc3565 147 continue;
WiredHome 5:cc0506dc3565 148
WiredHome 5:cc0506dc3565 149 // tcp protocol
WiredHome 5:cc0506dc3565 150 if (!sendCommand("set i p 2\r", "AOK"))
WiredHome 5:cc0506dc3565 151 continue;
WiredHome 5:cc0506dc3565 152
WiredHome 5:cc0506dc3565 153 // tcp retry
WiredHome 5:cc0506dc3565 154 if (!sendCommand("set i f 0x7\r", "AOK"))
WiredHome 5:cc0506dc3565 155 continue;
WiredHome 5:cc0506dc3565 156
WiredHome 5:cc0506dc3565 157 // set dns server
WiredHome 5:cc0506dc3565 158 if (!sendCommand("set d n rn.microchip.com\r", "AOK"))
WiredHome 5:cc0506dc3565 159 continue;
WiredHome 5:cc0506dc3565 160
WiredHome 5:cc0506dc3565 161 //dhcp
WiredHome 5:cc0506dc3565 162 sprintf(cmd, "set i d %d\r", (state.dhcp) ? 1 : 0);
WiredHome 5:cc0506dc3565 163 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 164 continue;
WiredHome 5:cc0506dc3565 165
WiredHome 5:cc0506dc3565 166 // ssid
WiredHome 5:cc0506dc3565 167 sprintf(cmd, "set w s %s\r", ssid);
WiredHome 5:cc0506dc3565 168 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 169 continue;
WiredHome 5:cc0506dc3565 170
WiredHome 5:cc0506dc3565 171 //auth
WiredHome 5:cc0506dc3565 172 sprintf(cmd, "set w a %d\r", state.sec);
WiredHome 5:cc0506dc3565 173 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 174 continue;
WiredHome 5:cc0506dc3565 175
WiredHome 5:cc0506dc3565 176 // if no dhcp, set ip, netmask and gateway
WiredHome 5:cc0506dc3565 177 if (!state.dhcp) {
WiredHome 5:cc0506dc3565 178 DBG("not dhcp");
WiredHome 5:cc0506dc3565 179
WiredHome 5:cc0506dc3565 180 sprintf(cmd, "set i a %s\r\n", ip);
WiredHome 5:cc0506dc3565 181 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 182 continue;
WiredHome 5:cc0506dc3565 183
WiredHome 5:cc0506dc3565 184 sprintf(cmd, "set i n %s\r", netmask);
WiredHome 5:cc0506dc3565 185 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 186 continue;
WiredHome 5:cc0506dc3565 187
WiredHome 5:cc0506dc3565 188 sprintf(cmd, "set i g %s\r", gateway);
WiredHome 5:cc0506dc3565 189 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 190 continue;
WiredHome 5:cc0506dc3565 191 }
WiredHome 5:cc0506dc3565 192
WiredHome 5:cc0506dc3565 193 //key step
WiredHome 5:cc0506dc3565 194 if (state.sec != NONE) {
WiredHome 5:cc0506dc3565 195 if (state.sec == WPA)
WiredHome 5:cc0506dc3565 196 sprintf(cmd, "set w p %s\r", phrase);
WiredHome 5:cc0506dc3565 197 else if (state.sec == WEP_128)
WiredHome 5:cc0506dc3565 198 sprintf(cmd, "set w k %s\r", phrase);
WiredHome 5:cc0506dc3565 199
WiredHome 5:cc0506dc3565 200 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 201 continue;
WiredHome 5:cc0506dc3565 202 }
WiredHome 5:cc0506dc3565 203
WiredHome 5:cc0506dc3565 204 //join the network (10s timeout)
WiredHome 5:cc0506dc3565 205 if (state.dhcp) {
WiredHome 8:79415e982c32 206 if (!sendCommand("join\r", "DHCP=ON", NULL, 0, 10000))
WiredHome 5:cc0506dc3565 207 continue;
WiredHome 5:cc0506dc3565 208 } else {
WiredHome 8:79415e982c32 209 if (!sendCommand("join\r", "Associated", NULL, 0, 10000))
WiredHome 5:cc0506dc3565 210 continue;
WiredHome 5:cc0506dc3565 211 }
WiredHome 5:cc0506dc3565 212
WiredHome 5:cc0506dc3565 213 //do not store, so it is default on every start
WiredHome 5:cc0506dc3565 214 //if (!sendCommand("save\r", "Stor"))
WiredHome 5:cc0506dc3565 215 // continue;
WiredHome 5:cc0506dc3565 216 exit(); // exit command mode
WiredHome 5:cc0506dc3565 217
WiredHome 5:cc0506dc3565 218 state.associated = true;
WiredHome 5:cc0506dc3565 219 //INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, getStringSecurity());
WiredHome 5:cc0506dc3565 220 return true;
WiredHome 5:cc0506dc3565 221 }
WiredHome 5:cc0506dc3565 222 return false;
WiredHome 5:cc0506dc3565 223 }
WiredHome 5:cc0506dc3565 224
WiredHome 5:cc0506dc3565 225
WiredHome 5:cc0506dc3565 226 bool Wifly::setProtocol(Protocol p)
WiredHome 5:cc0506dc3565 227 {
WiredHome 5:cc0506dc3565 228 // use udp auto pairing
WiredHome 5:cc0506dc3565 229 char cmd[20];
WiredHome 5:cc0506dc3565 230 sprintf(cmd, "set i p %d\r", p);
WiredHome 5:cc0506dc3565 231 if (!sendCommand(cmd, "AOK"))
WiredHome 5:cc0506dc3565 232 return false;
WiredHome 5:cc0506dc3565 233
WiredHome 5:cc0506dc3565 234 switch(p) {
WiredHome 5:cc0506dc3565 235 case TCP:
WiredHome 5:cc0506dc3565 236 // set ip flags: tcp retry enabled
WiredHome 5:cc0506dc3565 237 if (!sendCommand("set i f 0x07\r", "AOK"))
WiredHome 5:cc0506dc3565 238 return false;
WiredHome 5:cc0506dc3565 239 break;
WiredHome 5:cc0506dc3565 240 case UDP:
WiredHome 5:cc0506dc3565 241 // set ip flags: udp auto pairing enabled
WiredHome 5:cc0506dc3565 242 if (!sendCommand("set i h 0.0.0.0\r", "AOK"))
WiredHome 5:cc0506dc3565 243 return false;
WiredHome 5:cc0506dc3565 244 if (!sendCommand("set i f 0x40\r", "AOK"))
WiredHome 5:cc0506dc3565 245 return false;
WiredHome 5:cc0506dc3565 246 break;
WiredHome 5:cc0506dc3565 247 }
WiredHome 5:cc0506dc3565 248 state.proto = p;
WiredHome 5:cc0506dc3565 249 return true;
WiredHome 5:cc0506dc3565 250 }
WiredHome 5:cc0506dc3565 251
WiredHome 9:86105ba18d96 252
WiredHome 5:cc0506dc3565 253 char * Wifly::getStringSecurity()
WiredHome 5:cc0506dc3565 254 {
WiredHome 5:cc0506dc3565 255 switch(state.sec) {
WiredHome 9:86105ba18d96 256 case NONE: // 0
WiredHome 5:cc0506dc3565 257 return "NONE";
WiredHome 9:86105ba18d96 258 case WEP_128: // 1
WiredHome 5:cc0506dc3565 259 return "WEP_128";
WiredHome 9:86105ba18d96 260 case WPA1: // 2
WiredHome 9:86105ba18d96 261 return "WPA1";
WiredHome 9:86105ba18d96 262 case WPA: // 3
WiredHome 5:cc0506dc3565 263 return "WPA";
WiredHome 9:86105ba18d96 264 case WPA2_PSK: // 4
WiredHome 9:86105ba18d96 265 return "WPA2_PSK";
WiredHome 9:86105ba18d96 266 case ADHOC: // 6
WiredHome 9:86105ba18d96 267 return "ADHOC";
WiredHome 9:86105ba18d96 268 case WPE_64: // 8
WiredHome 9:86105ba18d96 269 return "WPE_64";
WiredHome 9:86105ba18d96 270 default: // ?
WiredHome 9:86105ba18d96 271 return "UNKNOWN";
WiredHome 5:cc0506dc3565 272 }
WiredHome 5:cc0506dc3565 273 }
WiredHome 5:cc0506dc3565 274
WiredHome 5:cc0506dc3565 275 bool Wifly::connect(const char * host, int port)
WiredHome 5:cc0506dc3565 276 {
WiredHome 5:cc0506dc3565 277 char rcv[20];
WiredHome 5:cc0506dc3565 278 char cmd[20];
WiredHome 5:cc0506dc3565 279
WiredHome 5:cc0506dc3565 280 // try to open
WiredHome 8:79415e982c32 281 #if defined(DEBUG)
WiredHome 5:cc0506dc3565 282 printf("Wifly::connect(%s,%d)\r\n", host, port);
WiredHome 8:79415e982c32 283 #endif
WiredHome 5:cc0506dc3565 284 sprintf(cmd, "open %s %d\r", host, port);
WiredHome 8:79415e982c32 285 if (sendCommand(cmd, "OPEN", NULL, 0, 10000)) {
WiredHome 5:cc0506dc3565 286 state.tcp = true;
WiredHome 5:cc0506dc3565 287 state.cmd_mode = false;
WiredHome 5:cc0506dc3565 288 return true;
WiredHome 5:cc0506dc3565 289 }
WiredHome 5:cc0506dc3565 290
WiredHome 5:cc0506dc3565 291 // if failed, retry and parse the response
WiredHome 8:79415e982c32 292 if (sendCommand(cmd, NULL, rcv, sizeof(rcv), 5000)) {
WiredHome 5:cc0506dc3565 293 if (strstr(rcv, "OPEN") == NULL) {
WiredHome 5:cc0506dc3565 294 if (strstr(rcv, "Connected") != NULL) {
WiredHome 6:9b25f2bc3b03 295 //wait_ms(250); //DS This should be unnecessary
WiredHome 5:cc0506dc3565 296 if (!sendCommand("close\r", "CLOS"))
WiredHome 5:cc0506dc3565 297 return false;
WiredHome 6:9b25f2bc3b03 298 //wait_ms(250); //DS This should be unnecessary
WiredHome 8:79415e982c32 299 if (!sendCommand(cmd, "OPEN", NULL, 0, 10000))
WiredHome 5:cc0506dc3565 300 return false;
WiredHome 5:cc0506dc3565 301 } else {
WiredHome 5:cc0506dc3565 302 return false;
WiredHome 5:cc0506dc3565 303 }
WiredHome 5:cc0506dc3565 304 }
WiredHome 5:cc0506dc3565 305 } else {
WiredHome 5:cc0506dc3565 306 return false;
WiredHome 5:cc0506dc3565 307 }
WiredHome 5:cc0506dc3565 308
WiredHome 5:cc0506dc3565 309 state.tcp = true;
WiredHome 5:cc0506dc3565 310 state.cmd_mode = false;
WiredHome 5:cc0506dc3565 311
WiredHome 5:cc0506dc3565 312 return true;
WiredHome 5:cc0506dc3565 313 }
WiredHome 5:cc0506dc3565 314
WiredHome 5:cc0506dc3565 315 void Wifly::setConnectionState(bool value) {
WiredHome 5:cc0506dc3565 316 state.tcp = value;
WiredHome 5:cc0506dc3565 317 }
WiredHome 5:cc0506dc3565 318
WiredHome 5:cc0506dc3565 319
WiredHome 5:cc0506dc3565 320
WiredHome 9:86105ba18d96 321 char * Wifly::getWiflyVerString() {
WiredHome 9:86105ba18d96 322 char rcv[128]; // This we hope is generous enough
WiredHome 9:86105ba18d96 323
WiredHome 9:86105ba18d96 324 if (wiflyVer == NULL) {
WiredHome 9:86105ba18d96 325 if (!sendCommand("ver\r", NULL, rcv, sizeof(rcv), 2000))
WiredHome 9:86105ba18d96 326 return NULL;
WiredHome 9:86105ba18d96 327 wiflyVer = (char *)malloc(strlen(rcv)+1);
WiredHome 9:86105ba18d96 328 if (wiflyVer)
WiredHome 9:86105ba18d96 329 strcpy(wiflyVer, rcv);
WiredHome 9:86105ba18d96 330 flush();
WiredHome 9:86105ba18d96 331 }
WiredHome 9:86105ba18d96 332 return wiflyVer;
WiredHome 9:86105ba18d96 333 }
WiredHome 9:86105ba18d96 334
WiredHome 5:cc0506dc3565 335 bool Wifly::gethostbyname(const char * host, char * ip, int sizeof_ip)
WiredHome 5:cc0506dc3565 336 {
WiredHome 5:cc0506dc3565 337 string h = host;
WiredHome 9:86105ba18d96 338 char rcv[100]; // This we hope is generous enough for the "lookup" response
WiredHome 9:86105ba18d96 339 char * cmd;
WiredHome 9:86105ba18d96 340 const char lookup[] = "lookup %s\r";
WiredHome 5:cc0506dc3565 341 int l = 0;
WiredHome 5:cc0506dc3565 342 char * point;
WiredHome 5:cc0506dc3565 343 int nb_digits = 0;
WiredHome 5:cc0506dc3565 344
WiredHome 5:cc0506dc3565 345 // no dns needed
WiredHome 5:cc0506dc3565 346 int pos = h.find(".");
WiredHome 5:cc0506dc3565 347 if (pos != string::npos) {
WiredHome 5:cc0506dc3565 348 string sub = h.substr(0, h.find("."));
WiredHome 5:cc0506dc3565 349 nb_digits = atoi(sub.c_str());
WiredHome 5:cc0506dc3565 350 }
WiredHome 5:cc0506dc3565 351 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) {
WiredHome 5:cc0506dc3565 352 strcpy(ip, host);
WiredHome 5:cc0506dc3565 353 }
WiredHome 5:cc0506dc3565 354 // dns needed
WiredHome 5:cc0506dc3565 355 else {
WiredHome 5:cc0506dc3565 356 nb_digits = 0;
WiredHome 9:86105ba18d96 357 cmd = (char *)malloc(strlen(lookup) + strlen(host));
WiredHome 9:86105ba18d96 358 if (cmd) {
WiredHome 9:86105ba18d96 359 bool ok;
WiredHome 9:86105ba18d96 360 sprintf(cmd, lookup, host);
WiredHome 9:86105ba18d96 361 ok = sendCommand(cmd, NULL, rcv, sizeof(rcv));
WiredHome 9:86105ba18d96 362 free(cmd); // cleanup the allocation when done with the cmd
WiredHome 9:86105ba18d96 363 if (!ok)
WiredHome 9:86105ba18d96 364 return false;
WiredHome 9:86105ba18d96 365 // look for the ip address
WiredHome 9:86105ba18d96 366 char * begin = strstr(rcv, "=") + 1;
WiredHome 9:86105ba18d96 367 for (int i = 0; i < 3; i++) {
WiredHome 9:86105ba18d96 368 point = strstr(begin + l, ".");
WiredHome 9:86105ba18d96 369 DBG("str: %s", begin + l);
WiredHome 9:86105ba18d96 370 l += point - (begin + l) + 1;
WiredHome 9:86105ba18d96 371 }
WiredHome 5:cc0506dc3565 372 DBG("str: %s", begin + l);
WiredHome 9:86105ba18d96 373 while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') {
WiredHome 9:86105ba18d96 374 DBG("digit: %c", *(begin + l + nb_digits));
WiredHome 9:86105ba18d96 375 nb_digits++;
WiredHome 9:86105ba18d96 376 }
WiredHome 9:86105ba18d96 377 if (l + nb_digits <= sizeof_ip) {
WiredHome 9:86105ba18d96 378 memcpy(ip, begin, l + nb_digits);
WiredHome 9:86105ba18d96 379 ip[l+nb_digits] = '\0';
WiredHome 9:86105ba18d96 380 DBG("ip from dns: %s", ip);
WiredHome 9:86105ba18d96 381 } else {
WiredHome 9:86105ba18d96 382 return false;
WiredHome 9:86105ba18d96 383 }
WiredHome 5:cc0506dc3565 384 } else {
WiredHome 9:86105ba18d96 385 return false; // malloc failed
WiredHome 5:cc0506dc3565 386 }
WiredHome 5:cc0506dc3565 387 }
WiredHome 5:cc0506dc3565 388 return true;
WiredHome 5:cc0506dc3565 389 }
WiredHome 5:cc0506dc3565 390
WiredHome 5:cc0506dc3565 391
WiredHome 5:cc0506dc3565 392 void Wifly::flush()
WiredHome 5:cc0506dc3565 393 {
WiredHome 5:cc0506dc3565 394 buf_wifly.flush();
WiredHome 5:cc0506dc3565 395 }
WiredHome 5:cc0506dc3565 396
WiredHome 8:79415e982c32 397 bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int resSize, int timeout)
WiredHome 5:cc0506dc3565 398 {
WiredHome 5:cc0506dc3565 399 if (!state.cmd_mode) {
WiredHome 5:cc0506dc3565 400 cmdMode();
WiredHome 5:cc0506dc3565 401 }
WiredHome 8:79415e982c32 402 if (send(cmd, strlen(cmd), ack, res, resSize, timeout) == -1) {
WiredHome 5:cc0506dc3565 403 ERR("sendCommand: cannot %s\r\n", cmd);
WiredHome 5:cc0506dc3565 404 exit();
WiredHome 5:cc0506dc3565 405 return false;
WiredHome 5:cc0506dc3565 406 }
WiredHome 5:cc0506dc3565 407 return true;
WiredHome 5:cc0506dc3565 408 }
WiredHome 5:cc0506dc3565 409
WiredHome 5:cc0506dc3565 410 bool Wifly::cmdMode()
WiredHome 5:cc0506dc3565 411 {
WiredHome 5:cc0506dc3565 412 // if already in cmd mode, return
WiredHome 5:cc0506dc3565 413 if (state.cmd_mode)
WiredHome 5:cc0506dc3565 414 return true;
WiredHome 5:cc0506dc3565 415
WiredHome 5:cc0506dc3565 416 wait_ms(250); // manual 1.2.1 (250 msec before and after)
WiredHome 5:cc0506dc3565 417 if (send("$$$", 3, "CMD") == -1) {
WiredHome 5:cc0506dc3565 418 ERR("cannot enter in cmd mode\r\n");
WiredHome 5:cc0506dc3565 419 exit();
WiredHome 5:cc0506dc3565 420 return false;
WiredHome 5:cc0506dc3565 421 }
WiredHome 5:cc0506dc3565 422 state.cmd_mode = true;
WiredHome 5:cc0506dc3565 423 return true;
WiredHome 5:cc0506dc3565 424 }
WiredHome 5:cc0506dc3565 425
WiredHome 5:cc0506dc3565 426 bool Wifly::disconnect()
WiredHome 5:cc0506dc3565 427 {
WiredHome 5:cc0506dc3565 428 // if already disconnected, return
WiredHome 5:cc0506dc3565 429 if (!state.associated)
WiredHome 5:cc0506dc3565 430 return true;
WiredHome 5:cc0506dc3565 431
WiredHome 5:cc0506dc3565 432 if (!sendCommand("leave\r", "DeAuth"))
WiredHome 5:cc0506dc3565 433 return false;
WiredHome 5:cc0506dc3565 434 exit();
WiredHome 5:cc0506dc3565 435
WiredHome 5:cc0506dc3565 436 state.associated = false;
WiredHome 5:cc0506dc3565 437 return true;
WiredHome 5:cc0506dc3565 438
WiredHome 5:cc0506dc3565 439 }
WiredHome 5:cc0506dc3565 440
WiredHome 5:cc0506dc3565 441 bool Wifly::is_connected()
WiredHome 5:cc0506dc3565 442 {
WiredHome 5:cc0506dc3565 443 return (tcp_status.read() == 1) ? true : false;
WiredHome 5:cc0506dc3565 444 }
WiredHome 5:cc0506dc3565 445
WiredHome 5:cc0506dc3565 446
WiredHome 5:cc0506dc3565 447 void Wifly::reset()
WiredHome 5:cc0506dc3565 448 {
WiredHome 5:cc0506dc3565 449 reset_pin = 0;
WiredHome 5:cc0506dc3565 450 wait_ms(200);
WiredHome 5:cc0506dc3565 451 reset_pin = 1;
WiredHome 5:cc0506dc3565 452 wait_ms(200);
WiredHome 5:cc0506dc3565 453 flushIn(); // clear the reset text
WiredHome 5:cc0506dc3565 454 }
WiredHome 5:cc0506dc3565 455
WiredHome 5:cc0506dc3565 456 bool Wifly::reboot()
WiredHome 5:cc0506dc3565 457 {
WiredHome 5:cc0506dc3565 458 // if already in cmd mode, return
WiredHome 5:cc0506dc3565 459 if (!sendCommand("reboot\r"))
WiredHome 5:cc0506dc3565 460 return false;
WiredHome 5:cc0506dc3565 461
WiredHome 5:cc0506dc3565 462 wait_ms(300);
WiredHome 5:cc0506dc3565 463 wifi.baud(9600); // After a reboot, it is back at 9600 baud because we don't store
WiredHome 5:cc0506dc3565 464 baud(baudrate); // shift it up to where you want it
WiredHome 5:cc0506dc3565 465 exit(); // exit command mode
WiredHome 5:cc0506dc3565 466 return true;
WiredHome 5:cc0506dc3565 467 }
WiredHome 5:cc0506dc3565 468
WiredHome 5:cc0506dc3565 469 bool Wifly::close()
WiredHome 5:cc0506dc3565 470 {
WiredHome 5:cc0506dc3565 471 if (!state.tcp)
WiredHome 5:cc0506dc3565 472 return true;
WiredHome 5:cc0506dc3565 473
WiredHome 5:cc0506dc3565 474 if (!sendCommand("close\r", "CLOS"))
WiredHome 5:cc0506dc3565 475 return false;
WiredHome 5:cc0506dc3565 476 exit();
WiredHome 5:cc0506dc3565 477
WiredHome 5:cc0506dc3565 478 state.tcp = false;
WiredHome 5:cc0506dc3565 479 return true;
WiredHome 5:cc0506dc3565 480 }
WiredHome 5:cc0506dc3565 481
WiredHome 5:cc0506dc3565 482
WiredHome 5:cc0506dc3565 483 int Wifly::putc(char c)
WiredHome 5:cc0506dc3565 484 {
WiredHome 5:cc0506dc3565 485 while (!wifi.writeable())
WiredHome 5:cc0506dc3565 486 ;
WiredHome 5:cc0506dc3565 487 return wifi.putc(c);
WiredHome 5:cc0506dc3565 488 }
WiredHome 5:cc0506dc3565 489
WiredHome 5:cc0506dc3565 490
WiredHome 5:cc0506dc3565 491 bool Wifly::exit()
WiredHome 5:cc0506dc3565 492 {
WiredHome 5:cc0506dc3565 493 flush();
WiredHome 5:cc0506dc3565 494 if (!state.cmd_mode)
WiredHome 5:cc0506dc3565 495 return true;
WiredHome 5:cc0506dc3565 496 if (!sendCommand("exit\r", "EXIT"))
WiredHome 5:cc0506dc3565 497 return false;
WiredHome 5:cc0506dc3565 498 state.cmd_mode = false;
WiredHome 5:cc0506dc3565 499 flush();
WiredHome 5:cc0506dc3565 500 return true;
WiredHome 5:cc0506dc3565 501 }
WiredHome 5:cc0506dc3565 502
WiredHome 5:cc0506dc3565 503
WiredHome 5:cc0506dc3565 504 int Wifly::readable()
WiredHome 5:cc0506dc3565 505 {
WiredHome 5:cc0506dc3565 506 return buf_wifly.available();
WiredHome 5:cc0506dc3565 507 }
WiredHome 5:cc0506dc3565 508
WiredHome 5:cc0506dc3565 509 int Wifly::writeable()
WiredHome 5:cc0506dc3565 510 {
WiredHome 5:cc0506dc3565 511 return wifi.writeable();
WiredHome 5:cc0506dc3565 512 }
WiredHome 5:cc0506dc3565 513
WiredHome 5:cc0506dc3565 514 char Wifly::getc()
WiredHome 5:cc0506dc3565 515 {
WiredHome 5:cc0506dc3565 516 char c;
WiredHome 5:cc0506dc3565 517 while (!buf_wifly.available())
WiredHome 5:cc0506dc3565 518 ;
WiredHome 5:cc0506dc3565 519 buf_wifly.dequeue(&c);
WiredHome 5:cc0506dc3565 520 return c;
WiredHome 5:cc0506dc3565 521 }
WiredHome 5:cc0506dc3565 522
WiredHome 5:cc0506dc3565 523 void Wifly::handler_rx(void)
WiredHome 5:cc0506dc3565 524 {
WiredHome 5:cc0506dc3565 525 //read characters
WiredHome 5:cc0506dc3565 526 while (wifi.readable())
WiredHome 5:cc0506dc3565 527 buf_wifly.queue(wifi.getc());
WiredHome 5:cc0506dc3565 528 }
WiredHome 5:cc0506dc3565 529
WiredHome 5:cc0506dc3565 530 void Wifly::attach_rx(bool callback)
WiredHome 5:cc0506dc3565 531 {
WiredHome 5:cc0506dc3565 532 if (!callback)
WiredHome 5:cc0506dc3565 533 wifi.attach(NULL);
WiredHome 5:cc0506dc3565 534 else
WiredHome 5:cc0506dc3565 535 wifi.attach(this, &Wifly::handler_rx);
WiredHome 5:cc0506dc3565 536 }
WiredHome 5:cc0506dc3565 537
WiredHome 5:cc0506dc3565 538
WiredHome 8:79415e982c32 539 int Wifly::send(const char * str, int len, const char * ACK, char * res, int resSize, int timeout)
WiredHome 5:cc0506dc3565 540 {
WiredHome 5:cc0506dc3565 541 char read;
WiredHome 5:cc0506dc3565 542 size_t found = string::npos;
WiredHome 5:cc0506dc3565 543 string checking;
WiredHome 5:cc0506dc3565 544 Timer tmr;
WiredHome 5:cc0506dc3565 545 int result = 0;
WiredHome 5:cc0506dc3565 546
WiredHome 5:cc0506dc3565 547 attach_rx(false);
WiredHome 5:cc0506dc3565 548
WiredHome 5:cc0506dc3565 549 //We flush the buffer
WiredHome 5:cc0506dc3565 550 flushIn();
WiredHome 5:cc0506dc3565 551
WiredHome 5:cc0506dc3565 552 #ifdef DEBUG
WiredHome 5:cc0506dc3565 553 char dbuf[100];
WiredHome 5:cc0506dc3565 554 strcpy(dbuf, str);
WiredHome 5:cc0506dc3565 555 char * p = dbuf;
WiredHome 5:cc0506dc3565 556 while (*p && *p >= ' ')
WiredHome 5:cc0506dc3565 557 *p++;
WiredHome 5:cc0506dc3565 558 *p = '\0';
WiredHome 5:cc0506dc3565 559 DBG("send(%s,%d,%s,...,%d)",dbuf,len,ACK,timeout);
WiredHome 5:cc0506dc3565 560 #endif
WiredHome 5:cc0506dc3565 561
WiredHome 5:cc0506dc3565 562 if (!ACK || !strcmp(ACK, "NO")) {
WiredHome 5:cc0506dc3565 563 for (int i = 0; i < len; i++)
WiredHome 5:cc0506dc3565 564 result = (putc(str[i]) == str[i]) ? result + 1 : result;
WiredHome 5:cc0506dc3565 565 } else {
WiredHome 5:cc0506dc3565 566 tmr.start();
WiredHome 5:cc0506dc3565 567 for (int i = 0; i < len; i++)
WiredHome 5:cc0506dc3565 568 result = (putc(str[i]) == str[i]) ? result + 1 : result;
WiredHome 5:cc0506dc3565 569 while (1) {
WiredHome 5:cc0506dc3565 570 if (tmr.read_ms() > timeout) {
WiredHome 5:cc0506dc3565 571 DBG(" timeout");
WiredHome 5:cc0506dc3565 572 flushIn();
WiredHome 5:cc0506dc3565 573
WiredHome 5:cc0506dc3565 574 //DBG("check: %s", checking.c_str());
WiredHome 5:cc0506dc3565 575
WiredHome 5:cc0506dc3565 576 result = -1;
WiredHome 5:cc0506dc3565 577 break;
WiredHome 5:cc0506dc3565 578 } else if (wifi.readable()) {
WiredHome 5:cc0506dc3565 579 read = wifi.getc();
WiredHome 5:cc0506dc3565 580 if ( read != '\r' && read != '\n') {
WiredHome 5:cc0506dc3565 581 checking += read;
WiredHome 5:cc0506dc3565 582 found = checking.find(ACK);
WiredHome 5:cc0506dc3565 583 if (found != string::npos) {
WiredHome 5:cc0506dc3565 584 wait_ms(10);
WiredHome 5:cc0506dc3565 585 flushIn();
WiredHome 5:cc0506dc3565 586 break;
WiredHome 5:cc0506dc3565 587 }
WiredHome 5:cc0506dc3565 588 // We can "early out" if we got an error response
WiredHome 5:cc0506dc3565 589 found = checking.find("ERR: ");
WiredHome 5:cc0506dc3565 590 if (found != string::npos) {
WiredHome 5:cc0506dc3565 591 wait_ms(10);
WiredHome 5:cc0506dc3565 592 ERR(" response: %s", checking.c_str());
WiredHome 5:cc0506dc3565 593 flushIn();
WiredHome 5:cc0506dc3565 594 result = -1;
WiredHome 5:cc0506dc3565 595 break;
WiredHome 5:cc0506dc3565 596 }
WiredHome 5:cc0506dc3565 597 }
WiredHome 5:cc0506dc3565 598 }
WiredHome 5:cc0506dc3565 599 }
WiredHome 5:cc0506dc3565 600 attach_rx(true);
WiredHome 5:cc0506dc3565 601 return result;
WiredHome 5:cc0506dc3565 602 }
WiredHome 5:cc0506dc3565 603
WiredHome 8:79415e982c32 604 //the user wants the result from the command (ACK == NULL, res != NULL, resSize > 0)
WiredHome 8:79415e982c32 605 if ( res != NULL && resSize > 0) {
WiredHome 5:cc0506dc3565 606 int i = 0;
WiredHome 5:cc0506dc3565 607 Timer timeout;
WiredHome 5:cc0506dc3565 608 timeout.start();
WiredHome 5:cc0506dc3565 609 tmr.reset();
WiredHome 8:79415e982c32 610 while (i < resSize) {
WiredHome 5:cc0506dc3565 611 if (timeout.read() > 2) {
WiredHome 5:cc0506dc3565 612 if (i == 0) {
WiredHome 5:cc0506dc3565 613 res = NULL;
WiredHome 5:cc0506dc3565 614 break;
WiredHome 5:cc0506dc3565 615 }
WiredHome 5:cc0506dc3565 616 res[i] = '\0';
WiredHome 5:cc0506dc3565 617 DBG("user str 1: %s", res);
WiredHome 5:cc0506dc3565 618 break;
WiredHome 5:cc0506dc3565 619 } else {
WiredHome 5:cc0506dc3565 620 if (tmr.read_ms() > 300) {
WiredHome 5:cc0506dc3565 621 res[i] = '\0';
WiredHome 5:cc0506dc3565 622 DBG("user str: %s", res);
WiredHome 5:cc0506dc3565 623 break;
WiredHome 5:cc0506dc3565 624 }
WiredHome 5:cc0506dc3565 625 if (wifi.readable()) {
WiredHome 5:cc0506dc3565 626 tmr.start();
WiredHome 5:cc0506dc3565 627 read = wifi.getc();
WiredHome 5:cc0506dc3565 628
WiredHome 5:cc0506dc3565 629 // we drop \r and \n
WiredHome 5:cc0506dc3565 630 if ( read != '\r' && read != '\n') {
WiredHome 5:cc0506dc3565 631 res[i++] = read;
WiredHome 8:79415e982c32 632 res[i] = '\0';
WiredHome 5:cc0506dc3565 633 }
WiredHome 5:cc0506dc3565 634 }
WiredHome 5:cc0506dc3565 635 }
WiredHome 5:cc0506dc3565 636 }
WiredHome 5:cc0506dc3565 637 DBG("user str: %s", res);
WiredHome 5:cc0506dc3565 638 }
WiredHome 5:cc0506dc3565 639
WiredHome 5:cc0506dc3565 640 //We flush the buffer
WiredHome 5:cc0506dc3565 641 flushIn();
WiredHome 5:cc0506dc3565 642
WiredHome 5:cc0506dc3565 643 attach_rx(true);
WiredHome 5:cc0506dc3565 644 return result;
WiredHome 5:cc0506dc3565 645 }
WiredHome 8:79415e982c32 646