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

Revision:
2:f4d9c4ea17f9
Parent:
0:8f57713b2147
Child:
3:9dd2b131afa0
--- a/SprintUSBModem.cpp	Wed Sep 12 09:46:58 2012 +0000
+++ b/SprintUSBModem.cpp	Wed Sep 26 07:08:18 2012 +0000
@@ -26,22 +26,28 @@
 
 #include "SprintUSBModem.h"
 
-SprintUSBModem::SprintUSBModem() : m_dongle(),
+//#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_pppStream), 
-m_dongleConnected(false), m_ipInit(false), m_smsInit(false), m_atOpen(false)
+m_dongleConnected(false), m_ipInit(false), m_smsInit(false), m_atOpen(false),
+m_powerGatingPin(powerGatingPin), m_powerGatingOnWhenPinHigh(powerGatingOnWhenPinHigh)
 {
-
+  if( m_powerGatingPin != NC )
+  {
+    power(false); //Dongle will have to be powered on manually
+  }
 }
 
-class CREGProcessor : public IATCommandsProcessor
+class CSSProcessor : public IATCommandsProcessor
 {
 public:
-  CREGProcessor() : status(STATUS_REGISTERING)
+  CSSProcessor() : status(STATUS_REGISTERING)
   {
 
   }
-  enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK, STATUS_FAILED };
+  enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK };
   REGISTERING_STATUS getStatus()
   {
     return status;
@@ -49,22 +55,16 @@
 private:
   virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
   {
-    int r;
-    if( sscanf(line, "+CREG: %*d,%d", &r) == 1 )
+    char r;
+    if( sscanf(line, "%*d, %c", &r) == 1 )
     {
       switch(r)
       {
-      case 1:
-      case 5:
-        status = STATUS_OK;
-        break;
-      case 0:
-      case 2:
+      case 'Z':
         status = STATUS_REGISTERING;
         break;
-      case 3:
       default:
-        status = STATUS_FAILED;
+        status = STATUS_OK;
         break;
       }
     }
@@ -94,8 +94,8 @@
 
   #if USE_ONE_PORT
   m_smsInit = false; //SMS status reset
-  m_ussdInit = false; //USSD status reset
-  m_linkMonitorInit = false; //Link monitor status reset
+  //m_ussdInit = false; //USSD status reset
+  //m_linkMonitorInit = false; //Link monitor status reset
   #endif
 
   ATCommandsInterface::ATResult result;
@@ -271,15 +271,50 @@
   return &m_at;
 }
 
+int SprintUSBModem::power(bool enable)
+{
+  if( m_powerGatingPin == NC )
+  {
+    return NET_INVALID; //A pin name has not been provided in the constructor
+  }
+
+  if(!enable) //Will force components to re-init
+  {
+    cleanup();
+  }
+  
+  DigitalOut powerGatingOut(m_powerGatingPin);
+  powerGatingOut = m_powerGatingOnWhenPinHigh?enable:!enable;
+
+  return OK;
+}
+
+bool SprintUSBModem::power()
+{
+  if( m_powerGatingPin == NC )
+  {
+    return true; //Assume power is always on 
+  }
+  
+  DigitalOut powerGatingOut(m_powerGatingPin);
+  return m_powerGatingOnWhenPinHigh?powerGatingOut:!powerGatingOut;
+}
+
 int SprintUSBModem::init()
 {
   if( !m_dongleConnected )
   {
+    if(!power())
+    {
+      //Obviously cannot initialize the dongle if it is disconnected...
+      ERR("Power is off");
+      return NET_INVALID;
+    }
     m_dongleConnected = true;
     while( !m_dongle.connected() )
     {
       m_dongle.tryConnect();
-      Thread::wait(10);
+      Thread::wait(100);
     }
   }
 
@@ -314,27 +349,45 @@
   ATCommandsInterface::ATResult result;
 
   //Wait for network registration
-  CREGProcessor cregProcessor;
+  CSSProcessor cssProcessor;
   do
   {
     DBG("Waiting for network registration");
-    ret = m_at.execute("AT+CREG?", &cregProcessor, &result);
+    ret = m_at.execute("AT+CSS?", &cssProcessor, &result);
     DBG("Result of command: Err code=%d\n", ret);
     DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
-    if(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING)
+    if(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING)
     {
       Thread::wait(3000);
     }
-  } while(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING);
-  if(cregProcessor.getStatus() == CREGProcessor::STATUS_FAILED)
-  {
-    ERR("Registration denied");
-    return NET_AUTH;
-  }
+  } while(cssProcessor.getStatus() == CSSProcessor::STATUS_REGISTERING);
 
   m_atOpen = true;
 
   return OK;
 }
 
+int SprintUSBModem::cleanup()
+{
+  if(m_ppp.isConnected())
+  {
+    WARN("Data connection is still open"); //Try to encourage good behaviour from the user
+    m_ppp.disconnect(); 
+  }
+  
+  m_smsInit = false;
+//  m_linkMonitorInit = false;
+  //We don't reset m_ipInit as PPPIPInterface::init() only needs to be called once
+  
+  if(m_atOpen)
+  {
+    m_at.close();
+    m_atOpen = false;
+  }
+  
+  m_dongle.disconnect();
+  m_dongleConnected = false;
+  
+  return OK;
+}