Either ipv4 or ipv4v6 PPP and IP stacks are enabled based on 3GPP context

pull/4911/head
Mika Leppänen 2017-08-11 14:57:43 +03:00
parent 457f940a7c
commit dd346ec5a8
10 changed files with 125 additions and 63 deletions

View File

@ -49,7 +49,8 @@ nsapi_error_t EthernetInterface::connect()
return mbed_lwip_bringup_2(_dhcp, false, return mbed_lwip_bringup_2(_dhcp, false,
_ip_address[0] ? _ip_address : 0, _ip_address[0] ? _ip_address : 0,
_netmask[0] ? _netmask : 0, _netmask[0] ? _netmask : 0,
_gateway[0] ? _gateway : 0); _gateway[0] ? _gateway : 0,
DEFAULT_STACK);
} }
nsapi_error_t EthernetInterface::disconnect() nsapi_error_t EthernetInterface::disconnect()

View File

@ -511,10 +511,10 @@ nsapi_error_t mbed_lwip_init(emac_interface_t *emac)
// Backwards compatibility with people using DEVICE_EMAC // Backwards compatibility with people using DEVICE_EMAC
nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw)
{ {
return mbed_lwip_bringup_2(dhcp, false, ip, netmask, gw); return mbed_lwip_bringup_2(dhcp, false, ip, netmask, gw, DEFAULT_STACK);
} }
nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const char *netmask, const char *gw) nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const char *netmask, const char *gw, const nsapi_ip_stack_t stack)
{ {
// Check if we've already connected // Check if we've already connected
if (lwip_connected) { if (lwip_connected) {
@ -533,7 +533,7 @@ nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const cha
} }
} else { } else {
if (ppp) { if (ppp) {
ret = ppp_lwip_if_init(&lwip_netif); ret = ppp_lwip_if_init(&lwip_netif, stack);
} else { } else {
ret = mbed_lwip_emac_init(NULL); ret = mbed_lwip_emac_init(NULL);
} }
@ -553,43 +553,49 @@ nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const cha
netif_set_status_callback(&lwip_netif, mbed_lwip_netif_status_irq); netif_set_status_callback(&lwip_netif, mbed_lwip_netif_status_irq);
#if LWIP_IPV6 #if LWIP_IPV6
if (lwip_netif.hwaddr_len == ETH_HWADDR_LEN) { if (stack != IPV4_STACK) {
netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/); if (lwip_netif.hwaddr_len == ETH_HWADDR_LEN) {
} netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/);
}
#if LWIP_IPV6_MLD #if LWIP_IPV6_MLD
/* /*
* For hardware/netifs that implement MAC filtering. * For hardware/netifs that implement MAC filtering.
* All-nodes link-local is handled by default, so we must let the hardware know * All-nodes link-local is handled by default, so we must let the hardware know
* to allow multicast packets in. * to allow multicast packets in.
* Should set mld_mac_filter previously. */ * Should set mld_mac_filter previously. */
if (lwip_netif.mld_mac_filter != NULL) { if (lwip_netif.mld_mac_filter != NULL) {
ip6_addr_t ip6_allnodes_ll; ip6_addr_t ip6_allnodes_ll;
ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
lwip_netif.mld_mac_filter(&lwip_netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); lwip_netif.mld_mac_filter(&lwip_netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
} }
#endif /* LWIP_IPV6_MLD */ #endif /* LWIP_IPV6_MLD */
#if LWIP_IPV6_AUTOCONFIG #if LWIP_IPV6_AUTOCONFIG
/* IPv6 address autoconfiguration not enabled by default */ /* IPv6 address autoconfiguration not enabled by default */
lwip_netif.ip6_autoconfig_enabled = 1; lwip_netif.ip6_autoconfig_enabled = 1;
} else {
// Disable router solidifications
lwip_netif.rs_count = 0;
}
#endif /* LWIP_IPV6_AUTOCONFIG */ #endif /* LWIP_IPV6_AUTOCONFIG */
#endif // LWIP_IPV6 #endif // LWIP_IPV6
#if LWIP_IPV4 #if LWIP_IPV4
if (!dhcp && !ppp) { if (stack != IPV6_STACK) {
ip4_addr_t ip_addr; if (!dhcp && !ppp) {
ip4_addr_t netmask_addr; ip4_addr_t ip_addr;
ip4_addr_t gw_addr; ip4_addr_t netmask_addr;
ip4_addr_t gw_addr;
if (!inet_aton(ip, &ip_addr) || if (!inet_aton(ip, &ip_addr) ||
!inet_aton(netmask, &netmask_addr) || !inet_aton(netmask, &netmask_addr) ||
!inet_aton(gw, &gw_addr)) { !inet_aton(gw, &gw_addr)) {
return NSAPI_ERROR_PARAMETER; return NSAPI_ERROR_PARAMETER;
}
netif_set_addr(&lwip_netif, &ip_addr, &netmask_addr, &gw_addr);
} }
netif_set_addr(&lwip_netif, &ip_addr, &netmask_addr, &gw_addr);
} }
#endif #endif
@ -614,13 +620,15 @@ nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const cha
} }
#if LWIP_DHCP #if LWIP_DHCP
// Connect to the network if (stack != IPV6_STACK) {
lwip_dhcp = dhcp; // Connect to the network
lwip_dhcp = dhcp;
if (lwip_dhcp) { if (lwip_dhcp) {
err_t err = dhcp_start(&lwip_netif); err_t err = dhcp_start(&lwip_netif);
if (err) { if (err) {
return NSAPI_ERROR_DHCP_FAILURE; return NSAPI_ERROR_DHCP_FAILURE;
}
} }
} }
#endif #endif
@ -636,17 +644,21 @@ nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const cha
} }
#if PREF_ADDR_TIMEOUT #if PREF_ADDR_TIMEOUT
// If address is not for preferred stack waits a while to see if (stack != IPV4_STACK && stack != IPV6_STACK) {
// if preferred stack address is acquired // If address is not for preferred stack waits a while to see
if (!mbed_lwip_get_ip_addr(false, &lwip_netif)) { // if preferred stack address is acquired
sys_arch_sem_wait(&lwip_netif_has_pref_addr, PREF_ADDR_TIMEOUT * 1000); if (!mbed_lwip_get_ip_addr(false, &lwip_netif)) {
sys_arch_sem_wait(&lwip_netif_has_pref_addr, PREF_ADDR_TIMEOUT * 1000);
}
} }
#endif #endif
#if BOTH_ADDR_TIMEOUT #if BOTH_ADDR_TIMEOUT
// If addresses for both stacks are not available waits a while to if (stack != IPV4_STACK && stack != IPV6_STACK) {
// see if address for both stacks are acquired // If addresses for both stacks are not available waits a while to
if (!(mbed_lwip_get_ipv4_addr(&lwip_netif) && mbed_lwip_get_ipv6_addr(&lwip_netif))) { // see if address for both stacks are acquired
sys_arch_sem_wait(&lwip_netif_has_both_addr, BOTH_ADDR_TIMEOUT * 1000); if (!(mbed_lwip_get_ipv4_addr(&lwip_netif) && mbed_lwip_get_ipv6_addr(&lwip_netif))) {
sys_arch_sem_wait(&lwip_netif_has_both_addr, BOTH_ADDR_TIMEOUT * 1000);
}
} }
#endif #endif

