AT Parser and bufferedSerial based SPWF library

Dependencies:   ATParser

Dependents:   X_NUCLEO_IDW01M1v2

Fork of SPWF01SA by ST Expansion SW Team

Revision:
24:419285201dba
Parent:
23:0b01aa59bb6f
Child:
25:6b79352bc1fa
--- a/SPWFSA01.cpp	Thu Nov 03 06:53:47 2016 +0000
+++ b/SPWFSA01.cpp	Tue Nov 22 14:36:25 2016 +0000
@@ -23,24 +23,19 @@
 #define SPWFSA01_MISC_TIMEOUT       500
 #define SPWFSA01_SOCKQ_TIMEOUT      3000
 
-SPWFSA01::SPWFSA01(PinName tx, PinName rx, bool debug)
-    : _serial(tx, rx, 1024), _parser(_serial),
-      _wakeup(D14, PIN_INPUT, PullNone, 0), _reset(D15, PIN_INPUT, PullNone, 1),
-      //PC_12->D15, PC_8->D14 (re-wires needed in-case used, currently not used)
+   SPWFSA01::SPWFSA01(PinName tx, PinName rx, PinName reset, PinName wakeup, bool debug)
+    : _serial(tx, rx, 1024), _parser(_serial), 
+      _reset(reset, PIN_OUTPUT, PullNone, 1),
+      _wakeup(wakeup, PIN_OUTPUT, PullNone, 0),
       dbg_on(debug)
