Index: rtos_arduino/trunk/arduino_lib/libraries/ESP8266_Arudino_AT/ESP8266.cpp
===================================================================
--- rtos_arduino/trunk/arduino_lib/libraries/ESP8266_Arudino_AT/ESP8266.cpp	(revision 144)
+++ rtos_arduino/trunk/arduino_lib/libraries/ESP8266_Arudino_AT/ESP8266.cpp	(revision 177)
@@ -2,5 +2,5 @@
  * @file ESP8266.cpp
  * @brief The implementation of class ESP8266. 
- * @author Wu Pengfei<pengfei.wu@itead.cc> 
+ * @author Wu Pengfei<pengfei.wu@itead.cc>, Shinya Honda<honda@ertl.jp> 
  * @date 2015.02
  * 
@@ -26,4 +26,7 @@
 #define LOG_OUTPUT_DEBUG_PREFIX     (1)
 
+#define MUXID_ANY 255
+#define MUXID_SINGLE 0
+
 #ifdef TOPPERS_WITH_ARDUINO
 #define WAIT_TIMEOUT delay(1);
@@ -50,21 +53,112 @@
     } while(0)
 
+ESP8266_RingBuffer::ESP8266_RingBuffer(void)
+{
+    free(); 
+    buffer = NULL;
+}
+
+void ESP8266_RingBuffer::init(void)
+{
+    free();
+    if(buffer!=NULL) {
+        ::free(buffer);
+        buffer = NULL;
+    }
+}
+
+bool ESP8266_RingBuffer::write(uint8_t c)
+{
+    if (len == ESP8266_RINGBUFFER_SIZE) {return false;}  
+
+    if (buffer == NULL) {
+        buffer = (uint8_t*)malloc(ESP8266_RINGBUFFER_SIZE);
+        if(buffer == NULL) {return false;}
+    }
+
+    buffer[tail++] = c;
+    len++;
+
+    if (tail == ESP8266_RINGBUFFER_SIZE) {
+        tail = 0;
+    }
+    return true;
+}
+
+uint8_t ESP8266_RingBuffer::read(void)
+{
+    uint8_t c;
+    if (len == 0) {return 0;}
+    c = buffer[head++];
+    len--;
+    if (head == ESP8266_RINGBUFFER_SIZE) {
+        head = 0;
+    }
+    return c;
+}
+
+
+uint32_t ESP8266_RingBuffer::copy(uint8_t *pdata, uint32_t size)
+{
+    uint32_t ret;
+    uint32_t pdata_index = 0;
+
+    /* copy size */
+    ret = (len < size)? len : size;
+    
+    while((pdata_index < ret)) {
+        pdata[pdata_index++] = buffer[head++];
+        if (head == ESP8266_RINGBUFFER_SIZE) {
+            head = 0;
+        }
+    }
+
+    len -= ret;
+
+    return ret;
+}
+
+uint8_t ESP8266_RingBuffer::peek(void)
+{
+    if (len == 0) {return 0;}    
+    return buffer[head];
+}
+
+void ESP8266::initialize_status(void)
+{
+    wifi_status = ESP8266_STATUS_DISCONNECTED;
+    connection_bitmap = 0;
+    mux_mode = false;
+    rx_cmd = "";
+    for(int i = 0; i < ESP8266_NUM_CONNECTION; i++){
+        rx_buffer[i].init();
+    }
+}
+
 #ifdef ESP8266_USE_SOFTWARE_SERIAL
-void ESP8266::begin(SoftwareSerial &uart, uint32_t baud)
-{
+int ESP8266::begin(SoftwareSerial &uart, uint32_t baud)
+#else /* !ESP8266_USE_SOFTWARE_SERIAL */
+int ESP8266::begin(HardwareSerial &uart, uint32_t baud)
+#endif /* ESP8266_USE_SOFTWARE_SERIAL */
+{
+    String version;
+    
     m_puart = &uart;
     m_baud = baud;
     m_puart->begin(baud);
+    initialize_status();
     rx_empty();
-}
-#else
-void ESP8266::begin(HardwareSerial &uart, uint32_t baud)
-{
-    m_puart = &uart;
-    m_baud = baud;
-    m_puart->begin(baud);
-    rx_empty();
-}
-#endif
+    
+    if (!kick()) {
+        return 1;
+    }
+    
+    eATGMR(version);
+    if(version.indexOf(ESP8266_SUPPORT_VERSION) == -1) {
+        return 2;
+    }
+    
+    return 0;
+}
 
 bool ESP8266::kick(void)
