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)

Files at this revision

API Documentation at this revision

Comitter:
gsfan
Date:
Thu Oct 31 06:41:45 2013 +0000
Parent:
6:6a6396b56405
Child:
9:4565d3d3d13b
Commit message:
supported mbed RTOS

Changed in this revision

GSwifi/GSwifi.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi/GSwifi.h Show annotated file Show diff for this revision Revisions of this file
GSwifi/GSwifi_at.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi/GSwifi_hal.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi/GSwifi_http.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi/GSwifi_msg.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi/GSwifi_sock.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi/GSwifi_util.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifiInterface.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifiInterface.h Show annotated file Show diff for this revision Revisions of this file
Socket/Endpoint.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/Socket.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/TCPSocketConnection.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/TCPSocketConnection.h Show annotated file Show diff for this revision Revisions of this file
Socket/TCPSocketServer.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/UDPSocket.cpp Show annotated file Show diff for this revision Revisions of this file
Socket/UDPSocket.h Show annotated file Show diff for this revision Revisions of this file
--- a/GSwifi/GSwifi.cpp	Wed Jan 30 05:52:14 2013 +0000
+++ b/GSwifi/GSwifi.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -26,644 +26,355 @@
 
 GSwifi * GSwifi::_inst;
 
-GSwifi::GSwifi(   PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, const char * ssid, const char * phrase, Security sec):
-    _uart(tx, rx), _reset(reset), _buf_gswifi(CFG_CMD_SIZE)
+GSwifi::GSwifi(PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm, int baud):
+    _gs(tx, rx), _reset(reset)
 {
+    _inst = this;
     memset(&_state, 0, sizeof(_state));
     memset(&_con, 0, sizeof(_con));
-    _state.sec = sec;
+    _state.cid = -1;
     _state.acid = -1;
-
-    // change all ' ' in '$' in the ssid and the passphrase
-    strncpy(_ssid, ssid, sizeof(_ssid));
-    for (int i = 0; i < strlen(ssid); i++) {
-        if (_ssid[i] == ' ')
-            _ssid[i] = '$';
-    }
-    strncpy(_phrase, phrase, sizeof(_phrase));
-    for (int i = 0; i < strlen(phrase); i++) {
-        if (_phrase[i] == ' ')
-            _phrase[i] = '$';
-    }
-
-    _inst = this;
-    _state.mode = MODE_COMMAND;
-
-#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
-    if (cts == p12) { // CTS input (P0_17)
-        LPC_UART1->MCR |= (1<<7); // CTSEN
-        LPC_PINCON->PINSEL1 &= ~(3 << 2);
-        LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
+    _state.buf = new CircBuffer<char>(CFG_DATA_SIZE);
+#ifdef RTOS_H
+    for (int i = 0; i < 16; i ++) {
+        _con[i].buf = new CircBuffer<char>(CFG_DATA_SIZE);
     }
-    if (rts == P0_22) { // RTS output (P0_22)
-        LPC_UART1->MCR |= (1<<6); // RTSEN
-        LPC_PINCON->PINSEL1 &= ~(3 << 12);
-        LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
-        _rts = true;
-    } else {
-        _rts = false;
-    }
-#elif defined(TARGET_LPC11U24)
-    if (cts == p21) { // CTS input (P0_7)
-        LPC_USART->MCR |= (1<<7); // CTSEN
-        LPC_IOCON->PIO0_7 &= ~0x07;
-        LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
-    }
-    if (rts == p22) { // RTS output (P0_17)
-        LPC_USART->MCR |= (1<<6); // RTSEN
-        LPC_IOCON->PIO0_17 &= ~0x07;
-        LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
-        _rts = true;
-    } else {
-        _rts = false;
-    }
+    _threadPoll = NULL;
 #endif
-    _uart.baud(CFG_UART_BAUD);
-    _uart.attach(this, &GSwifi::handler_rx);
-    this->reset();
+
+    setReset(true);
+    initUart(cts, rts, alarm, baud);
+    setAlarm(true);
+    wait_ms(10);
+    setAlarm(false);
+    wait_ms(100);
+    setReset(false);
+    wait_ms(100);
 }
 
-bool GSwifi::join()
+int GSwifi::join(Security sec, const char *ssid, const char *phrase)
 {
-    bool r;
-    char cmd[CFG_CMD_SIZE];
-
-    send("\r\n", 2);
-    if (sendCommand("ATE0") == false) return -1;
-    if (_rts) {
-        sendCommand("AT&K0");
-        sendCommand("AT&R1");
-    }
+    bool r = -1;
 
-    disconnect();
-    sendCommand("AT+WREGDOMAIN=" CFG_WREGDOMAIN);
-    sendCommand("AT+BDATA=1");
-    sendCommand("AT+WM=0"); // infrastructure
+    _state.wm = WM_INFRASTRUCTURE;
+    setSsid(sec, ssid, phrase);
+    if (!strlen(_state.name)) {
+        strncpy(_state.name, CFG_DHCPNAME, sizeof(_state.name));
+    }
+    clearFlags();
+    sendCommand(NULL, RES_NULL, 0);
+    if (cmdE(false)) return -1;
+    if (_flow) {
+        cmdR(true);
+    }
+    cmdBDATA(true);
+    if (cmdNMAC()) return -1;
+    cmdWM(0); // infrastructure
     wait_ms(100);
-    if (_state.dhcp && _state.sec != SEC_WPS_BUTTON) {
-        sendCommand("AT+NDHCP=1");
-    } else {
-        sendCommand("AT+NDHCP=0");
-    }
 
-    switch (_state.sec) {
+    switch (sec) {
     case SEC_NONE:
     case SEC_OPEN:
     case SEC_WEP:
-        sprintf(cmd, "AT+WAUTH=%d", _ssid);
-        sendCommand(cmd);
-        if (_state.sec != SEC_NONE) {
-            sprintf(cmd, "AT+WWEP1=%s", _phrase);
-            sendCommand(cmd);
+        cmdNDHCP(_state.dhcp, _state.name, 0);
+        cmdWAUTH(_state.sec);
+        if (sec != SEC_NONE) {
+            cmdWWEP(1, _state.pass);
             wait_ms(100);
         }
-        sprintf(cmd, "AT+WA=%s", _ssid);
-        for (int i= 0; i < MAX_TRY_JOIN; i++) {
-            r = sendCommand(cmd, RES_DHCP, CFG_TIMEOUT2);
-            if (r) break;
+        r = cmdWA(_state.ssid);
+        if (r) {
+            DBG("retry\r\n");
+            wait_ms(1000);
+            r = cmdWA(_state.ssid);
         }
         break;
     case SEC_WPA_PSK:
     case SEC_WPA2_PSK:
-        sendCommand("AT+WAUTH=0");
-        sprintf(cmd, "AT+WPAPSK=%s,%s", _ssid, _phrase);
-        sendCommand(cmd, RES_NORMAL, CFG_TIMEOUT2);
+        cmdNDHCP(_state.dhcp, _state.name, 0);
+        cmdWAUTH(0);
+        cmdWPAPSK(_state.ssid, _state.pass);
         wait_ms(100);
-        sprintf(cmd, "AT+WA=%s", _ssid);
-        for (int i= 0; i < MAX_TRY_JOIN; i++) {
-            r = sendCommand(cmd, RES_DHCP, CFG_TIMEOUT2);
-            if (r) break;
+        r = cmdWA(_state.ssid);
+        if (r) {
+            DBG("retry\r\n");
+            wait_ms(1000);
+            r = cmdWA(_state.ssid);
         }
         break;
+    case SEC_WPA_ENT:
+    case SEC_WPA2_ENT:
+        cmdWAUTH(0);
+        DBG("Can't support security\r\n");
+        break;
     case SEC_WPS_BUTTON:
-        sendCommand("AT+WAUTH=0");
-        for (int i= 0; i < MAX_TRY_JOIN; i++) {
-            r = sendCommand("AT+WWPS=1", RES_WPS, CFG_TIMEOUT2);
-            if (r) break;
+        cmdNDHCP(false);
+        cmdWAUTH(0);
+        r = cmdWWPS(true);
+        if (r) break;
+        if (_state.dhcp) {
+            r = cmdNDHCP(_state.dhcp, _state.name);
         }
-        if (r && _state.dhcp) {
-            r = sendCommand("AT+NDHCP=1", RES_DHCP, CFG_TIMEOUT2);
+        cmdWSTATUS();
+        cmdWPAPSK(_state.ssid, _state.pass);
+        break;
+    case SEC_WPS_PIN:
+        cmdNDHCP(false);
+        cmdWAUTH(0);
+        r = cmdWWPS(true, _state.pass);
+        if (r) break;
+        if (_state.dhcp) {
+            r = cmdNDHCP(_state.dhcp, _state.name);
         }
+        cmdWSTATUS();
+        cmdWPAPSK(_state.ssid, _state.pass);
         break;
     default:
         DBG("Can't use security\r\n");
-        r = false;
         break;
     }
 
-    if (r) {
-        if (!_state.dhcp) {
-            sprintf(cmd, "AT+NSET=%s,%s,%s", _ip, _netmask, _gateway);
-            sendCommand(cmd);
-            sprintf(cmd, "AT+DNSSET=%s", _nameserver);
-            sendCommand(cmd);
+    if (!r) {
+        if (! _state.dhcp) {
+            cmdDNSSET(_state.nameserver);
         }
-
         _state.associated = true;
-        INFO("ssid: %s\r\nphrase: %s\r\nsecurity: %d", _ssid, _phrase, _state.sec);
+#ifdef RTOS_H
+        _threadPoll = new Thread(&threadPoll);
+//        _threadPoll = new Thread(&threadPoll, NULL, osPriorityLow);
+#endif
     }
-
     return r;
 }
 
-
-bool GSwifi::gethostbyname(const char * host, char * ip)
+int GSwifi::adhock (Security sec, const char *ssid, const char *phrase)
 {
-    int i, flg = 0;
-    char cmd[CFG_CMD_SIZE];
+    bool r = -1;
 
-    for (i = 0; i < strlen(host); i ++) {
-        if ((host[i] < '0' || host[i] > '9') && host[i] != '.') {
-            flg = 1;
-            break;
-        }
+    _state.wm = WM_ADHOCK;
+    setSsid(sec, ssid, phrase);
+    clearFlags();
+    sendCommand(NULL, RES_NULL, 0);
+    if (cmdE(false)) return -1;
+    if (_flow) {
+        cmdR(true);
     }
-    if (!flg) {
-        strncpy(ip, host, 16);
-        return true;
+    if (cmdNMAC()) return -1;
+    cmdBDATA(true);
+    cmdWM(1); // adhock
+    wait_ms(100);
+
+    cmdNDHCP(false);
+    if (! _state.dhcp) {
+        cmdNSET(_state.ip, _state.netmask, _state.ip);
     }
 
-    sprintf(cmd, "AT+DNSLOOKUP=%s", host);
-    if (sendCommand(cmd, RES_DNSLOOKUP)) {
-        strncpy(ip, _resolv, 16);
-        return true;
+    switch (sec) {
+    case SEC_NONE:
+    case SEC_OPEN:
+    case SEC_WEP:
+        cmdWAUTH(_state.sec);
+        if (sec != SEC_NONE) {
+            cmdWWEP(1, _state.pass);
+            wait_ms(100);
+        }
+        r = cmdWA(_state.ssid);
+        break;
+    default:
+        DBG("Can't use security\r\n");
+        break;
     }
 
-    return false; 
+    if (!r) {
+        _state.associated = true;
+    }
+    return r;
 }
 
-
-void GSwifi::flush(int cid)
+int GSwifi::limitedap (Security sec, const char *ssid, const char *phrase)
 {
-    if (cid < 0) {
-        return _buf_gswifi.flush();
-    } else {
-        if (_con[cid].buf == NULL)
-            _con[cid].buf = new CircBuffer<char>(CFG_DATA_SIZE);
-        return _con[cid].buf->flush();
+    bool r = -1;
+
+    _state.wm = WM_LIMITEDAP;
+    setSsid(sec, ssid, phrase);
+    if (!strlen(_state.name)) {
+        strncpy(_state.name, CFG_DNSNAME, sizeof(_state.name));
+    }
+    clearFlags();
+    sendCommand(NULL, RES_NULL, 0);
+    if (cmdE(false)) return -1;
+    if (_flow) {
+        cmdR(true);
+    }
+    if (cmdNMAC()) return -1;
+    cmdBDATA(true);
+    cmdWM(2); // limitedap
+    wait_ms(100);
+
+    cmdNDHCP(false);
+    if (! _state.dhcp) {
+        cmdNSET(_state.ip, _state.netmask, _state.ip);
+        cmdDNSSET(_state.ip);
     }
+    cmdDHCPSRVR(true);
+    cmdDNS(true, _state.name);
+
+    switch (sec) {
+    case SEC_NONE:
+    case SEC_OPEN:
+    case SEC_WEP:
+        cmdWAUTH(_state.sec);
+        if (sec != SEC_NONE) {
+            cmdWWEP(1, _state.pass);
+            wait_ms(100);
+        }
+        r = cmdWA(_state.ssid);
+        break;
+    default:
+        DBG("Can't use security\r\n");
+        break;
+    }
+
+    if (!r) {
+        _state.associated = true;
+    }
+    return r;
 }
 
-bool GSwifi::sendCommand(const char * cmd, Response res, int timeout)
+int GSwifi::disconnect()
 {
-    DBG("command: %s",cmd);
+    int i;
 
-    send(cmd, strlen(cmd));
-    if (send("\r\n", 2, res, timeout) == -1) {
-        ERR("sendCommand: cannot %s", cmd);
-        return false;
-    }
-    return true;
-}
-
-
-bool GSwifi::disconnect()
-{
     // if already disconnected, return
     if (!_state.associated)
-        return true;
+        return 0;
 
-    for (int i = 0; i < 16; i ++) {
-        if (_con[i].buf)
+#ifdef RTOS_H
+    if (_threadPoll) {
+        _threadPoll->terminate();
+        delete _threadPoll;
+    }
+#endif
+    for (i = 0; i < 16; i ++) {
+        if (_con[i].buf) {
             _con[i].buf->flush();
+        }
     }
-    sendCommand("AT+NCLOSEALL");
-    sendCommand("AT+WD");
-    sendCommand("AT+NDHCP=0");
+    cmdNCLOSEALL();
+    cmdWD();
+    cmdNDHCP(false);
     wait_ms(100);
 
     _state.associated = false;
-    return true;
+    return 0;
 
 }
 
-bool GSwifi::is_connected(int cid)
-{
-    return _con[cid].connected;
-}
-
-
-void GSwifi::reset()
-{
-    _reset = 0;
-    wait_ms(100);
-    _reset = 1;
-    wait_ms(500);
-}
-
-
-int GSwifi::putc(char c)
-{
-    while (!_uart.writeable());
-    return _uart.putc(c);
-}
-
-
-int GSwifi::readable(int cid)
+bool GSwifi::isConnected()
 {
-    if (cid < 0) {
-        return _buf_gswifi.available();
-    } else {
-        return _con[cid].buf->available();
-    }
-}
-
-int GSwifi::writeable()
-{
-    return _uart.writeable();
-}
-
-char GSwifi::getc(int cid)
-{
-    char c;
-    if (cid < 0) {
-        while (!_buf_gswifi.available());
-        _buf_gswifi.dequeue(&c);
-    } else {
-        while (!_con[cid].buf->available());
-        _con[cid].buf->dequeue(&c);
-    }
-    return c;
+    return _state.associated;
 }
 
-void GSwifi::handler_rx(void)
-{
-    static int len, flg;
-    static char tmp[20];
-    char dat;
-
-    while (_uart.readable()) {
-
-    dat = _uart.getc();
-
-    switch (_state.mode) {
-    case MODE_COMMAND: // command responce
-        if (_state.escape) {
-            // esc
-            switch (dat) {
-            case 'O':
-                DBG("ok");
-                _state.retres = RES_OK;
-                _state.cmdres = RES_OK;
-                break;
-            case 'F':
-                DBG("failure");
-                _state.retres = RES_FAILURE;
-                _state.cmdres = RES_FAILURE;
-                break;
-            case 'Z':
-            case 'H':
-                DBG("GSMODE_DATA_RX");
-                _state.mode = MODE_DATA_RX;
-                flg = 0;
-                break;
-            case 'y':
-                DBG("GSMODE_DATA_RXUDP");
-                _state.mode = MODE_DATA_RXUDP;
-                flg = 0;
-                break;
-            case 'S':
-            case 'u':
-            default:
-                WARN("unknown [ESC] %02x", dat);
-                break;
-            }
-            _state.escape = 0;
-        } else {
-            if (dat == 0x1b) {
-                _state.escape = 1;
-            } else
-            if (dat == '\n') {
-                parseResponse();
-            } else
-            if (dat != '\r') {
-                // command
-                _buf_gswifi.queue(dat);
-            }
-        }
-        break;
-
-    case MODE_DATA_RX:
-    case MODE_DATA_RXUDP:
-        switch (flg) {
-        case 0:
-            // CID
-            _state.cid = x2i(dat);
-            flg ++;
-            if (_state.mode == MODE_DATA_RX) {
-                flg = 3;
-            }
-            len = 0;
-            break;
-        case 1:
-            // IP (UDP)
-            if ((dat >= '0' && dat <= '9') || dat == '.') {
-                tmp[len] = dat;    
-                len ++;
-            } else
-            if (len < sizeof(tmp) - 1) {
-                tmp[len] = 0;
-                strncpy(_con[_state.cid].ip, tmp, sizeof(_con[_state.cid].ip));
-                flg ++;
-                len = 0;
-            }
-            break;
-        case 2:
-            // port
-            if (dat >= '0' && dat <= '9') {
-                tmp[len] = dat;            
-                len ++;        
-            } else {
-                tmp[len] = 0;
-                _con[_state.cid].port = atoi(tmp);
-                flg ++;
-                len = 0;
-            }
-            break;
-        case 3:
-            // length
-            tmp[len] = dat;            
-            len ++;        
-            if (len >= 4) {
-                tmp[len] = 0;
-                len = atoi(tmp);
-                flg ++;
-            }
-            break;
-        case 4:
-            // data
-            if (_con[_state.cid].buf != NULL) {
-                _con[_state.cid].buf->queue(dat);
-            }
-            len --;
-
-            if (len == 0 || _con[_state.cid].buf->isFull()) {
-                DBG("recv binary %d", _state.cid);
-                _state.escape = 0;
-                _state.mode = MODE_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;
-                }
-*/
-            }
-            break;
-        }
-        
-        break;
-    }
-
-    } // while
-}
-
-void GSwifi::parseResponse () {
-    int i;
-    char buf[CFG_CMD_SIZE];
-
-    while (_buf_gswifi.available()) {
-        i = 0;
-        while (_buf_gswifi.available() && i < sizeof(buf)) {
-            _buf_gswifi.dequeue(&buf[i]);
-            if (buf[i] == '\n') {
-                break;
-            }
-            i ++;
-        }
-        if (i == 0) continue;
-        buf[i] = 0;
-        DBG("parseResponse: %s", buf);
-
-        if (_state.cmdres != RES_NULL) {
-            parseCmdResponse(buf);
-            DBG("parseCmdResponse %d %d", _state.cmdres, _state.retres);
-        }
-
-        if (strncmp(buf, "CONNECT ", 8) == 0 && buf[8] >= '0' && buf[8] <= 'F' && buf[9] != 0) {
-            int cid;
-            char *tmp, *tmp2;
-            cid = x2i(buf[8]);
-            _state.acid = x2i(buf[10]);
-            tmp = buf + 12;
-            tmp2 = strstr(tmp, " ");
-            tmp2[0] = 0;
-            strncpy(_con[_state.acid].ip, tmp, sizeof(_con[_state.acid].ip));
-            tmp = tmp2 + 1;
-            _con[_state.acid].port = atoi(tmp);
-            _con[_state.acid].parent = cid;
-            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;
-            DBG("connect %d -> %d", cid, _state.acid);
-        } else
-        if (strncmp(buf, "DISCONNECT ", 11) == 0) {
-            int cid;
-            cid = x2i(buf[11]);
-            DBG("disconnect %d", cid);
-            _con[cid].connected = false;
-        } 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) {
-            _state.associated = false;
-            for (i = 0; i < 16; i ++) {
-                _con[i].connected = false;
-            }
-        } else
-        if (strncmp(buf, "Out of StandBy-Timer", 20) == 0 ||
-          strncmp(buf, "Out of StandBy-Alarm", 20) == 0) {
-            _state.status = STAT_WAKEUP;
-        } else 
-        if (strncmp(buf, "Out of Deep Sleep", 17) == 0 ) {
-            _state.status = STAT_READY;
-        } else 
-        if (strncmp(buf, "Out of", 6) == 0) {
+void GSwifi::poll () {
+    if (_state.wm == WM_INFRASTRUCTURE && (! isConnected()) && _state.ssid) {
+        // Wi-Fi re-associate
+        if (!cmdWA(_state.ssid)) {
+            _state.associated = true;
         }
     }
 }
 
-void GSwifi::parseCmdResponse (char *buf) {
-
-        if (strcmp(buf, "OK") == 0) {
-            _state.retres = RES_OK;
-        } else
-        if (strncmp(buf, "ERROR", 5) == 0) {
-            _state.retres = RES_FAILURE;
-        }
+#ifdef RTOS_H
+void GSwifi::threadPoll (void const *args) {
+    GSwifi * _wifi = GSwifi::getInstance();
+    if (_wifi == NULL)
+        error("Socket constructor error: no wifly instance available!\r\n");
 
-        switch(_state.cmdres) {
-        case RES_NORMAL:
-            _state.cmdres = RES_OK;
-            break;
-        case RES_WPS:
-            if (_state.n == 0 && strncmp(buf, "SSID", 4) == 0) {
-                _state.n ++;
-            } else
-            if (_state.n == 1 && strncmp(buf, "CHANNEL", 7) == 0) {
-                _state.n ++;
-            } else
-            if (_state.n == 2 && strncmp(buf, "PASSPHRASE", 10) == 0) {
-                _state.n ++;
-                _state.cmdres = RES_OK;
-            }
-            break;
-        case RES_CONNECT:
-            if (strncmp(buf, "CONNECT ", 8) == 0 && buf[9] == 0) {
-                _state.cid = x2i(buf[8]);
-                _state.cmdres = RES_OK;
-                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;
-                INFO("connect: %d", _state.cid);
-            }
-            break;
-        case RES_DHCP:
-            if (_state.n == 0 && strstr(buf, "SubNet") && strstr(buf, "Gateway")) {
-                _state.n ++;
-            } else
-            if (_state.n == 1) {
-                char *tmp, *tmp2;
-                tmp = buf + 1;
-                tmp2 = strstr(tmp, ":");
-                tmp2[0] = 0;
-                strncpy(_ip, tmp, sizeof(_ip));
-                tmp = tmp2 + 2;
-                tmp2 = strstr(tmp, ":");
-                tmp2[0] = 0;
-                strncpy(_netmask, tmp, sizeof(_netmask));
-                tmp = tmp2 + 2;
-                strncpy(_gateway, tmp, sizeof(_gateway));
-                _state.n ++;
-                _state.cmdres = RES_OK;
-                INFO("ip: %s\r\nnetmask: %s\r\ngateway: %s", _ip, _netmask, _gateway);
-            }
-            break;
-        case RES_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;
-*/
-                _state.cmdres = RES_OK;
-            }
-            break;
-        case RES_DNSLOOKUP:
-            if (strncmp(buf, "IP:", 3) == 0) {
-                strncpy(_resolv, &buf[3], sizeof(_resolv));
-                _state.cmdres = RES_OK;
-                INFO("resolv: %s", _resolv);
-            }
-            break;
-        case RES_HTTP:
-            if (buf[0] >= '0' && buf[0] <= 'F') {
-                _state.cid = x2i(buf[0]);
-                _state.cmdres = RES_OK;
-                INFO("http: %d", _state.cid);
-            }
-            break;
-        case RES_RSSI:
-            if (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9')) {
-                _rssi = atoi(buf);
-                _state.cmdres = RES_OK;
-                INFO("rssi: %d", _rssi);
-            }
-            break;
-        case RES_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);            
-                _state.cmdres = RES_OK;
-            }
-            break;
-        }
-}
-
-int GSwifi::send(const char * str, int len, Response res, int timeout)
-{
-    Timer tmr;
-    int result = 0;
-
-    if (res == RES_NULL) {
-        for (int i = 0; i < len; i++)
-            result = (putc(str[i]) == str[i]) ? result + 1 : result;
-    } else {
-        _state.cmdres = res;
-        _state.retres = RES_NULL;
-
-        tmr.start();
-        for (int i = 0; i < len; i++)
-            result = (putc(str[i]) == str[i]) ? result + 1 : result;
-
-        while (1) {
-            if (tmr.read_ms() > timeout || _state.retres == RES_FAILURE) {
-                result = -1;
-                break;
-            }
-            if (_state.retres == RES_OK && _state.cmdres != res) break;
+    INFO("threadPoll");
+    for (;;) {
+        Thread::signal_wait(1);
+        Thread::wait(1000);
+        INFO("disassociated");
+        while (!_wifi->isConnected()){
+            _wifi->poll();
+            Thread::wait(CFG_TIMEOUT);
         }
     }
-
-    _state.cmdres = RES_NULL;
-    _state.retres = RES_NULL;
-    return result;
 }
+#endif
 
-bool GSwifi::readRemote(int cid, char **ip, int *port) {
-    *ip = _con[cid].ip;
-    *port = _con[cid].port;
-    return true;
-}
-
-int GSwifi::readCID () {
-    return _state.cid;
-}
+int GSwifi::setSsid (Security sec, const char *ssid, const char *phrase) {
+    int i;
 
-int GSwifi::readACID () {
-    int r = -1;
-    if (_state.acid >= 0 && _con[_state.acid].connected == true) {
-        r = _state.acid;
-        _state.acid = -1;
+    _state.sec = sec;
+    // change all ' ' in '$' in the ssid and the passphrase
+    strncpy(_state.ssid, ssid, sizeof(_state.ssid));
+    for (i = 0; i < strlen(_state.ssid); i++) {
+        if (_state.ssid[i] == ' ')
+            _state.ssid[i] = '$';
     }
-    return r;
-}
-
-int GSwifi::x2i (char c) {
-    if (c >= '0' && c <= '9') {
-        return c - '0';
-    } else
-    if (c >= 'A' && c <= 'F') {
-        return c - 'A' + 10;
-    } else
-    if (c >= 'a' && c <= 'f') {
-        return c - 'a' + 10;
+    strncpy(_state.pass, phrase, sizeof(_state.pass));
+    for (i = 0; i < strlen(_state.pass); i++) {
+        if (_state.pass[i] == ' ')
+            _state.pass[i] = '$';
     }
     return 0;
 }
 
-char GSwifi::i2x (int i) {
-    if (i >= 0 && i <= 9) {
-        return i + '0';
-    } else
-    if (i >= 10 && i <= 15) {
-        return i - 10 + 'A';
+int GSwifi::standby (int msec) {
+    switch (_state.status) {
+    case STAT_READY:
+        cmdSTORENWCONN();
+        for (int i = 0; i < 16; i ++) {
+            _con[i].connected = false;
+        }
+        break;
+    case STAT_WAKEUP:
+        if (cmdE(false)) return -1;
+        if (_flow) {
+            cmdR(true);
+        }
+        break;
+    default:
+        return -1;
     }
-    return 0;
+
+    _state.status = STAT_STANDBY;
+    return cmdPSSTBY(msec, 0);
+}
+
+int GSwifi::deepSleep () {
+    if (_state.status != STAT_READY) return -1;
+    _state.status = STAT_DEEPSLEEP;
+    return cmdPSDPSLEEP(); // go deep sleep
 }
+
+int GSwifi::wakeup () {
+    if (_state.status == STAT_STANDBY) {
+        Timer timeout;
+        setAlarm(true);
+        timeout.start();
+        while (_state.status != STAT_WAKEUP && timeout.read() < CFG_TIMEOUT);
+        timeout.stop();
+        setAlarm(false);
+    }
+
+    switch (_state.status) {
+    case STAT_WAKEUP:
+        _state.status = STAT_READY;
+        if (cmdE(false)) return -1;
+        if (_flow) {
+            cmdR(true);
+        }
+        cmdBDATA(true);
+        int r = cmdRESTORENWCONN();
+        wait_ms(100);
+//        return cmdWRXACTIVE(true);
+        return r;
+    case STAT_DEEPSLEEP:
+        _state.status = STAT_READY;
+        return cmdAT();
+    }
+    return -1;
+}
+
--- a/GSwifi/GSwifi.h	Wed Jan 30 05:52:14 2013 +0000
+++ b/GSwifi/GSwifi.h	Thu Oct 31 06:41:45 2013 +0000
@@ -24,47 +24,77 @@
 /* Copyright (C) 2013 gsfan, MIT License
  *  port to the GainSpan Wi-FI module GS1011
  */
+/** @file
+ * @brief Gainspan wi-fi module library for mbed
+ * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
+ */
 
 #ifndef GSwifi_H
 #define GSwifi_H
 
 #include "mbed.h"
+#include "rtos.h"
+#include "RawSerial.h"
 #include "CBuffer.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DEBUG
 
 #define DEFAULT_WAIT_RESP_TIMEOUT 500
-#define CFG_TIMEOUT 10000 // ms
-#define CFG_TIMEOUT2 30000 // ms
+#define CFG_TIMEOUT 30000 // ms
 #define CFG_CMD_SIZE 100
-#define CFG_DATA_SIZE 1000
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+#define CFG_DATA_SIZE 1024
+#elif defined(TARGET_LPC11U24)
+#define CFG_DATA_SIZE 128
+#elif defined(TARGET_LPC4088)
+#define CFG_DATA_SIZE 4096
+#endif
 
+
+//#define CFG_UART_DIRECT
 #define CFG_UART_BAUD 9600
-#define CFG_WREGDOMAIN "2" // 0:FCC, 1:ETSI, 2:TELEC
+#define CFG_WREGDOMAIN 2 // 0:FCC, 1:ETSI, 2:TELEC
+#define CFG_DHCPNAME "mbed-gswifi"
+#define CFG_DNSNAME "setup.local"
 #define MAX_TRY_JOIN 3
 
+#define MSG_TABLE_NUM 15
+#define RES_TABLE_NUM 10
 
 //Debug is disabled by default
-#if (0 && !defined(TARGET_LPC11U24))
-#define DBG(x, ...) std::printf("[GSwifi : DBG]" x "\r\n", ##__VA_ARGS__);
-#define WARN(x, ...) std::printf("[GSwifi : WARN]" x "\r\n", ##__VA_ARGS__);
-#define ERR(x, ...) std::printf("[GSwifi : ERR]" x "\r\n", ##__VA_ARGS__);
+#if defined(DEBUG) and (!defined(TARGET_LPC11U24))
+#define DBG(x, ...) std::printf("[DBG]" x "\r\n", ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[WARN]" x "\r\n", ##__VA_ARGS__);
+#define ERR(x, ...) std::printf("[ERR]" x "\r\n", ##__VA_ARGS__);
+#define INFO(x, ...) std::printf("[INFO]" x "\r\n", ##__VA_ARGS__);
 #else
 #define DBG(x, ...)
 #define WARN(x, ...)
 #define ERR(x, ...)
-#endif
-
-#if (0 && !defined(TARGET_LPC11U24))
-#define INFO(x, ...) printf("[GSwifi : INFO]\r\n"x"\r\n", ##__VA_ARGS__);
-#else
 #define INFO(x, ...)
 #endif
 
 
+/** GSwifi class
+ */
 class GSwifi
 {
 
 public:
 
+    /** Wi-Fi mode
+     */
+    enum WiFiMode {
+        WM_INFRASTRUCTURE,
+        WM_ADHOCK,
+        WM_LIMITEDAP,
+    };
+
+    /** Wi-Fi security
+     */
     enum Security {
         SEC_AUTO = 0,
         SEC_NONE = 0,
@@ -75,8 +105,11 @@
         SEC_WPA_ENT = 16,
         SEC_WPA2_ENT = 32,
         SEC_WPS_BUTTON = 64,
+        SEC_WPS_PIN,
     };
 
+    /** TCP/IP protocol
+     */
     enum Protocol {
         PROTO_UDP = 0,
         PROTO_TCP = 1,
@@ -85,9 +118,15 @@
         PROTO_HTTPD,
     };
 
+    /** Client/Server
+     */
+    enum Type {
+        TYPE_CLIENT = 0,
+        TYPE_SERVER = 1,
+    };
+
     enum Response {
         RES_NULL,
-        RES_NORMAL,
         RES_CONNECT,
         RES_WPS,
         RES_MACADDRESS,
@@ -96,189 +135,377 @@
         RES_HTTP,
         RES_RSSI,
         RES_TIME,
-        RES_OK,
-        RES_FAILURE,
+        RES_STATUS,
     };
 
     enum Mode {
         MODE_COMMAND,
+        MODE_CMDRESP,
+        MODE_ESCAPE,
         MODE_DATA_RX,
+        MODE_DATA_RX_BULK,
         MODE_DATA_RXUDP,
+        MODE_DATA_RXUDP_BULK,
         MODE_DATA_RXHTTP,
+        MODE_DATA_RAW,
     };
 
     enum Status {
+        STAT_NONE,
         STAT_READY,
         STAT_STANDBY,
         STAT_WAKEUP,
         STAT_DEEPSLEEP,
     };
 
-    /*
-    * Constructor
-    *
-    * @param tx mbed pin to use for tx line of Serial interface
-    * @param rx mbed pin to use for rx line of Serial interface
-    * \param cts mbed pin to use for cts line of Serial interface
-    * \param rts mbed pin to use for rts line of Serial interface
-    * @param reset reset pin of the wifi module ()
-    * @param ssid ssid of the network
-    * @param phrase WEP or WPA key
-    * @param sec Security type (NONE, WEP_128 or WPA)
-    */
-    GSwifi(  PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, const char * ssid, const char * phrase, Security sec);
-
-    /*
-    * Connect the wifi module to the ssid contained in the constructor.
-    *
-    * @return true if connected, false otherwise
-    */
-    bool join();
+    // ----- GSwifi.cpp -----
+    /** Constructor
+     * \param tx mbed pin to use for tx line of Serial interface
+     * \param rx mbed pin to use for rx line of Serial interface
+     * \param cts mbed pin to use for cts line of Serial interface
+     * \param rts mbed pin to use for rts line of Serial interface
+     * \param reset reset pin of the wifi module
+     * \param alarm alarm pin of the wifi module
+     * \param baud baud rate of Serial interface
+     */
+    GSwifi (PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm, int baud);
 
-    /*
-    * Disconnect the wifly module from the access point
-    *
-    * @ returns true if successful
-    */
-    bool disconnect();
-
-    /*
-    * Reset the wifi module
-    */
-    void reset();
-    
-    /*
-    * Check if characters are available
-    *
-    * @return number of available characters
-    */
-    int readable(int cid);
-
-    /*
-    * Check if characters are available
-    *
-    * @return number of available characters
-    */
-    int writeable();
-
-    /*
-    * Check if a tcp link is active
-    *
-    * @returns true if successful
-    */
-    bool is_connected(int cid);
+    /** Connect the wifi module to the ssid contained in the constructor.
+     * @param sec Security type (NONE, WEP_128 or WPA)
+     * @param ssid ssid of the network
+     * @param phrase WEP or WPA key
+     * @return 0 if connected, -1 otherwise
+     */
+    int join (Security sec, const char *ssid, const char *phrase);
 
-    /*
-    * Read a character
-    *
-    * @return the character read
-    */
-    char getc(int cid);
-
-    /*
-    * Flush the buffer
-    */
-    void flush(int cid);
-
-    /*
-    * Write a character
-    *
-    * @param the character which will be written
-    */
-    int putc(char c);
+    /** Connect the wifi module to the adhock in the constructor.
+     * @param sec Security type (NONE, WEP_128 or WPA)
+     * @param ssid ssid of the network
+     * @param phrase WEP or WPA key
+     * @return 0 if connected, -1 otherwise
+     */
+    int adhock (Security sec, const char *ssid, const char *phrase);
 
-    /*
-    * Send a string to the wifi module by serial port. This function desactivates the user interrupt handler when a character is received to analyze the response from the wifi module.
-    * Useful to send a command to the module and wait a response.
-    *
-    *
-    * @param str string to be sent
-    * @param len string length
-    * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO")
-    * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL)
-    *
-    * @return true if ACK has been found in the response from the wifi module. False otherwise or if there is no response in 5s.
-    */
-    int send(const char * str, int len, Response res = RES_NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
+    /** Connect the wifi module to the limited AP in the constructor.
+     * @param sec Security type (NONE, WEP_128 or WPA)
+     * @param ssid ssid of the network
+     * @param phrase WEP or WPA key
+     * @return 0 if connected, -1 otherwise
+     */
+    int limitedap (Security sec, const char *ssid, const char *phrase);
 
-    /*
-    * Send a command to the wify module. Check if the module is in command mode. If not enter in command mode
-    *
-    * @param str string to be sent
-    * @param ACK string which must be acknowledge by the wifi module. If ACK == NULL, no string has to be acknoledged. (default: "NO")
-    * @param res this field will contain the response from the wifi module, result of a command sent. This field is available only if ACK = "NO" AND res != NULL (default: NULL)
-    *
-    * @returns true if successful
-    */
-    bool sendCommand(const char * cmd, Response res = RES_NORMAL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
+    /** Disconnect the wifi module from the access point
+     * @returns 0 if successful
+     */
+    int disconnect ();
     
-    /*
-    * Return true if the module is using dhcp
-    *
-    * @returns true if the module is using dhcp
-    */
-    bool isDHCP() {
-        return _state.dhcp;
-    }
+    /** Check if a tcp link is active
+     * @returns true if successful
+     */
+    bool isConnected();
 
-    bool gethostbyname(const char * host, char * ip);
+    int setSsid (Security sec, const char *ssid, const char *phrase);
+
+    void poll ();
 
     static GSwifi * getInstance() {
         return _inst;
     };
 
-    bool readRemote(int cid, char **ip, int *port);
-    int readCID ();
-    int readACID ();
+    // ----- GSwifi_util.cpp -----
+    int setRegion (int reg);
+
+    /** RSSI
+     * @return RSSI (dBm)
+     */
+    int getRssi ();
+
+    /** power save mode
+     * @param active rx radio 0:switched off, 1:always on
+     * @param save power save 0:disable, 1:enable
+     */
+    int powerSave (int active, int save);
+
+    /** RF power
+     * @param power 0(high)-7(low)
+     */
+    int setRfPower (int power);
+
+    /** set system time
+     * @param time date time (UTC)
+     */
+    int setTime (time_t time);
+
+    /** get system time
+     * @return date time (UTC)
+     */
+    time_t getTime ();
+
+    /** set NTP server
+     * @param host SNTP server
+     * @param sec time sync interval, 0:one time
+     */
+    int ntpdate (char *host, int sec = 0);
+
+    /** GPIO output
+     * @param port 10,11,30,31
+     * @param out 0:set(high), 1:reset(low)
+     */
+    int setGpio (int port, int out);
+
+    /** Web server
+     */
+    int provisioning (char *user, char *pass);
+
+    /** standby mode
+     * @param msec wakeup after
+     * wakeup after msec or alarm1/2
+     * core off, save to RTC ram
+     */
+    int standby (int msec);
+
+    /** deep sleep mode
+     */
+    int deepSleep ();
+
+    /** restore standby or deep sleep
+     */
+    int wakeup ();
+
+    // ----- GSwifi_sock.cpp -----
+    /** Resolv hostname
+     * @param name hostname
+     * @param ip resolved ip address
+     */
+    int getHostByName(const char * host, char * ip);
+
+    /** TCP/UDP client
+     * @return CID, -1:failure
+     */
+    int open (Protocol proto, const char *ip, int port, int src = 0);
+
+    /** TCP/UDP server
+     * @return CID, -1:failure
+     */
+    int listen (Protocol proto, int port);
+
+    /** close client/server
+     */
+    int close (int cid);
+
+    /** send data tcp(s/c), udp(c)
+     */
+    int send (int cid, const char *buf, int len);
+
+    /*
+     * send data udp(s)
+     */
+    int sendto (int cid, const char *buf, int len, const char *ip, int port);
+
+    /** recv data tcp(s/c), udp(c)
+     * @return length
+     */
+    int recv (int cid, char *buf, int len);
+
+    /** recv data udp(s)
+     * @return length
+     */
+    int recvfrom (int cid, char *buf, int len, char *ip, int *port);
+
+    /** readable recv data
+     */
+    int readable (int cid);
+
+    /** tcp/udp connected
+     */
+    bool isConnected (int cid);
+
+    int accept (int cid);
+    int getRemote(int cid, char **ip, int *port);
+
+    // ----- GSwifi_http.cpp -----
+    int httpGet (const char *host, int port, const char *uri, bool ssl = false, const char *user = NULL, const char *pwd = NULL);
+    int httpPost (const char *host, int port, const char *uri, const char *body, bool ssl = false, const char *user = NULL, const char *pwd = NULL);
+    int base64encode (const char *input, int length, char *output, int len);
+    int urlencode (const char *str, char *buf, int len);
+    int urldecode (const char *str, char *buf, int len);
+
+    // ----- GSwifi_msg.cpp -----
+
+    // ----- GSwifi_at.cpp -----
+    /** Send a command to the wifi module. Check if the module is in command mode. If not enter in command mode
+     * @param cmd string to be sent
+     * @param res need response
+     * @param timeout
+     * @returns 0 if successful
+     */
+    int sendCommand(const char * cmd, Response res = RES_NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
+
+    /** Send a command to the wifi module. Check if the module is in command mode. If not enter in command mode
+     * @param data string to be sent
+     * @param res need response
+     * @param timeout
+     * @param cmd 
+     * @returns 0 if successful
+     */
+    int sendData(const char * data, int len, int timeout = DEFAULT_WAIT_RESP_TIMEOUT, const char * cmd = NULL);
+
 
 protected:
-    Serial _uart;
-    bool _rts;
-    DigitalOut _reset;
-    char _phrase[30];
-    char _ssid[30];
-    char _ip[16];
-    char _netmask[16];
-    char _gateway[16];
-    char _nameserver[16];
-    char _resolv[16];
-    int _rssi;
-    time_t _time;
-    CircBuffer<char> _buf_gswifi;
 
     static GSwifi * _inst;
-
-    void attach_rx(bool null);
-    void handler_rx(void);
+#ifdef RTOS_H
+    Thread *_threadPoll;
+    Mutex _mutexUart;
+#endif
 
-    int x2i (char c);
-    char i2x (int i);
-    void parseResponse ();
-    void parseCmdResponse (char *buf);
+//    Serial _gs;
+    RawSerial _gs;
+    int _baud;
+    DigitalIn *_cts;
+    DigitalOut *_rts;
+    int _flow;
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088)
+    LPC_UART1_TypeDef *_uart;
+#elif defined(TARGET_LPC11U24)
+    LPC_USART_Type *_uart;
+#endif
+    DigitalInOut _reset;
+    DigitalInOut *_alarm;
 
-    typedef struct STATE {
-        bool associated;
+    struct STATE {
+        WiFiMode wm;
+        Security sec;
+        char ssid[35];
+        char pass[66];
+        char ip[16];
+        char netmask[16];
+        char gateway[16];
+        char nameserver[16];
+        char mac[18];
+        char resolv[16];
+        char name[32];
+        int rssi;
         bool dhcp;
-        Security sec;
-        Mode mode;
-        Status status;
+        time_t time;
+
+        bool associated;
+        volatile Mode mode;
+        volatile Status status;
         bool escape;
+        volatile bool ok, failure;
+        Response res;
         int cid, acid;
-        volatile Response cmdres, retres;
         int n;
-    } State;
+        CircBuffer<char> *buf;
+    } _state;
 
-    State _state;
-
-    typedef struct CONNECTION {
+    struct CONNECTION {
+        Protocol protocol;
+        Type type;
         bool connected;
         char ip[16];
         int port;
         CircBuffer<char> *buf;
-        int parent;
-    } Connection;
+        volatile bool received;
+        volatile int parent;
+        volatile bool accept;
+    } _con[16];
+
+
+    // ----- GSwifi.cpp -----
+#ifdef RTOS_H
+    static void threadPoll (void const *args);
+#endif
+
+    // ----- GSwifi_util.cpp -----
+    int x2i (char c);
+    char i2x (int i);
+    int from_hex (int ch);
+    int to_hex (int code);
+
+    // ----- GSwifi_msg.cpp -----
+    void recvData (char c);
+    int parseMessage ();
+    void msgOk (const char*);
+    void msgError (const char*);
+    void msgConnect (const char*);
+    void msgDisconnect (const char*);
+    void msgDisassociated (const char*);
+    void msgReset (const char*);
+    void msgOutofStandby (const char*);
+    void msgOutofDeepsleep (const char*);
+    void resNormal (const char*);
+    void resConnect (const char*);
+    void resWps (const char*);
+    void resMacAddress (const char*);
+    void resIp (const char*);
+    void resLookup (const char*);
+    void resRssi (const char*);
+    void resTime (const char*);
+    void resChannel (const char*);
+    void resStatus (const char*);
 
-    Connection _con[16];
+    // ----- GSwifi_at.cpp -----
+    void clearFlags ();
+    int cmdAT ();
+    int cmdE (bool n);
+    int cmdR (bool n);
+    int cmdNMAC (const char *s = NULL);
+    int cmdWREGDOMAIN (int n = CFG_WREGDOMAIN);
+    int cmdWS ();
+    int cmdWM (int n);
+    int cmdWA (const char *s);
+    int cmdWD ();
+    int cmdWWPS (bool n, const char *p = NULL);
+    int cmdNSTAT ();
+    int cmdWSTATUS ();
+    int cmdWRSSI ();
+    int cmdWAUTH (int n);
+    int cmdWWEP (int n, const char *s);
+    int cmdWPAPSK (const char *s, const char *p);
+    int cmdWRXACTIVE (bool n);
+    int cmdWRXPS (bool n);
+    int cmdWP (int n);
+    int cmdNDHCP (bool n, const char *s = NULL, int m = CFG_TIMEOUT);
+    int cmdDHCPSRVR (bool n);
+    int cmdNSET (const char *s, const char *t, const char *u);
+    int cmdDNS (bool n, const char *s);
+    int cmdDNSLOOKUP (const char *s);
+    int cmdDNSSET (const char *s);
+    int cmdSTORENWCONN ();
+    int cmdRESTORENWCONN ();
+    int cmdBDATA (bool n);
+    int cmdNCTCP (const char *s, int n);
+    int cmdNCUDP (const char *s, int n, int m = 0);
+    int cmdNSTCP (int n);
+    int cmdNSUDP (int n);
+    int cmdNCLOSE (int n);
+    int cmdNCLOSEALL ();
+    int cmdHTTPCONF (int n, const char *s);
+    int cmdHTTPCONFDEL (int n);
+    int cmdHTTPOPEN (const char *s, int n = 80, bool m = false);
+    int cmdHTTPSEND (int n, bool m, const char *s, int t = 0);
+    int cmdHTTPCLOSE (int n);
+    int cmdPSDPSLEEP (int n = 0);
+    int cmdPSSTBY (int n, int m = 0);
+    int cmdWEBPROV (const char *s, const char *p);
+    int cmdSETTIME (const char *s, const char *t);
+    int cmdGETTIME ();
+    int cmdNTIMESYNC (bool n, const char *s, int m = 0);
+    int cmdDGPIO (int n, int m);
+
+    // ----- GSwifi_hal.cpp -----
+    void setReset (bool flg);
+    void setAlarm (bool flg);
+    void isrUart ();
+    int getUart ();
+    void putUart (char c);
+    void setRts (bool flg);
+    int lockUart (int ms);
+    void unlockUart ();
+    void initUart (PinName cts, PinName rts, PinName alarm, int baud);
+
 };
 
 #endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GSwifi/GSwifi_at.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -0,0 +1,404 @@
+/* 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"
+
+void GSwifi::clearFlags () {
+    _state.ok = false;
+    _state.failure = false;
+    _state.res = RES_NULL;
+    _state.mode = MODE_COMMAND;
+}
+
+int GSwifi::sendCommand(const char * cmd, Response res, int timeout) {
+    int i;
+    Timer t;
+
+    if (lockUart(timeout)) return -1;
+
+    clearFlags();
+    _state.res = res;
+    _state.n = 0;
+    for (i = 0; i < strlen(cmd); i ++) {
+        putUart(cmd[i]);
+    }
+    putUart('\r');
+    putUart('\n');
+    unlockUart();
+    INFO("command: '%s'\r\n", cmd);
+
+    if (timeout) {
+        t.start();
+        for (;;) {
+            if (_state.ok) break;
+            if (_state.failure || t.read_ms() > timeout) {
+                WARN("failure or timeout\r\n");
+                _state.res = RES_NULL;
+                return -1;
+            }
+        }
+        t.stop();
+    }
+    INFO("ok\r\n");
+    _state.res = RES_NULL;
+
+    return 0;
+}
+
+int GSwifi::sendData(const char * data, int len, int timeout, const char * cmd) {
+    int i;
+    Timer t;
+
+    if (lockUart(timeout)) return -1;
+
+    clearFlags();
+    for (i = 0; i < strlen(cmd); i ++) {
+        putUart(cmd[i]);
+    }
+    for (i = 0; i < len; i ++) {
+        putUart(data[i]);
+    }
+    unlockUart();
+    INFO("data: '%s' %d\r\n", cmd, len);
+
+    if (timeout) {
+        t.start();
+        for (;;) {
+            if (_state.ok) break;
+            if (_state.failure || t.read_ms() > timeout) {
+                WARN("failure or timeout\r\n");
+                return -1;
+            }
+        }
+        t.stop();
+    }
+
+    return i;
+}
+
+
+int GSwifi::cmdAT () {
+    return sendCommand("AT");
+}
+
+int GSwifi::cmdE (bool n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "ATE%d", n ? 1 : 0);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdR (bool n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT&R%d", n ? 1 : 0);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdNMAC (const char *s) {
+    int r;
+    char cmd[CFG_CMD_SIZE];
+    const char xmac[] = "00:1D:C9:01:99:99";
+    if (s) {
+        sprintf(cmd, "AT+NMAC2=%s", s);
+        r = sendCommand(cmd);
+    } else {
+        sprintf(cmd, "AT+NMAC=?");
+        r = sendCommand(cmd, RES_MACADDRESS);
+        if (!r && strncmp(_state.mac, xmac, 17) == 0) {
+            r = -1;
+        }
+    }
+    return r;
+}
+
+int GSwifi::cmdWREGDOMAIN (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WREGDOMAIN=%d", n);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdWS () {
+    return sendCommand("AT+WS");
+}
+
+int GSwifi::cmdWM (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WM=%d", n);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdWA (const char *s) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WA=%s", s);
+    return sendCommand(cmd, RES_DHCP, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdWD () {
+    return sendCommand("AT+WD");
+}
+
+int GSwifi::cmdWWPS (bool n, const char *p) {
+    char cmd[CFG_CMD_SIZE];
+    if (p) {
+        sprintf(cmd, "AT+WWPS=2,%s", p);
+    } else {
+        sprintf(cmd, "AT+WWPS=%d", n ? 1 : 0);
+    }
+    return sendCommand(cmd, RES_WPS, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdNSTAT () {
+    return sendCommand("AT+NSTAT=?");
+}
+
+int GSwifi::cmdWSTATUS () {
+    return sendCommand("AT+WSTATUS", RES_STATUS);
+}
+
+int GSwifi::cmdWRSSI () {
+    return sendCommand("AT+WRSSI=?", RES_RSSI);
+}
+
+int GSwifi::cmdWAUTH (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WAUTH=%d", n);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdWWEP (int n, const char *s) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WWEP%d=%s", n, s);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdWPAPSK (const char *s, const char *p) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WPAPSK=%s,%s", s, p);
+    return sendCommand(cmd, RES_NULL, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdWRXACTIVE (bool n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WRXACTIVE=%d", n ? 1 : 0);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdWRXPS (bool n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WRXPS=%d", n ? 1 : 0);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdWP (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WP=%d", n);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdNDHCP (bool n, const char *s, int m) {
+    char cmd[CFG_CMD_SIZE];
+    if (n) {
+        if (s) {
+            sprintf(cmd, "AT+NDHCP=1,%s", s);
+        } else {
+            sprintf(cmd, "AT+NDHCP=1");
+        }
+        return sendCommand(cmd, RES_DHCP, m);
+    } else {
+        return sendCommand("AT+NDHCP=0");
+    }
+}
+
+int GSwifi::cmdDHCPSRVR (bool n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+DHCPSRVR=%d", n ? 1 : 0);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdNSET (const char *s, const char *t, const char *u) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+NSET=%s,%s,%s", s, t, u);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdDNS (bool n, const char *s) {
+    char cmd[CFG_CMD_SIZE];
+    if (n) {
+        if (s) {
+            sprintf(cmd, "AT+DNS=1,%s", s);
+        } else {
+            sprintf(cmd, "AT+DNS=1," CFG_DNSNAME);
+        }
+    } else {
+        sprintf(cmd, "AT+DNS=0");
+    }
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdDNSLOOKUP (const char *s) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+DNSLOOKUP=%s", s);
+    return sendCommand(cmd, RES_DNSLOOKUP, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdDNSSET (const char *s) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+DNSSET=%s", s);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdSTORENWCONN () {
+    return sendCommand("AT+STORENWCONN");
+}
+
+int GSwifi::cmdRESTORENWCONN () {
+    return sendCommand("AT+RESTORENWCONN");
+}
+
+int GSwifi::cmdBDATA (bool n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+BDATA=%d", n ? 1 : 0);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdNCTCP (const char *s, int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+NCTCP=%s,%d", s, n);
+    return sendCommand(cmd, RES_CONNECT, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdNCUDP (const char *s, int n, int m) {
+    char cmd[CFG_CMD_SIZE];
+    if (m) {
+        sprintf(cmd, "AT+NCUDP=%s,%d,%d", s, n, m);
+    } else {
+        sprintf(cmd, "AT+NCUDP=%s,%d", s, n);
+    }
+    return sendCommand(cmd, RES_CONNECT, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdNSTCP (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+NSTCP=%d", n);
+    return sendCommand(cmd, RES_CONNECT);
+}
+
+int GSwifi::cmdNSUDP (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+NSUDP=%d", n);
+    return sendCommand(cmd, RES_CONNECT);
+}
+
+int GSwifi::cmdNCLOSE (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+NCLOSE=%d", n);
+    return sendCommand(cmd, RES_NULL, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdNCLOSEALL () {
+    return sendCommand("AT+NCLOSEALL", RES_NULL, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdHTTPCONF (int n, const char *s) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+HTTPCONF=%d,%s", n, s);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdHTTPCONFDEL (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+HTTPCONFDEL=%d", n);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdHTTPOPEN (const char *s, int n, bool m) {
+    char cmd[CFG_CMD_SIZE];
+    if (m) {
+        sprintf(cmd, "AT+HTTPOPEN=%s,%d,1", s, n);
+    } else {
+        sprintf(cmd, "AT+HTTPOPEN=%s,%d", s, n);
+    }
+    return sendCommand(cmd, RES_CONNECT, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdHTTPSEND (int n, bool m, const char *s, int t) {
+    char cmd[CFG_CMD_SIZE];
+    if (m) {
+        sprintf(cmd, "AT+HTTPSEND=%d,3,%d,%s,%d", n, CFG_TIMEOUT / 1000, s, t);
+    } else {
+        sprintf(cmd, "AT+HTTPSEND=%d,1,%d,%s", n, CFG_TIMEOUT / 1000, s);
+    }
+    return sendCommand(cmd, RES_CONNECT, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdHTTPCLOSE (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+HTTPCLOSE=%d", n);
+    return sendCommand(cmd, RES_NULL, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdPSDPSLEEP (int n) {
+    char cmd[CFG_CMD_SIZE];
+    if (n) {
+        sprintf(cmd, "AT+PSDPSLEEP=%d", n);
+    } else {
+        sprintf(cmd, "AT+PSDPSLEEP");
+    }
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdPSSTBY (int n, int m) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+PSSTBY=%d,0,%d,%d", n, m, m);
+    return sendCommand(cmd, RES_NULL, 0);
+}
+
+int GSwifi::cmdWEBPROV (const char *s, const char *p) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+WEBPROV=%s,%s", s, p);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdSETTIME (const char *s, const char *t) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+SETTIME=%s,%s", s, t);
+    return sendCommand(cmd);
+}
+
+int GSwifi::cmdGETTIME () {
+    return sendCommand("AT+GETTIME=?", RES_TIME);
+}
+
+int GSwifi::cmdNTIMESYNC (bool n, const char *s, int m) {
+    char cmd[CFG_CMD_SIZE];
+    if (n) {
+        if (m) {
+            sprintf(cmd, "AT+NTIMESYNC=1,%s,%d,1,%d", s, CFG_TIMEOUT / 1000, m);
+        } else {
+            sprintf(cmd, "AT+NTIMESYNC=1,%s,%d,0", s, CFG_TIMEOUT / 1000);
+        }
+    } else {
+        sprintf(cmd, "AT+NTIMESYNC=0");
+    }
+    return sendCommand(cmd, RES_NULL, CFG_TIMEOUT);
+}
+
+int GSwifi::cmdDGPIO (int n, int m) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "AT+DGPIO=%d,%d", n, m);
+    return sendCommand(cmd);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GSwifi/GSwifi_hal.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -0,0 +1,221 @@
+/* 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"
+
+void GSwifi::setReset (bool flg) {
+    if (flg) {
+        // low
+        _reset.output();
+        _reset = 0;
+    } else {
+        // high z
+        _reset.input();
+        _reset.mode(PullNone);
+    }
+}
+
+void GSwifi::setAlarm (bool flg) {
+    if (_alarm == NULL) return;
+
+    if (flg) {
+        // low
+        _alarm->output(); // low
+        _alarm->write(0);
+    } else {
+        // high
+        _alarm->input(); // high
+        _alarm->mode(PullUp);
+    }
+}
+
+void GSwifi::isrUart () {
+    recvData(getUart());
+}
+
+int GSwifi::getUart () {
+#ifdef CFG_UART_DIRECT
+    return _uart->RBR;
+#else
+    return _gs.getc();
+#endif
+}
+
+void GSwifi::putUart (char c) {
+#ifdef CFG_UART_DIRECT
+    while(!(_uart->LSR & (1<<5)));
+    _uart->THR = c;
+#else
+    _gs.putc(c);
+#endif
+}
+
+void GSwifi::setRts (bool flg) {
+    if (flg) {
+        // low
+        if (_flow == 1) {
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
+            _uart->MCR |= (1<<6); // RTSEN
+#endif
+        } else
+        if (_flow == 2) {
+            if (_rts) {
+                _rts->write(0); // low
+            }
+        }
+    } else {
+        // high
+        if (_flow == 1) {
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
+            _uart->MCR &= ~(1<<6); // RTS off
+            _uart->MCR &= ~(1<<1);
+#endif
+        } else
+        if (_flow == 2) {
+            if (_rts) {
+                _rts->write(1); // high
+            }
+        }
+    }
+}
+
+int GSwifi::lockUart (int ms) {
+    Timer t;
+
+    if (_state.mode != MODE_COMMAND) {
+        t.start();
+        while (_state.mode != MODE_COMMAND) {
+            if (t.read_ms() >= ms) {
+                WARN("lock timeout\r\n");
+                return -1;
+            }
+        }
+    }
+
+#ifdef RTOS_H
+    if (_mutexUart.lock(ms) != osOK) return -1;
+#endif
+
+    if (_flow == 1) {
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088)
+        if (!(_uart->MSR & (1<<4))) {
+            // CTS check
+            t.start();
+            while (!(_uart->MSR & (1<<4))) {
+                if (t.read_ms() >= ms) {
+                    DBG("cts timeout\r\n");
+                    return -1;
+                }
+            }
+        }
+#endif
+    } else
+    if (_flow == 2) {
+        if (_cts && _cts->read()) {
+            // CTS check
+            t.start();
+            while (_cts->read()) {
+                if (t.read_ms() >= ms) {
+                    DBG("cts timeout\r\n");
+                    return -1;
+                }
+            }
+        }
+    }
+    setRts(false);
+    return 0;
+}
+
+void GSwifi::unlockUart () {
+    setRts(true);
+#ifdef RTOS_H
+    _mutexUart.unlock();
+#endif
+}
+
+void GSwifi::initUart (PinName cts, PinName rts, PinName alarm, int baud) {
+
+    _baud = baud;
+    if (_baud) _gs.baud(_baud);
+    _gs.attach(this, &GSwifi::isrUart, Serial::RxIrq);
+
+    _uart = NULL;
+    _cts = NULL;
+    _rts = NULL;
+    _flow = 0;
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+    _uart = LPC_UART1;
+    if (cts == p12) { // CTS input (P0_17)
+        _uart->MCR |= (1<<7); // CTSEN
+        LPC_PINCON->PINSEL1 &= ~(3 << 2);
+        LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
+    } else
+    if (cts != NC) {
+        _cts = new DigitalIn(cts);
+    }
+    if (rts == P0_22) { // RTS output (P0_22)
+        _uart->MCR |= (1<<6); // RTSEN
+        LPC_PINCON->PINSEL1 &= ~(3 << 12);
+        LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS
+        _flow = 1;
+    } else
+    if (rts != NC) {
+        _rts = new DigitalOut(rts);
+        _flow = 2;
+    }
+#elif defined(TARGET_LPC11U24)
+    _uart = LPC_USART;
+    if (cts == p21) { // CTS input (P0_7)
+        _uart->MCR |= (1<<7); // CTSEN
+        LPC_IOCON->PIO0_7 &= ~0x07;
+        LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
+    } else
+    if (cts != NC) {
+        _cts = new DigitalIn(cts);
+    }
+    if (rts == p22) { // RTS output (P0_17)
+        _uart->MCR |= (1<<6); // RTSEN
+        LPC_IOCON->PIO0_17 &= ~0x07;
+        LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
+        _flow = 1;
+    } else
+    if (rts != NC) {
+        _rts = new DigitalOut(rts);
+        _flow = 2;
+    }
+#elif defined(TARGET_LPC4088)
+    _uart = (LPC_UART_TypeDef*)LPC_UART2;
+    if (cts != NC && rts != NC) {
+        _cts = new DigitalIn(cts);
+        _rts = new DigitalOut(rts);
+        _flow = 2;
+    }
+#else
+    if (cts != NC && rts != NC) {
+        _cts = new DigitalIn(cts);
+        _rts = new DigitalOut(rts);
+        _flow = 2;
+    }
+#endif
+
+    if (alarm != NC) {
+        _alarm = new DigitalInOut(alarm);
+    } else {
+        _alarm = NULL;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GSwifi/GSwifi_http.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -0,0 +1,175 @@
+/* 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"
+
+int GSwifi::httpGet (const char *host, int port, const char *uri, bool ssl, const char *user, const char *pwd) {
+    char ip[17];
+    int cid;
+
+    if (getHostByName(host, ip)) return -1;
+    if (! port) {
+        if (ssl) {
+            port = 443;
+        } else {
+            port = 80;
+        }
+    }
+
+    if (cmdHTTPCONF(3, "close")) return -1; // Connection
+    cmdHTTPCONFDEL(5);
+    cmdHTTPCONFDEL(7);
+    cmdHTTPCONF(11, host); // Host
+    if (user && pwd) {
+        char tmp[CFG_CMD_SIZE], tmp2[CFG_CMD_SIZE];
+        snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
+        base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
+        sprintf(tmp, "Basic %s", tmp2);
+        cmdHTTPCONF(2, tmp); // Authorization
+    } else {
+        cmdHTTPCONFDEL(2);
+    }
+
+    if (cmdHTTPOPEN(ip, port, ssl)) return -1;
+    if (_state.cid < 0) return -1;
+    cid = _state.cid;
+    _con[cid].protocol = PROTO_HTTPGET;
+    _con[cid].type = TYPE_CLIENT;
+
+    cmdHTTPSEND(cid, false, uri); // GET
+    return cid;
+}
+
+int GSwifi::httpPost (const char *host, int port, const char *uri, const char *body, bool ssl, const char *user, const char *pwd) {
+    char cmd[CFG_CMD_SIZE];
+    char ip[17];
+    int cid, len;
+
+    if (getHostByName(host, ip)) return -1;
+    if (! port) {
+        if (ssl) {
+            port = 443;
+        } else {
+            port = 80;
+        }
+    }
+    len = strlen(body);
+
+    if (cmdHTTPCONF(3, "close")) return -1; // Connection
+    sprintf(cmd, "%d", len);
+    cmdHTTPCONF(5, cmd); // Content-Length
+    cmdHTTPCONF(7, "application/x-www-form-urlencoded"); // Content-type
+    cmdHTTPCONF(11, host); // Host
+    if (user && pwd) {
+        char tmp[CFG_CMD_SIZE], tmp2[CFG_CMD_SIZE];
+        snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
+        base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
+        sprintf(tmp, "Basic %s", tmp2);
+        cmdHTTPCONF(2, tmp); // Authorization
+    } else {
+        cmdHTTPCONFDEL(2);
+    }
+
+    if (cmdHTTPOPEN(ip, port, ssl)) return -1;
+    if (_state.cid < 0) return -1;
+    cid = _state.cid;
+    _con[cid].protocol = PROTO_HTTPPOST;
+    _con[cid].type = TYPE_CLIENT;
+
+    cmdHTTPSEND(cid, true, uri, len); // POST
+    sprintf(cmd, "\x1bH%X", cid);
+    sendData(body, len, DEFAULT_WAIT_RESP_TIMEOUT, cmd);
+    return cid;
+}
+
+
+
+/* base64encode code from 
+ * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+ */
+int GSwifi::base64encode (const char *input, int length, char *output, int len) {
+    static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+    unsigned int c, c1, c2, c3;
+
+    if (len < ((((length-1)/3)+1)<<2)) return -1;
+    for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
+        c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
+        c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
+        c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
+
+        c = ((c1 & 0xFC) >> 2);
+        output[j+0] = base64[c];
+        c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
+        output[j+1] = base64[c];
+        c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
+        output[j+2] = (length>i+1)?base64[c]:'=';
+        c = (c3 & 0x3F);
+        output[j+3] = (length>i+2)?base64[c]:'=';
+    }
+    output[(((length-1)/3)+1)<<2] = '\0';
+    return 0;
+}
+
+
+/* urlencode code from 
+ * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+ */
+int GSwifi::urlencode (const char *str, char *buf, int len) {
+//  char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
+    const char *pstr = str;
+    char *pbuf = buf;
+
+    if (len < (strlen(str) * 3 + 1)) return -1;
+    while (*pstr) {
+        if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 
+            *pbuf++ = *pstr;
+        else if (*pstr == ' ') 
+            *pbuf++ = '+';
+        else 
+            *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
+        pstr++;
+    }
+    *pbuf = '\0';
+    return 0;
+}
+
+/* urldecode code from 
+ * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+ */
+int GSwifi::urldecode (const char *str, char *buf, int len) {
+//  char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf;
+    const char *pstr = str;
+    char *pbuf = buf;
+
+    if (len < (strlen(str) / 3 - 1)) return -1;
+    while (*pstr) {
+        if (*pstr == '%') {
+            if (pstr[1] && pstr[2]) {
+                *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
+                pstr += 2;
+            }
+        } else if (*pstr == '+') { 
+            *pbuf++ = ' ';
+        } else {
+            *pbuf++ = *pstr;
+        }
+        pstr++;
+    }
+    *pbuf = '\0';
+    return 0;
+}
--- /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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GSwifi/GSwifi_sock.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -0,0 +1,174 @@
+/* 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"
+
+int GSwifi::getHostByName(const char * host, char * ip)
+{
+    int i, flg = 0;
+
+    for (i = 0; i < strlen(host); i ++) {
+        if ((host[i] < '0' || host[i] > '9') && host[i] != '.') {
+            flg = 1;
+            break;
+        }
+    }
+    if (!flg) {
+        strncpy(ip, host, 16);
+        return 0;
+    }
+
+    if (cmdDNSLOOKUP(host)) {
+        // retry
+        wait_ms(1000);
+        if (cmdDNSLOOKUP(host)) return -1;
+    }
+    strncpy(ip, _state.resolv, 16);
+    return 0;
+}
+
+int GSwifi::open (Protocol proto, const char *ip, int port, int src) {
+    _state.cid = -1;
+    _state.acid = -1;
+    if (proto == PROTO_TCP) {
+        if (cmdNCTCP(ip, port)) return -1;
+    } else {
+        if (cmdNCUDP(ip, port, src)) return -1;
+    }
+    if (_state.cid < 0) return -1;
+    _con[_state.cid].protocol = proto;
+    _con[_state.cid].type = TYPE_CLIENT;
+    return _state.cid;
+}
+
+int GSwifi::listen (Protocol proto, int port) {
+    _state.cid = -1;
+    _state.acid = -1;
+    if (proto == PROTO_TCP) {
+        if (cmdNSTCP(port)) return -1;
+    } else {
+        if (cmdNSUDP(port)) return -1;
+    }
+    if (_state.cid < 0) return -1;
+    _con[_state.cid].protocol = proto;
+    _con[_state.cid].type = TYPE_SERVER;
+    return _state.cid;
+}
+
+int GSwifi::close (int cid) {
+    if (cid < 0 || cid >= 16) return -1;
+    _con[cid].connected = false;
+    return cmdNCLOSE(cid);
+}
+
+int GSwifi::send (int cid, const char *buf, int len) {
+    char cmd[CFG_CMD_SIZE];
+
+    if (cid < 0 || cid >= 16) return -1;
+    if (!_con[cid].connected) return -1;
+
+    if ((_con[cid].protocol == PROTO_TCP) ||
+      (_con[cid].protocol == PROTO_UDP && _con[cid].type == TYPE_CLIENT) ||
+      (_con[cid].protocol == PROTO_HTTPD)) {
+        if (len > CFG_DATA_SIZE) len = CFG_DATA_SIZE;
+        sprintf(cmd, "\x1bZ%X%04d", cid, len);
+        return sendData(buf, len, DEFAULT_WAIT_RESP_TIMEOUT, cmd);
+    } else {
+        return -1;
+    }
+}
+
+int GSwifi::sendto (int cid, const char *buf, int len, const char *ip, int port) {
+    char cmd[CFG_CMD_SIZE];
+
+    if (cid < 0 || cid >= 16) return -1;
+    if (!_con[cid].connected) return -1;
+
+    if ((_con[cid].protocol == PROTO_UDP && _con[cid].type == TYPE_SERVER)) {
+        if (len > CFG_DATA_SIZE) len = CFG_DATA_SIZE;
+        sprintf(cmd, "\x1bY%X%s:%d:%04d", cid, ip, port, len);
+        return sendData(buf, len, DEFAULT_WAIT_RESP_TIMEOUT, cmd);
+    } else {
+        return -1;
+    }
+}
+
+int GSwifi::recv (int cid, char *buf, int len) {
+    int i;
+
+    if (cid < 0 || cid >= 16) return -1;
+    if (!_con[cid].connected) return -1;
+
+    if (_con[cid].buf == NULL) return 0;
+    while (!_con[cid].received && _state.mode != MODE_COMMAND);
+    _con[cid].received = false;
+    for (i = 0; i < len; i ++) {
+        if (_con[cid].buf->dequeue(&buf[i]) == false) break;
+    }
+    setRts(true);
+    return i;
+}
+
+int GSwifi::recvfrom (int cid, char *buf, int len, char *ip, int *port) {
+    int i;
+
+    if (cid < 0 || cid >= 16) return -1;
+    if (!_con[cid].connected) return -1;
+
+    if (_con[cid].buf == NULL) return 0;
+    while (!_con[cid].received && _state.mode != MODE_COMMAND);
+    _con[cid].received = false;
+    for (i = 0; i < len; i ++) {
+        if (_con[cid].buf->dequeue(&buf[i]) == false) break;
+    }
+    strncpy(ip, _con[cid].ip, 16);
+    *port = _con[cid].port;
+    setRts(true);
+    return i;
+}
+
+int GSwifi::readable (int cid) {
+    if (cid < 0 || cid >= 16) return -1;
+    if (!_con[cid].connected) return -1;
+    if (_con[cid].buf == NULL) return -1;
+    return _con[cid].buf->available();
+}
+
+bool GSwifi::isConnected (int cid) {
+    if (cid < 0 || cid >= 16) return false;
+    return _con[cid].connected;
+}
+
+int GSwifi::accept (int cid) {
+    int i;
+    if (cid < 0 || cid >= 16) return -1;
+    for (i = 0; i < 16; i ++) {
+        if (_con[i].connected && _con[i].accept && _con[i].parent == cid) {
+            _con[i].accept = false;
+            return i;
+        }
+    }
+    return -1;
+}
+
+int GSwifi::getRemote(int cid, char **ip, int *port) {
+    if (cid < 0 || cid >= 16) return -1;
+    *ip = _con[cid].ip;
+    *port = _con[cid].port;
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GSwifi/GSwifi_util.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -0,0 +1,100 @@
+/* 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"
+
+int GSwifi::x2i (char c) {
+    if (c >= '0' && c <= '9') {
+        return c - '0';
+    } else
+    if (c >= 'A' && c <= 'F') {
+        return c - 'A' + 10;
+    } else
+    if (c >= 'a' && c <= 'f') {
+        return c - 'a' + 10;
+    }
+    return 0;
+}
+
+char GSwifi::i2x (int i) {
+    if (i >= 0 && i <= 9) {
+        return i + '0';
+    } else
+    if (i >= 10 && i <= 15) {
+        return i - 10 + 'A';
+    }
+    return 0;
+}
+
+int GSwifi::from_hex (int ch) {
+  return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
+}
+
+int GSwifi::to_hex (int code) {
+  static char hex[] = "0123456789abcdef";
+  return hex[code & 15];
+}
+
+
+int GSwifi::setRegion (int reg) {
+    return cmdWREGDOMAIN(reg);
+}
+
+int GSwifi::getRssi () {
+    cmdWRSSI();
+    return _state.rssi;
+}
+
+int GSwifi::powerSave (int active, int save) {
+    cmdWRXACTIVE(active);
+    return cmdWRXPS(save);
+}
+
+int GSwifi::setRfPower (int power) {
+    if (power < 0 || power > 7) return false;
+    return cmdWP(power);
+}
+
+int GSwifi::setTime (time_t time) {
+    char dmy[16], hms[16];
+    struct tm *t = localtime(&time);
+
+    sprintf(dmy, "%d/%d/%d", t->tm_mday, t->tm_mon + 1, t->tm_year + 1900);
+    sprintf(hms, "%d:%d:%d", t->tm_hour, t->tm_min, t->tm_sec);
+    return cmdSETTIME(dmy, hms);
+}
+
+time_t GSwifi::getTime () {
+    cmdGETTIME();
+    return _state.time;
+}
+
+int GSwifi::ntpdate (char *host, int sec) {
+    char ip[17];
+
+    if (getHostByName(host, ip)) return -1;
+    return cmdNTIMESYNC(true, ip, sec);
+}
+
+int GSwifi::setGpio (int port, int out) {
+    return cmdDGPIO(port, out);
+}
+
+int GSwifi::provisioning (char *user, char *pass) {
+    return cmdWEBPROV(user, pass);
+}
--- a/GSwifiInterface.cpp	Wed Jan 30 05:52:14 2013 +0000
+++ b/GSwifiInterface.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -4,31 +4,41 @@
 
 #include "GSwifiInterface.h"
 
-GSwifiInterface::GSwifiInterface( PinName tx, PinName rx, PinName cts, PinName rts, PinName reset,
-                                const char * ssid, const char * phrase, Security sec) :
-    GSwifi(tx, rx, cts, rts, reset, ssid, phrase, sec)
+GSwifiInterface::GSwifiInterface( PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm, int baud) :
+    GSwifi(tx, rx, cts, rts, reset, alarm, baud)
 {
 }
 
-int GSwifiInterface::init()
+int GSwifiInterface::init(const char* name)
 {
     _state.dhcp = true;
-    return 0;
-}
-
-int GSwifiInterface::init(const char* ip, const char* mask, const char* gateway)
-{
-    _state.dhcp = false;
-    strncpy(_ip, ip, sizeof(_ip));
-    strncpy(_netmask, mask, sizeof(_netmask));
-    strncpy(_gateway, gateway, sizeof(_gateway));
+    strncpy(_state.name, name, sizeof(_state.name));
 
     return 0;
 }
 
-int GSwifiInterface::connect()
+int GSwifiInterface::init(const char* ip, const char* mask, const char* gateway, const char* name)
 {
-    return join();
+    _state.dhcp = false;
+    strncpy(_state.ip, ip, sizeof(_state.ip));
+    strncpy(_state.netmask, mask, sizeof(_state.netmask));
+    strncpy(_state.gateway, gateway, sizeof(_state.gateway));
+    strncpy(_state.name, name, sizeof(_state.name));
+
+    return 0;
+}
+
+int GSwifiInterface::connect(Security sec, const char* ssid, const char* phrase, WiFiMode mode)
+{
+    switch (mode) {
+    case WM_INFRASTRUCTURE:
+        return join(sec, ssid, phrase);
+    case WM_ADHOCK:
+        return adhock(sec, ssid, phrase);
+    case WM_LIMITEDAP:
+        return limitedap(sec, ssid, phrase);
+    }
+    return -1;
 }
 
 int GSwifiInterface::disconnect()
@@ -36,8 +46,22 @@
     return GSwifi::disconnect();
 }
 
+char * GSwifiInterface::getMACAddress()
+{
+    return _state.mac;
+}
+
 char * GSwifiInterface::getIPAddress()
 {
+    return _state.ip;
+}
 
-    return _ip;
-}
\ No newline at end of file
+char * GSwifiInterface::getGateway()
+{
+    return _state.gateway;
+}
+
+char * GSwifiInterface::getNetworkMask()
+{
+    return _state.netmask;
+}
--- a/GSwifiInterface.h	Wed Jan 30 05:52:14 2013 +0000
+++ b/GSwifiInterface.h	Thu Oct 31 06:41:45 2013 +0000
@@ -1,4 +1,5 @@
 /* GSwifiInterface.h */
+/* EthernetInterface.h */
 /* Copyright (C) 2012 mbed.org, MIT License
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
@@ -20,8 +21,8 @@
  *  port to the GainSpan Wi-FI module GS1011
  */
  
-#ifndef GSwifiINTERFACE_H_
-#define GSwifiINTERFACE_H_
+#ifndef GSWIFIINTERFACE_H_
+#define GSWIFIINTERFACE_H_
 
 #include "GSwifi.h"
 
@@ -38,18 +39,17 @@
     * \param rx mbed pin to use for rx line of Serial interface
     * \param cts mbed pin to use for cts line of Serial interface
     * \param rts mbed pin to use for rts line of Serial interface
-    * \param reset reset pin of the wifi module ()
-    * \param ssid ssid of the network
-    * \param phrase WEP or WPA key
-    * \param sec Security type (NONE, WEP_128 or WPA)
+    * \param reset reset pin of the wifi module
+    * \param alarm alarm pin of the wifi module (default: NC)
+    * \param baud baud rate of Serial interface (default: 9600)
     */
-  GSwifiInterface(PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, const char * ssid, const char * phrase, Security sec = SEC_NONE);
+  GSwifiInterface(PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm = NC, int baud = 9600);
 
   /** Initialize the interface with DHCP.
   * Initialize the interface and configure it to use DHCP (no connection at this point).
   * \return 0 on success, a negative number on failure
   */
-  int init(); //With DHCP
+  int init(const char* name = NULL); //With DHCP
 
   /** Initialize the interface with a static IP address.
   * Initialize the interface and configure it with the following static configuration (no connection at this point).
@@ -58,13 +58,17 @@
   * \param gateway the gateway to use
   * \return 0 on success, a negative number on failure
   */
-  int init(const char* ip, const char* mask, const char* gateway);
+  int init(const char* ip, const char* mask, const char* gateway, const char* name = NULL);
 
   /** Connect
   * Bring the interface up, start DHCP if needed.
+  * \param sec the Wi-Fi security type
+  * \param ssid the Wi-Fi SSID
+  * \param phrase the Wi-Fi passphrase or security key
+  * \param mode the Wi-Fi mode
   * \return 0 on success, a negative number on failure
   */
-  int connect();
+  int connect(Security sec, const char* ssid, const char* phrase, WiFiMode mode = WM_INFRASTRUCTURE);
   
   /** Disconnect
   * Bring the interface down
@@ -72,19 +76,32 @@
   */
   int disconnect();
   
-  /** Get IP address
-  *
-  * @ returns ip address
-  */
+  /** Get the MAC address of your Ethernet interface
+   * \return a pointer to a string containing the MAC address
+   */
+  char* getMACAddress();
+  
+  /** Get the IP address of your Ethernet interface
+   * \return a pointer to a string containing the IP address
+   */
   char* getIPAddress();
-  
-private:
-    char _ip_string[20];
-    bool _ip_set;
+
+  /** Get the Gateway address of your Ethernet interface
+   * \return a pointer to a string containing the Gateway address
+   */
+  char* getGateway();
+ 
+  /** Get the Network mask of your Ethernet interface
+   * \return a pointer to a string containing the Network mask
+   */
+  char* getNetworkMask();
+
 };
 
 #include "TCPSocketConnection.h"
 #include "TCPSocketServer.h"
+
+#include "Endpoint.h"
 #include "UDPSocket.h"
 
-#endif /* WIFLYINTERFACE_H_ */
+#endif /* GSWIFIINTERFACE_H_ */
--- a/Socket/Endpoint.cpp	Wed Jan 30 05:52:14 2013 +0000
+++ b/Socket/Endpoint.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -40,7 +40,7 @@
 int Endpoint::set_address(const char* host, const int port) {
     //Resolve DNS address or populate hard-coded IP address
     _port = port;
-    return _ewifi->gethostbyname(host, _ipAddress) == true ? 0 : -1;
+    return _ewifi->getHostByName(host, _ipAddress);
 }
 
 char* Endpoint::get_address() {
--- a/Socket/Socket.cpp	Wed Jan 30 05:52:14 2013 +0000
+++ b/Socket/Socket.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -40,13 +40,11 @@
 }
 
 int Socket::close() {
-    char cmd[CFG_CMD_SIZE];
-
     if (_cid < 0) return 0;
 
-    sprintf(cmd, "AT+NCLOSE=%X", _cid);
+    _wifi->close(_cid);
     _cid = -1;
-    return _wifi->sendCommand(cmd);    
+    return 0;
 }
 
 Socket::~Socket() {
--- a/Socket/TCPSocketConnection.cpp	Wed Jan 30 05:52:14 2013 +0000
+++ b/Socket/TCPSocketConnection.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -26,66 +26,45 @@
 
 int TCPSocketConnection::connect(const char* host, const int port)
 {  
-    char cmd[CFG_CMD_SIZE];
-    char ip[16];
+    if (set_address(host, port) != 0) return -1;
 
-    if (_cid < 0 || !_wifi->is_connected(_cid)) {
-        // Socket open
-        if (_wifi->gethostbyname(host, ip) == false) return -1;
-        _server = false;
-        sprintf(cmd, "AT+NCTCP=%s,%d", ip, port);
-        if (_wifi->sendCommand(cmd, GSwifi::RES_CONNECT) == false) return -1;
-        _cid = _wifi->readCID();
-        return 0;
-    }
+    _server = false;
+    _cid = _wifi->open(GSwifi::PROTO_TCP, get_address(), get_port());
+    if (_cid < 0) return -1;
 
-    return -1;
+    return 0;
 }
 
 bool TCPSocketConnection::is_connected(void)
 {
-    return _wifi->is_connected(_cid);
+    bool _is_connected = _wifi->isConnected(_cid);
+    if (!_is_connected) _cid = -1;
+    return _is_connected;
 }
 
 int TCPSocketConnection::send(char* data, int length)
 {
-    char cmd[CFG_CMD_SIZE];
-    Timer tmr;
-
-    if (!_blocking) {
-        tmr.start();
-        while (tmr.read_ms() < _timeout) {
-            if (_wifi->writeable())
-                break;
-        }
-        if (tmr.read_ms() >= _timeout) {
-            return -1;
-        }
-    }
+    if (_cid < 0 || !is_connected()) return -1;
 
     // TCP Client/Server
-    sprintf(cmd, "\x1bZ%X%04d", _cid, length);
-    _wifi->send(cmd, strlen(cmd));
-    return _wifi->send(data, length, GSwifi::RES_NORMAL);
+    return _wifi->send(_cid, data, length);
 }
 
 // -1 if unsuccessful, else number of bytes written
 int TCPSocketConnection::send_all(char* data, int length)
 {
-    char cmd[CFG_CMD_SIZE];
     Timer tmr;
     int idx = 0;
+
+    if (_cid < 0 || !is_connected()) return -1;
+
     tmr.start();
-
     // TCP Client/Server
-    sprintf(cmd, "\x1bZ%X%04d", _cid, length);
-    _wifi->send(cmd, strlen(cmd));
-
     while ((tmr.read_ms() < _timeout) || _blocking) {
 
-        idx += _wifi->send(data, length, GSwifi::RES_NORMAL);
+        idx += _wifi->send(_cid, &data[idx], length - idx);
+        if (idx < 0) return -1;
 
-        if (idx == -1) return -1;
         if (idx == length)
             return idx;
     }
@@ -97,9 +76,10 @@
 {
     Timer tmr;
     int time = -1;
-    
-    
-    if (!_blocking) {
+
+    if (_cid < 0 || !is_connected()) return -1;
+
+    if (_blocking) {
         tmr.start();
         while (time < _timeout + 20) {
             if (_wifi->readable(_cid)) {
@@ -112,14 +92,9 @@
         }
     }
 
+    int nb_available = _wifi->recv(_cid, data, length);
 
-    while(!_wifi->readable(_cid));
-    int nb_available = _wifi->readable(_cid);
-    for (int i = 0; i < min(nb_available, length); i++) {
-        data[i] = _wifi->getc(_cid);
-    }
-
-    return min(nb_available, length);
+    return nb_available;
 }
 
 
@@ -130,14 +105,14 @@
     int idx = 0;
     int time = -1;
 
+    if (_cid < 0 || !is_connected()) return -1;
+
     tmr.start();
     
     while (time < _timeout || _blocking) {
 
-        int nb_available = _wifi->readable(_cid);
-        for (int i = 0; i < min(nb_available, length); i++) {
-            data[idx++] = _wifi->getc(_cid);
-        }
+        idx += _wifi->recv(_cid, &data[idx], length - idx);
+        if (idx < 0) return -1;
 
         if (idx == length)
             break;
@@ -148,12 +123,12 @@
     return (idx == 0) ? -1 : idx;
 }
 
-void TCPSocketConnection::confCID (int cid) {
+void TCPSocketConnection::acceptCID (int cid) {
     char *ip;
     int port;
     _server = true;
     _cid = cid;
-    if (_wifi->readRemote(_cid, &ip, &port)) {
+    if (!_wifi->getRemote(_cid, &ip, &port)) {
         set_address(ip, port);
     }
 }
--- a/Socket/TCPSocketConnection.h	Wed Jan 30 05:52:14 2013 +0000
+++ b/Socket/TCPSocketConnection.h	Thu Oct 31 06:41:45 2013 +0000
@@ -75,7 +75,7 @@
     */
     int receive_all(char* data, int length);
 
-    void confCID (int cid);
+    void acceptCID (int cid);
 };
 
 #endif
--- a/Socket/TCPSocketServer.cpp	Wed Jan 30 05:52:14 2013 +0000
+++ b/Socket/TCPSocketServer.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -31,15 +31,12 @@
 }
 
 int TCPSocketServer::listen(int backlog) {
-    char cmd[CFG_CMD_SIZE];
-
     _server = true;
     if (_cid < 0) {
         // Socket open
         _server = false;
-        sprintf(cmd, "AT+NSTCP=%d", _port);
-        if (_wifi->sendCommand(cmd, GSwifi::RES_CONNECT) == false) return -1;
-        _cid = _wifi->readCID();
+        _cid = _wifi->listen(GSwifi::PROTO_TCP, _port);
+        if (_cid < 0) return -1;
     }
 
     if (backlog != 1)
@@ -49,11 +46,13 @@
 
 
 int TCPSocketServer::accept(TCPSocketConnection& connection) {
-    int acid;
+    int acid = -1;
     while (1) {
-        acid = _wifi->readACID();
+        while (acid < 0) {
+            acid = _wifi->accept(_cid);
+        }
         if (acid >= 0) {
-            connection.confCID(acid);
+            connection.acceptCID(acid);
             return 0;
         }
     }
--- a/Socket/UDPSocket.cpp	Wed Jan 30 05:52:14 2013 +0000
+++ b/Socket/UDPSocket.cpp	Thu Oct 31 06:41:45 2013 +0000
@@ -49,13 +49,29 @@
     Timer tmr;
     int idx = 0;
 
+    if (_cid < 0 && _wifi->isConnected()) {
+        // Socket open
+        if (_server) {
+            _cid = _wifi->listen(GSwifi::PROTO_UDP, _port);
+        } else {
+            _cid = _wifi->open(GSwifi::PROTO_UDP, remote.get_address(), remote.get_port(), _port);
+        }
+        if (_cid < 0) return -1;
+    }
+
     tmr.start();
 
     while ((tmr.read_ms() < _timeout) || _blocking) {
 
-        idx += sendPacket(remote, packet, length);
+        if (_server) {
+            idx += _wifi->sendto(_cid, packet, length, remote.get_address(), remote.get_port());
+        } else {
+            idx += _wifi->send(_cid, packet, length);
+        }
+        if (idx < 0) {
+            if (!_wifi->isConnected(_cid)) _cid = -1;
+        }
 
-        if (idx == -1) return -1;
         if (idx == length)
             return idx;
     }
@@ -67,41 +83,46 @@
 {
     Timer tmr;
     int idx = 0;
-    int nb_available = 0;
     int time = -1;
+    char ip[16];
+    int port;
 
-    if (_cid < 0 || !_wifi->is_connected(_cid)) {
+    if (_cid < 0 && _wifi->isConnected()) {
         // Socket open
-        char cmd[CFG_CMD_SIZE];
         if (_server) {
-            sprintf(cmd, "AT+NSUDP=%d", _port);
+            _cid = _wifi->listen(GSwifi::PROTO_UDP, _port);
         } else {
-            sprintf(cmd, "AT+NCUDP=%s,%d", remote.get_address(), remote.get_port());
-            if (_port) {
-                sprintf(&cmd[strlen(cmd)], ",%d", _port);
-            }
+            _cid = _wifi->open(GSwifi::PROTO_UDP, remote.get_address(), remote.get_port(), _port);
         }
-        if (_wifi->sendCommand(cmd, GSwifi::RES_CONNECT) == false) return -1;
-        _cid = _wifi->readCID();
+        if (_cid < 0) return -1;
     }
 
     if (_blocking) {
-        while (1) {
-            nb_available = _wifi->readable(_cid);
-            if (nb_available != 0) {
+        tmr.start();
+        while (time < _timeout + 20) {
+            if (_wifi->readable(_cid)) {
                 break;
             }
+            time = tmr.read_ms();
+        }
+        if (time >= _timeout + 20) {
+            return -1;
         }
     }
 
+    tmr.reset();
     tmr.start();
 
     while (time < _timeout) {
 
-        nb_available = _wifi->readable(_cid);
-        for (int i = 0; i < min(nb_available, length); i++) {
-            buffer[idx] = _wifi->getc(_cid);
-            idx++;
+        if (_server) {
+            idx += _wifi->recvfrom(_cid, &buffer[idx], length - idx, ip, &port);
+        } else {
+            idx += _wifi->recv(_cid, &buffer[idx], length - idx);
+        }
+        if (idx < 0) {
+            if (!_wifi->isConnected(_cid)) _cid = -1;
+            return -1;
         }
 
         if (idx == length) {
@@ -112,47 +133,7 @@
     }
 
     if (_server) {
-        char *ip;
-        int port;
-        if (_wifi->readRemote(_cid, &ip, &port)) {
-            remote.set_address(ip, port);
-        }
+        remote.set_address(ip, port);
     }
     return (idx == 0) ? -1 : idx;
 }
-
-int UDPSocket::sendPacket (Endpoint &ep, const char *buf, int len)
-{
-    char cmd[CFG_CMD_SIZE];
-    Timer tmr;
-    int result = 0;
-
-    if (_cid < 0 || !_wifi->is_connected(_cid)) {
-        // Socket open
-        char cmd[CFG_CMD_SIZE];
-        if (_server) {
-            sprintf(cmd, "AT+NSUDP=%d", _port);
-        } else {
-            sprintf(cmd, "AT+NCUDP=%s,%d", ep.get_address(), ep.get_port());
-            if (_port) {
-                sprintf(&cmd[strlen(cmd)], ",%d", _port);
-            }
-        }
-        if (_wifi->sendCommand(cmd, GSwifi::RES_CONNECT) == false) return -1;
-        _cid = _wifi->readCID();
-    }
-
-    if (_server) {
-        // UDP Server
-        sprintf(cmd, "\x1bY%X%s:%d:%04d", _cid, ep.get_address(), ep.get_port(), len);
-        _wifi->send(cmd, strlen(cmd));
-        result = _wifi->send(buf, len, GSwifi::RES_NORMAL);
-    } else {
-        // UDP Client
-        sprintf(cmd, "\x1bZ%X%04d", _cid, len);
-        _wifi->send(cmd, strlen(cmd));
-        result = _wifi->send(buf, len, GSwifi::RES_NORMAL);
-    }
-
-    return result;
-}
--- a/Socket/UDPSocket.h	Wed Jan 30 05:52:14 2013 +0000
+++ b/Socket/UDPSocket.h	Thu Oct 31 06:41:45 2013 +0000
@@ -67,7 +67,6 @@
     
 private:
     bool endpoint_connected;
-    int sendPacket (Endpoint &ep, const char *buf, int len);
     
 };