ワークショップ用のサンプルプログラムです。

Dependencies:   DHT Milkcocoa mbed

Files at this revision

API Documentation at this revision

Comitter:
jksoft
Date:
Fri Apr 29 21:31:00 2016 +0000
Commit message:
??

Changed in this revision

DHT.lib Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/ESP8266/CBuffer.h Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/ESP8266/ESP8266.cpp Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/ESP8266/ESP8266.h Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/ESP8266Interface.cpp Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/ESP8266Interface.h Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Helper/def.h Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/Endpoint.cpp Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/Endpoint.h Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/Socket.cpp Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/Socket.h Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/TCPSocketConnection.cpp Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/TCPSocketConnection.h Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/TCPSocketServer.cpp Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/TCPSocketServer.h Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/UDPSocket.cpp Show annotated file Show diff for this revision Revisions of this file
ESP8266InterfaceTiny/Socket/UDPSocket.h Show annotated file Show diff for this revision Revisions of this file
MQTTESP8266.h Show annotated file Show diff for this revision Revisions of this file
Milkcocoa.lib Show annotated file Show diff for this revision Revisions of this file
SoftSerialSendOnly/SoftSerialSendOnry.cpp Show annotated file Show diff for this revision Revisions of this file
SoftSerialSendOnly/SoftSerialSendOnry.h Show annotated file Show diff for this revision Revisions of this file
SoftSerialSendOnly/SoftSerialSendOnry_tx.cpp Show annotated file Show diff for this revision Revisions of this file
SoftSerialSendOnly/SoftSerial_Ticker.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 8ac5bb04e34d DHT.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DHT.lib	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/components/code/DHT/#df22ddf10d75
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/ESP8266/CBuffer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266/CBuffer.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,75 @@
+/* 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;
+    };
+
+    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
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/ESP8266/ESP8266.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266/ESP8266.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,523 @@
+/* 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.
+ */
+
+#include "mbed.h"
+#include "ESP8266.h"
+#include "Endpoint.h"
+#include "SoftSerialSendOnry.h"
+
+extern SoftSerialSendOnry pc;
+
+//#include <string>
+//#include <algorithm>
+
+//Debug is disabled by default
+#if 0
+#define DBG(x, ...)  pc.printf("[ESP8266 : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+#define WARN(x, ...) pc.printf("[ESP8266 : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+#define ERR(x, ...)  pc.printf("[ESP8266 : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+#else
+#define DBG(x, ...) //wait_us(10);
+#define WARN(x, ...) //wait_us(10);
+#define ERR(x, ...)
+#endif
+
+#if 0
+#define INFO(x, ...) printf("[ESP8266 : INFO]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+#else
+#define INFO(x, ...)
+#endif
+
+#define ESP_MAX_TRY_JOIN 3
+#define ESP_MAXID 4 // the largest possible ID Value (max num of sockets possible)
+
+ESP8266 * ESP8266::inst;
+char* ip = NULL;
+
+ESP8266::ESP8266(PinName tx, PinName rx, PinName reset, const char *ssid, const char *phrase, uint32_t baud) :
+    wifi(tx, rx), reset_pin(reset), buf_ESP8266(ESP_MBUFFE_MAX)
+{
+    INFO("Initializing ESP8266 object");
+    memset(&state, 0, sizeof(state));
+
+
+    strcpy(this->ssid, ssid);
+    strcpy(this->phrase, phrase);
+    inst = this;
+    attach_rx(false);
+
+    wifi.baud(baud); // initial baud rate of the ESP8266
+
+    state.associated = false;
+    state.cmdMode = false;
+}
+
+bool ESP8266::join()
+{
+    char cmd[100];
+    sendCommand( "AT+CWMODE=1", "change", NULL, 1000);
+    //string cmd="AT+CWJAP=\""+(string)this->ssid+"\",\""+(string)this->phrase+"\"";
+    sprintf(cmd,"AT+CWJAP=\"%s\",\"%s\"",this->ssid,this->phrase);
+    if( sendCommand( cmd, "OK", NULL, 10000) ) {
+        // successfully joined the network
+        state.associated = true;
+        INFO("ssid: %s, phrase: %s", this->ssid, this->phrase);
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::connect()
+{
+    sendCommand("AT+CWDHCP=1,1","OK",NULL,1000); // DHCP Enabled in Station Mode
+    return ESP8266::join();
+}
+
+bool ESP8266::is_connected()
+{
+    return true;
+}
+
+bool ESP8266::start(bool type,char* ip, int port, int id)
+{
+    char cmd[256];
+    // Error Check
+    if(id > ESP_MAXID) {
+        ERR("startUDPMulti: max id is: %d, id given is %d",ESP_MAXID,id);
+        return false;
+    }
+    // Single Connection Mode
+    if(id < 0) {
+        DBG("Start Single Connection Mode");
+        //char portstr[5];
+        bool check [3] = {0};
+        //sprintf(portstr, "%d", port);
+        switch(type) {
+            case ESP_UDP_TYPE : //UDP
+                sprintf(cmd,"AT+CIPSTART=\"UDP\",\"%s\",%d",ip,port);
+                check[0] = sendCommand(cmd, "OK", NULL, 10000);
+                //check[0] = sendCommand(( "AT+CIPSTART=\"UDP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
+               break;
+            case ESP_TCP_TYPE : //TCP
+                sprintf(cmd,"AT+CIPSTART=\"TCP\",\"%s\",%d",ip,port);
+                check[0] = sendCommand(cmd, "OK", NULL, 10000);
+                //check[0] = sendCommand(( "AT+CIPSTART=\"TCP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
+                break;
+            default:
+                ERR("Default hit for starting connection, this shouldnt be possible!!");
+                break;
+        }
+        check[1] = sendCommand("AT+CIPMODE=1", "OK", NULL, 1000);// go into transparent mode
+        check[2] = sendCommand("AT+CIPSEND", ">", NULL, 1000);// go into transparent mode
+        // check that all commands were sucessful
+        if(check[0] and check[1] and check[2]) {
+            state.cmdMode = false;
+            return true;
+        } else {
+            ERR("startUDPTransparent Failed for ip:%s, port:%d",ip,port);
+            return false;
+        }
+    }
+    // Multi Connection Mode
+    else {
+        //TODO: impliment Multi Connection Mode
+        ERR("Not currently Supported!");
+        return false;
+    }
+}
+
+bool ESP8266::startUDP(char* ip, int port, int id, int length)
+{
+    char cmd[256];
+    char portstr[5];
+    char idstr[1];
+    char lenstr[2];
+    
+    sprintf(portstr, "%d", port);
+    sprintf(idstr, "%d", id);
+    sprintf(lenstr, "%d", length);
+    
+    sendCommand("AT+CIPMUX=1", "OK", NULL, 1000);
+    sprintf(cmd,"AT+CIPSTART=%d,\"UDP\",\"%s\",%d,1112,0",id,ip,port);
+    sendCommand(cmd, "OK", NULL, 10000);
+    //sendCommand(( "AT+CIPSTART=" + string(idstr) + ",\"UDP\",\"" + (string) ip + "\"," + (string) portstr + ",1112,0").c_str(), "OK", NULL, 10000);
+    sprintf(cmd,"AT+CIPSEND=%d,%d",id,length);
+    sendCommand(cmd, ">", NULL, 1000);// go into transparent mode
+    //sendCommand(("AT+CIPSEND=" + (string)idstr + "," +  (string)lenstr).c_str(), ">", NULL, 1000);// go into transparent mode
+    DBG("Data Mode\r\n");
+    state.cmdMode = false;
+
+    return true;
+}
+
+bool ESP8266::startTCPServer(int port)
+{
+    char cmd[100];
+    bool command_results[3];
+    command_results[0]=sendCommand("AT+CWMODE=3", "OK", NULL, 1000);
+    command_results[1]=sendCommand("AT+CIPMUX=1", "OK", NULL, 1000);
+    if(port == 333){
+        command_results[2]=sendCommand("AT+CIPSERVER=1", "OK", NULL, 1000);
+    }
+    else{
+        sprintf(cmd,"AT+CIPSERVER=1,%d",port);
+        command_results[2]=sendCommand(cmd, "OK", NULL, 1000);
+    }
+    //sendCommand("AT+CIFSR", "OK", NULL, 1000);
+    DBG("Data Mode\r\n");
+    state.cmdMode = false;
+    if (command_results[0] and command_results[1] and command_results[2]){
+        return true;
+    }
+    else{
+        return false;
+    }
+}
+
+bool ESP8266::close()
+{
+    wait(0.1f);
+    send("+++",3);
+    wait(1.0f);
+    state.cmdMode = true;
+    sendCommand("AT+CIPCLOSE","OK", NULL, 10000);
+    return true;
+}
+
+bool ESP8266::disconnect()
+{
+    // if already disconnected, return
+    if (!state.associated)
+        return true;
+    // send command to quit AP
+    sendCommand("AT+CWQAP", "OK", NULL, 10000);
+    state.associated = false;
+    return true;
+}
+
+int ESP8266::strfind(const char *str,const char *chkstr,int pos)
+{
+    if( (strlen(str)-pos) < strlen(chkstr) )    return(-1);
+    
+
+    for(int i=pos;i<strlen(str);i++)
+    {
+        if(memcmp(chkstr,&str[i],strlen(chkstr))==0)
+        {
+            return(i);
+        }
+    }
+    return(-1);
+}
+
+char* ESP8266::substr(const char *str , char *outstr , int pos1 , int pos2 )
+{
+    int size = pos2 - pos1;
+    
+    memcpy(outstr , &str[pos1] , size );
+    outstr[size] = '\0';
+    
+    return(outstr);
+}
+
+int ESP8266::strcount(const char *str , char countstr )
+{
+    int ret = 0;
+    
+    for(int i = 0 ; i < strlen(str) ; i++)
+    {
+        if( str[i] == countstr )
+        {
+            ret++;
+        }
+        
+    }
+    
+    return(ret);
+}
+
+/*
+    Assuming Returned data looks like this:
+    +CIFSR:STAIP,"192.168.11.2"
+    +CIFSR:STAMAC,"18:fe:34:9f:3a:f5"
+    grabbing IP from first set of quotation marks
+*/
+char* ESP8266::getIPAddress()
+{
+    char result[30] = {0};
+    char tmp[30] = {0};
+    int check = 0;
+    check = sendCommand("AT+CIFSR", NULL, result, 1000);
+    //pc.printf("\r\nReceivedInfo for IP Command is: %s\r\n",result);
+    ip = ipString;
+    if(check) {
+        // Success
+        uint8_t pos1 = 0, pos2 = 0;
+        //uint8_t pos3 = 0, pos4 = 0;
+        pos1 = strfind(result,"+CIFSR:STAIP",0);
+        //pos1 = resultString.find("+CIFSR:STAIP");
+        pos1 = strfind(result,"\"",pos1);
+        //pos1 = resultString.find('"',pos1);
+        pos2 = strfind(result,"\"",pos1+1);
+        //pos2 = resultString.find('"',pos1+1);
+        //pos3 = resultString.find('"',pos2+1); //would find mac address
+        //pos4 = resultString.find('"',pos3+1);
+        strncpy(ipString,substr(result,tmp,pos1,pos2),sizeof(ipString));
+        INFO("IP: %s",ipString);
+        ip = ipString;
+
+    } else {
+        // Failure
+        ERR("getIPAddress() failed");
+        ip = NULL;
+    }
+    return ip;
+}
+
+bool ESP8266::gethostbyname(const char * host, char * ip)
+{
+    int nb_digits = 0;
+    char tmp[100];
+    
+    strcpy(ip,host);
+    
+    return true;
+#if 0
+    // no dns needed
+    int pos = strfind(host,".",0);
+    if (pos != -1) {
+        nb_digits = atoi(substr(host,tmp,0,pos));
+    }
+    //printf("substrL %s\r\n", sub.c_str());
+    if (strcount(host,'.') == 3 && nb_digits > 0) {
+        strcpy(ip, host);
+        return true;
+    } else {
+        // dns needed, not currently available
+        ERR("gethostbyname(): DNS Not currently available, only use IP Addresses!");
+        return false;
+    }
+#endif
+}
+
+void ESP8266::reset()
+{
+    reset_pin = 0;
+    wait_us(20);
+    reset_pin = 1;
+    //wait(1);
+    //reset_pin = !reset_pin
+    //send("+++",3);
+    wait(1);
+    state.cmdMode = true;
+    sendCommand("AT", "OK", NULL, 1000);
+    sendCommand("AT+RST", "ready", NULL, 10000);
+    state.associated = false;
+
+}
+
+bool ESP8266::reboot()
+{
+    reset();
+    return true;
+}
+
+void ESP8266::handler_rx(void)
+{
+    //read characters
+    char c;
+    while (wifi.readable()) {
+        c=wifi.getc();
+        buf_ESP8266.queue(c);
+        //if (state.cmdMode) pc.printf("%c",c); //debug echo, needs fast serial console to prevent UART overruns
+    }
+}
+
+void ESP8266::attach_rx(bool callback)
+{
+    if (!callback) {
+        wifi.attach(NULL);
+    }
+    else {
+        wifi.attach(this, &ESP8266::handler_rx);
+    }
+}
+
+int ESP8266::readable()
+{
+    return buf_ESP8266.available();
+}
+
+int ESP8266::writeable()
+{
+    return wifi.writeable();
+}
+
+char ESP8266::getc()
+{
+    char c=0;
+    while (!buf_ESP8266.available());
+    buf_ESP8266.dequeue(&c);
+    return c;
+}
+
+int ESP8266::putc(char c)
+{
+    while (!wifi.writeable() || wifi.readable()); //wait for echoed command characters to be read first
+    return wifi.putc(c);
+}
+
+void ESP8266::flush()
+{
+    buf_ESP8266.flush();
+}
+
+int ESP8266::send(const char * buf, int len)
+{
+    //TODO: need to add handler for data > 2048B, this is the max packet size of the ESP8266.
+    if(len >= 2048){
+        WARN("send buffer >= 2048B, need to chunk this up to be less.");    
+    }
+    const char* bufptr=buf;
+    for(int i=0; i<len; i++) {
+        putc((int)*bufptr++);
+    }
+    return len;
+}
+
+bool ESP8266::sendCommand(const char * cmd, const char * ACK, char * res, int timeout)
+{
+    char read;
+    char checking[512] = "";
+    int checking_size = 0;
+    int fond = -1;
+    Timer tmr;
+    int result = 0;
+
+    DBG("sendCmd:\t %s",cmd);
+
+    attach_rx(true);
+
+    //We flush the buffer
+    while (readable())
+        getc();
+
+    if (!ACK || !strcmp(ACK, "NO")) {
+        for (int i = 0; i < strlen(cmd); i++) {
+            result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result;
+            wait(0.005f); // prevents stuck recieve ready (?) need to let echoed character get read first
+        }
+        putc(13); //CR
+        wait(0.005f); // wait for echo
+        putc(10); //LF
+
+    } else {
+        //We flush the buffer
+        while (readable())
+            getc();
+
+        tmr.start();
+        for (int i = 0; i < strlen(cmd); i++) {
+            result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result;
+            wait(.005); // wait for echo
+        }
+        putc(13); //CR
+        wait(0.005f); // wait for echo
+        putc(10); //LF
+
+        while (1) {
+            if (tmr.read_ms() > timeout) {
+                //We flush the buffer
+                while (readable())
+                    getc();
+
+                DBG("check:\t %s", checking);
+
+                attach_rx(true);
+                return -1;
+            } else if (readable()) {
+                read = getc();
+                //pc.printf("%c",read); //debug echo
+                if ( read != '\r' && read != '\n') {
+                    checking[checking_size] = read;
+                    checking_size++;
+                    checking[checking_size] = '\0';
+                    fond = strfind(checking,ACK,0);
+                    if (fond != -1) {
+                        wait(0.01f);
+
+                        //We flush the buffer
+                        while (readable())
+                            read = getc();
+                        //printf("%c",read); //debug echo
+                        break;
+                    }
+                }
+            }
+        }
+        DBG("check: %s", checking);
+
+        attach_rx(true);
+        return result;
+    }
+
+    //the user wants the result from the command (ACK == NULL, res != NULL)
+    if (res != NULL) {
+        int i = 0;
+        Timer timeout;
+        timeout.start();
+        tmr.reset();
+        while (1) {
+            if (timeout.read() > 2) {
+                if (i == 0) {
+                    res = NULL;
+                    break;
+                }
+                res[i] = '\0';
+                DBG("user str 1: %s", res);
+
+                break;
+            } else {
+                if (tmr.read_ms() > 300) {
+                    res[i] = '\0';
+                    DBG("user str: %s", res);
+
+                    break;
+                }
+                if (readable()) {
+                    tmr.start();
+                    read = getc();
+
+                    // we drop \r and \n
+                    if ( read != '\r' && read != '\n') {
+                        res[i++] = read;
+                    }
+                }
+            }
+        }
+        DBG("user str: %s", res);
+    }
+
+    //We flush the buffer
+    while (readable())
+        getc();
+
+    attach_rx(true);
+    DBG("result: %d", result)
+    return result;
+}
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/ESP8266/ESP8266.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266/ESP8266.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,235 @@
+/* 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.
+ *
+ * @section DESCRIPTION
+ *
+ * ESP8266 serial wifi module
+ *
+ * Datasheet:
+ *
+ * http://www.electrodragon.com/w/Wi07c
+ */
+
+#ifndef ESP8266_H
+#define ESP8266_H
+
+#include "mbed.h"
+#include "CBuffer.h"
+
+#define DEFAULT_WAIT_RESP_TIMEOUT 500
+#define ESP_TCP_TYPE 1
+#define ESP_UDP_TYPE 0 
+#define ESP_MBUFFE_MAX 256
+
+/**
+ * The ESP8266 class
+ */
+class ESP8266
+{
+
+public:
+    /**
+    * 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 reset reset pin of the wifi module ()
+    * @param ssid ssid of the network
+    * @param phrase WEP, WPA or WPA2 key
+    * @param baud the baudrate of the serial connection
+    */
+    ESP8266( PinName tx, PinName rx, PinName reset, const char * ssid, const char * phrase, uint32_t baud );
+
+    /**
+    * Connect the wifi module to the ssid contained in the constructor.
+    *
+    * @return true if connected, false otherwise
+    */
+    bool join();
+
+    /**
+    * Same as Join: connect to the ssid and get DHCP settings
+    * @return true if successful
+    */
+    bool connect();
+    
+    /**
+    * Check connection to the access point
+    * @return true if successful
+    */
+    bool is_connected();
+
+    /**
+    * Disconnect the ESP8266 module from the access point
+    *
+    * @return true if successful
+    */
+    bool disconnect();
+    
+    /*
+    * Start up a UDP or TCP Connection
+    * @param type 0 for UDP, 1 for TCP
+    * @param ip A string that contains the IP, no quotes
+    * @param port Numerical port number to connect to
+    * @param id number between 0-4, if defined it denotes ID to use in multimode (Default to Single connection mode with -1)
+    * @return true if sucessful, 0 if fail
+    */
+    bool start(bool type, char* ip, int port, int id = -1);
+    
+    /*
+    * Legacy Start for UDP only connection in transparent mode
+    * @param ip A string that contains the IP, no quotes
+    * @param id number between 0-4
+    * @param port Numerical port number to connect to
+    * @param length number of characters in the message being sent
+    */
+    bool startUDP(char* ip, int port, int id, int length);
+
+    /*
+    * Legacy Start for UDP only connection in transparent mode
+    * @param ip A string that contains the IP, no quotes
+    * @param id number between 0-4
+    * @param port Numerical port number to connect to
+    * @param length number of characters in the message being sent
+    */
+    //bool startUDP(char* ip, int port, int id, int length);
+
+    /*
+    *Starts the ESP chip as a TCP Server
+    *@param port Numerical port of the server, default is 333
+    */
+    bool startTCPServer(int port = 333);
+
+    /**
+    * Close a connection
+    *
+    * @return true if successful
+    */
+    bool close();
+    
+    /**
+    * Return the IP address 
+    * @return IP address as a string
+    */
+    char* getIPAddress();
+
+    /**
+    * Return the IP address from host name
+    * @return true on success, false on failure
+    */    
+    bool gethostbyname(const char * host, char * ip);
+
+    /**
+    * Reset the wifi module
+    */
+    void reset();
+    
+    /**
+    * Reboot the wifi module
+    */
+    bool reboot();
+
+    /**
+    * Check if characters are available
+    *
+    * @return number of available characters
+    */
+    int readable();
+
+    /**
+    * Check if characters are available
+    *
+    * @return number of available characters
+    */
+    int writeable();
+
+    /**
+    * Read a character
+    *
+    * @return the character read
+    */
+    char getc();
+
+    /**
+    * Write a character
+    *
+    * @param the character which will be written
+    */
+    int putc(char c);
+
+    /**
+    * Flush the buffer
+    */
+    void flush();
+
+    /**
+    * Send a command to the wifi 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 acknowledged. (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 successful
+    */
+    bool sendCommand(const char * cmd, const char * ack = NULL, char * res = NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
+
+    /**
+    * 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 * buf, int len);
+
+    static ESP8266 * getInstance() {
+        return inst;
+    };
+
+protected:
+    int strfind(const char *str,const char *chkstr,int pos=0);
+    char* substr(const char *str , char *outstr , int pos1 , int pos2 );
+    int strcount(const char *str , char countstr );
+
+
+    RawSerial wifi;
+    DigitalOut reset_pin;
+    char phrase[30];
+    char ssid[30];
+    char ipString[20];
+    CircBuffer<char> buf_ESP8266;
+
+    static ESP8266 * inst;
+
+    void attach_rx(bool null);
+    void handler_rx(void);
+
+
+    typedef struct STATE {
+        bool associated;
+        bool cmdMode;
+    } State;
+
+    State state;
+};
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/ESP8266Interface.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266Interface.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,28 @@
+#include "ESP8266Interface.h"
+
+ESP8266Interface::ESP8266Interface( PinName tx, PinName rx, PinName reset,
+                                const char * ssid, const char * phrase, uint32_t baud ) :
+    ESP8266(tx, rx, reset, ssid, phrase, baud )
+{
+}
+
+int ESP8266Interface::init()
+{
+    ESP8266::reset();
+    return 0;
+}
+
+bool ESP8266Interface::connect()
+{
+    return ESP8266::connect();
+}
+
+int ESP8266Interface::disconnect()
+{
+    return ESP8266::disconnect();
+}
+
+char * ESP8266Interface::getIPAddress()
+{
+    return ESP8266::getIPAddress();
+}
\ No newline at end of file
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/ESP8266Interface.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/ESP8266Interface.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,73 @@
+/* ESP8266Interface.h */
+/* 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 ESP8266INTERFACE_H_
+#define ESP8266INTERFACE_H_
+
+#include "ESP8266.h"
+#include "Endpoint.h"
+
+ /**
+ * Interface using ESP8266 to connect to an IP-based network
+ */
+class ESP8266Interface: public ESP8266 {
+public:
+
+    /**
+    * 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 reset reset pin of the wifi module ()
+    * \param ssid ssid of the network
+    * \param phrase WEP or WPA key
+    * \param baud the baudrate of the serial connection (defaults to 115200, diff revs of the firmware use diff baud rates
+    */
+  ESP8266Interface(PinName tx, PinName rx, PinName reset, const char * ssid, const char * phrase, uint32_t baud = 115200 );
+
+  /** 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
+
+  /** Connect
+  * Bring the interface up, start DHCP if needed.
+  * \return 0 on success, a negative number on failure
+  */
+  bool connect();
+  
+  /** Disconnect
+  * Bring the interface down
+  * \return 0 on success, a negative number on failure
+  */
+  int disconnect();
+  
+  /** Get IP address
+  *
+  * \return ip address
+  */
+  char* getIPAddress();
+  
+private:
+};
+
+#include "UDPSocket.h"
+
+#endif /* ESP8266INTERFACE_H_ */
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Helper/def.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Helper/def.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,28 @@
+/* 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 DEF_H
+#define DEF_H
+
+#include "cmsis.h"
+#define htons(x)      __REV16(x)
+#define ntohs(x)      __REV16(x)
+#define htonl(x)      __REV(x)
+#define ntohl(x)      __REV(x)
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/Endpoint.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/Endpoint.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,64 @@
+/* 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.
+ */
+#include "Socket/Socket.h"
+#include "Socket/Endpoint.h"
+#include <cstring>
+
+using std::memset;
+
+Endpoint::Endpoint()
+{
+    ESP8266 = ESP8266::getInstance();
+    if (ESP8266 == NULL)
+        error("Endpoint constructor error: no ESP8266 instance available!\r\n");
+    reset_address();
+}
+Endpoint::~Endpoint() {}
+
+void Endpoint::reset_address(void)
+{
+    _ipAddress[0] = '\0';
+    _port = 0;
+    _id = -1;
+}
+
+int Endpoint::set_address(const char* host, const int port)
+{
+    //Resolve DNS address or populate hard-coded IP address
+    if(ESP8266->gethostbyname(host, _ipAddress)) {
+        _port = port;
+        return 0;
+    } else {
+        return -1;
+    }
+}
+
+char* Endpoint::get_address()
+{
+    return _ipAddress;
+}
+
+int   Endpoint::get_port()
+{
+    return _port;
+}
+
+int Endpoint::get_id()
+{
+    return _id;
+}
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/Endpoint.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/Endpoint.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,72 @@
+/* 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 ENDPOINT_H
+#define ENDPOINT_H
+
+#include "ESP8266.h"
+
+class UDPSocket;
+
+/**
+IP Endpoint (address, port)
+*/
+class Endpoint {
+    friend class UDPSocket;
+
+public:
+    /** IP Endpoint (address, port)
+     */
+    Endpoint(void);
+    
+    ~Endpoint(void);
+    
+    /** Reset the address of this endpoint
+     */
+    void reset_address(void);
+    
+    /** Set the address of this endpoint
+    \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS).
+    \param port The endpoint port
+    \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS).
+     */
+    int  set_address(const char* host, const int port);
+    
+    /** Get the IP address of this endpoint
+    \return The IP address of this endpoint.
+     */
+    char* get_address(void);
+    
+    /** Get the port of this endpoint
+    \return The port of this endpoint
+     */
+    int get_port(void);
+    
+    /** Get the id of this endpoint
+    \return The id of this endpoint
+     */
+    int get_id(void);
+
+protected:
+    char _ipAddress[64];
+    int _port;
+    int _id;
+    
+    ESP8266 * ESP8266;
+};
+
+#endif
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/Socket.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/Socket.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,57 @@
+/* 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.
+ */
+ 
+#include "Socket.h"
+#include <cstring>
+
+//Debug is disabled by default
+#if 0
+//Enable debug
+#include <cstdio>
+#define DBG(x, ...) std::printf("[Socket : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+#define WARN(x, ...) std::printf("[Socket : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+#define ERR(x, ...) std::printf("[Socket : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+
+#else
+//Disable debug
+#define DBG(x, ...) 
+#define WARN(x, ...)
+#define ERR(x, ...) 
+
+#endif
+
+Socket::Socket() : _blocking(true), _timeout(1500) {
+    wifi = ESP8266::getInstance();
+    if (wifi == NULL)
+        ERR("Socket constructor error: no ESP8266 instance available!");
+}
+
+void Socket::set_blocking(bool blocking, unsigned int timeout) {
+    DBG("set blocking: %d %d", blocking, timeout);
+    _blocking = blocking;
+    _timeout = timeout;
+}
+
+int Socket::close() {
+    
+    return (wifi->close()) ? 0 : -1;
+}
+
+Socket::~Socket() {
+    close(); //Don't want to leak
+}
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/Socket.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/Socket.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,51 @@
+/* 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 SOCKET_H_
+#define SOCKET_H_
+
+#include "ESP8266.h"
+
+/** Socket file descriptor and select wrapper
+  */
+class Socket {
+public:
+    /** Socket
+     */
+    Socket();
+    
+    /** Set blocking or non-blocking mode of the socket and a timeout on
+        blocking socket operations
+    \param blocking  true for blocking mode, false for non-blocking mode.
+    \param timeout   timeout in ms [Default: (1500)ms].
+    */
+    void set_blocking(bool blocking, unsigned int timeout=1500);
+    
+    /** Close the socket file descriptor
+     */
+    int close();
+    
+    ~Socket();
+    
+protected:
+    bool _blocking;
+    int _timeout;
+    ESP8266 * wifi;
+};
+
+
+#endif /* SOCKET_H_ */
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/TCPSocketConnection.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/TCPSocketConnection.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,249 @@
+/* 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.
+ */
+#include "TCPSocketConnection.h"
+#include <cstring>
+#include <algorithm>
+#include "SoftSerialSendOnry.h"
+
+extern SoftSerialSendOnry pc;
+
+using std::memset;
+using std::memcpy;
+
+//Debug is disabled by default
+#if 0
+#define DBG(x, ...)  pc.printf("[TCPConnection : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+#define WARN(x, ...) pc.printf("[TCPConnection: WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+#define ERR(x, ...)  pc.printf("[TCPConnection : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 
+#else
+#define DBG(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+#endif
+
+TCPSocketConnection::TCPSocketConnection() :
+    _is_connected(false)
+{
+}
+
+int TCPSocketConnection::connect(const char* host, const int port)
+{
+//    if (init_socket(SOCK_STREAM) < 0)
+//        return -1;
+//
+    if (set_address(host, port) != 0)
+        return -1;
+//
+//    if (lwip_connect(_sock_fd, (const struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
+//        close();
+//        return -1;
+//    }
+//    _is_connected = true;
+
+    _is_connected = ESP8266->start(ESP_TCP_TYPE,_ipAddress,_port);
+    if(_is_connected) { //success
+        return 0;
+    } else { // fail
+        return -1;
+    }
+}
+
+bool TCPSocketConnection::is_connected(void)
+{
+    return _is_connected;
+}
+
+int TCPSocketConnection::send(char* data, int length)
+{
+    if (!_is_connected) {
+        ERR("TCPSocketConnection::receive() - _is_connected is false : you cant receive data until you connect to a socket!");
+        return -1;
+    }
+    Timer tmr;
+    int idx = 0;
+    tmr.start();
+    while ((tmr.read_ms() < _timeout) || _blocking) {
+
+        idx += wifi->send(data, length);
+
+        if (idx == length)
+            return idx;
+    }
+    return (idx == 0) ? -1 : idx;
+
+    //return wifi->send(data,length);
+//
+//    if (!_blocking) {
+//        TimeInterval timeout(_timeout);
+//        if (wait_writable(timeout) != 0)
+//            return -1;
+//    }
+//
+//    int n = lwip_send(_sock_fd, data, length, 0);
+//    _is_connected = (n != 0);
+//
+//    return n;
+
+}
+
+// -1 if unsuccessful, else number of bytes written
+int TCPSocketConnection::send_all(char* data, int length)
+{
+//   if ((_sock_fd < 0) || !_is_connected)
+//        return -1;
+//
+//    int writtenLen = 0;
+//    TimeInterval timeout(_timeout);
+//    while (writtenLen < length) {
+//        if (!_blocking) {
+//            // Wait for socket to be writeable
+//            if (wait_writable(timeout) != 0)
+//                return writtenLen;
+//        }
+//
+//        int ret = lwip_send(_sock_fd, data + writtenLen, length - writtenLen, 0);
+//        if (ret > 0) {
+//            writtenLen += ret;
+//            continue;
+//        } else if (ret == 0) {
+//            _is_connected = false;
+//            return writtenLen;
+//        } else {
+//            return -1; //Connnection error
+//        }
+//    }
+//    return writtenLen;
+    return send(data,length); // just remap to send
+}
+
+int TCPSocketConnection::receive(char* buffer, int length)
+{
+    if (!_is_connected) {
+        ERR("TCPSocketConnection::receive() - _is_connected is false : you cant receive data until you connect to a socket!");
+        return -1;
+    }
+    Timer tmr;
+    int idx = 0;
+    int nb_available = 0;
+    int time = -1;
+
+    //make this the non-blocking case and return if <= 0
+    // remember to change the config to blocking
+    // if ( ! _blocking) {
+    // if ( wifi.readable <= 0 ) {
+    // return (wifi.readable);
+    // }
+    // }
+    //---
+    tmr.start();
+    if (_blocking) {
+        while (1) {
+            nb_available = wifi->readable();
+            if (nb_available != 0) {
+                break;
+            }
+        }
+    }
+    //---
+    // blocking case
+    else {
+        tmr.reset();
+
+        while (time < _timeout) {
+            nb_available = wifi->readable();
+            if (nb_available < 0) return nb_available;
+            if (nb_available > 0) break ;
+            time = tmr.read_ms();
+        }
+
+        if (nb_available == 0) return nb_available;
+    }
+
+    // change this to < 20 mS timeout per byte to detect end of packet gap
+    // this may not work due to buffering at the UART interface
+    tmr.reset();
+    // while ( tmr.read_ms() < 20 ) {
+    // if ( wifi.readable() && (idx < length) ) {
+    // buffer[idx++] = wifi->getc();
+    // tmr.reset();
+    // }
+    // if ( idx == length ) {
+    // break;
+    // }
+    // }
+    //---
+    while (time < _timeout) {
+
+        nb_available = wifi->readable();
+        //for (int i = 0; i < min(nb_available, length); i++) {
+        for (int i = 0; i < min(nb_available, (length-idx)); i++) {
+            buffer[idx] = wifi->getc();
+            idx++;
+        }
+        if (idx == length) {
+            break;
+        }
+        time = tmr.read_ms();
+    }
+    //---
+    return (idx == 0) ? -1 : idx;
+
+//************************ original code below
+//
+//    if (!_blocking) {
+//        TimeInterval timeout(_timeout);
+//        if (wait_readable(timeout) != 0)
+//            return -1;
+//    }
+//
+//    int n = lwip_recv(_sock_fd, data, length, 0);
+//    _is_connected = (n != 0);
+//
+//    return n;
+
+}
+
+// -1 if unsuccessful, else number of bytes received
+int TCPSocketConnection::receive_all(char* data, int length)
+{
+    //ERR("receive_all() not yet implimented");
+    //  if ((_sock_fd < 0) || !_is_connected)
+//        return -1;
+//
+//    int readLen = 0;
+//    TimeInterval timeout(_timeout);
+//    while (readLen < length) {
+//        if (!_blocking) {
+//            //Wait for socket to be readable
+//            if (wait_readable(timeout) != 0)
+//                return readLen;
+//        }
+//
+//        int ret = lwip_recv(_sock_fd, data + readLen, length - readLen, 0);
+//        if (ret > 0) {
+//            readLen += ret;
+//        } else if (ret == 0) {
+//            _is_connected = false;
+//            return readLen;
+//        } else {
+//            return -1; //Connnection error
+//        }
+//    }
+//    return readLen;
+    receive(data,length);
+}
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/TCPSocketConnection.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/TCPSocketConnection.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,82 @@
+/* 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 TCPSOCKET_H
+#define TCPSOCKET_H
+ 
+#include "Socket/Socket.h"
+#include "Socket/Endpoint.h"
+ 
+/**
+TCP socket connection
+*/
+class TCPSocketConnection : public Socket, public Endpoint {
+    friend class TCPSocketServer;
+    
+public:
+    /** TCP socket connection
+    */
+    TCPSocketConnection();
+    
+    /** Connects this TCP socket to the server
+    \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
+    \param port The host's port to connect to.
+    \return 0 on success, -1 on failure.
+    */
+    int connect(const char* host, const int port);
+    
+    /** Check if the socket is connected
+    \return true if connected, false otherwise.
+    */
+    bool is_connected(void);
+    
+    /** Send data to the remote host.
+    \param data The buffer to send to the host.
+    \param length The length of the buffer to send.
+    \return the number of written bytes on success (>=0) or -1 on failure
+     */
+    int send(char* data, int length);
+    
+    /** Send all the data to the remote host.
+    \param data The buffer to send to the host.
+    \param length The length of the buffer to send.
+    \return the number of written bytes on success (>=0) or -1 on failure
+    */
+    int send_all(char* data, int length);
+    
+    /** Receive data from the remote host.
+    \param data The buffer in which to store the data received from the host.
+    \param length The maximum length of the buffer.
+    \return the number of received bytes on success (>=0) or -1 on failure
+     */
+    int receive(char* data, int length);
+    
+    /** Receive all the data from the remote host.
+    \param data The buffer in which to store the data received from the host.
+    \param length The maximum length of the buffer.
+    \return the number of received bytes on success (>=0) or -1 on failure
+    */
+    int receive_all(char* data, int length);
+ 
+private:
+    bool _is_connected;
+ 
+};
+ 
+#endif
+ 
\ No newline at end of file
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/TCPSocketServer.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/TCPSocketServer.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,44 @@
+/* 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.
+ */
+#include "TCPSocketServer.h"
+ 
+#include <cstring>
+ 
+using std::memset;
+using std::memcpy;
+ 
+TCPSocketServer::TCPSocketServer() {
+    
+}
+ 
+int TCPSocketServer::bind(int port) {
+  if(!wifi->startTCPServer(port)) {
+            return(-1);
+   }
+    _port = port;
+    return 0;
+}
+ 
+int TCPSocketServer::listen(int max) {
+    
+    return 0;
+}
+ 
+int TCPSocketServer::accept(TCPSocketConnection& connection) {
+    return 0;
+}
\ No newline at end of file
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/TCPSocketServer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/TCPSocketServer.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,55 @@
+/* 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 TCPSOCKETSERVER_H
+#define TCPSOCKETSERVER_H
+ 
+#include "Socket/Socket.h"
+#include "TCPSocketConnection.h"
+ 
+/** TCP Server.
+  */
+class TCPSocketServer : public Socket {
+  friend class TCPSocketConnection;
+  public:
+    /** Instantiate a TCP Server.
+    */
+    TCPSocketServer();
+    
+    /** Bind a socket to a specific port.
+    \param port The port to listen for incoming connections on.
+    \return 0 on success, -1 on failure.
+    */
+    int bind(int port);
+    
+    /** Start listening for incoming connections.
+    \param backlog number of pending connections that can be queued up at any
+                   one time [Default: 1].
+    \return 0 on success, -1 on failure.
+    */
+    int listen(int backlog=1);
+    
+    /** Accept a new connection.
+    \param connection A TCPSocketConnection instance that will handle the incoming connection.
+    \return 0 on success, -1 on failure.
+    */
+    int accept(TCPSocketConnection& connection);
+private:
+    int _port;
+};
+ 
+#endif
\ No newline at end of file
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/UDPSocket.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/UDPSocket.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,154 @@
+/* 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.
+ */
+
+#include "UDPSocket.h"
+
+#include <string>
+#include <algorithm>
+
+UDPSocket::UDPSocket()
+{
+    endpoint_configured = false;
+    endpoint_read = false;
+    Endpoint currentEndpoint;
+}
+
+int UDPSocket::init(void)
+{
+    return 0;
+}
+
+// Server initialization
+int UDPSocket::bind(int port)
+{
+    return 0;
+}
+
+// -1 if unsuccessful, else number of bytes written
+int UDPSocket::sendTo(Endpoint &remote, char *packet, int length)
+{
+    Timer tmr;
+    int idx = 0;
+
+
+    confEndpoint(remote);
+    
+    // initialize transparent mode if not already done
+    if(!endpoint_configured) {
+        // initialize UDP (default id of -1 means transparent mode)
+        //!wifi->start(ESP_UDP_TYPE, remote._ipAddress, remote._port, remote._id
+        if(!wifi->startUDP(remote._ipAddress, remote._port, 0,length)) {
+            return(-1);
+        }
+        endpoint_configured = true;
+    }
+    
+    tmr.start();
+
+    while ((tmr.read_ms() < _timeout) || _blocking) {
+
+        idx += wifi->send(packet, length);
+
+        if (idx == length)
+            return idx;
+    }
+    return (idx == 0) ? -1 : idx;
+}
+
+// -1 if unsuccessful, else number of bytes received
+int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length)
+{
+    Timer tmr;
+    int idx = 0;
+    int nb_available = 0;
+    int time = -1;
+
+    //make this the non-blocking case and return if <= 0
+    // remember to change the config to blocking
+    // if ( ! _blocking) {
+    // if ( wifi.readable <= 0 ) {
+    // return (wifi.readable);
+    // }
+    // }
+    //---
+    tmr.start();
+    if (_blocking) {
+        while (1) {
+            nb_available = wifi->readable();
+            if (nb_available != 0) {
+                break;
+            }
+        }
+    }
+    //---
+    // blocking case
+    else {
+        tmr.reset();
+
+        while (time < _timeout) {
+            nb_available = wifi->readable();
+            if (nb_available < 0) return nb_available;
+            if (nb_available > 0) break ;
+            time = tmr.read_ms();
+        }
+
+        if (nb_available == 0) return nb_available;
+    }
+
+    // change this to < 20 mS timeout per byte to detect end of packet gap
+    // this may not work due to buffering at the UART interface
+    tmr.reset();
+    // while ( tmr.read_ms() < 20 ) {
+    // if ( wifi.readable() && (idx < length) ) {
+    // buffer[idx++] = wifi->getc();
+    // tmr.reset();
+    // }
+    // if ( idx == length ) {
+    // break;
+    // }
+    // }
+    //---
+    while (time < _timeout) {
+
+        nb_available = wifi->readable();
+        //for (int i = 0; i < min(nb_available, length); i++) {
+        for (int i = 0; i < min(nb_available, (length-idx)); i++) {
+            buffer[idx] = wifi->getc();
+            idx++;
+        }
+        if (idx == length) {
+            break;
+        }
+        time = tmr.read_ms();
+    }
+    //---
+    readEndpoint(remote);
+    return (idx == 0) ? -1 : idx;
+}
+
+bool UDPSocket::confEndpoint(Endpoint & ep)
+{
+    currentEndpoint = ep;
+    return true;
+}
+
+bool UDPSocket::readEndpoint(Endpoint & ep)
+{
+    ep = currentEndpoint;
+    return true;
+}
diff -r 000000000000 -r 8ac5bb04e34d ESP8266InterfaceTiny/Socket/UDPSocket.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266InterfaceTiny/Socket/UDPSocket.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,76 @@
+/* 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 UDPSOCKET_H
+#define UDPSOCKET_H
+
+#include "Endpoint.h"
+#include "Socket.h"
+
+#include <cstdint>
+
+/**
+UDP Socket
+*/
+class UDPSocket: public Socket {
+
+public:
+    /** Instantiate an UDP Socket.
+    */
+    UDPSocket();
+    
+    /** Init the UDP Client Socket without binding it to any specific port
+    \return 0 on success, -1 on failure.
+    */
+    int init(void);
+    
+    /** Bind a UDP Server Socket to a specific port
+    \param port The port to listen for incoming connections on
+    \return 0 on success, -1 on failure.
+    */
+    int bind(int port = -1);
+    
+    /** Send a packet to a remote endpoint
+    \param remote   The remote endpoint
+    \param packet   The packet to be sent
+    \param length   The length of the packet to be sent
+    \return the number of written bytes on success (>=0) or -1 on failure
+    */
+    int sendTo(Endpoint &remote, char *packet, int length);
+    
+    /** Receive a packet from a remote endpoint
+    \param remote   The remote endpoint
+    \param buffer   The buffer for storing the incoming packet data. If a packet
+           is too long to fit in the supplied buffer, excess bytes are discarded
+    \param length   The length of the buffer
+    \return the number of received bytes on success (>=0) or -1 on failure
+    */
+    int receiveFrom(Endpoint &remote, char *buffer, int length);
+    
+private:
+    bool confEndpoint(Endpoint & ep);
+    bool readEndpoint(Endpoint & ep);
+    bool endpoint_configured;
+    bool endpoint_read;
+    Endpoint currentEndpoint;
+    
+};
+
+#include "def.h"
+
+#endif
diff -r 000000000000 -r 8ac5bb04e34d MQTTESP8266.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MQTTESP8266.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,44 @@
+
+#if !defined(MQTTESP8266_H)
+#define MQTTESP8266_H
+
+#include "MQTTmbed.h"
+#include "ESP8266Interface.h"
+#include "MQTTSocket.h"
+
+// This struct is only used to workaround the order that the interfaces are initialized
+// MQTTSocket contains a TCPSocketConnection which needs the ESP8266Interface to be 
+// instantiated first. Unfortunately the only way to instantiate a member before a superclass 
+// is through another superclass.
+struct MQTTESP8266Holder {
+    MQTTESP8266Holder(PinName tx, PinName rx, PinName reset, const char *ssid, const char *pass) :
+            _wifi(tx, rx, reset, ssid, pass) {}
+    
+    ESP8266Interface _wifi;
+};
+
+// Straightforward implementation of a MQTT interface
+class MQTTESP8266 : public MQTTESP8266Holder, public MQTTSocket {    
+private:
+    MQTTESP8266Holder::_wifi;
+    //ESP8266Interface _wifi;
+    
+public:    
+    MQTTESP8266(PinName tx, PinName rx, PinName reset, const char *ssid, const char *pass) :
+            MQTTESP8266Holder(tx, rx, reset, ssid, pass) {
+        _wifi.init();
+        _wifi.connect();
+    }
+    
+    ESP8266Interface& getInterface() {
+        return _wifi;
+    }
+    
+    void reconnect() {
+        _wifi.disconnect();
+        _wifi.connect();
+    }
+};
+
+
+#endif
diff -r 000000000000 -r 8ac5bb04e34d Milkcocoa.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Milkcocoa.lib	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/jksoft/code/Milkcocoa/#9afb66979712
diff -r 000000000000 -r 8ac5bb04e34d SoftSerialSendOnly/SoftSerialSendOnry.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerialSendOnly/SoftSerialSendOnry.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,36 @@
+#include "SoftSerialSendOnry.h"
+
+SoftSerialSendOnry::SoftSerialSendOnry(PinName TX, const char* name) {
+    tx_en = false;
+    if (TX != NC) {
+        tx = new DigitalOut(TX);
+        tx_en = true;
+        tx->write(1);
+        tx_bit = -1;
+        txticker.attach(this, &SoftSerialSendOnry::tx_handler);
+    }
+    
+    baud(9600);
+    format();
+}
+
+SoftSerialSendOnry::~SoftSerialSendOnry() {
+    if (tx_en)
+        delete(tx);
+}
+
+void SoftSerialSendOnry::baud(int baudrate) {
+    bit_period = 1000000 / baudrate;
+}
+
+void SoftSerialSendOnry::format(int bits, Parity parity, int stop_bits) {
+    _bits = bits;
+    _parity = parity;
+    _stop_bits = stop_bits;
+    _total_bits = 1 + _bits + _stop_bits + (bool)_parity;
+}
+
+int SoftSerialSendOnry::_getc()
+{
+    return(0);    
+}
\ No newline at end of file
diff -r 000000000000 -r 8ac5bb04e34d SoftSerialSendOnly/SoftSerialSendOnry.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerialSendOnly/SoftSerialSendOnry.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,105 @@
+#ifndef SOFTSERIAL_SEND_ONRY_H
+#define SOFTSERIAL_SEND_ONRY_H
+
+#include "mbed.h"
+#include "SoftSerial_Ticker.h"
+/** A software serial implementation
+ *
+ */
+class SoftSerialSendOnry: public Stream {
+
+public:
+    /**
+    * Constructor
+    *
+    * @param TX Name of the TX pin, NC for not connected
+    * @param name Name of the connection
+    */
+    SoftSerialSendOnry(PinName TX, const char* name = NULL);
+    virtual ~SoftSerialSendOnry();
+    
+    /** Set the baud rate of the serial port
+     *
+     *  @param baudrate The baudrate of the serial port (default = 9600).
+     */
+    void baud(int baudrate);
+
+    enum Parity {
+        None = 0,
+        Odd,
+        Even,
+        Forced1,
+        Forced0
+    };
+
+    enum IrqType {
+        RxIrq = 0,
+        TxIrq
+    };
+
+    /** Set the transmission format used by the serial port
+     *
+     *  @param bits The number of bits in a word (default = 8)
+     *  @param parity The parity used (SerialBase::None, SerialBase::Odd, SerialBase::Even, SerialBase::Forced1, SerialBase::Forced0; default = SerialBase::None)
+     *  @param stop The number of stop bits (default = 1)
+     */
+    void format(int bits=8, Parity parity=SoftSerialSendOnry::None, int stop_bits=1);
+
+    /** Determine if there is space available to write a character
+     *
+     *  @returns
+     *    1 if there is space to write a character,
+     *    0 otherwise
+     */
+    int writeable();
+
+    /** Attach a function to call whenever a serial interrupt is generated
+     *
+     *  @param fptr A pointer to a void function, or 0 to set as none
+     *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+     */
+    void attach(void (*fptr)(void), IrqType type=RxIrq) {
+        fpointer[type].attach(fptr);
+    }
+
+    /** Attach a member function to call whenever a serial interrupt is generated
+     *
+     *  @param tptr pointer to the object to call the member function on
+     *  @param mptr pointer to the member function to be called
+     *  @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+     */
+    template<typename T>
+    void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
+        fpointer[type].attach(tptr, mptr);
+    }
+
+    /** Generate a break condition on the serial line
+     */
+    void send_break();
+
+protected:
+    DigitalOut *tx;
+    
+    bool tx_en;
+    int bit_period;
+    int _bits, _stop_bits, _total_bits;
+    Parity _parity;
+    
+    FunctionPointer fpointer[2];
+    
+    //tx
+    void tx_handler(void);
+    void prepare_tx(int c);
+    FlexTicker txticker;
+    int _char;
+    volatile int tx_bit;
+    
+    
+    
+    virtual int _getc();
+    virtual int _putc(int c);
+};
+
+
+#endif
+
diff -r 000000000000 -r 8ac5bb04e34d SoftSerialSendOnly/SoftSerialSendOnry_tx.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerialSendOnly/SoftSerialSendOnry_tx.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,80 @@
+#include "SoftSerialSendOnry.h"
+
+int SoftSerialSendOnry::_putc(int c)
+{
+    while(!writeable());
+    prepare_tx(c);
+    tx_bit = 0;
+    txticker.prime();
+    tx_handler();
+    return 0;
+}
+
+void SoftSerialSendOnry::send_break(void) {
+    while(!writeable());
+    tx_bit = 0;         //Just to make sure it appears as non-writable to other threads/IRQs
+    tx->write(0);
+    wait_us((bit_period * _total_bits * 3) / 2);
+    tx->write(1);
+    tx_bit = -1;
+}
+
+int SoftSerialSendOnry::writeable(void)
+{
+    if (!tx_en)
+        return false;
+    if (tx_bit == -1)
+        return true;
+    return false;
+}
+
+void SoftSerialSendOnry::tx_handler(void)
+{
+    if (tx_bit == _total_bits) {
+        tx_bit = -1;
+        fpointer[TxIrq].call();
+        return;
+    }
+
+    //Flip output
+    int cur_out = tx->read();
+    tx->write(!cur_out);
+
+    //Calculate when to do it again
+    int count = bit_period;
+    tx_bit++;
+    while(((_char >> tx_bit) & 0x01) == !cur_out) {
+        count+=bit_period;
+        tx_bit++;
+    }
+
+    txticker.setNext(count);
+}
+
+void SoftSerialSendOnry::prepare_tx(int c)
+{
+    _char = c << 1;
+
+    bool parity;
+    switch (_parity) {
+        case Forced1:
+            _char |= 1 << (_bits + 1);
+        case Even:
+            parity = false;
+            for (int i = 0; i<_bits; i++) {
+                if (((_char >> i) & 0x01) == 1)
+                    parity = !parity;
+            }
+            _char |= parity << (_bits + 1);
+        case Odd:
+            parity = true;
+            for (int i = 0; i<_bits; i++) {
+                if (((_char >> i) & 0x01) == 1)
+                    parity = !parity;
+            }
+            _char |= parity << (_bits + 1);
+    }
+    
+    _char |= 0xFFFF << (1 + _bits + (bool)_parity);
+    _char &= ~(1<<_total_bits);
+}
diff -r 000000000000 -r 8ac5bb04e34d SoftSerialSendOnly/SoftSerial_Ticker.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerialSendOnly/SoftSerial_Ticker.h	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,38 @@
+//A modified version of the regular ticker/timeout libraries to allow us to do timeout without losing accuracy
+
+#ifndef FLEXTICKER_H
+#define FLEXTICKER_H
+
+#include "mbed.h"
+
+class FlexTicker: public TimerEvent {
+    public:
+    template<typename T>
+    void attach(T* tptr, void (T::*mptr)(void)) {
+        _function.attach(tptr, mptr);
+    }
+ 
+    /** Detach the function
+     */
+    void detach() {
+        remove();
+    }
+    
+    void setNext(int delay) {
+        insert(event.timestamp + delay);
+    }
+    
+    void prime(void) {
+        event.timestamp = us_ticker_read();
+    }
+ 
+protected:
+    virtual void handler() {
+        _function.call();
+    }
+ 
+    unsigned int _delay;
+    FunctionPointer _function;
+};
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 8ac5bb04e34d main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,87 @@
+#include "mbed.h"
+#include "MQTTESP8266.h"
+#include "MQTTClient.h"
+#include "SoftSerialSendOnry.h"
+#include "Milkcocoa.h"
+#include "MClient.h"
+#include "DHT.h"
+
+
+// The default setting is for the Simple IoT Board(mbed LPC1114FN28)
+// Please change to fit the platform
+SoftSerialSendOnry pc(dp10); // tx
+DigitalOut myled(dp18);
+DHT sensor(dp13, DHT11);
+
+/************************* WiFi Access Point *********************************/
+
+//#define WLAN_SSID       "...SSID..."
+//#define WLAN_PASS       "...PASS..."
+#define WLAN_SSID       "wx01-dda3ad"
+#define WLAN_PASS       "0db20294cb0d3"
+
+/************************* Your Milkcocoa Setup *********************************/
+
+//#define MILKCOCOA_APP_ID      "...YOUR_MILKCOCOA_APP_ID..."
+#define MILKCOCOA_APP_ID      "teaidsirehz"
+#define MILKCOCOA_DATASTORE   "esp8266"
+
+/************* Milkcocoa Setup (you don't need to change this!) ******************/
+
+#define MILKCOCOA_SERVERPORT  1883
+
+/************ Global State (you don't need to change this!) ******************/
+
+// Create an ESP8266 WiFiClient class to connect to the MQTT server.
+// The default setting is for the Simple IoT Board(mbed LPC1114FN28)
+// Please change to fit the platform
+MQTTESP8266 ipstack(dp16,dp15,dp26,WLAN_SSID,WLAN_PASS); // TX,RX,Reset,SSID,Password,Baud
+MClient client(&ipstack);
+
+const char MQTT_SERVER[]  = MILKCOCOA_APP_ID ".mlkcca.com";
+const char MQTT_CLIENTID[] = __TIME__ MILKCOCOA_APP_ID;
+
+Milkcocoa milkcocoa = Milkcocoa(&client, MQTT_SERVER, MILKCOCOA_SERVERPORT, MILKCOCOA_APP_ID, MQTT_CLIENTID);
+
+extern void onpush(MQTT::MessageData& md);
+
+int main() {
+// void setup() {
+    int error = 0;
+    double h = 0.0f, c = 0.0f;
+    
+    pc.baud(9600);
+    pc.printf("Milkcocoa mbed ver demo\n\r\n\r\n\r");
+    pc.printf("Connecting to %s\n\r",WLAN_SSID);
+    milkcocoa.connect();
+    pc.printf("\n\rWiFi connected\n\r");
+    
+    pc.printf("%d\n\r",milkcocoa.on(MILKCOCOA_DATASTORE, "push", onpush));
+    
+// }
+    while(1) {
+// void loop() {
+        milkcocoa.loop();
+        
+        error = sensor.readData();
+        if (0 == error) {
+            c   = sensor.ReadTemperature(CELCIUS);
+            h   = sensor.ReadHumidity();
+            
+            DataElement elem = DataElement();
+            elem.setValue("temp", c);
+            elem.setValue("hmt", h);
+            milkcocoa.push(MILKCOCOA_DATASTORE, elem);
+        }
+        
+        wait(7.0);
+    }
+}
+
+void onpush(MQTT::MessageData& md)
+{
+    MQTT::Message &message = md.message;
+    DataElement de = DataElement((char*)message.payload);
+    pc.printf("onpush\n\r");
+    pc.printf("%d\n\r",de.getInt("v"));
+}
\ No newline at end of file
diff -r 000000000000 -r 8ac5bb04e34d mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Apr 29 21:31:00 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/aae6fcc7d9bb
\ No newline at end of file