Dmitry Pakhomenko / VodafoneUSBModem

Dependencies:   Socket USBHostWANDongle lwip-sys lwip

Fork of VodafoneUSBModem by mbed official

Committer:
donatien
Date:
Thu May 24 16:40:40 2012 +0000
Revision:
0:3b2f052c333b
Initial Commit

Who changed what in which revision?

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