AT Parser and bufferedSerial based SPWF library

Dependencies:   ATParser

Dependents:   X_NUCLEO_IDW01M1v2

Fork of SPWF01SA by ST Expansion SW Team

Files at this revision

API Documentation at this revision

Comitter:
mapellil
Date:
Tue Nov 22 14:36:25 2016 +0000
Parent:
23:0b01aa59bb6f
Child:
25:6b79352bc1fa
Commit message:
Improved RECV

Changed in this revision

ATParser.lib Show annotated file Show diff for this revision Revisions of this file
SPWFSA01.cpp Show annotated file Show diff for this revision Revisions of this file
SPWFSA01.h Show annotated file Show diff for this revision Revisions of this file
--- a/ATParser.lib	Thu Nov 03 06:53:47 2016 +0000
+++ b/ATParser.lib	Tue Nov 22 14:36:25 2016 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/teams/ST/code/ATParser/#537f1380c44a
+https://developer.mbed.org/teams/ST/code/ATParser/#ea155e6b1fb1
--- 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()
 {
--- a/SPWFSA01.h	Thu Nov 03 06:53:47 2016 +0000
+++ b/SPWFSA01.h	Tue Nov 22 14:36:25 2016 +0000
@@ -25,8 +25,9 @@
 class SPWFSA01
 {
 public:
-    SPWFSA01(PinName tx, PinName rx, bool debug=false);
- 
+    
+    SPWFSA01(PinName tx, PinName rx, PinName reset=NC, PinName wakeup=NC, bool debug=false);
+    
     /**
     * Init the SPWFSA01
     *
@@ -130,12 +131,6 @@
     */
     bool close(int id);
  
-    /**
-    * Allows timeout to be changed between commands
-    *
-    * @param timeout_ms timeout of the connection
-    */
-    void setTimeout(uint32_t timeout_ms);
  
     /**
     * Checks if data is available
@@ -151,11 +146,15 @@
     BufferedSerial _serial;
     ATParser _parser;
     DigitalInOut _wakeup;
-    DigitalInOut _reset;
- 
+    DigitalInOut _reset; 
     char _ip_buffer[16];
     char _mac_buffer[18];
     bool dbg_on;
+//    int _timeout; // FIXME LICIO we have "virtual" socket tmo, module socket tmo, 
+// AT parser tmo, recv/send tmo, actually used the NetworksocketAPI socket tmo
+    unsigned int _recv_timeout; // see SO_RCVTIMEO setsockopt
+    unsigned int _send_timeout; // see SO_SNDTIMEO setsockopt   
+    unsigned int socket_closed;
 };
  
-#endif  //SPWFSA01_H
\ No newline at end of file
+#endif  //SPWFSA01_H