This is a fork specifically for seeed wifi shield
Dependents: seeed_Wifi_HelloWorld Wifly_Xively_HelloWorld
Fork of WiflyInterface by
Wifly.cpp
00001 /* Copyright (C) 2012 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "mbed.h" 00020 #include "Wifly.h" 00021 #include <string> 00022 #include <algorithm> 00023 00024 //Debug is disabled by default 00025 #if (1 && defined(TARGET_LPC1768)) 00026 #define DBG(x, ...) std::printf("[Wifly : DBG]"x"\r\n", ##__VA_ARGS__); 00027 #define WARN(x, ...) std::printf("[Wifly : WARN]"x"\r\n", ##__VA_ARGS__); 00028 #define ERR(x, ...) std::printf("[Wifly : ERR]"x"\r\n", ##__VA_ARGS__); 00029 #else 00030 #define DBG(x, ...) 00031 #define WARN(x, ...) 00032 #define ERR(x, ...) 00033 #endif 00034 00035 #if TARGET_LPC1768 00036 #define INFO(x, ...) printf("[Wifly : INFO]"x"\r\n", ##__VA_ARGS__); 00037 #else 00038 #define INFO(x, ...) 00039 #endif 00040 00041 #define MAX_TRY_JOIN 3 00042 00043 Wifly * Wifly::inst; 00044 00045 Wifly::Wifly( PinName tx, PinName rx, PinName _reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec): 00046 wifi(tx, rx), reset_pin(_reset), tcp_status(tcp_status), buf_wifly(256) 00047 { 00048 memset(&state, 0, sizeof(state)); 00049 state.sec = sec; 00050 00051 // change all ' ' in '$' in the ssid and the passphrase 00052 strcpy(this->ssid, ssid); 00053 for (int i = 0; i < strlen(ssid); i++) { 00054 if (this->ssid[i] == ' ') 00055 this->ssid[i] = '$'; 00056 } 00057 strcpy(this->phrase, phrase); 00058 for (int i = 0; i < strlen(phrase); i++) { 00059 if (this->phrase[i] == ' ') 00060 this->phrase[i] = '$'; 00061 } 00062 00063 inst = this; 00064 attach_rx(false); 00065 state.cmd_mode = false; 00066 } 00067 00068 bool Wifly::join() 00069 { 00070 char cmd[20]; 00071 00072 for (int i= 0; i < MAX_TRY_JOIN; i++) { 00073 // set time 00074 if (!sendCommand("set c t 20\r", "AOK")) 00075 continue; 00076 00077 // set size 00078 if (!sendCommand("set c s 128\r", "AOK")) 00079 continue; 00080 00081 // red led on when tcp connection active 00082 if (!sendCommand("set s i 0x40\r", "AOK")) 00083 continue; 00084 00085 // no string sent to the tcp client 00086 if (!sendCommand("set c r 0\r", "AOK")) 00087 continue; 00088 00089 // tcp protocol 00090 if (!sendCommand("set i p 2\r", "AOK")) 00091 continue; 00092 00093 // tcp retry 00094 if (!sendCommand("set i f 0x7\r", "AOK")) 00095 continue; 00096 00097 //no echo 00098 if (!sendCommand("set u m 1\r", "AOK")) 00099 continue; 00100 00101 // no auto join 00102 if (!sendCommand("set w j 0\r", "AOK")) 00103 continue; 00104 00105 //dhcp 00106 sprintf(cmd, "set i d %d\r", (state.dhcp) ? 1 : 0); 00107 if (!sendCommand(cmd, "AOK")) 00108 continue; 00109 00110 // ssid 00111 sprintf(cmd, "set w s %s\r", ssid); 00112 if (!sendCommand(cmd, "AOK", NULL, 1000)) 00113 continue; 00114 00115 //auth 00116 sprintf(cmd, "set w a %d\r", state.sec); 00117 if (!sendCommand(cmd, "AOK")) 00118 continue; 00119 00120 // if no dhcp, set ip, netmask and gateway 00121 if (!state.dhcp) { 00122 DBG("not dhcp\r"); 00123 00124 sprintf(cmd, "set i a %s\r\n", ip); 00125 if (!sendCommand(cmd, "AOK")) 00126 continue; 00127 00128 sprintf(cmd, "set i n %s\r", netmask); 00129 if (!sendCommand(cmd, "AOK")) 00130 continue; 00131 00132 sprintf(cmd, "set i g %s\r", gateway); 00133 if (!sendCommand(cmd, "AOK")) 00134 continue; 00135 } 00136 00137 //key step 00138 if (state.sec != NONE) { 00139 if (state.sec == WPA) 00140 sprintf(cmd, "set w p %s\r", phrase); 00141 else if (state.sec == WEP_128) 00142 sprintf(cmd, "set w k %s\r", phrase); 00143 00144 if (!sendCommand(cmd, "AOK", NULL, 1000)) 00145 continue; 00146 } 00147 00148 //join the network 00149 sprintf(cmd, "join\r"); 00150 if (!sendCommand(cmd, "Associated", NULL, 3000)) 00151 continue; 00152 00153 if (!sendCommand("", "IP=", NULL, 10000)) 00154 continue; 00155 00156 if (state.dhcp) { 00157 if (!sendCommand("get i\r", "DHCP=ON", NULL, 3000)) 00158 continue; 00159 } 00160 00161 exit(); 00162 00163 state.associated = true; 00164 INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase, getStringSecurity()); 00165 return true; 00166 } 00167 return false; 00168 } 00169 00170 00171 bool Wifly::setProtocol(Protocol p) 00172 { 00173 // use udp auto pairing 00174 char cmd[20]; 00175 sprintf(cmd, "set i p %d\r", p); 00176 if (!sendCommand(cmd, "AOK")) 00177 return false; 00178 00179 switch(p) { 00180 case TCP: 00181 // set ip flags: tcp retry enabled 00182 if (!sendCommand("set i f 0x07\r", "AOK")) 00183 return false; 00184 break; 00185 case UDP: 00186 // set ip flags: udp auto pairing enabled 00187 if (!sendCommand("set i f 0x40\r", "AOK")) 00188 return false; 00189 if (!sendCommand("set i h 0.0.0.0\r", "AOK")) 00190 return false; 00191 if (!sendCommand("set i r 0\r", "AOK")) 00192 return false; 00193 break; 00194 } 00195 state.proto = p; 00196 return true; 00197 } 00198 00199 char * Wifly::getStringSecurity() 00200 { 00201 switch(state.sec) { 00202 case NONE: 00203 return "NONE"; 00204 case WEP_128: 00205 return "WEP_128"; 00206 case WPA: 00207 return "WPA"; 00208 } 00209 return "UNKNOWN"; 00210 } 00211 00212 bool Wifly::connect(const char * host, int port) 00213 { 00214 char rcv[20]; 00215 char cmd[20]; 00216 00217 // get ip from host and set host 00218 if (gethostbyname(host, rcv)) { 00219 sprintf(cmd, "set i h %s\r", rcv); 00220 if (!sendCommand(cmd, "AOK")) 00221 return false; 00222 } else { 00223 return false; 00224 } 00225 00226 // set port 00227 sprintf(cmd, "set i r %d\r", port); 00228 if (!sendCommand(cmd, "AOK")) 00229 return false; 00230 00231 // open 00232 if (sendCommand("open\r", NULL, rcv)) { 00233 if (strstr(rcv, "OPEN") == NULL) { 00234 if (strstr(rcv, "Connected") != NULL) { 00235 if (!sendCommand("close\r", "CLOS")) 00236 return false; 00237 if (!sendCommand("open\r", "OPEN")) 00238 return false; 00239 } else { 00240 return false; 00241 } 00242 } 00243 } else { 00244 return false; 00245 } 00246 00247 state.tcp = true; 00248 state.cmd_mode = false; 00249 00250 return true; 00251 } 00252 00253 00254 bool Wifly::gethostbyname(const char * host, char * ip) 00255 { 00256 string h = host; 00257 char cmd[30], rcv[100]; 00258 int l = 0; 00259 char * point; 00260 int nb_digits = 0; 00261 00262 // no dns needed 00263 int pos = h.find("."); 00264 if (pos != string::npos) { 00265 string sub = h.substr(0, h.find(".")); 00266 nb_digits = atoi(sub.c_str()); 00267 } 00268 //printf("substrL %s\r\n", sub.c_str()); 00269 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) { 00270 strcpy(ip, host); 00271 } 00272 // dns needed 00273 else { 00274 nb_digits = 0; 00275 sprintf(cmd, "lookup %s\r", host); 00276 if (!sendCommand(cmd, NULL, rcv)) 00277 return false; 00278 00279 // look for the ip address 00280 char * begin = strstr(rcv, "=") + 1; 00281 for (int i = 0; i < 3; i++) { 00282 point = strstr(begin + l, "."); 00283 DBG("str: %s", begin + l); 00284 l += point - (begin + l) + 1; 00285 } 00286 DBG("str: %s", begin + l); 00287 while(*(begin + l + nb_digits) >= '0' && *(begin + l + nb_digits) <= '9') { 00288 DBG("digit: %c", *(begin + l + nb_digits)); 00289 nb_digits++; 00290 } 00291 memcpy(ip, begin, l + nb_digits); 00292 ip[l+nb_digits] = 0; 00293 DBG("ip from dns: %s", ip); 00294 } 00295 return true; 00296 } 00297 00298 00299 void Wifly::flush() 00300 { 00301 buf_wifly.flush(); 00302 } 00303 00304 bool Wifly::sendCommand(const char * cmd, const char * ack, char * res, int timeout) 00305 { 00306 if (!state.cmd_mode) { 00307 cmdMode(); 00308 } 00309 if (send(cmd, strlen(cmd), ack, res, timeout) == -1) { 00310 ERR("sendCommand: cannot %s\r\n", cmd); 00311 exit(); 00312 return false; 00313 } 00314 return true; 00315 } 00316 00317 bool Wifly::cmdMode() 00318 { 00319 // if already in cmd mode, return 00320 if (state.cmd_mode) 00321 return true; 00322 00323 if (send("$$$", 3, "CMD") == -1 && send("\r",1,">") != true) { 00324 ERR("cannot enter in cmd mode\r\n"); 00325 return false; 00326 } 00327 state.cmd_mode = true; 00328 return true; 00329 } 00330 00331 bool Wifly::disconnect() 00332 { 00333 // if already disconnected, return 00334 if (!state.associated) 00335 return true; 00336 00337 if (!sendCommand("leave\r", "DeAuth")) 00338 return false; 00339 exit(); 00340 00341 state.associated = false; 00342 return true; 00343 00344 } 00345 00346 bool Wifly::is_connected() 00347 { 00348 return (tcp_status.read() == 1) ? true : false; 00349 } 00350 00351 00352 void Wifly::reset() 00353 { 00354 reset_pin = 0; 00355 wait(0.2); 00356 reset_pin = 1; 00357 wait(0.2); 00358 } 00359 00360 bool Wifly::close() 00361 { 00362 // if not connected, return 00363 if (!state.tcp) 00364 return true; 00365 00366 wait(0.25); 00367 if (!sendCommand("close\r", "CLOS")) 00368 return false; 00369 exit(); 00370 00371 state.tcp = false; 00372 return true; 00373 } 00374 00375 00376 int Wifly::putc(char c) 00377 { 00378 while (!wifi.writeable()); 00379 return wifi.putc(c); 00380 } 00381 00382 00383 bool Wifly::exit() 00384 { 00385 flush(); 00386 if (!state.cmd_mode) 00387 return true; 00388 if (!sendCommand("exit\r", "EXIT")) 00389 return false; 00390 state.cmd_mode = false; 00391 flush(); 00392 return true; 00393 } 00394 00395 00396 int Wifly::readable() 00397 { 00398 return buf_wifly.available(); 00399 } 00400 00401 int Wifly::writeable() 00402 { 00403 return wifi.writeable(); 00404 } 00405 00406 char Wifly::getc() 00407 { 00408 char c; 00409 while (!buf_wifly.available()); 00410 buf_wifly.dequeue(&c); 00411 return c; 00412 } 00413 00414 void Wifly::handler_rx(void) 00415 { 00416 //read characters 00417 while (wifi.readable()) 00418 buf_wifly.queue(wifi.getc()); 00419 } 00420 00421 void Wifly::attach_rx(bool callback) 00422 { 00423 if (!callback) 00424 wifi.attach(NULL); 00425 else 00426 wifi.attach(this, &Wifly::handler_rx); 00427 } 00428 00429 00430 int Wifly::send(const char * str, int len, const char * ACK, char * res, int timeout) 00431 { 00432 char read; 00433 size_t found = string::npos; 00434 string checking; 00435 Timer tmr; 00436 int result = 0; 00437 00438 DBG("will send: %s\r\n",str); 00439 00440 attach_rx(false); 00441 00442 //We flush the buffer 00443 while (wifi.readable()) 00444 wifi.getc(); 00445 00446 if (!ACK || !strcmp(ACK, "NO")) { 00447 for (int i = 0; i < len; i++) 00448 result = (putc(str[i]) == str[i]) ? result + 1 : result; 00449 } else { 00450 //We flush the buffer 00451 while (wifi.readable()) 00452 wifi.getc(); 00453 00454 tmr.start(); 00455 for (int i = 0; i < len; i++) 00456 result = (putc(str[i]) == str[i]) ? result + 1 : result; 00457 00458 while (1) { 00459 if (tmr.read_ms() > timeout) { 00460 //We flush the buffer 00461 while (wifi.readable()) 00462 wifi.getc(); 00463 00464 DBG("check: %s\r\n", checking.c_str()); 00465 00466 attach_rx(true); 00467 return -1; 00468 } else if (wifi.readable()) { 00469 read = wifi.getc(); 00470 if ( read != '\r' && read != '\n') { 00471 checking += read; 00472 found = checking.find(ACK); 00473 if (found != string::npos) { 00474 wait(0.01); 00475 00476 //We flush the buffer 00477 while (wifi.readable()) 00478 wifi.getc(); 00479 00480 break; 00481 } 00482 } 00483 } 00484 } 00485 DBG("check: %s\r\n", checking.c_str()); 00486 00487 attach_rx(true); 00488 return result; 00489 } 00490 00491 //the user wants the result from the command (ACK == NULL, res != NULL) 00492 if ( res != NULL) { 00493 int i = 0; 00494 Timer timeout; 00495 timeout.start(); 00496 tmr.reset(); 00497 while (1) { 00498 if (timeout.read() > 2) { 00499 if (i == 0) { 00500 res = NULL; 00501 break; 00502 } 00503 res[i] = '\0'; 00504 DBG("user str 1: %s\r\n", res); 00505 00506 break; 00507 } else { 00508 if (tmr.read_ms() > 300) { 00509 res[i] = '\0'; 00510 DBG("user str: %s\r\n", res); 00511 00512 break; 00513 } 00514 if (wifi.readable()) { 00515 tmr.start(); 00516 read = wifi.getc(); 00517 00518 // we drop \r and \n 00519 if ( read != '\r' && read != '\n') { 00520 res[i++] = read; 00521 } 00522 } 00523 } 00524 } 00525 DBG("user str: %s\r\n", res); 00526 } 00527 00528 //We flush the buffer 00529 while (wifi.readable()) 00530 wifi.getc(); 00531 00532 attach_rx(true); 00533 DBG("result: %d\r\n", result) 00534 return result; 00535 }
Generated on Fri Jul 15 2022 02:01:12 by 1.7.2