Skip to content

Created PPP interface and PPP service classes to netsocket #10974

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Aug 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .astyleignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
^features/nanostack/sal-stack-nanostack
^features/nanostack/targets
^features/netsocket/emac-drivers
^features/netsocket/ppp/include
^features/netsocket/ppp/polarssl
^features/netsocket/ppp/source
^features/storage/filesystem/fat/ChaN
^features/storage/filesystem/littlefs/littlefs/
^features/unsupported/
Expand Down
121 changes: 73 additions & 48 deletions features/lwipstack/LWIPInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
#include "lwip/dns.h"
#include "lwip/udp.h"

#include "ppp_lwip.h"

#include "LWIPStack.h"

LWIP::Interface *LWIP::Interface::list;
Expand Down Expand Up @@ -352,7 +350,7 @@ char *LWIP::Interface::get_gateway(char *buf, nsapi_size_t buflen)
LWIP::Interface::Interface() :
hw(NULL), has_addr_state(0),
connected(NSAPI_STATUS_DISCONNECTED),
dhcp_started(false), dhcp_has_to_be_set(false), blocking(true), ppp(false)
dhcp_started(false), dhcp_has_to_be_set(false), blocking(true), ppp_enabled(false)
{
memset(&netif, 0, sizeof netif);

Expand Down Expand Up @@ -395,7 +393,7 @@ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardN
}
interface->emac = &emac;
interface->memory_manager = &memory_manager;
interface->ppp = false;
interface->ppp_enabled = false;

#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
netif->interface.hwaddr[0] = MBED_MAC_ADDR_0;
Expand Down Expand Up @@ -452,7 +450,7 @@ nsapi_error_t LWIP::add_l3ip_interface(L3IP &l3ip, bool default_if, OnboardNetwo
}
interface->l3ip = &l3ip;
interface->memory_manager = &memory_manager;
interface->ppp = false;
interface->ppp_enabled = false;



Expand All @@ -462,7 +460,7 @@ nsapi_error_t LWIP::add_l3ip_interface(L3IP &l3ip, bool default_if, OnboardNetwo
#if LWIP_IPV4
0, 0, 0,
#endif
interface, &LWIP::Interface::l3ip_if_init, tcpip_input)) {
interface, &LWIP::Interface::l3ip_if_init, ip_input)) {
return NSAPI_ERROR_DEVICE_ERROR;
}

Expand Down Expand Up @@ -521,21 +519,27 @@ nsapi_error_t LWIP::remove_l3ip_interface(OnboardNetworkStack::Interface **inter

#endif //LWIP_L3IP
}
/* Internal API to preserve existing PPP functionality - revise to better match mbed_ipstak_add_ethernet_interface later */
nsapi_error_t LWIP::_add_ppp_interface(void *hw, bool default_if, nsapi_ip_stack_t stack, LWIP::Interface **interface_out)


