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.

Files at this revision

API Documentation at this revision

Comitter:
donatien
Date:
Mon Jul 30 13:51:51 2012 +0000
Parent:
17:87e538c1fd74
Child:
19:71f038fb8e40
Commit message:
Vodafone K3772-Z support!

Changed in this revision

USBHostWANDongleLib.lib Show annotated file Show diff for this revision Revisions of this file
VodafoneK3770.cpp 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
ip/PPPIPInterface.cpp Show annotated file Show diff for this revision Revisions of this file
ip/PPPIPInterface.h Show annotated file Show diff for this revision Revisions of this file
--- a/USBHostWANDongleLib.lib	Sat Jul 28 14:33:57 2012 +0000
+++ b/USBHostWANDongleLib.lib	Mon Jul 30 13:51:51 2012 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/donatien/code/USBHostWANDongle_bleedingedge/#c4483d48fe96
+http://mbed.org/users/donatien/code/USBHostWANDongle_bleedingedge/#0d1ec493842c
--- a/VodafoneK3770.cpp	Sat Jul 28 14:33:57 2012 +0000
+++ b/VodafoneK3770.cpp	Mon Jul 30 13:51:51 2012 +0000
@@ -21,7 +21,7 @@
 SOFTWARE.
 */
 
-#define __DEBUG__ 0
+#define __DEBUG__ 3
 #ifndef __MODULE__
 #define __MODULE__ "VodafoneK3770.cpp"
 #endif
@@ -480,22 +480,43 @@
     return ret;
   }
 
-  #if USE_ONE_PORT
-  DBG("Configuring unsolicited result codes support properly");
-  //Configuring port to enable 3GPP-compliant unsollicited response codes but disable Huawei-specific unsollicited response codes
-  ret = m_at.executeSimple("AT^CURC=0;^PORTSEL=1", NULL); //Huawei-specific, not 3GPP-compliant
-  if(ret != OK)
+  if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_VODAFONEK3770)
   {
-    return NET_PROTOCOL;
+    INFO("Using a Vodafone K3770 Dongle");
+    #if USE_ONE_PORT
+    DBG("Configuring unsolicited result codes support properly");
+    //Configuring port to enable 3GPP-compliant unsollicited response codes but disable Huawei-specific unsollicited response codes
+    ret = m_at.executeSimple("AT^CURC=0;^PORTSEL=1", NULL); //Huawei-specific, not 3GPP-compliant
+    if(ret != OK)
+    {
+      return NET_PROTOCOL;
+    }
+    #else
+    //Configuring port to disable Huawei-specific unsollicited response codes
+    ret = m_at.executeSimple("AT^CURC=0", NULL); //Huawei-specific, not 3GPP-compliant
+    if(ret != OK)
+    {
+      return NET_PROTOCOL;
+    }  
+    #endif
   }
-  #else
-  //Configuring port to disable Huawei-specific unsollicited response codes
-  ret = m_at.executeSimple("AT^CURC=0", NULL); //Huawei-specific, not 3GPP-compliant
-  if(ret != OK)
+  else if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_VODAFONEK3772Z)
   {
-    return NET_PROTOCOL;
-  }  
-  #endif
+    INFO("Using a Vodafone K3772-Z Dongle");
+    //FIXME this returns %USBMODEM: [0] MODEM DRIVER<CR><LF><CR><LF><CR><LF>OK<CR><LF> which is not a compliant response
+    /*
+    //Configuring modem to directly boot into modem mode
+    ret = m_at.executeSimple("AT%USBMODEM=0", NULL); //Icera-specific, not 3GPP-compliant
+    if(ret != OK)
+    {
+      return NET_PROTOCOL;
+    }
+    */
+  }
+  else
+  {
+    WARN("Using an Unknown Dongle");
+  }
 
   ATCommandsInterface::ATResult result;
 
--- a/at/ATCommandsInterface.cpp	Sat Jul 28 14:33:57 2012 +0000
+++ b/at/ATCommandsInterface.cpp	Mon Jul 30 13:51:51 2012 +0000
@@ -21,7 +21,7 @@
 SOFTWARE.
 */
 
-#define __DEBUG__ 2//ERR+WARN
+#define __DEBUG__  2//ERR+WARN
 #ifndef __MODULE__
 #define __MODULE__ "ATCommandsInterface.cpp"
 #endif
--- 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;
 }
 
--- a/ip/PPPIPInterface.h	Sat Jul 28 14:33:57 2012 +0000
+++ b/ip/PPPIPInterface.h	Mon Jul 30 13:51:51 2012 +0000
@@ -50,6 +50,8 @@
     virtual int disconnect();
 
 private:
+    int cleanupLink();
+
     static void linkStatusCb(void *ctx, int errCode, void *arg); //PPP link status
     Semaphore m_linkStatusSphre;
     int m_pppErrCode;