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 25 14:34:13 2015 +0000
Revision:
99:514e67a69ad6
Parent:
98:1b851249d70b
supported SMS

Who changed what in which revision?

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