Created netsocket classes for PPP service and PPP interface

PPP service encapsulates the PPP protocol. PPP interface can be used as
helper class to bind PPP protocol with network stack (similar to
EMAC and L3IP interface). Added PPP interface to onboard network
stack class.
pull/10974/head
Mika Leppänen 2019-06-18 13:40:45 +03:00
parent a1e3a5d901
commit c9cb8f8296
5 changed files with 546 additions and 0 deletions

View File

@ -36,6 +36,7 @@ class WiFiInterface;
class MeshInterface;
class CellularInterface;
class EMACInterface;
class PPPInterface;
/** Common interface that is shared between network devices.
*
@ -338,6 +339,14 @@ public:
return 0;
}
/** Return pointer to a PPPInterface.
* @return Pointer to requested interface type or NULL if this class doesn't implement the interface.
*/
virtual PPPInterface *pppInterface()
{
return 0;
}
/** Return pointer to a CellularInterface.
* @return Pointer to requested interface type or NULL if this class doesn't implement the interface.
* @deprecated CellularBase migrated to CellularInterface - use cellularInterface()

View File

@ -22,6 +22,7 @@
#include "NetworkStack.h"
#include "EMAC.h"
#include "L3IP.h"
#include "PPP.h"
/**
* mbed OS API for onboard IP stack abstraction
@ -165,11 +166,21 @@ public:
return NSAPI_ERROR_OK;
};
virtual nsapi_error_t add_ppp_interface(PPP &ppp, bool default_if, Interface **interface_out)
{
return NSAPI_ERROR_UNSUPPORTED;
};
virtual nsapi_error_t remove_l3ip_interface(Interface **interface_out)
{
return NSAPI_ERROR_OK;
};
virtual nsapi_error_t remove_ppp_interface(Interface **interface_out)
{
return NSAPI_ERROR_UNSUPPORTED;
};
virtual void set_default_interface(OnboardNetworkStack::Interface *interface)
{
}

165
features/netsocket/PPP.h Normal file
View File

@ -0,0 +1,165 @@
/*
* 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.
*/
#ifndef PPP_H_
#define PPP_H_
#include <stdbool.h>
#include "Callback.h"
#include "FileHandle.h"
#include "NetStackMemoryManager.h"
class PPP {
public:
/** Return the default on-board PPP
*
* Returns the default on-board PPP - this will be target-specific, and
* may not be available on all targets.
*/
static PPP &get_default_instance();
virtual ~PPP() {};
/**
* Callback to be registered with PPP interface and to be called for received packets
*
* @param buf Received data
*/
//typedef void (*ppp_link_input_fn)(void *data, net_stack_mem_buf_t *buf);
typedef mbed::Callback<void (net_stack_mem_buf_t *buf)> ppp_link_input_cb_t;
/**
* Callback to be registered with PPP interface and to be called for link status changes
*
* @param up Link status
*/
//typedef void (*ppp_link_state_change_fn)(void *data, bool up);
typedef mbed::Callback<void (bool up)> ppp_link_state_change_cb_t;
/**
* Return maximum transmission unit
*
* @return MTU in bytes
*/
virtual uint32_t get_mtu_size() = 0;
/**
* Gets memory buffer alignment preference
*
* Gets preferred memory buffer alignment of the cellular device.
* @return Memory alignment requirement in bytes
*/
virtual uint32_t get_align_preference() const = 0;
/**
* Return interface name
*
* @param name Pointer to where the name should be written
* @param size Maximum number of characters to copy
*/
virtual void get_ifname(char *name, uint8_t size) const = 0;
/**
* Sends the packet over the link
*
* That cannot be called from an interrupt context.
*
* @param buf Packet to be sent
* @return True if the packet was sent, false otherwise
*/
virtual bool link_out(net_stack_mem_buf_t *buf, nsapi_ip_stack_t ip_stack) = 0;
/**
* Initializes the PPP
*
* @return True on success, False in case of an error.
*/
virtual bool power_up() = 0;
/**
* Deinitializes the PPP
*
*/
virtual void power_down() = 0;
/**
* Sets a callback that needs to be called for packets received for that interface
*
* @param input_cb Function to be register as a callback
*/
virtual void set_link_input_cb(ppp_link_input_cb_t input_cb) = 0;
/**
* Sets a callback that needs to be called on link status changes for given interface
*
* @param state_cb Function to be register as a callback
*/
virtual void set_link_state_cb(ppp_link_state_change_cb_t state_cb) = 0;
/** Sets memory manager that is used to handle memory buffers
*
* @param mem_mngr Pointer to memory manager
*/
virtual void set_memory_manager(NetStackMemoryManager &mem_mngr) = 0;
/** Sets file stream used to communicate with modem
*
* @param stream Pointer to file handle
*/
virtual void set_stream(mbed::FileHandle *stream) = 0;
/** Sets IP protocol versions of IP stack
*
* @param ip_stack IP protocol version
*/
virtual void set_ip_stack(nsapi_ip_stack_t ip_stack) = 0;
/** Sets user name and password for PPP protocol
*
* @param uname User name
* @param password Password
*/
virtual void set_credentials(const char *uname, const char *password) = 0;
/** Gets local IP address
*
* @param version IP address version
* @return IP address
*/
virtual const nsapi_addr_t *get_ip_address(nsapi_version_t version) = 0;
/** Get the local network mask.
*
* @return Local network mask or null if no network mask has been received.
*/
virtual const nsapi_addr_t *get_netmask() = 0;
/** Get the local gateway.
*
* @return Local gateway or null if no network mask has been received.
*/
virtual const nsapi_addr_t *get_gateway() = 0;
/** Gets DNS server address
*
* @param index Server index
*/
virtual const nsapi_addr_t *get_dns_server(uint8_t index) = 0;
};
#endif /* PPP_H_ */

