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 mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GSwifi_msg.cpp Source File

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 }