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.

Committer:
donatien
Date:
Wed Jul 11 21:25:03 2012 +0000
Revision:
12:66dc2c8eba2d
Parent:
11:565b2ec40dea
Child:
18:1789a11d1892
Link Monitoring / Dual serial port support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 8:04b6a042595f 1 /* PPPIPInterface.cpp */
donatien 8:04b6a042595f 2 /*
donatien 8:04b6a042595f 3 Copyright (C) 2012 ARM Limited.
donatien 8:04b6a042595f 4
donatien 8:04b6a042595f 5 Permission is hereby granted, free of charge, to any person obtaining a copy of
donatien 8:04b6a042595f 6 this software and associated documentation files (the "Software"), to deal in
donatien 8:04b6a042595f 7 the Software without restriction, including without limitation the rights to
donatien 8:04b6a042595f 8 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
donatien 8:04b6a042595f 9 of the Software, and to permit persons to whom the Software is furnished to do
donatien 8:04b6a042595f 10 so, subject to the following conditions:
donatien 8:04b6a042595f 11
donatien 8:04b6a042595f 12 The above copyright notice and this permission notice shall be included in all
donatien 8:04b6a042595f 13 copies or substantial portions of the Software.
donatien 8:04b6a042595f 14
donatien 8:04b6a042595f 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
donatien 8:04b6a042595f 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
donatien 8:04b6a042595f 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
donatien 8:04b6a042595f 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
donatien 8:04b6a042595f 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
donatien 8:04b6a042595f 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
donatien 8:04b6a042595f 21 SOFTWARE.
donatien 8:04b6a042595f 22 */
donatien 8:04b6a042595f 23
donatien 12:66dc2c8eba2d 24 #define MSISDN "*99#"
donatien 12:66dc2c8eba2d 25
donatien 12:66dc2c8eba2d 26 #define CONNECT_CMD "ATD " MSISDN "\x0D"
donatien 12:66dc2c8eba2d 27 #define EXPECTED_RESP CONNECT_CMD "\x0D" "\x0A" "CONNECT" "\x0D" "\x0A"
donatien 12:66dc2c8eba2d 28 #define OK_RESP
donatien 12:66dc2c8eba2d 29
donatien 12:66dc2c8eba2d 30 #define __DEBUG__ 0 //Maximum verbosity
donatien 8:04b6a042595f 31 #ifndef __MODULE__
donatien 8:04b6a042595f 32 #define __MODULE__ "PPPIPInterface.cpp"
donatien 8:04b6a042595f 33 #endif
donatien 8:04b6a042595f 34
donatien 8:04b6a042595f 35 #include "core/fwk.h"
donatien 8:04b6a042595f 36 #include "rtos.h"
donatien 8:04b6a042595f 37
donatien 8:04b6a042595f 38 #include "PPPIPInterface.h"
donatien 8:04b6a042595f 39
donatien 8:04b6a042595f 40 extern "C" {
donatien 8:04b6a042595f 41 #include "lwip/ip_addr.h"
donatien 8:04b6a042595f 42 #include "lwip/inet.h"
donatien 8:04b6a042595f 43 #include "netif/ppp/ppp.h"
donatien 8:04b6a042595f 44 }
donatien 8:04b6a042595f 45
donatien 8:04b6a042595f 46 PPPIPInterface::PPPIPInterface(IOStream* pStream) : LwIPInterface(), m_linkStatusSphre(1), m_pppErrCode(0), m_pStream(pStream), m_streamAvail(true), m_pppd(-1)
donatien 8:04b6a042595f 47 {
donatien 8:04b6a042595f 48 m_linkStatusSphre.wait();
donatien 8:04b6a042595f 49 }
donatien 8:04b6a042595f 50
donatien 8:04b6a042595f 51 /*virtual*/ PPPIPInterface::~PPPIPInterface()
donatien 8:04b6a042595f 52 {
donatien 8:04b6a042595f 53
donatien 8:04b6a042595f 54 }
donatien 8:04b6a042595f 55
donatien 8:04b6a042595f 56 /*virtual*/ int PPPIPInterface::init() //Init PPP-specific stuff, create the right bindings, etc
donatien 8:04b6a042595f 57 {
donatien 8:04b6a042595f 58 DBG("Initializing LwIP");
donatien 8:04b6a042595f 59 LwIPInterface::init(); //Init LwIP, NOT including PPP
donatien 8:04b6a042595f 60 DBG("Initializing PPP");
donatien 8:04b6a042595f 61 pppInit();
donatien 8:04b6a042595f 62 DBG("Done");
donatien 8:04b6a042595f 63 return OK;
donatien 8:04b6a042595f 64 }
donatien 8:04b6a042595f 65
donatien 8:04b6a042595f 66 int PPPIPInterface::setup(const char* user, const char* pw)
donatien 8:04b6a042595f 67 {
donatien 8:04b6a042595f 68 DBG("Configuring PPP authentication method");
donatien 8:04b6a042595f 69 pppSetAuth(PPPAUTHTYPE_ANY, user, pw);
donatien 8:04b6a042595f 70 DBG("Done");
donatien 8:04b6a042595f 71 return OK;
donatien 8:04b6a042595f 72 }
donatien 8:04b6a042595f 73
donatien 12:66dc2c8eba2d 74 /*virtual*/ int PPPIPInterface::connect()
donatien 8:04b6a042595f 75 {
donatien 9:3f077dde13c9 76 int ret;
donatien 9:3f077dde13c9 77 char buf[32];
donatien 9:3f077dde13c9 78 size_t len;
donatien 8:04b6a042595f 79 DBG("Trying to connect with PPP");
donatien 9:3f077dde13c9 80
donatien 9:3f077dde13c9 81 do //Clear buf
donatien 9:3f077dde13c9 82 {
donatien 12:66dc2c8eba2d 83 ret = m_pStream->read((uint8_t*)buf, &len, 32, 0);
donatien 9:3f077dde13c9 84 } while( (ret == OK) && (len > 0) );
donatien 9:3f077dde13c9 85
donatien 12:66dc2c8eba2d 86 DBG("Sending %s", CONNECT_CMD);
donatien 9:3f077dde13c9 87
donatien 12:66dc2c8eba2d 88 ret = m_pStream->write((uint8_t*)CONNECT_CMD, strlen(CONNECT_CMD), osWaitForever);
donatien 9:3f077dde13c9 89 if( ret != OK )
donatien 9:3f077dde13c9 90 {
donatien 9:3f077dde13c9 91 return NET_UNKNOWN;
donatien 9:3f077dde13c9 92 }
donatien 9:3f077dde13c9 93
donatien 12:66dc2c8eba2d 94 DBG("Expect %s [len %d]", EXPECTED_RESP, strlen(EXPECTED_RESP));
donatien 12:66dc2c8eba2d 95
donatien 12:66dc2c8eba2d 96 len = 0;
donatien 12:66dc2c8eba2d 97 while(len < strlen(EXPECTED_RESP))
donatien 9:3f077dde13c9 98 {
donatien 12:66dc2c8eba2d 99 size_t readLen;
donatien 12:66dc2c8eba2d 100 ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(EXPECTED_RESP) - len, 10000);
donatien 12:66dc2c8eba2d 101 if( ret != OK )
donatien 12:66dc2c8eba2d 102 {
donatien 9:3f077dde13c9 103 return NET_UNKNOWN;
donatien 12:66dc2c8eba2d 104 }
donatien 12:66dc2c8eba2d 105 len += readLen;
donatien 9:3f077dde13c9 106 }
donatien 9:3f077dde13c9 107
donatien 12:66dc2c8eba2d 108 buf[len]=0;
donatien 12:66dc2c8eba2d 109
donatien 12:66dc2c8eba2d 110 DBG("Got %s[len %d]", buf, len);
donatien 12:66dc2c8eba2d 111
donatien 12:66dc2c8eba2d 112 if( memcmp(EXPECTED_RESP, buf, strlen(EXPECTED_RESP)) != 0 )
donatien 9:3f077dde13c9 113 {
donatien 9:3f077dde13c9 114 //Discard buffer
donatien 9:3f077dde13c9 115 do //Clear buf
donatien 9:3f077dde13c9 116 {
donatien 12:66dc2c8eba2d 117 ret = m_pStream->read((uint8_t*)buf, &len, 32, 0);
donatien 9:3f077dde13c9 118 } while( (ret == OK) && (len > 0) );
donatien 9:3f077dde13c9 119 return NET_CONN;
donatien 9:3f077dde13c9 120 }
donatien 9:3f077dde13c9 121
donatien 9:3f077dde13c9 122 DBG("Transport link open");
donatien 8:04b6a042595f 123 m_linkStatusSphre.wait(0);
donatien 8:04b6a042595f 124 if((m_pppd != -1) && (m_pppErrCode == 0)) //Already connected
donatien 8:04b6a042595f 125 {
donatien 8:04b6a042595f 126 return NET_INVALID;
donatien 8:04b6a042595f 127 }
donatien 12:66dc2c8eba2d 128
donatien 12:66dc2c8eba2d 129 ret = pppOverSerialOpen(this, PPPIPInterface::linkStatusCb, this);
donatien 8:04b6a042595f 130 if(ret < 0)
donatien 8:04b6a042595f 131 {
donatien 8:04b6a042595f 132 switch(ret)
donatien 8:04b6a042595f 133 {
donatien 8:04b6a042595f 134 case PPPERR_OPEN:
donatien 8:04b6a042595f 135 default:
donatien 8:04b6a042595f 136 return NET_FULL; //All available resources are already used
donatien 8:04b6a042595f 137 }
donatien 8:04b6a042595f 138 }
donatien 8:04b6a042595f 139 m_pppd = ret; //PPP descriptor
donatien 8:04b6a042595f 140 m_linkStatusSphre.wait(); //Block indefinitely; there should be a timeout there
donatien 8:04b6a042595f 141 if(m_pppErrCode != PPPERR_NONE)
donatien 8:04b6a042595f 142 {
donatien 8:04b6a042595f 143 m_pppd = -1;
donatien 8:04b6a042595f 144 }
donatien 8:04b6a042595f 145 switch(m_pppErrCode)
donatien 8:04b6a042595f 146 {
donatien 8:04b6a042595f 147 case PPPERR_NONE: //Connected OK
donatien 8:04b6a042595f 148 return OK;
donatien 8:04b6a042595f 149 case PPPERR_CONNECT: //Connection lost
donatien 8:04b6a042595f 150 return NET_INTERRUPTED;
donatien 8:04b6a042595f 151 case PPPERR_AUTHFAIL: //Authentication failed
donatien 8:04b6a042595f 152 return NET_AUTH;
donatien 8:04b6a042595f 153 case PPPERR_PROTOCOL: //Protocol error
donatien 8:04b6a042595f 154 return NET_PROTOCOL;
donatien 8:04b6a042595f 155 default:
donatien 8:04b6a042595f 156 return NET_UNKNOWN;
donatien 8:04b6a042595f 157 }
donatien 8:04b6a042595f 158 }
donatien 8:04b6a042595f 159
donatien 8:04b6a042595f 160 /*virtual*/ int PPPIPInterface::disconnect()
donatien 8:04b6a042595f 161 {
donatien 8:04b6a042595f 162 int ret = m_linkStatusSphre.wait(0);
donatien 8:04b6a042595f 163 if(ret > 0) //Already disconnected?
donatien 8:04b6a042595f 164 {
donatien 8:04b6a042595f 165 m_pppd = -1; //Discard PPP descriptor
donatien 8:04b6a042595f 166 switch(m_pppErrCode)
donatien 8:04b6a042595f 167 {
donatien 8:04b6a042595f 168 case PPPERR_CONNECT: //Connection terminated
donatien 8:04b6a042595f 169 case PPPERR_AUTHFAIL: //Authentication failed
donatien 8:04b6a042595f 170 case PPPERR_PROTOCOL: //Protocol error
donatien 8:04b6a042595f 171 case PPPERR_USER:
donatien 8:04b6a042595f 172 return OK;
donatien 8:04b6a042595f 173 default:
donatien 8:04b6a042595f 174 return NET_UNKNOWN;
donatien 8:04b6a042595f 175 }
donatien 8:04b6a042595f 176 }
donatien 8:04b6a042595f 177 else
donatien 8:04b6a042595f 178 {
donatien 8:04b6a042595f 179 if(m_pppd == -1)
donatien 8:04b6a042595f 180 {
donatien 8:04b6a042595f 181 return NET_INVALID;
donatien 8:04b6a042595f 182 }
donatien 8:04b6a042595f 183 pppClose(m_pppd);
donatien 8:04b6a042595f 184 do
donatien 8:04b6a042595f 185 {
donatien 8:04b6a042595f 186 m_linkStatusSphre.wait(); //Block indefinitely; there should be a timeout there
donatien 8:04b6a042595f 187 DBG("Received PPP err code %d", m_pppErrCode);
donatien 8:04b6a042595f 188 } while(m_pppErrCode != PPPERR_USER);
donatien 8:04b6a042595f 189 m_pppd = -1; //Discard PPP descriptor
donatien 8:04b6a042595f 190 }
donatien 8:04b6a042595f 191 return OK;
donatien 8:04b6a042595f 192 }
donatien 8:04b6a042595f 193
donatien 8:04b6a042595f 194 /*static*/ void PPPIPInterface::linkStatusCb(void *ctx, int errCode, void *arg) //PPP link status
donatien 8:04b6a042595f 195 {
donatien 8:04b6a042595f 196 PPPIPInterface* pIf = (PPPIPInterface*)ctx;
donatien 8:04b6a042595f 197 struct ppp_addrs* addrs = (struct ppp_addrs*) arg;
donatien 8:04b6a042595f 198
donatien 8:04b6a042595f 199 switch(errCode)
donatien 8:04b6a042595f 200 {
donatien 8:04b6a042595f 201 case PPPERR_NONE:
donatien 8:04b6a042595f 202 WARN("Connected via PPP.");
donatien 8:04b6a042595f 203 DBG("Local IP address: %s", inet_ntoa(addrs->our_ipaddr));
donatien 8:04b6a042595f 204 DBG("Netmask: %s", inet_ntoa(addrs->netmask));
donatien 8:04b6a042595f 205 DBG("Remote IP address: %s", inet_ntoa(addrs->his_ipaddr));
donatien 8:04b6a042595f 206 DBG("Primary DNS: %s", inet_ntoa(addrs->dns1));
donatien 8:04b6a042595f 207 DBG("Secondary DNS: %s", inet_ntoa(addrs->dns2));
donatien 10:21a6f09d5631 208 pIf->setConnected(true);
donatien 10:21a6f09d5631 209 pIf->setIPAddress(inet_ntoa(addrs->our_ipaddr));
donatien 8:04b6a042595f 210 break;
donatien 8:04b6a042595f 211 case PPPERR_CONNECT: //Connection lost
donatien 8:04b6a042595f 212 WARN("Connection lost/terminated");
donatien 10:21a6f09d5631 213 pIf->setConnected(false);
donatien 8:04b6a042595f 214 break;
donatien 8:04b6a042595f 215 case PPPERR_AUTHFAIL: //Authentication failed
donatien 8:04b6a042595f 216 WARN("Authentication failed");
donatien 10:21a6f09d5631 217 pIf->setConnected(false);
donatien 8:04b6a042595f 218 break;
donatien 8:04b6a042595f 219 case PPPERR_PROTOCOL: //Protocol error
donatien 8:04b6a042595f 220 WARN("Protocol error");
donatien 10:21a6f09d5631 221 pIf->setConnected(false);
donatien 8:04b6a042595f 222 break;
donatien 8:04b6a042595f 223 case PPPERR_USER:
donatien 8:04b6a042595f 224 WARN("Disconnected by user");
donatien 10:21a6f09d5631 225 pIf->setConnected(false);
donatien 8:04b6a042595f 226 break;
donatien 8:04b6a042595f 227 default:
donatien 8:04b6a042595f 228 WARN("Unknown error (%d)", errCode);
donatien 10:21a6f09d5631 229 pIf->setConnected(false);
donatien 8:04b6a042595f 230 break;
donatien 8:04b6a042595f 231 }
donatien 8:04b6a042595f 232
donatien 8:04b6a042595f 233 pIf->m_linkStatusSphre.wait(0); //If previous event has not been handled, "delete" it now
donatien 8:04b6a042595f 234 pIf->m_pppErrCode = errCode;
donatien 8:04b6a042595f 235 pIf->m_linkStatusSphre.release();
donatien 8:04b6a042595f 236 }
donatien 8:04b6a042595f 237
donatien 8:04b6a042595f 238 //LwIP PPP implementation
donatien 8:04b6a042595f 239 extern "C"
donatien 8:04b6a042595f 240 {
donatien 8:04b6a042595f 241
donatien 8:04b6a042595f 242 /**
donatien 8:04b6a042595f 243 * Writes to the serial device.
donatien 8:04b6a042595f 244 *
donatien 8:04b6a042595f 245 * @param fd serial device handle
donatien 8:04b6a042595f 246 * @param data pointer to data to send
donatien 8:04b6a042595f 247 * @param len length (in bytes) of data to send
donatien 8:04b6a042595f 248 * @return number of bytes actually sent
donatien 8:04b6a042595f 249 *
donatien 8:04b6a042595f 250 * @note This function will block until all data can be sent.
donatien 8:04b6a042595f 251 */
donatien 8:04b6a042595f 252 u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len)
donatien 8:04b6a042595f 253 {
donatien 8:04b6a042595f 254 DBG("sio_write");
donatien 8:04b6a042595f 255 PPPIPInterface* pIf = (PPPIPInterface*)fd;
donatien 8:04b6a042595f 256 int ret;
donatien 8:04b6a042595f 257 if(!pIf->m_streamAvail) //If stream is not available (it is a shared resource) don't go further
donatien 8:04b6a042595f 258 {
donatien 8:04b6a042595f 259 return 0;
donatien 8:04b6a042595f 260 }
donatien 8:04b6a042595f 261 ret = pIf->m_pStream->write(data, len, osWaitForever); //Blocks until all data is sent or an error happens
donatien 8:04b6a042595f 262 if(ret != OK)
donatien 8:04b6a042595f 263 {
donatien 8:04b6a042595f 264 return 0;
donatien 8:04b6a042595f 265 }
donatien 8:04b6a042595f 266 return len;
donatien 8:04b6a042595f 267 }
donatien 8:04b6a042595f 268
donatien 8:04b6a042595f 269 /**
donatien 8:04b6a042595f 270 * Reads from the serial device.
donatien 8:04b6a042595f 271 *
donatien 8:04b6a042595f 272 * @param fd serial device handle
donatien 8:04b6a042595f 273 * @param data pointer to data buffer for receiving
donatien 8:04b6a042595f 274 * @param len maximum length (in bytes) of data to receive
donatien 8:04b6a042595f 275 * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
donatien 8:04b6a042595f 276 *
donatien 8:04b6a042595f 277 * @note This function will block until data can be received. The blocking
donatien 8:04b6a042595f 278 * can be cancelled by calling sio_read_abort().
donatien 8:04b6a042595f 279 */
donatien 8:04b6a042595f 280 u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len)
donatien 8:04b6a042595f 281 {
donatien 8:04b6a042595f 282 DBG("sio_read");
donatien 8:04b6a042595f 283 PPPIPInterface* pIf = (PPPIPInterface*)fd;
donatien 8:04b6a042595f 284 int ret;
donatien 8:04b6a042595f 285 size_t readLen;
donatien 8:04b6a042595f 286 if(!pIf->m_streamAvail) //If stream is not available (it is a shared resource) don't go further
donatien 8:04b6a042595f 287 {
donatien 8:04b6a042595f 288 WARN("EXIT NOT AVAIL");
donatien 8:04b6a042595f 289 return 0;
donatien 8:04b6a042595f 290 }
donatien 8:04b6a042595f 291 ret = pIf->m_pStream->read(data, &readLen, len, osWaitForever); //Blocks until some data is received or an error happens
donatien 8:04b6a042595f 292 if(ret != OK)
donatien 8:04b6a042595f 293 {
donatien 8:04b6a042595f 294 return 0;
donatien 8:04b6a042595f 295 }
donatien 8:04b6a042595f 296 DBG("ret");
donatien 8:04b6a042595f 297 return readLen;
donatien 8:04b6a042595f 298 }
donatien 8:04b6a042595f 299
donatien 8:04b6a042595f 300 /**
donatien 8:04b6a042595f 301 * Aborts a blocking sio_read() call.
donatien 8:04b6a042595f 302 *
donatien 8:04b6a042595f 303 * @param fd serial device handle
donatien 8:04b6a042595f 304 */
donatien 8:04b6a042595f 305 void sio_read_abort(sio_fd_t fd)
donatien 8:04b6a042595f 306 {
donatien 8:04b6a042595f 307 DBG("sio_read_abort");
donatien 8:04b6a042595f 308 PPPIPInterface* pIf = (PPPIPInterface*)fd;
donatien 8:04b6a042595f 309 if(!pIf->m_streamAvail) //If stream is not available (it is a shared resource) don't go further
donatien 8:04b6a042595f 310 {
donatien 8:04b6a042595f 311 return;
donatien 8:04b6a042595f 312 }
donatien 8:04b6a042595f 313 pIf->m_pStream->abortRead();
donatien 8:04b6a042595f 314 DBG("ret");
donatien 8:04b6a042595f 315 }
donatien 8:04b6a042595f 316
donatien 8:04b6a042595f 317 }
donatien 8:04b6a042595f 318