-      //Pin PC_8 is wakeup pin
-      //Pin PA_12 is reset pin
 {
-    _serial.baud(115200);
-    _reset.output();
-    _wakeup.output();
+    _serial.baud(115200);  // LICIO  FIXME increase the speed
     _parser.debugOn(debug);
 }
 
 bool SPWFSA01::startup(int mode)
 {
-    setTimeout(SPWFSA01_RECV_TIMEOUT);
-    
+    _parser.setTimeout(SPWFSA01_MISC_TIMEOUT);    
     /*Test module before reset*/
     waitSPWFReady();
     /*Reset module*/
@@ -94,12 +89,14 @@
 
 bool SPWFSA01::hw_reset(void)
 {    
+    if (_reset.is_connected()) {
     /* reset the pin PC12 */  
     _reset.write(0);
     wait_ms(200);
     _reset.write(1); 
     wait_ms(100);
     return 1;
+    } else { return 0; }
 }
 
 bool SPWFSA01::reset(void)
@@ -120,7 +117,7 @@
             //till we get OK from AT command
             //printf("\r\nwaiting for reset to complete..\n");
             return;
-                
+                 
 }
 
 /* Security Mode
@@ -131,7 +128,8 @@
 bool SPWFSA01::connect(const char *ap, const char *passPhrase, int securityMode)
 {
     uint32_t n1, n2, n3, n4;
-    
+
+    _parser.setTimeout(SPWFSA01_CONNECT_TIMEOUT);       
     //AT+S.SCFG=wifi_wpa_psk_text,%s\r
     if(!(_parser.send("AT+S.SCFG=wifi_wpa_psk_text,%s", passPhrase) && _parser.recv("OK"))) 
         {
@@ -244,14 +242,15 @@
 
 bool SPWFSA01::isConnected(void)
 {
-    return getIPAddress() != 0;
+    return getIPAddress() != 0; 
 }
 
 bool SPWFSA01::open(const char *type, int* id, const char* addr, int port)
 {
     Timer timer;
     timer.start();
-    
+    socket_closed = 0; 
+       
     if(!_parser.send("AT+S.SOCKON=%s,%d,%s,ind", addr, port, type))
         {
             debug_if(dbg_on, "SPWF> error opening socket\r\n");
@@ -280,8 +279,7 @@
 bool SPWFSA01::send(int id, const void *data, uint32_t amount)
 {    
     char _buf[18];
-    
-    setTimeout(SPWFSA01_SEND_TIMEOUT);
+    _parser.setTimeout(SPWFSA01_SEND_TIMEOUT);
     
     sprintf((char*)_buf,"AT+S.SOCKW=%d,%d\r", id, amount);   
     
@@ -291,156 +289,100 @@
             && _parser.write((char*)data, (int)amount) >= 0
             && _parser.recv("OK")) {
             return true;
-        }
+        }     
     }
-
     return false;
 }
 
-/*
-int32_t SPWFSA01::recv(int id, void *data, uint32_t amount)
-{
-    uint32_t recv_amount;
-    int recv_id;
-    bool wind_recv = true;
-    
-    if (!(_parser.recv("+WIND:55:Pending Data:%d:%u", &recv_id, &recv_amount)
-        && recv_id == id
-        && recv_amount <= amount
-        && recv_amount%730
-        && _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 > 0
-        && _parser.send("AT+S.SOCKR=%d,%d", id, recv_amount)
-        && (_parser.read((char*)data, recv_amount) >0)
-        && _parser.recv("OK"))) {
-            if(!(recv_amount%730))
-            {
-                // receive all the WIND messages
-                do {
-                    if (!(_parser.recv("+WIND:55:Pending Data:%d:%u", &recv_id, &recv_amount)
-                         && recv_id == id 
-                         && recv_amount <= amount
-                         && recv_amount > 0))
-                             wind_recv = false;
-                } while (!(recv_amount%730) && wind_recv);
-
-                // Read all the data pending on a socket
-                if(!( recv_amount > 0
-                    && _parser.send("AT+S.SOCKR=%d,%d", id, recv_amount)
-                    && (_parser.read((char*)data, recv_amount) >0)
-                    && _parser.recv("OK"))) {
-                        return -1;
-                    }
-            }
-            else {
-                return -2;
-            }
-    }    
-    return recv_amount;
-}
-*/
 
 int32_t SPWFSA01::recv(int id, void *data, uint32_t amount)
 {
-    Timer timer;
-    timer.start();
-    
     uint32_t recv_amount=0;
-    int recv_id;
-        
-    if(!(_parser.recv("+WIND:55:Pending Data:%d:", &recv_id))) {
-        //do nothing;
-        debug_if(dbg_on, "SPWF> WIND:55 Timeout\r\n");
-        }
-    
-    while(!recv_amount) {
-      if(!(_parser.send("AT+S.SOCKQ=%d", id)  //send a query (will be required for secure sockets)
+    int wind_id;    
+ 
+    if (socket_closed) {
+        socket_closed = 0;
+        return -3;
+    }
+    if(!(_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"))) {
-                return -2;
-            }
-      if (timer.read_ms() > SPWFSA01_SOCKQ_TIMEOUT) {
-                return -1;
-            }
-    }
+        return -2;
+    }            
+    if (recv_amount==0) { return -1; } 
     if(recv_amount > amount)
         recv_amount = amount;
         
-    _parser.flush();
-    if(!(_parser.send("AT+S.SOCKR=%d,%d", id, recv_amount)))
-        return -2;      
-
-    /* only when the data recv is greater than 3 bytes */
-    if(recv_amount > 3)     {
-        /* look for WIND messages in data */
+    int par_timeout = _parser.getTimeout();        
+    _parser.setTimeout(0);
     
-        // get first 3 bytes of data
-        for(int i=0;i<3;i++) {
-            int c = -1;
-            while(c < 0) {
-                c = _parser.getc();
-            }
-            ((char *)data)[i] = c;
+     while(_parser.recv("+WIND:%d:", &wind_id)) {
+//        printf("Wind received: %d\n\r", wind_id);
+        if (wind_id == 58) {
+            socket_closed = 1;
+            _parser.flush();            
         }
-                
-        /* 0xD: \r && 0xA: \n */
-        if(((char *)data)[0] == 0xD  
-         &&((char *)data)[1] == 0xA  
-         &&((char *)data)[2] == '+')   {
-          ((char *)data)[0] = 0;
-            while(((char *)data)[0] != 0xA)  {
-                ((char *)data)[0] = _parser.getc(); 
-            }
-
-            // complete data is yet to be read
-            if(!((_parser.read((char*)data, recv_amount) >0)
+    }       
+    _parser.setTimeout(par_timeout);
+    
+    _parser.flush();
+    if(!(_parser.send("AT+S.SOCKR=%d,%d", id, recv_amount))){
+        return -2;    
+    }
+    if(!((_parser.read((char*)data, recv_amount) >0)
             && _parser.recv("OK"))) {
-                return -2;
-            }
-        }
-        else {
-            // data left to be read is 3 bytes less.
-            if(!((_parser.read((char*)data+3, recv_amount-3) >0)
-                && _parser.recv("OK"))) {
-                                    return -2;
-                }
-            }
-        }
-    else {
-        if(!((_parser.read((char*)data, recv_amount) >0)
-            && _parser.recv("OK"))) {
-            return -2;
-        }
-    }
+        return -2;
+    }    
     return recv_amount;
 }
 
 bool SPWFSA01::close(int id)
 {
+    uint32_t recv_amount=0;    
+    void * data = NULL;    
+
+    _parser.setTimeout(SPWFSA01_MISC_TIMEOUT);    
+    _parser.flush();
+    /* socket flush */
+    if(!(_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"))) {
+            return -2;
+    } 
+    if (recv_amount>0) {
+        data = malloc (recv_amount+4);
+        if(!(_parser.send("AT+S.SOCKR=%d,%d", id, recv_amount))) { 
+            free (data); 
+            return -2; 
+        }
+ //       printf ("--->>>Close flushing recv_amount: %d  \n\r",recv_amount);            
+        if(!((_parser.read((char*)data, recv_amount) >0)
+            && _parser.recv("OK"))) {
+             free (data);
+             return -2;
+        }
+        free (data);                            
+    }     
+    
     //May take a second try if device is busy or error is returned
     for (unsigned i = 0; i < 2; i++) {
         if (_parser.send("AT+S.SOCKC=%d", id)
             && _parser.recv("OK")) {
+            socket_closed = 1;     
             return true;
         }
         else
-            {
-                if(_parser.recv("ERROR: Pending data"))
+        {
+            if(_parser.recv("ERROR: Pending data")) {
                     debug_if(dbg_on, "SPWF> ERROR!!!!\r\n");
                     return false;
-                }
+            }
+        }
         //TODO: Deal with "ERROR: Pending data" (Closing a socket with pending data)
     }
-
     return false;
 }
 
-void SPWFSA01::setTimeout(uint32_t timeout_ms)
-{
-    _parser.setTimeout(timeout_ms);
-}
 
 bool SPWFSA01::readable()
 {