AT Parser and bufferedSerial based SPWF library

Dependencies:   ATParser

Dependents:   X_NUCLEO_IDW01M1v2

Fork of SPWF01SA by ST Expansion SW Team

Revision:
13:f21e4e73bbb6
Parent:
12:00bc9c029aec
Child:
14:868b0fd4e84a
--- a/SPWFSA01.cpp	Thu Jul 07 13:20:19 2016 +0000
+++ b/SPWFSA01.cpp	Tue Aug 02 07:03:54 2016 +0000
@@ -15,6 +15,7 @@
  */
 
 #include "SPWFSA01.h"
+#include "mbed_debug.h"
 
 #define SPWFSA01_CONNECT_TIMEOUT 15000
 #define SPWFSA01_SEND_TIMEOUT    500
@@ -23,7 +24,8 @@
 
 SPWFSA01::SPWFSA01(PinName tx, PinName rx, bool debug)
     : _serial(tx, rx, 1024), _parser(_serial),
-      _wakeup(PC_8, PIN_INPUT, PullNone, 0), _reset(PC_12, PIN_INPUT, PullNone, 1)
+      _wakeup(PC_8, PIN_INPUT, PullNone, 0), _reset(PC_12, PIN_INPUT, PullNone, 1),
+      dbg_on(debug)
       //Pin PC_8 is wakeup pin
       //Pin PA_12 is reset pin
 {
@@ -45,27 +47,27 @@
     /*set local echo to 0*/
     if(!(_parser.send("AT+S.SCFG=localecho1,%d\r", 0) && _parser.recv("OK"))) 
         {
-            printf("\r\nerror local echo set\n");
+            debug_if(dbg_on, "SPWF> error local echo set\r\n");
             return false;
         }   
     /*reset factory settings*/
     if(!(_parser.send("AT&F") && _parser.recv("OK"))) 
         {
-            printf("\r\nerror AT&F\n");
+            debug_if(dbg_on, "SPWF> error AT&F\r\n");
             return false;
         }
 
     /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/
     if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", mode) && _parser.recv("OK")))
         {
-            printf("\r\nerror wifi mode set\n");
+            debug_if(dbg_on, "SPWF> error wifi mode set\r\n");
             return false;
         } 
 
     /* save current setting in flash */
     if(!(_parser.send("AT&W") && _parser.recv("OK")))
         {
-            printf("\r\nerror AT&W\n");
+            debug_if(dbg_on, "SPWF> error AT&W\r\n");
             return false;
         }
         
@@ -118,33 +120,33 @@
     //AT+S.SCFG=wifi_wpa_psk_text,%s\r
     if(!(_parser.send("AT+S.SCFG=wifi_wpa_psk_text,%s", passPhrase) && _parser.recv("OK"))) 
         {
-            printf("\r\nerror pass set\n");
+            debug_if(dbg_on, "SPWF> error pass set\r\n");
             return false;
         } 
     //AT+S.SSIDTXT=%s\r
     if(!(_parser.send("AT+S.SSIDTXT=%s", ap) && _parser.recv("OK"))) 
         {
-            printf("\r\nerror ssid set\n");
+            debug_if(dbg_on, "SPWF> error ssid set\r\n");
             return false;
         }
     //AT+S.SCFG=wifi_priv_mode,%d\r
     if(!(_parser.send("AT+S.SCFG=wifi_priv_mode,%d", securityMode) && _parser.recv("OK"))) 
         {
-            printf("\r\nerror security mode set\n");
+            debug_if(dbg_on, "SPWF> error security mode set\r\n");
             return false;
         } 
     //"AT+S.SCFG=wifi_mode,%d\r"
     /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/
     if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 1) && _parser.recv("OK")))
         {
-            printf("\r\nerror wifi mode set\n");
+            debug_if(dbg_on, "SPWF> error wifi mode set\r\n");
             return false;
         }
     //AT&W
     /* save current setting in flash */
     if(!(_parser.send("AT&W") && _parser.recv("OK")))
         {
-            printf("\r\nerror AT&W\n");
+            debug_if(dbg_on, "SPWF> error AT&W\r\n");
             return false;
         }
     //reset module
@@ -165,14 +167,14 @@
     /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/
     if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 0) && _parser.recv("OK")))
         {
-            printf("\r\nerror wifi mode set\n");
+            debug_if(dbg_on, "SPWF> error wifi mode set\r\n");
             return false;
         }
     //AT&W
     /* save current setting in flash */
     if(!(_parser.send("AT&W") && _parser.recv("OK")))
         {
-            printf("\r\nerror AT&W\n");
+            debug_if(dbg_on, "SPWF> error AT&W\r\n");
             return false;
         }
     //reset module
@@ -200,7 +202,7 @@
     if (!(_parser.send("AT+S.STS=ip_ipaddr")
         && _parser.recv("#  ip_ipaddr = %u.%u.%u.%u", &n1, &n2, &n3, &n4)
         && _parser.recv("OK"))) {
-            printf("\r\ngetIPAddress error\n");
+            debug_if(dbg_on, "SPWF> getIPAddress error\r\n");
         return 0;
     }
 
