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