View File

@ -29,7 +29,7 @@ extern "C" {
nsapi_error_t mbed_lwip_init(emac_interface_t *emac); nsapi_error_t mbed_lwip_init(emac_interface_t *emac);
nsapi_error_t mbed_lwip_emac_init(emac_interface_t *emac); nsapi_error_t mbed_lwip_emac_init(emac_interface_t *emac);
nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw); nsapi_error_t mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw);
nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const char *netmask, const char *gw); nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const char *netmask, const char *gw, const nsapi_ip_stack_t stack);
nsapi_error_t mbed_lwip_bringdown(void); nsapi_error_t mbed_lwip_bringdown(void);
nsapi_error_t mbed_lwip_bringdown_2(bool ppp); nsapi_error_t mbed_lwip_bringdown_2(bool ppp);

View File

@ -34,6 +34,16 @@
"value": false, "value": false,
"macro_name": "NSAPI_PPP_AVAILABLE" "macro_name": "NSAPI_PPP_AVAILABLE"
}, },
"ppp-ipv4-enabled": {
"help": "Enable support for ipv4 PPP interface",
"value": true,
"macro_name": "NSAPI_PPP_IPV4_AVAILABLE"
},
"ppp-ipv6-enabled": {
"help": "Enable support for ipv6 PPP interface",
"value": false,
"macro_name": "NSAPI_PPP_IPV6_AVAILABLE"
},
"use-mbed-trace": { "use-mbed-trace": {
"help": "Use mbed trace for debug, rather than printf", "help": "Use mbed trace for debug, rather than printf",
"value": false "value": false

View File

@ -313,7 +313,7 @@ extern "C" err_t ppp_lwip_disconnect()
return ret; return ret;
} }
extern "C" nsapi_error_t ppp_lwip_if_init(struct netif *netif) extern "C" nsapi_error_t ppp_lwip_if_init(struct netif *netif, const nsapi_ip_stack_t stack)
{ {
if (!prepare_event_queue()) { if (!prepare_event_queue()) {
return NSAPI_ERROR_NO_MEMORY; return NSAPI_ERROR_NO_MEMORY;
@ -330,9 +330,17 @@ extern "C" nsapi_error_t ppp_lwip_if_init(struct netif *netif)
} }
#if LWIP_IPV4 #if LWIP_IPV4
ppp_set_usepeerdns(my_ppp_pcb, true); if (stack != IPV6_STACK) {
ppp_set_usepeerdns(my_ppp_pcb, true);
}
#endif #endif
if (stack == IPV4_STACK) {
my_ppp_pcb->ipv6cp_disabled = true;
} else if (stack == IPV6_STACK) {
my_ppp_pcb->ipcp_disabled = true;
}
return NSAPI_ERROR_OK; return NSAPI_ERROR_OK;
} }
@ -341,7 +349,7 @@ nsapi_error_t nsapi_ppp_error_code()
return connect_error_code; return connect_error_code;
} }
nsapi_error_t nsapi_ppp_connect(FileHandle *stream, Callback<void(nsapi_error_t)> cb, const char *uname, const char *password) nsapi_error_t nsapi_ppp_connect(FileHandle *stream, Callback<void(nsapi_error_t)> cb, const char *uname, const char *password, const nsapi_ip_stack_t stack)
{ {
if (my_stream) { if (my_stream) {
return NSAPI_ERROR_PARAMETER; return NSAPI_ERROR_PARAMETER;
@ -354,7 +362,7 @@ nsapi_error_t nsapi_ppp_connect(FileHandle *stream, Callback<void(nsapi_error_t)
// mustn't start calling input until after connect - // mustn't start calling input until after connect -
// attach deferred until ppp_lwip_connect, called from mbed_lwip_bringup // attach deferred until ppp_lwip_connect, called from mbed_lwip_bringup
nsapi_error_t retcode = mbed_lwip_bringup_2(false, true, NULL, NULL, NULL); nsapi_error_t retcode = mbed_lwip_bringup_2(false, true, NULL, NULL, NULL, stack);
if (retcode != NSAPI_ERROR_OK && connect_error_code != NSAPI_ERROR_OK) { if (retcode != NSAPI_ERROR_OK && connect_error_code != NSAPI_ERROR_OK) {
return connect_error_code; return connect_error_code;
@ -388,7 +396,7 @@ const char *nsapi_ppp_get_ip_addr(FileHandle *stream)
} }
const char *nsapi_ppp_get_netmask(FileHandle *stream) const char *nsapi_ppp_get_netmask(FileHandle *stream)
{ {
#if LWIP_IPV6 #if !LWIP_IPV4
return NULL; return NULL;
#endif #endif
@ -403,7 +411,7 @@ const char *nsapi_ppp_get_netmask(FileHandle *stream)
} }
const char *nsapi_ppp_get_gw_addr(FileHandle *stream) const char *nsapi_ppp_get_gw_addr(FileHandle *stream)
{ {
#if LWIP_IPV6 #if !LWIP_IPV4
return NULL; return NULL;
#endif #endif

View File

@ -30,7 +30,7 @@ extern "C" {
* *
* @return 0 for success and negative error codes for failure * @return 0 for success and negative error codes for failure
*/ */
nsapi_error_t ppp_lwip_if_init(struct netif *netif); nsapi_error_t ppp_lwip_if_init(struct netif *netif, const nsapi_ip_stack_t stack);
/** Connects to a PPP pipe /** Connects to a PPP pipe
* *
@ -53,9 +53,9 @@ err_t ppp_lwip_disconnect(void);
/** /**
* Stubs in case LWIP PPP is not enabled * Stubs in case LWIP PPP is not enabled
*/ */
#define ppp_lwip_if_init(netif) NSAPI_ERROR_UNSUPPORTED #define ppp_lwip_if_init(netif, stack) NSAPI_ERROR_UNSUPPORTED
#define ppp_lwip_connect() ERR_IF #define ppp_lwip_connect() ERR_IF
#define ppp_lwip_disconnect() ERR_IF #define ppp_lwip_disconnect() ERR_IF
#endif //LWIP_PPP_API #endif //LWIP_PPP_API
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -262,6 +262,7 @@ PPPCellularInterface::PPPCellularInterface(FileHandle *fh, bool debug)
_pwd = NULL; _pwd = NULL;
_fh = fh; _fh = fh;
_debug_trace_on = debug; _debug_trace_on = debug;
_stack = DEFAULT_STACK;
dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING; dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING; dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
dev_info.ppp_connection_up = false; dev_info.ppp_connection_up = false;
@ -451,21 +452,38 @@ nsapi_error_t PPPCellularInterface::setup_context_and_credentials()
return NSAPI_ERROR_PARAMETER; return NSAPI_ERROR_PARAMETER;
} }
bool try_ipv6 = false; #if NSAPI_PPP_IPV4_AVAILABLE && NSAPI_PPP_IPV6_AVAILABLE
const char ipv4v6_pdp_type[] = {"IPV4V6"};
const char ipv4_pdp_type[] = {"IP"};
const char *pdp_type = ipv4v6_pdp_type;
_stack = IPV4V6_STACK;
#elif NSAPI_PPP_IPV6_AVAILABLE
const char pdp_type[] = {"IPV6"};
#elif NSAPI_PPP_IPV4_AVAILABLE
const char pdp_type[] = {"IP"};
#endif
const char *auth = _uname && _pwd ? "CHAP:" : ""; const char *auth = _uname && _pwd ? "CHAP:" : "";
retry_without_ipv6: #if NSAPI_PPP_IPV4_AVAILABLE && NSAPI_PPP_IPV6_AVAILABLE
retry_without_dual_stack:
#endif
success = _at->send("AT" success = _at->send("AT"
"+FCLASS=0;" // set to connection (ATD) to data mode "+FCLASS=0;" // set to connection (ATD) to data mode
"+CGDCONT="CTX",\"%s\",\"%s%s\"", "+CGDCONT="CTX",\"%s\",\"%s%s\"",
try_ipv6 ? "IPV4V6" : "IP", auth, _apn pdp_type, auth, _apn
) )
&& _at->recv("OK"); && _at->recv("OK");
if (!success && try_ipv6) { #if NSAPI_PPP_IPV4_AVAILABLE && NSAPI_PPP_IPV6_AVAILABLE
try_ipv6 = false; if (_stack == IPV4V6_STACK) {
goto retry_without_ipv6; if (!success) {
// fallback to ipv4
pdp_type = ipv4_pdp_type;
_stack = IPV4_STACK;
goto retry_without_dual_stack;
}
} }
#endif
if (!success) { if (!success) {
_at->recv("OK"); _at->recv("OK");
@ -662,7 +680,7 @@ nsapi_error_t PPPCellularInterface::connect()
/* Initialize PPP /* Initialize PPP
* mbed_ppp_init() is a blocking call, it will block until * mbed_ppp_init() is a blocking call, it will block until
* connected, or timeout after 30 seconds*/ * connected, or timeout after 30 seconds*/
retcode = nsapi_ppp_connect(_fh, _connection_status_cb, _uname, _pwd); retcode = nsapi_ppp_connect(_fh, _connection_status_cb, _uname, _pwd, _stack);
if (retcode == NSAPI_ERROR_OK) { if (retcode == NSAPI_ERROR_OK) {
dev_info.ppp_connection_up = true; dev_info.ppp_connection_up = true;
} }

View File

@ -252,6 +252,7 @@ private:
const char *_uname; const char *_uname;
const char *_pwd; const char *_pwd;
bool _debug_trace_on; bool _debug_trace_on;
nsapi_ip_stack_t _stack;
Callback<void(nsapi_error_t)> _connection_status_cb; Callback<void(nsapi_error_t)> _connection_status_cb;
void base_initialization(); void base_initialization();
void setup_at_parser(); void setup_at_parser();

View File

@ -36,10 +36,11 @@ NetworkStack *nsapi_ppp_get_stack();
* @param status_cb Optional, user provided callback for connection status * @param status_cb Optional, user provided callback for connection status
* @param uname Optional, username for the connection * @param uname Optional, username for the connection
* @param pwd Optional, password for the connection * @param pwd Optional, password for the connection
* @param stack Optional, stack for the connection
* *
* @return 0 on success, negative error code on failure * @return 0 on success, negative error code on failure
*/ */
nsapi_error_t nsapi_ppp_connect(FileHandle *stream, Callback<void(nsapi_error_t)> status_cb=0, const char *uname=0, const char *pwd=0); nsapi_error_t nsapi_ppp_connect(FileHandle *stream, Callback<void(nsapi_error_t)> status_cb=0, const char *uname=0, const char *pwd=0, const nsapi_ip_stack_t stack=DEFAULT_STACK);
/** Close a PPP connection /** Close a PPP connection
* *

View File

@ -216,6 +216,17 @@ typedef enum nsapi_socket_option {
NSAPI_RCVBUF, /*!< Sets recv buffer size */ NSAPI_RCVBUF, /*!< Sets recv buffer size */
} nsapi_socket_option_t; } nsapi_socket_option_t;
/** Supported IP protocol versions of IP stack
*
* @enum nsapi_ip_stack
*/
typedef enum nsapi_ip_stack {
DEFAULT_STACK = 0,
IPV4_STACK,
IPV6_STACK,
IPV4V6_STACK
} nsapi_ip_stack_t;
/* Backwards compatibility - previously didn't distinguish stack and socket options */ /* Backwards compatibility - previously didn't distinguish stack and socket options */
typedef nsapi_socket_level_t nsapi_level_t; typedef nsapi_socket_level_t nsapi_level_t;
typedef nsapi_socket_option_t nsapi_option_t; typedef nsapi_socket_option_t nsapi_option_t;