PHS module SMA-01 library. see: https://developer.mbed.org/users/phsfan/notebook/abitusbmodem/

Dependencies:   Socket lwip-sys lwip

Dependents:   AbitUSBModem_HTTPTest AbitUSBModem_MQTTTest AbitUSBModem_WebsocketTest AbitUSBModem_SMSTest

Fork of VodafoneUSBModem by mbed official

/media/uploads/phsfan/sma01_003.png

Committer:
phsfan
Date:
Wed Feb 18 09:40:07 2015 +0000
Revision:
96:b50f5f795684
Parent:
79:a6ac8206a58d
Child:
97:7d9cc95e2ea7
1st build.; ABIT SMA-01

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
phsfan 96:b50f5f795684 33 #define MSISDN "0570570711##64"
donatien 18:1789a11d1892 34
phsfan 96:b50f5f795684 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"
phsfan 96:b50f5f795684 38 #define EXPECTED_RESP_MIN_LEN 30
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 79:a6ac8206a58d 52 PPPIPInterface::PPPIPInterface(
ashleymills 79:a6ac8206a58d 53 IOStream* pStream,
ashleymills 79:a6ac8206a58d 54 IOStream* atStream,
ashleymills 79:a6ac8206a58d 55 ATCommandsInterface* pIf,
ashleymills 79:a6ac8206a58d 56 bool hangupViaATPort
ashleymills 79:a6ac8206a58d 57 ) :
ashleymills 79:a6ac8206a58d 58 LwIPInterface(),
phsfan 96:b50f5f795684 59 m_pIf(pIf),
ashleymills 79:a6ac8206a58d 60 m_linkStatusSphre(1),
ashleymills 79:a6ac8206a58d 61 m_pppErrCode(0),
ashleymills 79:a6ac8206a58d 62 m_pStream(pStream),
ashleymills 79:a6ac8206a58d 63 m_atStream(atStream),
ashleymills 79:a6ac8206a58d 64 m_streamAvail(true),
phsfan 96:b50f5f795684 65 m_hangupViaATPort(hangupViaATPort),
phsfan 96:b50f5f795684 66 m_pppd(-1)
donatien 8:04b6a042595f 67 {
ashleymills 79:a6ac8206a58d 68
ashleymills 79: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 79:a6ac8206a58d 77 void PPPIPInterface::setHangupViaATPort(bool val) {
ashleymills 79:a6ac8206a58d 78 m_hangupViaATPort = val;
ashleymills 79:a6ac8206a58d 79 }
ashleymills 79:a6ac8206a58d 80
donatien 8:04b6a042595f 81 /*virtual*/ int PPPIPInterface::init() //Init PPP-specific stuff, create the right bindings, etc
donatien 8:04b6a042595f 82 {
ashleymills 79:a6ac8206a58d 83 DBG("Initializing LwIP");
ashleymills 79:a6ac8206a58d 84 LwIPInterface::init(); //Init LwIP, NOT including PPP
ashleymills 79:a6ac8206a58d 85 DBG("Initializing PPP");
ashleymills 79:a6ac8206a58d 86 pppInit();
ashleymills 79:a6ac8206a58d 87 DBG("Done");
ashleymills 79: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 79:a6ac8206a58d 93 DBG("Configuring PPP authentication method");
ashleymills 79:a6ac8206a58d 94 pppSetAuth(PPPAUTHTYPE_ANY, user, pw);
ashleymills 79:a6ac8206a58d 95 DBG("Done");
ashleymills 79: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 79:a6ac8206a58d 101 int ret;
ashleymills 79:a6ac8206a58d 102 char buf[32];
ashleymills 79:a6ac8206a58d 103 size_t len;
ashleymills 79:a6ac8206a58d 104 DBG("Trying to connect with PPP");
ashleymills 79:a6ac8206a58d 105
ashleymills 79:a6ac8206a58d 106 cleanupLink();
ashleymills 79:a6ac8206a58d 107
ashleymills 79:a6ac8206a58d 108 DBG("Sending %s", CONNECT_CMD);
ashleymills 79:a6ac8206a58d 109
ashleymills 79:a6ac8206a58d 110 ret = m_pStream->write((uint8_t*)CONNECT_CMD, strlen(CONNECT_CMD), osWaitForever);
ashleymills 79:a6ac8206a58d 111 if( ret != OK ) {
ashleymills 79:a6ac8206a58d 112 return NET_UNKNOWN;
ashleymills 79:a6ac8206a58d 113 }
ashleymills 79:a6ac8206a58d 114
ashleymills 79:a6ac8206a58d 115 DBG("Expect %s", EXPECTED_RESP);
ashleymills 79:a6ac8206a58d 116
phsfan 96:b50f5f795684 117 Thread::wait(100);
ashleymills 79:a6ac8206a58d 118 len = 0;
ashleymills 79:a6ac8206a58d 119 size_t readLen;
ashleymills 79:a6ac8206a58d 120 ret = m_pStream->read((uint8_t*)buf + len, &readLen, EXPECTED_RESP_MIN_LEN, 10000);
ashleymills 79:a6ac8206a58d 121 if( ret != OK ) {
ashleymills 79:a6ac8206a58d 122 return NET_UNKNOWN;
donatien 12:66dc2c8eba2d 123 }
donatien 12:66dc2c8eba2d 124 len += readLen;
ashleymills 79:a6ac8206a58d 125 while( (len < EXPECTED_RESP_MIN_LEN) || (buf[len-1] != LF) ) {
ashleymills 79:a6ac8206a58d 126 ret = m_pStream->read((uint8_t*)buf + len, &readLen, 1, 10000);
ashleymills 79:a6ac8206a58d 127 if( ret != OK ) {
ashleymills 79:a6ac8206a58d 128 return NET_UNKNOWN;
ashleymills 79:a6ac8206a58d 129 }
ashleymills 79:a6ac8206a58d 130 len += readLen;
ashleymills 79:a6ac8206a58d 131 }
ashleymills 79:a6ac8206a58d 132
ashleymills 79:a6ac8206a58d 133 buf[len]=0;
ashleymills 79:a6ac8206a58d 134
ashleymills 79:a6ac8206a58d 135 DBG("Got %s[len %d]", buf, len);
ashleymills 79:a6ac8206a58d 136
ashleymills 79:a6ac8206a58d 137 int datarate = 0;
ashleymills 79:a6ac8206a58d 138 if( (sscanf( buf, EXPECTED_RESP_DATARATE, &datarate ) != 1) && (strcmp(EXPECTED_RESP, buf) != 0) ) {
ashleymills 79:a6ac8206a58d 139 //Discard buffer
ashleymills 79:a6ac8206a58d 140 do { //Clear buf
ashleymills 79:a6ac8206a58d 141 ret = m_pStream->read((uint8_t*)buf, &len, 32, 0);
ashleymills 79:a6ac8206a58d 142 } while( (ret == OK) && (len > 0) );
ashleymills 79:a6ac8206a58d 143 return NET_CONN;
ashleymills 79:a6ac8206a58d 144 }
ashleymills 79:a6ac8206a58d 145
ashleymills 79:a6ac8206a58d 146 DBG("Transport link open");
ashleymills 79:a6ac8206a58d 147 if(datarate != 0) {
ashleymills 79:a6ac8206a58d 148 DBG("Datarate: %d bps", datarate);
donatien 8:04b6a042595f 149 }
ashleymills 79:a6ac8206a58d 150 m_linkStatusSphre.wait(0);
ashleymills 79:a6ac8206a58d 151 if((m_pppd != -1) && (m_pppErrCode == 0)) { //Already connected
ashleymills 79:a6ac8206a58d 152 return NET_INVALID;
ashleymills 79:a6ac8206a58d 153 }
ashleymills 79:a6ac8206a58d 154
ashleymills 79:a6ac8206a58d 155 ret = pppOverSerialOpen(this, PPPIPInterface::linkStatusCb, this);
ashleymills 79:a6ac8206a58d 156 if(ret < 0) {
ashleymills 79:a6ac8206a58d 157 switch(ret) {
ashleymills 79:a6ac8206a58d 158 case PPPERR_OPEN:
ashleymills 79:a6ac8206a58d 159 default:
ashleymills 79:a6ac8206a58d 160 return NET_FULL; //All available resources are already used
ashleymills 79:a6ac8206a58d 161 }
ashleymills 79:a6ac8206a58d 162 }
ashleymills 79:a6ac8206a58d 163 m_pppd = ret; //PPP descriptor
ashleymills 79:a6ac8206a58d 164 m_linkStatusSphre.wait(); //Block indefinitely; there should be a timeout there
ashleymills 79:a6ac8206a58d 165 if(m_pppErrCode != PPPERR_NONE) {
ashleymills 79:a6ac8206a58d 166 m_pppd = -1;
ashleymills 79:a6ac8206a58d 167 }
ashleymills 79:a6ac8206a58d 168 switch(m_pppErrCode) {
ashleymills 79:a6ac8206a58d 169 case PPPERR_NONE: //Connected OK
ashleymills 79:a6ac8206a58d 170 return OK;
ashleymills 79:a6ac8206a58d 171 case PPPERR_CONNECT: //Connection lost
ashleymills 79:a6ac8206a58d 172 return NET_INTERRUPTED;
ashleymills 79:a6ac8206a58d 173 case PPPERR_AUTHFAIL: //Authentication failed
ashleymills 79:a6ac8206a58d 174 return NET_AUTH;
ashleymills 79:a6ac8206a58d 175 case PPPERR_PROTOCOL: //Protocol error
ashleymills 79:a6ac8206a58d 176 return NET_PROTOCOL;
ashleymills 79:a6ac8206a58d 177 default:
ashleymills 79:a6ac8206a58d 178 return NET_UNKNOWN;
ashleymills 79:a6ac8206a58d 179 }
donatien 8:04b6a042595f 180 }
donatien 8:04b6a042595f 181
donatien 8:04b6a042595f 182 /*virtual*/ int PPPIPInterface::disconnect()
donatien 8:04b6a042595f 183 {
ashleymills 79:a6ac8206a58d 184 DBG("disconnect called");
ashleymills 79:a6ac8206a58d 185 int ret = m_linkStatusSphre.wait(0);
ashleymills 79:a6ac8206a58d 186 if(ret > 0) { //Already disconnected?
ashleymills 79:a6ac8206a58d 187 m_pppd = -1; //Discard PPP descriptor
ashleymills 79:a6ac8206a58d 188 switch(m_pppErrCode) {
ashleymills 79:a6ac8206a58d 189 case PPPERR_CONNECT: //Connection terminated
ashleymills 79:a6ac8206a58d 190 case PPPERR_AUTHFAIL: //Authentication failed
ashleymills 79:a6ac8206a58d 191 case PPPERR_PROTOCOL: //Protocol error
ashleymills 79:a6ac8206a58d 192 case PPPERR_USER:
ashleymills 79:a6ac8206a58d 193 return OK;
ashleymills 79:a6ac8206a58d 194 default:
ashleymills 79:a6ac8206a58d 195 return NET_UNKNOWN;
ashleymills 79:a6ac8206a58d 196 }
ashleymills 79:a6ac8206a58d 197 } else {
ashleymills 79:a6ac8206a58d 198 if(m_pppd == -1) {
ashleymills 79:a6ac8206a58d 199 return NET_INVALID;
ashleymills 79:a6ac8206a58d 200 }
ashleymills 79:a6ac8206a58d 201 pppClose(m_pppd);
ashleymills 79:a6ac8206a58d 202 do {
ashleymills 79:a6ac8206a58d 203 m_linkStatusSphre.wait(); //Block indefinitely; there should be a timeout there
ashleymills 79:a6ac8206a58d 204 DBG("Received PPP err code %d", m_pppErrCode);
ashleymills 79:a6ac8206a58d 205 } while(m_pppErrCode != PPPERR_USER);
ashleymills 79:a6ac8206a58d 206 m_pppd = -1; //Discard PPP descriptor
donatien 8:04b6a042595f 207 }
ashleymills 79:a6ac8206a58d 208
ashleymills 79:a6ac8206a58d 209 if(!m_hangupViaATPort) {
ashleymills 79:a6ac8206a58d 210 DBG("Sending %s", ESCAPE_SEQ);
ashleymills 79:a6ac8206a58d 211 Thread::wait(1000);
ashleymills 79:a6ac8206a58d 212 ret = m_pStream->write((uint8_t*)ESCAPE_SEQ, strlen(ESCAPE_SEQ), osWaitForever);
ashleymills 79:a6ac8206a58d 213 Thread::wait(1000);
ashleymills 79:a6ac8206a58d 214 if( ret != OK ) {
ashleymills 79:a6ac8206a58d 215 return NET_UNKNOWN;
ashleymills 79:a6ac8206a58d 216 }
ashleymills 79:a6ac8206a58d 217 }
ashleymills 79:a6ac8206a58d 218
ashleymills 79:a6ac8206a58d 219 cleanupLink();
ashleymills 79:a6ac8206a58d 220
ashleymills 79:a6ac8206a58d 221 return OK;
donatien 18:1789a11d1892 222 }
donatien 18:1789a11d1892 223
donatien 18:1789a11d1892 224
donatien 18:1789a11d1892 225 int PPPIPInterface::cleanupLink()
donatien 18:1789a11d1892 226 {
ashleymills 79:a6ac8206a58d 227 int ret;
ashleymills 79:a6ac8206a58d 228 char buf[32];
ashleymills 79:a6ac8206a58d 229 size_t len;
ashleymills 79:a6ac8206a58d 230
ashleymills 79:a6ac8206a58d 231 do { //Clear buf
ashleymills 79:a6ac8206a58d 232 ret = m_pStream->read((uint8_t*)buf, &len, 32, 100);
ashleymills 79:a6ac8206a58d 233 if(ret == OK) {
ashleymills 79:a6ac8206a58d 234 buf[len] = '\0';
ashleymills 79:a6ac8206a58d 235 DBG("Got %s", buf);
ashleymills 79:a6ac8206a58d 236 }
ashleymills 79:a6ac8206a58d 237 } while( (ret == OK) && (len > 0) );
ashleymills 79:a6ac8206a58d 238
ashleymills 79:a6ac8206a58d 239
ashleymills 79:a6ac8206a58d 240 DBG("Sending %s", HANGUP_CMD);
ashleymills 79:a6ac8206a58d 241
ashleymills 79:a6ac8206a58d 242 // set the port to send the hangup command to, and disable AT thread if necessary
ashleymills 79:a6ac8206a58d 243 IOStream *hangupPort = m_pStream;
ashleymills 79:a6ac8206a58d 244 if(m_hangupViaATPort) {
ashleymills 79:a6ac8206a58d 245 m_pIf->pause();
ashleymills 79:a6ac8206a58d 246 hangupPort = m_atStream;
donatien 18:1789a11d1892 247 }
ashleymills 79:a6ac8206a58d 248
ashleymills 79:a6ac8206a58d 249
ashleymills 79:a6ac8206a58d 250 ret = hangupPort->write((uint8_t*)HANGUP_CMD, strlen(HANGUP_CMD), osWaitForever);
ashleymills 79:a6ac8206a58d 251 if( ret != OK ) {
ashleymills 79:a6ac8206a58d 252 return NET_UNKNOWN;
ashleymills 79:a6ac8206a58d 253 }
ashleymills 79:a6ac8206a58d 254
ashleymills 79:a6ac8206a58d 255 size_t readLen;
ashleymills 79:a6ac8206a58d 256
ashleymills 79:a6ac8206a58d 257 //Hangup
ashleymills 79:a6ac8206a58d 258 DBG("Expect %s", HANGUP_CMD);
donatien 18:1789a11d1892 259
ashleymills 79:a6ac8206a58d 260 len = 0;
ashleymills 79:a6ac8206a58d 261 while( len < strlen(HANGUP_CMD) ) {
ashleymills 79:a6ac8206a58d 262 ret = hangupPort->read((uint8_t*)buf + len, &readLen, strlen(HANGUP_CMD) - len, 100);
ashleymills 79:a6ac8206a58d 263 if( ret != OK ) {
ashleymills 79:a6ac8206a58d 264 break;
ashleymills 79:a6ac8206a58d 265 }
ashleymills 79:a6ac8206a58d 266 len += readLen;
ashleymills 79:a6ac8206a58d 267 /////
ashleymills 79:a6ac8206a58d 268 buf[len]=0;
ashleymills 79:a6ac8206a58d 269 DBG("Got %s", buf);
donatien 18:1789a11d1892 270 }
ashleymills 79:a6ac8206a58d 271
donatien 18:1789a11d1892 272 buf[len]=0;
ashleymills 79:a6ac8206a58d 273
ashleymills 79:a6ac8206a58d 274 DBG("Got %s[len %d]", buf, len);
ashleymills 79:a6ac8206a58d 275
ashleymills 79:a6ac8206a58d 276 //OK response
ashleymills 79:a6ac8206a58d 277 DBG("Expect %s", OK_RESP);
donatien 18:1789a11d1892 278
ashleymills 79:a6ac8206a58d 279 len = 0;
ashleymills 79:a6ac8206a58d 280 while( len < strlen(OK_RESP) ) {
ashleymills 79:a6ac8206a58d 281 ret = hangupPort->read((uint8_t*)buf + len, &readLen, strlen(OK_RESP) - len, 100);
ashleymills 79:a6ac8206a58d 282 if( ret != OK ) {
ashleymills 79:a6ac8206a58d 283 break;
ashleymills 79:a6ac8206a58d 284 }
ashleymills 79:a6ac8206a58d 285 len += readLen;
ashleymills 79:a6ac8206a58d 286 /////
ashleymills 79:a6ac8206a58d 287 buf[len]=0;
ashleymills 79:a6ac8206a58d 288 DBG("Got %s", buf);
donatien 18:1789a11d1892 289 }
ashleymills 79:a6ac8206a58d 290
ashleymills 79:a6ac8206a58d 291
ashleymills 79:a6ac8206a58d 292
donatien 18:1789a11d1892 293 buf[len]=0;
ashleymills 79:a6ac8206a58d 294
ashleymills 79:a6ac8206a58d 295 DBG("Got %s[len %d]", buf, len);
ashleymills 79:a6ac8206a58d 296
ashleymills 79:a6ac8206a58d 297 // restart AT thread
ashleymills 79:a6ac8206a58d 298 if(m_hangupViaATPort) {
ashleymills 79:a6ac8206a58d 299 m_pIf->restart();
ashleymills 79:a6ac8206a58d 300 }
ashleymills 79:a6ac8206a58d 301
ashleymills 79:a6ac8206a58d 302 //NO CARRIER event
ashleymills 79:a6ac8206a58d 303 DBG("Expect %s", NO_CARRIER_RESP);
donatien 18:1789a11d1892 304
ashleymills 79:a6ac8206a58d 305 len = 0;
ashleymills 79:a6ac8206a58d 306 while( len < strlen(NO_CARRIER_RESP) ) {
ashleymills 79:a6ac8206a58d 307 ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(NO_CARRIER_RESP) - len, 100);
ashleymills 79:a6ac8206a58d 308 if( ret != OK ) {
ashleymills 79:a6ac8206a58d 309 break;
ashleymills 79:a6ac8206a58d 310 }
ashleymills 79:a6ac8206a58d 311 len += readLen;
ashleymills 79:a6ac8206a58d 312 /////
ashleymills 79:a6ac8206a58d 313 buf[len]=0;
ashleymills 79:a6ac8206a58d 314 DBG("Got %s", buf);
donatien 18:1789a11d1892 315 }
ashleymills 79:a6ac8206a58d 316
donatien 18:1789a11d1892 317 buf[len]=0;
ashleymills 79:a6ac8206a58d 318
ashleymills 79:a6ac8206a58d 319 DBG("Got %s[len %d]", buf, len);
ashleymills 79:a6ac8206a58d 320
ashleymills 79:a6ac8206a58d 321 do { //Clear buf
ashleymills 79:a6ac8206a58d 322 ret = m_pStream->read((uint8_t*)buf, &len, 32, 100);
ashleymills 79:a6ac8206a58d 323 if(ret == OK) {
ashleymills 79:a6ac8206a58d 324 buf[len] = '\0';
ashleymills 79:a6ac8206a58d 325 DBG("Got %s", buf);
ashleymills 79:a6ac8206a58d 326 }
ashleymills 79:a6ac8206a58d 327 } while( (ret == OK) && (len > 0) );
ashleymills 79:a6ac8206a58d 328
ashleymills 79:a6ac8206a58d 329
ashleymills 79:a6ac8206a58d 330 return OK;
donatien 8:04b6a042595f 331 }
donatien 8:04b6a042595f 332
donatien 8:04b6a042595f 333 /*static*/ void PPPIPInterface::linkStatusCb(void *ctx, int errCode, void *arg) //PPP link status
donatien 8:04b6a042595f 334 {
ashleymills 79:a6ac8206a58d 335 PPPIPInterface* pIf = (PPPIPInterface*)ctx;
ashleymills 79:a6ac8206a58d 336 struct ppp_addrs* addrs = (struct ppp_addrs*) arg;
ashleymills 79:a6ac8206a58d 337
ashleymills 79:a6ac8206a58d 338 switch(errCode) {
ashleymills 79:a6ac8206a58d 339 case PPPERR_NONE:
ashleymills 79:a6ac8206a58d 340 WARN("Connected via PPP.");
ashleymills 79:a6ac8206a58d 341 DBG("Local IP address: %s", inet_ntoa(addrs->our_ipaddr));
ashleymills 79:a6ac8206a58d 342 DBG("Netmask: %s", inet_ntoa(addrs->netmask));
ashleymills 79:a6ac8206a58d 343 DBG("Remote IP address: %s", inet_ntoa(addrs->his_ipaddr));
ashleymills 79:a6ac8206a58d 344 DBG("Primary DNS: %s", inet_ntoa(addrs->dns1));
ashleymills 79:a6ac8206a58d 345 DBG("Secondary DNS: %s", inet_ntoa(addrs->dns2));
ashleymills 79:a6ac8206a58d 346 //Setup DNS
ashleymills 79:a6ac8206a58d 347 if (addrs->dns1.addr != 0) {
ashleymills 79:a6ac8206a58d 348 dns_setserver(0, (struct ip_addr*)&(addrs->dns1));
ashleymills 79:a6ac8206a58d 349 }
ashleymills 79:a6ac8206a58d 350 if (addrs->dns2.addr != 0) {
ashleymills 79:a6ac8206a58d 351 dns_setserver(1, (struct ip_addr*)&(addrs->dns1));
ashleymills 79:a6ac8206a58d 352 }
donatien 8:04b6a042595f 353
ashleymills 79:a6ac8206a58d 354 pIf->setConnected(true);
ashleymills 79:a6ac8206a58d 355 pIf->setIPAddress(inet_ntoa(addrs->our_ipaddr));
ashleymills 79:a6ac8206a58d 356 break;
ashleymills 79:a6ac8206a58d 357 case PPPERR_CONNECT: //Connection lost
ashleymills 79:a6ac8206a58d 358 WARN("Connection lost/terminated");
ashleymills 79:a6ac8206a58d 359 pIf->setConnected(false);
ashleymills 79:a6ac8206a58d 360 break;
ashleymills 79:a6ac8206a58d 361 case PPPERR_AUTHFAIL: //Authentication failed
ashleymills 79:a6ac8206a58d 362 WARN("Authentication failed");
ashleymills 79:a6ac8206a58d 363 pIf->setConnected(false);
ashleymills 79:a6ac8206a58d 364 break;
ashleymills 79:a6ac8206a58d 365 case PPPERR_PROTOCOL: //Protocol error
ashleymills 79:a6ac8206a58d 366 WARN("Protocol error");
ashleymills 79:a6ac8206a58d 367 pIf->setConnected(false);
ashleymills 79:a6ac8206a58d 368 break;
ashleymills 79:a6ac8206a58d 369 case PPPERR_USER:
ashleymills 79:a6ac8206a58d 370 WARN("Disconnected by user");
ashleymills 79:a6ac8206a58d 371 pIf->setConnected(false);
ashleymills 79:a6ac8206a58d 372 break;
ashleymills 79:a6ac8206a58d 373 default:
ashleymills 79:a6ac8206a58d 374 WARN("Unknown error (%d)", errCode);
ashleymills 79:a6ac8206a58d 375 pIf->setConnected(false);
ashleymills 79:a6ac8206a58d 376 break;
donatien 38:d19354028042 377 }
donatien 8:04b6a042595f 378
ashleymills 79:a6ac8206a58d 379 pIf->m_linkStatusSphre.wait(0); //If previous event has not been handled, "delete" it now
ashleymills 79:a6ac8206a58d 380 pIf->m_pppErrCode = errCode;
ashleymills 79:a6ac8206a58d 381 pIf->m_linkStatusSphre.release();
donatien 8:04b6a042595f 382 }
donatien 8:04b6a042595f 383
donatien 8:04b6a042595f 384 //LwIP PPP implementation
donatien 8:04b6a042595f 385 extern "C"
donatien 8:04b6a042595f 386 {
donatien 8:04b6a042595f 387
ashleymills 79:a6ac8206a58d 388 /**
ashleymills 79:a6ac8206a58d 389 * Writes to the serial device.
ashleymills 79:a6ac8206a58d 390 *
ashleymills 79:a6ac8206a58d 391 * @param fd serial device handle
ashleymills 79:a6ac8206a58d 392 * @param data pointer to data to send
ashleymills 79:a6ac8206a58d 393 * @param len length (in bytes) of data to send
ashleymills 79:a6ac8206a58d 394 * @return number of bytes actually sent
ashleymills 79:a6ac8206a58d 395 *
ashleymills 79:a6ac8206a58d 396 * @note This function will block until all data can be sent.
ashleymills 79:a6ac8206a58d 397 */
ashleymills 79:a6ac8206a58d 398 u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len)
ashleymills 79:a6ac8206a58d 399 {
ashleymills 79:a6ac8206a58d 400 DBG("sio_write");
ashleymills 79:a6ac8206a58d 401 PPPIPInterface* pIf = (PPPIPInterface*)fd;
ashleymills 79:a6ac8206a58d 402 int ret;
ashleymills 79:a6ac8206a58d 403 if(!pIf->m_streamAvail) { //If stream is not available (it is a shared resource) don't go further
ashleymills 79:a6ac8206a58d 404 return 0;
ashleymills 79:a6ac8206a58d 405 }
ashleymills 79:a6ac8206a58d 406 ret = pIf->m_pStream->write(data, len, osWaitForever); //Blocks until all data is sent or an error happens
ashleymills 79:a6ac8206a58d 407 if(ret != OK) {
ashleymills 79:a6ac8206a58d 408 return 0;
ashleymills 79:a6ac8206a58d 409 }
ashleymills 79:a6ac8206a58d 410 return len;
ashleymills 79:a6ac8206a58d 411 }
donatien 8:04b6a042595f 412
ashleymills 79:a6ac8206a58d 413 /**
ashleymills 79:a6ac8206a58d 414 * Reads from the serial device.
ashleymills 79:a6ac8206a58d 415 *
ashleymills 79:a6ac8206a58d 416 * @param fd serial device handle
ashleymills 79:a6ac8206a58d 417 * @param data pointer to data buffer for receiving
ashleymills 79:a6ac8206a58d 418 * @param len maximum length (in bytes) of data to receive
ashleymills 79:a6ac8206a58d 419 * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
ashleymills 79:a6ac8206a58d 420 *
ashleymills 79:a6ac8206a58d 421 * @note This function will block until data can be received. The blocking
ashleymills 79:a6ac8206a58d 422 * can be cancelled by calling sio_read_abort().
ashleymills 79:a6ac8206a58d 423 */
ashleymills 79:a6ac8206a58d 424 u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len)
ashleymills 79:a6ac8206a58d 425 {
ashleymills 79:a6ac8206a58d 426 DBG("sio_read");
ashleymills 79:a6ac8206a58d 427 PPPIPInterface* pIf = (PPPIPInterface*)fd;
ashleymills 79:a6ac8206a58d 428 int ret;
ashleymills 79:a6ac8206a58d 429 size_t readLen;
ashleymills 79:a6ac8206a58d 430 if(!pIf->m_streamAvail) { //If stream is not available (it is a shared resource) don't go further
ashleymills 79:a6ac8206a58d 431 WARN("EXIT NOT AVAIL");
ashleymills 79:a6ac8206a58d 432 return 0;
ashleymills 79:a6ac8206a58d 433 }
ashleymills 79:a6ac8206a58d 434 ret = pIf->m_pStream->read(data, &readLen, len, osWaitForever); //Blocks until some data is received or an error happens
ashleymills 79:a6ac8206a58d 435 if(ret != OK) {
ashleymills 79:a6ac8206a58d 436 return 0;
ashleymills 79:a6ac8206a58d 437 }
ashleymills 79:a6ac8206a58d 438 DBG("ret");
ashleymills 79:a6ac8206a58d 439 return readLen;
ashleymills 79:a6ac8206a58d 440 }
donatien 8:04b6a042595f 441
ashleymills 79:a6ac8206a58d 442 /**
ashleymills 79:a6ac8206a58d 443 * Aborts a blocking sio_read() call.
ashleymills 79:a6ac8206a58d 444 *
ashleymills 79:a6ac8206a58d 445 * @param fd serial device handle
ashleymills 79:a6ac8206a58d 446 */
ashleymills 79:a6ac8206a58d 447 void sio_read_abort(sio_fd_t fd)
ashleymills 79:a6ac8206a58d 448 {
ashleymills 79:a6ac8206a58d 449 DBG("sio_read_abort");
ashleymills 79:a6ac8206a58d 450 PPPIPInterface* pIf = (PPPIPInterface*)fd;
ashleymills 79:a6ac8206a58d 451 if(!pIf->m_streamAvail) { //If stream is not available (it is a shared resource) don't go further
ashleymills 79:a6ac8206a58d 452 return;
ashleymills 79:a6ac8206a58d 453 }
ashleymills 79:a6ac8206a58d 454 pIf->m_pStream->abortRead();
ashleymills 79:a6ac8206a58d 455 DBG("ret");
ashleymills 79:a6ac8206a58d 456 }
donatien 8:04b6a042595f 457
donatien 8:04b6a042595f 458 }
donatien 8:04b6a042595f 459