RTC auf true

Committer:
kevman
Date:
Wed Nov 28 15:10:15 2018 +0000
Revision:
0:38ceb79fef03
RTC modified

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 0:38ceb79fef03 1 /* mbed Microcontroller Library
kevman 0:38ceb79fef03 2 * Copyright (c) 2016 ARM Limited
kevman 0:38ceb79fef03 3 *
kevman 0:38ceb79fef03 4 * Licensed under the Apache License, Version 2.0 (the "License");
kevman 0:38ceb79fef03 5 * you may not use this file except in compliance with the License.
kevman 0:38ceb79fef03 6 * You may obtain a copy of the License at
kevman 0:38ceb79fef03 7 *
kevman 0:38ceb79fef03 8 * http://www.apache.org/licenses/LICENSE-2.0
kevman 0:38ceb79fef03 9 *
kevman 0:38ceb79fef03 10 * Unless required by applicable law or agreed to in writing, software
kevman 0:38ceb79fef03 11 * distributed under the License is distributed on an "AS IS" BASIS,
kevman 0:38ceb79fef03 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kevman 0:38ceb79fef03 13 * See the License for the specific language governing permissions and
kevman 0:38ceb79fef03 14 * limitations under the License.
kevman 0:38ceb79fef03 15 */
kevman 0:38ceb79fef03 16
kevman 0:38ceb79fef03 17 #include <errno.h>
kevman 0:38ceb79fef03 18 #include "platform/FileHandle.h"
kevman 0:38ceb79fef03 19 #include "platform/mbed_poll.h"
kevman 0:38ceb79fef03 20 #include "events/EventQueue.h"
kevman 0:38ceb79fef03 21 #include "mbed_trace.h"
kevman 0:38ceb79fef03 22 #define TRACE_GROUP "LPPP"
kevman 0:38ceb79fef03 23 #include "rtos/Thread.h"
kevman 0:38ceb79fef03 24 #include "lwip/tcpip.h"
kevman 0:38ceb79fef03 25 #include "lwip/tcp.h"
kevman 0:38ceb79fef03 26 #include "lwip/ip.h"
kevman 0:38ceb79fef03 27 #include "lwip/dns.h"
kevman 0:38ceb79fef03 28 #include "lwip/pbuf.h"
kevman 0:38ceb79fef03 29 extern "C" { // "pppos.h" is missing extern C
kevman 0:38ceb79fef03 30 #include "netif/ppp/pppapi.h"
kevman 0:38ceb79fef03 31 }
kevman 0:38ceb79fef03 32
kevman 0:38ceb79fef03 33 #include "nsapi_ppp.h"
kevman 0:38ceb79fef03 34 #include "ppp_lwip.h"
kevman 0:38ceb79fef03 35 #include "LWIPStack.h"
kevman 0:38ceb79fef03 36
kevman 0:38ceb79fef03 37 namespace mbed {
kevman 0:38ceb79fef03 38
kevman 0:38ceb79fef03 39 using rtos::Thread;
kevman 0:38ceb79fef03 40 using events::EventQueue;
kevman 0:38ceb79fef03 41
kevman 0:38ceb79fef03 42 #if LWIP_PPP_API
kevman 0:38ceb79fef03 43
kevman 0:38ceb79fef03 44 static EventQueue *event_queue;
kevman 0:38ceb79fef03 45 static Thread *event_thread;
kevman 0:38ceb79fef03 46 static volatile bool event_queued;
kevman 0:38ceb79fef03 47 static nsapi_error_t connect_error_code;
kevman 0:38ceb79fef03 48
kevman 0:38ceb79fef03 49 // Just one interface for now
kevman 0:38ceb79fef03 50 static FileHandle *my_stream;
kevman 0:38ceb79fef03 51 static LWIP::Interface *my_interface;
kevman 0:38ceb79fef03 52 static ppp_pcb *my_ppp_pcb;
kevman 0:38ceb79fef03 53 static bool ppp_active = false;
kevman 0:38ceb79fef03 54 static bool blocking_connect = true;
kevman 0:38ceb79fef03 55 static const char *login;
kevman 0:38ceb79fef03 56 static const char *pwd;
kevman 0:38ceb79fef03 57 static sys_sem_t ppp_close_sem;
kevman 0:38ceb79fef03 58 static Callback<void(nsapi_event_t, intptr_t)> connection_status_cb;
kevman 0:38ceb79fef03 59
kevman 0:38ceb79fef03 60 static EventQueue *prepare_event_queue()
kevman 0:38ceb79fef03 61 {
kevman 0:38ceb79fef03 62 if (event_queue) {
kevman 0:38ceb79fef03 63 return event_queue;
kevman 0:38ceb79fef03 64 }
kevman 0:38ceb79fef03 65
kevman 0:38ceb79fef03 66 // Should be trying to get a global shared event queue here!
kevman 0:38ceb79fef03 67 // Shouldn't have to be making a private thread!
kevman 0:38ceb79fef03 68
kevman 0:38ceb79fef03 69 // Only need to queue 2 events. new blows on failure.
kevman 0:38ceb79fef03 70 event_queue = new EventQueue(2 * EVENTS_EVENT_SIZE, NULL);
kevman 0:38ceb79fef03 71 event_thread = new Thread(osPriorityNormal, PPP_THREAD_STACK_SIZE);
kevman 0:38ceb79fef03 72
kevman 0:38ceb79fef03 73 if (event_thread->start(callback(event_queue, &EventQueue::dispatch_forever)) != osOK) {
kevman 0:38ceb79fef03 74 delete event_thread;
kevman 0:38ceb79fef03 75 delete event_queue;
kevman 0:38ceb79fef03 76 return NULL;
kevman 0:38ceb79fef03 77 }
kevman 0:38ceb79fef03 78
kevman 0:38ceb79fef03 79 return event_queue;
kevman 0:38ceb79fef03 80 }
kevman 0:38ceb79fef03 81
kevman 0:38ceb79fef03 82 static u32_t ppp_output(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
kevman 0:38ceb79fef03 83 {
kevman 0:38ceb79fef03 84 FileHandle *stream = my_stream;
kevman 0:38ceb79fef03 85 if (!stream) {
kevman 0:38ceb79fef03 86 return 0;
kevman 0:38ceb79fef03 87 }
kevman 0:38ceb79fef03 88
kevman 0:38ceb79fef03 89 pollfh fhs;
kevman 0:38ceb79fef03 90 fhs.fh = stream;
kevman 0:38ceb79fef03 91 fhs.events = POLLOUT;
kevman 0:38ceb79fef03 92
kevman 0:38ceb79fef03 93 // LWIP expects us to block on write
kevman 0:38ceb79fef03 94 // File handle will be in non-blocking mode, because of read events.
kevman 0:38ceb79fef03 95 // Therefore must use poll to achieve the necessary block for writing.
kevman 0:38ceb79fef03 96
kevman 0:38ceb79fef03 97 uint32_t written = 0;
kevman 0:38ceb79fef03 98 while (len != 0) {
kevman 0:38ceb79fef03 99 // Block forever until we're selected - don't care about reason we wake;
kevman 0:38ceb79fef03 100 // return from write should tell us what's up.
kevman 0:38ceb79fef03 101 poll(&fhs, 1, -1);
kevman 0:38ceb79fef03 102 // This write will be non-blocking, but blocking would be fine.
kevman 0:38ceb79fef03 103 ssize_t ret = stream->write(data, len);
kevman 0:38ceb79fef03 104 if (ret == -EAGAIN) {
kevman 0:38ceb79fef03 105 continue;
kevman 0:38ceb79fef03 106 } else if (ret < 0) {
kevman 0:38ceb79fef03 107 break;
kevman 0:38ceb79fef03 108 }
kevman 0:38ceb79fef03 109 written += ret;
kevman 0:38ceb79fef03 110 data += ret;
kevman 0:38ceb79fef03 111 len -= ret;
kevman 0:38ceb79fef03 112 }
kevman 0:38ceb79fef03 113
kevman 0:38ceb79fef03 114 // /tr_debug("> %ld bytes of data written\n", (long) written);
kevman 0:38ceb79fef03 115
kevman 0:38ceb79fef03 116 return written;
kevman 0:38ceb79fef03 117 }
kevman 0:38ceb79fef03 118
kevman 0:38ceb79fef03 119 static void ppp_link_status(ppp_pcb *pcb, int err_code, void *ctx)
kevman 0:38ceb79fef03 120 {
kevman 0:38ceb79fef03 121 nsapi_error_t mapped_err_code = NSAPI_ERROR_NO_CONNECTION;
kevman 0:38ceb79fef03 122
kevman 0:38ceb79fef03 123 switch(err_code) {
kevman 0:38ceb79fef03 124 case PPPERR_NONE:
kevman 0:38ceb79fef03 125 mapped_err_code = NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 126 tr_info("status_cb: Connected");
kevman 0:38ceb79fef03 127 #if PPP_IPV4_SUPPORT
kevman 0:38ceb79fef03 128 tr_debug(" our_ipaddr = %s", ipaddr_ntoa(&ppp_netif(pcb)->ip_addr));
kevman 0:38ceb79fef03 129 tr_debug(" his_ipaddr = %s", ipaddr_ntoa(&ppp_netif(pcb)->gw));
kevman 0:38ceb79fef03 130 tr_debug(" netmask = %s", ipaddr_ntoa(&ppp_netif(pcb)->netmask));
kevman 0:38ceb79fef03 131 #if LWIP_DNS
kevman 0:38ceb79fef03 132 const ip_addr_t *ns;
kevman 0:38ceb79fef03 133 ns = dns_getserver(0);
kevman 0:38ceb79fef03 134 if (ns) {
kevman 0:38ceb79fef03 135 tr_debug(" dns1 = %s", ipaddr_ntoa(ns));
kevman 0:38ceb79fef03 136 }
kevman 0:38ceb79fef03 137 ns = dns_getserver(1);
kevman 0:38ceb79fef03 138 if (ns) {
kevman 0:38ceb79fef03 139 tr_debug(" dns2 = %s", ipaddr_ntoa(ns));
kevman 0:38ceb79fef03 140 }
kevman 0:38ceb79fef03 141 #endif /* LWIP_DNS */
kevman 0:38ceb79fef03 142 #endif /* PPP_IPV4_SUPPORT */
kevman 0:38ceb79fef03 143 #if PPP_IPV6_SUPPORT
kevman 0:38ceb79fef03 144 tr_debug(" our6_ipaddr = %s", ip6addr_ntoa(netif_ip6_addr(ppp_netif(pcb), 0)));
kevman 0:38ceb79fef03 145 #endif /* PPP_IPV6_SUPPORT */
kevman 0:38ceb79fef03 146 break;
kevman 0:38ceb79fef03 147
kevman 0:38ceb79fef03 148 case PPPERR_PARAM:
kevman 0:38ceb79fef03 149 tr_info("status_cb: Invalid parameter");
kevman 0:38ceb79fef03 150 break;
kevman 0:38ceb79fef03 151
kevman 0:38ceb79fef03 152 case PPPERR_OPEN:
kevman 0:38ceb79fef03 153 tr_info("status_cb: Unable to open PPP session");
kevman 0:38ceb79fef03 154 break;
kevman 0:38ceb79fef03 155
kevman 0:38ceb79fef03 156 case PPPERR_DEVICE:
kevman 0:38ceb79fef03 157 tr_info("status_cb: Invalid I/O device for PPP");
kevman 0:38ceb79fef03 158 break;
kevman 0:38ceb79fef03 159
kevman 0:38ceb79fef03 160 case PPPERR_ALLOC:
kevman 0:38ceb79fef03 161 tr_info("status_cb: Unable to allocate resources");
kevman 0:38ceb79fef03 162 break;
kevman 0:38ceb79fef03 163
kevman 0:38ceb79fef03 164 case PPPERR_USER:
kevman 0:38ceb79fef03 165 tr_info("status_cb: User interrupt");
kevman 0:38ceb79fef03 166 break;
kevman 0:38ceb79fef03 167
kevman 0:38ceb79fef03 168 case PPPERR_CONNECT:
kevman 0:38ceb79fef03 169 tr_info("status_cb: Connection lost");
kevman 0:38ceb79fef03 170 mapped_err_code = NSAPI_ERROR_CONNECTION_LOST;
kevman 0:38ceb79fef03 171 break;
kevman 0:38ceb79fef03 172
kevman 0:38ceb79fef03 173 case PPPERR_AUTHFAIL:
kevman 0:38ceb79fef03 174 tr_info("status_cb: Failed authentication challenge");
kevman 0:38ceb79fef03 175 mapped_err_code = NSAPI_ERROR_AUTH_FAILURE;
kevman 0:38ceb79fef03 176 break;
kevman 0:38ceb79fef03 177
kevman 0:38ceb79fef03 178 case PPPERR_PROTOCOL:
kevman 0:38ceb79fef03 179 tr_info("status_cb: Failed to meet protocol");
kevman 0:38ceb79fef03 180 break;
kevman 0:38ceb79fef03 181
kevman 0:38ceb79fef03 182 case PPPERR_PEERDEAD:
kevman 0:38ceb79fef03 183 tr_info("status_cb: Connection timeout");
kevman 0:38ceb79fef03 184 mapped_err_code = NSAPI_ERROR_CONNECTION_TIMEOUT;
kevman 0:38ceb79fef03 185 break;
kevman 0:38ceb79fef03 186
kevman 0:38ceb79fef03 187 case PPPERR_IDLETIMEOUT:
kevman 0:38ceb79fef03 188 tr_info("status_cb: Idle Timeout");
kevman 0:38ceb79fef03 189 break;
kevman 0:38ceb79fef03 190
kevman 0:38ceb79fef03 191 case PPPERR_CONNECTTIME:
kevman 0:38ceb79fef03 192 tr_info("status_cb: Max connect time reached");
kevman 0:38ceb79fef03 193 break;
kevman 0:38ceb79fef03 194
kevman 0:38ceb79fef03 195 case PPPERR_LOOPBACK:
kevman 0:38ceb79fef03 196 tr_info("status_cb: Loopback detected");
kevman 0:38ceb79fef03 197 break;
kevman 0:38ceb79fef03 198
kevman 0:38ceb79fef03 199 default:
kevman 0:38ceb79fef03 200 tr_info("status_cb: Unknown error code %d", err_code);
kevman 0:38ceb79fef03 201 break;
kevman 0:38ceb79fef03 202
kevman 0:38ceb79fef03 203 }
kevman 0:38ceb79fef03 204
kevman 0:38ceb79fef03 205 if (err_code == PPPERR_NONE) {
kevman 0:38ceb79fef03 206 /* status changes have to be reported */
kevman 0:38ceb79fef03 207 if (connection_status_cb) {
kevman 0:38ceb79fef03 208 connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_GLOBAL_UP);
kevman 0:38ceb79fef03 209 }
kevman 0:38ceb79fef03 210 return;
kevman 0:38ceb79fef03 211 }
kevman 0:38ceb79fef03 212
kevman 0:38ceb79fef03 213 /* If some error happened, we need to properly shutdown the PPP interface */
kevman 0:38ceb79fef03 214 if (ppp_active) {
kevman 0:38ceb79fef03 215 ppp_active = false;
kevman 0:38ceb79fef03 216 connect_error_code = mapped_err_code;
kevman 0:38ceb79fef03 217 sys_sem_signal(&ppp_close_sem);
kevman 0:38ceb79fef03 218 }
kevman 0:38ceb79fef03 219
kevman 0:38ceb79fef03 220 /* Alright, PPP interface is down, we need to notify upper layer */
kevman 0:38ceb79fef03 221 if (connection_status_cb) {
kevman 0:38ceb79fef03 222 connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED);
kevman 0:38ceb79fef03 223 }
kevman 0:38ceb79fef03 224 }
kevman 0:38ceb79fef03 225
kevman 0:38ceb79fef03 226 static void handle_modem_hangup()
kevman 0:38ceb79fef03 227 {
kevman 0:38ceb79fef03 228 if (my_ppp_pcb->phase != PPP_PHASE_DEAD) {
kevman 0:38ceb79fef03 229 ppp_close(my_ppp_pcb, 1);
kevman 0:38ceb79fef03 230 }
kevman 0:38ceb79fef03 231 }
kevman 0:38ceb79fef03 232
kevman 0:38ceb79fef03 233 #if !PPP_INPROC_IRQ_SAFE
kevman 0:38ceb79fef03 234 #error "PPP_INPROC_IRQ_SAFE must be enabled"
kevman 0:38ceb79fef03 235 #endif
kevman 0:38ceb79fef03 236 static void ppp_input()
kevman 0:38ceb79fef03 237 {
kevman 0:38ceb79fef03 238 // Allow new events from now, avoiding potential races around the read
kevman 0:38ceb79fef03 239 event_queued = false;
kevman 0:38ceb79fef03 240
kevman 0:38ceb79fef03 241 if (!my_stream) {
kevman 0:38ceb79fef03 242 return;
kevman 0:38ceb79fef03 243 }
kevman 0:38ceb79fef03 244
kevman 0:38ceb79fef03 245 // Non-blocking error check handler
kevman 0:38ceb79fef03 246 pollfh fhs;
kevman 0:38ceb79fef03 247 fhs.fh = my_stream;
kevman 0:38ceb79fef03 248 fhs.events = POLLIN;
kevman 0:38ceb79fef03 249 poll(&fhs, 1, 0);
kevman 0:38ceb79fef03 250 if (fhs.revents & (POLLHUP|POLLERR|POLLNVAL)) {
kevman 0:38ceb79fef03 251 handle_modem_hangup();
kevman 0:38ceb79fef03 252 return;
kevman 0:38ceb79fef03 253 }
kevman 0:38ceb79fef03 254
kevman 0:38ceb79fef03 255 // Infinite loop, but we assume that we can read faster than the
kevman 0:38ceb79fef03 256 // serial, so we will fairly rapidly hit -EAGAIN.
kevman 0:38ceb79fef03 257 for (;;) {
kevman 0:38ceb79fef03 258 u8_t buffer[16];
kevman 0:38ceb79fef03 259 ssize_t len = my_stream->read(buffer, sizeof buffer);
kevman 0:38ceb79fef03 260 if (len == -EAGAIN) {
kevman 0:38ceb79fef03 261 break;
kevman 0:38ceb79fef03 262 } else if (len <= 0) {
kevman 0:38ceb79fef03 263 handle_modem_hangup();
kevman 0:38ceb79fef03 264 return;
kevman 0:38ceb79fef03 265 }
kevman 0:38ceb79fef03 266 pppos_input(my_ppp_pcb, buffer, len);
kevman 0:38ceb79fef03 267 }
kevman 0:38ceb79fef03 268 return;
kevman 0:38ceb79fef03 269 }
kevman 0:38ceb79fef03 270
kevman 0:38ceb79fef03 271 static void stream_cb() {
kevman 0:38ceb79fef03 272 if (my_stream && !event_queued) {
kevman 0:38ceb79fef03 273 event_queued = true;
kevman 0:38ceb79fef03 274 if (event_queue->call(callback(ppp_input)) == 0) {
kevman 0:38ceb79fef03 275 event_queued = false;
kevman 0:38ceb79fef03 276 }
kevman 0:38ceb79fef03 277 }
kevman 0:38ceb79fef03 278 }
kevman 0:38ceb79fef03 279
kevman 0:38ceb79fef03 280 extern "C" err_t ppp_lwip_connect(void *pcb)
kevman 0:38ceb79fef03 281 {
kevman 0:38ceb79fef03 282 #if PPP_AUTH_SUPPORT
kevman 0:38ceb79fef03 283 ppp_set_auth(my_ppp_pcb, PPPAUTHTYPE_ANY, login, pwd);
kevman 0:38ceb79fef03 284 #endif //PPP_AUTH_SUPPORT
kevman 0:38ceb79fef03 285 ppp_active = true;
kevman 0:38ceb79fef03 286 err_t ret = ppp_connect(my_ppp_pcb, 0);
kevman 0:38ceb79fef03 287 // lwIP's ppp.txt says input must not be called until after connect
kevman 0:38ceb79fef03 288 if (ret == ERR_OK) {
kevman 0:38ceb79fef03 289 my_stream->sigio(callback(stream_cb));
kevman 0:38ceb79fef03 290 } else {
kevman 0:38ceb79fef03 291 ppp_active = false;
kevman 0:38ceb79fef03 292 }
kevman 0:38ceb79fef03 293 return ret;
kevman 0:38ceb79fef03 294 }
kevman 0:38ceb79fef03 295
kevman 0:38ceb79fef03 296 extern "C" err_t ppp_lwip_disconnect(void *pcb)
kevman 0:38ceb79fef03 297 {
kevman 0:38ceb79fef03 298 err_t ret = ERR_OK;
kevman 0:38ceb79fef03 299 if (ppp_active) {
kevman 0:38ceb79fef03 300 ret = ppp_close(my_ppp_pcb, 0);
kevman 0:38ceb79fef03 301 if (ret == ERR_OK) {
kevman 0:38ceb79fef03 302 /* close call made, now let's catch the response in the status callback */
kevman 0:38ceb79fef03 303 sys_arch_sem_wait(&ppp_close_sem, 0);
kevman 0:38ceb79fef03 304 }
kevman 0:38ceb79fef03 305 ppp_active = false;
kevman 0:38ceb79fef03 306 }
kevman 0:38ceb79fef03 307 return ret;
kevman 0:38ceb79fef03 308 }
kevman 0:38ceb79fef03 309
kevman 0:38ceb79fef03 310 extern "C" nsapi_error_t ppp_lwip_if_init(void *pcb, struct netif *netif, const nsapi_ip_stack_t stack)
kevman 0:38ceb79fef03 311 {
kevman 0:38ceb79fef03 312 if (!prepare_event_queue()) {
kevman 0:38ceb79fef03 313 return NSAPI_ERROR_NO_MEMORY;
kevman 0:38ceb79fef03 314 }
kevman 0:38ceb79fef03 315
kevman 0:38ceb79fef03 316 if (!my_ppp_pcb) {
kevman 0:38ceb79fef03 317 my_ppp_pcb = pppos_create(netif,
kevman 0:38ceb79fef03 318 ppp_output, ppp_link_status, NULL);
kevman 0:38ceb79fef03 319 if (!my_ppp_pcb) {
kevman 0:38ceb79fef03 320 return NSAPI_ERROR_DEVICE_ERROR;
kevman 0:38ceb79fef03 321 }
kevman 0:38ceb79fef03 322
kevman 0:38ceb79fef03 323 sys_sem_new(&ppp_close_sem, 0);
kevman 0:38ceb79fef03 324 }
kevman 0:38ceb79fef03 325
kevman 0:38ceb79fef03 326 #if LWIP_IPV4
kevman 0:38ceb79fef03 327 if (stack != IPV6_STACK) {
kevman 0:38ceb79fef03 328 ppp_set_usepeerdns(my_ppp_pcb, true);
kevman 0:38ceb79fef03 329 }
kevman 0:38ceb79fef03 330 #endif
kevman 0:38ceb79fef03 331
kevman 0:38ceb79fef03 332 #if LWIP_IPV4 && LWIP_IPV6
kevman 0:38ceb79fef03 333 if (stack == IPV4_STACK) {
kevman 0:38ceb79fef03 334 my_ppp_pcb->ipv6cp_disabled = true;
kevman 0:38ceb79fef03 335 } else if (stack == IPV6_STACK) {
kevman 0:38ceb79fef03 336 my_ppp_pcb->ipcp_disabled = true;
kevman 0:38ceb79fef03 337 }
kevman 0:38ceb79fef03 338 #endif
kevman 0:38ceb79fef03 339
kevman 0:38ceb79fef03 340 return NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 341 }
kevman 0:38ceb79fef03 342
kevman 0:38ceb79fef03 343 nsapi_error_t nsapi_ppp_error_code()
kevman 0:38ceb79fef03 344 {
kevman 0:38ceb79fef03 345 return connect_error_code;
kevman 0:38ceb79fef03 346 }
kevman 0:38ceb79fef03 347
kevman 0:38ceb79fef03 348 nsapi_error_t nsapi_ppp_set_blocking(bool blocking)
kevman 0:38ceb79fef03 349 {
kevman 0:38ceb79fef03 350 blocking_connect = blocking;
kevman 0:38ceb79fef03 351 return NSAPI_ERROR_OK;
kevman 0:38ceb79fef03 352 }
kevman 0:38ceb79fef03 353
kevman 0:38ceb79fef03 354 nsapi_error_t nsapi_ppp_connect(FileHandle *stream, Callback<void(nsapi_event_t, intptr_t)> cb, const char *uname, const char *password, const nsapi_ip_stack_t stack)
kevman 0:38ceb79fef03 355 {
kevman 0:38ceb79fef03 356 if (my_stream) {
kevman 0:38ceb79fef03 357 return NSAPI_ERROR_PARAMETER;
kevman 0:38ceb79fef03 358 }
kevman 0:38ceb79fef03 359 my_stream = stream;
kevman 0:38ceb79fef03 360 stream->set_blocking(false);
kevman 0:38ceb79fef03 361 connection_status_cb = cb;
kevman 0:38ceb79fef03 362 login = uname;
kevman 0:38ceb79fef03 363 pwd = password;
kevman 0:38ceb79fef03 364
kevman 0:38ceb79fef03 365 nsapi_error_t retcode;
kevman 0:38ceb79fef03 366
kevman 0:38ceb79fef03 367 if (!my_interface) {
kevman 0:38ceb79fef03 368 LWIP &lwip = LWIP::get_instance();
kevman 0:38ceb79fef03 369 retcode = lwip._add_ppp_interface(stream, true, stack, &my_interface);
kevman 0:38ceb79fef03 370 if (retcode != NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 371 my_interface = NULL;
kevman 0:38ceb79fef03 372 my_stream->set_blocking(true);
kevman 0:38ceb79fef03 373 my_stream = NULL;
kevman 0:38ceb79fef03 374 connection_status_cb = NULL;
kevman 0:38ceb79fef03 375 return retcode;
kevman 0:38ceb79fef03 376 }
kevman 0:38ceb79fef03 377 }
kevman 0:38ceb79fef03 378
kevman 0:38ceb79fef03 379 // mustn't start calling input until after connect -
kevman 0:38ceb79fef03 380 // attach deferred until ppp_lwip_connect, called from mbed_lwip_bringup
kevman 0:38ceb79fef03 381 retcode = my_interface->bringup(false, NULL, NULL, NULL, stack, blocking_connect);
kevman 0:38ceb79fef03 382
kevman 0:38ceb79fef03 383 if (retcode != NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 384 connection_status_cb = NULL;
kevman 0:38ceb79fef03 385 my_stream->sigio(NULL);
kevman 0:38ceb79fef03 386 my_stream->set_blocking(true);
kevman 0:38ceb79fef03 387 my_stream = NULL;
kevman 0:38ceb79fef03 388 }
kevman 0:38ceb79fef03 389
kevman 0:38ceb79fef03 390 if (retcode != NSAPI_ERROR_OK && connect_error_code != NSAPI_ERROR_OK) {
kevman 0:38ceb79fef03 391 return connect_error_code;
kevman 0:38ceb79fef03 392 } else {
kevman 0:38ceb79fef03 393 return retcode;
kevman 0:38ceb79fef03 394 }
kevman 0:38ceb79fef03 395 }
kevman 0:38ceb79fef03 396
kevman 0:38ceb79fef03 397 nsapi_error_t nsapi_ppp_disconnect(FileHandle *stream)
kevman 0:38ceb79fef03 398 {
kevman 0:38ceb79fef03 399 if (my_stream != stream) {
kevman 0:38ceb79fef03 400 return NSAPI_ERROR_NO_CONNECTION;
kevman 0:38ceb79fef03 401 }
kevman 0:38ceb79fef03 402
kevman 0:38ceb79fef03 403 nsapi_error_t retcode = my_interface->bringdown();
kevman 0:38ceb79fef03 404
kevman 0:38ceb79fef03 405 connection_status_cb = NULL;
kevman 0:38ceb79fef03 406 /* Detach callbacks, and put handle back to default blocking mode */
kevman 0:38ceb79fef03 407 my_stream->sigio(NULL);
kevman 0:38ceb79fef03 408 my_stream->set_blocking(true);
kevman 0:38ceb79fef03 409 my_stream = NULL;
kevman 0:38ceb79fef03 410
kevman 0:38ceb79fef03 411 return retcode;
kevman 0:38ceb79fef03 412 }
kevman 0:38ceb79fef03 413
kevman 0:38ceb79fef03 414 NetworkStack *nsapi_ppp_get_stack()
kevman 0:38ceb79fef03 415 {
kevman 0:38ceb79fef03 416 return &LWIP::get_instance();
kevman 0:38ceb79fef03 417 }
kevman 0:38ceb79fef03 418
kevman 0:38ceb79fef03 419 const char *nsapi_ppp_get_ip_addr(FileHandle *stream)
kevman 0:38ceb79fef03 420 {
kevman 0:38ceb79fef03 421 static char ip_addr[IPADDR_STRLEN_MAX];
kevman 0:38ceb79fef03 422
kevman 0:38ceb79fef03 423 if (stream == my_stream) {
kevman 0:38ceb79fef03 424
kevman 0:38ceb79fef03 425 if (my_interface->get_ip_address(ip_addr, IPADDR_STRLEN_MAX)) {
kevman 0:38ceb79fef03 426 return ip_addr;
kevman 0:38ceb79fef03 427 }
kevman 0:38ceb79fef03 428 }
kevman 0:38ceb79fef03 429
kevman 0:38ceb79fef03 430 return NULL;
kevman 0:38ceb79fef03 431 }
kevman 0:38ceb79fef03 432 const char *nsapi_ppp_get_netmask(FileHandle *stream)
kevman 0:38ceb79fef03 433 {
kevman 0:38ceb79fef03 434 #if !LWIP_IPV4
kevman 0:38ceb79fef03 435 return NULL;
kevman 0:38ceb79fef03 436 #endif
kevman 0:38ceb79fef03 437
kevman 0:38ceb79fef03 438 static char netmask[IPADDR_STRLEN_MAX];
kevman 0:38ceb79fef03 439 if (stream == my_stream) {
kevman 0:38ceb79fef03 440 if (my_interface->get_netmask(netmask, IPADDR_STRLEN_MAX)) {
kevman 0:38ceb79fef03 441 return netmask;
kevman 0:38ceb79fef03 442 }
kevman 0:38ceb79fef03 443 }
kevman 0:38ceb79fef03 444
kevman 0:38ceb79fef03 445 return NULL;
kevman 0:38ceb79fef03 446 }
kevman 0:38ceb79fef03 447 const char *nsapi_ppp_get_gw_addr(FileHandle *stream)
kevman 0:38ceb79fef03 448 {
kevman 0:38ceb79fef03 449 #if !LWIP_IPV4
kevman 0:38ceb79fef03 450 return NULL;
kevman 0:38ceb79fef03 451 #endif
kevman 0:38ceb79fef03 452
kevman 0:38ceb79fef03 453 static char gwaddr[IPADDR_STRLEN_MAX];
kevman 0:38ceb79fef03 454 if (stream == my_stream) {
kevman 0:38ceb79fef03 455 if (my_interface->get_gateway(gwaddr, IPADDR_STRLEN_MAX)) {
kevman 0:38ceb79fef03 456 return gwaddr;
kevman 0:38ceb79fef03 457 }
kevman 0:38ceb79fef03 458 }
kevman 0:38ceb79fef03 459
kevman 0:38ceb79fef03 460 return NULL;
kevman 0:38ceb79fef03 461 }
kevman 0:38ceb79fef03 462
kevman 0:38ceb79fef03 463 #endif /* LWIP_PPP_API */
kevman 0:38ceb79fef03 464
kevman 0:38ceb79fef03 465 } // namespace mbed