Vodafone K3770/K3772-Z modems driver & networking library

Dependencies:   Socket USBHostWANDongle lwip-sys lwip

Dependents:   VodafoneUSBModemHTTPClientTest VodafoneUSBModemNTPClientTest VodafoneUSBModemSMSTest VodafoneUSBModemUSSDTest ... more

Fork of VodafoneUSBModem_bleedingedge by Donatien Garnier

This is the driver for the Vodafone K3700 & K3772-Z Dongles:

K3770

More details and instructions can be found here.

Revision:
18:1789a11d1892
Parent:
12:66dc2c8eba2d
Child:
22:06fb2a93a1f6
--- a/ip/PPPIPInterface.cpp	Sat Jul 28 14:33:57 2012 +0000
+++ b/ip/PPPIPInterface.cpp	Mon Jul 30 13:51:51 2012 +0000
@@ -21,12 +21,6 @@
 SOFTWARE.
 */
 
-#define MSISDN "*99#"
-
-#define CONNECT_CMD "ATD " MSISDN "\x0D"
-#define EXPECTED_RESP CONNECT_CMD "\x0D" "\x0A" "CONNECT" "\x0D" "\x0A"
-#define OK_RESP
-
 #define __DEBUG__ 0 //Maximum verbosity
 #ifndef __MODULE__
 #define __MODULE__ "PPPIPInterface.cpp"
@@ -37,6 +31,16 @@
 
 #include "PPPIPInterface.h"
 
+#define MSISDN "*99#"
+
+#define CONNECT_CMD "ATD " MSISDN "\x0D"
+#define EXPECTED_RESP CONNECT_CMD "\x0D" "\x0A" "CONNECT" "\x0D" "\x0A"
+#define EXPECTED_RESP_DATARATE CONNECT_CMD "\x0D" "\x0A" "CONNECT %d" "\x0D" "\x0A"
+#define EXPECTED_RESP_MIN_LEN 20
+#define OK_RESP "\x0D" "\x0A" "OK" "\x0D" "\x0A"
+#define ESCAPE_SEQ "+++"
+#define HANGUP_CMD "ATH" "\x0D"
+#define NO_CARRIER_RESP "\x0D" "\x0A" "NO CARRIER" "\x0D" "\x0A"
 extern "C" {
 #include "lwip/ip_addr.h"
 #include "lwip/inet.h"
@@ -78,10 +82,7 @@
   size_t len;
   DBG("Trying to connect with PPP");
   
-  do //Clear buf
-  {
-    ret = m_pStream->read((uint8_t*)buf, &len, 32, 0);
-  } while( (ret == OK) && (len > 0) );
+  cleanupLink();
   
   DBG("Sending %s", CONNECT_CMD);
   
@@ -91,16 +92,22 @@
     return NET_UNKNOWN;
   }
   
-  DBG("Expect %s [len %d]", EXPECTED_RESP, strlen(EXPECTED_RESP));
+  DBG("Expect %s", EXPECTED_RESP);
     
   len = 0;
-  while(len < strlen(EXPECTED_RESP))
+  size_t readLen;
+  ret = m_pStream->read((uint8_t*)buf + len, &readLen, EXPECTED_RESP_MIN_LEN, 10000);
+  if( ret != OK )
   {
-    size_t readLen;
-    ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(EXPECTED_RESP) - len, 10000);
+    return NET_UNKNOWN;
+  }
+  len += readLen;
+  while( (len < EXPECTED_RESP_MIN_LEN) || (buf[len-1] != LF) )
+  {
+    ret = m_pStream->read((uint8_t*)buf + len, &readLen, 1, 10000);
     if( ret != OK )
     {
-    return NET_UNKNOWN;
+      return NET_UNKNOWN;
     }
     len += readLen;
   }
@@ -109,7 +116,8 @@
   
   DBG("Got %s[len %d]", buf, len);
   
-  if( memcmp(EXPECTED_RESP, buf, strlen(EXPECTED_RESP)) != 0 )
+  int datarate = 0;
+  if( (sscanf( buf, EXPECTED_RESP_DATARATE, &datarate ) != 1) && (strcmp(EXPECTED_RESP, buf) != 0) )
   {
     //Discard buffer
     do //Clear buf
@@ -120,6 +128,10 @@
   }
       
   DBG("Transport link open");
+  if(datarate != 0)
+  {
+    DBG("Datarate: %d bps", datarate);
+  }
   m_linkStatusSphre.wait(0);
   if((m_pppd != -1) && (m_pppErrCode == 0)) //Already connected
   {
@@ -188,6 +200,121 @@
     } while(m_pppErrCode != PPPERR_USER);
     m_pppd = -1; //Discard PPP descriptor
   }
+  
+  DBG("Sending %s", ESCAPE_SEQ);
+  
+  ret = m_pStream->write((uint8_t*)ESCAPE_SEQ, strlen(ESCAPE_SEQ), osWaitForever);
+  if( ret != OK )
+  {
+    return NET_UNKNOWN;
+  }
+  
+  cleanupLink();
+  
+  return OK;
+}
+
+
+int PPPIPInterface::cleanupLink()
+{
+  int ret;
+  char buf[32];
+  size_t len;
+  
+  do //Clear buf
+  {
+    ret = m_pStream->read((uint8_t*)buf, &len, 32, 100);
+    if(ret == OK)
+    {
+      buf[len] = '\0';
+      DBG("Got %s", buf);
+    }
+  } while( (ret == OK) && (len > 0) );
+  
+  DBG("Sending %s", HANGUP_CMD);
+  
+  ret = m_pStream->write((uint8_t*)HANGUP_CMD, strlen(HANGUP_CMD), osWaitForever);
+  if( ret != OK )
+  {
+    return NET_UNKNOWN;
+  }
+     
+  size_t readLen;
+  
+  //Hangup
+  DBG("Expect %s", HANGUP_CMD);
+
+  len = 0;
+  while( len < strlen(HANGUP_CMD) )
+  {
+    ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(HANGUP_CMD) - len, 100);
+    if( ret != OK )
+    {
+      break;
+    }
+    len += readLen;
+    /////
+    buf[len]=0;
+    DBG("Got %s", buf);
+  }
+  
+  buf[len]=0;
+  
+  DBG("Got %s[len %d]", buf, len);
+  
+  //OK response
+  DBG("Expect %s", OK_RESP);
+
+  len = 0;
+  while( len < strlen(OK_RESP) )
+  {
+    ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(OK_RESP) - len, 100);
+    if( ret != OK )
+    {
+      break;
+    }
+    len += readLen;
+    /////
+    buf[len]=0;
+    DBG("Got %s", buf);
+  }
+  
+  buf[len]=0;
+  
+  DBG("Got %s[len %d]", buf, len);
+  
+  //NO CARRIER event
+  DBG("Expect %s", NO_CARRIER_RESP);
+
+  len = 0;
+  while( len < strlen(NO_CARRIER_RESP) )
+  {
+    ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(NO_CARRIER_RESP) - len, 100);
+    if( ret != OK )
+    {
+      break;
+    }
+    len += readLen;
+    /////
+    buf[len]=0;
+    DBG("Got %s", buf);
+  }
+  
+  buf[len]=0;
+  
+  DBG("Got %s[len %d]", buf, len);
+  
+  do //Clear buf
+  {
+    ret = m_pStream->read((uint8_t*)buf, &len, 32, 100);
+    if(ret == OK)
+    {
+      buf[len] = '\0';
+      DBG("Got %s", buf);
+    }
+  } while( (ret == OK) && (len > 0) );
+  
+  
   return OK;
 }