@@ -76,4 +170,5 @@
 {
     unsigned long start;
+    initialize_status();
     if (eATRST()) {
         m_puart->end();
@@ -102,11 +197,11 @@
 {
     uint8_t mode;
-    if (!qATCWMODE(&mode)) {
+    if (!qATCWMODE_CUR(&mode)) {
         return false;
     }
-    if (mode == 1) {
+    if (mode == ESP8266_WMODE_STATION) {
         return true;
     } else {
-        if (sATCWMODE(1) && restart()) {
+        if (sATCWMODE_CUR(ESP8266_WMODE_STATION) && restart()) {
             return true;
         } else {
@@ -119,11 +214,11 @@
 {
     uint8_t mode;
-    if (!qATCWMODE(&mode)) {
+    if (!qATCWMODE_CUR(&mode)) {
         return false;
     }
-    if (mode == 2) {
+    if (mode == ESP8266_WMODE_SOFTAP) {
         return true;
     } else {
-        if (sATCWMODE(2) && restart()) {
+        if (sATCWMODE_CUR(ESP8266_WMODE_SOFTAP) && restart()) {
             return true;
         } else {
@@ -136,11 +231,11 @@
 {
     uint8_t mode;
-    if (!qATCWMODE(&mode)) {
+    if (!qATCWMODE_CUR(&mode)) {
         return false;
     }
-    if (mode == 3) {
+    if (mode == ESP8266_WMODE_AP_STATION) {
         return true;
     } else {
-        if (sATCWMODE(3) && restart()) {
+        if (sATCWMODE_CUR(ESP8266_WMODE_AP_STATION) && restart()) {
             return true;
         } else {
@@ -159,5 +254,5 @@
 bool ESP8266::joinAP(String ssid, String pwd)
 {
-    return sATCWJAP(ssid, pwd);
+    return sATCWJAP_CUR(ssid, pwd);
 }
 
@@ -169,5 +264,5 @@
 bool ESP8266::setSoftAPParam(String ssid, String pwd, uint8_t chl, uint8_t ecn)
 {
-    return sATCWSAP(ssid, pwd, chl, ecn);
+    return sATCWSAP_CUR(ssid, pwd, chl, ecn);
 }
 
@@ -189,60 +284,131 @@
 {
     String list;
+    int32_t index_start = -1;
+    int32_t index_end = -1;
+    
     eATCIFSR(list);
-    return list;
+    index_start = list.indexOf('\"');
+    index_end   = list.indexOf('\"', list.indexOf('\"')+1);
+    if ((index_start !=  -1) && (index_end != -1)) {
+        return list.substring(index_start+1, index_end);
+    }
+    return "";
 }
 
 bool ESP8266::enableMUX(void)
 {
-    return sATCIPMUX(1);
+    if (sATCIPMUX(1)) {
+        mux_mode = true;
+        return true;
+      }
+    return false;
 }
 
 bool ESP8266::disableMUX(void)
 {
-    return sATCIPMUX(0);
+    if (sATCIPMUX(0)){
+        mux_mode = false;
+        return true;
+    }
+    return false;
 }
 
 bool ESP8266::createTCP(String addr, uint32_t port)
 {
-    return sATCIPSTARTSingle("TCP", addr, port);
+    bool ret;
+    if (mux_mode) return false;
+
+    if((ret = sATCIPSTARTSingle("TCP", addr, port))) {
+        connection_bitmap = 1;
+    }
+    return ret;
 }
 
 bool ESP8266::releaseTCP(void)
 {
-    return eATCIPCLOSESingle();
+    bool ret;
+    
+    if (mux_mode) return false;    
+    if((ret = eATCIPCLOSESingle())) {
+        connection_bitmap = 0;
+        rx_buffer[MUXID_SINGLE].free();
+    }
+    return ret;    
 }
 
 bool ESP8266::registerUDP(String addr, uint32_t port)
 {
-    return sATCIPSTARTSingle("UDP", addr, port);
+    bool ret;
+    if (mux_mode) return false;
+    if((ret = sATCIPSTARTSingle("UDP", addr, port))) {
+        connection_bitmap = 1;
+    }    
+    return ret;
 }
 
 bool ESP8266::unregisterUDP(void)
 {
-    return eATCIPCLOSESingle();
+    bool ret;
+    if (mux_mode) return false;
+    if((ret = eATCIPCLOSESingle())) {
+        connection_bitmap = 0;
+        rx_buffer[MUXID_SINGLE].free();
+    }    
+    return ret;    
 }
 
 bool ESP8266::createTCP(uint8_t mux_id, String addr, uint32_t port)
 {
-    return sATCIPSTARTMultiple(mux_id, "TCP", addr, port);
+    bool ret;
+    if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
+    if (!mux_mode) return false;
+    
+    if((ret = sATCIPSTARTMultiple(mux_id, "TCP", addr, port))) {
+        connection_bitmap |= 1 << mux_id;
+    }
+    return ret;
 }
 
 bool ESP8266::releaseTCP(uint8_t mux_id)
 {
-    return sATCIPCLOSEMulitple(mux_id);
+    bool ret;
+    if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
+    if (!mux_mode) return false;
+    
+    if ((ret = sATCIPCLOSEMulitple(mux_id))) {
+        connection_bitmap &= ~(1 << mux_id);
+        rx_buffer[mux_id].free();
+    }
+    return ret;
 }
 
 bool ESP8266::registerUDP(uint8_t mux_id, String addr, uint32_t port)
 {
-    return sATCIPSTARTMultiple(mux_id, "UDP", addr, port);
+    bool ret;
+    if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
+    if (!mux_mode) return false;
+    
+    if ((ret = sATCIPSTARTMultiple(mux_id, "UDP", addr, port))) {
+        connection_bitmap |= 1 << mux_id;
+    }
+    return ret;
 }
 
 bool ESP8266::unregisterUDP(uint8_t mux_id)
 {
-    return sATCIPCLOSEMulitple(mux_id);
+    bool ret;    
+    if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
+    if (!mux_mode) return false;
+    
+    if ((ret = sATCIPCLOSEMulitple(mux_id))) {
+        connection_bitmap &= ~(1 << mux_id);
+        rx_buffer[mux_id].free();
+    }
+    return ret;    
 }
 
 bool ESP8266::setTCPServerTimeout(uint32_t timeout)
 {
+    if (!mux_mode) return false;
     return sATCIPSTO(timeout);
 }
@@ -250,4 +416,5 @@
 bool ESP8266::startTCPServer(uint32_t port)
 {
+    if (!mux_mode) return false;
     if (sATCIPSERVER(1, port)) {
         return true;
@@ -259,5 +426,4 @@
 {
     sATCIPSERVER(0);
-    restart();
     return false;
 }
@@ -265,4 +431,5 @@
 bool ESP8266::startServer(uint32_t port)
 {
+    if (!mux_mode) return false;    
     return startTCPServer(port);
 }
@@ -275,4 +442,5 @@
 bool ESP8266::send(const uint8_t *buffer, uint32_t len)
 {
+    if (mux_mode) return 0;
     return sATCIPSENDSingle(buffer, len);
 }
@@ -280,4 +448,5 @@
 bool ESP8266::send(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
 {
+    if (!mux_mode) return false;
     return sATCIPSENDMultiple(mux_id, buffer, len);
 }
@@ -285,4 +454,5 @@
 bool ESP8266::send(String &str)
 {
+    if (mux_mode) return 0;
     return sATCIPSENDSingle(str);
 }
@@ -290,4 +460,7 @@
 bool ESP8266::send(uint8_t mux_id, String &str)
 {
+    if (!mux_mode) return false;
+    if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
+    
     return sATCIPSENDMultiple(mux_id, str);
 }
@@ -295,37 +468,142 @@
 uint32_t ESP8266::recv(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
 {
-    return recvPkg(buffer, buffer_size, NULL, timeout, NULL);
+    if (mux_mode) return 0;
+    return recvPkg(buffer, buffer_size, timeout, 0, NULL);
 }
 
 uint32_t ESP8266::recv(uint8_t mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
 {
-    uint8_t id;
-    uint32_t ret;
-    ret = recvPkg(buffer, buffer_size, NULL, timeout, &id);
-    if (ret > 0 && id == mux_id) {
-        return ret;
-    }
+    if (!mux_mode) return false;
+    if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
+    
+    return recvPkg(buffer, buffer_size, timeout, mux_id, NULL);
+}
+
+uint32_t ESP8266::recv(uint8_t *coming_mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
+{
+    if (!mux_mode) return false;
+    return recvPkg(buffer, buffer_size, timeout, MUXID_ANY, coming_mux_id);
+}
+
+bool ESP8266::isDataAvailable(uint8_t mux_id)
+{
+    if (!mux_mode) return false;
+    if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
+
+    if(rx_buffer[mux_id].length() > 0) return true;
+    rx_update();
+    if(rx_buffer[mux_id].length() > 0) return true;
     return 0;
 }
 
-uint32_t ESP8266::recv(uint8_t *coming_mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
-{
-    return recvPkg(buffer, buffer_size, NULL, timeout, coming_mux_id);
-}
-
-int ESP8266::dataAvailable(void)
-{
-    return (m_puart->available() > 0)? 1 : 0;
-}
-            
+bool ESP8266::isDataAvailable(void)
+{
+    if (mux_mode) {
+        for(int i = 0; i < ESP8266_NUM_CONNECTION; i++){
+            if(rx_buffer[i].length() > 0) return true;
+        }
+        rx_update();
+        for(int i = 0; i < ESP8266_NUM_CONNECTION; i++){
+            if(rx_buffer[i].length() > 0) return true;
+        }
+    }
+    else {
+        /* single mode */
+        if(rx_buffer[0].length() > 0) return true;
+        rx_update();
+        if(rx_buffer[0].length() > 0) return true;        
+    }
+    return false;
+}
+
+bool ESP8266::isConnected(void)
+{
+    if (mux_mode) return false;    
+    rx_update();
+    return (connection_bitmap == 1);
+}
+
+bool ESP8266::isConnected(uint8_t mux_id)
+{
+    if (!mux_mode) return false;    
+    if (!(mux_id < ESP8266_NUM_CONNECTION)) return false;
+    rx_update();
+    return ((connection_bitmap & (1<<mux_id)) != 0);
+}
+
+bool ESP8266::getMuxCStatus(uint8_t *mux_id_ptn)
+{
+    if (!mux_mode) return false;    
+    rx_update();
+    *mux_id_ptn = connection_bitmap;
+    return true;
+}
+
 /*----------------------------------------------------------------------------*/
 /* +IPD,<id>,<len>:<data> */
 /* +IPD,<len>:<data> */
 
-uint32_t ESP8266::recvPkg(uint8_t *buffer, uint32_t buffer_size, uint32_t *data_len, uint32_t timeout, uint8_t *coming_mux_id)
+uint32_t ESP8266::recvPkg(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout,
+                          uint8_t mux_id, uint8_t *coming_mux_id)
+{    
+    char a;
+    unsigned long start;
+    uint32_t ret;
+    uint32_t recv_mux_id = 0;
+    
+    /*
+     * Try to recive data from rx_buffer
+     */
+    if (mux_id == MUXID_ANY) {
+        for(int i = 0; i < ESP8266_NUM_CONNECTION; i++){
+            if(rx_buffer[i].length() > 0) {
+                recv_mux_id = i;
+                *coming_mux_id = i;
+                break;
+            }
+        }
+    }
+    else {
+        recv_mux_id = mux_id;
+    }
+    
+    if(rx_buffer[recv_mux_id].length() > 0) {
+        return rx_buffer[recv_mux_id].copy(buffer, buffer_size);
+    }
+
+    /*
+     * Try to recive data from uart
+     */    
+    start = millis();
+    while (millis() - start < timeout) {
+        while(m_puart->available() > 0) {            
+            a = m_puart->read();
+            rx_cmd += a;
+            if (rx_cmd.indexOf("+IPD,") != -1) {
+                if((ret = recvIPD(timeout - (millis() - start), buffer, buffer_size,
+                                  mux_id, coming_mux_id)) > 0) {
+                    rx_cmd = "";
+                    return ret;
+                }
+            } else {
+                recvAsyncdata();
+            }
+        }
+        WAIT_TIMEOUT;
+    }
+    return 0;
+}
+
+/*
+ * call after read  +IPD,
+ * +IPD,<id>,<len>:<data>
+ * +IPD,<len>:<data>
+ */
+uint32_t ESP8266::recvIPD(uint32_t timeout, uint8_t *buffer, uint32_t buffer_size,
+                          uint8_t mux_id, uint8_t *coming_mux_id)
 {
     String data;
     char a;
-    int32_t index_PIPDcomma = -1;
+    unsigned long start;
     int32_t index_colon = -1; /* : */
     int32_t index_comma = -1; /* , */
@@ -334,29 +612,17 @@
     bool has_data = false;
     uint32_t ret;
-    unsigned long start;
     uint32_t i;
-    
-    if (buffer == NULL) {
-        return 0;
-    }
-    
+    ESP8266_RingBuffer *p_rx_buffer;
+      
     start = millis();
-    while (millis() - start < timeout) {
+    while (millis() - start < timeout) {        
         if(m_puart->available() > 0) {
             a = m_puart->read();
             data += a;
-        }else{
-            WAIT_TIMEOUT;
-        }
-        
-        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) {
+            if((index_colon = data.indexOf(':')) != -1) {
+                if(((index_comma = data.indexOf(',')) != -1) && index_comma < index_colon) {
+                    /* +IPD,id,len:data */
+                    id = data.substring(0, index_comma).toInt();
+                    if (id < 0 || id > (ESP8266_NUM_CONNECTION-1)) {
                         return 0;
                     }
@@ -365,6 +631,9 @@
                         return 0;
                     }
-                } else { /* +IPD,len:data */
-                    len = data.substring(index_PIPDcomma + 5, index_colon).toInt();
+                }
+                else {
+                    /* +IPD,len:data */
+                    len = data.substring(0, index_colon).toInt();
+                    id = 0;
                     if (len <= 0) {
                         return 0;
@@ -375,28 +644,54 @@
             }
         }
+        else {
+            WAIT_TIMEOUT;
+        }
     }
     
     if (has_data) {
-        i = 0;
-        ret = (uint32_t)len > buffer_size ? buffer_size : len;
-        start = millis();
-        while (millis() - start < 3000) {
-            while(m_puart->available() > 0 && i < ret) {
-                a = m_puart->read();
-                buffer[i++] = a;
+        p_rx_buffer = (id == -1)? &rx_buffer[0] : &rx_buffer[id];
+        if (buffer == NULL || ((mux_id != MUXID_ANY) && (id != mux_id))) {
+            /* Store in rx_buffer */        
+            start = millis();
+            i = 0;
+            while (millis() - start < 3000) {
+                while((m_puart->available() > 0) && (i < (uint32_t)len)) {
+                    a = m_puart->read();
+                    p_rx_buffer->write(a);
+                    i++;
+                }
+                if (i == (uint32_t)len) {
+                    return len;
+                }
+                WAIT_TIMEOUT
+            }            
+            return 0;
+        }
+        else {
+            /* Store in buffer */
+            i = 0;
+            ret = ((uint32_t)len > buffer_size) ? buffer_size : len;
+            start = millis();
+            while ((millis() - start) < 3000) {
+                while((m_puart->available() > 0) && (i < (uint32_t)len)) {                    
+                    a = m_puart->read();
+                    if(i < buffer_size) {
+                        buffer[i] = a;
+                    } else {
+                        p_rx_buffer->write(a);
+                    }
+                    i++;
+                }
+                if (i == (uint32_t)len) {
+                    if (mux_id == MUXID_ANY) {
+                        *coming_mux_id = id;
+                    }
+                    return ret;
+                }
+                WAIT_TIMEOUT;
             }
-            if (i == ret) {
-                rx_empty();
-                if (data_len) {
-                    *data_len = len;    
-                }
-                if (index_comma != -1 && coming_mux_id) {
-                    *coming_mux_id = id;
-                }
-                return ret;
-            }
-            WAIT_TIMEOUT
-        }
-    }
+        }        
+    }
+    
     return 0;
 }
@@ -409,87 +704,91 @@
 }
 
-String ESP8266::recvString(String target, uint32_t timeout)
-{
-    String data;
+void ESP8266::recvAsyncdata(uint32_t timeout)
+{
+    int index;
+    int id;
+
+    if (rx_cmd.indexOf("+IPD,") != -1) {
+        if(recvIPD(timeout) > 0) {
+            rx_cmd = "";
+        }
+    } else if (rx_cmd.indexOf("CLOSED") != -1) {
+        if ((index = rx_cmd.indexOf(",CLOSED")) != -1) {
+            /* <link ID>,CLOSED */
+            id = rx_cmd.substring(index-1, index).toInt();
+            connection_bitmap &= ~(1 << id);
+        } else {
+            connection_bitmap = 0;                
+        }
+        rx_cmd = "";
+    } else if ((index = rx_cmd.indexOf(",CONNECT")) != -1) {
+        /* <link ID>,CONNECT */
+        id = rx_cmd.substring(index-1, index).toInt();
+        connection_bitmap |= (1 << id);
+        rx_cmd = "";
+    } else if ((index = rx_cmd.indexOf("WIFI CONNECTED")) != -1) {
+        wifi_status = ESP8266_STATUS_CONNECTED;
+        rx_cmd = "";
+    } else if ((index = rx_cmd.indexOf("WIFI GOT IP")) != -1) {
+        wifi_status = ESP8266_STATUS_GOTIP;
+        rx_cmd = "";        
+    } else if ((index = rx_cmd.indexOf("WIFI DISCONNECT")) != -1) {
+        wifi_status = ESP8266_STATUS_DISCONNECTED;
+        rx_cmd = "";        
+    }    
+}
+
+void ESP8266::rx_update(void)
+{
+    char a;
+    
+    while(m_puart->available() > 0) {
+        a = m_puart->read();
+        rx_cmd += a;
+        recvAsyncdata(3000);
+    }
+}
+
+int ESP8266::recvString(String target1, String target2, String target3, uint32_t timeout)
+{
     char a;
     unsigned long start = millis();
     while (millis() - start < timeout) {
-        while(m_puart->available() > 0) {
+        while (m_puart->available() > 0) {            
             a = m_puart->read();
-            if(a == '\0') continue;
-            data += a;
-        }
-        if (data.indexOf(target) != -1) {
-            break;
-        }
-        WAIT_TIMEOUT
-    }
-    return data;
-}
-
-String ESP8266::recvString(String target1, String target2, uint32_t timeout)
-{
-    String data;
-    char a;
-    unsigned long start = millis();
-    while (millis() - start < timeout) {
-        while(m_puart->available() > 0) {
-            a = m_puart->read();
-            if(a == '\0') continue;
-            data += a;
-        }
-        if (data.indexOf(target1) != -1) {
-            break;
-        } else if (data.indexOf(target2) != -1) {
-            break;
-        }
-        WAIT_TIMEOUT
-    }
-    return data;
-}
-
-String ESP8266::recvString(String target1, String target2, String target3, uint32_t timeout)
-{
-    String data;
-    char a;
-    unsigned long start = millis();
-    while (millis() - start < timeout) {
-        while(m_puart->available() > 0) {
-            a = m_puart->read();
-            if(a == '\0') continue;
-            data += a;
-        }
-        if (data.indexOf(target1) != -1) {
-            break;
-        } else if (data.indexOf(target2) != -1) {
-            break;
-        } else if (data.indexOf(target3) != -1) {
-            break;
-        }
-        WAIT_TIMEOUT
-    }
-    return data;
+            rx_cmd += a;
+            if (rx_cmd.indexOf(target1) != -1) {
+                return 1;
+            } else if ((target2.length() != 0 ) && (rx_cmd.indexOf(target2) != -1)) {
+                return 2;
+            } else if ((target3.length() != 0 ) && (rx_cmd.indexOf(target3) != -1)) {
+                return 3;
+            } else {
+                recvAsyncdata(timeout - (millis() - start));
+            }
+        }
+        WAIT_TIMEOUT;
+    }
+    return -1;
 }
 
 bool ESP8266::recvFind(String target, uint32_t timeout)
 {
-    String data_tmp;
-    data_tmp = recvString(target, timeout);
-    if (data_tmp.indexOf(target) != -1) {
-        return true;
-    }
-    return false;
+    int ret;
+    
+    ret = recvString(target, "", "", timeout);
+    if (ret != -1) rx_cmd = "";
+    return (ret == 1);
 }
 
 bool ESP8266::recvFindAndFilter(String target, String begin, String end, String &data, uint32_t timeout)
 {
-    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 (recvString(target, "", "", timeout) == 1) {
+        int32_t index1 = rx_cmd.indexOf(begin);
+        int32_t index2 = rx_cmd.indexOf(end);
         if (index1 != -1 && index2 != -1) {
             index1 += begin.length();
-            data = data_tmp.substring(index1, index2);
+            data = rx_cmd.substring(index1, index2);
+            rx_cmd = "";
             return true;
         }
@@ -501,5 +800,4 @@
 bool ESP8266::eAT(void)
 {
-    rx_empty();
     m_puart->println("AT");
     return recvFind("OK");
@@ -508,5 +806,4 @@
 bool ESP8266::eATRST(void) 
 {
-    rx_empty();
     m_puart->println("AT+RST");
     return recvFind("OK");
@@ -515,10 +812,9 @@
 bool ESP8266::eATGMR(String &version)
 {
-    rx_empty();
     m_puart->println("AT+GMR");
     return recvFindAndFilter("OK", "\r\r\n", "\r\nOK", version); 
 }
-
-bool ESP8266::qATCWMODE(uint8_t *mode) 
+/* checked */
+bool ESP8266::qATCWMODE_CUR(uint8_t *mode) 
 {
     String str_mode;
@@ -527,7 +823,6 @@
         return false;
     }
-    rx_empty();
-    m_puart->println("AT+CWMODE?");
-    ret = recvFindAndFilter("OK", "+CWMODE:", "\r\n\r\nOK", str_mode); 
+    m_puart->println("AT+CWMODE_CUR?");
+    ret = recvFindAndFilter("OK", "+CWMODE_CUR:", "\r\n\r\nOK", str_mode); 
     if (ret) {
         *mode = (uint8_t)str_mode.toInt();
@@ -537,23 +832,21 @@
     }
 }
-
-bool ESP8266::sATCWMODE(uint8_t mode)
-{
-    String data;
-    rx_empty();
-    m_puart->print("AT+CWMODE=");
+/* checked */
+bool ESP8266::sATCWMODE_CUR(uint8_t mode)
+{
+    int ret;
+    
+    m_puart->print("AT+CWMODE_CUR=");
     m_puart->println(mode);
-    
-    data = recvString("OK", "no change");
-    if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
-        return true;
-    }
-    return false;
-}
-
-bool ESP8266::sATCWJAP(String ssid, String pwd)
-{
-    String data;
-    rx_empty();
+
+    ret = recvString("OK", "ERROR", "");
+    if (ret != -1) rx_cmd = "";
+    return (ret == 1);
+}
+/* checked */
+bool ESP8266::sATCWJAP_CUR(String ssid, String pwd)
+{
+    int ret;
+    
     m_puart->print("AT+CWJAP=\"");
     m_puart->print(ssid);
@@ -562,15 +855,11 @@
     m_puart->println("\"");
     
-    data = recvString("OK", "FAIL", 10000);
-    if (data.indexOf("OK") != -1) {
-        return true;
-    }
-    return false;
+    ret = recvString("OK", "FAIL", "", 10000);
+    if (ret != -1) rx_cmd = "";
+    return (ret == 1);
 }
 
 bool ESP8266::eATCWLAP(String &list)
 {
-    String data;
-    rx_empty();
     m_puart->println("AT+CWLAP");
     return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 10000);
@@ -579,15 +868,13 @@
 bool ESP8266::eATCWQAP(void)
 {
-    String data;
-    rx_empty();
     m_puart->println("AT+CWQAP");
     return recvFind("OK");
 }
-
-bool ESP8266::sATCWSAP(String ssid, String pwd, uint8_t chl, uint8_t ecn)
-{
-    String data;
-    rx_empty();
-    m_puart->print("AT+CWSAP=\"");
+/* checked */
+bool ESP8266::sATCWSAP_CUR(String ssid, String pwd, uint8_t chl, uint8_t ecn)
+{
+    int ret;
+    
+    m_puart->print("AT+CWSAP_CUR=\"");
     m_puart->print(ssid);
     m_puart->print("\",\"");
@@ -598,30 +885,25 @@
     m_puart->println(ecn);
     
-    data = recvString("OK", "ERROR", 5000);
-    if (data.indexOf("OK") != -1) {
-        return true;
-    }
-    return false;
+    ret = recvString("OK", "ERROR", "", 5000);
+    if (ret != -1) rx_cmd = "";
+    return (ret == 1);
 }
 
 bool ESP8266::eATCWLIF(String &list)
 {
-    String data;
-    rx_empty();
     m_puart->println("AT+CWLIF");
     return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
 }
+
 bool ESP8266::eATCIPSTATUS(String &list)
 {
-    String data;
-    delay(100);
-    rx_empty();
     m_puart->println("AT+CIPSTATUS");
     return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
 }
+
 bool ESP8266::sATCIPSTARTSingle(String type, String addr, uint32_t port)
 {
-    String data;
-    rx_empty();
+    int ret;
+    
     m_puart->print("AT+CIPSTART=\"");
     m_puart->print(type);
@@ -631,14 +913,13 @@
     m_puart->println(port);
     
-    data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
-    if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
-        return true;
-    }
-    return false;
-}
+    ret = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
+    if (ret != -1) rx_cmd = "";
+    return (ret == 1 || ret == 3);
+}
+
 bool ESP8266::sATCIPSTARTMultiple(uint8_t mux_id, String type, String addr, uint32_t port)
 {
-    String data;
-    rx_empty();
+    int ret;
+    
     m_puart->print("AT+CIPSTART=");
     m_puart->print(mux_id);
@@ -650,17 +931,14 @@
     m_puart->println(port);
     
-    data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
-    if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
-        return true;
-    }
-    return false;
-}
+    ret = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
+    if (ret != -1) rx_cmd = "";
+    return ((ret == 1)||(ret == 3));
+}
+
 bool ESP8266::sATCIPSENDSingle(const uint8_t *buffer, uint32_t len)
 {
-    rx_empty();
     m_puart->print("AT+CIPSEND=");
     m_puart->println(len);
     if (recvFind(">", 5000)) {
-        rx_empty();
         for (uint32_t i = 0; i < len; i++) {
             m_puart->write(buffer[i]);
@@ -670,7 +948,7 @@
     return false;
 }
+
 bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
 {
-    rx_empty();
     m_puart->print("AT+CIPSEND=");
     m_puart->print(mux_id);
@@ -678,5 +956,4 @@
     m_puart->println(len);
     if (recvFind(">", 5000)) {
-        rx_empty();
         for (uint32_t i = 0; i < len; i++) {
             m_puart->write(buffer[i]);
@@ -686,11 +963,10 @@
     return false;
 }
+
 bool ESP8266::sATCIPSENDSingle(String &str)
 {
-    rx_empty();
     m_puart->print("AT+CIPSEND=");
     m_puart->println(str.length());
     if (recvFind(">", 5000)) {
-        rx_empty();
         for (uint32_t i = 0; i < str.length(); i++) {
             m_puart->write(str.charAt(i));
@@ -700,7 +976,7 @@
     return false;
 }
+
 bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, String &str)
 {
-    rx_empty();
     m_puart->print("AT+CIPSEND=");
     m_puart->print(mux_id);
@@ -708,5 +984,4 @@
     m_puart->println(str.length());
     if (recvFind(">", 5000)) {
-        rx_empty();
         for (uint32_t i = 0; i < str.length(); i++) {
             m_puart->write(str.charAt(i));
@@ -716,64 +991,60 @@
     return false;
 }
+
 bool ESP8266::sATCIPCLOSEMulitple(uint8_t mux_id)
 {
-    String data;
-    rx_empty();
+    int ret;
+    
     m_puart->print("AT+CIPCLOSE=");
     m_puart->println(mux_id);
     
-    data = recvString("OK", "link is not", 5000);
-    if (data.indexOf("OK") != -1 || data.indexOf("link is not") != -1) {
-        return true;
-    }
-    return false;
-}
+    ret = recvString("OK", "link is not", "", 5000);
+    if (ret != -1) rx_cmd = "";
+    return ((ret == 1) || (ret == 2));
+}
+
 bool ESP8266::eATCIPCLOSESingle(void)
 {
-    rx_empty();
     m_puart->println("AT+CIPCLOSE");
     return recvFind("OK", 5000);
 }
+
 bool ESP8266::eATCIFSR(String &list)
 {
-    rx_empty();
     m_puart->println("AT+CIFSR");
     return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
 }
+/* checked */
 bool ESP8266::sATCIPMUX(uint8_t mode)
 {
-    String data;
-    rx_empty();
+    int ret;
+    
     m_puart->print("AT+CIPMUX=");
     m_puart->println(mode);
     
-    data = recvString("OK", "Link is builded");
-    if (data.indexOf("OK") != -1) {
-        return true;
-    }
-    return false;
-}
+    ret = recvString("OK", "ERROR", "");
+    if (ret != -1) rx_cmd = "";
+    return (ret == 1);    
+}
+
 bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port)
 {
-    String data;
+    int ret;
+    
     if (mode) {
-        rx_empty();
         m_puart->print("AT+CIPSERVER=1,");
-        m_puart->println(port);
-        
-        data = recvString("OK", "no change");
-        if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
-            return true;
-        }
-        return false;
+        m_puart->println(port);        
+        ret = recvString("OK", "ERROR", "");
+        if (ret != -1) rx_cmd = "";
+        return (ret == 1);
     } else {
-        rx_empty();
         m_puart->println("AT+CIPSERVER=0");
-        return recvFind("\r\r\n");
+        ret = recvString("OK", "ERROR", "");
+        if (ret != -1) rx_cmd = "";
+        return (ret == 1);        
     }
 }
 bool ESP8266::sATCIPSTO(uint32_t timeout)
 {
-    rx_empty();
     m_puart->print("AT+CIPSTO=");
     m_puart->println(timeout);