@@ -216,7 +218,7 @@
     if (!(_parser.send("AT+S.GCFG=nv_wifi_macaddr")
         && _parser.recv("#  nv_wifi_macaddr = %x:%x:%x:%x:%x:%x", &n1, &n2, &n3, &n4, &n5, &n6)
         && _parser.recv("OK"))) {
-            printf("\r\ngetMACAddress error\n");
+            debug_if(dbg_on, "SPWF> getMACAddress error\r\n");
         return 0;
     }
 
@@ -232,10 +234,12 @@
 
 bool SPWFSA01::open(const char *type, int* id, const char* addr, int port)
 {
+    Timer timer;
+    timer.start();
     
     if(!_parser.send("AT+S.SOCKON=%s,%d,%s,ind", addr, port, type))
         {
-            printf("\r\nerror opening socket\n");
+            debug_if(dbg_on, "SPWF> error opening socket\r\n");
             return false;
         }
         
@@ -244,6 +248,11 @@
             if( _parser.recv(" ID: %d", id)
                 && _parser.recv("OK"))
                 break;
+            
+            if (timer.read_ms() > SPWFSA01_CONNECT_TIMEOUT) {
+                return false;
+            }
+        
             //TODO:implement time-out functionality in case of no response
             //if(timeout) return false;
             //TODO: deal with errors like "ERROR: Failed to resolve name"
@@ -275,30 +284,54 @@
 
 int32_t SPWFSA01::recv(int id, void *data, uint32_t amount)
 {
-    uint32_t recv_amount;
+    uint32_t recv_amount, read_amt;
     int recv_id;
-    //char _buf[18];
+    char _buf[18];
 
     if (!(_parser.recv("+WIND:55:Pending Data:%d:%u", &recv_id, &recv_amount)
         && recv_id == id        
         //&& _parser.send("AT+S.SOCKQ=%d", id)//send a query (will be required for secure sockets)
         //&& _parser.recv(" DATALEN: %u", &recv_amount)
         //&& _parser.recv("OK")
-        && recv_amount <= amount
-        //&& sprintf((char*)_buf,"AT+S.SOCKR=%d,%d\r", id, recv_amount)
-        //&& _parser.write((char*)_buf, strlen(_buf))
-        && _parser.send("AT+S.SOCKR=%d,%d", id, recv_amount)
-        && (_parser.read((char*)data, recv_amount) >0)
-        && _parser.recv("OK"))) {
-        return -1;
+        && recv_amount <= amount)) {
+            return -1;//Block call
+            }
+    //&& sprintf((char*)_buf,"AT+S.SOCKR=%d,%d\r", id, recv_amount)
+    //&& _parser.write((char*)_buf, strlen(_buf))
+    if (!_parser.send("AT+S.SOCKR=%d,%d", id, recv_amount)) {
+        //if error, resend SOCKR again to flush the socket
+        //This should prevent Error: Pending Data errors or the next WIND showing this pending data
+        sprintf((char*)_buf,"AT+S.SOCKR=%d,%d\r", id, recv_amount);
+        _parser.write((char*)_buf, strlen(_buf));
+        debug_if(dbg_on, "SPWF> read send SOCKR error\r\n");
+        return -2;//return NSAPI_ERROR_DEVICE_ERROR
+        }
+            
+    read_amt = _parser.read((char*)data, recv_amount);            
+    if (read_amt<=0) {        
+        debug_if(dbg_on, "SPWF> read recv SOCKR error: read_amt = %d\r\n", read_amt);
+        return -2;//return NSAPI_ERROR_DEVICE_ERROR
     }
-    
-    /*int i = 0;
-    char * buf = (char*)data;
+        
+    //Sometimes OK is not received because _parser.read() reads in ERROR statement. "E.g. ERROR: Command not found".
+    //ERROR statement hence takes up space in recv_amount and hence OK is not read as a result.
     
-    for ( ; i < recv_amount; i++) {
-        printf("%d = %d\r\n", i, buf[i]);
-        }*/
+    if (!_parser.recv("OK")) {            
+        debug_if(dbg_on, "SPWF> read recv SOCKR OK error\r\n");
+        
+        if(std::strncmp("\r\nERROR: ", (const char* )data, 9)==0) {
+            debug_if(dbg_on, "SPWF> Module Error Reply\r\n");
+            return -2;
+            }
+        
+        /*int i = 0;
+        char * buf = (char*)data;
+        
+        for ( ; i < recv_amount; i++) {
+            debug_if(dbg_on, ("%d = %c\r\n", i, buf[i]);
+            }*/
+        return -2;//return NSAPI_ERROR_DEVICE_ERROR
+    }
     
     return recv_amount;
 }
@@ -314,7 +347,7 @@
         else
             {
                 if(_parser.recv("ERROR: Pending data"))
-                    printf("\r\nERROR!!!!\r\n");
+                    debug_if(dbg_on, "SPWF> ERROR!!!!\r\n");
                     return false;
                 }
         //TODO: Deal with "ERROR: Pending data" (Closing a socket with pending data)