gs fan / Mbed 2 deprecated Wirefree_sample

Dependencies:   mbed

Revision:
0:bf663118b11b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Wirefree/gs.cpp	Sun May 27 03:19:54 2012 +0000
@@ -0,0 +1,850 @@
+/*
+ * Gainspan Wifi library for mbed
+ * Modified for mbed, 2012 gsfan.
+ *
+
+gs.cpp - HAL driver to talk with Gainspan GS1011 WiFi module
+
+Copyright (C) 2011 DIYSandbox LLC
+
+Porting for chipKIT boards Copyright (c) 2012 http://electronics.trev.id.au
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "dbg.h"
+#include "mbed.h"
+#include "ipaddr.h"
+#include "host.h"
+#include "gs.h"
+
+#include <stdio.h>
+#include <stdint.h>
+
+struct _cmd_tbl {
+    const char *cmd_str;
+} cmd_tbl[] = {
+        {"ATE0"},
+        {"AT+WWPA="},
+        {"AT+WA="},
+        {"AT+NDHCP=0"},
+        {"AT+NDHCP=1"},
+        {"AT+WD"},
+        {"AT+NSTCP=80"},
+        {"AT+NCTCP="},
+        {"AT+NMAC=?"},
+        {"AT+DNSLOOKUP="},
+        {"AT+NCLOSE="},
+        {"AT+NSET="},
+        {"AT+WM=2"},
+        {"AT+DHCPSRVR=1"},
+};
+
+int hex_to_int(char c)
+{
+    int val = 0;
+
+    if (c >= '0' && c <= '9') {
+        val = c - '0';
+    }
+    else if (c >= 'A' && c <= 'F') {
+        val = c - 'A' + 10;
+    }
+    else if (c >= 'a' && c <= 'f') {
+        val = c - 'a' + 10;
+    }
+
+    return val;
+}
+
+char int_to_hex(int c)
+{
+    char val = '0';
+
+    if (c >= 0 && c <= 9) {
+        val = c + '0';
+    }
+    else if (c >= 10 && c <= 15) {
+        val = c + 'A' - 10;
+    }
+
+    return val;
+}
+
+GSClass::GSClass(PinName p_tx, PinName p_rx): _gs(p_tx, p_rx) {
+}
+
+GSClass::GSClass(PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts): _gs(p_tx, p_rx) {
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+    if (p_cts == p12) { // CTS input (P0_17)
+        LPC_UART1->MCR |= (1<<7); // CTSEN
+        LPC_PINCON->PINSEL1 &= ~(3 << 2);
+        LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS
+    }
+    if (p_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
+        _gs.attach(this, &GSClass::isr_recv, Serial::RxIrq);
+        _rts = true;
+    } else {
+        _rts = false;
+    }
+#elif defined(TARGET_LPC11U24)
+    if (p_cts == p21) { // CTS input (P0_7)
+        LPC_UART->MCR = (1<<7); // CTSEN
+        LPC_IOCON->PIO0_7 &= ~0x07;
+        LPC_IOCON->PIO0_7 |= 0x01; // UART CTS
+    }
+    if (p_rts == p22) { // RTS output (P0_17)
+        LPC_UART->MCR = (1<<6); // RTSEN
+        LPC_IOCON->PIO0_17 &= ~0x07;
+        LPC_IOCON->PIO0_17 |= 0x01; // UART RTS
+        _gs.attach(this, &GSClass::isr_recv, Serial::RxIrq);
+        _rts = true;
+    } else {
+        _rts = false;
+    }
+#endif
+}
+
+int GSClass::init(void (*rx_data_hndlr)(char *data, int len))
+{
+    _gs.baud(9600);
+    wait_ms(1000);
+
+    flush();
+    _gs.printf("\r\n");
+    wait_ms(1000);
+
+    dev_mode = DEV_OP_MODE_COMMAND;
+    connection_state = DEV_CONN_ST_DISCONNECTED;
+    dataOnSock = 255;
+
+    rx_data_handler = rx_data_hndlr;
+
+    for (int i = 0; i < 4; i++) {
+        sock_table[i].cid = 0;
+        sock_table[i].port = 0;
+        sock_table[i].protocol = 0;
+        sock_table[i].status = 0;
+    }
+
+    // disable echo
+    if (!send_cmd_w_resp(CMD_DISABLE_ECHO)) {
+        return 0;
+    }
+
+    // get device ID
+    if (!send_cmd_w_resp(CMD_GET_MAC_ADDR)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+int GSClass::send_cmd(int cmd)
+{
+    flush();
+
+    DBG("send_cmd %d\r\n", cmd);
+    switch(cmd) {
+    case CMD_SET_UART_115200:
+    case CMD_DISABLE_ECHO:
+    case CMD_DISABLE_DHCP:
+    case CMD_DISCONNECT:
+    case CMD_ENABLE_DHCP:
+    case CMD_LISTEN:
+    case CMD_GET_MAC_ADDR:
+    case CMD_WIRELESS_MODE:
+    case CMD_ENABLE_DHCPSVR:
+    {
+        _gs.printf("%s\r\n", cmd_tbl[cmd].cmd_str);
+        break;
+    }
+    case CMD_SET_WPA_PSK:
+    {
+        _gs.printf("%s%s\r\n", cmd_tbl[cmd].cmd_str, security_key);
+        break;
+    }
+    case CMD_SET_SSID:
+    {
+        if (mode == 0) {
+            _gs.printf("%s%s\r\n", cmd_tbl[cmd].cmd_str, ssid);
+        }
+        else if (mode == 2) {
+            _gs.printf("%s%s,,11\r\n", cmd_tbl[cmd].cmd_str, ssid);
+        }
+        break;
+    }
+    case CMD_TCP_CONN:
+    {
+        _gs.printf("%s%d.%d.%d.%d,%d\r\n", cmd_tbl[cmd].cmd_str, ip[0], ip[1], ip[2], ip[3], port);
+        break;
+    }
+    case CMD_NETWORK_SET:
+    {
+        _gs.printf("%s%d.%d.%d.%d,", cmd_tbl[cmd].cmd_str, ip[0], ip[1], ip[2], ip[3]);
+        _gs.printf("%d.%d.%d.%d,", subnet[0], subnet[1], subnet[2], subnet[3]);
+        _gs.printf("%d.%d.%d.%d\r\n", gateway[0], gateway[1], gateway[2], gateway[3]);
+        break;
+    }
+    case CMD_DNS_LOOKUP:
+    {
+        _gs.printf("%s%s\r\n", cmd_tbl[cmd].cmd_str, dns_url_ip.getName());
+        break;
+    }
+    case CMD_CLOSE_CONN:
+    {
+        if (sock_table[socket_num].status != SOCK_STATUS::CLOSED) {
+            _gs.printf("%s%d\r\n", cmd_tbl[cmd].cmd_str, sock_table[socket_num].cid);
+        } else {
+            return 0;
+        }
+        break;
+    }
+    default:
+        break;
+    }
+
+    return 1;
+}
+
+int GSClass::parse_resp(int cmd)
+{
+    int resp_done = 0;
+    int ret = 0;
+    char buf[256];
+    int len;
+
+    while (!resp_done) {
+        len = readline(buf, sizeof(buf));
+
+        switch(cmd) {
+        case CMD_SET_UART_115200:
+        case CMD_DISABLE_ECHO:
+        case CMD_DISABLE_DHCP:
+        case CMD_DISCONNECT:
+        case CMD_SET_WPA_PSK:
+        case CMD_SET_SSID:
+        case CMD_ENABLE_DHCP:
+        case CMD_NETWORK_SET:
+        case CMD_WIRELESS_MODE:
+        case CMD_ENABLE_DHCPSVR:
+        {
+            if (strcmp(buf, "OK") == 0) {
+                /* got OK */
+                ret = 1;
+                resp_done = 1;
+            } else if (strstr(buf, "ERROR")) {
+                /* got ERROR */
+                ret = 0;
+                resp_done = 1;
+            }
+            break;
+        }
+        case CMD_LISTEN:
+        {
+            if (strstr(buf, "CONNECT")) {
+                /* got CONNECT */
+                serv_cid = hex_to_int(buf[8]);
+                sock_table[socket_num].cid = hex_to_int(buf[8]);
+                sock_table[socket_num].status = SOCK_STATUS::LISTEN;
+                
+            } else if (strcmp(buf, "OK") == 0) {
+                /* got OK */
+                ret = 1;
+                resp_done = 1;
+            } else if (strstr(buf, "ERROR")) {
+                /* got ERROR */
+                serv_cid = INVALID_CID;
+                sock_table[socket_num].cid = 0;
+                sock_table[socket_num].status = SOCK_STATUS::CLOSED;
+                ret = 0;
+                resp_done = 1;
+            }
+            break;
+        }
+        case CMD_TCP_CONN:
+        {
+            if (strstr(buf, "CONNECT")) {
+                /* got CONNECT */
+                client_cid = hex_to_int(buf[8]);
+                sock_table[socket_num].cid = hex_to_int(buf[8]);
+                sock_table[socket_num].status = SOCK_STATUS::ESTABLISHED;
+            } else if (strcmp(buf, "OK") == 0) {
+                /* got OK */
+                ret = 1;
+                resp_done = 1;
+            } else if (strstr(buf, "ERROR")) {
+                /* got ERROR */
+                client_cid = INVALID_CID;
+                sock_table[socket_num].cid = 0;
+                sock_table[socket_num].status = SOCK_STATUS::CLOSED;
+                ret = 0;
+                resp_done = 1;
+            }
+            break;
+        }
+        case CMD_GET_MAC_ADDR:
+        {
+            if (strstr(buf, "00")) {
+                /* got MAC addr */
+                int mac1, mac2, mac3, mac4, mac5, mac6;
+                sscanf(buf, "%x:%x:%x:%x:%x:%x", &mac1, &mac2, &mac3, &mac4, &mac5, &mac6);
+                dev_id[0] = mac1;
+                dev_id[1] = mac2;
+                dev_id[2] = mac3;
+                dev_id[3] = mac4;
+                dev_id[4] = mac5;
+                dev_id[5] = mac6;
+            } else if (strcmp(buf, "OK") == 0) {
+                /* got OK */
+                ret = 1;
+                resp_done = 1;
+            } else if (strstr(buf, "ERROR")) {
+                /* got ERROR */
+                for (int i = 0; i < 6; i ++) dev_id[i] = 0xff;
+                ret = 0;
+                resp_done = 1;
+            }
+            break;
+        }
+        case CMD_DNS_LOOKUP:
+        {
+            if (strstr(buf, "IP:")) {
+                /* got IP address */
+                int ip1, ip2, ip3, ip4;
+                sscanf(&buf[3], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
+                dns_url_ip.setIp(IpAddr(ip1, ip2, ip3, ip4));
+            } else if (strcmp(buf, "OK") == 0) {
+                /* got OK */
+                ret = 1;
+                resp_done = 1;
+            } else if (strstr(buf, "ERROR")) {
+                /* got ERROR */
+                ret = 0;
+                resp_done = 1;
+            }
+            break;
+        }
+        case CMD_CLOSE_CONN:
+        {
+            if (strcmp(buf, "OK") == 0) {
+                /* got OK */
+                ret = 1;
+                resp_done = 1;
+
+                /* clean up socket */
+                sock_table[socket_num].status = 0;
+                sock_table[socket_num].cid = 0;
+                sock_table[socket_num].port = 0;
+                sock_table[socket_num].protocol = 0;
+                
+                dev_mode = DEV_OP_MODE_COMMAND;
+                
+                /* clear flag */
+                dataOnSock = 255;
+            } else if (strstr(buf, "ERROR")) {
+                /* got ERROR */
+                ret = 0;
+                resp_done = 1;
+            }
+            break;
+        }
+        default:
+            break;
+        }
+    }
+
+    return ret;
+}
+
+int GSClass::send_cmd_w_resp(int cmd)
+{
+    if (send_cmd(cmd)) {
+        return parse_resp(cmd);
+    } else {
+        return 0;
+    }
+}
+
+void GSClass::configure(GS_PROFILE *prof)
+{
+    // configure params
+    strcpy(ssid, prof->ssid);
+    strcpy(security_key, prof->security_key);
+    local_ip     = prof->ip;
+    subnet       = prof->subnet;
+    gateway      = prof->gateway;
+}
+
+int GSClass::connect()
+{
+
+    if (!send_cmd_w_resp(CMD_DISCONNECT)) {
+        return 0;
+    }
+
+    if (!send_cmd_w_resp(CMD_DISABLE_DHCP)) {
+        return 0;
+    }
+
+    if (mode == 0) {
+        if (!send_cmd_w_resp(CMD_SET_WPA_PSK)) {
+            return 0;
+        }
+
+        if (!send_cmd_w_resp(CMD_SET_SSID)) {
+            return 0;
+        }
+
+        if (local_ip.isNull()) {
+            if (!send_cmd_w_resp(CMD_ENABLE_DHCP)) {
+                return 0;
+            }
+        } else {
+            if (!send_cmd_w_resp(CMD_NETWORK_SET)) {
+                return 0;
+            }
+        }
+
+    } else if (mode == 2) {
+        if (!send_cmd_w_resp(CMD_NETWORK_SET)) {
+                    return 0;
+                }
+        if (!send_cmd_w_resp(CMD_WIRELESS_MODE)) {
+                        return 0;
+                }
+        if (!send_cmd_w_resp(CMD_SET_SSID)) {
+                        return 0;
+                }
+        if (!send_cmd_w_resp(CMD_ENABLE_DHCPSVR)) {
+            return 0;
+        }
+        
+    } 
+
+    connection_state = DEV_CONN_ST_CONNECTED;
+
+    return 1;
+}
+
+int GSClass::connected()
+{
+    return connection_state;
+}
+
+int GSClass::readline(char *buf, int size)
+{
+    int len = 0;
+    char inByte;
+
+    bool endDetected = false;
+
+    while (!endDetected)
+    {
+//        if (_gs.readable()) {
+        if ((! _rts && _gs.readable()) || (_rts && bufreadable())) {
+            // valid data in HW UART buffer, so check if it's \r or \n
+            // if so, throw away
+            // if strBuf length greater than 0, then this is a true end of line,
+            // so break out
+//            inByte = _gs.getc();
+            if (_rts) {
+                inByte = getbuf();
+            } else {
+                inByte = _gs.getc();
+            }
+            DBG("%c", inByte);
+
+            if ((inByte == '\r') || (inByte == '\n'))
+            {
+                // throw away
+                if ((len > 0) && (inByte == '\n'))
+                {
+                    endDetected = true;
+                }
+            }
+            else
+            {
+                buf[len] = inByte;
+                len ++;
+                if (len >= size) break;
+            }
+        }
+    }
+    DBG("\r\n");
+
+    buf[len] = 0;
+    return len;
+}
+
+int GSClass::readData(SOCKET s, uint8_t* buf, int len)
+{
+    int dataLen = 0;
+    uint8_t tmp1, tmp2;
+
+//    if (!_gs.readable())
+    if (!((! _rts && _gs.readable()) || (_rts && bufreadable())))
+        return 0;
+
+    while(dataLen < len) {
+//        if (_gs.readable()) {
+//            tmp1 = _gs.getc();
+        if ((! _rts && _gs.readable()) || (_rts && bufreadable())) {
+            if (_rts) {
+                tmp1 = getbuf();
+            } else {
+                tmp1 = _gs.getc();
+            }
+//            DBG("%02x ", tmp1);
+//            DBG("%c", tmp1);
+            if (tmp1 == 0x1b) {
+                // escape seq
+
+                /* read in escape sequence */
+                while(1) {
+//                    if (_gs.readable()) {
+//                        tmp2 = _gs.getc();
+                    if ((! _rts && _gs.readable()) || (_rts && bufreadable())) {
+                        if (_rts) {
+                            tmp2 = getbuf();
+                        } else {
+                            tmp2 = _gs.getc();
+                        }
+//                        DBG("%02x ", tmp2);
+                        break;
+                    }
+                }
+                
+                if (tmp2 == 0x45) {
+                    /* data end, switch to command mode */
+                    dev_mode = DEV_OP_MODE_COMMAND;
+                    /* clear flag */
+                    dataOnSock = 255;
+                    break;
+                } else {
+                    if (dataLen < (len-2)) {
+                        buf[dataLen++] = tmp1;
+                        buf[dataLen++] = tmp2;
+                    } else {
+                        buf[dataLen++] = tmp1;
+
+                        /* FIXME : throw away second byte ? */
+                    }
+                }
+            } else {
+                // data
+                buf[dataLen] = tmp1;
+                dataLen++;
+            }
+        }
+    }
+//    DBG(" (%d)\r\n", dataLen);
+
+//    buf[dataLen] = 0;
+    return dataLen;
+}
+
+int GSClass::writeData(SOCKET s, const uint8_t*  buf, int len)
+{    
+    if ((len == 0) || (buf[0] == '\r')){
+    } else {
+        _gs.putc(0x1b);    // data start
+        _gs.putc(0x53);
+        _gs.putc(int_to_hex(client_cid));
+        if (len == 1){
+            if (buf[0] != '\r' && buf[0] != '\n'){ 
+                _gs.putc(buf[0]);           // data to send
+            } else if (buf[0] == '\n') {
+                _gs.printf("\n\r");           // new line
+            } 
+        } else {
+            for (int i = 0; i < len; i ++) {
+                _gs.putc(buf[i]);
+            }
+        }
+
+        _gs.putc(0x1b);    // data end
+        _gs.putc(0x45);
+    }
+    wait_ms(10);
+
+    return 1;
+}
+
+void GSClass::process()
+{
+    char buf[256];
+    int len = 0;
+    char inByte;
+    int processDone = 0;
+
+//    if (!_gs.readable())
+    if (!((! _rts && _gs.readable()) && (_rts && bufreadable())))
+        return;
+
+    while (!processDone) {
+        if (dev_mode == DEV_OP_MODE_COMMAND) {
+            while (1) {
+//                if (_gs.readable()) {
+//                    inByte = _gs.getc();
+                if ((! _rts && _gs.readable()) || (_rts && bufreadable())) {
+                    if (_rts) {
+                        inByte = getbuf();
+                    } else {
+                        inByte = _gs.getc();
+                    }
+
+                    if (inByte == 0x1b) {
+                        // escape seq
+
+                        // switch mode
+                        dev_mode = DEV_OP_MODE_DATA;
+                        break;
+                    } else {
+                        // command string
+                        if ((inByte == '\r') || (inByte == '\n')) {
+                            // throw away
+                            if ((len > 0) && (inByte == '\n'))
+                            {
+                                // parse command
+                                parse_cmd(buf, len);
+                                processDone = 1;
+                                break;
+                            }
+                        }
+                        else
+                        {
+                            buf[len] = inByte;
+                            len ++;
+                        }
+                    }
+                }
+            }
+        } else if (dev_mode == DEV_OP_MODE_DATA) {
+            /* data mode */
+            while(1) {
+                //digitalWrite(5, LOW);
+//                if (_gs.readable()) {
+//                    inByte = _gs.getc();
+                if ((! _rts && _gs.readable()) || (_rts && bufreadable())) {
+                    if (_rts) {
+                        inByte = getbuf();
+                    } else {
+                        inByte = _gs.getc();
+                    }
+
+                    if (inByte == 0x53) {
+                        /* data start, switch to data RX mode */
+                        dev_mode = DEV_OP_MODE_DATA_RX;
+                        /* read in CID */
+                        while(1) {
+//                            if (_gs.readable()) {
+//                                inByte = _gs.getc();
+                            if ((! _rts && _gs.readable()) || (_rts && bufreadable())) {
+                                if (_rts) {
+                                    inByte = getbuf();
+                                } else {
+                                    inByte = _gs.getc();
+                                }
+                                
+                                break;
+                            }
+                        }
+
+                        // find socket from CID
+                        for (SOCKET new_sock = 0; new_sock < 4; new_sock++) {
+                            if (sock_table[new_sock].cid == hex_to_int(inByte)) {
+                                dataOnSock = new_sock;
+                                break;
+                            }
+                        }
+
+                        break;
+                    } else if (inByte == 0x45) {
+                        /* data end, switch to command mode */
+                        dev_mode = DEV_OP_MODE_COMMAND;
+                        processDone = 1;
+                        break;
+                    } else if (inByte == 0x4f) {
+                        /* data mode ok */
+                        tx_done = 1;
+                        dev_mode = DEV_OP_MODE_COMMAND;
+                        processDone = 1;
+                        break;
+                    } else if (inByte == 0x46) {
+                        /* TX failed */
+                        tx_done = 1;
+                        dev_mode = DEV_OP_MODE_COMMAND;
+                        processDone = 1;
+                        break;
+                    } else {
+                        /* unknown */
+                        dev_mode = DEV_OP_MODE_COMMAND;
+                        processDone = 1;
+                        break;
+                    }
+                }
+            }
+        } else if (dev_mode ==  DEV_OP_MODE_DATA_RX) {
+            //digitalWrite(6, LOW);
+            processDone = 1;
+        }
+    }
+}
+
+void GSClass::parse_cmd(char *buf, int len)
+{
+    if (strstr(buf, "CONNECT")) {
+        /* got CONNECT */
+
+        if (serv_cid == hex_to_int(buf[8])) {
+            /* client connected */
+            client_cid = hex_to_int(buf[10]);
+        }
+
+        for (int sock = 0; sock < 4; sock++) {
+            if ((sock_table[sock].status == SOCK_STATUS::LISTEN) &&
+                (sock_table[sock].cid == hex_to_int(buf[8])))
+            {
+                for (int new_sock = 0; new_sock < 4; new_sock++) {
+                    if (sock_table[new_sock].status == SOCK_STATUS::CLOSED) {
+                        sock_table[new_sock].cid = hex_to_int(buf[10]);
+                        sock_table[new_sock].port = sock_table[sock].port;
+                        sock_table[new_sock].protocol = sock_table[sock].protocol;
+                        sock_table[new_sock].status = SOCK_STATUS::ESTABLISHED;
+                        break;
+                    }
+                }
+            }
+        }
+
+    } else if (strstr(buf, "DISCONNECT")) {
+        /* got disconnect */
+        //digitalWrite(6, LOW);
+        for (int sock = 0; sock < 4; sock++) {
+            if ((sock_table[sock].status == SOCK_STATUS::ESTABLISHED) &&
+                (sock_table[sock].cid == hex_to_int(buf[11])))
+            {
+                sock_table[sock].cid = 0;
+                sock_table[sock].port = 0;
+                sock_table[sock].protocol = 0;
+                sock_table[sock].status = SOCK_STATUS::CLOSED;
+                break;
+            }
+        }
+        // FIXME : need to handle socket disconnection
+    } else if (strcmp(buf, "Disassociation Event")) {
+        /* disconnected from AP */
+        connection_state = DEV_CONN_ST_DISCONNECTED;
+    }
+}
+
+void GSClass::parse_data(char *buf, int len)
+{
+    rx_data_handler(buf, len);
+}
+
+int GSClass::connect_socket(Host &host)
+{
+    ip = host.getIp();
+    port = host.getPort();
+
+    if (!send_cmd_w_resp(CMD_TCP_CONN)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+int GSClass::dns_lookup(Host &url)
+{
+    dns_url_ip.setName(url.getName());
+
+    if (!send_cmd_w_resp(CMD_DNS_LOOKUP)) {
+        return 0;
+    }
+
+    url.setIp(dns_url_ip.getIp());
+    return 1;
+}
+
+uint8_t *GSClass::get_dev_id()
+{
+    return dev_id;
+}
+
+void GSClass::configSocket(SOCKET s, int protocol, int port)
+{
+    sock_table[s].protocol = protocol;
+    sock_table[s].port = port;
+    sock_table[s].status = SOCK_STATUS::INIT;
+}
+
+void GSClass::execSocketCmd(SOCKET s, int cmd)
+{
+    socket_num = s;
+
+    if (!send_cmd_w_resp(cmd)) {
+    }
+}
+
+int GSClass::readSocketStatus(SOCKET s)
+{
+    return sock_table[s].status;
+}
+
+int GSClass::isDataOnSock(SOCKET s)
+{
+    return (s == dataOnSock);
+}
+
+void GSClass::flush()
+{
+    // arduino-1.0 repurposed the Serial.flush() command
+    // to wait for outgoing data to be transmitted, not to
+    // clear the buffer
+    // since we need to clear the buffer, need to create this
+    // workaround
+    _rxaddr_w = _rxaddr_r = 0;
+/*
+    while (_gs.readable())
+    {
+        _gs.getc();
+    }
+*/
+}
+
+void GSClass::isr_recv () {
+    _rxbuf[_rxaddr_w] = _gs.getc();
+    DBG("%02x ", _rxbuf[_rxaddr_w]);
+    _rxaddr_w = (_rxaddr_w + 1) % MAX_RXBUF_SIZE;
+}
+
+int GSClass::getbuf () {
+    int r;
+//    if (_rxaddr_w == _rxaddr_r) return 0;
+    __disable_irq();
+    r = _rxbuf[_rxaddr_r];
+    _rxaddr_r = (_rxaddr_r + 1) % MAX_RXBUF_SIZE;
+    __enable_irq();
+    return r;
+}
+
+int GSClass::bufreadable () {
+    return _rxaddr_w != _rxaddr_r;
+}