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:
22:06fb2a93a1f6
Parent:
21:063f84a2614d
Child:
23:21046ba01b7b
--- a/VodafoneK3770.cpp	Sun Aug 05 15:29:22 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,548 +0,0 @@
-/* VodafoneK3770.cpp */
-/*
-Copyright (C) 2012 ARM Limited.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-#define __DEBUG__ 3
-#ifndef __MODULE__
-#define __MODULE__ "VodafoneK3770.cpp"
-#endif
-
-#include "core/fwk.h"
-
-#include "VodafoneK3770.h"
-
-VodafoneK3770::VodafoneK3770() : m_dongle(),
-m_atStream(m_dongle.getSerial(1)), m_pppStream(m_dongle.getSerial(0)), m_at(&m_atStream),
-m_sms(&m_at), m_ussd(&m_at), m_linkMonitor(&m_at), m_ppp(&m_pppStream), 
-m_dongleConnected(false), m_ipInit(false), m_smsInit(false), m_ussdInit(false), m_linkMonitorInit(false), m_atOpen(false)
-{
-
-}
-
-class CREGProcessor : public IATCommandsProcessor
-{
-public:
-  CREGProcessor() : status(STATUS_REGISTERING)
-  {
-
-  }
-  enum REGISTERING_STATUS { STATUS_REGISTERING, STATUS_OK, STATUS_FAILED };
-  REGISTERING_STATUS getStatus()
-  {
-    return status;
-  }
-private:
-  virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
-  {
-    int r;
-    if( sscanf(line, "+CREG: %*d,%d", &r) == 1 )
-    {
-      switch(r)
-      {
-      case 1:
-      case 5:
-        status = STATUS_OK;
-        break;
-      case 0:
-      case 2:
-        status = STATUS_REGISTERING;
-        break;
-      case 3:
-      default:
-        status = STATUS_FAILED;
-        break;
-      }
-    }
-    return OK;
-  }
-  virtual int onNewEntryPrompt(ATCommandsInterface* pInst)
-  {
-    return OK;
-  }
-  volatile REGISTERING_STATUS status;
-};
-
-#if 0
-class COPSProcessor : public IATCommandsProcessor
-{
-public:
-  COPSProcessor() : valid(false)
-  {
-    network[0] = '\0';
-    apn[0] = '\0';
-    bearer[0] = '\0';
-  }
-  char* getNetwork()
-  {
-    return network;
-  }
-  char* getAPN()
-  {
-    return apn;
-  }
-  char* getBearer()
-  {
-    return bearer;
-  }
-  bool isValid()
-  {
-    return valid;
-  }
-private:
-  virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
-  {
-    int networkId;
-    int bearerId;
-    int s = sscanf(line, "+COPS: %*d,%*d,\"%d\",%d", &networkId, &bearerId);
-    if( s == 2 )
-    {
-      switch(networkId)
-      {
-      case 23415:
-        strcpy(network, "Vodafone UK");
-        strcpy(apn, "pp.vodafone.co.uk");
-        valid = true;
-        break;
-      case 20810:
-        strcpy(network, "SFR FR");
-        strcpy(apn, "websfr");
-        valid = true;
-        break;
-      default:
-        break;
-      }
-    }
-    else
-    {
-      return OK;
-    }
-    switch(bearerId)
-    {
-    case 0: strcpy(bearer, "GSM"); break;
-    case 1: strcpy(bearer, "GSM Compact"); break;
-    case 2: strcpy(bearer, "UTRAN"); break;
-    case 3: strcpy(bearer, "GSM w/EGPRS"); break;
-    case 4: strcpy(bearer, "UTRAN w/HSDPA"); break;
-    case 5: strcpy(bearer, "UTRAN w/HSUPA"); break;
-    case 6: strcpy(bearer, "UTRAN w/HSDPA and HSUPA"); break;
-    case 7: strcpy(bearer, "E-UTRAN"); break;
-
-    default:
-      break;
-    }
-    return OK;
-  }
-  virtual int onNewEntryPrompt(ATCommandsInterface* pInst)
-  {
-    return OK;
-  }
-  char network[24];
-  char bearer[24];
-  char apn[24];
-  volatile bool valid;
-};
-#endif
-
-int VodafoneK3770::connect(const char* apn, const char* user, const char* password)
-{
-  if( !m_ipInit )
-  {
-    m_ipInit = true;
-    m_ppp.init();
-  }
-  m_ppp.setup(user, password);
-
-  int ret = init();
-  if(ret)
-  {
-    return ret;
-  }
-
-  #if USE_ONE_PORT
-  m_smsInit = false; //SMS status reset
-  m_ussdInit = false; //USSD status reset
-  m_linkMonitorInit = false; //Link monitor status reset
-  #endif
-
-  ATCommandsInterface::ATResult result;
-
-  #if 0
-  //Get network info & select corresponding APN
-  COPSProcessor copsProcessor;
-  DBG("Get network info & select APN from DB");
-  ret = m_at.execute("AT+COPS=,2;+COPS?", &copsProcessor, &result); //Configure to get operator's info in numeric code & get operator's id
-  DBG("Result of command: Err code=%d", ret);
-  DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
-
-  if(!copsProcessor.isValid())
-  {
-    WARN("Connected to an unknown network, try to connect with default parameters");
-    DBG("Connected with %s", copsProcessor.getBearer());
-  }
-  else
-  {
-    DBG("Connected to %s with %s", copsProcessor.getNetwork(), copsProcessor.getBearer());
-    char cmd[48];
-    sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", copsProcessor.getAPN());
-    ret = m_at.executeSimple(cmd, &result);
-    DBG("Result of command: Err code=%d", ret);
-    DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
-    DBG("APN set to %s", copsProcessor.getAPN());
-  }
-  #else
-  if(apn != NULL)
-  {
-    char cmd[48];
-    sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn);
-    ret = m_at.executeSimple(cmd, &result);
-    DBG("Result of command: Err code=%d", ret);
-    DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
-    DBG("APN set to %s", apn);
-  }
-  #endif
-
-
-  //Connect
-  DBG("Connecting");
-  #if 0
-  ret = m_at.executeSimple("ATDT *99#", &result);
-  DBG("Result of command: Err code=%d", ret);
-  DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
-  #endif
-  #if USE_ONE_PORT
-  m_at.close(); // Closing AT parser
-  m_atOpen = false; //Will need to be reinitialized afterwards
-  #endif
-
-  #if 0
-  DBG("AT Parser closed");
-  if( (ret!=NET_MOREINFO) || (result.result != ATCommandsInterface::ATResult::AT_CONNECT))
-  {
-    ERR("Could not connect");
-    return ret; //Could not connect
-  }
-  #endif
-  DBG("Connecting PPP");
-
-  ret = m_ppp.connect();
-  DBG("Result of connect: Err code=%d", ret);
-  return ret;
-}
-
-
-int VodafoneK3770::disconnect()
-{
-  DBG("Disconnecting from PPP");
-  int ret = m_ppp.disconnect();
-  if(ret)
-  {
-    ERR("Disconnect returned %d, still trying to disconnect", ret);
-  }
-
-  //Ugly but leave dongle time to recover
-  Thread::wait(500);
-
-  #if USE_ONE_PORT
-  ATCommandsInterface::ATResult result;
-  DBG("Starting AT thread");
-  ret = m_at.open();
-  if(ret)
-  {
-    return ret;
-  }
-  #endif
-
-  DBG("Trying to hangup");
-
-  #if 0 //Does not appear to work
-  int tries = 10;
-  do
-  {
-    ret = m_at.executeSimple("+++", &result, 1000);
-    DBG("Result of command: Err code=%d\n", ret);
-    DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
-  } while(tries-- && ret);
-  if(!ret)
-  {
-    ret = m_at.executeSimple("ATH", &result);
-    DBG("Result of command: Err code=%d\n", ret);
-    DBG("ATResult: AT return=%d (code %d)\n", result.result, result.code);
-  }
-  #endif
-
-  #if USE_ONE_PORT
-  //Reinit AT parser
-  ret = m_at.init();
-  DBG("Result of command: Err code=%d\n", ret);
-  if(ret)
-  {
-    m_at.close(); // Closing AT parser
-    DBG("AT Parser closed, could not complete disconnection");
-    return NET_TIMEOUT;
-  }
-
-  #if 0
-  m_at.close(); // Closing AT parser
-  DBG("AT Parser closed");
-  #endif
-  #endif
-  return OK;
-}
-
-int VodafoneK3770::sendSM(const char* number, const char* message)
-{
-  int ret = init();
-  if(ret)
-  {
-    return ret;
-  }
-
-  if(!m_smsInit)
-  {
-    ret = m_sms.init();
-    if(ret)
-    {
-      return ret;
-    }
-    m_smsInit = true;
-  }
-
-  ret = m_sms.send(number, message);
-  if(ret)
-  {
-    return ret;
-  }
-
-  return OK;
-}
-
-int VodafoneK3770::getSM(char* number, char* message, size_t maxLength)
-{
-  int ret = init();
-  if(ret)
-  {
-    return ret;
-  }
-
-  if(!m_smsInit)
-  {
-    ret = m_sms.init();
-    if(ret)
-    {
-      return ret;
-    }
-    m_smsInit = true;
-  }
-
-  ret = m_sms.get(number, message, maxLength);
-  if(ret)
-  {
-    return ret;
-  }
-
-  return OK;
-}
-
-int VodafoneK3770::getSMCount(size_t* pCount)
-{
-  int ret = init();
-  if(ret)
-  {
-    return ret;
-  }
-
-  if(!m_smsInit)
-  {
-    ret = m_sms.init();
-    if(ret)
-    {
-      return ret;
-    }
-    m_smsInit = true;
-  }
-
-  ret = m_sms.getCount(pCount);
-  if(ret)
-  {
-    return ret;
-  }
-
-  return OK;
-}
-
-int VodafoneK3770::sendUSSD(const char* command, char* result, size_t maxLength)
-{
-  int ret = init();
-  if(ret)
-  {
-    return ret;
-  }
-
-  if(!m_ussdInit)
-  {
-    ret = m_ussd.init();
-    if(ret)
-    {
-      return ret;
-    }
-    m_ussdInit = true;
-  }
-
-  ret = m_ussd.send(command, result, maxLength);
-  if(ret)
-  {
-    return ret;
-  }
-
-  return OK;
-}
-
-int VodafoneK3770::getLinkState(int* pRssi, LinkMonitor::REGISTRATION_STATE* pRegistrationState, LinkMonitor::BEARER* pBearer)
-{
-  int ret = init();
-  if(ret)
-  {
-    return ret;
-  }
-  
-  if(!m_linkMonitorInit)
-  {
-    ret = m_linkMonitor.init();
-    if(ret)
-    {
-      return ret;
-    }
-    m_linkMonitorInit = true;
-  }
-
-  ret = m_linkMonitor.getState(pRssi, pRegistrationState, pBearer);
-  if(ret)
-  {
-    return ret;
-  }
-
-  return OK;
-}
-
-
-ATCommandsInterface* VodafoneK3770::getATCommandsInterface()
-{
-  return &m_at;
-}
-
-int VodafoneK3770::init()
-{
-  if( !m_dongleConnected )
-  {
-    m_dongleConnected = true;
-    while( !m_dongle.connected() )
-    {
-      m_dongle.tryConnect();
-      Thread::wait(10);
-    }
-  }
-
-  if(m_atOpen)
-  {
-    return OK;
-  }
-
-  DBG("Starting AT thread if needed");
-  int ret = m_at.open();
-  if(ret)
-  {
-    return ret;
-  }
-
-  DBG("Sending initialisation commands");
-  ret = m_at.init();
-  if(ret)
-  {
-    return ret;
-  }
-
-  if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_VODAFONEK3770)
-  {
-    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 if(m_dongle.getDongleType() == WAN_DONGLE_TYPE_VODAFONEK3772Z)
-  {
-    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;
-
-  //Wait for network registration
-  CREGProcessor cregProcessor;
-  do
-  {
-    DBG("Waiting for network registration");
-    ret = m_at.execute("AT+CREG?", &cregProcessor, &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)
-    {
-      Thread::wait(3000);
-    }
-  } while(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING);
-  if(cregProcessor.getStatus() == CREGProcessor::STATUS_FAILED)
-  {
-    ERR("Registration denied");
-    return NET_AUTH;
-  }
-
-  m_atOpen = true;
-
-  return OK;
-}
-
-
-