USB Host Library for Sprint Dongles

Dependencies:   Socket USBHostWANDongleSprint lwip-sys lwip

Dependents:   SprintUSBModemWebsocketTest SprintUSBModemHTTPClientTest SprintUSBModemNTPClientTest SprintUSBModemSMSTest ... more

Fork of SprintUSBModem_bleedingedge by Donatien Garnier

Files at this revision

API Documentation at this revision

Comitter:
donatien
Date:
Wed Oct 10 08:20:51 2012 +0000
Parent:
3:9dd2b131afa0
Child:
5:a2a739fc2bed
Commit message:
Use one serial port only for now; hangup delay adjusted

Changed in this revision

SprintUSBModem.cpp Show annotated file Show diff for this revision Revisions of this file
SprintUSBModem.h Show annotated file Show diff for this revision Revisions of this file
USBHostWANDongleSprint_bleedingedge.lib Show annotated file Show diff for this revision Revisions of this file
at/ATCommandsInterface.cpp Show annotated file Show diff for this revision Revisions of this file
at/ATCommandsInterface.h Show annotated file Show diff for this revision Revisions of this file
ip/PPPIPInterface.cpp Show annotated file Show diff for this revision Revisions of this file
sms/SMSInterface.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/SprintUSBModem.cpp	Thu Sep 27 09:00:34 2012 +0000
+++ b/SprintUSBModem.cpp	Wed Oct 10 08:20:51 2012 +0000
@@ -29,8 +29,9 @@
 #define USE_ONE_PORT 1
 
 SprintUSBModem::SprintUSBModem(PinName powerGatingPin /*= NC*/, bool powerGatingOnWhenPinHigh /* = true*/) : m_dongle(),
-m_atStream(m_dongle.getSerial(1)), m_pppStream(m_dongle.getSerial(0)), m_at(&m_atStream),
-m_sms(&m_at), m_ppp(&m_atStream), //FIXME
+m_stream(m_dongle.getSerial(0)), 
+m_at(&m_stream),
+m_sms(&m_at), m_ppp(&m_stream),
 m_dongleConnected(false), m_ipInit(false), m_smsInit(false), m_atOpen(false),
 m_powerGatingPin(powerGatingPin), m_powerGatingOnWhenPinHigh(powerGatingOnWhenPinHigh)
 {
--- a/SprintUSBModem.h	Thu Sep 27 09:00:34 2012 +0000
+++ b/SprintUSBModem.h	Wed Oct 10 08:20:51 2012 +0000
@@ -95,8 +95,7 @@
 private:
   WANDongle m_dongle;
   
-  USBSerialStream m_atStream;
-  USBSerialStream m_pppStream;
+  USBSerialStream m_stream;
   
   ATCommandsInterface m_at;
   
--- a/USBHostWANDongleSprint_bleedingedge.lib	Thu Sep 27 09:00:34 2012 +0000
+++ b/USBHostWANDongleSprint_bleedingedge.lib	Wed Oct 10 08:20:51 2012 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/donatien/code/USBHostWANDongleSprint_bleedingedge/#9ec92dd8a8cb
+http://mbed.org/users/donatien/code/USBHostWANDongleSprint_bleedingedge/#99f453c4756b
--- a/at/ATCommandsInterface.cpp	Thu Sep 27 09:00:34 2012 +0000
+++ b/at/ATCommandsInterface.cpp	Wed Oct 10 08:20:51 2012 +0000
@@ -387,10 +387,21 @@
             }
           }
           //Process line
-          processReadLine();
-          //Shift remaining data to beginning of buffer
-          memmove(m_inputBuf, m_inputBuf + crPos + lfOff + 1, (m_inputPos + 1) - (crPos + lfOff + 1)); //Move null-terminating char as well
-          m_inputPos = m_inputPos - (crPos + lfOff + 1); //Adjust m_inputPos
+          int ret = processReadLine();
+          if(ret)
+          {
+            m_inputPos = 0;
+            m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
+            lineDetected = false;
+            return ret;
+          }
+
+          //If sendData has been called, all incoming data has been discarded
+          if(m_inputPos > 0)
+          {
+            memmove(m_inputBuf, m_inputBuf + crPos + lfOff + 1, (m_inputPos + 1) - (crPos + lfOff + 1)); //Move null-terminating char as well
+            m_inputPos = m_inputPos - (crPos + lfOff + 1); //Adjust m_inputPos
+          }
           DBG("One line was successfully processed");
           lineProcessed = true; //Line was processed with success
           lineDetected = false; //Search now for a new line
