L3IP Interface Implementation

LWIP L3IP interface initial implementatioon
pull/8739/head
Tymoteusz Bloch 2018-11-14 13:50:36 +01:00 committed by Tymoteusz Bloch
parent ab1c2be997
commit fc88922845
16 changed files with 1217 additions and 172 deletions

View File

@ -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)
{

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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 */

158
features/netsocket/L3IP.h Normal file
View File

@ -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 */

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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 ------------------------------ */

View 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_ */

View File

@ -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