GSwifiInterface library (interface for GainSpan Wi-Fi GS1011 modules) Please see https://mbed.org/users/gsfan/notebook/GSwifiInterface/
Dependents: GSwifiInterface_HelloWorld GSwifiInterface_HelloServo GSwifiInterface_UDPEchoServer GSwifiInterface_UDPEchoClient ... more
Fork of WiflyInterface by
GSwifi_msg.cpp
00001 /* Copyright (C) 2013 gsfan, 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 "GSwifi.h" 00020 00021 #ifdef CFG_ENABLE_RTOS 00022 #undef DBG 00023 #define DBG(x, ...) 00024 #endif 00025 00026 void GSwifi::recvData (char c) { 00027 static int cid, sub, len, count; 00028 00029 #ifdef DEBUG_DUMP 00030 if (c < 0x20 || c >= 0x7f) { 00031 std::printf("_%02x", c); 00032 } else { 00033 std::printf("_%c", c); 00034 } 00035 #endif 00036 switch (_state.mode) { 00037 case MODE_COMMAND: 00038 switch (c) { 00039 case 0: 00040 case 0x0a: // LF 00041 case 0x0d: // CR 00042 break; 00043 case 0x1b: // ESC 00044 _state.buf->flush(); 00045 _state.mode = MODE_ESCAPE; 00046 _state.escape = false; 00047 break; 00048 case 0xf3: // SPI link ready indication 00049 case 0xf5: // IDLE 00050 break; 00051 default: 00052 _state.buf->flush(); 00053 _state.buf->queue(c); 00054 _state.mode = MODE_CMDRESP; 00055 _state.escape = false; 00056 break; 00057 } 00058 break; 00059 00060 case MODE_CMDRESP: 00061 switch (c) { 00062 case 0: 00063 break; 00064 case 0x0a: // LF 00065 case 0x0d: // CR 00066 // _state.buf->queue(c); 00067 if (_flow == 2) setRts(false); 00068 _state.mode = MODE_COMMAND; 00069 parseMessage(); 00070 if (_flow == 2) setRts(true); 00071 break; 00072 case 0x1b: // ESC 00073 _state.mode = MODE_ESCAPE; 00074 break; 00075 default: 00076 _state.buf->queue(c); 00077 break; 00078 } 00079 break; 00080 00081 case MODE_ESCAPE: 00082 sub = 0; 00083 switch (c) { 00084 case 'H': 00085 _state.mode = MODE_DATA_RXHTTP; 00086 break; 00087 case 'u': 00088 _state.mode = MODE_DATA_RXUDP; 00089 break; 00090 case 'y': 00091 _state.mode = MODE_DATA_RXUDP_BULK; 00092 break; 00093 case 'Z': 00094 _state.mode = MODE_DATA_RX_BULK; 00095 break; 00096 case 'S': 00097 _state.mode = MODE_DATA_RX; 00098 break; 00099 case ':': 00100 _state.mode = MODE_DATA_RAW; 00101 break; 00102 case 'O': 00103 _state.mode = MODE_COMMAND; 00104 _state.ok = true; 00105 return; 00106 case 'F': 00107 _state.mode = MODE_COMMAND; 00108 _state.failure = true; 00109 return; 00110 default: 00111 _state.mode = MODE_COMMAND; 00112 return; 00113 } 00114 break; 00115 00116 case MODE_DATA_RX: 00117 case MODE_DATA_RXUDP: 00118 switch (sub) { 00119 case 0: 00120 // cid 00121 cid = x2i(c); 00122 sub ++; 00123 count = 0; 00124 if (_state.mode == MODE_DATA_RX) { 00125 sub = 3; 00126 } 00127 break; 00128 case 1: 00129 // ip 00130 if ((c >= '0' && c <= '9') || c == '.') { 00131 _con[cid].ip[count] = c; 00132 count ++; 00133 } else { 00134 _con[cid].ip[count] = 0; 00135 _con[cid].port = 0; 00136 sub ++; 00137 } 00138 break; 00139 case 2: 00140 // port 00141 if (c >= '0' && c <= '9') { 00142 _con[cid].port = (_con[cid].port * 10) + (c - '0'); 00143 } else { 00144 sub ++; 00145 count = 0; 00146 } 00147 break; 00148 default: 00149 // data 00150 if (_state.escape) { 00151 if (c == 'E') { 00152 DBG("recv ascii %d %d/a\r\n", cid, count); 00153 _con[cid].received = true; 00154 _state.mode = MODE_COMMAND; 00155 } else { 00156 if (_con[cid].buf != NULL) { 00157 _con[cid].buf->queue(0x1b); 00158 _con[cid].buf->queue(c); 00159 } 00160 count += 2; 00161 } 00162 _state.escape = false; 00163 } else 00164 if (c == 0x1b) { 00165 _state.escape = true; 00166 } else { 00167 if (_con[cid].buf != NULL) { 00168 _con[cid].buf->queue(c); 00169 if (_con[cid].func != NULL && _con[cid].buf->available() > CFG_DATA_SIZE - 16) { 00170 setRts(false); 00171 _con[cid].received = true; 00172 WARN("buf full"); 00173 } 00174 } 00175 count ++; 00176 } 00177 break; 00178 } 00179 break; 00180 00181 case MODE_DATA_RX_BULK: 00182 case MODE_DATA_RXUDP_BULK: 00183 case MODE_DATA_RXHTTP: 00184 switch (sub) { 00185 case 0: 00186 // cid 00187 cid = x2i(c); 00188 sub ++; 00189 len = 0; 00190 count = 0; 00191 if (_state.mode != MODE_DATA_RXUDP_BULK) { 00192 sub = 3; 00193 } 00194 break; 00195 case 1: 00196 // ip 00197 if ((c >= '0' && c <= '9') || c == '.') { 00198 _con[cid].ip[count] = c; 00199 count ++; 00200 } else { 00201 _con[cid].ip[count] = 0; 00202 _con[cid].port = 0; 00203 sub ++; 00204 } 00205 break; 00206 case 2: 00207 // port 00208 if (c >= '0' && c <= '9') { 00209 _con[cid].port = (_con[cid].port * 10) + (c - '0'); 00210 } else { 00211 sub ++; 00212 count = 0; 00213 } 00214 break; 00215 case 3: 00216 // length 00217 len = (len * 10) + (c - '0'); 00218 count ++; 00219 if (count >= 4) { 00220 sub ++; 00221 count = 0; 00222 } 00223 break; 00224 default: 00225 // data 00226 #ifdef CFG_ENABLE_HTTPD 00227 if (_con[cid].protocol == PROTO_HTTPD) { 00228 httpdRecvData(cid, c); 00229 } else 00230 #endif 00231 if (_con[cid].buf != NULL) { 00232 #ifdef CFG_SPI_DATAINTERFACE 00233 if (_state.datainterface) { 00234 if (_state.escape) { // dencode 00235 _con[cid].buf->queue(c ^ 0x20); // xor 00236 _state.escape = false; 00237 } else 00238 if (c == 0xfb) { 00239 _state.escape = true; 00240 } else { 00241 _con[cid].buf->queue(c); 00242 } 00243 } else { 00244 _con[cid].buf->queue(c); 00245 } 00246 #else 00247 _con[cid].buf->queue(c); 00248 #endif 00249 if (_con[cid].func != NULL && _con[cid].buf->available() > CFG_DATA_SIZE - 16) { 00250 setRts(false); 00251 _con[cid].received = true; 00252 WARN("buf full"); 00253 } 00254 } 00255 if (!_state.escape) count ++; 00256 if (count >= len) { 00257 DBG("recv bulk %d %d/%d\r\n", cid, count, len); 00258 _con[cid].received = true; 00259 _state.mode = MODE_COMMAND; 00260 } 00261 break; 00262 } 00263 break; 00264 } 00265 } 00266 00267 #define MSG_TABLE_NUM 16 00268 #define RES_TABLE_NUM 11 00269 int GSwifi::parseMessage () { 00270 int i; 00271 char buf[256]; 00272 static const struct MSG_TABLE { 00273 const char msg[24]; 00274 void (GSwifi::*func)(const char*); 00275 } msg_table[MSG_TABLE_NUM] = { 00276 {"OK", &GSwifi::msgOk}, 00277 {"ERROR", &GSwifi::msgError}, 00278 {"INVALID INPUT", &GSwifi::msgError}, 00279 {"CONNECT ", &GSwifi::msgConnect}, 00280 {"DISCONNECT ", &GSwifi::msgDisconnect}, 00281 {"DISASSOCIATED", &GSwifi::msgDisassociated}, 00282 {"Disassociated", &GSwifi::msgDisassociated}, 00283 {"Disassociation Event", &GSwifi::msgDisassociated}, 00284 {"Serial2WiFi APP", &GSwifi::msgReset}, 00285 {"UnExpected Warm Boot", &GSwifi::msgReset}, 00286 {"APP Reset-APP SW Reset", &GSwifi::msgReset}, 00287 {"APP Reset-Wlan Except", &GSwifi::msgReset}, 00288 {"Out of StandBy-Timer", &GSwifi::msgOutofStandby}, 00289 {"Out of StandBy-Alarm", &GSwifi::msgOutofStandby}, 00290 {"Out of Deep Sleep", &GSwifi::msgOutofDeepsleep}, 00291 {"DataInterfaceReady", &GSwifi::msgDataInterfaceReady}, 00292 }; 00293 static const struct RES_TABLE { 00294 const Response res; 00295 void (GSwifi::*func)(const char*); 00296 } res_table[RES_TABLE_NUM] = { 00297 {RES_NULL, NULL}, 00298 {RES_CONNECT, &GSwifi::resConnect}, 00299 {RES_WPAPSK, &GSwifi::resWpapsk}, 00300 {RES_WPS, &GSwifi::resWps}, 00301 {RES_MACADDRESS, &GSwifi::resMacAddress}, 00302 {RES_DHCP, &GSwifi::resIp}, 00303 {RES_DNSLOOKUP, &GSwifi::resLookup}, 00304 {RES_HTTP, &GSwifi::resHttp}, 00305 {RES_RSSI, &GSwifi::resRssi}, 00306 {RES_TIME, &GSwifi::resTime}, 00307 {RES_STATUS, &GSwifi::resStatus}, 00308 }; 00309 00310 for (i = 0; i < sizeof(buf); i++) { 00311 if (_state.buf->dequeue(&buf[i]) == false) break; 00312 } 00313 buf[i] = 0; 00314 00315 if (_state.res != RES_NULL) { 00316 for (i = 0; i < RES_TABLE_NUM; i ++) { 00317 if (res_table[i].res == _state.res) { 00318 DBG("parse res %d '%s'\r\n", i, buf); 00319 if (res_table[i].func != NULL) { 00320 (this->*(res_table[i].func))(buf); 00321 } 00322 } 00323 } 00324 } 00325 00326 for (i = 0; i < MSG_TABLE_NUM; i ++) { 00327 if (strncmp(buf, msg_table[i].msg, strlen(msg_table[i].msg)) == 0) { 00328 DBG("parse msg %d '%s'\r\n", i, buf); 00329 if (msg_table[i].func != NULL) { 00330 (this->*(msg_table[i].func))(buf); 00331 } 00332 return 0; 00333 } 00334 } 00335 00336 return -1; 00337 } 00338 00339 void GSwifi::msgOk (const char *buf) { 00340 _state.ok = true; 00341 if (_state.status == STAT_DEEPSLEEP) { 00342 _state.status = STAT_READY; 00343 } 00344 } 00345 00346 void GSwifi::msgError (const char *buf) { 00347 _state.failure = true; 00348 } 00349 00350 void GSwifi::msgConnect (const char *buf) { 00351 int i, count; 00352 int cid, acid; 00353 00354 if (buf[8] < '0' || buf[8] > 'F' || buf[9] != ' ') return; 00355 00356 cid = x2i(buf[8]); 00357 acid = x2i(buf[10]); 00358 DBG("forked %d -> %d\r\n", cid, acid); 00359 // ip 00360 count = 0; 00361 for (i = 12; i < strlen(buf); i ++) { 00362 if ((buf[i] >= '0' && buf[i] <= '9') || buf[i] == '.') { 00363 _con[acid].ip[count] = buf[i]; 00364 count ++; 00365 } else { 00366 _con[acid].ip[count] = 0; 00367 break; 00368 } 00369 } 00370 // port 00371 _con[acid].port = 0; 00372 count = 0; 00373 for (; i < strlen(buf); i ++) { 00374 if (buf[i] >= '0' && buf[i] <= '9') { 00375 _con[acid].port = (_con[acid].port * 10) + (buf[i] - '0'); 00376 } else { 00377 break; 00378 } 00379 } 00380 00381 // initialize 00382 initCon(acid, true); 00383 _con[acid].protocol = _con[cid].protocol; 00384 _con[acid].type = _con[cid].type; 00385 _con[acid].parent = cid; 00386 _con[acid].func = _con[cid].func; 00387 _con[acid].accept = true; 00388 00389 #ifdef CFG_ENABLE_HTTPD 00390 if (_con[acid].protocol == PROTO_HTTPD) { 00391 _httpd[acid].mode = HTTPDMODE_REQUEST; 00392 #ifdef CFG_ENABLE_WEBSOCKET 00393 _httpd[acid].websocket = 0; 00394 #endif 00395 } 00396 #endif 00397 } 00398 00399 void GSwifi::msgDisconnect (const char *buf) { 00400 int cid; 00401 00402 if (buf[11] < '0' || buf[11] > 'F') return; 00403 00404 cid = x2i(buf[11]); 00405 DBG("disconnect %d\r\n", cid); 00406 _con[cid].connected = false; 00407 } 00408 00409 void GSwifi::msgDisassociated (const char *buf) { 00410 int i; 00411 DBG("disassociate\r\n"); 00412 _state.associated = false; 00413 for (i = 0; i < 16; i ++) { 00414 _con[i].connected = false; 00415 } 00416 #ifdef CFG_ENABLE_RTOS 00417 if (_threadPoll) 00418 _threadPoll->signal_set(1); 00419 #endif 00420 } 00421 00422 void GSwifi::msgReset (const char *buf) { 00423 DBG("reset\r\n"); 00424 _state.initialized = false; 00425 _state.mode = MODE_COMMAND; 00426 _state.status = STAT_READY; 00427 msgDisassociated(NULL); 00428 clearFlags(); 00429 #ifdef CFG_ENABLE_RTOS 00430 if (_threadPoll) { 00431 _threadPoll->terminate(); 00432 delete _threadPoll; 00433 } 00434 #endif 00435 } 00436 00437 void GSwifi::msgOutofStandby (const char *buf) { 00438 DBG("OutofStandby\r\n"); 00439 _state.status = STAT_WAKEUP; 00440 } 00441 00442 void GSwifi::msgOutofDeepsleep (const char *buf) { 00443 DBG("OutofDeepsleep\r\n"); 00444 _state.status = STAT_READY; 00445 } 00446 00447 void GSwifi::msgDataInterfaceReady (const char *buf) { 00448 DBG("DataInterfaceReady\r\n"); 00449 _state.datainterface = true; 00450 _state.status = STAT_READY; 00451 } 00452 00453 void GSwifi::resConnect (const char *buf) { 00454 int cid; 00455 00456 // udp/tcp listen socket 00457 if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) { 00458 cid = x2i(buf[8]); 00459 DBG("connect %d\r\n", cid); 00460 // initialize 00461 initCon(cid, true); 00462 _state.cid = cid; 00463 _state.res = RES_NULL; 00464 } 00465 } 00466 00467 void GSwifi::resWpapsk (const char *buf) { 00468 if (strncmp(buf, "Computing PSK from SSID and PassPhrase", 38) == 0) { 00469 _state.res = RES_NULL; 00470 DBG("wpapsk\r\n"); 00471 } 00472 } 00473 00474 void GSwifi::resWps (const char *buf) { 00475 if (_state.n == 0 && strncmp(buf, "SSID", 4) == 0) { 00476 strncpy(_state.ssid, &buf[5], sizeof(_state.ssid)); 00477 _state.n ++; 00478 } else 00479 if (_state.n == 1 && strncmp(buf, "CHANNEL", 7) == 0) { 00480 _state.n ++; 00481 } else 00482 if (_state.n == 2 && strncmp(buf, "PASSPHRASE", 10) == 0) { 00483 strncpy(_state.pass, &buf[11], sizeof(_state.pass)); 00484 _state.n ++; 00485 _state.res = RES_NULL; 00486 DBG("wps %s %s\r\n", _state.ssid, _state.pass); 00487 } 00488 } 00489 00490 void GSwifi::resMacAddress (const char *buf) { 00491 if (buf[2] == ':' && buf[5] == ':') { 00492 strncpy(_state.mac, buf, sizeof(_state.mac)); 00493 _state.mac[17] = 0; 00494 _state.res = RES_NULL; 00495 DBG("mac %s\r\n", _state.mac); 00496 } 00497 } 00498 00499 void GSwifi::resIp (const char *buf) { 00500 const char *tmp, *tmp2; 00501 00502 if (_state.n == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) { 00503 _state.n ++; 00504 } else 00505 if (_state.n == 1 && buf[0] == ' ') { 00506 tmp = buf + 1; 00507 tmp2 = strstr(tmp, ":"); 00508 strncpy(_state.ip, tmp, tmp2 - tmp); 00509 tmp = tmp2 + 1; 00510 tmp2 = strstr(tmp, ":"); 00511 strncpy(_state.netmask, tmp, tmp2 - tmp); 00512 tmp = tmp2 + 1; 00513 strncpy(_state.gateway, tmp, sizeof(_state.gateway)); 00514 _state.n ++; 00515 _state.res = RES_NULL; 00516 DBG("ip: %s\r\nnetmask: %s\r\ngateway: %s", _state.ip, _state.netmask, _state.gateway); 00517 } 00518 } 00519 00520 void GSwifi::resLookup (const char *buf) { 00521 if (strncmp(buf, "IP:", 3) == 0) { 00522 strncpy(_state.resolv, &buf[3], sizeof(_state.resolv)); 00523 _state.res = RES_NULL; 00524 DBG("resolv: %s\r\n", _state.resolv); 00525 } 00526 } 00527 00528 void GSwifi::resRssi (const char *buf) { 00529 if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) { 00530 _state.rssi = atoi(buf); 00531 _state.res = RES_NULL; 00532 DBG("rssi: %d\r\n", _state.rssi); 00533 } 00534 } 00535 00536 void GSwifi::resTime (const char *buf) { 00537 int year, month, day, hour, min, sec; 00538 struct tm t; 00539 if (buf[0] >= '0' && buf[0] <= '9') { 00540 sscanf(buf, "%d/%d/%d,%d:%d:%d", &day, &month, &year, &hour, &min, &sec); 00541 t.tm_sec = sec; 00542 t.tm_min = min; 00543 t.tm_hour = hour; 00544 t.tm_mday = day; 00545 t.tm_mon = month - 1; 00546 t.tm_year = year - 1900; 00547 _state.time = mktime(&t); 00548 _state.res = RES_NULL; 00549 } 00550 } 00551 00552 void GSwifi::resChannel (const char *buf) { 00553 } 00554 00555 void GSwifi::resStatus (const char *buf) { 00556 if (_state.n == 0 && strncmp(buf, "NOT ASSOCIATED", 14) == 0) { 00557 msgDisassociated(NULL); 00558 _state.res = RES_NULL; 00559 } 00560 00561 if (_state.n == 0 && strncmp(buf, "MODE:", 5) == 0) { 00562 _state.n ++; 00563 } else 00564 if (_state.n == 1 && strncmp(buf, "BSSID:", 6) == 0) { 00565 const char *tmp = strstr(buf, "SECURITY:") + 2; 00566 if (strncmp(tmp, "WEP (OPEN)", 10) == NULL) { 00567 _state.sec = SEC_OPEN; 00568 } else 00569 if (strncmp(tmp, "WEP (SHARED)", 12) == NULL) { 00570 _state.sec = SEC_WEP; 00571 } else 00572 if (strncmp(tmp, "WPA-PERSONAL", 12) == NULL) { 00573 _state.sec = SEC_WPA_PSK; 00574 } else 00575 if (strncmp(tmp, "WPA2-PERSONAL", 13) == NULL) { 00576 _state.sec = SEC_WPA2_PSK; 00577 } 00578 _state.res = RES_NULL; 00579 } 00580 } 00581 00582 void GSwifi::resHttp (const char *buf) { 00583 int cid; 00584 00585 // http client socket 00586 if (buf[0] >= '0' && buf[0] <= 'F' && buf[1] == 0) { 00587 cid = x2i(buf[0]); 00588 DBG("connect %d\r\n", cid); 00589 // initialize 00590 initCon(cid, true); 00591 _state.cid = cid; 00592 _state.res = RES_NULL; 00593 } 00594 }
Generated on Thu Jul 14 2022 07:53:37 by 1.7.2