Implementation of 3G USB Modem Huawei E372

Dependents:   PYRN

Committer:
clemounet
Date:
Fri Feb 20 17:15:55 2015 +0000
Revision:
1:fbf17fb09581
Child:
2:61ac95f0af72
Add PPP networking

Who changed what in which revision?

UserRevisionLine numberNew contents of line
clemounet 1:fbf17fb09581 1 /* PPPIPInterface.cpp */
clemounet 1:fbf17fb09581 2 /* Copyright (C) 2012 mbed.org, MIT License
clemounet 1:fbf17fb09581 3 *
clemounet 1:fbf17fb09581 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
clemounet 1:fbf17fb09581 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
clemounet 1:fbf17fb09581 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
clemounet 1:fbf17fb09581 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
clemounet 1:fbf17fb09581 8 * furnished to do so, subject to the following conditions:
clemounet 1:fbf17fb09581 9 *
clemounet 1:fbf17fb09581 10 * The above copyright notice and this permission notice shall be included in all copies or
clemounet 1:fbf17fb09581 11 * substantial portions of the Software.
clemounet 1:fbf17fb09581 12 *
clemounet 1:fbf17fb09581 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
clemounet 1:fbf17fb09581 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
clemounet 1:fbf17fb09581 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
clemounet 1:fbf17fb09581 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
clemounet 1:fbf17fb09581 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
clemounet 1:fbf17fb09581 18 */
clemounet 1:fbf17fb09581 19
clemounet 1:fbf17fb09581 20 #define __DEBUG__ 0
clemounet 1:fbf17fb09581 21 #ifndef __MODULE__
clemounet 1:fbf17fb09581 22 #define __MODULE__ "PPPIPInterface.cpp"
clemounet 1:fbf17fb09581 23 #endif
clemounet 1:fbf17fb09581 24
clemounet 1:fbf17fb09581 25 #include "dbg.h"
clemounet 1:fbf17fb09581 26 #define DBG(x, ...) USB_DBG(x, __VA_ARGS__)
clemounet 1:fbf17fb09581 27
clemounet 1:fbf17fb09581 28 #include "core/fwk.h"
clemounet 1:fbf17fb09581 29 #include "rtos.h"
clemounet 1:fbf17fb09581 30
clemounet 1:fbf17fb09581 31 #include <cstdio>
clemounet 1:fbf17fb09581 32 using std::sscanf;
clemounet 1:fbf17fb09581 33
clemounet 1:fbf17fb09581 34 #include "PPPIPInterface.h"
clemounet 1:fbf17fb09581 35
clemounet 1:fbf17fb09581 36 #define MSISDN "*99#"
clemounet 1:fbf17fb09581 37
clemounet 1:fbf17fb09581 38 #define CONNECT_CMD "ATD " MSISDN "\x0D"
clemounet 1:fbf17fb09581 39 #define EXPECTED_RESP CONNECT_CMD "\x0D" "\x0A" "CONNECT" "\x0D" "\x0A"
clemounet 1:fbf17fb09581 40 #define EXPECTED_RESP_DATARATE CONNECT_CMD "\x0D" "\x0A" "CONNECT %d" "\x0D" "\x0A"
clemounet 1:fbf17fb09581 41 #define EXPECTED_RESP_MIN_LEN 20
clemounet 1:fbf17fb09581 42 #define OK_RESP "\x0D" "\x0A" "OK" "\x0D" "\x0A"
clemounet 1:fbf17fb09581 43 #define ESCAPE_SEQ "+++"
clemounet 1:fbf17fb09581 44 #define HANGUP_CMD "ATH" "\x0D"
clemounet 1:fbf17fb09581 45 #define NO_CARRIER_RESP "\x0D" "\x0A" "NO CARRIER" "\x0D" "\x0A"
clemounet 1:fbf17fb09581 46 extern "C" {
clemounet 1:fbf17fb09581 47 #include "lwip/ip_addr.h"
clemounet 1:fbf17fb09581 48 #include "lwip/inet.h"
clemounet 1:fbf17fb09581 49 #include "lwip/err.h"
clemounet 1:fbf17fb09581 50 #include "lwip/dns.h"
clemounet 1:fbf17fb09581 51
clemounet 1:fbf17fb09581 52 #include "netif/ppp/ppp.h"
clemounet 1:fbf17fb09581 53 }
clemounet 1:fbf17fb09581 54
clemounet 1:fbf17fb09581 55 PPPIPInterface::PPPIPInterface(IOStream* pStream) : LwIPInterface(), m_linkStatusSphre(1), m_pppErrCode(0), m_pStream(pStream), m_streamAvail(true), m_pppd(-1)
clemounet 1:fbf17fb09581 56 {
clemounet 1:fbf17fb09581 57 m_linkStatusSphre.wait();
clemounet 1:fbf17fb09581 58 }
clemounet 1:fbf17fb09581 59
clemounet 1:fbf17fb09581 60 /*virtual*/ PPPIPInterface::~PPPIPInterface()
clemounet 1:fbf17fb09581 61 {
clemounet 1:fbf17fb09581 62
clemounet 1:fbf17fb09581 63 }
clemounet 1:fbf17fb09581 64
clemounet 1:fbf17fb09581 65 /*virtual*/ int PPPIPInterface::init() //Init PPP-specific stuff, create the right bindings, etc
clemounet 1:fbf17fb09581 66 {
clemounet 1:fbf17fb09581 67 DBG("Initializing LwIP");
clemounet 1:fbf17fb09581 68 LwIPInterface::init(); //Init LwIP, NOT including PPP
clemounet 1:fbf17fb09581 69 DBG("Initializing PPP");
clemounet 1:fbf17fb09581 70 pppInit();
clemounet 1:fbf17fb09581 71 DBG("Done");
clemounet 1:fbf17fb09581 72 return OK;
clemounet 1:fbf17fb09581 73 }
clemounet 1:fbf17fb09581 74
clemounet 1:fbf17fb09581 75 int PPPIPInterface::setup(const char* user, const char* pw)
clemounet 1:fbf17fb09581 76 {
clemounet 1:fbf17fb09581 77 DBG("Configuring PPP authentication method");
clemounet 1:fbf17fb09581 78 pppSetAuth(PPPAUTHTYPE_ANY, user, pw);
clemounet 1:fbf17fb09581 79 DBG("Done");
clemounet 1:fbf17fb09581 80 return OK;
clemounet 1:fbf17fb09581 81 }
clemounet 1:fbf17fb09581 82
clemounet 1:fbf17fb09581 83 /*virtual*/ int PPPIPInterface::connect()
clemounet 1:fbf17fb09581 84 {
clemounet 1:fbf17fb09581 85 int ret;
clemounet 1:fbf17fb09581 86 char buf[32];
clemounet 1:fbf17fb09581 87 size_t len;
clemounet 1:fbf17fb09581 88 DBG("Trying to connect with PPP");
clemounet 1:fbf17fb09581 89
clemounet 1:fbf17fb09581 90 cleanupLink();
clemounet 1:fbf17fb09581 91
clemounet 1:fbf17fb09581 92 DBG("Sending %s", CONNECT_CMD);
clemounet 1:fbf17fb09581 93
clemounet 1:fbf17fb09581 94 ret = m_pStream->write((uint8_t*)CONNECT_CMD, strlen(CONNECT_CMD), osWaitForever);
clemounet 1:fbf17fb09581 95 if( ret != OK )
clemounet 1:fbf17fb09581 96 {
clemounet 1:fbf17fb09581 97 return NET_UNKNOWN;
clemounet 1:fbf17fb09581 98 }
clemounet 1:fbf17fb09581 99
clemounet 1:fbf17fb09581 100 DBG("Expect %s", EXPECTED_RESP);
clemounet 1:fbf17fb09581 101
clemounet 1:fbf17fb09581 102 len = 0;
clemounet 1:fbf17fb09581 103 size_t readLen;
clemounet 1:fbf17fb09581 104 ret = m_pStream->read((uint8_t*)buf + len, &readLen, EXPECTED_RESP_MIN_LEN, 10000);
clemounet 1:fbf17fb09581 105 if( ret != OK )
clemounet 1:fbf17fb09581 106 {
clemounet 1:fbf17fb09581 107 return NET_UNKNOWN;
clemounet 1:fbf17fb09581 108 }
clemounet 1:fbf17fb09581 109 len += readLen;
clemounet 1:fbf17fb09581 110 while( (len < EXPECTED_RESP_MIN_LEN) || (buf[len-1] != LF) )
clemounet 1:fbf17fb09581 111 {
clemounet 1:fbf17fb09581 112 ret = m_pStream->read((uint8_t*)buf + len, &readLen, 1, 10000);
clemounet 1:fbf17fb09581 113 if( ret != OK )
clemounet 1:fbf17fb09581 114 {
clemounet 1:fbf17fb09581 115 return NET_UNKNOWN;
clemounet 1:fbf17fb09581 116 }
clemounet 1:fbf17fb09581 117 len += readLen;
clemounet 1:fbf17fb09581 118 }
clemounet 1:fbf17fb09581 119
clemounet 1:fbf17fb09581 120 buf[len]=0;
clemounet 1:fbf17fb09581 121
clemounet 1:fbf17fb09581 122 DBG("Got %s[len %d]", buf, len);
clemounet 1:fbf17fb09581 123
clemounet 1:fbf17fb09581 124 int datarate = 0;
clemounet 1:fbf17fb09581 125 if( (sscanf( buf, EXPECTED_RESP_DATARATE, &datarate ) != 1) && (strcmp(EXPECTED_RESP, buf) != 0) )
clemounet 1:fbf17fb09581 126 {
clemounet 1:fbf17fb09581 127 //Discard buffer
clemounet 1:fbf17fb09581 128 do //Clear buf
clemounet 1:fbf17fb09581 129 {
clemounet 1:fbf17fb09581 130 ret = m_pStream->read((uint8_t*)buf, &len, 32, 0);
clemounet 1:fbf17fb09581 131 } while( (ret == OK) && (len > 0) );
clemounet 1:fbf17fb09581 132 return NET_CONN;
clemounet 1:fbf17fb09581 133 }
clemounet 1:fbf17fb09581 134
clemounet 1:fbf17fb09581 135 DBG("Transport link open");
clemounet 1:fbf17fb09581 136 if(datarate != 0)
clemounet 1:fbf17fb09581 137 {
clemounet 1:fbf17fb09581 138 DBG("Datarate: %d bps", datarate);
clemounet 1:fbf17fb09581 139 }
clemounet 1:fbf17fb09581 140 m_linkStatusSphre.wait(0);
clemounet 1:fbf17fb09581 141 if((m_pppd != -1) && (m_pppErrCode == 0)) //Already connected
clemounet 1:fbf17fb09581 142 {
clemounet 1:fbf17fb09581 143 return NET_INVALID;
clemounet 1:fbf17fb09581 144 }
clemounet 1:fbf17fb09581 145
clemounet 1:fbf17fb09581 146 ret = pppOverSerialOpen(this, PPPIPInterface::linkStatusCb, this);
clemounet 1:fbf17fb09581 147 if(ret < 0)
clemounet 1:fbf17fb09581 148 {
clemounet 1:fbf17fb09581 149 switch(ret)
clemounet 1:fbf17fb09581 150 {
clemounet 1:fbf17fb09581 151 case PPPERR_OPEN:
clemounet 1:fbf17fb09581 152 default:
clemounet 1:fbf17fb09581 153 return NET_FULL; //All available resources are already used
clemounet 1:fbf17fb09581 154 }
clemounet 1:fbf17fb09581 155 }
clemounet 1:fbf17fb09581 156 m_pppd = ret; //PPP descriptor
clemounet 1:fbf17fb09581 157 m_linkStatusSphre.wait(); //Block indefinitely; there should be a timeout there
clemounet 1:fbf17fb09581 158 if(m_pppErrCode != PPPERR_NONE)
clemounet 1:fbf17fb09581 159 {
clemounet 1:fbf17fb09581 160 m_pppd = -1;
clemounet 1:fbf17fb09581 161 }
clemounet 1:fbf17fb09581 162 switch(m_pppErrCode)
clemounet 1:fbf17fb09581 163 {
clemounet 1:fbf17fb09581 164 case PPPERR_NONE: //Connected OK
clemounet 1:fbf17fb09581 165 return OK;
clemounet 1:fbf17fb09581 166 case PPPERR_CONNECT: //Connection lost
clemounet 1:fbf17fb09581 167 return NET_INTERRUPTED;
clemounet 1:fbf17fb09581 168 case PPPERR_AUTHFAIL: //Authentication failed
clemounet 1:fbf17fb09581 169 return NET_AUTH;
clemounet 1:fbf17fb09581 170 case PPPERR_PROTOCOL: //Protocol error
clemounet 1:fbf17fb09581 171 return NET_PROTOCOL;
clemounet 1:fbf17fb09581 172 default:
clemounet 1:fbf17fb09581 173 return NET_UNKNOWN;
clemounet 1:fbf17fb09581 174 }
clemounet 1:fbf17fb09581 175 }
clemounet 1:fbf17fb09581 176
clemounet 1:fbf17fb09581 177 /*virtual*/ int PPPIPInterface::disconnect()
clemounet 1:fbf17fb09581 178 {
clemounet 1:fbf17fb09581 179 int ret = m_linkStatusSphre.wait(0);
clemounet 1:fbf17fb09581 180 if(ret > 0) //Already disconnected?
clemounet 1:fbf17fb09581 181 {
clemounet 1:fbf17fb09581 182 m_pppd = -1; //Discard PPP descriptor
clemounet 1:fbf17fb09581 183 switch(m_pppErrCode)
clemounet 1:fbf17fb09581 184 {
clemounet 1:fbf17fb09581 185 case PPPERR_CONNECT: //Connection terminated
clemounet 1:fbf17fb09581 186 case PPPERR_AUTHFAIL: //Authentication failed
clemounet 1:fbf17fb09581 187 case PPPERR_PROTOCOL: //Protocol error
clemounet 1:fbf17fb09581 188 case PPPERR_USER:
clemounet 1:fbf17fb09581 189 return OK;
clemounet 1:fbf17fb09581 190 default:
clemounet 1:fbf17fb09581 191 return NET_UNKNOWN;
clemounet 1:fbf17fb09581 192 }
clemounet 1:fbf17fb09581 193 }
clemounet 1:fbf17fb09581 194 else
clemounet 1:fbf17fb09581 195 {
clemounet 1:fbf17fb09581 196 if(m_pppd == -1)
clemounet 1:fbf17fb09581 197 {
clemounet 1:fbf17fb09581 198 return NET_INVALID;
clemounet 1:fbf17fb09581 199 }
clemounet 1:fbf17fb09581 200 pppClose(m_pppd);
clemounet 1:fbf17fb09581 201 do
clemounet 1:fbf17fb09581 202 {
clemounet 1:fbf17fb09581 203 m_linkStatusSphre.wait(); //Block indefinitely; there should be a timeout there
clemounet 1:fbf17fb09581 204 DBG("Received PPP err code %d", m_pppErrCode);
clemounet 1:fbf17fb09581 205 } while(m_pppErrCode != PPPERR_USER);
clemounet 1:fbf17fb09581 206 m_pppd = -1; //Discard PPP descriptor
clemounet 1:fbf17fb09581 207 }
clemounet 1:fbf17fb09581 208
clemounet 1:fbf17fb09581 209 DBG("Sending %s", ESCAPE_SEQ);
clemounet 1:fbf17fb09581 210
clemounet 1:fbf17fb09581 211 ret = m_pStream->write((uint8_t*)ESCAPE_SEQ, strlen(ESCAPE_SEQ), osWaitForever);
clemounet 1:fbf17fb09581 212 if( ret != OK )
clemounet 1:fbf17fb09581 213 {
clemounet 1:fbf17fb09581 214 return NET_UNKNOWN;
clemounet 1:fbf17fb09581 215 }
clemounet 1:fbf17fb09581 216
clemounet 1:fbf17fb09581 217 cleanupLink();
clemounet 1:fbf17fb09581 218
clemounet 1:fbf17fb09581 219 return OK;
clemounet 1:fbf17fb09581 220 }
clemounet 1:fbf17fb09581 221
clemounet 1:fbf17fb09581 222
clemounet 1:fbf17fb09581 223 int PPPIPInterface::cleanupLink()
clemounet 1:fbf17fb09581 224 {
clemounet 1:fbf17fb09581 225 int ret;
clemounet 1:fbf17fb09581 226 char buf[32];
clemounet 1:fbf17fb09581 227 size_t len;
clemounet 1:fbf17fb09581 228
clemounet 1:fbf17fb09581 229 do //Clear buf
clemounet 1:fbf17fb09581 230 {
clemounet 1:fbf17fb09581 231 ret = m_pStream->read((uint8_t*)buf, &len, 32, 100);
clemounet 1:fbf17fb09581 232 if(ret == OK)
clemounet 1:fbf17fb09581 233 {
clemounet 1:fbf17fb09581 234 buf[len] = '\0';
clemounet 1:fbf17fb09581 235 DBG("Got %s", buf);
clemounet 1:fbf17fb09581 236 }
clemounet 1:fbf17fb09581 237 } while( (ret == OK) && (len > 0) );
clemounet 1:fbf17fb09581 238
clemounet 1:fbf17fb09581 239 DBG("Sending %s", HANGUP_CMD);
clemounet 1:fbf17fb09581 240
clemounet 1:fbf17fb09581 241 ret = m_pStream->write((uint8_t*)HANGUP_CMD, strlen(HANGUP_CMD), osWaitForever);
clemounet 1:fbf17fb09581 242 if( ret != OK )
clemounet 1:fbf17fb09581 243 {
clemounet 1:fbf17fb09581 244 return NET_UNKNOWN;
clemounet 1:fbf17fb09581 245 }
clemounet 1:fbf17fb09581 246
clemounet 1:fbf17fb09581 247 size_t readLen;
clemounet 1:fbf17fb09581 248
clemounet 1:fbf17fb09581 249 //Hangup
clemounet 1:fbf17fb09581 250 DBG("Expect %s", HANGUP_CMD);
clemounet 1:fbf17fb09581 251
clemounet 1:fbf17fb09581 252 len = 0;
clemounet 1:fbf17fb09581 253 while( len < strlen(HANGUP_CMD) )
clemounet 1:fbf17fb09581 254 {
clemounet 1:fbf17fb09581 255 ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(HANGUP_CMD) - len, 100);
clemounet 1:fbf17fb09581 256 if( ret != OK )
clemounet 1:fbf17fb09581 257 {
clemounet 1:fbf17fb09581 258 break;
clemounet 1:fbf17fb09581 259 }
clemounet 1:fbf17fb09581 260 len += readLen;
clemounet 1:fbf17fb09581 261 /////
clemounet 1:fbf17fb09581 262 buf[len]=0;
clemounet 1:fbf17fb09581 263 DBG("Got %s", buf);
clemounet 1:fbf17fb09581 264 }
clemounet 1:fbf17fb09581 265
clemounet 1:fbf17fb09581 266 buf[len]=0;
clemounet 1:fbf17fb09581 267
clemounet 1:fbf17fb09581 268 DBG("Got %s[len %d]", buf, len);
clemounet 1:fbf17fb09581 269
clemounet 1:fbf17fb09581 270 //OK response
clemounet 1:fbf17fb09581 271 DBG("Expect %s", OK_RESP);
clemounet 1:fbf17fb09581 272
clemounet 1:fbf17fb09581 273 len = 0;
clemounet 1:fbf17fb09581 274 while( len < strlen(OK_RESP) )
clemounet 1:fbf17fb09581 275 {
clemounet 1:fbf17fb09581 276 ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(OK_RESP) - len, 100);
clemounet 1:fbf17fb09581 277 if( ret != OK )
clemounet 1:fbf17fb09581 278 {
clemounet 1:fbf17fb09581 279 break;
clemounet 1:fbf17fb09581 280 }
clemounet 1:fbf17fb09581 281 len += readLen;
clemounet 1:fbf17fb09581 282 /////
clemounet 1:fbf17fb09581 283 buf[len]=0;
clemounet 1:fbf17fb09581 284 DBG("Got %s", buf);
clemounet 1:fbf17fb09581 285 }
clemounet 1:fbf17fb09581 286
clemounet 1:fbf17fb09581 287 buf[len]=0;
clemounet 1:fbf17fb09581 288
clemounet 1:fbf17fb09581 289 DBG("Got %s[len %d]", buf, len);
clemounet 1:fbf17fb09581 290
clemounet 1:fbf17fb09581 291 //NO CARRIER event
clemounet 1:fbf17fb09581 292 DBG("Expect %s", NO_CARRIER_RESP);
clemounet 1:fbf17fb09581 293
clemounet 1:fbf17fb09581 294 len = 0;
clemounet 1:fbf17fb09581 295 while( len < strlen(NO_CARRIER_RESP) )
clemounet 1:fbf17fb09581 296 {
clemounet 1:fbf17fb09581 297 ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(NO_CARRIER_RESP) - len, 100);
clemounet 1:fbf17fb09581 298 if( ret != OK )
clemounet 1:fbf17fb09581 299 {
clemounet 1:fbf17fb09581 300 break;
clemounet 1:fbf17fb09581 301 }
clemounet 1:fbf17fb09581 302 len += readLen;
clemounet 1:fbf17fb09581 303 /////
clemounet 1:fbf17fb09581 304 buf[len]=0;
clemounet 1:fbf17fb09581 305 DBG("Got %s", buf);
clemounet 1:fbf17fb09581 306 }
clemounet 1:fbf17fb09581 307
clemounet 1:fbf17fb09581 308 buf[len]=0;
clemounet 1:fbf17fb09581 309
clemounet 1:fbf17fb09581 310 DBG("Got %s[len %d]", buf, len);
clemounet 1:fbf17fb09581 311
clemounet 1:fbf17fb09581 312 do //Clear buf
clemounet 1:fbf17fb09581 313 {
clemounet 1:fbf17fb09581 314 ret = m_pStream->read((uint8_t*)buf, &len, 32, 100);
clemounet 1:fbf17fb09581 315 if(ret == OK)
clemounet 1:fbf17fb09581 316 {
clemounet 1:fbf17fb09581 317 buf[len] = '\0';
clemounet 1:fbf17fb09581 318 DBG("Got %s", buf);
clemounet 1:fbf17fb09581 319 }
clemounet 1:fbf17fb09581 320 } while( (ret == OK) && (len > 0) );
clemounet 1:fbf17fb09581 321
clemounet 1:fbf17fb09581 322
clemounet 1:fbf17fb09581 323 return OK;
clemounet 1:fbf17fb09581 324 }
clemounet 1:fbf17fb09581 325
clemounet 1:fbf17fb09581 326 /*static*/ void PPPIPInterface::linkStatusCb(void *ctx, int errCode, void *arg) //PPP link status
clemounet 1:fbf17fb09581 327 {
clemounet 1:fbf17fb09581 328 PPPIPInterface* pIf = (PPPIPInterface*)ctx;
clemounet 1:fbf17fb09581 329 struct ppp_addrs* addrs = (struct ppp_addrs*) arg;
clemounet 1:fbf17fb09581 330
clemounet 1:fbf17fb09581 331 switch(errCode)
clemounet 1:fbf17fb09581 332 {
clemounet 1:fbf17fb09581 333 case PPPERR_NONE:
clemounet 1:fbf17fb09581 334 WARN("Connected via PPP.");
clemounet 1:fbf17fb09581 335 DBG("Local IP address: %s", inet_ntoa(addrs->our_ipaddr));
clemounet 1:fbf17fb09581 336 DBG("Netmask: %s", inet_ntoa(addrs->netmask));
clemounet 1:fbf17fb09581 337 DBG("Remote IP address: %s", inet_ntoa(addrs->his_ipaddr));
clemounet 1:fbf17fb09581 338 DBG("Primary DNS: %s", inet_ntoa(addrs->dns1));
clemounet 1:fbf17fb09581 339 DBG("Secondary DNS: %s", inet_ntoa(addrs->dns2));
clemounet 1:fbf17fb09581 340 //Setup DNS
clemounet 1:fbf17fb09581 341 if (addrs->dns1.addr != 0)
clemounet 1:fbf17fb09581 342 {
clemounet 1:fbf17fb09581 343 dns_setserver(0, (struct ip_addr*)&(addrs->dns1));
clemounet 1:fbf17fb09581 344 }
clemounet 1:fbf17fb09581 345 if (addrs->dns2.addr != 0)
clemounet 1:fbf17fb09581 346 {
clemounet 1:fbf17fb09581 347 dns_setserver(1, (struct ip_addr*)&(addrs->dns1));
clemounet 1:fbf17fb09581 348 }
clemounet 1:fbf17fb09581 349
clemounet 1:fbf17fb09581 350 pIf->setConnected(true);
clemounet 1:fbf17fb09581 351 pIf->setIPAddress(inet_ntoa(addrs->our_ipaddr));
clemounet 1:fbf17fb09581 352 break;
clemounet 1:fbf17fb09581 353 case PPPERR_CONNECT: //Connection lost
clemounet 1:fbf17fb09581 354 WARN("Connection lost/terminated");
clemounet 1:fbf17fb09581 355 pIf->setConnected(false);
clemounet 1:fbf17fb09581 356 break;
clemounet 1:fbf17fb09581 357 case PPPERR_AUTHFAIL: //Authentication failed
clemounet 1:fbf17fb09581 358 WARN("Authentication failed");
clemounet 1:fbf17fb09581 359 pIf->setConnected(false);
clemounet 1:fbf17fb09581 360 break;
clemounet 1:fbf17fb09581 361 case PPPERR_PROTOCOL: //Protocol error
clemounet 1:fbf17fb09581 362 WARN("Protocol error");
clemounet 1:fbf17fb09581 363 pIf->setConnected(false);
clemounet 1:fbf17fb09581 364 break;
clemounet 1:fbf17fb09581 365 case PPPERR_USER:
clemounet 1:fbf17fb09581 366 WARN("Disconnected by user");
clemounet 1:fbf17fb09581 367 pIf->setConnected(false);
clemounet 1:fbf17fb09581 368 break;
clemounet 1:fbf17fb09581 369 default:
clemounet 1:fbf17fb09581 370 WARN("Unknown error (%d)", errCode);
clemounet 1:fbf17fb09581 371 pIf->setConnected(false);
clemounet 1:fbf17fb09581 372 break;
clemounet 1:fbf17fb09581 373 }
clemounet 1:fbf17fb09581 374
clemounet 1:fbf17fb09581 375 pIf->m_linkStatusSphre.wait(0); //If previous event has not been handled, "delete" it now
clemounet 1:fbf17fb09581 376 pIf->m_pppErrCode = errCode;
clemounet 1:fbf17fb09581 377 pIf->m_linkStatusSphre.release();
clemounet 1:fbf17fb09581 378 }
clemounet 1:fbf17fb09581 379
clemounet 1:fbf17fb09581 380 //LwIP PPP implementation
clemounet 1:fbf17fb09581 381 extern "C"
clemounet 1:fbf17fb09581 382 {
clemounet 1:fbf17fb09581 383
clemounet 1:fbf17fb09581 384 /**
clemounet 1:fbf17fb09581 385 * Writes to the serial device.
clemounet 1:fbf17fb09581 386 *
clemounet 1:fbf17fb09581 387 * @param fd serial device handle
clemounet 1:fbf17fb09581 388 * @param data pointer to data to send
clemounet 1:fbf17fb09581 389 * @param len length (in bytes) of data to send
clemounet 1:fbf17fb09581 390 * @return number of bytes actually sent
clemounet 1:fbf17fb09581 391 *
clemounet 1:fbf17fb09581 392 * @note This function will block until all data can be sent.
clemounet 1:fbf17fb09581 393 */
clemounet 1:fbf17fb09581 394 u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len)
clemounet 1:fbf17fb09581 395 {
clemounet 1:fbf17fb09581 396 DBG("sio_write");
clemounet 1:fbf17fb09581 397 PPPIPInterface* pIf = (PPPIPInterface*)fd;
clemounet 1:fbf17fb09581 398 int ret;
clemounet 1:fbf17fb09581 399 if(!pIf->m_streamAvail) //If stream is not available (it is a shared resource) don't go further
clemounet 1:fbf17fb09581 400 {
clemounet 1:fbf17fb09581 401 return 0;
clemounet 1:fbf17fb09581 402 }
clemounet 1:fbf17fb09581 403 ret = pIf->m_pStream->write(data, len, osWaitForever); //Blocks until all data is sent or an error happens
clemounet 1:fbf17fb09581 404 if(ret != OK)
clemounet 1:fbf17fb09581 405 {
clemounet 1:fbf17fb09581 406 return 0;
clemounet 1:fbf17fb09581 407 }
clemounet 1:fbf17fb09581 408 return len;
clemounet 1:fbf17fb09581 409 }
clemounet 1:fbf17fb09581 410
clemounet 1:fbf17fb09581 411 /**
clemounet 1:fbf17fb09581 412 * Reads from the serial device.
clemounet 1:fbf17fb09581 413 *
clemounet 1:fbf17fb09581 414 * @param fd serial device handle
clemounet 1:fbf17fb09581 415 * @param data pointer to data buffer for receiving
clemounet 1:fbf17fb09581 416 * @param len maximum length (in bytes) of data to receive
clemounet 1:fbf17fb09581 417 * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
clemounet 1:fbf17fb09581 418 *
clemounet 1:fbf17fb09581 419 * @note This function will block until data can be received. The blocking
clemounet 1:fbf17fb09581 420 * can be cancelled by calling sio_read_abort().
clemounet 1:fbf17fb09581 421 */
clemounet 1:fbf17fb09581 422 u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len)
clemounet 1:fbf17fb09581 423 {
clemounet 1:fbf17fb09581 424 DBG("sio_read");
clemounet 1:fbf17fb09581 425 PPPIPInterface* pIf = (PPPIPInterface*)fd;
clemounet 1:fbf17fb09581 426 int ret;
clemounet 1:fbf17fb09581 427 size_t readLen;
clemounet 1:fbf17fb09581 428 if(!pIf->m_streamAvail) //If stream is not available (it is a shared resource) don't go further
clemounet 1:fbf17fb09581 429 {
clemounet 1:fbf17fb09581 430 WARN("EXIT NOT AVAIL");
clemounet 1:fbf17fb09581 431 return 0;
clemounet 1:fbf17fb09581 432 }
clemounet 1:fbf17fb09581 433 ret = pIf->m_pStream->read(data, &readLen, len, osWaitForever); //Blocks until some data is received or an error happens
clemounet 1:fbf17fb09581 434 if(ret != OK)
clemounet 1:fbf17fb09581 435 {
clemounet 1:fbf17fb09581 436 return 0;
clemounet 1:fbf17fb09581 437 }
clemounet 1:fbf17fb09581 438 DBG("ret");
clemounet 1:fbf17fb09581 439 return readLen;
clemounet 1:fbf17fb09581 440 }
clemounet 1:fbf17fb09581 441
clemounet 1:fbf17fb09581 442 /**
clemounet 1:fbf17fb09581 443 * Aborts a blocking sio_read() call.
clemounet 1:fbf17fb09581 444 *
clemounet 1:fbf17fb09581 445 * @param fd serial device handle
clemounet 1:fbf17fb09581 446 */
clemounet 1:fbf17fb09581 447 void sio_read_abort(sio_fd_t fd)
clemounet 1:fbf17fb09581 448 {
clemounet 1:fbf17fb09581 449 DBG("sio_read_abort");
clemounet 1:fbf17fb09581 450 PPPIPInterface* pIf = (PPPIPInterface*)fd;
clemounet 1:fbf17fb09581 451 if(!pIf->m_streamAvail) //If stream is not available (it is a shared resource) don't go further
clemounet 1:fbf17fb09581 452 {
clemounet 1:fbf17fb09581 453 return;
clemounet 1:fbf17fb09581 454 }
clemounet 1:fbf17fb09581 455 pIf->m_pStream->abortRead();
clemounet 1:fbf17fb09581 456 DBG("ret");
clemounet 1:fbf17fb09581 457 }
clemounet 1:fbf17fb09581 458
clemounet 1:fbf17fb09581 459 }
clemounet 1:fbf17fb09581 460