@@ -442,6 +453,7 @@
             if(ret)
             {
               m_inputPos = 0;
+              m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
               lineDetected = false;
               return ret;
             }
@@ -490,6 +502,7 @@
             if(ret)
             {
               m_inputPos = 0;
+              m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
               lineDetected = false;
               return ret;
             }
@@ -515,6 +528,7 @@
   {
     //Discard everything
     m_inputPos = 0;
+    m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
     WARN("Incoming buffer is too short to process incoming line");
     //Look for a new line
     lineDetected = false;
@@ -721,13 +735,17 @@
     if(ret)
     {
       WARN("Could not read from stream (returned %d)", ret);
+      m_inputPos = 0; //Reset input buffer state
+      m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
       return ret;
-    };
+    }
 
     if( memcmp(m_inputBuf, data + dataPos, readLen) != 0 )
     {
       //Echo does not match output
       WARN("Echo does not match output");
+      m_inputPos = 0; //Reset input buffer state
+      m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
       return NET_DIFF;
     }
 
@@ -739,6 +757,7 @@
   DBG("String sent successfully");
 
   m_inputPos = 0; //Reset input buffer state
+  m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
 
   return OK;
 }
@@ -799,4 +818,3 @@
     DBG("AT Processing stopped");
   }
 }
-
--- a/at/ATCommandsInterface.h	Thu Sep 27 09:00:34 2012 +0000
+++ b/at/ATCommandsInterface.h	Wed Oct 10 08:20:51 2012 +0000
@@ -51,7 +51,7 @@
   friend class ATCommandsInterface;
 };
 
-#define AT_INPUT_BUF_SIZE 64
+#define AT_INPUT_BUF_SIZE 192//64
 
 //Signals to be sent to the processing thread
 #define AT_SIG_PROCESSING_START 1
@@ -113,7 +113,8 @@
   void process(); //Processing thread
 
   IOStream* m_pStream;
-  bool m_open;
+  
+  bool m_open; //< TRUE when the AT interface is open, and FALSE when it is not.
 
   const char* m_transactionCommand;
   const char* m_transactionData;
--- a/ip/PPPIPInterface.cpp	Thu Sep 27 09:00:34 2012 +0000
+++ b/ip/PPPIPInterface.cpp	Wed Oct 10 08:20:51 2012 +0000
@@ -17,7 +17,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#define __DEBUG__ 4 //Maximum verbosity
+#define __DEBUG__ 0
 #ifndef __MODULE__
 #define __MODULE__ "PPPIPInterface.cpp"
 #endif
@@ -198,6 +198,8 @@
     m_pppd = -1; //Discard PPP descriptor
   }
   
+  Thread::wait(500);
+  
   DBG("Sending %s", ESCAPE_SEQ);
   
   ret = m_pStream->write((uint8_t*)ESCAPE_SEQ, strlen(ESCAPE_SEQ), osWaitForever);
@@ -206,6 +208,8 @@
     return NET_UNKNOWN;
   }
   
+  Thread::wait(500);
+  
   cleanupLink();
   
   return OK;
--- a/sms/SMSInterface.cpp	Thu Sep 27 09:00:34 2012 +0000
+++ b/sms/SMSInterface.cpp	Wed Oct 10 08:20:51 2012 +0000
@@ -17,7 +17,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#define __DEBUG__ 0
+#define __DEBUG__ 2
 #ifndef __MODULE__
 #define __MODULE__ "SMSInterface.cpp"
 #endif
@@ -30,14 +30,17 @@
 
 #define DEFAULT_TIMEOUT 10000
 
