diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h index 2930420d9c..ee8a9a0ef5 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h +++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h @@ -177,8 +177,6 @@ #define LWIP_SOCKET 0 #define SO_REUSE 1 -#define IP_SOF_BROADCAST 1 -#define IP_SOF_BROADCAST_RECV 1 // Support Multicast #include "stdlib.h" diff --git a/features/FEATURE_LWIP/lwip-interface/ppp_lwip.cpp b/features/FEATURE_LWIP/lwip-interface/ppp_lwip.cpp index a1054321c0..12fd502b85 100644 --- a/features/FEATURE_LWIP/lwip-interface/ppp_lwip.cpp +++ b/features/FEATURE_LWIP/lwip-interface/ppp_lwip.cpp @@ -54,9 +54,11 @@ static volatile bool event_queued; // Just one interface for now static FileHandle *my_stream; static ppp_pcb *my_ppp_pcb; -static bool ppp_link_up; +static bool ppp_link_up = false; +static const char *login; +static const char *pwd; static sys_sem_t ppp_close_sem; -static void (*notify_ppp_link_status)(int) = 0; +static void (*notify_ppp_link_down)(void) = 0; static EventQueue *prepare_event_queue() { @@ -199,14 +201,19 @@ static void ppp_link_status(ppp_pcb *pcb, int err_code, void *ctx) if (err_code == PPPERR_NONE) { ppp_link_up = true; - } else { - if (ppp_link_up) { - ppp_link_up = false; - sys_sem_signal(&ppp_close_sem); - } + /* suppress generating a callback event for connection up + * Because connect() call is blocking, why wait for a callback */ + return; } - notify_ppp_link_status(err_code); + /* If some error happened, we need to properly shutdown the PPP interface */ + if (ppp_link_up) { + ppp_link_up = false; + sys_sem_signal(&ppp_close_sem); + } + + /* Alright, PPP interface is down, we need to notify upper layer */ + notify_ppp_link_down(); } #if !PPP_INPROC_IRQ_SAFE @@ -251,13 +258,6 @@ hup: return; } -/*static void ppp_carrier_lost() -{ - if (my_stream) { - ppp_close(my_ppp_pcb, 1); - } -}*/ - static void stream_cb() { if (my_stream && !event_queued) { event_queued = true; @@ -269,6 +269,10 @@ static void stream_cb() { extern "C" err_t ppp_lwip_connect() { +#if PPP_AUTH_SUPPORT + ppp_set_auth(my_ppp_pcb, PPPAUTHTYPE_ANY, login, pwd); +#endif //PPP_AUTH_SUPPORT + err_t ret = ppp_connect(my_ppp_pcb, 0); // lwIP's ppp.txt says input must not be called until after connect if (ret == ERR_OK) { @@ -318,14 +322,17 @@ extern "C" nsapi_error_t ppp_lwip_if_init(struct netif *netif) return NSAPI_ERROR_OK; } -nsapi_error_t nsapi_ppp_connect(FileHandle *stream, void (*ppp_link_status_cb)(int)) +nsapi_error_t nsapi_ppp_connect(FileHandle *stream, void (*ppp_link_down_cb)(void), const char *uname, const char *password) { if (my_stream) { return NSAPI_ERROR_PARAMETER; } my_stream = stream; stream->set_blocking(false); - notify_ppp_link_status = ppp_link_status_cb; + notify_ppp_link_down = ppp_link_down_cb; + login = uname; + pwd = password; + // mustn't start calling input until after connect - // attach deferred until ppp_lwip_connect, called from mbed_lwip_bringup return mbed_lwip_bringup(false, true, NULL, NULL, NULL); @@ -337,13 +344,6 @@ nsapi_error_t nsapi_ppp_disconnect(FileHandle *stream) return mbed_lwip_bringdown(true); } -/*void nsapi_ppp_carrier_lost(FileHandle *stream) -{ - if (stream == my_stream) { - event_queue->call(callback(ppp_carrier_lost)); - } -}*/ - NetworkStack *nsapi_ppp_get_stack() { return nsapi_create_stack(&lwip_stack); diff --git a/features/netsocket/CellularInterface.h b/features/netsocket/CellularInterface.h index 3e4e468d19..e4833b693e 100644 --- a/features/netsocket/CellularInterface.h +++ b/features/netsocket/CellularInterface.h @@ -1,8 +1,4 @@ - -/** \addtogroup netsocket */ -/** @{*/ -/* CellularInterface - * Copyright (c) 2015 ARM Limited +/* Copyright (c) 2017 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,60 +12,69 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #ifndef CELLULAR_INTERFACE_H #define CELLULAR_INTERFACE_H - + #include "netsocket/NetworkInterface.h" - /** CellularInterface class * - * Common interface that is shared between ethernet hardware + * Common interface that is shared between Cellular interfaces */ -class CellularInterface : public NetworkInterface -{ -public: +class CellularInterface: public NetworkInterface { /** CellularInterface lifetime */ - virtual ~CellularInterface() {}; + //virtual ~CellularInterface() {}; - /** Set the cellular network APN and credentials + /** Set the Cellular network credentials * - * @param apn Optional name of the network to connect to - * @param user Optional username for the APN - * @param pass Optional password fot the APN - * @return 0 on success, negative error code on failure + * Please check documentation of connect() for default behaviour of APN settings. + * + * @param apn Access point name + * @param uname optionally, Username + * @param pwd optionally, password */ - virtual nsapi_error_t set_credentials(const char *apn, - const char *username = 0, const char *password = 0) = 0; + virtual void set_credentials(const char *apn, + const char *uname = 0, + const char *pwd = 0) = 0; + + /** Set the pin code for SIM card + * + * @param sim_pin PIN for the SIM card + */ + virtual void set_SIM_pin(const char *sim_pin) = 0; /** Start the interface * - * @param apn Optional name of the network to connect to - * @param username Optional username for your APN - * @param password Optional password for your APN - * @return 0 on success, negative error code on failure + * Attempts to connect to a Cellular network. + * + * @param sim_pin PIN for the SIM card + * @param apn optionally, access point name + * @param uname optionally, Username + * @param pwd optionally, password + * @return NSAPI_ERROR_OK on success, or negative error code on failure */ - virtual nsapi_error_t connect(const char *apn, - const char *username = 0, const char *password = 0) = 0; + virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0, + const char *uname = 0, + const char *pwd = 0) = 0; /** Start the interface * - * Attempts to connect to a cellular network based on supplied credentials + * Attempts to connect to a Cellular network. + * If the SIM requires a PIN, and it is not set/invalid, NSAPI_ERROR_AUTH_ERROR is returned. * - * @return 0 on success, negative error code on failure + * @return NSAPI_ERROR_OK on success, or negative error code on failure */ virtual nsapi_error_t connect() = 0; - + /** Stop the interface - * - * @return 0 on success, negative error code on failure - */ + * + * @return 0 on success, or error code on failure + */ virtual nsapi_error_t disconnect() = 0; }; - #endif /** @}*/ diff --git a/features/netsocket/nsapi_ppp.h b/features/netsocket/nsapi_ppp.h index a86c2ec7d1..78f324be39 100644 --- a/features/netsocket/nsapi_ppp.h +++ b/features/netsocket/nsapi_ppp.h @@ -24,11 +24,8 @@ namespace mbed { NetworkStack *nsapi_ppp_get_stack(); -nsapi_error_t nsapi_ppp_connect(FileHandle *stream, void(*link_status_cb)(int)); +nsapi_error_t nsapi_ppp_connect(FileHandle *stream, void(*link_down_cb)(void)=0, const char *uname=0, const char *pwd=0); nsapi_error_t nsapi_ppp_disconnect(FileHandle *stream); - -//void nsapi_ppp_carrier_lost(FileHandle *stream); // can be called from IRQ - } //namespace mbed #endif /* NSAPI_PPP_H_ */ diff --git a/platform/APN_db.h b/platform/APN_db.h new file mode 100644 index 0000000000..bd98d37b9c --- /dev/null +++ b/platform/APN_db.h @@ -0,0 +1,175 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ublox, ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------- + APN stands for Access Point Name, a setting on your modem or phone + that identifies an external network your phone can access for data + (e.g. 3G or 4G Internet service on your phone). + + The APN settings can be forced when calling the join function. + Below is a list of known APNs that us used if no apn config + is forced. This list could be extended by other settings. + + For further reading: + wiki apn: http://en.wikipedia.org/wiki/Access_Point_Name + wiki mcc/mnc: http://en.wikipedia.org/wiki/Mobile_country_code + google: https://www.google.de/search?q=APN+list +---------------------------------------------------------------- */ + +/** + * Helper to generate the APN string + */ +#define _APN(apn,username,password) apn "\0" username "\0" password "\0" + +/** + * Helper to extract a field from the cfg string + */ +#define _APN_GET(cfg) \ + *cfg ? cfg : NULL; \ + cfg += strlen(cfg) + 1 + +/** + * APN lookup struct + */ +typedef struct { + const char* mccmnc; /**< mobile country code (MCC) and mobile network code MNC */ + const char* cfg; /**< APN configuartion string, use _APN macro to generate */ +} APN_t; + +/** + * Default APN settings used by many networks + */ +static const char* apndef = _APN("internet",,); + +/** + * List of special APNs for different network operators. + * + * No need to add default, "internet" will be used as a default if no entry matches. + * The APN without username/password have to be listed first. + */ + +static const APN_t apnlut[] = { +// MCC Country +// { /* Operator */ "MCC-MNC[,MNC]" _APN(APN,USERNAME,PASSWORD) }, +// MCC must be 3 digits +// MNC must be either 2 or 3 digits +// MCC must be separated by '-' from MNC, multiple MNC can be separated by ',' + +// 232 Austria - AUT + { /* T-Mobile */ "232-03", _APN("m2m.business",,) }, + +// 460 China - CN + { /* CN Mobile */"460-00", _APN("cmnet",,) + _APN("cmwap",,) }, + { /* Unicom */ "460-01", _APN("3gnet",,) + _APN("uninet","uninet","uninet") }, + +// 262 Germany - DE + { /* T-Mobile */ "262-01", _APN("internet.t-mobile","t-mobile","tm") }, + { /* T-Mobile */ "262-02,06", + _APN("m2m.business",,) }, + +// 222 Italy - IT + { /* TIM */ "222-01", _APN("ibox.tim.it",,) }, + { /* Vodafone */ "222-10", _APN("web.omnitel.it",,) }, + { /* Wind */ "222-88", _APN("internet.wind.biz",,) }, + +// 440 Japan - JP + { /* Softbank */ "440-04,06,20,40,41,42,43,44,45,46,47,48,90,91,92,93,94,95" + ",96,97,98" + _APN("open.softbank.ne.jp","opensoftbank","ebMNuX1FIHg9d3DA") + _APN("smile.world","dna1trop","so2t3k3m2a") }, + { /* NTTDoCoMo */"440-09,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27," + "28,29,30,31,32,33,34,35,36,37,38,39,58,59,60,61,62,63," + "64,65,66,67,68,69,87,99", + _APN("bmobilewap",,) /*BMobile*/ + _APN("mpr2.bizho.net","Mopera U",) /* DoCoMo */ + _APN("bmobile.ne.jp","bmobile@wifi2","bmobile") /*BMobile*/ }, + +// 204 Netherlands - NL + { /* Vodafone */ "204-04", _APN("public4.m2minternet.com",,) }, + +// 293 Slovenia - SI + { /* Si.mobil */ "293-40", _APN("internet.simobil.si",,) }, + { /* Tusmobil */ "293-70", _APN("internet.tusmobil.si",,) }, + +// 240 Sweden SE + { /* Telia */ "240-01", _APN("online.telia.se",,) }, + { /* Telenor */ "240-06,08", + _APN("services.telenor.se",,) }, + { /* Tele2 */ "240-07", _APN("mobileinternet.tele2.se",,) }, + +// 228 Switzerland - CH + { /* Swisscom */ "228-01", _APN("gprs.swisscom.ch",,) }, + { /* Orange */ "228-03", _APN("internet",,) /* contract */ + _APN("click",,) /* pre-pay */ }, + +// 234 United Kingdom - GB + { /* O2 */ "234-02,10,11", + _APN("mobile.o2.co.uk","faster","web") /* contract */ + _APN("mobile.o2.co.uk","bypass","web") /* pre-pay */ + _APN("payandgo.o2.co.uk","payandgo","payandgo") }, + { /* Vodafone */ "234-15", _APN("internet","web","web") /* contract */ + _APN("pp.vodafone.co.uk","wap","wap") /* pre-pay */ }, + { /* Three */ "234-20", _APN("three.co.uk",,) }, + +// 310 United States of America - US + { /* T-Mobile */ "310-026,260,490", + _APN("epc.tmobile.com",,) + _APN("fast.tmobile.com",,) /* LTE */ }, + { /* AT&T */ "310-030,150,170,260,410,560,680", + _APN("phone",,) + _APN("wap.cingular","WAP@CINGULARGPRS.COM","CINGULAR1") + _APN("isp.cingular","ISP@CINGULARGPRS.COM","CINGULAR1") }, + +// 901 International - INT + { /* Transatel */ "901-37", _APN("netgprs.com","tsl","tsl") }, +}; + +/** + * Configuring APN by extraction from IMSI and matching the table. + * + * @param imsi strinf containing IMSI + */ +inline const char* apnconfig(const char* imsi) +{ + const char* config = NULL; + if (imsi && *imsi) { + // many carriers use internet without username and password, os use this as default + // now try to lookup the setting for our table + for (size_t i = 0; i < sizeof(apnlut)/sizeof(*apnlut) && !config; i ++) { + const char* p = apnlut[i].mccmnc; + // check the MCC + if ((0 == memcmp(imsi, p, 3))) { + p += 3; + // check all the MNC, MNC length can be 2 or 3 digits + while (((p[0] == '-') || (p[0] == ',')) && + (p[1] >= '0') && (p[1] <= '9') && + (p[2] >= '0') && (p[2] <= '9') && !config) { + int l = ((p[3] >= '0') && (p[3] <= '9')) ? 3 : 2; + if (0 == memcmp(imsi+3,p+1,l)) + config = apnlut[i].cfg; + p += 1 + l; + } + } + } + } + // use default if not found + if (!config) { + config = apndef; + } + return config; +}