GainSpan Wi-Fi library see: http://mbed.org/users/gsfan/notebook/gainspan_wifi/

Dependents:   GSwifi_httpd GSwifi_websocket GSwifi_tcpclient GSwifi_tcpserver ... more

Fork of GSwifi by gs fan

GainSpan Wi-Fi library

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

see: http://mbed.org/users/gsfan/notebook/gainspan_wifi/

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

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

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

解説: http://mbed.org/users/gsfan/notebook/gainspan_wifi/

Revision:
26:b347ee3a1087
Parent:
25:f6e5622d2930
Child:
28:fbba4c58d14c
--- a/GSwifi.cpp	Mon Feb 11 06:01:46 2013 +0000
+++ b/GSwifi.cpp	Fri Feb 22 01:05:10 2013 +0000
@@ -20,7 +20,6 @@
  * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
  */
 
-#include "dbg.h"
 #include "mbed.h"
 #include "GSwifi.h"
 
@@ -28,28 +27,35 @@
 GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_reset, PinName p_alarm, int baud) : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) {
 
     if (p_alarm != NC) {
-        _alarm = new DigitalOut(p_alarm);
-        _alarm->write(1);
+        _alarm = new DigitalInOut(p_alarm);
+        _alarm->output(); // low
+        _alarm->write(0);
     } else {
         _alarm = NULL;
     }
 
+    _reset.output(); // low
+    _reset = 0;
     _gs.baud(baud);
     _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
     _rts = false;
 
+    wait_ms(500);
     reset();
 }
 
 GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, PinName p_reset, PinName p_alarm, int baud) : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) {
 
     if (p_alarm != NC) {
-        _alarm = new DigitalOut(p_alarm);
-        _alarm->write(1);
+        _alarm = new DigitalInOut(p_alarm);
+        _alarm->output(); // low
+        _alarm->write(0);
     } else {
         _alarm = NULL;
     }
 
+    _reset.output(); // low
+    _reset = 0;
     _gs.baud(baud);
     _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
@@ -82,22 +88,37 @@
     }
 #endif
 
+    wait_ms(500);
     reset();
 }
 
 void GSwifi::reset () {
+
+    if (_alarm != NULL) {
+        _alarm->output(); // low
+        _alarm->write(0);
+        wait_ms(10);
+        _alarm->input(); // high
+        _alarm->mode(PullNone);
+        wait_ms(10);
+    }
+    _reset.output(); // low
+    _reset = 0;
+
     _connect = false;
     _status = GSSTAT_READY;
     _escape = 0;
-    _response = GSRES_NONE;
+    resetResponse(GSRES_NONE);
     _gs_mode = GSMODE_COMMAND;
     _ssid = NULL;
+    _pass = NULL;
     _reconnect = 0;
     _reconnect_count = 0;
+    _buf_cmd.flush();
 
-    _reset = 0;
-    wait_ms(100);
-    _reset = 1;
+    wait_ms(10);
+    _reset.input(); // high
+    _reset.mode(PullNone);
     wait_ms(500);
 }
 
@@ -116,7 +137,11 @@
     
     if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) return;
 #ifdef DEBUG_VIEW