-SMSInterface::SMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL), /*m_msgCount(0),*/
-m_msgRefListCount(0), m_needsUpdate(true), m_state(SMS_IDLE)
+SMSInterface::SMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL)
 {
   m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers
 }
 
 int SMSInterface::init()
 {
+  m_msgRefListCount = 0;
+  m_needsUpdate = true;
+  m_state = SMS_IDLE;
+
   DBG("Set format");
   //Set Text mode format
   int ret = m_pIf->executeSimple("AT+CMGF=1", NULL, DEFAULT_TIMEOUT);
@@ -116,7 +119,9 @@
   m_inboxMtx.lock();
   if(m_msgRefListCount == 0 && m_needsUpdate)
   {
+    DBG("Message list count is 0 and needs updating. Running updateInbox.");
     ret = updateInbox();
+    
     if (ret)
     {
       m_inboxMtx.unlock();
@@ -127,6 +132,7 @@
   if(m_msgRefListCount == 0)
   {
     m_inboxMtx.unlock();
+    DBG("Message list count is 0, I think it's empty and returning.");
     return NET_EMPTY; //No message to read
   }
 
@@ -151,27 +157,29 @@
 
   if (m_state != SMS_CMD_PROCESSED)
   {
-    m_state = SMS_IDLE;
-    m_inboxMtx.unlock();
-    return NET_EMPTY;
+    WARN("State variable is not 'SMS_CMD_PROCESSED' - returning 'NET_EMPTY'");
   }
 
-  m_state = SMS_IDLE;
-
-  DBG("Deleting message");
+  DBG("Deleting message from index number: %d", m_msgRefList[0] );
   //Delete message from outbox
   std::sprintf(cmd, "AT+CMGD=%d", m_msgRefList[0]);
   ret = m_pIf->executeSimple(cmd, NULL, DEFAULT_TIMEOUT);
   if(ret != OK)
   {
-    m_inboxMtx.unlock();
-    WARN("Could not delete message");
+    ERR("Could not delete message");
   }
-
   //Remove message from list
   std::memmove(m_msgRefList, m_msgRefList+1, m_msgRefListCount-1);
   m_msgRefListCount--;
-
+  
+  if (m_state != SMS_CMD_PROCESSED)
+  {
+    m_state = SMS_IDLE;
+    m_inboxMtx.unlock();
+    return NET_EMPTY;
+  }
+  
+  m_state = SMS_IDLE;
   m_inboxMtx.unlock();
 
   return OK;
@@ -230,7 +238,7 @@
   {
     DBG("Header: %s", line);
     int msgRef;
-    if( std::sscanf(line, "+CMGL: %d", &msgRef) == 1 )
+    if( std::sscanf(line, "+CMGL: %d,\"REC", &msgRef) == 1 ) //Filter on REC READ and REC UNREAD messages 
     {
       m_state = SMS_GET_COUNT_HDR_RECEIVED;
       //Add message to list
@@ -334,30 +342,51 @@
   if( std::sscanf(evt, "\"SM\",%d", &msgRef) == 1 )
   {
     DBG("Adding message to list (ref %d)", msgRef);
-    m_inboxMtx.lock();
-    //Add message to list
-    if(m_msgRefListCount < MAX_SM)
+    if(m_inboxMtx.trylock())
     {
-      m_msgRefList[m_msgRefListCount] = msgRef;
+      //Add message to list
+      if(m_msgRefListCount < MAX_SM)
+      {
+        m_msgRefList[m_msgRefListCount] = msgRef;
+      }
+      else
+      {
+        m_needsUpdate = true;
+      }
+      m_msgRefListCount++; //Always count message
+      m_inboxMtx.unlock();
     }
     else
     {
+      WARN("Could not get lock");
       m_needsUpdate = true;
     }
-    m_msgRefListCount++; //Always count message
-    m_inboxMtx.unlock();
   }
 }
 
 int SMSInterface::updateInbox()
 {
   //Get memory indexes of unread messages
-  m_state = SMS_GET_COUNT_CMD_SENT;
 
   DBG("Updating inbox");
   m_msgRefListCount = 0; //Reset list
+  m_needsUpdate = false; //Assume we won't need update after this routine (can be set to true by an incoming SM event)
 
-  int ret = m_pIf->execute("AT+CMGL=\"REC UNREAD\"", this, NULL, DEFAULT_TIMEOUT);
+  //First list the "REC READ" messages that were not processed in the previous session
+  m_state = SMS_GET_COUNT_CMD_SENT;
+  int ret = m_pIf->execute("AT+CMGL=\"REC READ\"", this, NULL, DEFAULT_TIMEOUT);
+  if( ret != OK )
+  {
+    WARN("AT+CMGL returned %d", ret);
+    m_state = SMS_IDLE;
+    m_msgRefListCount = 0; //List could be invalid
+    m_needsUpdate = true;
+    return NET_PROTOCOL;
+  }
+  
+  //Now list the "REC UNREAD" messages that were received by the modem since
+  m_state = SMS_GET_COUNT_CMD_SENT;
+  ret = m_pIf->execute("AT+CMGL=\"REC UNREAD\"", this, NULL, DEFAULT_TIMEOUT);
   if( ret != OK )
   {
     WARN("AT+CMGL returned %d", ret);
@@ -373,14 +402,9 @@
   {
     m_needsUpdate = true;
   }
-  else
-  {
-    m_needsUpdate = false;
-  }
 
   m_state = SMS_IDLE;
 
   return OK;
 }
 
-