nsapi_error_t LWIP::add_ppp_interface(PPP &ppp, bool default_if, OnboardNetworkStack::Interface **interface_out)
{
#if LWIP_PPP_API
#if PPP_SUPPORT
Interface *interface = new (std::nothrow) Interface();
if (!interface) {
return NSAPI_ERROR_NO_MEMORY;
}
interface->hw = hw;
interface->ppp = true;
interface->ppp = &ppp;
interface->memory_manager = &memory_manager;
interface->ppp_enabled = true;

nsapi_error_t ret = ppp_lwip_if_init(hw, &interface->netif, stack);
if (ret != NSAPI_ERROR_OK) {
free(interface);
return ret;
// interface->netif.hwaddr_len = 0; should we set?

if (!netif_add(&interface->netif,
#if LWIP_IPV4
0, 0, 0,
#endif
interface, &LWIP::Interface::ppp_if_init, tcpip_input)) {
return NSAPI_ERROR_DEVICE_ERROR;
}

if (default_if) {
Expand All @@ -548,11 +552,62 @@ nsapi_error_t LWIP::_add_ppp_interface(void *hw, bool default_if, nsapi_ip_stack

*interface_out = interface;

//lwip_add_random_seed(seed); to do?

return NSAPI_ERROR_OK;

#else
return NSAPI_ERROR_UNSUPPORTED;

#endif //PPP_SUPPORT
}

nsapi_error_t LWIP::remove_ppp_interface(OnboardNetworkStack::Interface **interface_out)
{
#if PPP_SUPPORT
if ((interface_out != NULL) && (*interface_out != NULL)) {

Interface *lwip = static_cast<Interface *>(*interface_out);
Interface *node = lwip->list;

if (lwip->list != NULL) {
if (lwip->list == lwip) {
// Power down PPP service
lwip->ppp->power_down();
if (netif_is_link_up(&lwip->netif)) {
// Wait PPP service to report link down
osSemaphoreAcquire(lwip->unlinked, osWaitForever);
}
netif_remove(&node->netif);
lwip->list = lwip->list->next;
delete node;
} else {
while (node->next != NULL && node->next != lwip) {
node = node->next;
}
if (node->next != NULL && node->next == lwip) {
Interface *remove = node->next;
// Power down PPP service
remove->ppp->power_down();
if (netif_is_link_up(&lwip->netif)) {
// Wait PPP service to report link down
osSemaphoreAcquire(lwip->unlinked, osWaitForever);
}
netif_remove(&remove->netif);
node->next = node->next->next;
delete remove;
}
}
}
}

return NSAPI_ERROR_OK;
#else
return NSAPI_ERROR_UNSUPPORTED;
#endif //LWIP_PPP_API

#endif //PPP_SUPPORT
}

void LWIP::set_default_interface(OnboardNetworkStack::Interface *interface)
{
if (interface) {
Expand Down Expand Up @@ -609,7 +664,7 @@ nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *ne

#if LWIP_IPV4
if (stack != IPV6_STACK) {
if (!dhcp && !ppp) {
if (!dhcp && !ppp_enabled) {
ip4_addr_t ip_addr;
ip4_addr_t netmask_addr;
ip4_addr_t gw_addr;
Expand All @@ -629,23 +684,10 @@ nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *ne
client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING);
}

if (ppp) {
err_t err = ppp_lwip_connect(hw);
if (err) {
connected = NSAPI_STATUS_DISCONNECTED;
if (client_callback) {
client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED);
}
return err_remap(err);
}
}

if (!netif_is_link_up(&netif)) {
if (blocking) {
if (osSemaphoreAcquire(linked, LINK_TIMEOUT * 1000) != osOK) {
if (ppp) {
(void) ppp_lwip_disconnect(hw);
}
return NSAPI_ERROR_NO_CONNECTION;
}
}
Expand All @@ -665,9 +707,6 @@ nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *ne
// If doesn't have address
if (!LWIP::get_ip_addr(true, &netif)) {
if (osSemaphoreAcquire(has_any_addr, DHCP_TIMEOUT * 1000) != osOK) {
if (ppp) {
(void) ppp_lwip_disconnect(hw);
}
return NSAPI_ERROR_DHCP_FAILURE;
}
}
Expand Down Expand Up @@ -713,21 +752,7 @@ nsapi_error_t LWIP::Interface::bringdown()
}
#endif

if (ppp) {
/* this is a blocking call, returns when PPP is properly closed */
err_t err = ppp_lwip_disconnect(hw);
if (err) {
return err_remap(err);
}
MBED_ASSERT(!netif_is_link_up(&netif));
/*if (netif_is_link_up(&netif)) {
if (sys_arch_sem_wait(&unlinked, 15000) == SYS_ARCH_TIMEOUT) {
return NSAPI_ERROR_DEVICE_ERROR;
}
}*/
} else {
netif_set_down(&netif);
}
netif_set_down(&netif);

#if LWIP_IPV6
mbed_lwip_clear_ipv6_addresses(&netif);
Expand Down
166 changes: 166 additions & 0 deletions features/lwipstack/LWIPInterfacePPP.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* Copyright (c) 2019 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/

#include "lwip/tcpip.h"
#include "lwip/tcp.h"
#include "lwip/ip.h"
#include "lwip/ip_addr.h"
#include "lwip/dns.h"
#include "netif/etharp.h"
#include "lwip/ethip6.h"
#include "netsocket/nsapi_types.h"
#include "netsocket/PPP.h"
#include "LWIPStack.h"
#include "lwip_tools.h"

#if PPP_SUPPORT

#if PPP_IPV4_SUPPORT && LWIP_IPV4
err_t LWIP::Interface::ppp4_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
{
/* Increase reference counter since lwip stores handle to pbuf and frees
it after output */
pbuf_ref(p);

LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
bool ret = mbed_if->ppp->link_out(p, IPV4_STACK);
return ret ? ERR_OK : ERR_IF;
}
#endif
#if PPP_IPV6_SUPPORT && LWIP_IPV6
err_t LWIP::Interface::ppp6_output(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
{
/* Increase reference counter since lwip stores handle to pbuf and frees
it after output */
pbuf_ref(p);

LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
bool ret = mbed_if->ppp->link_out(p, IPV6_STACK);
return ret ? ERR_OK : ERR_IF;
}
#endif
void LWIP::Interface::ppp_input(net_stack_mem_buf_t *buf)
{
struct pbuf *p = static_cast<struct pbuf *>(buf);

/* pass all packets to IP stack input */
if (netif.input(p, &netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Emac LWIP: IP input error\n"));

pbuf_free(p);
}
}

void LWIP::Interface::ppp_state_change(bool up)
{
if (up) {
#if PPP_IPV6_SUPPORT && LWIP_IPV6
const nsapi_addr_t *ipv6_addr = LWIP::Interface::ppp->get_ip_address(NSAPI_IPv6);

ip_addr_t ip_addr;
if (ipv6_addr && convert_mbed_addr_to_lwip(&ip_addr, ipv6_addr)) {
netif_ip6_addr_set(&netif, 0, ip_2_ip6(&ip_addr));
netif_ip6_addr_set_state(&netif, 0, IP6_ADDR_PREFERRED);
}
#endif

#if PPP_IPV4_SUPPORT && LWIP_IPV4
const nsapi_addr_t *ipv4_addr = LWIP::Interface::ppp->get_ip_address(NSAPI_IPv4);
if (ipv4_addr) {
ip_addr_t ip_addr;
ip_addr_t netmask;
ip_addr_t gateway;

int conv_ip = 0;
if (convert_mbed_addr_to_lwip(&ip_addr, ipv4_addr)) {
conv_ip++;
}

const nsapi_addr_t *ipv4_netmask = LWIP::Interface::ppp->get_netmask();
if (ipv4_netmask && convert_mbed_addr_to_lwip(&netmask, ipv4_netmask)) {
conv_ip++;
}

const nsapi_addr_t *ipv4_gateway = LWIP::Interface::ppp->get_gateway();
if (ipv4_gateway && convert_mbed_addr_to_lwip(&gateway, ipv4_gateway)) {
conv_ip++;
}

if (conv_ip == 3) {
netif_set_addr(&netif, ip_2_ip4(&ip_addr), ip_2_ip4(&netmask), ip_2_ip4(&gateway));
}

unsigned char dns_index = 0;
// If default interface set default DNS addresses, otherwise interface specific
struct netif *dns_netif = &netif;
if (netif_check_default(&netif)) {
dns_netif = NULL;
}
for (unsigned char index = 0; index < 2; index++) {
ip_addr_t dns_server;
const nsapi_addr_t *ipv4_dns_server = LWIP::Interface::ppp->get_dns_server(index);
if (ipv4_dns_server && convert_mbed_addr_to_lwip(&dns_server, ipv4_dns_server)) {
dns_setserver(dns_index++, &dns_server, dns_netif);
}
}
}
#endif
// Read negotiated MTU
uint32_t mtu = LWIP::Interface::ppp->get_mtu_size();
netif.mtu = mtu;
#if PPP_IPV6_SUPPORT && LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
netif.mtu6 = mtu;
#endif
tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, &netif, 1);
} else {
tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, &netif, 1);
}
}

err_t LWIP::Interface::ppp_if_init(struct netif *netif)
{
int err = ERR_OK;
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);

mbed_if->ppp->set_memory_manager(*mbed_if->memory_manager);
mbed_if->ppp->set_link_input_cb(mbed::callback(mbed_if, &LWIP::Interface::ppp_input));
mbed_if->ppp->set_link_state_cb(mbed::callback(mbed_if, &LWIP::Interface::ppp_state_change));

/* Interface capabilities */
netif->flags = NETIF_FLAG_BROADCAST;

if (!mbed_if->ppp->power_up()) {
err = ERR_IF;
}

netif->mtu = mbed_if->ppp->get_mtu_size();
mbed_if->ppp->get_ifname(netif->name, NSAPI_INTERFACE_PREFIX_SIZE);

#if PPP_IPV4_SUPPORT && LWIP_IPV4
netif->output = &LWIP::Interface::ppp4_output;
#endif /* PPP_IPV4_SUPPORT */
#if PPP_IPV6_SUPPORT && LWIP_IPV6
netif->output_ip6 = &LWIP::Interface::ppp6_output;
#endif
netif->linkoutput = NULL;

return err;
}

#endif


Loading