-    DBG("_%02x", dat);
+    if (dat >= 0x20 && dat < 0x7f) {
+        DBG("%c_", dat);
+    } else {
+        DBG("%02x_", dat);
+    }
 #endif
 
     switch (_gs_mode) {
@@ -126,11 +151,11 @@
             switch (dat) {
             case 'O':
                 DBG("ok\r\n");
-                _gs_ok = 1;
+                _gs_ok = true;
                 break;
             case 'F':
                 DBG("failure\r\n");
-                _gs_failure = 1;
+                _gs_failure = true;
                 break;
             case 'S':
                 DBG("GSMODE_DATA_RX\r\n");
@@ -162,16 +187,13 @@
             if (dat == 0x1b) {
                 _escape = 1;
             } else
+            if (dat == '\n') {
+                // end of line
+                parseResponse();
+            } else
             if (dat != '\r') {
                 // command
                 _buf_cmd.queue(dat);
-                if (dat == '\n') {
-                    _gs_enter ++;
-                    if (_response == GSRES_NONE && _connect) {
-                        DBG("poll_cmd\r\n");
-                        poll_cmd();
-                    }
-                }
             }
         }
         break;
@@ -181,7 +203,7 @@
         if (mode == 0) {
             // cid
             _cid = x2i(dat);
-            _gs_sock[_cid].received = 0;
+            _gs_sock[_cid].received = false;
             mode ++;
             if (_gs_mode == GSMODE_DATA_RX) {
                 mode = 3;
@@ -219,12 +241,13 @@
             switch (dat) {
             case 'E':
                 DBG("recv ascii %d\r\n", _cid);
-                _gs_sock[_cid].received = 1;
+                _gs_sock[_cid].received = true;
                 _gs_mode = GSMODE_COMMAND;
-                // recv interrupt
-                if (_gs_sock[_cid].protocol == GSPROT_HTTPGET && _gs_sock[_cid].onGsReceive != NULL) {
-                    _gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
-                    _gs_sock[_cid].received = 0;
+
+                if (_gs_sock[_cid].protocol == GSPROT_HTTPGET) {
+                    // recv interrupt
+                    if (_gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->use()) == 0)
+                        _gs_sock[_cid].received = false;
                 }
                 break;
             default:
@@ -239,11 +262,11 @@
                 // data
                 _gs_sock[_cid].data->queue(dat);
                 len ++;
-                if (len < GS_DATA_SIZE && _gs_sock[_cid].data->available() == 0) {
+
+                if (len < GS_DATA_SIZE && _gs_sock[_cid].data->isFull()) {
                     // buffer full
-                    if (_gs_sock[_cid].onGsReceive != NULL) {
-                        _gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
-                    }
+                    // recv interrupt
+                    _gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->use());
                 }
             }
         }
@@ -254,7 +277,7 @@
         if (mode == 0) {
             // cid
             _cid = x2i(dat);
-            _gs_sock[_cid].received = 0;
+            _gs_sock[_cid].received = false;
             mode ++;
             if (_gs_mode == GSMODE_DATA_RX_BULK) {
                 mode = 3;
@@ -304,21 +327,22 @@
                 _gs_sock[_cid].data->queue(dat);
             }
             len  --;
-            if (len && _gs_sock[_cid].data->available() == 0) {
+
+            if (len && _gs_sock[_cid].data->isFull()) {
                 // buffer full
-                if (_gs_sock[_cid].onGsReceive != NULL) {
-                    _gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
-                }
+                // recv interrupt
+                _gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->use());
             }
             if (len == 0) {
                 DBG("recv binary %d\r\n", _cid);
-                _gs_sock[_cid].received = 1;
+                _gs_sock[_cid].received = true;
                 _escape = 0;
                 _gs_mode = GSMODE_COMMAND;
-                // recv interrupt
-                if (_gs_sock[_cid].protocol == GSPROT_HTTPGET && _gs_sock[_cid].onGsReceive != NULL) {
-                    _gs_sock[_cid].onGsReceive(_cid, _gs_sock[_cid].data->use());
-                    _gs_sock[_cid].received = 0;
+
+                if (_gs_sock[_cid].protocol == GSPROT_HTTPGET) {
+                    // recv interrupt
+                    if (_gs_sock[_cid].onGsReceive.call(_cid, _gs_sock[_cid].data->use()) == 0)
+                        _gs_sock[_cid].received = false;
                 }
             }
         }
@@ -328,24 +352,21 @@
 }
 
 int GSwifi::command (const char *cmd, GSRESPONCE res, int timeout) {
-    int i, r = 0;
+    int i;
 
-    if (! cmd) {
+    if (cmd == NULL) {
         // dummy CR+LF
+printf("1\r\n");
         _gs.printf("\r\n");
-        for (i = 0; i < 10; i ++) {
-            wait_ms(10);
-            poll_cmd();
-            _buf_cmd.flush();
-        }
+printf("2\r\n");
+        wait_ms(100);
+printf("3\r\n");
+        _buf_cmd.flush();
+printf("4\r\n");
         return 0;
     }
 
-    _response = res;
-    _buf_cmd.flush();
-    _gs_ok = 0;
-    _gs_failure = 0;
-    _gs_enter = 0;
+    resetResponse(res);
     for (i = 0; i < strlen(cmd); i ++) {
         _gs_putc(cmd[i]);
     }
@@ -353,151 +374,38 @@
     _gs_putc('\n');
     DBG("command: %s\r\n", cmd);
     if (strlen(cmd) == 0) return 0;
-//    wait_ms(10);
-    if (timeout) {
-        r = cmdResponse(res, timeout);
-    }
-    _response = GSRES_NONE;
-    return r;
+
+    return waitResponse(timeout);
 }
 
-int GSwifi::cmdResponse (GSRESPONCE res, int ms) {
-    int i, n = 0, flg = 0;
-    char buf[GS_CMD_SIZE];
+void GSwifi::resetResponse (GSRESPONCE res) {
+    _gs_ok = false;
+    _gs_failure = false;
+    _gs_flg = 0;
+    _gs_res = res;
+}
+
+int GSwifi::waitResponse (int ms) {
     Timer timeout;
 
+    if (! ms) return 0;
+
     timeout.start();
     for (;;) {
-        // recv response
-        i = 0;
-        while (i < sizeof(buf)) {
-            if (! _buf_cmd.isEmpty()) {
-                _buf_cmd.dequeue(&buf[i]);
-                if (buf[i] == '\n') {
-                    break;
-                }
-                i ++;
-            }
-            if (timeout.read_ms() > ms) {
-                timeout.stop();
-                DBG("timeout\r\n");
-                return -1;
-            }
-        }
-        _gs_enter = 0;
-        if (i == 0) continue;
-        buf[i] = 0;
-        DBG("response: %s\r\n", buf);
-        timeout.stop();
-
-        if (strcmp(buf, "OK") == 0) {
-            _gs_ok = 1;
-        } else
-        if (strncmp(buf, "ERROR", 5) == 0) {
-            _gs_failure = 1;
-        }
-
-        switch(res) {
-        case GSRES_NORMAL:
-            flg = 1;
-            break;
-        case GSRES_WPS:
-            if (n == 0 && strncmp(buf, "SSID", 4) == 0) {
-                n ++;
-            } else
-            if (n == 1 && strncmp(buf, "CHANNEL", 7) == 0) {
-                n ++;
-            } else
-            if (n == 2 && strncmp(buf, "PASSPHRASE", 10) == 0) {
-                n ++;
-                flg = 1;
-            }
-            break;
-        case GSRES_CONNECT:
-            if (strncmp(buf, "CONNECT ", 8) == 0) {
-                _cid = x2i(buf[8]);
-                flg = 1;
-            }
-            break;
-        case GSRES_DHCP:
-            if (n == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) {
-                n ++;
-            } else
-            if (n == 1) {
-                int ip1, ip2, ip3, ip4;
-                char *tmp = buf + 1;
-                sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
-                _ipaddr = IpAddr(ip1, ip2, ip3, ip4);
-                tmp = strstr(tmp, ":") + 2;
-                sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
-                _netmask = IpAddr(ip1, ip2, ip3, ip4);
-                tmp = strstr(tmp, ":") + 2;
-                sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
-                _gateway = IpAddr(ip1, ip2, ip3, ip4);
-                n ++;
-                flg = 1;
-            }
-            break;
-        case GSRES_MACADDRESS:
-            if (buf[2] == ':' && buf[5] == ':') {
-                int mac1, mac2, mac3, mac4, mac5, mac6;
-                sscanf(buf, "%x:%x:%x:%x:%x:%x", &mac1, &mac2, &mac3, &mac4, &mac5, &mac6);
-                _mac[0] = mac1;
-                _mac[1] = mac2;
-                _mac[2] = mac3;
-                _mac[3] = mac4;
-                _mac[4] = mac5;
-                _mac[5] = mac6;
-                flg = 1;
-            }
-            break;
-        case GSRES_DNSLOOKUP:
-            if (strncmp(buf, "IP:", 3) == 0) {
-                int ip1, ip2, ip3, ip4;
-                sscanf(&buf[3], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
-                _resolv = IpAddr(ip1, ip2, ip3, ip4);
-                flg = 1;
-            }
-            break;
-        case GSRES_HTTP:
-            if (buf[0] >= '0' && buf[0] <= 'F') {
-                _cid = x2i(buf[0]);
-                flg = 1;
-            }
-            break;
-        case GSRES_RSSI:
-            if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) {
-                _rssi = atoi(buf);
-                flg = 1;
-            }
-            break;
-        case GSRES_TIME:
-            if (buf[0] >= '0' && buf[0] <= '9') {
-                int year, month, day, hour, min, sec;
-                struct tm t;
-                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;   
-                _time = mktime(&t);            
-                flg = 1;
-            }
+        if (timeout.read_ms() > ms) {
+            DBG("timeout\r\n");
             break;
         }
-        
-        if ((flg && _gs_ok) || _gs_failure) break;
-        timeout.reset();
-        timeout.start();
+        if (_gs_ok && (_gs_flg == -1 || _gs_res == GSRES_NONE)) {
+            timeout.stop();
+            _gs_res = GSRES_NONE;
+            return 0;
+        }
+        if (_gs_failure) break;
     }
-
-    if (_gs_failure || flg == 0) {
-        return -1;
-    } else {
-        return 0;
-    }
+    timeout.stop();
+    _gs_res = GSRES_NONE;
+    return -1;
 }
 
 int GSwifi::connect (GSSECURITY sec, const char *ssid, const char *pass, int dhcp, int reconnect) {
@@ -541,6 +449,7 @@
         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
         if (r) {
             DBG("retry\r\n");
+            wait_ms(1000);
             r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
         }
         break;
@@ -556,6 +465,7 @@
         r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
         if (r) {
             DBG("retry\r\n");
+            wait_ms(1000);
             r = command(cmd, GSRES_DHCP, GS_TIMEOUT2);
         }
         break;
@@ -655,7 +565,7 @@
 #endif
 
     command("AT+WM=2", GSRES_NORMAL); // limited ap
-    wait_ms(1000);
+    wait_ms(100);
     command("AT+NDHCP=0", GSRES_NORMAL);
     setAddress(ipaddr, netmask, ipaddr, ipaddr);
     if (command("AT+DHCPSRVR=1", GSRES_NORMAL)) return -1;
@@ -744,6 +654,11 @@
     return 0;
 }
 
+int GSwifi::getMac (char *mac) {
+    memcpy(mac, _mac, 6);
+    return 0;
+}
+
 int GSwifi::getHostByName (const char* name, IpAddr &addr) {
     char cmd[GS_CMD_SIZE];
 
@@ -789,20 +704,23 @@
 }
 
 int GSwifi::standby (int msec) {
+    int i;
     char cmd[GS_CMD_SIZE];
 
     if (_status != GSSTAT_READY && _status != GSSTAT_WAKEUP) return -1;
 
-    if (_status != GSSTAT_WAKEUP) {
+    if (_status == GSSTAT_READY) {
         command("AT+WRXACTIVE=0", GSRES_NORMAL);
         command("AT+STORENWCONN", GSRES_NORMAL);
     } else {
         command("ATE0", GSRES_NORMAL);
         if (_rts) {
-            command("AT&K0", GSRES_NORMAL);
             command("AT&R1", GSRES_NORMAL);
         }
     }
+    for (i = 0; i < 16; i ++) {
+        _gs_sock[i].connect = false;
+    }
     _status = GSSTAT_STANDBY;
     sprintf(cmd, "AT+PSSTBY=%d,0,0,0", msec); // go standby
     return command(cmd, GSRES_NORMAL, 0);
@@ -810,22 +728,23 @@
 
 int GSwifi::wakeup () {
 
-    if (_status == GSSTAT_STANDBY && _alarm) {
+    if (_status == GSSTAT_STANDBY && _alarm != NULL) {
         Timer timeout;
+        _alarm->output(); // low
         _alarm->write(0);
         timeout.start();
         while (_status != GSSTAT_WAKEUP && timeout.read() < GS_TIMEOUT) {
             poll();
         }
         timeout.stop();
-        _alarm->write(1);
+        _alarm->input(); // high
+        _alarm->mode(PullNone);
     }
 
     if (_status == GSSTAT_WAKEUP) {
         _status = GSSTAT_READY;
         command("ATE0", GSRES_NORMAL);
         if (_rts) {
-            command("AT&K0", GSRES_NORMAL);
             command("AT&R1", GSRES_NORMAL);
         }
 #ifdef GS_BULK
@@ -914,15 +833,12 @@
     return command(cmd, GSRES_NORMAL);
 }
 
-void GSwifi::poll_cmd () {
+void GSwifi::parseResponse () {
     int i;
+    char buf[GS_CMD_SIZE];
 
-    while (_gs_enter) {
+    while (! _buf_cmd.isEmpty()) {
         // received "\n"
-        char buf[GS_CMD_SIZE];
-
-//        wait_ms(10);
-        _gs_enter --;
         i = 0;
         while ((! _buf_cmd.isEmpty()) && i < sizeof(buf)) {
             _buf_cmd.dequeue(&buf[i]);
@@ -931,54 +847,42 @@
             }
             i ++;
         }
+        if (i == 0) continue;
         buf[i] = 0;
-        DBG("poll: %d %s\r\n", _gs_enter, buf);
+        DBG("parseResponse: %s\r\n", buf);
 
-        if (i == 0) {
-        } else
-        if (strncmp(buf, "CONNECT", 7) == 0 && buf[8] >= '0' && buf[8] <= 'F') {
+        parseCmdResponse(buf);
+
+        if (strncmp(buf, "CONNECT ", 8) == 0 && buf[8] >= '0' && buf[8] <= 'F' && buf[9] != 0) {
             int cid = x2i(buf[8]);
             if (_gs_sock[cid].type == GSTYPE_SERVER) {
+                // fork (server socket)
                 int acid, ip1, ip2, ip3, ip4;
                 char *tmp = buf + 12;
 
                 acid = x2i(buf[10]);
                 DBG("connect %d -> %d\r\n", cid, acid);
-                newSock(acid, _gs_sock[cid].type, _gs_sock[cid].protocol, _gs_sock[cid].onGsReceive);
+                newSock(acid, _gs_sock[cid].type, _gs_sock[cid].protocol);
+                _gs_sock[acid].onGsReceive = _gs_sock[cid].onGsReceive;
                 _gs_sock[acid].lcid = cid;
                 sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
                 _gs_sock[acid].host.setIp(IpAddr(ip1, ip2, ip3, ip4));
                 tmp = strstr(tmp, " ") + 1;
                 _gs_sock[acid].host.setPort(atoi(tmp));
-
-#ifdef GS_USE_HTTPD
-                if (_gs_sock[acid].protocol == GSPROT_HTTPD) {
-                    poll_httpd(acid, 0);
-                } else
-#endif
-                if (_gs_sock[acid].onGsReceive != NULL) {
-                    _gs_sock[acid].onGsReceive(acid, 0); // event connected
-                }
+                _gs_sock[acid].onGsReceive.call(acid, 0); // event connected
             }
         } else
-        if (strncmp(buf, "DISCONNECT", 10) == 0) {
+        if (strncmp(buf, "DISCONNECT ", 11) == 0) {
             int cid = x2i(buf[11]);
             DBG("disconnect %d\r\n", cid);
             _gs_sock[cid].connect = false;
-
-#ifdef GS_USE_HTTPD
-            if (_gs_sock[cid].protocol == GSPROT_HTTPD) {
-                poll_httpd(cid, 0);
-            } else
-#endif
-            if (_gs_sock[cid].onGsReceive != NULL) {
-                _gs_sock[cid].onGsReceive(cid, 0); // event disconnected
-            }
+            _gs_sock[cid].onGsReceive.call(cid, -1); // event disconnected
         } else
         if (strncmp(buf, "DISASSOCIATED", 13) == 0 ||
           strncmp(buf, "Disassociated", 13) == 0 ||
           strncmp(buf, "Disassociation Event", 20) == 0 ||
-          strncmp(buf, "UnExpected Warm Boot", 20) == 0) {
+          strncmp(buf, "UnExpected Warm Boot", 20) == 0 ||
+          strncmp(buf, "APP Reset-Wlan Except", 21) == 0 ) {
             _connect = false;
             for (i = 0; i < 16; i ++) {
                 _gs_sock[i].connect = false;
@@ -994,41 +898,133 @@
 //            if (_status == GSSTAT_DEEPSLEEP) {
                 _status = GSSTAT_READY;
 //            }
-        } else 
-        if (strncmp(buf, "Out of", 6) == 0) {
         }
         DBG("status: %d\r\n", _status);
     }
 }
 
+void GSwifi::parseCmdResponse (char *buf) {
+    if (_gs_res == GSRES_NONE) return;
+    DBG("cmd\r\n");
+
+    if (strcmp(buf, "OK") == 0) {
+        _gs_ok = true;
+    } else
+    if (strncmp(buf, "ERROR", 5) == 0) {
+        _gs_failure = true;
+    }
+
+    switch(_gs_res) {
+    case GSRES_NORMAL:
+        _gs_flg = -1;
+        break;
+    case GSRES_WPS:
+        if (_gs_flg == 0 && strncmp(buf, "SSID=", 5) == 0) {
+            if (!_ssid) _ssid = new char[sizeof(strlen(&buf[5])) + 1];
+            strcpy(_ssid, &buf[5]);
+            _gs_flg ++;
+        } else
+        if (_gs_flg == 1 && strncmp(buf, "CHANNEL=", 8) == 0) {
+            _gs_flg ++;
+        } else
+        if (_gs_flg == 2 && strncmp(buf, "PASSPHRASE=", 11) == 0) {
+            if (!_pass) _pass = new char[sizeof(strlen(&buf[11])) + 1];
+            strcpy(_pass, &buf[11]);
+            _gs_flg = -1;
+        }
+        break;
+    case GSRES_CONNECT:
+        if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) {
+            _cid = x2i(buf[8]);
+            _gs_flg = -1;
+        }
+        break;
+    case GSRES_DHCP:
+        if (_gs_flg == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) {
+            _gs_flg ++;
+        } else
+        if (_gs_flg == 1) {
+            int ip1, ip2, ip3, ip4;
+            char *tmp = buf + 1;
+            sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
+            _ipaddr = IpAddr(ip1, ip2, ip3, ip4);
+            tmp = strstr(tmp, ":") + 2;
+            sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
+            _netmask = IpAddr(ip1, ip2, ip3, ip4);
+            tmp = strstr(tmp, ":") + 2;
+            sscanf(tmp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
+            _gateway = IpAddr(ip1, ip2, ip3, ip4);
+            _gs_flg = -1;
+        }
+        break;
+    case GSRES_MACADDRESS:
+        if (buf[2] == ':' && buf[5] == ':') {
+            int mac1, mac2, mac3, mac4, mac5, mac6;
+            sscanf(buf, "%x:%x:%x:%x:%x:%x", &mac1, &mac2, &mac3, &mac4, &mac5, &mac6);
+            _mac[0] = mac1;
+            _mac[1] = mac2;
+            _mac[2] = mac3;
+            _mac[3] = mac4;
+            _mac[4] = mac5;
+            _mac[5] = mac6;
+            _gs_flg = -1;
+        }
+        break;
+    case GSRES_DNSLOOKUP:
+        if (strncmp(buf, "IP:", 3) == 0) {
+            int ip1, ip2, ip3, ip4;
+            sscanf(&buf[3], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
+            _resolv = IpAddr(ip1, ip2, ip3, ip4);
+            _gs_flg = -1;
+        }
+        break;
+    case GSRES_HTTP:
+        if (buf[0] >= '0' && buf[0] <= 'F') {
+            _cid = x2i(buf[0]);
+            _gs_flg = -1;
+        }
+        break;
+    case GSRES_RSSI:
+        if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) {
+            _rssi = atoi(buf);
+            _gs_flg = -1;
+        }
+        break;
+    case GSRES_TIME:
+        if (buf[0] >= '0' && buf[0] <= '9') {
+            int year, month, day, hour, min, sec;
+            struct tm t;
+            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;   
+            _time = mktime(&t);            
+            _gs_flg = -1;
+        }
+        break;
+    }
+
+    return;
+}
+
 void GSwifi::poll () {
     int i, j;
 
-    poll_cmd();
-
     for (i = 0; i < 16; i ++) {
-//        if (_gs_sock[i].connect && _gs_sock[i].received) {
-        if (_gs_sock[i].received && _gs_sock[i].data->use()) {
+        if (_gs_sock[i].received && (! _gs_sock[i].data->isEmpty())) {
             // recv interrupt
-            _gs_sock[i].received = 0;
-#ifdef GS_USE_HTTPD
-            if (_gs_sock[i].protocol == GSPROT_HTTPD) {
-                for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
-                    if (! _gs_sock[i].connect || ! _gs_sock[i].data->use()) break;
-                    poll_httpd(i, _gs_sock[i].data->use());
-                }
-            } else
-#endif
-            if (_gs_sock[i].onGsReceive != NULL) {
-                for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
-                    if (! _gs_sock[i].connect || ! _gs_sock[i].data->use()) break;
-                    _gs_sock[i].onGsReceive(i, _gs_sock[i].data->use());
-                }
+            _gs_sock[i].received = false;
+            for (j = 0; j < 1500 / GS_DATA_SIZE + 1; j ++) {
+                if (! _gs_sock[i].connect || _gs_sock[i].data->isEmpty()) break;
+                _gs_sock[i].onGsReceive.call(i, _gs_sock[i].data->use());
             }
         }
     }
     
-    if (!_connect && _reconnect_count < _reconnect && _ssid) {
+    if ((!_connect) && _reconnect_count < _reconnect && _ssid) {
         // re-connrct
         int r;
         char cmd[GS_CMD_SIZE];
@@ -1052,12 +1048,13 @@
     sprintf(cmd, "AT+TCERTADD=%s,1,%d,1", name, len);  // Hex, ram
     command(cmd, GSRES_NORMAL);
     
+    resetResponse(GSRES_NORMAL);
     _gs_putc(0x1b);
     _gs_putc('W');
     for (i = 0; i < len; i ++) {
         _gs_putc(cert[i]);
     }
-    return cmdResponse(GSRES_NORMAL, GS_TIMEOUT);
+    return waitResponse(GS_TIMEOUT);
 }
 
 int GSwifi::provisioning (char *user, char *pass) {
@@ -1075,11 +1072,8 @@
 
     _gs.printf("ATB=%d\r\n", baud);
     _gs.baud(baud);
-    for (int i = 0; i < 10; i ++) {
-        wait_ms(10);
-        poll_cmd();
-        _buf_cmd.flush();
-    }
+    wait_ms(100);
+    _buf_cmd.flush();
     return 0;
 }