View File

@ -0,0 +1,174 @@
/*
* 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 "PPPInterface.h"
using namespace mbed;
/* Interface implementation */
PPPInterface::PPPInterface(PPP &ppp, OnboardNetworkStack &stack) :
_ppp(ppp),
_stack(stack),
_interface(NULL),
_blocking(true),
_ip_address(),
_netmask(),
_gateway(),
_stream(NULL),
_ip_stack(DEFAULT_STACK),
_uname(NULL),
_password(NULL)
{
}
PPPInterface::~PPPInterface()
{
_stack.remove_ppp_interface(&_interface);
}
nsapi_error_t PPPInterface::set_network(const char *ip_address, const char *netmask, const char *gateway)
{
strncpy(_ip_address, ip_address ? ip_address : "", sizeof(_ip_address));
_ip_address[sizeof(_ip_address) - 1] = '\0';
strncpy(_netmask, netmask ? netmask : "", sizeof(_netmask));
_netmask[sizeof(_netmask) - 1] = '\0';
strncpy(_gateway, gateway ? gateway : "", sizeof(_gateway));
_gateway[sizeof(_gateway) - 1] = '\0';
return NSAPI_ERROR_OK;
}
nsapi_error_t PPPInterface::connect()
{
_ppp.set_stream(_stream);
_ppp.set_ip_stack(_ip_stack);
_ppp.set_credentials(_uname, _password);
if (!_interface) {
nsapi_error_t err = _stack.add_ppp_interface(_ppp, true, &_interface);
if (err != NSAPI_ERROR_OK) {
_interface = NULL;
return err;
}
_interface->attach(_connection_status_cb);
}
return _interface->bringup(false,
_ip_address[0] ? _ip_address : 0,
_netmask[0] ? _netmask : 0,
_gateway[0] ? _gateway : 0,
_ip_stack,
_blocking);
}
nsapi_error_t PPPInterface::disconnect()
{
if (_interface) {
return _interface->bringdown();
}
return NSAPI_ERROR_OK;
}
const char *PPPInterface::get_ip_address()
{
if (_interface && _interface->get_ip_address(_ip_address, sizeof(_ip_address))) {
return _ip_address;
}
return NULL;
}
const char *PPPInterface::get_netmask()
{
if (_interface && _interface->get_netmask(_netmask, sizeof(_netmask))) {
return _netmask;
}
return 0;
}
const char *PPPInterface::get_gateway()
{
if (_interface && _interface->get_gateway(_gateway, sizeof(_gateway))) {
return _gateway;
}
return 0;
}
char *PPPInterface::get_interface_name(char *interface_name)
{
if (_interface) {
return _interface->get_interface_name(interface_name);
}
return NULL;
}
void PPPInterface::set_as_default()
{
if (_interface) {
_stack.set_default_interface(_interface);
}
}
void PPPInterface::set_stream(mbed::FileHandle *stream)
{
_stream = stream;
}
void PPPInterface::set_ip_stack(nsapi_ip_stack_t ip_stack)
{
_ip_stack = ip_stack;
}
void PPPInterface::set_credentials(const char *uname, const char *password)
{
_uname = uname;
_password = password;
}
NetworkStack *PPPInterface::get_stack()
{
return &_stack;
}
void PPPInterface::attach(
mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
{
_connection_status_cb = status_cb;
if (_interface) {
_interface->attach(status_cb);
}
}
nsapi_connection_status_t PPPInterface::get_connection_status() const
{
if (_interface) {
return _interface->get_connection_status();
} else {
return NSAPI_STATUS_DISCONNECTED;
}
}
nsapi_error_t PPPInterface::set_blocking(bool blocking)
{
_blocking = blocking;
return NSAPI_ERROR_OK;
}

View File

@ -0,0 +1,187 @@
/*
* 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.
*/
#ifndef PPP_INTERFACE_H
#define PPP_INTERFACE_H
#include "nsapi.h"
#include "OnboardNetworkStack.h"
#include "NetworkInterface.h"
#include "PPP.h"
/** PPPInterface class
* Implementation of the NetworkInterface for an PPP-service
*
* This class provides the necessary glue logic to create a NetworkInterface
* based on an PPP and an OnboardNetworkStack.
*
*/
class PPPInterface : public virtual NetworkInterface {
public:
/** Create an PPP-based network interface.
*
* The default arguments obtain the default PPP, which will be target-
* dependent (and the target may have some JSON option to choose which
* is the default, if there are multiple). The default stack is configured
* by JSON option nsapi.default-stack.
*
* Due to inability to return errors from the constructor, no real
* work is done until the first call to connect().
*
* @param ppp Reference to PPP to use
* @param stack Reference to onboard-network stack to use
*/
PPPInterface(PPP &ppp = PPP::get_default_instance(),
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance());
virtual ~PPPInterface();
/** Set a static IP address
*
* Configures this network interface to use a static IP address.
* Implicitly disables DHCP, which can be enabled in set_dhcp.
* Requires that the network is disconnected.
*
* @param ip_address Null-terminated representation of the local IP address
* @param netmask Null-terminated representation of the local network mask
* @param gateway Null-terminated representation of the local gateway
* @return 0 on success, negative error code on failure
*/
virtual nsapi_error_t set_network(const char *ip_address, const char *netmask, const char *gateway);
/** Start the interface
* @return 0 on success, negative on failure
*/
virtual nsapi_error_t connect();
/** Stop the interface
* @return 0 on success, negative on failure
*/
virtual nsapi_error_t disconnect();
/** Get the local IP address
*
* @return Null-terminated representation of the local IP address
* or null if no IP address has been received
*/
virtual const char *get_ip_address();
/** Get the local network mask
*
* @return Null-terminated representation of the local network mask
* or null if no network mask has been received
*/
virtual const char *get_netmask();
/** Get the local gateways
*
* @return Null-terminated representation of the local gateway
* or null if no network mask has been received
*/
virtual const char *get_gateway();
/** Get the network interface name
*
* @return Null-terminated representation of the network interface name
* or null if interface not exists
*/
virtual char *get_interface_name(char *interface_name);
/** Set the network interface as default one
*/
virtual void set_as_default();
/** Register callback for status reporting
*
* @param status_cb The callback for status changes
*/
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
/** Get the connection status
*
* @return The connection status according to nsapi_connection_status_t
*/
virtual nsapi_connection_status_t get_connection_status() const;
/** Set blocking status of connect() which by default should be blocking
*
* @param blocking true if connect is blocking
* @return 0 on success, negative error code on failure
*/
virtual nsapi_error_t set_blocking(bool blocking);
/** Sets file stream used to communicate with modem
*
* @param stream Pointer to file handle
*/
virtual void set_stream(mbed::FileHandle *stream);
/** Sets IP protocol versions of IP stack
*
* @param ip_stack IP protocol version
*/
virtual void set_ip_stack(nsapi_ip_stack_t ip_stack);
/** Sets user name and password for PPP protocol
*
* @param uname User name
* @param password Password
*/
virtual void set_credentials(const char *uname, const char *password);
/** Provide access to the PPP
*
* This should be used with care - normally the network stack would
* control the PPP, so manipulating the PPP while the stack
* is also using it (ie after connect) will likely cause problems.
*
* @return Reference to the PPP in use
*/
PPP &getppp() const
{
return _ppp;
}
virtual PPPInterface *pppInterface()
{
return this;
}
protected:
/** Provide access to the underlying stack
*
* @return The underlying network stack
*/
virtual NetworkStack *get_stack();
PPP &_ppp;
OnboardNetworkStack &_stack;
OnboardNetworkStack::Interface *_interface;
bool _blocking;
char _ip_address[NSAPI_IPv6_SIZE];
char _netmask[NSAPI_IPv4_SIZE];
char _gateway[NSAPI_IPv4_SIZE];
mbed::Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
mbed::FileHandle *_stream;
nsapi_ip_stack_t _ip_stack;
const char *_uname;
const char *_password;
};
#endif