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

Dependents:   GSwifi_httpd GSwifi_websocket GSwifi_tcpclient GSwifi_tcpserver ... more

Fork of GSwifi by gs fan

GainSpan Wi-Fi library

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

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

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

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

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

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

Files at this revision

API Documentation at this revision

Comitter:
gsfan
Date:
Mon Feb 11 06:01:46 2013 +0000
Parent:
24:5c350ae2e703
Child:
26:b347ee3a1087
Commit message:
split the file

Changed in this revision

CBuffer.h Show annotated file Show diff for this revision Revisions of this file
GSwifi.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi.h Show annotated file Show diff for this revision Revisions of this file
GSwifi_http.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi_httpd.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi_net.h Show annotated file Show diff for this revision Revisions of this file
GSwifi_smtp.cpp Show annotated file Show diff for this revision Revisions of this file
GSwifi_sock.cpp Show annotated file Show diff for this revision Revisions of this file
RingBuffer.cpp Show diff for this revision Revisions of this file
RingBuffer.h Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CBuffer.h	Mon Feb 11 06:01:46 2013 +0000
@@ -0,0 +1,79 @@
+/* Copyright (C) 2012 mbed.org, 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.
+ */
+
+#ifndef CIRCBUFFER_H_
+#define CIRCBUFFER_H_
+
+template <class T>
+class CircBuffer {
+public:
+    CircBuffer(int length) {
+        write = 0;
+        read = 0;
+        size = length + 1;
+        buf = (T *)malloc(size * sizeof(T));
+    };
+
+    bool isFull() {
+        return (((write + 1) % size) == read);
+    };
+
+    bool isEmpty() {
+        return (read == write);
+    };
+
+    void queue(T k) {
+        if (isFull()) {
+            read++;
+            read %= size;
+        }
+        buf[write++] = k;
+        write %= size;
+    }
+    
+    void flush() {
+        read = 0;
+        write = 0;
+    }
+    
+
+    uint32_t available() {
+        return (write >= read) ? write - read : size - read + write;
+    };
+
+    uint32_t use() {
+        return size - available() - 1;
+    };
+
+    bool dequeue(T * c) {
+        bool empty = isEmpty();
+        if (!empty) {
+            *c = buf[read++];
+            read %= size;
+        }
+        return(!empty);
+    };
+
+private:
+    volatile uint32_t write;
+    volatile uint32_t read;
+    uint32_t size;
+    T * buf;
+};
+
+#endif
--- a/GSwifi.cpp	Wed Jan 23 07:41:23 2013 +0000
+++ b/GSwifi.cpp	Mon Feb 11 06:01:46 2013 +0000
@@ -1,49 +1,57 @@
-/**
- * Gainspan wi-fi module library for mbed
- * Copyright (c) 2012 gsfan
- * Released under the MIT License: http://mbed.org/license/mit
+/* 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.
  */
-
 /** @file
  * @brief Gainspan wi-fi module library for mbed
  * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
- * module configuration: ATB=115200
  */
 
 #include "dbg.h"
 #include "mbed.h"
 #include "GSwifi.h"
-#include <ctype.h>
 
 
-GSwifi::GSwifi (PinName p_tx, PinName p_rx, int baud) : _gs(p_tx, p_rx), _buf_cmd(GS_CMD_SIZE) {
-    _connect = false;
-    _status = GSSTAT_READY;
-    _escape = 0;
-    _response = GSRES_NONE;
-    _gs_mode = GSMODE_COMMAND;
-    _ssid = NULL;
-    _reconnect = 0;
-    _reconnect_count = 0;
+GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_reset, PinName p_alarm, int baud) : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) {
+
+    if (p_alarm != NC) {
+        _alarm = new DigitalOut(p_alarm);
+        _alarm->write(1);
+    } else {
+        _alarm = NULL;
+    }
 
     _gs.baud(baud);
     _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
     _rts = false;
+
+    reset();
 }
 
-GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, int baud) : _gs(p_tx, p_rx), _buf_cmd(GS_CMD_SIZE) {
-    _connect = false;
-    _status = GSSTAT_READY;
-    _escape = 0;
-    _response = GSRES_NONE;
-    _gs_mode = GSMODE_COMMAND;
-    _ssid = NULL;
-    _reconnect = 0;
-    _reconnect_count = 0;
+GSwifi::GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, PinName p_reset, PinName p_alarm, int baud) : _gs(p_tx, p_rx), _reset(p_reset), _buf_cmd(GS_CMD_SIZE) {
+
+    if (p_alarm != NC) {
+        _alarm = new DigitalOut(p_alarm);
+        _alarm->write(1);
+    } else {
+        _alarm = NULL;
+    }
 
     _gs.baud(baud);
     _gs.attach(this, &GSwifi::isr_recv, Serial::RxIrq);
-
 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
     if (p_cts == p12) { // CTS input (P0_17)
         LPC_UART1->MCR |= (1<<7); // CTSEN
@@ -73,6 +81,24 @@
         _rts = false;
     }
 #endif
+
+    reset();
+}
+
+void GSwifi::reset () {
+    _connect = false;
+    _status = GSSTAT_READY;
+    _escape = 0;
+    _response = GSRES_NONE;
+    _gs_mode = GSMODE_COMMAND;
+    _ssid = NULL;
+    _reconnect = 0;
+    _reconnect_count = 0;
+
+    _reset = 0;
+    wait_ms(100);
+    _reset = 1;
+    wait_ms(500);
 }
 
 // uart interrupt
@@ -90,15 +116,9 @@
     
     if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) return;
 #ifdef DEBUG_VIEW
-//    DBG("%02x_", dat);
+    DBG("_%02x", dat);
 #endif
