local fork

Dependencies:   Socket USBHostWANDongle_bleedingedge lwip-sys lwip

Dependents:   Encrypted

Fork of VodafoneUSBModem_bleedingedge by Donatien Garnier

Committer:
ashleymills
Date:
Wed Jan 09 16:13:50 2013 +0000
Revision:
75:a6ac8206a58d
Parent:
38:d19354028042
Experimental MU509 Support

Who changed what in which revision?

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