mirror of https://github.com/ARMmbed/mbed-os.git
L3IP Interface Implementation
LWIP L3IP interface initial implementatioonpull/8739/head
parent
ab1c2be997
commit
fc88922845
|
@ -409,6 +409,60 @@ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardN
|
|||
#endif //LWIP_ETHERNET
|
||||
}
|
||||
|
||||
|
||||
nsapi_error_t LWIP::add_l3ip_interface(L3IP &l3ip, bool default_if, OnboardNetworkStack::Interface **interface_out)
|
||||
{
|
||||
#if LWIP_L3IP
|
||||
Interface *interface = new (std::nothrow) Interface();
|
||||
if (!interface) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
interface->l3ip = &l3ip;
|
||||
interface->memory_manager = &memory_manager;
|
||||
interface->ppp = false;
|
||||
|
||||
|
||||
|
||||
// interface->netif.hwaddr_len = 0; should we set?
|
||||
|
||||
if (!netif_add(&interface->netif,
|
||||
#if LWIP_IPV4
|
||||
0, 0, 0,
|
||||
#endif
|
||||
interface, &LWIP::Interface::emac_if_init, ip_input)) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (default_if) {
|
||||
netif_set_default(&interface->netif);
|
||||
default_interface = interface;
|
||||
}
|
||||
|
||||
netif_set_link_callback(&interface->netif, &LWIP::Interface::netif_link_irq);
|
||||
netif_set_status_callback(&interface->netif, &LWIP::Interface::netif_status_irq);
|
||||
|
||||
*interface_out = interface;
|
||||
|
||||
|
||||
//lwip_add_random_seed(seed); to do?
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
|
||||
#else
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
|
||||
#endif //LWIP_L3IP
|
||||
}
|
||||
|
||||
nsapi_error_t LWIP::remove_l3ip_interface(OnboardNetworkStack::Interface **interface_out)
|
||||
{
|
||||
#if LWIP_L3IP
|
||||
return NSAPI_ERROR_OK;
|
||||
#else
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
|
||||
#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)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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 "netif/etharp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netsocket/nsapi_types.h"
|
||||
#include "netsocket/L3IP.h"
|
||||
|
||||
#include "LWIPStack.h"
|
||||
|
||||
#if LWIP_L3IP
|
||||
|
||||
err_t LWIP::Interface::l3ip_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->l3ip->link_out(p);
|
||||
return ret ? ERR_OK : ERR_IF;
|
||||
}
|
||||
|
||||
void LWIP::Interface::l3ip_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::l3ip_state_change(bool up)
|
||||
{
|
||||
if (up) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#if LWIP_IGMP
|
||||
|
||||
#include "lwip/igmp.h"
|
||||
/**
|
||||
* IPv4 address filtering setup.
|
||||
*
|
||||
* \param[in] netif the lwip network interface structure
|
||||
* \param[in] group IPv4 group to modify
|
||||
* \param[in] action
|
||||
* \return ERR_OK or error code
|
||||
*/
|
||||
err_t LWIP::Interface::l3ip_multicast_ipv4_filter(struct netif *netif, const ip4_addr_t *group, enum netif_mac_filter_action action)
|
||||
{
|
||||
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
|
||||
SocketAddress addr(&group, NSAPI_IPv6);
|
||||
switch (action) {
|
||||
case NETIF_ADD_MAC_FILTER: {
|
||||
mbed_if->l3ip->add_ipv4_multicast_group(addr.get_ip_address());
|
||||
return ERR_OK;
|
||||
}
|
||||
case NETIF_DEL_MAC_FILTER:
|
||||
mbed_if->l3ip->remove_ipv4_multicast_group(addr.get_ip_address());
|
||||
return ERR_OK;
|
||||
default:
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6_MLD
|
||||
|
||||
#include "lwip/mld6.h"
|
||||
/**
|
||||
* IPv6 address filtering setup.
|
||||
*
|
||||
* \param[in] netif the lwip network interface structure
|
||||
* \param[in] group IPv6 group to modify
|
||||
* \param[in] action
|
||||
* \return ERR_OK or error code
|
||||
*/
|
||||
err_t LWIP::Interface::l3ip_multicast_ipv6_filter(struct netif *netif, const ip6_addr_t *group, enum netif_mac_filter_action action)
|
||||
{
|
||||
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
|
||||
SocketAddress addr(&group, NSAPI_IPv6);
|
||||
switch (action) {
|
||||
case NETIF_ADD_MAC_FILTER: {
|
||||
|
||||
mbed_if->l3ip->add_ipv6_multicast_group(addr.get_ip_address());
|
||||
return ERR_OK;
|
||||
}
|
||||
case NETIF_DEL_MAC_FILTER:
|
||||
mbed_if->l3ip->remove_ipv6_multicast_group(addr.get_ip_address());
|
||||
return ERR_OK;
|
||||
default:
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
err_t LWIP::Interface::l3ip_if_init(struct netif *netif)
|
||||
{
|
||||
int err = ERR_OK;
|
||||
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
|
||||
|
||||
mbed_if->l3ip->set_memory_manager(*mbed_if->memory_manager);
|
||||
mbed_if->l3ip->set_link_input_cb(mbed::callback(mbed_if, &LWIP::Interface::l3ip_input));
|
||||
mbed_if->l3ip->set_link_state_cb(mbed::callback(mbed_if, &LWIP::Interface::l3ip_state_change));
|
||||
|
||||
/* Interface capabilities */
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET;
|
||||
|
||||
if (!mbed_if->l3ip->power_up()) {
|
||||
err = ERR_IF;
|
||||
}
|
||||
|
||||
netif->mtu = mbed_if->l3ip->get_mtu_size();
|
||||
mbed_if->l3ip->get_ifname(netif->name, NSAPI_INTERFACE_NAME_SIZE);
|
||||
|
||||
#if LWIP_IPV4
|
||||
netif->output = &LWIP::Interface::l3ip_output;
|
||||
#if LWIP_IGMP
|
||||
netif->igmp_mac_filter = &LWIP::Interface::l3ip_multicast_ipv4_filter;
|
||||
netif->flags |= NETIF_FLAG_IGMP;
|
||||
#endif /* LWIP_IGMP */
|
||||
#endif /* LWIP_IPV4 */
|
||||
#if LWIP_IPV6
|
||||
//netif->output_ip6 = ethip6_output;//to be done
|
||||
#if LWIP_IPV6_MLD
|
||||
netif->mld_mac_filter = &LWIP::Interface::l3ip_multicast_ipv6_filter;
|
||||
netif->flags |= NETIF_FLAG_MLD6;
|
||||
#else
|
||||
// Would need to enable all multicasts here - no API in fsl_enet to do that
|
||||
#error "IPv6 multicasts won't be received if LWIP_IPV6_MLD is disabled, breaking the system"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
netif->linkoutput = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
#include "pbuf.h"
|
||||
#include "LWIPMemoryManager.h"
|
||||
|
||||
emac_mem_buf_t *LWIPMemoryManager::alloc_heap(uint32_t size, uint32_t align)
|
||||
net_stack_mem_buf_t *LWIPMemoryManager::alloc_heap(uint32_t size, uint32_t align)
|
||||
{
|
||||
struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + align, PBUF_RAM);
|
||||
if (pbuf == NULL) {
|
||||
|
@ -25,10 +25,10 @@ emac_mem_buf_t *LWIPMemoryManager::alloc_heap(uint32_t size, uint32_t align)
|
|||
|
||||
align_memory(pbuf, align);
|
||||
|
||||
return static_cast<emac_mem_buf_t *>(pbuf);
|
||||
return static_cast<net_stack_mem_buf_t *>(pbuf);
|
||||
}
|
||||
|
||||
emac_mem_buf_t *LWIPMemoryManager::alloc_pool(uint32_t size, uint32_t align)
|
||||
net_stack_mem_buf_t *LWIPMemoryManager::alloc_pool(uint32_t size, uint32_t align)
|
||||
{
|
||||
uint32_t total_align = count_total_align(size, align);
|
||||
|
||||
|
@ -39,7 +39,7 @@ emac_mem_buf_t *LWIPMemoryManager::alloc_pool(uint32_t size, uint32_t align)
|
|||
|
||||
align_memory(pbuf, align);
|
||||
|
||||
return static_cast<emac_mem_buf_t *>(pbuf);
|
||||
return static_cast<net_stack_mem_buf_t *>(pbuf);
|
||||
}
|
||||
|
||||
uint32_t LWIPMemoryManager::get_pool_alloc_unit(uint32_t align) const
|
||||
|
@ -48,56 +48,56 @@ uint32_t LWIPMemoryManager::get_pool_alloc_unit(uint32_t align) const
|
|||
return alloc_unit;
|
||||
}
|
||||
|
||||
void LWIPMemoryManager::free(emac_mem_buf_t *buf)
|
||||
void LWIPMemoryManager::free(net_stack_mem_buf_t *buf)
|
||||
{
|
||||
pbuf_free(static_cast<struct pbuf *>(buf));
|
||||
}
|
||||
|
||||
uint32_t LWIPMemoryManager::get_total_len(const emac_mem_buf_t *buf) const
|
||||
uint32_t LWIPMemoryManager::get_total_len(const net_stack_mem_buf_t *buf) const
|
||||
{
|
||||
return (static_cast<const struct pbuf *>(buf))->tot_len;
|
||||
}
|
||||
|
||||
void LWIPMemoryManager::copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf)
|
||||
void LWIPMemoryManager::copy(net_stack_mem_buf_t *to_buf, const net_stack_mem_buf_t *from_buf)
|
||||
{
|
||||
pbuf_copy(static_cast<struct pbuf *>(to_buf), static_cast<const struct pbuf *>(from_buf));
|
||||
}
|
||||
|
||||
void LWIPMemoryManager::copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len)
|
||||
void LWIPMemoryManager::copy_to_buf(net_stack_mem_buf_t *to_buf, const void *ptr, uint32_t len)
|
||||
{
|
||||
pbuf_take(static_cast<struct pbuf *>(to_buf), ptr, len);
|
||||
}
|
||||
|
||||
uint32_t LWIPMemoryManager::copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const
|
||||
uint32_t LWIPMemoryManager::copy_from_buf(void *ptr, uint32_t len, const net_stack_mem_buf_t *from_buf) const
|
||||
{
|
||||
return pbuf_copy_partial(static_cast<const struct pbuf *>(from_buf), ptr, len, 0);
|
||||
}
|
||||
|
||||
void LWIPMemoryManager::cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf)
|
||||
void LWIPMemoryManager::cat(net_stack_mem_buf_t *to_buf, net_stack_mem_buf_t *cat_buf)
|
||||
{
|
||||
pbuf_cat(static_cast<struct pbuf *>(to_buf), static_cast<struct pbuf *>(cat_buf));
|
||||
}
|
||||
|
||||
emac_mem_buf_t *LWIPMemoryManager::get_next(const emac_mem_buf_t *buf) const
|
||||
net_stack_mem_buf_t *LWIPMemoryManager::get_next(const net_stack_mem_buf_t *buf) const
|
||||
{
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
struct pbuf *next = (static_cast<const struct pbuf *>(buf))->next;
|
||||
return static_cast<emac_mem_buf_t *>(next);
|
||||
return static_cast<net_stack_mem_buf_t *>(next);
|
||||
}
|
||||
|
||||
void *LWIPMemoryManager::get_ptr(const emac_mem_buf_t *buf) const
|
||||
void *LWIPMemoryManager::get_ptr(const net_stack_mem_buf_t *buf) const
|
||||
{
|
||||
return (static_cast<const struct pbuf *>(buf))->payload;
|
||||
}
|
||||
|
||||
uint32_t LWIPMemoryManager::get_len(const emac_mem_buf_t *buf) const
|
||||
uint32_t LWIPMemoryManager::get_len(const net_stack_mem_buf_t *buf) const
|
||||
{
|
||||
return (static_cast<const struct pbuf *>(buf))->len;
|
||||
}
|
||||
|
||||
void LWIPMemoryManager::set_len(emac_mem_buf_t *buf, uint32_t len)
|
||||
void LWIPMemoryManager::set_len(net_stack_mem_buf_t *buf, uint32_t len)
|
||||
{
|
||||
struct pbuf *pbuf = static_cast<struct pbuf *>(buf);
|
||||
pbuf->len = len;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "EMACMemoryManager.h"
|
||||
|
||||
|
||||
class LWIPMemoryManager : public EMACMemoryManager {
|
||||
public:
|
||||
|
||||
|
@ -30,7 +31,7 @@ public:
|
|||
* @param align Memory alignment requirement in bytes
|
||||
* @return Allocated memory buffer, or NULL in case of error
|
||||
*/
|
||||
virtual emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align);
|
||||
virtual net_stack_mem_buf_t *alloc_heap(uint32_t size, uint32_t align);
|
||||
|
||||
/**
|
||||
* Allocates memory buffer chain from a pool
|
||||
|
@ -43,7 +44,7 @@ public:
|
|||
* @param align Memory alignment requirement for each buffer in bytes
|
||||
* @return Allocated memory buffer chain, or NULL in case of error
|
||||
*/
|
||||
virtual emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align);
|
||||
virtual net_stack_mem_buf_t *alloc_pool(uint32_t size, uint32_t align);
|
||||
|
||||
/**
|
||||
* Get memory buffer pool allocation unit
|
||||
|
@ -63,7 +64,7 @@ public:
|
|||
*
|
||||
* @param buf Memory buffer chain to be freed.
|
||||
*/
|
||||
virtual void free(emac_mem_buf_t *buf);
|
||||
virtual void free(net_stack_mem_buf_t *buf);
|
||||
|
||||
/**
|
||||
* Return total length of a memory buffer chain
|
||||
|
@ -73,7 +74,7 @@ public:
|
|||
* @param buf Memory buffer chain
|
||||
* @return Total length in bytes
|
||||
*/
|
||||
virtual uint32_t get_total_len(const emac_mem_buf_t *buf) const;
|
||||
virtual uint32_t get_total_len(const net_stack_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Copy a memory buffer chain
|
||||
|
@ -84,7 +85,7 @@ public:
|
|||
* @param to_buf Memory buffer chain to copy to
|
||||
* @param from_buf Memory buffer chain to copy from
|
||||
*/
|
||||
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf);
|
||||
virtual void copy(net_stack_mem_buf_t *to_buf, const net_stack_mem_buf_t *from_buf);
|
||||
|
||||
/**
|
||||
* Copy to a memory buffer chain
|
||||
|
@ -97,7 +98,7 @@ public:
|
|||
* @param ptr Pointer to data
|
||||
* @param len Data length
|
||||
*/
|
||||
virtual void copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len);
|
||||
virtual void copy_to_buf(net_stack_mem_buf_t *to_buf, const void *ptr, uint32_t len);
|
||||
|
||||
/**
|
||||
* Copy from a memory buffer chain
|
||||
|
@ -109,7 +110,7 @@ public:
|
|||
* @param from_buf Memory buffer chain to copy from
|
||||
* @return Length of the data that was copied
|
||||
*/
|
||||
virtual uint32_t copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const;
|
||||
virtual uint32_t copy_from_buf(void *ptr, uint32_t len, const net_stack_mem_buf_t *from_buf) const;
|
||||
|
||||
/**
|
||||
* Concatenate two memory buffer chains
|
||||
|
@ -121,7 +122,7 @@ public:
|
|||
* @param to_buf Memory buffer chain to concatenate to
|
||||
* @param cat_buf Memory buffer chain to concatenate
|
||||
*/
|
||||
virtual void cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf);
|
||||
virtual void cat(net_stack_mem_buf_t *to_buf, net_stack_mem_buf_t *cat_buf);
|
||||
|
||||
/**
|
||||
* Returns the next buffer
|
||||
|
@ -131,7 +132,7 @@ public:
|
|||
* @param buf Memory buffer
|
||||
* @return The next memory buffer, or NULL if last
|
||||
*/
|
||||
virtual emac_mem_buf_t *get_next(const emac_mem_buf_t *buf) const;
|
||||
virtual net_stack_mem_buf_t *get_next(const net_stack_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Return pointer to the payload of the buffer
|
||||
|
@ -139,7 +140,7 @@ public:
|
|||
* @param buf Memory buffer
|
||||
* @return Pointer to the payload
|
||||
*/
|
||||
virtual void *get_ptr(const emac_mem_buf_t *buf) const;
|
||||
virtual void *get_ptr(const net_stack_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Return payload size of the buffer
|
||||
|
@ -147,7 +148,7 @@ public:
|
|||
* @param buf Memory buffer
|
||||
* @return Size in bytes
|
||||
*/
|
||||
virtual uint32_t get_len(const emac_mem_buf_t *buf) const;
|
||||
virtual uint32_t get_len(const net_stack_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Sets the payload size of the buffer
|
||||
|
@ -158,7 +159,7 @@ public:
|
|||
* @param buf Memory buffer
|
||||
* @param len Payload size, must be less or equal allocated size
|
||||
*/
|
||||
virtual void set_len(emac_mem_buf_t *buf, uint32_t len);
|
||||
virtual void set_len(net_stack_mem_buf_t *buf, uint32_t len);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "lwip/ethip6.h"
|
||||
#include "netsocket/nsapi_types.h"
|
||||
#include "netsocket/EMAC.h"
|
||||
#include "netsocket/L3IP.h"
|
||||
#include "netsocket/OnboardNetworkStack.h"
|
||||
#include "LWIPMemoryManager.h"
|
||||
|
||||
|
@ -122,7 +123,7 @@ public:
|
|||
|
||||
#if LWIP_ETHERNET
|
||||
static err_t emac_low_level_output(struct netif *netif, struct pbuf *p);
|
||||
void emac_input(emac_mem_buf_t *buf);
|
||||
void emac_input(net_stack_mem_buf_t *buf);
|
||||
void emac_state_change(bool up);
|
||||
#if LWIP_IGMP
|
||||
static err_t emac_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group, enum netif_mac_filter_action action);
|
||||
|
@ -134,10 +135,28 @@ public:
|
|||
static err_t emac_if_init(struct netif *netif);
|
||||
#endif
|
||||
|
||||
#if LWIP_L3IP
|
||||
static err_t l3ip_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr);
|
||||
void l3ip_input(net_stack_mem_buf_t *buf);
|
||||
void l3ip_state_change(bool up);
|
||||
#if LWIP_IGMP
|
||||
static err_t l3ip_multicast_ipv4_filter(struct netif *netif, const ip4_addr_t *group, enum netif_mac_filter_action action);
|
||||
#endif
|
||||
#if LWIP_IPV6_MLD
|
||||
static err_t l3ip_multicast_ipv6_filter(struct netif *netif, const ip6_addr_t *group, enum netif_mac_filter_action action);
|
||||
#endif
|
||||
|
||||
static err_t l3ip_if_init(struct netif *netif);
|
||||
#endif
|
||||
|
||||
union {
|
||||
#if LWIP_ETHERNET
|
||||
EMAC *emac; /**< HW specific emac implementation */
|
||||
#endif
|
||||
#if LWIP_L3IP
|
||||
L3IP *l3ip; /**< L3IP implementation */
|
||||
#endif
|
||||
|
||||
void *hw; /**< alternative implementation pointer - used for PPP */
|
||||
};
|
||||
|
||||
|
@ -183,6 +202,18 @@ public:
|
|||
*/
|
||||
virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out);
|
||||
|
||||
/** Register a network interface with the IP stack
|
||||
*
|
||||
* Connects L3IP layer with the IP stack and initializes all the required infrastructure.
|
||||
* This function should be called only once for each available interface.
|
||||
*
|
||||
* @param l3ip L3IP HAL implementation for this network interface
|
||||
* @param default_if true if the interface should be treated as the default one
|
||||
* @param[out] interface_out pointer to stack interface object controlling the L3IP
|
||||
* @return NSAPI_ERROR_OK on success, or error code
|
||||
*/
|
||||
virtual nsapi_error_t add_l3ip_interface(L3IP &l3ip, bool default_if, OnboardNetworkStack::Interface **interface_out);
|
||||
|
||||
/** Register a PPP interface with the IP stack
|
||||
*
|
||||
* Connects PPP layer with the IP stack and initializes all the required infrastructure.
|
||||
|
@ -202,6 +233,17 @@ public:
|
|||
*/
|
||||
nsapi_error_t _add_ppp_interface(void *pcb, bool default_if, nsapi_ip_stack_t stack, LWIP::Interface **interface_out);
|
||||
|
||||
/** Remove a network interface from IP stack
|
||||
*
|
||||
* Connects L3IP layer with the IP stack and initializes all the required infrastructure.
|
||||
* This function should be called only once for each available interface.
|
||||
|
||||
|
||||
* @param[out] interface_out pointer to stack interface object controlling the L3IP
|
||||
* @return NSAPI_ERROR_OK on success, or error code
|
||||
*/
|
||||
virtual nsapi_error_t remove_l3ip_interface(OnboardNetworkStack::Interface **interface_out);
|
||||
|
||||
/** Get a domain name server from a list of servers to query
|
||||
*
|
||||
* Returns a DNS server address for a index. If returns error no more
|
||||
|
|
|
@ -331,6 +331,7 @@
|
|||
#define LWIP_ETHERNET 0
|
||||
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED
|
||||
|
||||
#define LWIP_L3IP 0
|
||||
// Note generic macro name used rather than MBED_CONF_LWIP_PPP_ENABLED
|
||||
// to allow users like PPPCellularInterface to detect that nsapi_ppp.h is available.
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
|
|
|
@ -37,150 +37,12 @@
|
|||
*/
|
||||
|
||||
#include "nsapi.h"
|
||||
#include "NetStackMemoryManager.h"
|
||||
|
||||
typedef void emac_mem_buf_t; // Memory buffer
|
||||
|
||||
class EMACMemoryManager {
|
||||
public:
|
||||
class EMACMemoryManager : public NetStackMemoryManager {
|
||||
|
||||
/**
|
||||
* Allocates memory buffer from the heap
|
||||
*
|
||||
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
|
||||
*
|
||||
* @param size Size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @return Allocated memory buffer, or NULL in case of error
|
||||
*/
|
||||
virtual emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align) = 0;
|
||||
|
||||
/**
|
||||
* Allocates memory buffer chain from a pool
|
||||
*
|
||||
* Memory allocated from pool is contiguous if size is equal or less than
|
||||
* (aligned) allocation unit, otherwise may be chained. Will typically come from
|
||||
* fixed-size packet pool memory.
|
||||
*
|
||||
* @param size Total size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement for each buffer in bytes
|
||||
* @return Allocated memory buffer chain, or NULL in case of error
|
||||
*/
|
||||
virtual emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align) = 0;
|
||||
|
||||
/**
|
||||
* Get memory buffer pool allocation unit
|
||||
*
|
||||
* Returns the maximum size of contiguous memory that can be allocated from a pool.
|
||||
*
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @return Contiguous memory size
|
||||
*/
|
||||
virtual uint32_t get_pool_alloc_unit(uint32_t align) const = 0;
|
||||
|
||||
/**
|
||||
* Free memory buffer chain
|
||||
*
|
||||
* If memory buffer is chained must point to the start of the chain. Frees all buffers
|
||||
* from the chained list.
|
||||
*
|
||||
* @param buf Memory buffer chain to be freed.
|
||||
*/
|
||||
virtual void free(emac_mem_buf_t *buf) = 0;
|
||||
|
||||
/**
|
||||
* Return total length of a memory buffer chain
|
||||
*
|
||||
* Returns a total length of this buffer and any following buffers in the chain.
|
||||
*
|
||||
* @param buf Memory buffer chain
|
||||
* @return Total length in bytes
|
||||
*/
|
||||
virtual uint32_t get_total_len(const emac_mem_buf_t *buf) const = 0;
|
||||
|
||||
/**
|
||||
* Copy a memory buffer chain
|
||||
*
|
||||
* Copies data from one buffer chain to another. Copy operation does not adjust the lengths
|
||||
* of the copied-to memory buffer chain, so chain total lengths must be the same.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to copy to
|
||||
* @param from_buf Memory buffer chain to copy from
|
||||
*/
|
||||
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf) = 0;
|
||||
|
||||
/**
|
||||
* Copy to a memory buffer chain
|
||||
*
|
||||
* Copies data to a buffer chain. Copy operation does not adjust the lengths
|
||||
* of the copied-to memory buffer chain, so chain total length must match the
|
||||
* copied length.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to copy to
|
||||
* @param ptr Pointer to data
|
||||
* @param len Data length
|
||||
*/
|
||||
virtual void copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len);
|
||||
|
||||
/**
|
||||
* Copy from a memory buffer chain
|
||||
*
|
||||
* Copies data from a memory buffer chain.
|
||||
*
|
||||
* @param len Data length
|
||||
* @param ptr Pointer to data
|
||||
* @param from_buf Memory buffer chain to copy from
|
||||
* @return Length of the data that was copied
|
||||
*/
|
||||
virtual uint32_t copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const;
|
||||
|
||||
/**
|
||||
* Concatenate two memory buffer chains
|
||||
*
|
||||
* Concatenates buffer chain to end of the other buffer chain. Concatenated-to buffer total length
|
||||
* is adjusted accordingly. cat_buf must point to the start of a the chain. After concatenation
|
||||
* to_buf's chain now owns those buffers, and they will be freed when the to_buf chain is freed.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to concatenate to
|
||||
* @param cat_buf Memory buffer chain to concatenate
|
||||
*/
|
||||
virtual void cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf) = 0;
|
||||
|
||||
/**
|
||||
* Returns the next buffer
|
||||
*
|
||||
* Returns the next buffer from the memory buffer chain.
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return The next memory buffer, or NULL if last
|
||||
*/
|
||||
virtual emac_mem_buf_t *get_next(const emac_mem_buf_t *buf) const = 0;
|
||||
|
||||
/**
|
||||
* Return pointer to the payload of the buffer
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return Pointer to the payload
|
||||
*/
|
||||
virtual void *get_ptr(const emac_mem_buf_t *buf) const = 0;
|
||||
|
||||
/**
|
||||
* Return payload size of the buffer
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return Size in bytes
|
||||
*/
|
||||
virtual uint32_t get_len(const emac_mem_buf_t *buf) const = 0;
|
||||
|
||||
/**
|
||||
* Sets the payload size of the buffer
|
||||
*
|
||||
* The allocated payload size will not change. It is not permitted
|
||||
* to change the length of a buffer that is not the first (or only) in a chain.
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @param len Payload size, must be less or equal allocated size
|
||||
*/
|
||||
virtual void set_len(emac_mem_buf_t *buf, uint32_t len) = 0;
|
||||
};
|
||||
|
||||
#endif /* EMAC_MEMORY_MANAGER_H */
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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 L3IP_H
|
||||
#define L3IP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "Callback.h"
|
||||
#include "NetStackMemoryManager.h"
|
||||
|
||||
|
||||
/**
|
||||
* This interface should be used to abstract low level access to networking hardware
|
||||
* All operations receive a `void *` hardware pointer which an l3ip device provides when
|
||||
* it is registered with a stack.
|
||||
*/
|
||||
class L3IP {
|
||||
public:
|
||||
|
||||
/** Return the default on-board L3IP
|
||||
*
|
||||
* Returns the default on-board L3IP - this will be target-specific, and
|
||||
* may not be available on all targets.
|
||||
*/
|
||||
static L3IP &get_default_instance();
|
||||
|
||||
/**
|
||||
* Callback to be registered with L3IP interface and to be called for received packets
|
||||
*
|
||||
* @param buf Received data
|
||||
*/
|
||||
//typedef void (*l3ip_link_input_fn)(void *data, net_stack_mem_buf_t *buf);
|
||||
typedef mbed::Callback<void (net_stack_mem_buf_t *buf)> l3ip_link_input_cb_t;
|
||||
|
||||
/**
|
||||
* Callback to be registered with L3IP interface and to be called for link status changes
|
||||
*
|
||||
* @param up Link status
|
||||
*/
|
||||
//typedef void (*l3ip_link_state_change_fn)(void *data, bool up);
|
||||
typedef mbed::Callback<void (bool up)> l3ip_link_state_change_cb_t;
|
||||
|
||||
/**
|
||||
* Return maximum transmission unit
|
||||
*
|
||||
* @return MTU in bytes
|
||||
*/
|
||||
virtual uint32_t get_mtu_size() const = 0;
|
||||
|
||||
/**
|
||||
* Gets memory buffer alignment preference
|
||||
*
|
||||
* Gets preferred memory buffer alignment of the l3ip 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 send
|
||||
* @return True if the packet was send successfully, false otherwise
|
||||
*/
|
||||
virtual bool link_out(net_stack_mem_buf_t *buf) = 0;
|
||||
|
||||
/**
|
||||
* Initializes the hardware
|
||||
*
|
||||
* @return True on success, False in case of an error.
|
||||
*/
|
||||
virtual bool power_up() = 0;
|
||||
|
||||
/**
|
||||
* Deinitializes the hardware
|
||||
*
|
||||
*/
|
||||
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(l3ip_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(l3ip_link_state_change_cb_t state_cb) = 0;
|
||||
|
||||
/** Add device to an IP4 multicast group
|
||||
*
|
||||
* @param address An IP4 multicast group address
|
||||
*/
|
||||
virtual void add_ipv4_multicast_group(const char *address) = 0;
|
||||
|
||||
/** Add device to an IP6 multicast group
|
||||
*
|
||||
* @param address An IP6 multicast group address
|
||||
*/
|
||||
virtual void add_ipv6_multicast_group(const char *address) = 0;
|
||||
|
||||
/** Remove device from an IPV4 multicast group
|
||||
*
|
||||
* @param address An IPV4 multicast group address
|
||||
*/
|
||||
virtual void remove_ipv4_multicast_group(const char *address) = 0;
|
||||
|
||||
/** Remove device from an IPV6 multicast group
|
||||
*
|
||||
* @param address An IPV6 multicast group address
|
||||
*/
|
||||
virtual void remove_ipv6_multicast_group(const char *address) = 0;
|
||||
|
||||
/** Request reception of all multicast packets
|
||||
*
|
||||
* @param all True to receive all multicasts
|
||||
* False to receive only multicasts addressed to specified groups
|
||||
*/
|
||||
virtual void set_all_multicast(bool all) = 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* L3IP_H */
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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 "L3IPInterface.h"
|
||||
using namespace mbed;
|
||||
|
||||
/* Interface implementation */
|
||||
L3IPInterface::L3IPInterface(L3IP &l3ip, OnboardNetworkStack &stack) :
|
||||
_l3ip(l3ip),
|
||||
_stack(stack),
|
||||
_interface(NULL),
|
||||
_dhcp(true),
|
||||
_blocking(true),
|
||||
_ip_address(),
|
||||
_netmask(),
|
||||
_gateway()
|
||||
{
|
||||
}
|
||||
|
||||
L3IPInterface::~ L3IPInterface()
|
||||
{
|
||||
_stack.remove_l3ip_interface(&_interface);
|
||||
}
|
||||
|
||||
nsapi_error_t L3IPInterface::set_network(const char *ip_address, const char *netmask, const char *gateway)
|
||||
{
|
||||
_dhcp = false;
|
||||
|
||||
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 L3IPInterface::set_dhcp(bool dhcp)
|
||||
{
|
||||
_dhcp = dhcp;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t L3IPInterface::connect()
|
||||
{
|
||||
if (!_interface) {
|
||||
nsapi_error_t err = _stack.add_l3ip_interface(_l3ip, true, &_interface);
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
_interface = NULL;
|
||||
return err;
|
||||
}
|
||||
_interface->attach(_connection_status_cb);
|
||||
}
|
||||
|
||||
return _interface->bringup(_dhcp,
|
||||
_ip_address[0] ? _ip_address : 0,
|
||||
_netmask[0] ? _netmask : 0,
|
||||
_gateway[0] ? _gateway : 0,
|
||||
DEFAULT_STACK,
|
||||
_blocking);
|
||||
}
|
||||
|
||||
nsapi_error_t L3IPInterface::disconnect()
|
||||
{
|
||||
if (_interface) {
|
||||
return _interface->bringdown();
|
||||
}
|
||||
return NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
|
||||
const char *L3IPInterface::get_ip_address()
|
||||
{
|
||||
if (_interface && _interface->get_ip_address(_ip_address, sizeof(_ip_address))) {
|
||||
return _ip_address;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *L3IPInterface::get_netmask()
|
||||
{
|
||||
if (_interface && _interface->get_netmask(_netmask, sizeof(_netmask))) {
|
||||
return _netmask;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *L3IPInterface::get_gateway()
|
||||
{
|
||||
if (_interface && _interface->get_gateway(_gateway, sizeof(_gateway))) {
|
||||
return _gateway;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetworkStack *L3IPInterface::get_stack()
|
||||
{
|
||||
return &_stack;
|
||||
}
|
||||
|
||||
void L3IPInterface::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 L3IPInterface::get_connection_status() const
|
||||
{
|
||||
if (_interface) {
|
||||
return _interface->get_connection_status();
|
||||
} else {
|
||||
return NSAPI_STATUS_DISCONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t L3IPInterface::set_blocking(bool blocking)
|
||||
{
|
||||
_blocking = blocking;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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 L3IP_INTERFACE_H
|
||||
#define L3IP_INTERFACE_H
|
||||
|
||||
#include "nsapi.h"
|
||||
#include "L3IP.h"
|
||||
#include "OnboardNetworkStack.h"
|
||||
|
||||
|
||||
/** L3IPInterface class
|
||||
* Implementation of the NetworkInterface for an IP-based driver
|
||||
*
|
||||
* This class provides the necessary glue logic to create a NetworkInterface
|
||||
* based on an L3IP and an OnboardNetworkStack. Cellular Interface drivers derive from it.
|
||||
*
|
||||
* Drivers derived from L3IPInterface should be constructed so that their
|
||||
* L3IP is functional without the need to call `connect()`.
|
||||
*/
|
||||
class L3IPInterface : public virtual NetworkInterface {
|
||||
public:
|
||||
/** Create an L3IP-based network interface.
|
||||
*
|
||||
* The default arguments obtain the default L3IP, 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 l3ip Reference to L3IP to use
|
||||
* @param stack Reference to onboard-network stack to use
|
||||
*/
|
||||
L3IPInterface(L3IP &l3ip = L3IP::get_default_instance(),
|
||||
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance());
|
||||
~L3IPInterface();
|
||||
/** 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);
|
||||
|
||||
/** Enable or disable DHCP on the network
|
||||
*
|
||||
* Requires that the network is disconnected
|
||||
*
|
||||
* @param dhcp False to disable dhcp (defaults to enabled)
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t set_dhcp(bool dhcp);
|
||||
|
||||
/** 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 recieved
|
||||
*/
|
||||
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 recieved
|
||||
*/
|
||||
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 recieved
|
||||
*/
|
||||
virtual const char *get_gateway();
|
||||
|
||||
/** 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);
|
||||
|
||||
/** Provide access to the L3IP
|
||||
*
|
||||
* This should be used with care - normally the network stack would
|
||||
* control the L3IP, so manipulating the L3IP while the stack
|
||||
* is also using it (ie after connect) will likely cause problems.
|
||||
*
|
||||
* @return Reference to the L3IP in use
|
||||
*/
|
||||
L3IP &getl3ip() const
|
||||
{
|
||||
return _l3ip;
|
||||
}
|
||||
|
||||
virtual L3IPInterface *l3ipInterface()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Provide access to the underlying stack
|
||||
*
|
||||
* @return The underlying network stack
|
||||
*/
|
||||
virtual NetworkStack *get_stack();
|
||||
|
||||
L3IP &_l3ip;
|
||||
OnboardNetworkStack &_stack;
|
||||
OnboardNetworkStack::Interface *_interface;
|
||||
bool _dhcp;
|
||||
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;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,4 +1,6 @@
|
|||
/* Copyright (c) 2018 ARM Limited
|
||||
/*
|
||||
* Copyright (c) 2018 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.
|
||||
|
@ -13,9 +15,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "EMACMemoryManager.h"
|
||||
#include "NetStackMemoryManager.h"
|
||||
|
||||
void EMACMemoryManager::copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len)
|
||||
void NetStackMemoryManager::copy_to_buf(net_stack_mem_buf_t *to_buf, const void *ptr, uint32_t len)
|
||||
{
|
||||
while (to_buf && len) {
|
||||
void *copy_to_ptr = get_ptr(to_buf);
|
||||
|
@ -35,7 +37,7 @@ void EMACMemoryManager::copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uin
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t EMACMemoryManager::copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const
|
||||
uint32_t NetStackMemoryManager::copy_from_buf(void *ptr, uint32_t len, const net_stack_mem_buf_t *from_buf) const
|
||||
{
|
||||
uint32_t copied_len = 0;
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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 NET_STACK_MEMORY_MANAGER_H
|
||||
#define NET_STACK_MEMORY_MANAGER_H
|
||||
|
||||
/**
|
||||
* Network Stack interface memory manager
|
||||
*
|
||||
* This interface provides abstraction for memory modules used in different IP stacks (often to accommodate zero
|
||||
* copy). NetStack interface is required to accept output packets and provide received data using this stack-
|
||||
* independent API. This header should be implemented for each IP stack, so that we keep EMAC module independent.
|
||||
*
|
||||
* NetStack memory interface uses memory buffer chains to store data. Data passed in either direction
|
||||
* may be either contiguous (a single-buffer chain), or may consist of multiple buffers.
|
||||
* Chaining of the buffers is made using singly-linked list. The NetStack data-passing APIs do not specify
|
||||
* alignment or structure of the chain in either direction.
|
||||
*
|
||||
* Memory buffers can be allocated either from heap or from memory pools. Heap buffers are always contiguous.
|
||||
* Memory pool buffers may be either contiguous or chained depending on allocation size.
|
||||
*
|
||||
* On NetStack interface buffer chain ownership is transferred. EMAC must free buffer chain that it is given for
|
||||
* link output and the stack must free the buffer chain that it is given for link input.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsapi.h"
|
||||
|
||||
typedef void net_stack_mem_buf_t; // Memory buffer
|
||||
|
||||
class NetStackMemoryManager {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Allocates memory buffer from the heap
|
||||
*
|
||||
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
|
||||
*
|
||||
* @param size Size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @return Allocated memory buffer, or NULL in case of error
|
||||
*/
|
||||
virtual net_stack_mem_buf_t *alloc_heap(uint32_t size, uint32_t align) = 0;
|
||||
|
||||
/**
|
||||
* Allocates memory buffer chain from a pool
|
||||
*
|
||||
* Memory allocated from pool is contiguous if size is equal or less than
|
||||
* (aligned) allocation unit, otherwise may be chained. Will typically come from
|
||||
* fixed-size packet pool memory.
|
||||
*
|
||||
* @param size Total size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement for each buffer in bytes
|
||||
* @return Allocated memory buffer chain, or NULL in case of error
|
||||
*/
|
||||
virtual net_stack_mem_buf_t *alloc_pool(uint32_t size, uint32_t align) = 0;
|
||||
|
||||
/**
|
||||
* Get memory buffer pool allocation unit
|
||||
*
|
||||
* Returns the maximum size of contiguous memory that can be allocated from a pool.
|
||||
*
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @return Contiguous memory size
|
||||
*/
|
||||
virtual uint32_t get_pool_alloc_unit(uint32_t align) const = 0;
|
||||
|
||||
/**
|
||||
* Free memory buffer chain
|
||||
*
|
||||
* Frees all buffers from the chained list.
|
||||
*
|
||||
* @param buf Memory buffer chain to be freed.
|
||||
*/
|
||||
virtual void free(net_stack_mem_buf_t *buf) = 0;
|
||||
|
||||
/**
|
||||
* Return total length of a memory buffer chain
|
||||
*
|
||||
* Returns a total length of this buffer and any following buffers in the chain.
|
||||
*
|
||||
* @param buf Memory buffer chain
|
||||
* @return Total length in bytes
|
||||
*/
|
||||
virtual uint32_t get_total_len(const net_stack_mem_buf_t *buf) const = 0;
|
||||
|
||||
/**
|
||||
* Copy a memory buffer chain
|
||||
*
|
||||
* Copies data from one buffer chain to another. Copy operation does not adjust the lengths
|
||||
* of the copied-to memory buffer chain, so chain total lengths must be the same.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to copy to
|
||||
* @param from_buf Memory buffer chain to copy from
|
||||
*/
|
||||
virtual void copy(net_stack_mem_buf_t *to_buf, const net_stack_mem_buf_t *from_buf) = 0;
|
||||
|
||||
/**
|
||||
* Copy to a memory buffer chain
|
||||
*
|
||||
* Copies data to a buffer chain. Copy operation does not adjust the lengths
|
||||
* of the copied-to memory buffer chain, so chain total length must match the
|
||||
* copied length.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to copy to
|
||||
* @param ptr Pointer to data
|
||||
* @param len Data length
|
||||
*/
|
||||
virtual void copy_to_buf(net_stack_mem_buf_t *to_buf, const void *ptr, uint32_t len);
|
||||
|
||||
/**
|
||||
* Copy from a memory buffer chain
|
||||
*
|
||||
* Copies data from a memory buffer chain.
|
||||
*
|
||||
* @param len Data length
|
||||
* @param ptr Pointer to data
|
||||
* @param from_buf Memory buffer chain to copy from
|
||||
* @return Length of the data that was copied
|
||||
*/
|
||||
virtual uint32_t copy_from_buf(void *ptr, uint32_t len, const net_stack_mem_buf_t *from_buf) const;
|
||||
|
||||
/**
|
||||
* Concatenate two memory buffer chains
|
||||
*
|
||||
* Concatenates buffer chain to end of the other buffer chain. Concatenated-to buffer total length
|
||||
* is adjusted accordingly. cat_buf must point to the start of a the chain. After concatenation
|
||||
* to_buf's chain now owns those buffers, and they will be freed when the to_buf chain is freed.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to concatenate to
|
||||
* @param cat_buf Memory buffer chain to concatenate
|
||||
*/
|
||||
virtual void cat(net_stack_mem_buf_t *to_buf, net_stack_mem_buf_t *cat_buf) = 0;
|
||||
|
||||
/**
|
||||
* Returns the next buffer
|
||||
*
|
||||
* Returns the next buffer from the memory buffer chain.
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return The next memory buffer, or NULL if last
|
||||
*/
|
||||
virtual net_stack_mem_buf_t *get_next(const net_stack_mem_buf_t *buf) const = 0;
|
||||
|
||||
/**
|
||||
* Return pointer to the payload of the buffer
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return Pointer to the payload
|
||||
*/
|
||||
virtual void *get_ptr(const net_stack_mem_buf_t *buf) const = 0;
|
||||
|
||||
/**
|
||||
* Return payload size of the buffer
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return Size in bytes
|
||||
*/
|
||||
virtual uint32_t get_len(const net_stack_mem_buf_t *buf) const = 0;
|
||||
|
||||
/**
|
||||
* Sets the payload size of the buffer
|
||||
*
|
||||
* The allocated payload size will not change. It is not permitted
|
||||
* to change the length of a buffer that is not the first (or only) in a chain.
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @param len Payload size, must be less or equal to the allocated size
|
||||
*/
|
||||
virtual void set_len(net_stack_mem_buf_t *buf, uint32_t len) = 0;
|
||||
};
|
||||
|
||||
#endif /* NET_STACK_MEMORY_MANAGER_H */
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "NetworkStack.h"
|
||||
#include "EMAC.h"
|
||||
#include "L3IP.h"
|
||||
|
||||
/**
|
||||
* mbed OS API for onboard IP stack abstraction
|
||||
|
@ -133,6 +134,16 @@ public:
|
|||
* @return NSAPI_ERROR_OK on success, or error code
|
||||
*/
|
||||
virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Interface **interface_out) = 0;
|
||||
|
||||
virtual nsapi_error_t add_l3ip_interface(L3IP &l3ip, bool default_if, Interface **interface_out)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
virtual nsapi_error_t remove_l3ip_interface(Interface **interface_out)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* MBED_IPSTACK_H */
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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 "mbed_interface.h"
|
||||
#include "netsocket/nsapi_types.h"
|
||||
#include "cellular_driver_l3ip.h"
|
||||
|
||||
Cellular_driver_L3IP::Cellular_driver_L3IP()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool Cellular_driver_L3IP::link_out(net_stack_mem_buf_t *buf)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Cellular_driver_L3IP::power_up()
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t Cellular_driver_L3IP::get_mtu_size() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Cellular_driver_L3IP::get_align_preference() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Cellular_driver_L3IP::get_ifname(char *name, uint8_t size) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Cellular_driver_L3IP::set_link_input_cb(l3ip_link_input_cb_t input_cb)
|
||||
{
|
||||
l3ip_link_input_cb = input_cb;
|
||||
}
|
||||
|
||||
void Cellular_driver_L3IP::set_link_state_cb(l3ip_link_state_change_cb_t state_cb)
|
||||
{
|
||||
l3ip_link_state_cb = state_cb;
|
||||
}
|
||||
|
||||
void Cellular_driver_L3IP::add_ipv4_multicast_group(const char *address)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cellular_driver_L3IP::add_ipv6_multicast_group(const char *address)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cellular_driver_L3IP::remove_ipv4_multicast_group(const char *address)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cellular_driver_L3IP::remove_ipv6_multicast_group(const char *address)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cellular_driver_L3IP::set_all_multicast(bool all)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cellular_driver_L3IP::power_down()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cellular_driver_L3IP::set_memory_manager(NetStackMemoryManager &mem_mngr)
|
||||
{
|
||||
memory_manager = &mem_mngr;
|
||||
}
|
||||
|
||||
|
||||
Cellular_driver_L3IP &Cellular_driver_L3IP::get_instance()
|
||||
{
|
||||
static Cellular_driver_L3IP l3ip_test_driver;
|
||||
return l3ip_test_driver;
|
||||
}
|
||||
|
||||
// Weak so a module can override
|
||||
MBED_WEAK L3IP &L3IP::get_default_instance()
|
||||
{
|
||||
return Cellular_driver_L3IP::get_instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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 CELLULAR_DRIVER_L3IP_H_
|
||||
#define CELLULAR_DRIVER_L3IP_H_
|
||||
|
||||
#include "L3IP.h"
|
||||
|
||||
|
||||
class Cellular_driver_L3IP : public L3IP {
|
||||
public:
|
||||
Cellular_driver_L3IP();
|
||||
|
||||
static Cellular_driver_L3IP &get_instance();
|
||||
|
||||
/**
|
||||
* Return maximum transmission unit
|
||||
*
|
||||
* @return MTU in bytes
|
||||
*/
|
||||
virtual uint32_t get_mtu_size() const;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Initializes the hardware
|
||||
*
|
||||
* @return True on success, False in case of an error.
|
||||
*/
|
||||
virtual bool power_up();
|
||||
|
||||
/**
|
||||
* Deinitializes the hardware
|
||||
*
|
||||
*/
|
||||
virtual void power_down();
|
||||
|
||||
/**
|
||||
* 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(l3ip_link_input_cb_t input_cb);
|
||||
|
||||
/**
|
||||
* 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(l3ip_link_state_change_cb_t state_cb);
|
||||
|
||||
/** Add device to an IP4 multicast group
|
||||
*
|
||||
* @param address an IP4 multicast group address
|
||||
*/
|
||||
virtual void add_ipv4_multicast_group(const char *address);
|
||||
|
||||
/** Add device to an IP6 multicast group
|
||||
*
|
||||
* @param address an IP6 multicast group address
|
||||
*/
|
||||
virtual void add_ipv6_multicast_group(const char *address);
|
||||
|
||||
/** Remove device from an IPV4 multicast group
|
||||
*
|
||||
* @param address An IPV4 multicast group address
|
||||
*/
|
||||
virtual void remove_ipv4_multicast_group(const char *address);
|
||||
|
||||
/** Remove device from an IPV6 multicast group
|
||||
*
|
||||
* @param address An IPV6 multicast group address
|
||||
*/
|
||||
virtual void remove_ipv6_multicast_group(const char *address);
|
||||
|
||||
/** Request reception of all multicast packets
|
||||
*
|
||||
* @param all True to receive all multicasts
|
||||
* False to receive only multicasts addressed to specified groups
|
||||
*/
|
||||
virtual void set_all_multicast(bool all);
|
||||
|
||||
/** 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);
|
||||
|
||||
private:
|
||||
|
||||
l3ip_link_input_cb_t l3ip_link_input_cb; /**< Callback for incoming data */
|
||||
l3ip_link_state_change_cb_t l3ip_link_state_cb; /**< Link state change callback */
|
||||
NetStackMemoryManager *memory_manager; /**< Memory manager */
|
||||
|
||||
};
|
||||
|
||||
#endif /* CELLULAR_DRIVER_L3IP_H_ */
|
|
@ -127,6 +127,10 @@ typedef enum nsapi_security {
|
|||
NSAPI_SECURITY_UNKNOWN = 0xFF, /*!< unknown/unsupported security in scan results */
|
||||
} nsapi_security_t;
|
||||
|
||||
/** Maximum size of network interface name
|
||||
*/
|
||||
#define NSAPI_INTERFACE_NAME_SIZE 2
|
||||
|
||||
/** Maximum size of IP address representation
|
||||
*/
|
||||
#define NSAPI_IP_SIZE NSAPI_IPv6_SIZE
|
||||
|
|
Loading…
Reference in New Issue