Base library for cellular modem implementations

Dependencies:   Socket lwip-sys lwip

Dependents:   CellularUSBModem CellularUSBModem

Deprecated

This is an mbed 2 networking library. For mbed 5, the networking libraries have been revised to better support additional network stacks and thread safety here.

Committer:
mbed_official
Date:
Thu May 08 11:00:26 2014 +0100
Revision:
8:944cd194963e
Parent:
4:3fc75e611736
Synchronized with git revision df12bf01ac7dbb50751e2b16a351c894994e1dcf

Full URL: https://github.com/mbedmicro/mbed/commit/df12bf01ac7dbb50751e2b16a351c894994e1dcf/

Who changed what in which revision?

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