work.

Dependencies:   Blynk mbed

Revision:
3:4cd9171ba989
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ESP8266.cpp	Thu Jun 16 08:08:30 2016 +0000
@@ -0,0 +1,1533 @@
+/**
+ * @file ESP8266.cpp
+ * @brief The implementation of class ESP8266.
+ * @author Wu Pengfei<pengfei.wu@itead.cc>
+ * @date 2015.02
+ *
+ * @par Copyright:
+ * Copyright (c) 2015 ITEAD Intelligent Systems Co., Ltd. \n\n
+ * 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. \n\n
+ * 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 "ESP8266_HardSer.h"
+//#include <avr/pgmspace.h>
+#ifdef ESP8266_USE_SOFTWARE_SERIAL
+ESP8266::ESP8266(SoftwareSerial &uart): m_puart(&uart)
+{
+    m_onData = NULL;
+    m_onDataPtr = NULL;
+}
+#else
+ESP8266::ESP8266(HardwareSerial &uart): m_puart(&uart)
+{
+    m_onData = NULL;
+    m_onDataPtr = NULL;
+}
+#endif
+
+bool ESP8266::kick(void)
+{
+    LOG_ENTER;
+    return eAT();
+}
+
+bool ESP8266::restart(void)
+{
+    LOG_ENTER;
+    unsigned long start;
+    if (eATRST()) {
+        //delay(2000);
+        wait_ms(2000);
+        //start = millis();
+        start = g_Timer.read_ms();
+        while (g_Timer.read_ms() - start < 3000) {
+            if (eAT()) {
+                //delay(1500); /* Waiting for stable */
+                wait_ms(1500);
+                return true;
+            }
+            //delay(100);
+            wait_ms(100);
+        }
+    }
+    return false;
+}
+
+String ESP8266::getVersion(void)
+{
+    LOG_ENTER;
+    String version;
+    eATGMR(version);
+    return version;
+}
+
+bool ESP8266::setEcho(uint8_t mode)
+{
+    LOG_ENTER;
+    return eATE(mode);
+}
+
+bool ESP8266::restore(void)
+{
+    LOG_ENTER;
+    return eATRESTORE();
+}
+
+bool ESP8266::setUart(uint32_t baudrate,uint8_t pattern)
+{
+    LOG_ENTER;
+    return eATSETUART(baudrate,pattern);
+}
+
+bool ESP8266::deepSleep(uint32_t time)
+{
+    LOG_ENTER;
+    return eATGSLP(time);
+}
+
+bool ESP8266::setOprToStation(uint8_t pattern1,uint8_t pattern2)
+{
+    LOG_ENTER;
+    uint8_t mode;
+    if (!qATCWMODE(&mode,pattern1)) {
+        return false;
+    }
+    if (mode == 1) {
+        return true;
+    } else {
+        if (sATCWMODE(1,pattern2)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+
+String ESP8266::getWifiModeList(void)
+{
+    LOG_ENTER;
+    String list;
+    eATCWMODE(list);
+    return list;
+}
+
+bool ESP8266::setOprToSoftAP(uint8_t pattern1,uint8_t pattern2)
+{
+    LOG_ENTER;
+    uint8_t mode;
+    if (!qATCWMODE(&mode,pattern1)) {
+        return false;
+    }
+    if (mode == 2) {
+        return true;
+    } else {
+        if (sATCWMODE(2,pattern2) ) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+
+bool ESP8266::setOprToStationSoftAP(uint8_t pattern1,uint8_t pattern2)
+{
+    LOG_ENTER;
+    uint8_t mode;
+    if (!qATCWMODE(&mode,pattern1)) {
+        return false;
+    }
+    if (mode == 3) {
+        return true;
+    } else {
+        if (sATCWMODE(3,pattern2) ) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+
+uint8_t ESP8266::getOprMode(uint8_t pattern1)
+{
+    LOG_ENTER;
+    uint8_t mode;
+    if (!qATCWMODE(&mode,pattern1)) {
+        return 0;
+    } else {
+        return mode;
+    }
+}
+
+String ESP8266::getNowConecAp(uint8_t pattern)
+{
+    LOG_ENTER;
+    String ssid;
+    qATCWJAP(ssid,pattern);
+    return ssid;
+}
+
+String ESP8266::getAPList(void)
+{
+    LOG_ENTER;
+    String list;
+    eATCWLAP(list);
+    return list;
+}
+
+bool ESP8266::joinAP(String ssid, String pwd,uint8_t pattern)
+{
+    LOG_ENTER;
+    return sATCWJAP(ssid, pwd,pattern);
+}
+
+bool ESP8266::leaveAP(void)
+{
+    LOG_ENTER;
+    return eATCWQAP();
+}
+
+String ESP8266::getSoftAPParam(uint8_t pattern)
+{
+    LOG_ENTER;
+    String list;
+    qATCWSAP(list,pattern);
+    return list;
+}
+
+bool ESP8266::setSoftAPParam(String ssid, String pwd, uint8_t chl, uint8_t ecn,uint8_t pattern)
+{
+    LOG_ENTER;
+    return sATCWSAP(ssid, pwd, chl, ecn,pattern);
+}
+
+String ESP8266::getJoinedDeviceIP(void)
+{
+    LOG_ENTER;
+    String list;
+    eATCWLIF(list);
+    return list;
+}
+
+String ESP8266::getDHCP(uint8_t pattern)
+{
+    LOG_ENTER;
+    String dhcp;
+    qATCWDHCP(dhcp,pattern);
+    return dhcp;
+}
+
+bool ESP8266::setDHCP(uint8_t mode, uint8_t en, uint8_t pattern)
+{
+    LOG_ENTER;
+    return sATCWDHCP(mode, en, pattern);
+}
+
+bool ESP8266::setAutoConnect(uint8_t en)
+{
+    LOG_ENTER;
+    return eATCWAUTOCONN(en);
+}
+
+String ESP8266::getStationMac(uint8_t pattern)
+{
+    LOG_ENTER;
+    String mac;
+    qATCIPSTAMAC(mac,pattern);
+    return mac;
+}
+
+bool ESP8266::setStationMac(String mac,uint8_t pattern)
+{
+    LOG_ENTER;
+    return eATCIPSTAMAC(mac,pattern);
+}
+
+String ESP8266::getStationIp(uint8_t pattern)
+{
+    LOG_ENTER;
+    String ip;
+    qATCIPSTAIP(ip,pattern);
+    return ip;
+}
+
+bool ESP8266::setStationIp(String ip,String gateway,String netmask,uint8_t pattern)
+{
+    LOG_ENTER;
+    return eATCIPSTAIP(ip,gateway,netmask,pattern);
+}
+
+String ESP8266::getAPIp(uint8_t pattern)
+{
+    LOG_ENTER;
+    String ip;
+    qATCIPAP(ip,pattern);
+    return ip;
+}
+
+bool ESP8266::setAPIp(String ip,uint8_t pattern)
+{
+    LOG_ENTER;
+    return eATCIPAP(ip,pattern);
+}
+
+bool ESP8266::startSmartConfig(uint8_t type)
+{
+    LOG_ENTER;
+    return eCWSTARTSMART(type);
+}
+
+bool ESP8266::stopSmartConfig(void)
+{
+    LOG_ENTER;
+    return eCWSTOPSMART();
+}
+
+
+String ESP8266::getIPStatus(void)
+{
+    LOG_ENTER;
+    String list;
+    eATCIPSTATUS(list);
+    return list;
+}
+
+String ESP8266::getLocalIP(void)
+{
+    LOG_ENTER;
+    String list;
+    eATCIFSR(list);
+    return list;
+}
+
+bool ESP8266::enableMUX(void)
+{
+    LOG_ENTER;
+    return sATCIPMUX(1);
+}
+
+bool ESP8266::disableMUX(void)
+{
+    LOG_ENTER;
+    return sATCIPMUX(0);
+}
+
+bool ESP8266::createTCP(String addr, uint32_t port)
+{
+    LOG_ENTER;
+    return sATCIPSTARTSingle("TCP", addr, port);
+}
+
+bool ESP8266::releaseTCP(void)
+{
+    LOG_ENTER;
+    return eATCIPCLOSESingle();
+}
+
+bool ESP8266::registerUDP(String addr, uint32_t port)
+{
+    LOG_ENTER;
+    return sATCIPSTARTSingle("UDP", addr, port);
+}
+
+bool ESP8266::unregisterUDP(void)
+{
+    LOG_ENTER;
+    return eATCIPCLOSESingle();
+}
+
+bool ESP8266::createTCP(uint8_t mux_id, String addr, uint32_t port)
+{
+    LOG_ENTER;
+    return sATCIPSTARTMultiple(mux_id, "TCP", addr, port);
+}
+
+bool ESP8266::releaseTCP(uint8_t mux_id)
+{
+    LOG_ENTER;
+    return sATCIPCLOSEMulitple(mux_id);
+}
+
+bool ESP8266::registerUDP(uint8_t mux_id, String addr, uint32_t port)
+{
+    LOG_ENTER;
+    return sATCIPSTARTMultiple(mux_id, "UDP", addr, port);
+}
+
+bool ESP8266::unregisterUDP(uint8_t mux_id)
+{
+    LOG_ENTER;
+    return sATCIPCLOSEMulitple(mux_id);
+}
+
+bool ESP8266::setTCPServerTimeout(uint32_t timeout)
+{
+    LOG_ENTER;
+    return sATCIPSTO(timeout);
+}
+
+bool ESP8266::startTCPServer(uint32_t port)
+{
+    LOG_ENTER;
+    if (sATCIPSERVER(1, port)) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::stopTCPServer(void)
+{
+    LOG_ENTER;
+    sATCIPSERVER(0);
+    restart();
+    return false;
+}
+
+bool ESP8266::setCIPMODE(uint8_t mode)
+{
+    LOG_ENTER;
+    return sATCIPMODE(mode);
+}
+
+bool ESP8266::saveTransLink (uint8_t mode,String ip,uint32_t port)
+{
+    LOG_ENTER;
+    return eATSAVETRANSLINK(mode,ip,port);
+}
+
+bool ESP8266::setPing(String ip)
+{
+    LOG_ENTER;
+    return eATPING(ip);
+}
+
+
+bool ESP8266::startServer(uint32_t port)
+{
+    LOG_ENTER;
+    return startTCPServer(port);
+}
+
+bool ESP8266::stopServer(void)
+{
+    LOG_ENTER;
+    return stopTCPServer();
+}
+
+bool ESP8266::send(const uint8_t *buffer, uint32_t len)
+{
+    LOG_ENTER;
+    return sATCIPSENDSingle(buffer, len);
+}
+
+bool ESP8266::sendFromFlash(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
+{
+    LOG_ENTER;
+    return sATCIPSENDMultipleFromFlash(mux_id, buffer, len);
+}
+
+bool ESP8266::sendFromFlash(const uint8_t *buffer, uint32_t len)
+{
+    LOG_ENTER;
+    return sATCIPSENDSingleFromFlash(buffer, len);
+}
+
+bool ESP8266::send(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
+{
+    LOG_ENTER;
+    return sATCIPSENDMultiple(mux_id, buffer, len);
+}
+
+void ESP8266::run()
+{
+    LOG_ENTER;
+    rx_empty();
+}
+
+/*----------------------------------------------------------------------------*/
+/* +IPD,<id>,<len>:<data> */
+/* +IPD,<len>:<data> */
+
+uint32_t ESP8266::checkIPD(String& data)
+{
+    //Serial.print("### check: ");
+    //Serial.println(data);
+	LOG_ENTER;
+    int32_t index_PIPDcomma = -1;
+    int32_t index_colon = -1; /* : */
+    int32_t index_comma = -1; /* , */
+    int32_t len = -1;
+    int8_t id = -1;
+    {
+        // Just for easier diffing
+        index_PIPDcomma = data.indexOf("+IPD,");
+        if (index_PIPDcomma != -1) {
+            index_colon = data.indexOf(':', index_PIPDcomma + 5);
+            if (index_colon != -1) {
+                index_comma = data.indexOf(',', index_PIPDcomma + 5);
+                /* +IPD,id,len:data */
+                if (index_comma != -1 && index_comma < index_colon) {
+                    id = data.substring(index_PIPDcomma + 5, index_comma).toInt();
+                    if (id < 0 || id > 4) {
+                        return 0;
+                    }
+                    len = data.substring(index_comma + 1, index_colon).toInt();
+                    if (len <= 0) {
+                        return 0;
+                    }
+                } else { /* +IPD,len:data */
+                    len = data.substring(index_PIPDcomma + 5, index_colon).toInt();
+                    if (len <= 0) {
+                        return 0;
+                    }
+                }
+                if (m_onData) {
+                    m_onData(id, len, m_onDataPtr);
+                }
+                return len;
+            }
+        }
+    }
+    return 0;
+}
+
+void ESP8266::rx_empty(void)
+{
+    LOG_ENTER;
+    String data;
+    char a;
+    unsigned long start = g_Timer.read_ms();
+    while (g_Timer.read_ms() - start < 10) {
+        if (m_puart->readable()) {
+            a = m_puart->getc();
+            if(a == '\0') continue;
+            data += a;
+            if (checkIPD(data)) {
+                data = "";
+            }
+            start = g_Timer.read_ms();
+        }
+    }
+}
+
+String ESP8266::recvString(String target, uint32_t timeout)
+{
+    LOG_ENTER;
+    String data;
+    char a;
+    unsigned long start = g_Timer.read_ms();
+    while (g_Timer.read_ms() - start < timeout) {
+        while(m_puart->readable() > 0) {
+            a = m_puart->getc();
+            ESP8266_LOG("a=0x%02X ", a);
+            if(a == '\0') continue;
+            data += a;
+            if (data.indexOf(target) != -1) {
+                ESP8266_LOG("\r\ndata = %s\r\n", data.c_str());
+                return data;
+            } else if (checkIPD(data)) {
+                data = "";
+            }
+        }
+    }
+	ESP8266_LOG("\r\n");
+	ESP8266_LOG("data1 = %s\r\n", data.c_str());
+    return data;
+}
+
+String ESP8266::recvString(String target1, String target2, uint32_t timeout)
+{
+    LOG_ENTER;
+    String data;
+    char a;
+    unsigned long start = g_Timer.read_ms();
+    while (g_Timer.read_ms() - start < timeout) {
+        while(m_puart->readable() > 0) {
+            a = m_puart->getc();
+            ESP8266_LOG("a=0x%02x ", a);
+            if(a == '\0') continue;
+            data += a;
+            if (data.indexOf(target1) != -1) {
+                ESP8266_LOG("\r\ndata2 = %s\r\n", data.c_str());
+                return data;
+            } else if (data.indexOf(target2) != -1) {
+                ESP8266_LOG("\r\ndata3 = %s\r\n", data.c_str());
+                return data;
+            } else if (checkIPD(data)) {
+                data = "";
+            }
+        }
+    }
+    ESP8266_LOG("\r\ndata4 = %s\r\n", data.c_str());
+    return data;
+}
+
+String ESP8266::recvString(String target1, String target2, String target3, uint32_t timeout)
+{
+    LOG_ENTER;
+    String data;
+    char a;
+    unsigned long start = g_Timer.read_ms();
+    while (g_Timer.read_ms() - start < timeout) {
+        while(m_puart->readable() > 0) {
+            a = m_puart->getc();
+            ESP8266_LOG("a=0x%02x ", a);
+            if(a == '\0') continue;
+            data += a;
+
+            if (data.indexOf(target1) != -1) {
+                ESP8266_LOG("\r\ndata5 = %s\r\n", data.c_str());
+                return data;
+            } else if (data.indexOf(target2) != -1) {
+                ESP8266_LOG("\r\ndata6 = %s\r\n", data.c_str());
+                return data;
+            } else if (data.indexOf(target3) != -1) {
+                ESP8266_LOG("\r\ndata7 = %s\r\n", data.c_str());
+                return data;
+            } else if (checkIPD(data)) {
+                data = "";
+            }
+        }
+    }
+    ESP8266_LOG("\r\ndata8 = %s\r\n", data.c_str());
+    return data;
+}
+
+bool ESP8266::recvFind(String target, uint32_t timeout)
+{
+    LOG_ENTER;
+    String data_tmp;
+    data_tmp = recvString(target, timeout);
+    if (data_tmp.indexOf(target) != -1) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::recvFindAndFilter(String target, String begin, String end, String &data, uint32_t timeout)
+{
+    LOG_ENTER;
+    String data_tmp;
+    data_tmp = recvString(target, timeout);
+    if (data_tmp.indexOf(target) != -1) {
+        int32_t index1 = data_tmp.indexOf(begin);
+        int32_t index2 = data_tmp.indexOf(end);
+        if (index1 != -1 && index2 != -1) {
+            index1 += begin.length();
+            data = data_tmp.substring(index1, index2);
+            return true;
+        }
+    }
+    data = data_tmp;
+    return false;
+}
+
+bool ESP8266::eAT(void)
+{
+    LOG_ENTER;
+    rx_empty();
+    //m_puart->println(F("AT"));
+	m_puart->printf("AT\r\n");
+    return recvFind("OK");
+}
+
+bool ESP8266::eATRST(void)
+{
+    LOG_ENTER;
+    rx_empty();
+    //m_puart->println(F("AT+RST"));
+    m_puart->printf("AT+RST\r\n");
+    return recvFind("OK");
+}
+
+bool ESP8266::eATGMR(String &version)
+{
+    LOG_ENTER;
+    rx_empty();
+    wait_ms(3000);
+    //m_puart->println(F("AT+GMR"));
+    m_puart->printf("AT+GMR\r\n");
+    return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", version, 10000);
+}
+
+bool ESP8266::eATGSLP(uint32_t time)
+{
+    LOG_ENTER;
+    rx_empty();
+    //m_puart->print(F("AT+GSLP="));
+    //m_puart->println(time);
+    m_puart->printf("AT+GSLP=%u\r\n", time);
+    return recvFind("OK");
+}
+
+bool ESP8266::eATE(uint8_t mode)
+{
+    LOG_ENTER;
+    rx_empty();
+    //m_puart->print(F("ATE"));
+    //m_puart->println(mode);
+    m_puart->printf("ATE%d\r\n", mode);
+    return recvFind("OK");
+}
+
+bool ESP8266::eATRESTORE(void)
+{
+    LOG_ENTER;
+    rx_empty();
+    //m_puart->println(F("AT+RESTORE"));
+    m_puart->printf("AT+RESTORE\r\n");
+    return recvFind("OK");
+}
+
+bool ESP8266::eATSETUART(uint32_t baudrate,uint8_t pattern)
+{
+    LOG_ENTER;
+    rx_empty();
+    if(pattern>3||pattern<1) {
+        return false;
+    }
+    switch(pattern) {
+        case 1:
+            //m_puart->print(F("AT+UART="));
+            m_puart->printf("AT+UART=");
+            break;
+        case 2:
+            //m_puart->print(F("AT+UART_CUR="));
+            m_puart->printf("AT+UART_CUR=");
+            break;
+        case 3:
+            //m_puart->print(F("AT+UART_DEF="));
+            m_puart->printf("AT+UART_DEF=");
+            break;
+    }
+    #if 0
+    m_puart->print(baudrate);
+    m_puart->print(F(","));
+    m_puart->print(8);
+    m_puart->print(F(","));
+    m_puart->print(1);
+    m_puart->print(F(","));
+    m_puart->print(0);
+    m_puart->print(F(","));
+    m_puart->println(0);
+    #else
+    m_puart->printf("%u,%d,%d,%d,%d\r\n", baudrate, 8, 1, 0, 0);
+    #endif
+    if(recvFind("OK",5000)) {
+        //m_puart->begin(baudrate);
+        m_puart->baud(baudrate);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool ESP8266::qATCWMODE(uint8_t *mode,uint8_t pattern)
+{
+    LOG_ENTER;
+    String str_mode;
+    bool ret;
+    if (!mode||!pattern) {
+        return false;
+    }
+    rx_empty();
+    switch(pattern) {
+        case 1 :
+            //m_puart->println(F("AT+CWMODE_DEF?"));
+            m_puart->printf("AT+CWMODE_DEF?\r\n");
+            break;
+        case 2:
+            //m_puart->println(F("AT+CWMODE_CUR?"));
+            m_puart->printf("AT+CWMODE_CUR?\r\n");
+            break;
+        default:
+            //m_puart->println(F("AT+CWMODE?"));
+            m_puart->printf("AT+CWMODE?\r\n");
+    }
+    ret = recvFindAndFilter("OK", ":", "\r\n\r\nOK", str_mode);
+    if (ret) {
+        *mode = (uint8_t)str_mode.toInt();
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool ESP8266::eATCWMODE(String &list)
+{
+    LOG_ENTER;
+    rx_empty();
+    //m_puart->println(F("AT+CWMODE=?"));
+    m_puart->printf("AT+CWMODE=?\r\n");
+    return recvFindAndFilter("OK", "+CWMODE:(", ")\r\n\r\nOK", list);
+}
+
+bool ESP8266::sATCWMODE(uint8_t mode,uint8_t pattern)
+{
+    LOG_ENTER;
+    if(!pattern) {
+        return false;
+    }
+    String data;
+    rx_empty();
+    switch(pattern) {
+        case 1 :
+            //m_puart->print(F("AT+CWMODE_DEF="));
+            m_puart->printf("AT+CWMODE_DEF=");
+            break;
+        case 2:
+            //m_puart->print(F("AT+CWMODE_CUR="));
+            m_puart->printf("AT+CWMODE_CUR=");
+            break;
+        default:
+            //m_puart->print(F("AT+CWMODE="));
+            m_puart->printf("AT+CWMODE=");
+    }
+    //m_puart->println(mode);
+    m_puart->printf("%d\r\n", mode);
+    data = recvString("OK", "no change");
+
+    if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
+        return true;
+    }
+    return false;
+}
+
+
+bool ESP8266::qATCWJAP(String &ssid,uint8_t pattern)
+{
+	LOG_ENTER;
+    bool ret;
+    if (!pattern) {
+        return false;
+    }
+    rx_empty();
+    switch(pattern) {
+        case 1 :
+            //m_puart->println(F("AT+CWJAP_DEF?"));
+            m_puart->printf("AT+CWJAP_DEF?\r\n");
+            break;
+        case 2:
+            //m_puart->println(F("AT+CWJAP_CUR?"));
+            m_puart->printf("AT+CWJAP_CUR?\r\n");
+            break;
+        default:
+            //m_puart->println(F("AT+CWJAP?"));
+            m_puart->printf("AT+CWJAP?\r\n");
+    }
+    ssid = recvString("OK", "No AP");
+    if (ssid.indexOf("OK") != -1 || ssid.indexOf("No AP") != -1) {
+        return true;
+    }
+    return false;
+
+}
+
+bool ESP8266::sATCWJAP(String ssid, String pwd, uint8_t pattern)
+{
+    LOG_ENTER;
+    String data;
+    if (!pattern) {
+        return false;
+    }
+    rx_empty();
+    switch(pattern) {
+        case 1 :
+            //m_puart->print(F("AT+CWJAP_DEF=\""));
+            m_puart->printf("AT+CWJAP_DEF=\"");
+            break;
+        case 2:
+            //m_puart->print(F("AT+CWJAP_CUR=\""));
+            m_puart->printf("AT+CWJAP_CUR=\"");
+            break;
+        default:
+            //m_puart->print(F("AT+CWJAP=\""));
+            m_puart->printf("AT+CWJAP=\"");
+    }
+#if 0
+    m_puart->print(ssid);
+    m_puart->print(F("\",\""));
+    m_puart->print(pwd);
+    m_puart->println(F("\""));
+#else
+	//TODO:
+	m_puart->printf("%s\",\"%s\"\r\n", ssid.c_str(), pwd.c_str());
+#endif
+    data = recvString("OK", "FAIL", 20000);
+    if (data.indexOf("OK") != -1) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::eATCWLAP(String &list)
+{
+    LOG_ENTER;
+    String data;
+    rx_empty();
+    //m_puart->println(F("AT+CWLAP"));
+    m_puart->printf("AT+CWLAP\r\n");
+    return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 15000);
+}
+
+bool ESP8266::eATCWQAP(void)
+{
+    LOG_ENTER;
+    String data;
+    rx_empty();
+    //m_puart->println(F("AT+CWQAP"));
+    m_puart->printf("AT+CWQAP\r\n");
+    return recvFind("OK");
+}
+
+bool ESP8266::qATCWSAP(String &List,uint8_t pattern)
+{
+    LOG_ENTER;
+    if (!pattern) {
+        return false;
+    }
+    rx_empty();
+    switch(pattern) {
+        case 1 :
+            //m_puart->println(F("AT+CWSAP_DEF?"));
+			m_puart->printf("AT+CWSAP_DEF?\r\n");
+            break;
+        case 2:
+            //m_puart->println(F("AT+CWSAP_CUR?"));
+            m_puart->printf("AT+CWSAP_CUR?\r\n");
+            break;
+        default:
+            //m_puart->println(F("AT+CWSAP?"));
+            m_puart->printf("AT+CWSAP?\r\n");
+    }
+    return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", List,10000);
+}
+
+bool ESP8266::sATCWSAP(String ssid, String pwd, uint8_t chl, uint8_t ecn,uint8_t pattern)
+{
+    LOG_ENTER;
+    String data;
+    if (!pattern) {
+        return false;
+    }
+    rx_empty();
+    switch(pattern) {
+        case 1 :
+            //m_puart->print(F("AT+CWSAP_DEF=\""));
+			m_puart->printf("AT+CWSAP_DEF=\"");
+            break;
+        case 2:
+            //m_puart->print(F("AT+CWSAP_CUR=\""));
+            m_puart->printf("AT+CWSAP_CUR=\"");
+            break;
+        default:
+            //m_puart->print(F("AT+CWSAP=\""));
+			m_puart->printf("AT+CWSAP=\"");
+    }
+    #if 0
+    m_puart->print(ssid);
+    m_puart->print(F("\",\""));
+    m_puart->print(pwd);
+    m_puart->print(F("\","));
+    m_puart->print(chl);
+    m_puart->print(F(","));
+    m_puart->println(ecn);
+	#else
+	m_puart->printf("%s\",\"%s\",%d,%d\r\n", ssid.c_str(), pwd.c_str(), chl, ecn);
+	#endif
+    data = recvString("OK", "ERROR", 5000);
+    if (data.indexOf("OK") != -1) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::eATCWLIF(String &list)
+{
+    LOG_ENTER;
+    String data;
+    rx_empty();
+    //m_puart->println(F("AT+CWLIF"));
+    m_puart->printf("AT+CWLIF\r\n");
+    return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
+}
+
+bool ESP8266::qATCWDHCP(String &List,uint8_t pattern)
+{
+    LOG_ENTER;
+    if (!pattern) {
+        return false;
+    }
+    rx_empty();
+    switch(pattern) {
+        case 1 :
+            //m_puart->println(F("AT+CWDHCP_DEF?"));
+            m_puart->printf("AT+CWDHCP_DEF?\r\n");
+            break;
+        case 2:
+            //m_puart->println(F("AT+CWDHCP_CUR?"));
+            m_puart->printf("AT+CWDHCP_CUR?\r\n");
+            break;
+        default:
+            //m_puart->println(F("AT+CWDHCP?"));
+            m_puart->printf("AT+CWDHCP?\r\n");
+    }
+
+    return recvFindAndFilter("OK", "\r\r\n", "\r\nOK", List,10000);
+
+}
+
+
+bool ESP8266::sATCWDHCP(uint8_t mode, uint8_t en, uint8_t pattern)
+{
+    LOG_ENTER;
+    String data;
+    if (!pattern) {
+        return false;
+    }
+    rx_empty();
+    switch(pattern) {
+        case 1 :
+            //m_puart->print(F("AT+CWDHCP_DEF="));
+			m_puart->printf("AT+CWDHCP_DEF=");
+            break;
+        case 2:
+            //m_puart->print(F("AT+CWDHCP_CUR="));
+            m_puart->printf("AT+CWDHCP_CUR=");
+            break;
+        default:
+            //m_puart->print(F("AT+CWDHCP="));
+			m_puart->printf("AT+CWDHCP=");
+    }
+    #if 0
+    m_puart->print(mode);
+    m_puart->print(F(","));
+    m_puart->println(en);
+    #else
+    m_puart->printf("%d,%d\r\n", mode, en);
+    #endif
+    data = recvString("OK", "ERROR", 2000);
+
+    if (data.indexOf("OK") != -1) {
+        return true;
+    }
+    return false;
+}
+
+
+bool ESP8266::eATCWAUTOCONN(uint8_t en)
+{
+	LOG_ENTER;
+    rx_empty();
+    if(en>1||en<0) {
+        return false;
+    }
+    #if 0
+    m_puart->print(F("AT+CWAUTOCONN="));
+    m_puart->println(en);
+    #else
+    m_puart->printf("AT+CWAUTOCONN=%d\r\n", en);
+    #endif
+    return recvFind("OK");
+
+}
+
+bool ESP8266::qATCIPSTAMAC(String &mac,uint8_t pattern)
+{
+	LOG_ENTER;
+    rx_empty();
+    if (!pattern) {
+        return false;
+    }
+    switch(pattern) {
+        case 1 :
+            //m_puart->println(F("AT+CIPSTAMAC_DEF?"));
+			m_puart->printf("AT+CIPSTAMAC_DEF?\r\n");
+            break;
+        case 2:
+            //m_puart->println(F("AT+CIPSTAMAC_CUR?"));
+            m_puart->printf("AT+CIPSTAMAC_CUR?\r\n");
+            break;
+        default:
+            //m_puart->println(F("AT+CIPSTAMAC?"));
+			m_puart->printf("AT+CIPSTAMAC?\r\n");
+    }
+    return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", mac,2000);
+
+}
+
+
+
+bool ESP8266::eATCIPSTAMAC(String mac,uint8_t pattern)
+{
+	LOG_ENTER;
+    rx_empty();
+    if (!pattern) {
+        return false;
+    }
+    switch(pattern) {
+        case 1 :
+            //m_puart->print(F("AT+CIPSTAMAC_DEF="));
+			m_puart->printf("AT+CIPSTAMAC_DEF=");
+            break;
+        case 2:
+            //m_puart->print(F("AT+CIPSTAMAC_CUR="));
+            m_puart->printf("AT+CIPSTAMAC_CUR=");
+            break;
+        default:
+            //m_puart->print(F("AT+CIPSTAMAC="));
+			m_puart->printf("AT+CIPSTAMAC=");
+    }
+    #if 0
+    m_puart->print(F("\""));
+    m_puart->print(mac);
+    m_puart->println(F("\""));
+    #else
+    m_puart->printf("\"%s\"\r\n", mac.c_str());
+    #endif
+    return recvFind("OK");
+
+}
+
+bool ESP8266::qATCIPSTAIP(String &ip,uint8_t pattern)
+{
+	LOG_ENTER;
+    rx_empty();
+    if (!pattern) {
+        return false;
+    }
+    switch(pattern) {
+        case 1 :
+            //m_puart->println(F("AT+CIPSTA_DEF?"));
+			m_puart->printf("AT+CIPSTA_DEF?\r\n");
+            break;
+        case 2:
+            //m_puart->println(F("AT+CIPSTA_CUR?"));
+            m_puart->printf("AT+CIPSTA_CUR?\r\n");
+            break;
+        default:
+            //m_puart->println(F("AT+CIPSTA?"));
+			m_puart->printf("AT+CIPSTA?\r\n");
+    }
+    return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", ip,2000);
+
+}
+
+bool ESP8266::eATCIPSTAIP(String ip,String gateway,String netmask,uint8_t pattern)
+{
+	LOG_ENTER;
+    rx_empty();
+    if (!pattern) {
+        return false;
+    }
+    switch(pattern) {
+        case 1 :
+            //m_puart->print(F("AT+CIPSTA_DEF="));
+			m_puart->printf("AT+CIPSTA_DEF=");
+            break;
+        case 2:
+            //m_puart->print(F("AT+CIPSTA_CUR="));
+            m_puart->printf("AT+CIPSTA_CUR=");
+            break;
+        default:
+            //m_puart->print(F("AT+CIPSTA="));
+			m_puart->printf("AT+CIPSTA=");
+    }
+    #if 0
+    m_puart->print(F("\""));
+    m_puart->print(ip);
+    m_puart->print(F("\",\""));
+    m_puart->print(gateway);
+    m_puart->print(F("\",\""));
+    m_puart->print(netmask);
+    m_puart->println(F("\""));
+    #else
+    m_puart->printf("\"%s\",\"%s\",\"%s\"\r\n", ip.c_str(), gateway.c_str(), netmask.c_str());
+    #endif
+    return recvFind("OK");
+
+}
+
+
+bool ESP8266::qATCIPAP(String &ip,uint8_t pattern)
+{
+	LOG_ENTER;
+    rx_empty();
+    if (!pattern) {
+        return false;
+    }
+    switch(pattern) {
+        case 1 :
+            //m_puart->println(F("AT+CIPAP_DEF?"));
+			m_puart->printf("AT+CIPAP_DEF?\r\n");
+            break;
+        case 2:
+            //m_puart->println(F("AT+CIPAP_CUR?"));
+            m_puart->printf("AT+CIPAP_CUR?\r\n");
+            break;
+        default:
+            //m_puart->println(F("AT+CIPAP?"));
+			m_puart->printf("AT+CIPAP?\r\n");
+    }
+    return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", ip,2000);
+
+}
+
+
+bool ESP8266::eATCIPAP(String ip,uint8_t pattern)
+{
+	LOG_ENTER;
+    rx_empty();
+    if (!pattern) {
+        return false;
+    }
+    switch(pattern) {
+        case 1 :
+            //m_puart->print(F("AT+CIPAP_DEF="));
+			m_puart->printf("AT+CIPAP_DEF=");
+            break;
+        case 2:
+            //m_puart->print(F("AT+CIPAP_CUR="));
+            m_puart->printf("AT+CIPAP_CUR=");
+            break;
+        default:
+            //m_puart->print(F("AT+CIPAP="));
+			m_puart->printf("AT+CIPAP=");
+    }
+    #if 0
+    m_puart->print(F("\""));
+    m_puart->print(ip);
+    m_puart->println(F("\""));
+    #else
+    m_puart->printf("\"%s\"\r\n", ip.c_str());
+    #endif
+    return recvFind("OK");
+
+}
+
+
+bool ESP8266::eCWSTARTSMART(uint8_t type)
+{
+    LOG_ENTER;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CWSTARTSMART="));
+    m_puart->println(type);
+    #else
+    m_puart->printf("AT+CWSTARTSMART=%d\r\n", type);
+    #endif
+    return recvFind("OK");
+}
+
+bool ESP8266::eCWSTOPSMART(void)
+{
+    LOG_ENTER;
+    rx_empty();
+    //m_puart->println(F("AT+CWSTOPSMART"));
+    m_puart->printf("AT+CWSTOPSMART\r\n");
+    return recvFind("OK");
+}
+
+bool ESP8266::eATCIPSTATUS(String &list)
+{
+    LOG_ENTER;
+    String data;
+    //delay(100);
+    wait_ms(100);
+    rx_empty();
+    //m_puart->println(F("AT+CIPSTATUS"));
+    m_puart->printf("AT+CIPSTATUS\r\n");
+    return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
+}
+
+bool ESP8266::sATCIPSTARTSingle(String type, String addr, uint32_t port)
+{
+    LOG_ENTER;
+    String data;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPSTART=\""));
+    m_puart->print(type);
+    m_puart->print(F("\",\""));
+    m_puart->print(addr);
+    m_puart->print(F("\","));
+    m_puart->println(port);
+	#else
+	m_puart->printf("AT+CIPSTART=\"%s\",\"%s\",%u\r\n", type.c_str(), addr.c_str(), port);
+	#endif
+    data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
+    if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::sATCIPSTARTMultiple(uint8_t mux_id, String type, String addr, uint32_t port)
+{
+    LOG_ENTER;
+    String data;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPSTART="));
+    m_puart->print(mux_id);
+    m_puart->print(F(",\""));
+    m_puart->print(type);
+    m_puart->print(F("\",\""));
+    m_puart->print(addr);
+    m_puart->print(F("\","));
+    m_puart->println(port);
+	#else
+	m_puart->printf("AT+CIPSTART=%d,\"%s\",\"%s\",%u\r\n", mux_id, type.c_str(), addr.c_str(), port);
+	#endif
+    data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
+    if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::sATCIPSENDSingle(const uint8_t *buffer, uint32_t len)
+{
+    LOG_ENTER;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPSEND="));
+    m_puart->println(len);
+    #else
+    m_puart->printf("AT+CIPSEND=%u\r\n", len);
+    #endif
+    if (recvFind(">", 5000)) {
+        rx_empty();
+        for (uint32_t i = 0; i < len; i++) {
+            //m_puart->write(buffer[i]);
+            m_puart->putc(buffer[i]);
+        }
+        return recvFind("SEND OK", 10000);
+    }
+    return false;
+}
+
+bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
+{
+    LOG_ENTER;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPSEND="));
+    m_puart->print(mux_id);
+    m_puart->print(F(","));
+    m_puart->println(len);
+    #else
+    m_puart->printf("AT+CIPSEND=%d,%u\r\n", mux_id, len);
+    #endif
+    if (recvFind(">", 5000)) {
+        rx_empty();
+        for (uint32_t i = 0; i < len; i++) {
+            //m_puart->write(buffer[i]);
+            m_puart->putc(buffer[i]);
+        }
+        return recvFind("SEND OK", 10000);
+    }
+    return false;
+}
+
+bool ESP8266::sATCIPSENDSingleFromFlash(const uint8_t *buffer, uint32_t len)
+{
+    LOG_ENTER;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPSEND="));
+    m_puart->println(len);
+    #else
+    m_puart->printf("AT+CIPSEND=%u\r\n", len);
+    #endif
+    if (recvFind(">", 5000)) {
+        rx_empty();
+        for (uint32_t i = 0; i < len; i++) {
+            //m_puart->write((char) pgm_read_byte(&buffer[i]));
+            m_puart->putc(buffer[i]);
+        }
+        return recvFind("SEND OK", 10000);
+    }
+    return false;
+}
+
+bool ESP8266::sATCIPSENDMultipleFromFlash(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
+{
+    LOG_ENTER;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPSEND="));
+    m_puart->print(mux_id);
+    m_puart->print(F(","));
+    m_puart->println(len);
+    #else
+    m_puart->printf("AT+CIPSEND=%d,%u\r\n", mux_id, len);
+    #endif
+    if (recvFind(">", 5000)) {
+        rx_empty();
+        for (uint32_t i = 0; i < len; i++) {
+            //m_puart->write((char) pgm_read_byte(&buffer[i]));
+            m_puart->putc(buffer[i]);
+        }
+        return recvFind("SEND OK", 10000);
+    }
+    return false;
+}
+
+bool ESP8266::sATCIPCLOSEMulitple(uint8_t mux_id)
+{
+    LOG_ENTER;
+    String data;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPCLOSE="));
+    m_puart->println(mux_id);
+	#else
+	m_puart->printf("AT+CIPCLOSE=%d\r\n", mux_id);
+	#endif
+    data = recvString("OK", "link is not", 5000);
+    if (data.indexOf("OK") != -1 || data.indexOf("link is not") != -1) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::eATCIPCLOSESingle(void)
+{
+    LOG_ENTER;
+    rx_empty();
+    //m_puart->println(F("AT+CIPCLOSE"));
+    m_puart->printf("AT+CIPCLOSE\r\n");
+    return recvFind("OK", 5000);
+}
+
+bool ESP8266::eATCIFSR(String &list)
+{
+    LOG_ENTER;
+    rx_empty();
+    //m_puart->println(F("AT+CIFSR"));
+    m_puart->printf("AT+CIFSR\r\n");
+    return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
+}
+
+bool ESP8266::sATCIPMUX(uint8_t mode)
+{
+    LOG_ENTER;
+    String data;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPMUX="));
+    m_puart->println(mode);
+	#else
+	m_puart->printf("AT+CIPMUX=%d\r\n", mode);
+	#endif
+    data = recvString("OK", "Link is builded");
+    if (data.indexOf("OK") != -1) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port)
+{
+    LOG_ENTER;
+    String data;
+    if (mode) {
+        rx_empty();
+        #if 0
+        m_puart->print(F("AT+CIPSERVER=1,"));
+        m_puart->println(port);
+		#else
+		m_puart->printf("AT+CIPSERVER=1,%u\r\n", port);
+		#endif
+        data = recvString("OK", "no change");
+        if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
+            return true;
+        }
+        return false;
+    } else {
+        rx_empty();
+        //m_puart->println(F("AT+CIPSERVER=0"));
+        m_puart->printf("AT+CIPSERVER=0\r\n");
+        return recvFind("\r\r\n");
+    }
+}
+
+bool ESP8266::sATCIPMODE(uint8_t mode)
+{
+    LOG_ENTER;
+    String data;
+    if(mode>1||mode<0) {
+        return false;
+    }
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPMODE="));
+    m_puart->println(mode);
+	#else
+	m_puart->printf("AT+CIPMODE=%d\r\n", mode);
+	#endif
+    data = recvString("OK", "Link is builded",2000);
+    if (data.indexOf("OK") != -1 ) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::eATSAVETRANSLINK(uint8_t mode,String ip,uint32_t port)
+{
+	LOG_ENTER;
+    String data;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+SAVETRANSLINK="));
+    m_puart->print(mode);
+    m_puart->print(F(",\""));
+    m_puart->print(ip);
+    m_puart->print(F("\","));
+    m_puart->println(port);
+    #else
+    m_puart->printf("AT+SAVETRANSLINK=%d,\"%s\",%u\r\n", mode, ip.c_str(), port);
+    #endif
+    data = recvString("OK", "ERROR",2000);
+    if (data.indexOf("OK") != -1 ) {
+        return true;
+    }
+    return false;
+}
+
+bool ESP8266::eATPING(String ip)
+{
+    LOG_ENTER;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+PING="));
+    m_puart->print(F("\""));
+    m_puart->print(ip);
+    m_puart->println(F("\""));
+    #else
+    m_puart->printf("AT+PING=\"%s\"\r\n", ip.c_str());
+    #endif
+    return recvFind("OK",2000);
+}
+
+bool ESP8266::sATCIPSTO(uint32_t timeout)
+{
+    LOG_ENTER;
+    rx_empty();
+    #if 0
+    m_puart->print(F("AT+CIPSTO="));
+    m_puart->println(timeout);
+    #else
+    m_puart->printf("AT+CIPSTO=%u\r\n", timeout);
+    #endif
+    return recvFind("OK");
+}