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

GainSpan Wi-Fi library

The GS1011/GS2100 is an ultra low power 802.11b wireless module from GainSpan.

mbed RTOS supported.

/media/uploads/gsfan/gs_im_002.jpg /media/uploads/gsfan/gs1011m_2.jpg

ゲインスパン Wi-Fi モジュール ライブラリ

ゲインスパン社の低電力 Wi-Fiモジュール(無線LAN) GS1011/GS2100 シリーズ用のライブラリです。

mbed RTOS に対応しています。(mbed2.0)

Revision:
8:64184a968e3b
Child:
11:71d67fea5ace
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GSwifi/GSwifi_msg.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -0,0 +1,510 @@
+/* Copyright (C) 2013 gsfan, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "GSwifi.h"
+
+#ifdef RTOS_H
+#undef DBG
+#define DBG(x, ...)
+#endif
+
+void GSwifi::recvData (char c) {
+    static int sub, len, count;
+
+#ifdef DEBUG_DUMP
+    if (c < 0x20) {
+        DBG("%02x_", c);
+    } else {
+        DBG("%c_", c);
+    }
+#endif
+    switch (_state.mode) {
+    case MODE_COMMAND:
+        switch (c) {
+        case 0:
+        case 0x0a: // LF
+        case 0x0d: // CR
+            break;
+        case 0x1b: // ESC
+            _state.buf->flush();
+            _state.mode = MODE_ESCAPE;
+            break;
+        default:
+            _state.buf->flush();
+            _state.buf->queue(c);
+            _state.mode = MODE_CMDRESP;
+            break;
+        }
+        break;
+    
+    case MODE_CMDRESP:
+        switch (c) {
+        case 0:
+            break;
+        case 0x0a: // LF
+        case 0x0d: // CR
+//            _state.buf->queue(c);
+            parseMessage();
+            _state.mode = MODE_COMMAND;
+            break;
+        case 0x1b: // ESC
+            _state.mode = MODE_ESCAPE;
+            break;
+        default:
+            _state.buf->queue(c);
+            break;
+        }
+        break;
+
+    case MODE_ESCAPE:
+        sub = 0;
+        switch (c) {
+        case 'H':
+            _state.mode = MODE_DATA_RXHTTP;
+            break;
+        case 'u':
+            _state.mode = MODE_DATA_RXUDP;
+            break;
+        case 'y':
+            _state.mode = MODE_DATA_RXUDP_BULK;
+            break;
+        case 'Z':
+            _state.mode = MODE_DATA_RX_BULK;
+            break;
+        case 'S':
+            _state.mode = MODE_DATA_RX;
+            break;
+        case ':':
+            _state.mode = MODE_DATA_RAW;
+            break;
+        case 'O':
+            _state.mode = MODE_COMMAND;
+            _state.ok = true;
+            return;
+        case 'F':
+            _state.mode = MODE_COMMAND;
+            _state.failure = true;
+            return;
+        default:
+            _state.mode = MODE_COMMAND;
+            return;
+        }
+        break;
+    
+    case MODE_DATA_RX:
+    case MODE_DATA_RXUDP:
+        switch (sub) {
+        case 0:
+            // cid
+            _state.cid = x2i(c);
+            sub ++;
+            count = 0;
+            if (_state.mode == MODE_DATA_RX) {
+                sub = 3;
+            }
+            break;
+        case 1:
+            // ip
+            if ((c >= '0' && c <= '9') || c == '.') {
+                _con[_state.cid].ip[count] = c;
+                count ++;
+            } else {
+                _con[_state.cid].ip[count] = 0;
+                _con[_state.cid].port = 0;
+                sub ++;
+            }
+            break;
+        case 2:
+            // port
+            if (c >= '0' && c <= '9') {
+                _con[_state.cid].port = (_con[_state.cid].port * 10) + (c - '0'); 
+            } else {
+                sub ++;
+                count = 0;
+            }
+            break;            
+        default:
+            // data
+            if (_state.escape) {
+                if (c == 'E') {
+                    DBG("recv ascii %d %d/a\r\n", _state.cid, count);
+                    _con[_state.cid].received = true;
+                    _state.mode = MODE_COMMAND;
+                } else {
+                    if (_con[_state.cid].buf != NULL) {
+                        _con[_state.cid].buf->queue(0x1b);
+                        _con[_state.cid].buf->queue(c);
+                    }
+                    count += 2;
+                }
+                _state.escape = false;
+            } else
+            if (c == 0x1b) {
+                _state.escape = true;
+            } else {
+                if (_con[_state.cid].buf != NULL) {
+                    _con[_state.cid].buf->queue(c);
+                    if (_con[_state.cid].buf->available() > CFG_DATA_SIZE - 16) {
+                        setRts(false);
+                        _con[_state.cid].received = true;
+                    }
+                }
+                count ++;
+            }
+            break;
+        }
+        break;
+    
+    case MODE_DATA_RX_BULK:
+    case MODE_DATA_RXUDP_BULK:
+    case MODE_DATA_RXHTTP:
+        switch (sub) {
+        case 0:
+            // cid
+            _state.cid = x2i(c);
+            sub ++;
+            len = 0;
+            count = 0;
+            if (_state.mode == MODE_DATA_RX_BULK) {
+                sub = 3;
+            }
+            break;
+        case 1:
+            // ip
+            if ((c >= '0' && c <= '9') || c == '.') {
+                _con[_state.cid].ip[count] = c;
+                count ++;
+            } else {
+                _con[_state.cid].ip[count] = 0;
+                _con[_state.cid].port = 0;
+                sub ++;
+            }
+            break;
+        case 2:
+            // port
+            if (c >= '0' && c <= '9') {
+                _con[_state.cid].port = (_con[_state.cid].port * 10) + (c - '0'); 
+            } else {
+                sub ++;
+                count = 0;
+            }
+            break;
+        case 3:
+            // length
+            len = (len * 10) + (c - '0');
+            count ++;
+            if (count >= 4) {
+                sub ++;
+                count = 0;
+            }
+            break;
+        default:
+            // data
+            if (_con[_state.cid].buf != NULL) {
+                _con[_state.cid].buf->queue(c);
+                if (_con[_state.cid].buf->available() > CFG_DATA_SIZE - 16) {
+                    setRts(false);
+                    _con[_state.cid].received = true;
+                }
+            }
+            count ++;
+            if (count >= len) {
+                DBG("recv bulk %d %d/%d\r\n", _state.cid, count, len);
+                _con[_state.cid].received = true;
+                _state.mode = MODE_COMMAND;
+            }
+            break;
+        }
+        break;
+    }
+}
+
+int GSwifi::parseMessage () {
+    int i;
+    char buf[256];
+    static const struct MSG_TABLE {
+        const char msg[24];
+        void (GSwifi::*func)(const char*);
+    } msg_table[MSG_TABLE_NUM] = {
+      {"OK",                      &GSwifi::msgOk},
+      {"ERROR",                   &GSwifi::msgError},
+      {"INVALID INPUT",           &GSwifi::msgError},
+      {"CONNECT ",                &GSwifi::msgConnect},
+      {"DISCONNECT ",             &GSwifi::msgDisconnect},
+      {"DISASSOCIATED",           &GSwifi::msgDisassociated},
+      {"Disassociated",           &GSwifi::msgDisassociated},
+      {"Disassociation Event",    &GSwifi::msgDisassociated},
+      {"Serial2WiFi APP",         &GSwifi::msgReset},
+      {"UnExpected Warm Boot",    &GSwifi::msgReset},
+      {"APP Reset-APP SW Reset",  &GSwifi::msgReset},
+      {"APP Reset-Wlan Except",   &GSwifi::msgReset},
+      {"Out of StandBy-Timer",    &GSwifi::msgOutofStandby},
+      {"Out of StandBy-Alarm",    &GSwifi::msgOutofStandby},
+      {"Out of Deep Sleep",       &GSwifi::msgOutofDeepsleep},
+    };
+    static const struct RES_TABLE {
+        const Response res;
+        void (GSwifi::*func)(const char*);
+    } res_table[RES_TABLE_NUM] = {
+      {RES_NULL,        NULL},
+      {RES_CONNECT,     &GSwifi::resConnect},
+      {RES_WPS,         &GSwifi::resWps},
+      {RES_MACADDRESS,  &GSwifi::resMacAddress},
+      {RES_DHCP,        &GSwifi::resIp},
+      {RES_DNSLOOKUP,   &GSwifi::resLookup},
+      {RES_HTTP,        &GSwifi::resConnect},
+      {RES_RSSI,        &GSwifi::resRssi},
+      {RES_TIME,        &GSwifi::resTime},
+      {RES_STATUS,      &GSwifi::resStatus},
+    };
+
+    for (i = 0; i < sizeof(buf); i++) {
+        if (_state.buf->dequeue(&buf[i]) == false) break;
+    }
+    buf[i] = 0;
+
+    if (_state.res != RES_NULL) {
+      for (i = 0; i < RES_TABLE_NUM; i ++) {
+        if (res_table[i].res == _state.res) {
+            DBG("parse res %d '%s'\r\n", i, buf);
+            if (res_table[i].func != NULL) {
+                (this->*(res_table[i].func))(buf);
+            }
+        }
+      }
+    }
+
+    for (i = 0; i < MSG_TABLE_NUM; i ++) {
+        if (strncmp(buf, msg_table[i].msg, strlen(msg_table[i].msg)) == 0) {
+            DBG("parse msg %d '%s'\r\n", i, buf);
+            if (msg_table[i].func != NULL) {
+                (this->*(msg_table[i].func))(buf);
+            }
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+void GSwifi::msgOk (const char *buf) {
+    _state.ok = true;
+}
+
+void GSwifi::msgError (const char *buf) {
+    _state.failure = true;
+}
+
+void GSwifi::msgConnect (const char *buf) {
+    int i, count;
+
+    if (buf[8] < '0' || buf[8] > 'F' || buf[9] != ' ') return;
+
+    _state.cid = x2i(buf[8]);
+    _state.acid = x2i(buf[10]);
+    DBG("connect %d -> %d\r\n", _state.cid, _state.acid);
+    // ip
+    count = 0;
+    for (i = 12; i < strlen(buf); i ++) {
+        if ((buf[i] >= '0' && buf[i] <= '9') || buf[i] == '.') {
+            _con[_state.acid].ip[count] = buf[i];
+            count ++;
+        } else {
+            _con[_state.acid].ip[count] = 0;
+            break;
+        }
+    }
+    // port
+    _con[_state.acid].port = 0;
+    count = 0;
+    for (; i < strlen(buf); i ++) {
+        if (buf[i] >= '0' && buf[i] <= '9') {
+            _con[_state.acid].port = (_con[_state.acid].port * 10) + (buf[i] - '0'); 
+        } else {
+            break;
+        }
+    }
+
+    _con[_state.acid].protocol = _con[_state.cid].protocol;
+    _con[_state.acid].type = _con[_state.cid].type;
+    _con[_state.acid].parent = _state.cid;
+    _con[_state.acid].accept = true;
+    if (_con[_state.acid].buf == NULL)
+        _con[_state.acid].buf = new CircBuffer<char>(CFG_DATA_SIZE);
+    _con[_state.acid].buf->flush();
+    _con[_state.acid].connected = true;
+}
+
+void GSwifi::msgDisconnect (const char *buf) {
+    int cid;
+
+    if (buf[11] < '0' || buf[11] > 'F') return;
+
+    cid = x2i(buf[11]);
+    DBG("disconnect %d\r\n", cid);
+    _con[cid].connected = false;
+}
+
+void GSwifi::msgDisassociated (const char *buf) {
+    int i;
+    DBG("disassociate\r\n");
+    _state.associated = false;
+    for (i = 0; i < 16; i ++) {
+        _con[i].connected = false;
+    }
+#ifdef RTOS_H
+    if (_threadPoll)
+        _threadPoll->signal_set(1);
+#endif
+}
+
+void GSwifi::msgReset (const char *buf) {
+    _state.mode = MODE_COMMAND;
+    _state.status = STAT_READY;
+    msgDisassociated(NULL);
+}
+
+void GSwifi::msgOutofStandby (const char *buf) {
+    _state.status = STAT_WAKEUP;
+}
+
+void GSwifi::msgOutofDeepsleep (const char *buf) {
+    _state.status = STAT_READY;
+}
+
+void GSwifi::resConnect (const char *buf) {
+    if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) {
+        _state.cid = x2i(buf[8]);
+        DBG("connect %d\r\n", _state.cid);
+        _con[_state.cid].parent = -1;
+        _con[_state.cid].accept = false;
+        if (_con[_state.cid].buf == NULL)
+            _con[_state.cid].buf = new CircBuffer<char>(CFG_DATA_SIZE);
+        _con[_state.cid].buf->flush();
+        _con[_state.cid].connected = true;
+        _state.res = RES_NULL;
+        return;
+    }
+}
+
+void GSwifi::resWps (const char *buf) {
+    if (_state.n == 0 && strncmp(buf, "SSID", 4) == 0) {
+        strncpy(_state.ssid, &buf[5], sizeof(_state.ssid));
+        _state.n ++;
+    } else
+    if (_state.n == 1 && strncmp(buf, "CHANNEL", 7) == 0) {
+        _state.n ++;
+    } else
+    if (_state.n == 2 && strncmp(buf, "PASSPHRASE", 10) == 0) {
+        strncpy(_state.pass, &buf[11], sizeof(_state.pass));
+        _state.n ++;
+        _state.res = RES_NULL;
+    }
+}
+
+void GSwifi::resMacAddress (const char *buf) {
+    if (buf[2] == ':' && buf[5] == ':') {
+        strncpy(_state.mac, buf, sizeof(_state.mac));
+        _state.mac[17] = 0;
+        _state.res = RES_NULL;
+        DBG("mac: %s", _state.mac);
+    }
+}
+
+void GSwifi::resIp (const char *buf) {
+    const char *tmp, *tmp2;
+
+    if (_state.n == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) {
+        _state.n ++;
+    } else
+    if (_state.n == 1) {
+        tmp = buf + 1;
+        tmp2 = strstr(tmp, ":");
+        strncpy(_state.ip, tmp, tmp2 - tmp);
+        tmp = tmp2 + 2;
+        tmp2 = strstr(tmp, ":");
+        strncpy(_state.netmask, tmp, tmp2 - tmp);
+        tmp = tmp2 + 2;
+        strncpy(_state.gateway, tmp, sizeof(_state.gateway));
+        _state.n ++;
+        _state.res = RES_NULL;
+        DBG("ip: %s\r\nnetmask: %s\r\ngateway: %s", _state.ip, _state.netmask, _state.gateway);
+    }
+}
+
+void GSwifi::resLookup (const char *buf) {
+    if (strncmp(buf, "IP:", 3) == 0) {
+        strncpy(_state.resolv, &buf[3], sizeof(_state.resolv));
+        _state.res = RES_NULL;
+        DBG("resolv: %s", _state.resolv);
+    }
+}
+
+void GSwifi::resRssi (const char *buf) {
+    if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) {
+        _state.rssi = atoi(buf);
+        _state.res = RES_NULL;
+        DBG("rssi: %d", _state.rssi);
+    }
+}
+
+void GSwifi::resTime (const char *buf) {
+    int year, month, day, hour, min, sec;
+    struct tm t;
+    if (buf[0] >= '0' && buf[0] <= '9') {
+        sscanf(buf, "%d/%d/%d,%d:%d:%d", &day, &month, &year, &hour, &min, &sec);
+        t.tm_sec = sec;
+        t.tm_min = min;
+        t.tm_hour = hour;
+        t.tm_mday = day;
+        t.tm_mon = month - 1;
+        t.tm_year = year - 1900;   
+        _state.time = mktime(&t);            
+        _state.res = RES_NULL;
+    }
+}
+
+void GSwifi::resChannel (const char *buf) {
+}
+
+void GSwifi::resStatus (const char *buf) {
+    if (_state.n == 0 && strncmp(buf, "NOT ASSOCIATED", 14) == 0) {
+        msgDisassociated(NULL);
+        _state.res = RES_NULL;
+    }
+
+    if (_state.n == 0 && strncmp(buf, "MODE:", 5) == 0) {
+        _state.n ++;
+    } else
+    if (_state.n == 1 && strncmp(buf, "BSSID:", 6) == 0) {
+        const char *tmp = strstr(buf, "SECURITY:") + 2;
+        if (strncmp(tmp, "WEP (OPEN)", 10) == NULL) {
+            _state.sec = SEC_OPEN;
+        } else
+        if (strncmp(tmp, "WEP (SHARED)", 12) == NULL) {
+            _state.sec = SEC_WEP;
+        } else
+        if (strncmp(tmp, "WPA-PERSONAL", 12) == NULL) {
+            _state.sec = SEC_WPA_PSK;
+        } else
+        if (strncmp(tmp, "WPA2-PERSONAL", 13) == NULL) {
+            _state.sec = SEC_WPA2_PSK;
+        }
+        _state.res = RES_NULL;
+    }
+}