-/*
-    if (dat >= 0x20 && dat < 0x7f) {
-        DBG("_%c", dat);
-    } else {
-        DBG("_%02x", dat);
-    }
-*/
+
     switch (_gs_mode) {
     case GSMODE_COMMAND: // command responce
         if (_escape) {
@@ -144,7 +164,7 @@
             } else
             if (dat != '\r') {
                 // command
-                _buf_cmd.put(dat);
+                _buf_cmd.queue(dat);
                 if (dat == '\n') {
                     _gs_enter ++;
                     if (_response == GSRES_NONE && _connect) {
@@ -217,7 +237,7 @@
                 _escape = 1;
             } else {
                 // data
-                _gs_sock[_cid].data->put(dat);
+                _gs_sock[_cid].data->queue(dat);
                 len ++;
                 if (len < GS_DATA_SIZE && _gs_sock[_cid].data->available() == 0) {
                     // buffer full
@@ -231,7 +251,6 @@
 
     case GSMODE_DATA_RX_BULK:
     case GSMODE_DATA_RXUDP_BULK:
-//        DBG("%c", dat);
         if (mode == 0) {
             // cid
             _cid = x2i(dat);
@@ -282,7 +301,7 @@
         if (mode == 4) {
             // data
             if (_gs_sock[_cid].data != NULL) {
-                _gs_sock[_cid].data->put(dat);
+                _gs_sock[_cid].data->queue(dat);
             }
             len  --;
             if (len && _gs_sock[_cid].data->available() == 0) {
@@ -317,13 +336,13 @@
         for (i = 0; i < 10; i ++) {
             wait_ms(10);
             poll_cmd();
-            _buf_cmd.clear();
+            _buf_cmd.flush();
         }
         return 0;
     }
 
     _response = res;
-    _buf_cmd.clear();
+    _buf_cmd.flush();
     _gs_ok = 0;
     _gs_failure = 0;
     _gs_enter = 0;
@@ -352,8 +371,8 @@
         // recv response
         i = 0;
         while (i < sizeof(buf)) {
-            if (_buf_cmd.use()) {
-                _buf_cmd.get(&buf[i]);
+            if (! _buf_cmd.isEmpty()) {
+                _buf_cmd.dequeue(&buf[i]);
                 if (buf[i] == '\n') {
                     break;
                 }
@@ -499,7 +518,6 @@
 #endif
 
     disconnect();
-    command("AT+WREGDOMAIN=" GS_WREGDOMAIN, GSRES_NORMAL);
     command("AT+WM=0", GSRES_NORMAL); // infrastructure
     wait_ms(100);
     if (dhcp && sec != GSSEC_WPS_BUTTON) {
@@ -589,7 +607,6 @@
     command("AT+BDATA=1", GSRES_NORMAL);
 #endif
 
-    command("AT+WREGDOMAIN=" GS_WREGDOMAIN, GSRES_NORMAL);
     command("AT+WM=1", GSRES_NORMAL); // adhock
     wait_ms(100);
     command("AT+NDHCP=0", GSRES_NORMAL);
@@ -637,7 +654,6 @@
     command("AT+BDATA=1", GSRES_NORMAL);
 #endif
 
-    command("AT+WREGDOMAIN=" GS_WREGDOMAIN, GSRES_NORMAL);
     command("AT+WM=2", GSRES_NORMAL); // limited ap
     wait_ms(1000);
     command("AT+NDHCP=0", GSRES_NORMAL);
@@ -794,6 +810,17 @@
 
 int GSwifi::wakeup () {
 
+    if (_status == GSSTAT_STANDBY && _alarm) {
+        Timer timeout;
+        _alarm->write(0);
+        timeout.start();
+        while (_status != GSSTAT_WAKEUP && timeout.read() < GS_TIMEOUT) {
+            poll();
+        }
+        timeout.stop();
+        _alarm->write(1);
+    }
+
     if (_status == GSSTAT_WAKEUP) {
         _status = GSSTAT_READY;
         command("ATE0", GSRES_NORMAL);
@@ -827,7 +854,7 @@
     return _connect;
 }
 
-GSSTATUS GSwifi::getStatus () {
+GSwifi::GSSTATUS GSwifi::getStatus () {
     return _status;
 }
 
@@ -897,8 +924,8 @@
 //        wait_ms(10);
         _gs_enter --;
         i = 0;
-        while (_buf_cmd.use() && i < sizeof(buf)) {
-            _buf_cmd.get(&buf[i]);
+        while ((! _buf_cmd.isEmpty()) && i < sizeof(buf)) {
+            _buf_cmd.dequeue(&buf[i]);
             if (buf[i] == '\n') {
                 break;
             }
@@ -1016,299 +1043,6 @@
     }
 }
 
-void GSwifi::newSock (int cid, GSTYPE type, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
-    _gs_sock[cid].type = type;
-    _gs_sock[cid].protocol = pro;
-    _gs_sock[cid].connect = true;
-    if (_gs_sock[cid].data == NULL) {
-        _gs_sock[cid].data = new RingBuffer(GS_DATA_SIZE);
-    } else {
-        _gs_sock[cid].data->clear();
-    }
-    _gs_sock[cid].lcid = 0;
-    _gs_sock[cid].received = 0;
-    _gs_sock[cid].onGsReceive = ponGsReceive;
-}
-
-int GSwifi::open (Host &host, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
-    char cmd[GS_CMD_SIZE];
-
-    if (! _connect || _status != GSSTAT_READY) return -1;
-    if (host.getIp().isNull() || host.getPort() == 0) {
-        return -1;
-    }
-
-    if (pro == GSPROT_UDP) {
-        sprintf(cmd, "AT+NCUDP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
-    } else {
-        sprintf(cmd, "AT+NCTCP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
-    }
-    if (command(cmd, GSRES_CONNECT)) return -1;
-
-    newSock(_cid, GSTYPE_CLIENT, pro, ponGsReceive);
-    return _cid;
-}
-
-int GSwifi::listen (int port, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
-    char cmd[GS_CMD_SIZE];
-
-    if (! _connect || _status != GSSTAT_READY) return -1;
-    if (port == 0) {
-        return -1;
-    }
-
-    if (pro == GSPROT_UDP) {
-        sprintf(cmd, "AT+NSUDP=%d", port);
-    } else {
-        sprintf(cmd, "AT+NSTCP=%d", port);
-    }
-    if (command(cmd, GSRES_CONNECT)) return -1;
-
-    newSock(_cid, GSTYPE_SERVER, pro, ponGsReceive);
-    return _cid;
-}
-
-int GSwifi::close (int cid) {
-    char cmd[GS_CMD_SIZE];
-
-    if (! _gs_sock[cid].connect) return -1;
-
-    _gs_sock[cid].connect = false;
-//    delete _gs_sock[cid].data;
-//    _gs_sock[cid].data = NULL;
-    sprintf(cmd, "AT+NCLOSE=%X", cid);
-    return command(cmd, GSRES_NORMAL);    
-}
-
-int GSwifi::send (int cid, const char *buf, int len) {
-    int i;
-    Timer timeout;
-
-    if (! _gs_sock[cid].connect) return -1;
-
-    if ((_gs_sock[cid].protocol == GSPROT_TCP) ||
-      (_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_CLIENT) ||
-      (_gs_sock[cid].protocol == GSPROT_HTTPD)) {
-        // TCP Client, TCP Server, UDP Client
-        _gs_ok = 0;
-        _gs_failure = 0;
-#ifdef GS_BULK
-        _gs.printf("\x1bZ%X%04d", cid, len);
-        for (i = 0; i < len; i ++) {
-            _gs_putc(buf[i]);
-#ifdef DEBUG_VIEW
-            DBG("%c", buf[i]);
-#endif
-        }
-#else
-        _gs.printf("\x1bS%X", cid);
-        for (i = 0; i < len; i ++) {
-            if (buf[i] >= 0x20 && buf[i] < 0x7f) {
-                _gs_putc(buf[i]);
-#ifdef DEBUG_VIEW
-                DBG("%c", buf[i]);
-#endif
-            }
-        }
-        _gs_putc(0x1b);
-        _gs_putc('E');
-#endif
-    } else {
-        return -1;
-    }
-    timeout.start();
-    while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
-    return _gs_ok == 1 ? 0 : -1;
-}
-
-int GSwifi::send (int cid, const char *buf, int len, Host &host) {
-    int i;
-    Timer timeout;
-
-    if (! _gs_sock[cid].connect) return -1;
-
-    if ((_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_SERVER)) {
-        // UDP Server
-        _gs_ok = 0;
-        _gs_failure = 0;
-#ifdef GS_BULK
-        _gs.printf("\x1bY%X", cid);
-        _gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
-        _gs.printf("%04d", len);
-        for (i = 0; i < len; i ++) {
-            _gs_putc(buf[i]);
-#ifdef DEBUG_VIEW
-            DBG("%c", buf[i]);
-#endif
-        }
-#else
-        _gs.printf("\x1bU%X", cid);
-        _gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
-        for (i = 0; i < len; i ++) {
-            if (buf[i] >= 0x20 && buf[i] < 0x7f) {
-                _gs_putc(buf[i]);
-#ifdef DEBUG_VIEW
-                DBG("%c", buf[i]);
-#endif
-            }
-        }
-        _gs_putc(0x1b);
-        _gs_putc('E');
-#endif
-    } else {
-        return -1;
-    }
-    timeout.start();
-    while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
-    return _gs_ok == 1 ? 0 : -1;
-}
-
-int GSwifi::recv (int cid, char *buf, int len) {
-    int r;
-    Timer timeout;
-    
-    if (_gs_sock[cid].data == NULL) return 0;
-
-    timeout.start();
-    while (_gs_sock[cid].data->use() == 0) {
-        if (timeout.read_ms() > GS_TIMEOUT) return 0;
-    }
-    timeout.stop();
-
-    r = _gs_sock[cid].data->get(buf, len);
-    return r;
-}
-
-int GSwifi::recv (int cid, char *buf, int len, Host &host) {
-    int r;
-    Timer timeout;
-    
-    if (_gs_sock[cid].data == NULL) return 0;
-
-    timeout.start();
-    while (_gs_sock[cid].data->use() == 0) {
-        if (timeout.read_ms() > GS_TIMEOUT) return 0;
-    }
-    timeout.stop();
-
-    r = _gs_sock[cid].data->get(buf, len);
-    host = _from;
-    return r;
-}
-
-bool GSwifi::isConnected (int cid) {
-    return _gs_sock[cid].connect;
-}
-
-int GSwifi::httpGet (Host &host, const char *uri, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) {
-    char cmd[GS_CMD_SIZE];
-
-    if (! _connect || _status != GSSTAT_READY) return -1;
-
-    if (host.getIp().isNull()) {
-        if (getHostByName(host)) {
-            if (getHostByName(host)) return -1;
-        }
-    }
-    if (host.getPort() == 0) {
-        if (ssl) {
-            host.setPort(443);
-        } else {
-            host.setPort(80);
-        }
-    }
-
-    command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection:
-    sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName());  // Host:
-    command(cmd, GSRES_NORMAL);
-    if (user && pwd) {
-        char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE];
-        snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
-        base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
-        sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2);  // Authorization:
-        command(cmd, GSRES_NORMAL);
-    } else {
-        command("AT+HTTPCONFDEL=2", GSRES_NORMAL);
-    }
-    command("AT+HTTPCONFDEL=5", GSRES_NORMAL);
-    command("AT+HTTPCONFDEL=7", GSRES_NORMAL);
-
-    sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
-    if (ssl) {
-        strcat(cmd, ",1");
-    }
-    if (command(cmd, GSRES_HTTP)) return -1;
-    newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPGET, ponGsReceive);
-
-    sprintf(cmd, "AT+HTTPSEND=%d,1,%d,%s", _cid, GS_TIMEOUT / 1000, uri);  // GET
-    command(cmd, GSRES_NORMAL);
-
-    return _cid;
-}
-
-int GSwifi::httpGet (Host &host, const char *uri, int ssl, onGsReceiveFunc ponGsReceive) {
-    return httpGet (host, uri, NULL, NULL, ssl, ponGsReceive);
-}
-
-int GSwifi::httpPost (Host &host, const char *uri, const char *body, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) {
-    char cmd[GS_CMD_SIZE];
-    int i, len;
-
-    if (! _connect || _status != GSSTAT_READY) return -1;
-
-    if (host.getIp().isNull()) {
-        if (getHostByName(host)) {
-            if (getHostByName(host)) return -1;
-        }
-    }
-    if (host.getPort() == 0) {
-        if (ssl) {
-            host.setPort(443);
-        } else {
-            host.setPort(80);
-        }
-    }
-    len = strlen(body);
-
-    command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection:
-    sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName());  // Host:
-    command(cmd, GSRES_NORMAL);
-    sprintf(cmd, "AT+HTTPCONF=5,%d", len);  // Content-Length:
-    command(cmd, GSRES_NORMAL);
-    command("AT+HTTPCONF=7,application/x-www-form-urlencoded", GSRES_NORMAL); // Content-type:
-    if (user && pwd) {
-        char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE];
-        snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
-        base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
-        sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2);  // Authorization:
-        command(cmd, GSRES_NORMAL);
-    } else {
-        command("AT+HTTPCONFDEL=2", GSRES_NORMAL);
-    }
-
-    sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
-    if (ssl) {
-        strcat(cmd, ",1");
-    }
-    if (command(cmd, GSRES_HTTP)) return -1;
-    newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPPOST, ponGsReceive);
-
-    sprintf(cmd, "AT+HTTPSEND=%d,3,%d,%s,%d", _cid, GS_TIMEOUT / 1000, uri, len);  // POST
-    command(cmd, GSRES_NORMAL);
-
-    _gs.printf("\x1bH%X", _cid);
-    for (i = 0; i < len; i ++) {
-        _gs_putc(body[i]);
-        DBG("%c", body[i]);
-    }
-
-    return _cid;
-}
-
-int GSwifi::httpPost (Host &host, const char *uri, const char *body, int ssl, onGsReceiveFunc ponGsReceive) {
-    return httpPost (host, uri, body, NULL, NULL, ssl, ponGsReceive);
-}
-
 int GSwifi::certAdd (const char *name, const char *cert, int len) {
     int i;
     char cmd[GS_CMD_SIZE];
@@ -1344,36 +1078,21 @@
     for (int i = 0; i < 10; i ++) {
         wait_ms(10);
         poll_cmd();
-        _buf_cmd.clear();
+        _buf_cmd.flush();
     }
     return 0;
 }
 
-int GSwifi::base64encode (char *input, int length, char *output, int len) {
-    // code from 
-    // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
-    static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-    unsigned int c, c1, c2, c3;
+int GSwifi::setRegion (int reg) {
+    char cmd[GS_CMD_SIZE];
 
-    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;
+    if (_status != GSSTAT_READY) return -1;
 
-        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;
+    sprintf(cmd, "AT+WREGDOMAIN=%d", reg);
+    return command(cmd, GSRES_NORMAL);
 }
 
+
 int GSwifi::from_hex (int ch) {
   return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
 }
@@ -1383,50 +1102,6 @@
   return hex[code & 15];
 }
 
-int GSwifi::urlencode (char *str, char *buf, int len) {
-    // code from 
-    // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
-//  char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
-    char *pstr = str, *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;
-}
-
-int GSwifi::urldecode (char *str, char *buf, int len) {
-    // code from 
-    // Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
-//  char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf;
-    char *pstr = str, *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;
-}
-
 int GSwifi::x2i (char c) {
     if (c >= '0' && c <= '9') {
         return c - '0';
@@ -1450,6 +1125,7 @@
     return 0;
 }
 
+
 #ifdef DEBUG
 // for test
 void GSwifi::dump () {
@@ -1476,13 +1152,13 @@
 
 int GSwifi::getc() {
     char c;
-    if (_buf_cmd.use()) {
-        _buf_cmd.get(&c);
+    if (! _buf_cmd.isEmpty()) {
+        _buf_cmd.dequeue(&c);
     }
 /*
     } else
     if (_gs_sock[0].data != NULL) {
-        _gs_sock[0].data->get(&c);
+        _gs_sock[0].data->dequeue(&c);
     }
 */
     return c;
@@ -1493,7 +1169,7 @@
 }
 
 int GSwifi::readable() {
-    return _buf_cmd.use();
+    return ! _buf_cmd.isEmpty();
 //    return _buf_cmd.use() || (_gs_sock[0].data != NULL && _gs_sock[0].data->use());
 }
 #endif
--- a/GSwifi.h	Wed Jan 23 07:41:23 2013 +0000
+++ b/GSwifi.h	Mon Feb 11 06:01:46 2013 +0000
@@ -1,13 +1,23 @@
-/**
- * Gainspan wi-fi module library for mbed
- * Copyright (c) 2012 gsfan
- * Released under the MIT License: http://mbed.org/license/mit
+/* 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.
  */
-
 /** @file
  * @brief Gainspan wi-fi module library for mbed
  * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
- * module configuration: ATB=115200
  */
 
 #ifndef _GSWIFI_H_
@@ -15,17 +25,19 @@
 
 #include "mbed.h"
 #include "GSwifi_net.h"
-#include "RingBuffer.h"
+#include "CBuffer.h"
 #include "host.h"
 #include "ipaddr.h"
+#include <ctype.h>
 
-#define GS_BAUD 115200
+
+#define GS_BAUD 9600
 
 #define GS_UART_DIRECT
 #define GS_BULK
 
 #define GS_DNSNAME "setup.local"
-#define GS_WREGDOMAIN "2" // 0:FCC, 1:ETSI, 2:TELEC
+#define GS_WREGDOMAIN 2 // 0:FCC, 1:ETSI, 2:TELEC
 
 #define GS_TIMEOUT 10000 // ms
 #define GS_TIMEOUT2 30000 // ms
@@ -51,6 +63,12 @@
 #endif
 
 /**
+ * GSwifi class
+ */
+class GSwifi {
+public:
+
+/**
  * Wi-Fi security
  */
 enum GSSECURITY {
@@ -123,25 +141,25 @@
     GSPROTOCOL protocol;
     bool connect;
     Host host;
-    RingBuffer *data;
+    CircBuffer<char> *data;
     int lcid;
     int received;
     onGsReceiveFunc onGsReceive;
 };
 
-/**
- * GSwifi class
- */
-class GSwifi {
-public:
+    // ----- GSwifi.cpp -----
     /**
      * default constructor
      */
-    GSwifi (PinName p_tx, PinName p_rx, int baud = GS_BAUD);
+    GSwifi (PinName p_tx, PinName p_rx, PinName p_reset, PinName p_alarm = NC, int baud = GS_BAUD);
     /**
      * Default constructor (with hardware fllow controll)
      */
-    GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, int baud = GS_BAUD);
+    GSwifi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts, PinName p_reset, PinName p_alarm = NC, int baud = GS_BAUD);
+    /**
+     * reset module
+     */
+    void reset ();
     /**
      * send command
      */
@@ -275,12 +293,28 @@
      * @param out 0:set(high), 1:reset(low)
      */
     int gpioOut (int port, int out);
-
     /**
      * main polling
      */
     void poll();
+    /**
+     * Web server
+     */
+    int provisioning (char *user, char *pass);
+    /**
+     * change baud rate
+     */
+    int setBaud (int baud);
+    /**
+     * change radio region
+     */
+    int setRegion (int reg = GS_WREGDOMAIN);
+    /**
+     * certificate 
+     */
+    int certAdd (const char *name, const char *cert, int len);
 
+// ----- GSwifi_sock.cpp -----
     /**
      * tcp/udp client
      * @return CID, -1:failure
@@ -326,6 +360,7 @@
      */
     bool isConnected (int cid);
 
+// ----- GSwifi_http.cpp -----
     /**
      * http request (GET method)
      */
@@ -338,11 +373,20 @@
     int httpPost (Host &host, const char *uri, const char *body, int ssl = 0, onGsReceiveFunc ponGsReceive = NULL);
 
     /**
-     * certificate 
+     * base64 encode
+     */
+    int base64encode (char *input, int length, char *output, int len);
+    /**
+     * url encode
      */
-    int certAdd (const char *name, const char *cert, int len);
+    int urlencode (char *str, char *buf, int len);
+    /**
+     * url decode
+     */
+    int urldecode (char *str, char *buf, int len);
 
 #ifdef GS_USE_SMTP
+// ----- GSwifi_smtp.cpp -----
     /**
      * send mail (smtp)
      * @param host SMTP server
@@ -359,6 +403,7 @@
 #endif
 
 #ifdef GS_USE_HTTPD
+// ----- GSwifi_httpd.cpp -----
     /**
      * start http server
      * @param port
@@ -381,27 +426,6 @@
 #endif
 #endif
 
-    /**
-     * Web server
-     */
-    int provisioning (char *user, char *pass);
-    /**
-     * change baud rate
-     */
-    int setBaud (int baud);
-    /**
-     * base64 encode
-     */
-    int base64encode (char *input, int length, char *output, int len);
-    /**
-     * url encode
-     */
-    int urlencode (char *str, char *buf, int len);
-    /**
-     * url decode
-     */
-    int urldecode (char *str, char *buf, int len);
-
 #ifdef DEBUG
     void dump ();
     void test ();
@@ -415,10 +439,11 @@
     int x2i (char c);
     char i2x (int i);
     void isr_recv ();
-    void newSock (int cid, GSTYPE type, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive);
     int from_hex (int ch);
     int to_hex (int code);
 
+    void newSock (int cid, GSTYPE type, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive);
+
 #ifdef GS_USE_SMTP
     int wait_smtp (int cid, int code);
 #endif
@@ -433,6 +458,8 @@
 private:
     Serial _gs;
     bool _rts;
+    DigitalOut _reset;
+    DigitalOut *_alarm;
     volatile bool _connect;
     volatile GSSTATUS _status;
     volatile int _gs_ok, _gs_failure, _gs_enter;
@@ -443,7 +470,7 @@
     IpAddr _ipaddr, _netmask, _gateway, _nameserver, _resolv;
     Host _from, _to;
     char _mac[6];
-    RingBuffer _buf_cmd;
+    CircBuffer<char> _buf_cmd;
     struct GS_Socket _gs_sock[16];
     time_t _time;
     char *_ssid;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GSwifi_http.cpp	Mon Feb 11 06:01:46 2013 +0000
@@ -0,0 +1,208 @@
+/* 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.
+ */
+/** @file
+ * @brief Gainspan wi-fi module library for mbed
+ * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
+ */
+
+#include "dbg.h"
+#include "mbed.h"
+#include "GSwifi.h"
+
+
+int GSwifi::httpGet (Host &host, const char *uri, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) {
+    char cmd[GS_CMD_SIZE];
+
+    if (! _connect || _status != GSSTAT_READY) return -1;
+
+    if (host.getIp().isNull()) {
+        if (getHostByName(host)) {
+            if (getHostByName(host)) return -1;
+        }
+    }
+    if (host.getPort() == 0) {
+        if (ssl) {
+            host.setPort(443);
+        } else {
+            host.setPort(80);
+        }
+    }
+
+    command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection:
+    sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName());  // Host:
+    command(cmd, GSRES_NORMAL);
+    if (user && pwd) {
+        char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE];
+        snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
+        base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
+        sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2);  // Authorization:
+        command(cmd, GSRES_NORMAL);
+    } else {
+        command("AT+HTTPCONFDEL=2", GSRES_NORMAL);
+    }
+    command("AT+HTTPCONFDEL=5", GSRES_NORMAL);
+    command("AT+HTTPCONFDEL=7", GSRES_NORMAL);
+
+    sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
+    if (ssl) {
+        strcat(cmd, ",1");
+    }
+    if (command(cmd, GSRES_HTTP)) return -1;
+    newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPGET, ponGsReceive);
+
+    sprintf(cmd, "AT+HTTPSEND=%d,1,%d,%s", _cid, GS_TIMEOUT / 1000, uri);  // GET
+    command(cmd, GSRES_NORMAL);
+
+    return _cid;
+}
+
+int GSwifi::httpGet (Host &host, const char *uri, int ssl, onGsReceiveFunc ponGsReceive) {
+    return httpGet (host, uri, NULL, NULL, ssl, ponGsReceive);
+}
+
+int GSwifi::httpPost (Host &host, const char *uri, const char *body, const char *user, const char *pwd, int ssl, onGsReceiveFunc ponGsReceive) {
+    char cmd[GS_CMD_SIZE];
+    int i, len;
+
+    if (! _connect || _status != GSSTAT_READY) return -1;
+
+    if (host.getIp().isNull()) {
+        if (getHostByName(host)) {
+            if (getHostByName(host)) return -1;
+        }
+    }
+    if (host.getPort() == 0) {
+        if (ssl) {
+            host.setPort(443);
+        } else {
+            host.setPort(80);
+        }
+    }
+    len = strlen(body);
+
+    command("AT+HTTPCONF=3,close", GSRES_NORMAL); // Connection:
+    sprintf(cmd, "AT+HTTPCONF=11,%s", host.getName());  // Host:
+    command(cmd, GSRES_NORMAL);
+    sprintf(cmd, "AT+HTTPCONF=5,%d", len);  // Content-Length:
+    command(cmd, GSRES_NORMAL);
+    command("AT+HTTPCONF=7,application/x-www-form-urlencoded", GSRES_NORMAL); // Content-type:
+    if (user && pwd) {
+        char tmp[GS_CMD_SIZE], tmp2[GS_CMD_SIZE];
+        snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
+        base64encode(tmp, strlen(tmp), tmp2, sizeof(tmp2));
+        sprintf(cmd, "AT+HTTPCONF=2,Basic %s", tmp2);  // Authorization:
+        command(cmd, GSRES_NORMAL);
+    } else {
+        command("AT+HTTPCONFDEL=2", GSRES_NORMAL);
+    }
+
+    sprintf(cmd, "AT+HTTPOPEN=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
+    if (ssl) {
+        strcat(cmd, ",1");
+    }
+    if (command(cmd, GSRES_HTTP)) return -1;
+    newSock(_cid, GSTYPE_CLIENT, GSPROT_HTTPPOST, ponGsReceive);
+
+    sprintf(cmd, "AT+HTTPSEND=%d,3,%d,%s,%d", _cid, GS_TIMEOUT / 1000, uri, len);  // POST
+    command(cmd, GSRES_NORMAL);
+
+    _gs.printf("\x1bH%X", _cid);
+    for (i = 0; i < len; i ++) {
+        _gs_putc(body[i]);
+        DBG("%c", body[i]);
+    }
+
+    return _cid;
+}
+
+int GSwifi::httpPost (Host &host, const char *uri, const char *body, int ssl, onGsReceiveFunc ponGsReceive) {
+    return httpPost (host, uri, body, NULL, NULL, ssl, ponGsReceive);
+}
+
+
+/* base64encode code from 
+ * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+ */
+int GSwifi::base64encode (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 (char *str, char *buf, int len) {
+//  char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
+    char *pstr = str, *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 (char *str, char *buf, int len) {
+//  char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf;
+    char *pstr = str, *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;
+}
--- a/GSwifi_httpd.cpp	Wed Jan 23 07:41:23 2013 +0000
+++ b/GSwifi_httpd.cpp	Mon Feb 11 06:01:46 2013 +0000
@@ -1,3 +1,25 @@
+/* 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.
+ */
+/** @file
+ * @brief Gainspan wi-fi module library for mbed
+ * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
+ */
+
 #include "dbg.h"
 #include "mbed.h"
 #include "GSwifi.h"
@@ -6,19 +28,20 @@
 
 #ifdef GS_USE_HTTPD
 
-#define MIMETABLE_NUM 8
+#define MIMETABLE_NUM 9
 struct {
-    char ext[6];
+    char ext[5];
     char type[24];
 } mimetable[MIMETABLE_NUM] = {
-    {".txt", "text/plain"},
-    {".html", "text/html"},
-    {".htm", "text/html"},
-    {".css", "text/css"},
-    {".js", "application/javascript"},
-    {".jpg", "image/jpeg"},
-    {".png", "image/png"},
-    {".gif", "image/gif"},
+    {"txt", "text/plain"},  // default
+    {"html", "text/html"},
+    {"htm", "text/html"},
+    {"css", "text/css"},
+    {"js", "application/javascript"},
+    {"jpg", "image/jpeg"},
+    {"png", "image/png"},
+    {"gif", "image/gif"},
+    {"ico", "image/x-icon"},
 };
 
 int GSwifi::httpd (int port) {
@@ -76,7 +99,7 @@
     }
     // get 1 line
     for (j = 0; j < len; j ++) {
-        _gs_sock[cid].data->get(&c);
+        _gs_sock[cid].data->dequeue(&c);
         if (c == '\r') continue;
         if (c == '\n' && _httpd[cid].mode != GSHTTPDMODE_BODY) break;
         
@@ -314,7 +337,8 @@
     DBG("<%s>\r\n", file);
     for (i = 0; i < MIMETABLE_NUM; i ++) {
         j = strlen(mimetable[i].ext);
-        if (strnicmp(&file[strlen(file) - j], mimetable[i].ext, j) == NULL) {
+        if (file[strlen(file) - j - 1] == '.' &&
+          strnicmp(&file[strlen(file) - j], mimetable[i].ext, j) == NULL) {
             return mimetable[i].type;
         }
     }
@@ -322,7 +346,7 @@
 }
 
 int GSwifi::strnicmp (char *p1, char *p2, int n) {
-    int i, r;
+    int i, r = -1;
     char c1, c2;
     
     for (i = 0; i < n; i ++) {
@@ -405,7 +429,7 @@
         flg = 0;
         // get 1 line
         for (j = 0; j < len; j ++) {
-            _gs_sock[cid].data->get((char*)&c);
+            _gs_sock[cid].data->dequeue((char*)&c);
 //            DBG("_%c", c);
 
             switch (_httpd[cid].mode) {
--- a/GSwifi_net.h	Wed Jan 23 07:41:23 2013 +0000
+++ b/GSwifi_net.h	Mon Feb 11 06:01:46 2013 +0000
@@ -1,13 +1,23 @@
-/**
- * Gainspan wi-fi module library for mbed
- * Copyright (c) 2012 gsfan
- * Released under the MIT License: http://mbed.org/license/mit
+/* 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.
  */
-
 /** @file
  * @brief Gainspan wi-fi module library for mbed
  * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
- * module configuration: ATB=115200
  */
 
 #ifndef _GSWIFI_NET_H_
--- a/GSwifi_smtp.cpp	Wed Jan 23 07:41:23 2013 +0000
+++ b/GSwifi_smtp.cpp	Mon Feb 11 06:01:46 2013 +0000
@@ -1,3 +1,25 @@
+/* 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.
+ */
+/** @file
+ * @brief Gainspan wi-fi module library for mbed
+ * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
+ */
+
 #include "dbg.h"
 #include "mbed.h"
 #include "GSwifi.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GSwifi_sock.cpp	Mon Feb 11 06:01:46 2013 +0000
@@ -0,0 +1,214 @@
+/* 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.
+ */
+/** @file
+ * @brief Gainspan wi-fi module library for mbed
+ * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc.
+ */
+
+#include "dbg.h"
+#include "mbed.h"
+#include "GSwifi.h"
+
+
+void GSwifi::newSock (int cid, GSTYPE type, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
+    _gs_sock[cid].type = type;
+    _gs_sock[cid].protocol = pro;
+    _gs_sock[cid].connect = true;
+    if (_gs_sock[cid].data == NULL) {
+        _gs_sock[cid].data = new CircBuffer<char>(GS_DATA_SIZE);
+    } else {
+        _gs_sock[cid].data->flush();
+    }
+    _gs_sock[cid].lcid = 0;
+    _gs_sock[cid].received = 0;
+    _gs_sock[cid].onGsReceive = ponGsReceive;
+}
+
+int GSwifi::open (Host &host, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
+    char cmd[GS_CMD_SIZE];
+
+    if (! _connect || _status != GSSTAT_READY) return -1;
+    if (host.getIp().isNull() || host.getPort() == 0) {
+        return -1;
+    }
+
+    if (pro == GSPROT_UDP) {
+        sprintf(cmd, "AT+NCUDP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
+    } else {
+        sprintf(cmd, "AT+NCTCP=%d.%d.%d.%d,%d", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
+    }
+    if (command(cmd, GSRES_CONNECT)) return -1;
+
+    newSock(_cid, GSTYPE_CLIENT, pro, ponGsReceive);
+    return _cid;
+}
+
+int GSwifi::listen (int port, GSPROTOCOL pro, onGsReceiveFunc ponGsReceive) {
+    char cmd[GS_CMD_SIZE];
+
+    if (! _connect || _status != GSSTAT_READY) return -1;
+    if (port == 0) {
+        return -1;
+    }
+
+    if (pro == GSPROT_UDP) {
+        sprintf(cmd, "AT+NSUDP=%d", port);
+    } else {
+        sprintf(cmd, "AT+NSTCP=%d", port);
+    }
+    if (command(cmd, GSRES_CONNECT)) return -1;
+
+    newSock(_cid, GSTYPE_SERVER, pro, ponGsReceive);
+    return _cid;
+}
+
+int GSwifi::close (int cid) {
+    char cmd[GS_CMD_SIZE];
+
+    if (! _gs_sock[cid].connect) return -1;
+
+    _gs_sock[cid].connect = false;
+//    delete _gs_sock[cid].data;
+//    _gs_sock[cid].data = NULL;
+    sprintf(cmd, "AT+NCLOSE=%X", cid);
+    return command(cmd, GSRES_NORMAL);    
+}
+
+int GSwifi::send (int cid, const char *buf, int len) {
+    int i;
+    Timer timeout;
+
+    if (! _gs_sock[cid].connect) return -1;
+
+    if ((_gs_sock[cid].protocol == GSPROT_TCP) ||
+      (_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_CLIENT) ||
+      (_gs_sock[cid].protocol == GSPROT_HTTPD)) {
+        // TCP Client, TCP Server, UDP Client
+        _gs_ok = 0;
+        _gs_failure = 0;
+#ifdef GS_BULK
+        _gs.printf("\x1bZ%X%04d", cid, len);
+        for (i = 0; i < len; i ++) {
+            _gs_putc(buf[i]);
+#ifdef DEBUG_VIEW
+            DBG("%c", buf[i]);
+#endif
+        }
+#else
+        _gs.printf("\x1bS%X", cid);
+        for (i = 0; i < len; i ++) {
+            if (buf[i] >= 0x20 && buf[i] < 0x7f) {
+                _gs_putc(buf[i]);
+#ifdef DEBUG_VIEW
+                DBG("%c", buf[i]);
+#endif
+            }
+        }
+        _gs_putc(0x1b);
+        _gs_putc('E');
+#endif
+    } else {
+        return -1;
+    }
+    timeout.start();
+    while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
+    return _gs_ok == 1 ? 0 : -1;
+}
+
+int GSwifi::send (int cid, const char *buf, int len, Host &host) {
+    int i;
+    Timer timeout;
+
+    if (! _gs_sock[cid].connect) return -1;
+
+    if ((_gs_sock[cid].protocol == GSPROT_UDP && _gs_sock[cid].type == GSTYPE_SERVER)) {
+        // UDP Server
+        _gs_ok = 0;
+        _gs_failure = 0;
+#ifdef GS_BULK
+        _gs.printf("\x1bY%X", cid);
+        _gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
+        _gs.printf("%04d", len);
+        for (i = 0; i < len; i ++) {
+            _gs_putc(buf[i]);
+#ifdef DEBUG_VIEW
+            DBG("%c", buf[i]);
+#endif
+        }
+#else
+        _gs.printf("\x1bU%X", cid);
+        _gs.printf("%d.%d.%d.%d:%d:", host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3], host.getPort());
+        for (i = 0; i < len; i ++) {
+            if (buf[i] >= 0x20 && buf[i] < 0x7f) {
+                _gs_putc(buf[i]);
+#ifdef DEBUG_VIEW
+                DBG("%c", buf[i]);
+#endif
+            }
+        }
+        _gs_putc(0x1b);
+        _gs_putc('E');
+#endif
+    } else {
+        return -1;
+    }
+    timeout.start();
+    while (!_gs_ok && !_gs_failure && timeout.read_ms() < GS_TIMEOUT);
+    return _gs_ok == 1 ? 0 : -1;
+}
+
+int GSwifi::recv (int cid, char *buf, int len) {
+    int i;
+    Timer timeout;
+    
+    if (_gs_sock[cid].data == NULL) return 0;
+
+    timeout.start();
+    while (_gs_sock[cid].data->use() == 0) {
+        if (timeout.read_ms() > GS_TIMEOUT) return 0;
+    }
+    timeout.stop();
+
+    for (i = 0; i < len; i ++) {
+        if (_gs_sock[cid].data->dequeue(&buf[i]) == false) break;
+    }
+    return i;
+}
+
+int GSwifi::recv (int cid, char *buf, int len, Host &host) {
+    int i;
+    Timer timeout;
+    
+    if (_gs_sock[cid].data == NULL) return 0;
+
+    timeout.start();
+    while (_gs_sock[cid].data->use() == 0) {
+        if (timeout.read_ms() > GS_TIMEOUT) return 0;
+    }
+    timeout.stop();
+
+    for (i = 0; i < len; i ++) {
+        if (_gs_sock[cid].data->dequeue(&buf[i]) == false) break;
+    }
+    host = _from;
+    return i;
+}
+
+bool GSwifi::isConnected (int cid) {
+    return _gs_sock[cid].connect;
+}
--- a/RingBuffer.cpp	Wed Jan 23 07:41:23 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * mbed library for RingBuffer
- * Copyright (c) 2010 Hiroshi Suga
- * Released under the MIT License: http://mbed.org/license/mit
- */
-
-/* @file
- * @brief Ring Buffer
- */
- 
-#include "RingBuffer.h"
-
-RingBuffer::RingBuffer (int p_size) {
-    size = p_size + 1;
-    buf = new char[size];
-    addr_w = 0;
-    addr_r = 0;
-}
-
-RingBuffer::~RingBuffer () {
-    delete [] buf;
-}
-
-int RingBuffer::put (char dat) {
-    int next;
-
-    next = (addr_w + 1) % size;
-    if (next == addr_r) {
-        return -1;
-    }
-    buf[addr_w] = dat;
-    addr_w = next;
-    return -1;
-}
-
-int RingBuffer::put (char *dat, int len) {
-    int next, i;
-
-
-    for (i = 0; i < len; i ++) {
-        next = (addr_w + 1) % size;
-        if (next == addr_r) {
-            break;
-        }
-        buf[addr_w] = dat[i];
-        addr_w = next;
-    }
-    return i;
-}
-
-int RingBuffer::get (char *dat) {
-    if (addr_r == addr_w) {
-        return -1;
-    }
-    *dat = buf[addr_r];
-    addr_r = (addr_r + 1) % size;
-    return 0;
-}
-
-int RingBuffer::get (char *dat, int len) {
-    int i;
-
-    for (i = 0; i < len; i ++) {
-        if (addr_r == addr_w) {
-            break;
-        }
-        dat[i] = buf[addr_r];
-        addr_r = (addr_r + 1) % size;
-    }
-    return i;
-}
-
-int RingBuffer::available () {
-    if (addr_w < addr_r) {
-        return addr_r - addr_w - 1;
-    } else {
-        return (size - addr_w) + addr_r - 1;
-    }
-}
-
-int RingBuffer::use () {
-    return size - available() - 1;
-}
-
-void RingBuffer::clear () {
-    addr_w = 0;
-    addr_r = 0;
-}
--- a/RingBuffer.h	Wed Jan 23 07:41:23 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * mbed library for RingBuffer
- * Copyright (c) 2010 Hiroshi Suga
- * Released under the MIT License: http://mbed.org/license/mit
- */
-
-/* @file
- * @brief Ring Buffer
- */
-
-#ifndef RingBuffer_H
-#define RingBuffer_H
-
-#include "mbed.h"
-
-class RingBuffer {
-public:
-    /** init Stack class
-     * @param p_size size of ring buffer
-     */
-    RingBuffer (int p_size);
-    ~RingBuffer ();
-
-    /** put to ring buffer
-     * @param dat data
-     * @return data / -1:error
-     */
-    int put (char dat);
-
-    /** put to ring buffer
-     * @param dat data
-     * @param len length
-     * @return put length
-     */
-    int put (char *dat, int len);
-
-    /** get from ring buffer
-     * @param dat data
-     * @retval 0:ok / -1:error
-     */
-    int get (char *dat);
-
-    /** get from ring buffer
-     * @param dat data
-     * @param len length
-     * @return get length
-     */
-    int get (char *dat, int len);
-
-    void clear ();
-    int available ();
-    int use ();
-
-private:
-    char *buf;
-    int size;
-    int addr_w, addr_r;
-};
-
-#endif