Control a robot over the internet using UDP and a Wifly module (WiFi).

Dependencies:   Motor TextLCD WiflyInterface mbed-rtos mbed

Committer:
apatel336
Date:
Thu Oct 17 13:27:56 2013 +0000
Revision:
0:c0dc3a76f3d4
Initial Release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
apatel336 0:c0dc3a76f3d4 1 /* Copyright (C) 2012 mbed.org, MIT License
apatel336 0:c0dc3a76f3d4 2 *
apatel336 0:c0dc3a76f3d4 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
apatel336 0:c0dc3a76f3d4 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
apatel336 0:c0dc3a76f3d4 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
apatel336 0:c0dc3a76f3d4 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
apatel336 0:c0dc3a76f3d4 7 * furnished to do so, subject to the following conditions:
apatel336 0:c0dc3a76f3d4 8 *
apatel336 0:c0dc3a76f3d4 9 * The above copyright notice and this permission notice shall be included in all copies or
apatel336 0:c0dc3a76f3d4 10 * substantial portions of the Software.
apatel336 0:c0dc3a76f3d4 11 *
apatel336 0:c0dc3a76f3d4 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
apatel336 0:c0dc3a76f3d4 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
apatel336 0:c0dc3a76f3d4 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
apatel336 0:c0dc3a76f3d4 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
apatel336 0:c0dc3a76f3d4 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
apatel336 0:c0dc3a76f3d4 17 */
apatel336 0:c0dc3a76f3d4 18
apatel336 0:c0dc3a76f3d4 19 #include "mbed.h"
apatel336 0:c0dc3a76f3d4 20 #include "Wifly.h"
apatel336 0:c0dc3a76f3d4 21 #include <string>
apatel336 0:c0dc3a76f3d4 22 #include <algorithm>
apatel336 0:c0dc3a76f3d4 23
apatel336 0:c0dc3a76f3d4 24 //Debug is disabled by default
apatel336 0:c0dc3a76f3d4 25 #if (0 && !defined(TARGET_LPC11U24))
apatel336 0:c0dc3a76f3d4 26 #define DBG(x, ...) std::printf("[Wifly : DBG]"x"\r\n", ##__VA_ARGS__);
apatel336 0:c0dc3a76f3d4 27 #define WARN(x, ...) std::printf("[Wifly : WARN]"x"\r\n", ##__VA_ARGS__);
apatel336 0:c0dc3a76f3d4 28 #define ERR(x, ...) std::printf("[Wifly : ERR]"x"\r\n", ##__VA_ARGS__);
apatel336 0:c0dc3a76f3d4 29 #else
apatel336 0:c0dc3a76f3d4 30 #define DBG(x, ...)
apatel336 0:c0dc3a76f3d4 31 #define WARN(x, ...)
apatel336 0:c0dc3a76f3d4 32 #define ERR(x, ...)
apatel336 0:c0dc3a76f3d4 33 #endif
apatel336 0:c0dc3a76f3d4 34
apatel336 0:c0dc3a76f3d4 35 #if !defined(TARGET_LPC11U24)
apatel336 0:c0dc3a76f3d4 36 #define INFO(x, ...) printf("[Wifly : INFO]"x"\r\n", ##__VA_ARGS__);
apatel336 0:c0dc3a76f3d4 37 #else
apatel336 0:c0dc3a76f3d4 38 #define INFO(x, ...)
apatel336 0:c0dc3a76f3d4 39 #endif
apatel336 0:c0dc3a76f3d4 40
apatel336 0:c0dc3a76f3d4 41 #define MAX_TRY_JOIN 3
apatel336 0:c0dc3a76f3d4 42
apatel336 0:c0dc3a76f3d4 43 Wifly * Wifly::inst;
apatel336 0:c0dc3a76f3d4 44
apatel336 0:c0dc3a76f3d4 45 Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec):
apatel336 0:c0dc3a76f3d4 46 wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), buf_wifly(256)
apatel336 0:c0dc3a76f3d4 47 {
apatel336 0:c0dc3a76f3d4 48 memset(&state, 0, sizeof(state));
apatel336 0:c0dc3a76f3d4 49 state.sec = sec;
apatel336 0:c0dc3a76f3d4 50
apatel336 0:c0dc3a76f3d4 51 // change all ' ' in '$' in the ssid and the passphrase
apatel336 0:c0dc3a76f3d4 52 strcpy(this->ssid, ssid);
apatel336 0:c0dc3a76f3d4 53 for (int i = 0; i < strlen(ssid); i++) {
apatel336 0:c0dc3a76f3d4 54 if (this->ssid[i] == ' ')
apatel336 0:c0dc3a76f3d4 55 this->ssid[i] = '$';
apatel336 0:c0dc3a76f3d4 56 }
apatel336 0:c0dc3a76f3d4 57 strcpy(this->phrase, phrase);
apatel336 0:c0dc3a76f3d4 58 for (int i = 0; i < strlen(phrase); i++) {
apatel336 0:c0dc3a76f3d4 59 if (this->phrase[i] == ' ')
apatel336 0:c0dc3a76f3d4 60 this->phrase[i] = '$';
apatel336 0:c0dc3a76f3d4 61 }
apatel336 0:c0dc3a76f3d4 62
apatel336 0:c0dc3a76f3d4 63 inst = this;
apatel336 0:c0dc3a76f3d4 64 attach_rx(false);
apatel336 0:c0dc3a76f3d4 65 state.cmd_mode = false;
apatel336 0:c0dc3a76f3d4 66 }
apatel336 0:c0dc3a76f3d4 67
apatel336 0:c0dc3a76f3d4 68 bool Wifly::join()
apatel336 0:c0dc3a76f3d4 69 {
apatel336 0:c0dc3a76f3d4 70 char cmd[20];
apatel336 0:c0dc3a76f3d4 71
apatel336 0:c0dc3a76f3d4 72 for (int i= 0; i < MAX_TRY_JOIN; i++) {
apatel336 0:c0dc3a76f3d4 73
apatel336 0:c0dc3a76f3d4 74 // no auto join
apatel336 0:c0dc3a76f3d4 75 if (!sendCommand("set w j 0\r", "AOK"))
apatel336 0:c0dc3a76f3d4 76 continue;
apatel336 0:c0dc3a76f3d4 77
apatel336 0:c0dc3a76f3d4 78 //no echo
apatel336 0:c0dc3a76f3d4 79 if (!sendCommand("set u m 1\r", "AOK"))
apatel336 0:c0dc3a76f3d4 80 continue;
apatel336 0:c0dc3a76f3d4 81
apatel336 0:c0dc3a76f3d4 82 // set time
apatel336 0:c0dc3a76f3d4 83 if (!sendCommand("set c t 30\r", "AOK"))
apatel336 0:c0dc3a76f3d4 84 continue;
apatel336 0:c0dc3a76f3d4 85
apatel336 0:c0dc3a76f3d4 86 // set size
apatel336 0:c0dc3a76f3d4 87 if (!sendCommand("set c s 1024\r", "AOK"))
apatel336 0:c0dc3a76f3d4 88 continue;
apatel336 0:c0dc3a76f3d4 89
apatel336 0:c0dc3a76f3d4 90 // red led on when tcp connection active
apatel336 0:c0dc3a76f3d4 91 if (!sendCommand("set s i 0x40\r", "AOK"))
apatel336 0:c0dc3a76f3d4 92 continue;
apatel336 0:c0dc3a76f3d4 93
apatel336 0:c0dc3a76f3d4 94 // no string sent to the tcp client
apatel336 0:c0dc3a76f3d4 95 if (!sendCommand("set c r 0\r", "AOK"))
apatel336 0:c0dc3a76f3d4 96 continue;
apatel336 0:c0dc3a76f3d4 97
apatel336 0:c0dc3a76f3d4 98 // tcp protocol
apatel336 0:c0dc3a76f3d4 99 if (!sendCommand("set i p 2\r", "AOK"))
apatel336 0:c0dc3a76f3d4 100 continue;
apatel336 0:c0dc3a76f3d4 101
apatel336 0:c0dc3a76f3d4 102 // tcp retry
apatel336 0:c0dc3a76f3d4 103 if (!sendCommand("set i f 0x7\r", "AOK"))
apatel336 0:c0dc3a76f3d4 104 continue;
apatel336 0:c0dc3a76f3d4 105
apatel336 0:c0dc3a76f3d4 106 // set dns server
apatel336 0:c0dc3a76f3d4 107 if (!sendCommand("set d n rn.microchip.com\r", "AOK"))
apatel336 0:c0dc3a76f3d4 108 continue;
apatel336 0:c0dc3a76f3d4 109
apatel336 0:c0dc3a76f3d4 110 //dhcp
apatel336 0:c0dc3a76f3d4 111 sprintf(cmd, "set i d %d\r", (state.dhcp) ? 1 : 0);
apatel336 0:c0dc3a76f3d4 112 if (!sendCommand(cmd, "AOK"))
apatel336 0:c0dc3a76f3d4 113 continue;
apatel336 0:c0dc3a76f3d4 114
apatel336 0:c0dc3a76f3d4 115 // ssid
apatel336 0:c0dc3a76f3d4 116 sprintf(cmd, "set w s %s\r", ssid);
apatel336 0:c0dc3a76f3d4 117 if (!sendCommand(cmd, "AOK"))
apatel336 0:c0dc3a76f3d4 118 continue;
apatel336 0:c0dc3a76f3d4 119
apatel336 0:c0dc3a76f3d4 120 //auth
apatel336 0:c0dc3a76f3d4 121 sprintf(cmd, "set w a %d\r", state.sec);
apatel336 0:c0dc3a76f3d4 122 if (!sendCommand(cmd, "AOK"))
apatel336 0:c0dc3a76f3d4 123 continue;
apatel336 0:c0dc3a76f3d4 124
apatel336 0:c0dc3a76f3d4 125 // if no dhcp, set ip, netmask and gateway
apatel336 0:c0dc3a76f3d4 126 if (!state.dhcp) {
apatel336 0:c0dc3a76f3d4 127 DBG("not dhcp\r");
apatel336 0:c0dc3a76f3d4 128
apatel336 0:c0dc3a76f3d4 129 sprintf(cmd, "set i a %s\r\n", ip);
apatel336 0:c0dc3a76f3d4 130 if (!sendCommand(cmd, "AOK"))
apatel336 0:c0dc3a76f3d4 131 continue;
apatel336 0:c0dc3a76f3d4 132
apatel336 0:c0dc3a76f3d4 133 sprintf(cmd, "set i n %s\r", netmask);
apatel336 0:c0dc3a76f3d4 134 if (!sendCommand(cmd, "AOK"))
apatel336 0:c0dc3a76f3d4 135 continue;
apatel336 0:c0dc3a76f3d4 136
apatel336 0:c0dc3a76f3d4 137 sprintf(cmd, "set i g %s\r", gateway);
apatel336 0:c0dc3a76f3d4 138 if (!sendCommand(cmd, "AOK"))
apatel336 0:c0dc3a76f3d4 139 continue;
apatel336 0:c0dc3a76f3d4 140 }
apatel336 0:c0dc3a76f3d4 141
apatel336 0:c0dc3a76f3d4 142 //key step
apatel336 0:c0dc3a76f3d4 143 if (state.sec != NONE) {
apatel336 0:c0dc3a76f3d4 144 if (state.sec == WPA)
apatel336 0:c0dc3a76f3d4 145 sprintf(cmd, "set w p %s\r", phrase);
apatel336 0:c0dc3a76f3d4 146 else if (state.sec == WEP_128)
apatel336 0:c0dc3a76f3d4 147 sprintf(cmd, "set w k %s\r", phrase);
apatel336 0:c0dc3a76f3d4 148
apatel336 0:c0dc3a76f3d4 149 if (!sendCommand(cmd, "AOK"))
apatel336 0:c0dc3a76f3d4 150 continue;
apatel336 0:c0dc3a76f3d4 151 }
apatel336 0:c0dc3a76f3d4 152
apatel336 0:c0dc3a76f3d4 153 //join the network (10s timeout)
apatel336 0:c0dc3a76f3d4 154 if (state.dhcp) {
apatel336 0:c0dc3a76f3d4 155 if (!sendCommand("join\r", "DHCP=ON", NULL, 10000))
apatel336 0:c0dc3a76f3d4 156 continue;
apatel336 0:c0dc3a76f3d4 157 } else {
apatel336 0:c0dc3a76f3d4 158 if (!sendCommand("join\r", "Associated", NULL, 10000))
apatel336 0:c0dc3a76f3d4 159 continue;
apatel336 0:c0dc3a76f3d4 160 }
apatel336 0:c0dc3a76f3d4 161
apatel336 0:c0dc3a76f3d4 162 if (!sendCommand("save\r", "Stor"))
apatel336 0:c0dc3a76f3d4 163 continue;
apatel336 0:c0dc3a76f3d4 164
apatel336 0:c0dc3a76f3d4 165 exit();
apatel336 0:c0dc3a76f3d4 166
apatel336 0:c0dc3a76f3d4 167 state.associated = true;
apatel336 0:c0dc3a76f3d4 168 INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, getStringSecurity());
apatel336 0:c0dc3a76f3d4 169 return true;
apatel336 0:c0dc3a76f3d4 170 }
apatel336 0:c0dc3a76f3d4 171 return false;
apatel336 0:c0dc3a76f3d4 172 }
apatel336 0:c0dc3a76f3d4 173
apatel336 0:c0dc3a76f3d4 174
apatel336 0:c0dc3a76f3d4 175 bool Wifly::setProtocol(Protocol p)
apatel336 0:c0dc3a76f3d4 176 {
apatel336 0:c0dc3a76f3d4 177 // use udp auto pairing
apatel336 0:c0dc3a76f3d4 178 char cmd[20];
apatel336 0:c0dc3a76f3d4 179 sprintf(cmd, "set i p %d\r", p);
apatel336 0:c0dc3a76f3d4 180 if (!sendCommand(cmd, "AOK"))
apatel336 0:c0dc3a76f3d4 181 return false;
apatel336 0:c0dc3a76f3d4 182
apatel336 0:c0dc3a76f3d4 183 switch(p) {
apatel336 0:c0dc3a76f3d4 184 case TCP:
apatel336 0:c0dc3a76f3d4 185 // set ip flags: tcp retry enabled
apatel336 0:c0dc3a76f3d4 186 if (!sendCommand("set i f 0x07\r", "AOK"))
apatel336 0:c0dc3a76f3d4 187 return false;
apatel336 0:c0dc3a76f3d4 188 break;
apatel336 0:c0dc3a76f3d4 189 case UDP:
apatel336 0:c0dc3a76f3d4 190 // set ip flags: udp auto pairing enabled
apatel336 0:c0dc3a76f3d4 191 if (!sendCommand("set i h 0.0.0.0\r", "AOK"))
apatel336 0:c0dc3a76f3d4 192 return false;
apatel336 0:c0dc3a76f3d4 193 if (!sendCommand("set i f 0x40\r", "AOK"))
apatel336 0:c0dc3a76f3d4 194 return false;
apatel336 0:c0dc3a76f3d4 195 break;
apatel336 0:c0dc3a76f3d4 196 }
apatel336 0:c0dc3a76f3d4 197 state.proto = p;
apatel336 0:c0dc3a76f3d4 198 return true;
apatel336 0:c0dc3a76f3d4 199 }
apatel336 0:c0dc3a76f3d4 200
apatel336 0:c0dc3a76f3d4 201 char * Wifly::getStringSecurity()
apatel336 0:c0dc3a76f3d4 202 {
apatel336 0:c0dc3a76f3d4 203 switch(state.sec) {
apatel336 0:c0dc3a76f3d4 204 case NONE:
apatel336 0:c0dc3a76f3d4 205 return "NONE";
apatel336 0:c0dc3a76f3d4 206 case WEP_128:
apatel336 0:c0dc3a76f3d4 207 return "WEP_128";
apatel336 0:c0dc3a76f3d4 208 case WPA:
apatel336 0:c0dc3a76f3d4 209 return "WPA";
apatel336 0:c0dc3a76f3d4 210 }
apatel336 0:c0dc3a76f3d4 211 return "UNKNOWN";
apatel336 0:c0dc3a76f3d4 212 }
apatel336 0:c0dc3a76f3d4 213
apatel336 0:c0dc3a76f3d4 214 bool Wifly::connect(const char * host, int port)
apatel336 0:c0dc3a76f3d4 215 {
apatel336 0:c0dc3a76f3d4 216 char rcv[20];
apatel336 0:c0dc3a76f3d4 217 char cmd[20];
apatel336 0:c0dc3a76f3d4 218
apatel336 0:c0dc3a76f3d4 219 // try to open
apatel336 0:c0dc3a76f3d4 220 sprintf(cmd, "open %s %d\r", host, port);
apatel336 0:c0dc3a76f3d4 221 if (sendCommand(cmd, "OPEN", NULL, 10000)) {
apatel336 0:c0dc3a76f3d4 222 state.tcp = true;
apatel336 0:c0dc3a76f3d4 223 state.cmd_mode = false;
apatel336 0:c0dc3a76f3d4 224 return true;
apatel336 0:c0dc3a76f3d4 225 }
apatel336 0:c0dc3a76f3d4 226
apatel336 0:c0dc3a76f3d4 227 // if failed, retry and parse the response
apatel336 0:c0dc3a76f3d4 228 if (sendCommand(cmd, NULL, rcv, 5000)) {
apatel336 0:c0dc3a76f3d4 229 if (strstr(rcv, "OPEN") == NULL) {
apatel336 0:c0dc3a76f3d4 230 if (strstr(rcv, "Connected") != NULL) {
apatel336 0:c0dc3a76f3d4 231 wait(0.25);
apatel336 0:c0dc3a76f3d4 232 if (!sendCommand("close\r", "CLOS"))
apatel336 0:c0dc3a76f3d4 233 return false;
apatel336 0:c0dc3a76f3d4 234 wait(0.25);
apatel336 0:c0dc3a76f3d4 235 if (!sendCommand(cmd, "OPEN", NULL, 10000))
apatel336 0:c0dc3a76f3d4 236 return false;
apatel336 0:c0dc3a76f3d4 237 } else {
apatel336 0:c0dc3a76f3d4 238 return false;
apatel336 0:c0dc3a76f3d4 239 }
apatel336 0:c0dc3a76f3d4 240 }
apatel336 0:c0dc3a76f3d4 241 } else {
apatel336 0:c0dc3a76f3d4 242 return false;
apatel336 0:c0dc3a76f3d4 243 }
apatel336 0:c0dc3a76f3d4 244
apatel336 0:c0dc3a76f3d4 245 state.tcp = true;
apatel336 0:c0dc3a76f3d4 246 state.cmd_mode = false;
apatel336 0:c0dc3a76f3d4 247
apatel336 0:c0dc3a76f3d4 248 return true;
apatel336 0:c0dc3a76f3d4 249 }
apatel336 0:c0dc3a76f3d4 250
apatel336 0:c0dc3a76f3d4 251
apatel336 0:c0dc3a76f3d4 252 bool Wifly::gethostbyname(const char * host, char * ip)
apatel336 0:c0dc3a76f3d4 253 {
apatel336 0:c0dc3a76f3d4 254 string h = host;
apatel336 0:c0dc3a76f3d4 255 char cmd[30], rcv[100];
apatel336 0:c0dc3a76f3d4 256 int l = 0;
apatel336 0:c0dc3a76f3d4 257 char * point;
apatel336 0:c0dc3a76f3d4 258 int nb_digits = 0;
apatel336 0:c0dc3a76f3d4 259
apatel336 0:c0dc3a76f3d4 260 // no dns needed
apatel336 0:c0dc3a76f3d4 261 int pos = h.find(".");
apatel336 0:c0dc3a76f3d4 262 if (pos != string::npos) {
apatel336 0:c0dc3a76f3d4 263 string sub = h.substr(0, h.find("."));
apatel336 0:c0dc3a76f3d4 264 nb_digits = atoi(sub.c_str());
apatel336 0:c0dc3a76f3d4 265 }
apatel336 0:c0dc3a76f3d4 266 //printf("substrL %s\r\n", sub.c_str());
apatel336 0:c0dc3a76f3d4 267 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) {
apatel336 0:c0dc3a76f3d4 268 strcpy(ip, host);
apatel336 0:c0dc3a76f3d4 269 }
apatel336 0:c0dc3a76f3d4 270 // dns needed
apatel336 0:c0dc3a76f3d4 271 else {
apatel336 0:c0dc3a76f3d4 272 nb_digits = 0;
apatel336 0:c0dc3a76f3d4 273 sprintf(cmd, "lookup %s\r", host);
apatel336 0:c0dc3a76f3d4 274 if (!sendCommand(cmd, NULL, rcv))
apatel336 0:c0dc3a76f3d4 275 return false;
apatel336 0:c0dc3a76f3d4 276
apatel336 0:c0dc3a76f3d4 277 // look for the ip address
apatel336 0:c0dc3a76f3d4 278 char * begin = strstr(rcv, "=") + 1;
apatel336 0:c0dc3a76f3d4 279 for (int i = 0; i < 3; i++) {
apatel336 0:c0dc3a76f3d4 280 point = strstr(begin + l, ".");
apatel336 0:c0dc3a76f3d4 281 DBG("str: %s", begin + l);
apatel336 0:c0dc3a76f3d4 282 l += point - (begin + l) + 1;
apatel336 0:c0dc3a76f3d4 283 }
apatel336 0:c0dc3a76f3d4 284 DBG("str: %s", begin + l);
apatel336 0:c0dc3a76f3d4 285 while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') {
apatel336 0:c0dc3a76f3d4 286 DBG("digit: %c", *(begin + l + nb_digits));
apatel336 0:c0dc3a76f3d4 287 nb_digits++;
apatel336 0:c0dc3a76f3d4 288 }
apatel336 0:c0dc3a76f3d4 289 memcpy(ip, begin, l + nb_digits);
apatel336 0:c0dc3a76f3d4 290 ip[l+nb_digits] = 0;
apatel336 0:c0dc3a76f3d4 291 DBG("ip from dns: %s", ip);
apatel336 0:c0dc3a76f3d4 292 }
apatel336 0:c0dc3a76f3d4 293 return true;
apatel336 0:c0dc3a76f3d4 294 }
apatel336 0:c0dc3a76f3d4 295
apatel336 0:c0dc3a76f3d4 296
apatel336 0:c0dc3a76f3d4 297 void Wifly::flush()
apatel336 0:c0dc3a76f3d4 298 {
apatel336 0:c0dc3a76f3d4 299 buf_wifly.flush();
apatel336 0:c0dc3a76f3d4 300 }
apatel336 0:c0dc3a76f3d4 301
apatel336 0:c0dc3a76f3d4 302 bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout)
apatel336 0:c0dc3a76f3d4 303 {
apatel336 0:c0dc3a76f3d4 304 if (!state.cmd_mode) {
apatel336 0:c0dc3a76f3d4 305 cmdMode();
apatel336 0:c0dc3a76f3d4 306 }
apatel336 0:c0dc3a76f3d4 307 if (send(cmd, strlen(cmd), ack, res, timeout) == -1) {
apatel336 0:c0dc3a76f3d4 308 ERR("sendCommand: cannot %s\r\n", cmd);
apatel336 0:c0dc3a76f3d4 309 exit();
apatel336 0:c0dc3a76f3d4 310 return false;
apatel336 0:c0dc3a76f3d4 311 }
apatel336 0:c0dc3a76f3d4 312 return true;
apatel336 0:c0dc3a76f3d4 313 }
apatel336 0:c0dc3a76f3d4 314
apatel336 0:c0dc3a76f3d4 315 bool Wifly::cmdMode()
apatel336 0:c0dc3a76f3d4 316 {
apatel336 0:c0dc3a76f3d4 317 // if already in cmd mode, return
apatel336 0:c0dc3a76f3d4 318 if (state.cmd_mode)
apatel336 0:c0dc3a76f3d4 319 return true;
apatel336 0:c0dc3a76f3d4 320
apatel336 0:c0dc3a76f3d4 321 if (send("$$$", 3, "CMD") == -1) {
apatel336 0:c0dc3a76f3d4 322 ERR("cannot enter in cmd mode\r\n");
apatel336 0:c0dc3a76f3d4 323 exit();
apatel336 0:c0dc3a76f3d4 324 return false;
apatel336 0:c0dc3a76f3d4 325 }
apatel336 0:c0dc3a76f3d4 326 state.cmd_mode = true;
apatel336 0:c0dc3a76f3d4 327 return true;
apatel336 0:c0dc3a76f3d4 328 }
apatel336 0:c0dc3a76f3d4 329
apatel336 0:c0dc3a76f3d4 330 bool Wifly::disconnect()
apatel336 0:c0dc3a76f3d4 331 {
apatel336 0:c0dc3a76f3d4 332 // if already disconnected, return
apatel336 0:c0dc3a76f3d4 333 if (!state.associated)
apatel336 0:c0dc3a76f3d4 334 return true;
apatel336 0:c0dc3a76f3d4 335
apatel336 0:c0dc3a76f3d4 336 if (!sendCommand("leave\r", "DeAuth"))
apatel336 0:c0dc3a76f3d4 337 return false;
apatel336 0:c0dc3a76f3d4 338 exit();
apatel336 0:c0dc3a76f3d4 339
apatel336 0:c0dc3a76f3d4 340 state.associated = false;
apatel336 0:c0dc3a76f3d4 341 return true;
apatel336 0:c0dc3a76f3d4 342
apatel336 0:c0dc3a76f3d4 343 }
apatel336 0:c0dc3a76f3d4 344
apatel336 0:c0dc3a76f3d4 345 bool Wifly::is_connected()
apatel336 0:c0dc3a76f3d4 346 {
apatel336 0:c0dc3a76f3d4 347 return (tcp_status.read() == 1) ? true : false;
apatel336 0:c0dc3a76f3d4 348 }
apatel336 0:c0dc3a76f3d4 349
apatel336 0:c0dc3a76f3d4 350
apatel336 0:c0dc3a76f3d4 351 void Wifly::reset()
apatel336 0:c0dc3a76f3d4 352 {
apatel336 0:c0dc3a76f3d4 353 reset_pin = 0;
apatel336 0:c0dc3a76f3d4 354 wait(0.2);
apatel336 0:c0dc3a76f3d4 355 reset_pin = 1;
apatel336 0:c0dc3a76f3d4 356 wait(0.2);
apatel336 0:c0dc3a76f3d4 357 }
apatel336 0:c0dc3a76f3d4 358
apatel336 0:c0dc3a76f3d4 359 bool Wifly::reboot()
apatel336 0:c0dc3a76f3d4 360 {
apatel336 0:c0dc3a76f3d4 361 // if already in cmd mode, return
apatel336 0:c0dc3a76f3d4 362 if (!sendCommand("reboot\r"))
apatel336 0:c0dc3a76f3d4 363 return false;
apatel336 0:c0dc3a76f3d4 364
apatel336 0:c0dc3a76f3d4 365 wait(0.3);
apatel336 0:c0dc3a76f3d4 366
apatel336 0:c0dc3a76f3d4 367 state.cmd_mode = false;
apatel336 0:c0dc3a76f3d4 368 return true;
apatel336 0:c0dc3a76f3d4 369 }
apatel336 0:c0dc3a76f3d4 370
apatel336 0:c0dc3a76f3d4 371 bool Wifly::close()
apatel336 0:c0dc3a76f3d4 372 {
apatel336 0:c0dc3a76f3d4 373 // if not connected, return
apatel336 0:c0dc3a76f3d4 374 if (!state.tcp)
apatel336 0:c0dc3a76f3d4 375 return true;
apatel336 0:c0dc3a76f3d4 376
apatel336 0:c0dc3a76f3d4 377 wait(0.25);
apatel336 0:c0dc3a76f3d4 378 if (!sendCommand("close\r", "CLOS"))
apatel336 0:c0dc3a76f3d4 379 return false;
apatel336 0:c0dc3a76f3d4 380 exit();
apatel336 0:c0dc3a76f3d4 381
apatel336 0:c0dc3a76f3d4 382 state.tcp = false;
apatel336 0:c0dc3a76f3d4 383 return true;
apatel336 0:c0dc3a76f3d4 384 }
apatel336 0:c0dc3a76f3d4 385
apatel336 0:c0dc3a76f3d4 386
apatel336 0:c0dc3a76f3d4 387 int Wifly::putc(char c)
apatel336 0:c0dc3a76f3d4 388 {
apatel336 0:c0dc3a76f3d4 389 while (!wifi.writeable());
apatel336 0:c0dc3a76f3d4 390 return wifi.putc(c);
apatel336 0:c0dc3a76f3d4 391 }
apatel336 0:c0dc3a76f3d4 392
apatel336 0:c0dc3a76f3d4 393
apatel336 0:c0dc3a76f3d4 394 bool Wifly::exit()
apatel336 0:c0dc3a76f3d4 395 {
apatel336 0:c0dc3a76f3d4 396 flush();
apatel336 0:c0dc3a76f3d4 397 if (!state.cmd_mode)
apatel336 0:c0dc3a76f3d4 398 return true;
apatel336 0:c0dc3a76f3d4 399 if (!sendCommand("exit\r", "EXIT"))
apatel336 0:c0dc3a76f3d4 400 return false;
apatel336 0:c0dc3a76f3d4 401 state.cmd_mode = false;
apatel336 0:c0dc3a76f3d4 402 flush();
apatel336 0:c0dc3a76f3d4 403 return true;
apatel336 0:c0dc3a76f3d4 404 }
apatel336 0:c0dc3a76f3d4 405
apatel336 0:c0dc3a76f3d4 406
apatel336 0:c0dc3a76f3d4 407 int Wifly::readable()
apatel336 0:c0dc3a76f3d4 408 {
apatel336 0:c0dc3a76f3d4 409 return buf_wifly.available();
apatel336 0:c0dc3a76f3d4 410 }
apatel336 0:c0dc3a76f3d4 411
apatel336 0:c0dc3a76f3d4 412 int Wifly::writeable()
apatel336 0:c0dc3a76f3d4 413 {
apatel336 0:c0dc3a76f3d4 414 return wifi.writeable();
apatel336 0:c0dc3a76f3d4 415 }
apatel336 0:c0dc3a76f3d4 416
apatel336 0:c0dc3a76f3d4 417 char Wifly::getc()
apatel336 0:c0dc3a76f3d4 418 {
apatel336 0:c0dc3a76f3d4 419 char c;
apatel336 0:c0dc3a76f3d4 420 while (!buf_wifly.available());
apatel336 0:c0dc3a76f3d4 421 buf_wifly.dequeue(&c);
apatel336 0:c0dc3a76f3d4 422 return c;
apatel336 0:c0dc3a76f3d4 423 }
apatel336 0:c0dc3a76f3d4 424
apatel336 0:c0dc3a76f3d4 425 void Wifly::handler_rx(void)
apatel336 0:c0dc3a76f3d4 426 {
apatel336 0:c0dc3a76f3d4 427 //read characters
apatel336 0:c0dc3a76f3d4 428 while (wifi.readable())
apatel336 0:c0dc3a76f3d4 429 buf_wifly.queue(wifi.getc());
apatel336 0:c0dc3a76f3d4 430 }
apatel336 0:c0dc3a76f3d4 431
apatel336 0:c0dc3a76f3d4 432 void Wifly::attach_rx(bool callback)
apatel336 0:c0dc3a76f3d4 433 {
apatel336 0:c0dc3a76f3d4 434 if (!callback)
apatel336 0:c0dc3a76f3d4 435 wifi.attach(NULL);
apatel336 0:c0dc3a76f3d4 436 else
apatel336 0:c0dc3a76f3d4 437 wifi.attach(this, &Wifly::handler_rx);
apatel336 0:c0dc3a76f3d4 438 }
apatel336 0:c0dc3a76f3d4 439
apatel336 0:c0dc3a76f3d4 440
apatel336 0:c0dc3a76f3d4 441 int Wifly::send(const char * str, int len, const char * ACK, char * res, int timeout)
apatel336 0:c0dc3a76f3d4 442 {
apatel336 0:c0dc3a76f3d4 443 char read;
apatel336 0:c0dc3a76f3d4 444 size_t found = string::npos;
apatel336 0:c0dc3a76f3d4 445 string checking;
apatel336 0:c0dc3a76f3d4 446 Timer tmr;
apatel336 0:c0dc3a76f3d4 447 int result = 0;
apatel336 0:c0dc3a76f3d4 448
apatel336 0:c0dc3a76f3d4 449 DBG("will send: %s\r\n",str);
apatel336 0:c0dc3a76f3d4 450
apatel336 0:c0dc3a76f3d4 451 attach_rx(false);
apatel336 0:c0dc3a76f3d4 452
apatel336 0:c0dc3a76f3d4 453 //We flush the buffer
apatel336 0:c0dc3a76f3d4 454 while (wifi.readable())
apatel336 0:c0dc3a76f3d4 455 wifi.getc();
apatel336 0:c0dc3a76f3d4 456
apatel336 0:c0dc3a76f3d4 457 if (!ACK || !strcmp(ACK, "NO")) {
apatel336 0:c0dc3a76f3d4 458 for (int i = 0; i < len; i++)
apatel336 0:c0dc3a76f3d4 459 result = (putc(str[i]) == str[i]) ? result + 1 : result;
apatel336 0:c0dc3a76f3d4 460 } else {
apatel336 0:c0dc3a76f3d4 461 //We flush the buffer
apatel336 0:c0dc3a76f3d4 462 while (wifi.readable())
apatel336 0:c0dc3a76f3d4 463 wifi.getc();
apatel336 0:c0dc3a76f3d4 464
apatel336 0:c0dc3a76f3d4 465 tmr.start();
apatel336 0:c0dc3a76f3d4 466 for (int i = 0; i < len; i++)
apatel336 0:c0dc3a76f3d4 467 result = (putc(str[i]) == str[i]) ? result + 1 : result;
apatel336 0:c0dc3a76f3d4 468
apatel336 0:c0dc3a76f3d4 469 while (1) {
apatel336 0:c0dc3a76f3d4 470 if (tmr.read_ms() > timeout) {
apatel336 0:c0dc3a76f3d4 471 //We flush the buffer
apatel336 0:c0dc3a76f3d4 472 while (wifi.readable())
apatel336 0:c0dc3a76f3d4 473 wifi.getc();
apatel336 0:c0dc3a76f3d4 474
apatel336 0:c0dc3a76f3d4 475 DBG("check: %s\r\n", checking.c_str());
apatel336 0:c0dc3a76f3d4 476
apatel336 0:c0dc3a76f3d4 477 attach_rx(true);
apatel336 0:c0dc3a76f3d4 478 return -1;
apatel336 0:c0dc3a76f3d4 479 } else if (wifi.readable()) {
apatel336 0:c0dc3a76f3d4 480 read = wifi.getc();
apatel336 0:c0dc3a76f3d4 481 if ( read != '\r' && read != '\n') {
apatel336 0:c0dc3a76f3d4 482 checking += read;
apatel336 0:c0dc3a76f3d4 483 found = checking.find(ACK);
apatel336 0:c0dc3a76f3d4 484 if (found != string::npos) {
apatel336 0:c0dc3a76f3d4 485 wait(0.01);
apatel336 0:c0dc3a76f3d4 486
apatel336 0:c0dc3a76f3d4 487 //We flush the buffer
apatel336 0:c0dc3a76f3d4 488 while (wifi.readable())
apatel336 0:c0dc3a76f3d4 489 wifi.getc();
apatel336 0:c0dc3a76f3d4 490
apatel336 0:c0dc3a76f3d4 491 break;
apatel336 0:c0dc3a76f3d4 492 }
apatel336 0:c0dc3a76f3d4 493 }
apatel336 0:c0dc3a76f3d4 494 }
apatel336 0:c0dc3a76f3d4 495 }
apatel336 0:c0dc3a76f3d4 496 DBG("check: %s\r\n", checking.c_str());
apatel336 0:c0dc3a76f3d4 497
apatel336 0:c0dc3a76f3d4 498 attach_rx(true);
apatel336 0:c0dc3a76f3d4 499 return result;
apatel336 0:c0dc3a76f3d4 500 }
apatel336 0:c0dc3a76f3d4 501
apatel336 0:c0dc3a76f3d4 502 //the user wants the result from the command (ACK == NULL, res != NULL)
apatel336 0:c0dc3a76f3d4 503 if ( res != NULL) {
apatel336 0:c0dc3a76f3d4 504 int i = 0;
apatel336 0:c0dc3a76f3d4 505 Timer timeout;
apatel336 0:c0dc3a76f3d4 506 timeout.start();
apatel336 0:c0dc3a76f3d4 507 tmr.reset();
apatel336 0:c0dc3a76f3d4 508 while (1) {
apatel336 0:c0dc3a76f3d4 509 if (timeout.read() > 2) {
apatel336 0:c0dc3a76f3d4 510 if (i == 0) {
apatel336 0:c0dc3a76f3d4 511 res = NULL;
apatel336 0:c0dc3a76f3d4 512 break;
apatel336 0:c0dc3a76f3d4 513 }
apatel336 0:c0dc3a76f3d4 514 res[i] = '\0';
apatel336 0:c0dc3a76f3d4 515 DBG("user str 1: %s\r\n", res);
apatel336 0:c0dc3a76f3d4 516
apatel336 0:c0dc3a76f3d4 517 break;
apatel336 0:c0dc3a76f3d4 518 } else {
apatel336 0:c0dc3a76f3d4 519 if (tmr.read_ms() > 300) {
apatel336 0:c0dc3a76f3d4 520 res[i] = '\0';
apatel336 0:c0dc3a76f3d4 521 DBG("user str: %s\r\n", res);
apatel336 0:c0dc3a76f3d4 522
apatel336 0:c0dc3a76f3d4 523 break;
apatel336 0:c0dc3a76f3d4 524 }
apatel336 0:c0dc3a76f3d4 525 if (wifi.readable()) {
apatel336 0:c0dc3a76f3d4 526 tmr.start();
apatel336 0:c0dc3a76f3d4 527 read = wifi.getc();
apatel336 0:c0dc3a76f3d4 528
apatel336 0:c0dc3a76f3d4 529 // we drop \r and \n
apatel336 0:c0dc3a76f3d4 530 if ( read != '\r' && read != '\n') {
apatel336 0:c0dc3a76f3d4 531 res[i++] = read;
apatel336 0:c0dc3a76f3d4 532 }
apatel336 0:c0dc3a76f3d4 533 }
apatel336 0:c0dc3a76f3d4 534 }
apatel336 0:c0dc3a76f3d4 535 }
apatel336 0:c0dc3a76f3d4 536 DBG("user str: %s\r\n", res);
apatel336 0:c0dc3a76f3d4 537 }
apatel336 0:c0dc3a76f3d4 538
apatel336 0:c0dc3a76f3d4 539 //We flush the buffer
apatel336 0:c0dc3a76f3d4 540 while (wifi.readable())
apatel336 0:c0dc3a76f3d4 541 wifi.getc();
apatel336 0:c0dc3a76f3d4 542
apatel336 0:c0dc3a76f3d4 543 attach_rx(true);
apatel336 0:c0dc3a76f3d4 544 DBG("result: %d\r\n", result)
apatel336 0:c0dc3a76f3d4 545 return result;
apatel336 0:c0dc3a76f3d4 546 }