diff --git a/features/FEATURE_LWIP/lwip-interface/EthernetInterface.cpp b/features/FEATURE_LWIP/lwip-interface/EthernetInterface.cpp index 37fc686212..ae672a55ee 100644 --- a/features/FEATURE_LWIP/lwip-interface/EthernetInterface.cpp +++ b/features/FEATURE_LWIP/lwip-interface/EthernetInterface.cpp @@ -41,7 +41,7 @@ int EthernetInterface::set_dhcp(bool dhcp) int EthernetInterface::connect() { - return lwip_bringup(_dhcp, + return mbed_lwip_bringup(_dhcp, _ip_address[0] ? _ip_address : 0, _netmask[0] ? _netmask : 0, _gateway[0] ? _gateway : 0); @@ -49,17 +49,17 @@ int EthernetInterface::connect() int EthernetInterface::disconnect() { - return lwip_bringdown(); + return mbed_lwip_bringdown(); } const char *EthernetInterface::get_mac_address() { - return lwip_get_mac_address(); + return mbed_lwip_get_mac_address(); } const char *EthernetInterface::get_ip_address() { - if (lwip_get_ip_address(_ip_address, sizeof _ip_address)) { + if (mbed_lwip_get_ip_address(_ip_address, sizeof _ip_address)) { return _ip_address; } @@ -68,7 +68,7 @@ const char *EthernetInterface::get_ip_address() const char *EthernetInterface::get_netmask() { - if (lwip_get_netmask(_netmask, sizeof _netmask)) { + if (mbed_lwip_get_netmask(_netmask, sizeof _netmask)) { return _netmask; } @@ -77,7 +77,7 @@ const char *EthernetInterface::get_netmask() const char *EthernetInterface::get_gateway() { - if (lwip_get_gateway(_gateway, sizeof _gateway)) { + if (mbed_lwip_get_gateway(_gateway, sizeof _gateway)) { return _gateway; } diff --git a/features/FEATURE_LWIP/lwip-interface/emac_lwip.c b/features/FEATURE_LWIP/lwip-interface/emac_lwip.c new file mode 100644 index 0000000000..01f09faf0f --- /dev/null +++ b/features/FEATURE_LWIP/lwip-interface/emac_lwip.c @@ -0,0 +1,91 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * 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 "platform.h" + +#if DEVICE_EMAC + +#include "emac_api.h" +#include "emac_stack_mem.h" +#include "lwip/tcpip.h" +#include "lwip/tcp.h" +#include "lwip/ip.h" +#include "netif/etharp.h" + +static err_t emac_lwip_low_level_output(struct netif *netif, struct pbuf *p) +{ + emac_interface_t *mac = (emac_interface_t *)netif->state; + bool ret = mac->ops.link_out(mac, (emac_stack_mem_t *)p); + + return ret ? ERR_OK : ERR_IF; +} + +static void emac_lwip_input(void *data, emac_stack_t *buf) +{ + struct pbuf *p = (struct pbuf *)buf; + struct netif *netif = (struct netif *)data; + + /* pass all packets to ethernet_input, which decides what packets it supports */ + if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("Emac LWIP: IP input error\n")); + + pbuf_free(p); + } +} + +static void emac_lwip_state_change(void *data, bool up) +{ + struct netif *netif = (struct netif *)data; + + 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); + } +} + +err_t emac_lwip_if_init(struct netif *netif) +{ + int err = ERR_OK; + emac_interface_t *mac = (emac_interface_t *)netif->state; + + mac->ops.set_link_input_cb(mac, emac_lwip_input, netif); + mac->ops.set_link_state_cb(mac, emac_lwip_state_change, netif); + + netif->hwaddr_len = mac->ops.get_hwaddr_size(mac); + mac->ops.get_hwaddr(mac, netif->hwaddr); + + netif->mtu = mac->ops.get_mtu_size(mac); + + /* Interface capabilities */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP; + + mac->ops.get_ifname(mac, netif->name, 2); + +#if LWIP_IPV4 + netif->output = etharp_output; +#endif /* LWIP_IPV4 */ + + netif->linkoutput = emac_lwip_low_level_output; + + if (!mac->ops.power_up(mac)) { + err = ERR_IF; + } + + return err; +} + +#endif /* DEVICE_EMAC */ diff --git a/features/FEATURE_LWIP/lwip-interface/emac_stack_lwip.cpp b/features/FEATURE_LWIP/lwip-interface/emac_stack_lwip.cpp new file mode 100644 index 0000000000..d543529fd6 --- /dev/null +++ b/features/FEATURE_LWIP/lwip-interface/emac_stack_lwip.cpp @@ -0,0 +1,88 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * 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 "platform.h" + +#if DEVICE_EMAC + +#include "emac_stack_mem.h" +#include "pbuf.h" + +emac_stack_mem_t *emac_stack_mem_alloc(emac_stack_t* stack, uint32_t size, uint32_t align) +{ + + struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + align, PBUF_RAM); + if (pbuf == NULL) { + return NULL; + } + + if (align) { + uint32_t remainder = (uint32_t)pbuf->payload % align; + uint32_t offset = align - remainder; + if (offset >= align) { + offset = align; + } + + pbuf->payload = (void*)((char*)pbuf->payload + offset); + pbuf->tot_len -= offset; + pbuf->len -= offset; + } + + return (emac_stack_mem_t*)pbuf; +} + +void emac_stack_mem_free(emac_stack_t* stack, emac_stack_mem_t *mem) +{ + pbuf_free((struct pbuf*)mem); +} + +void *emac_stack_mem_ptr(emac_stack_t* stack, emac_stack_mem_t *mem) +{ + return ((struct pbuf*)mem)->payload; +} + +uint32_t emac_stack_mem_len(emac_stack_t* stack, emac_stack_mem_t *mem) +{ + return ((struct pbuf*)mem)->len; +} + +void emac_stack_mem_set_len(emac_stack_t* stack, emac_stack_mem_t *mem, uint32_t len) +{ + struct pbuf *pbuf = (struct pbuf*)mem; + + pbuf->len = len; +} + +emac_stack_mem_t *emac_stack_mem_chain_dequeue(emac_stack_t* stack, emac_stack_mem_chain_t **chain) +{ + struct pbuf **list = (struct pbuf**)chain; + struct pbuf *head = *list; + *list = (*list)->next; + + return (emac_stack_mem_t *)head; +} + +uint32_t emac_stack_mem_chain_len(emac_stack_t* stack, emac_stack_mem_chain_t *chain) +{ + return ((struct pbuf*)chain)->tot_len; +} + +void emac_stack_mem_ref(emac_stack_t* stack, emac_stack_mem_t *mem) +{ + pbuf_ref((struct pbuf*)mem); +} + +#endif /* DEVICE_EMAC */ diff --git a/features/FEATURE_LWIP/lwip-interface/eth_arch.h b/features/FEATURE_LWIP/lwip-interface/eth_arch.h index 1ff54b1d38..25bdde38dd 100644 --- a/features/FEATURE_LWIP/lwip-interface/eth_arch.h +++ b/features/FEATURE_LWIP/lwip-interface/eth_arch.h @@ -29,13 +29,17 @@ extern "C" { #endif +#if DEVICE_EMAC +err_t emac_lwip_if_init(struct netif *netif); + +#else /* DEVICE_EMAC */ void eth_arch_enable_interrupts(void); void eth_arch_disable_interrupts(void); err_t eth_arch_enetif_init(struct netif *netif); +#endif #ifdef __cplusplus } #endif #endif // #ifndef ETHARCHINTERFACE_H_ - diff --git a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c index 2ada01f22c..89b4e7e8de 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c @@ -33,6 +33,16 @@ #include "lwip/dns.h" #include "lwip/udp.h" +#include "emac_api.h" + +#if DEVICE_EMAC + #define MBED_NETIF_INIT_FN emac_lwip_if_init +#else + #define MBED_NETIF_INIT_FN eth_arch_enetif_init +#endif + +#define DHCP_TIMEOUT 15000 + /* Static arena of sockets */ static struct lwip_socket { bool in_use; @@ -47,12 +57,12 @@ static struct lwip_socket { static bool lwip_connected = false; -static void lwip_arena_init(void) +static void mbed_lwip_arena_init(void) { memset(lwip_arena, 0, sizeof lwip_arena); } -static struct lwip_socket *lwip_arena_alloc(void) +static struct lwip_socket *mbed_lwip_arena_alloc(void) { sys_prot_t prot = sys_arch_protect(); @@ -70,12 +80,12 @@ static struct lwip_socket *lwip_arena_alloc(void) return 0; } -static void lwip_arena_dealloc(struct lwip_socket *s) +static void mbed_lwip_arena_dealloc(struct lwip_socket *s) { s->in_use = false; } -static void lwip_socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len) +static void mbed_lwip_socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len) { sys_prot_t prot = sys_arch_protect(); @@ -164,7 +174,7 @@ static bool convert_lwip_addr_to_mbed(nsapi_addr_t *out, const ip_addr_t *in) return false; } -static const ip_addr_t *lwip_get_ipv4_addr(const struct netif *netif) +static const ip_addr_t *mbed_lwip_get_ipv4_addr(const struct netif *netif) { #if LWIP_IPV4 if (!netif_is_up(netif)) { @@ -179,7 +189,7 @@ static const ip_addr_t *lwip_get_ipv4_addr(const struct netif *netif) return NULL; } -static const ip_addr_t *lwip_get_ipv6_addr(const struct netif *netif) +static const ip_addr_t *mbed_lwip_get_ipv6_addr(const struct netif *netif) { #if LWIP_IPV6 if (!netif_is_up(netif)) { @@ -198,17 +208,17 @@ static const ip_addr_t *lwip_get_ipv6_addr(const struct netif *netif) } -const ip_addr_t *lwip_get_ip_addr(bool any_addr, const struct netif *netif) +const ip_addr_t *mbed_lwip_get_ip_addr(bool any_addr, const struct netif *netif) { const ip_addr_t *pref_ip_addr = 0; const ip_addr_t *npref_ip_addr = 0; #if IP_VERSION_PREF == PREF_IPV4 - pref_ip_addr = lwip_get_ipv4_addr(netif); - npref_ip_addr = lwip_get_ipv6_addr(netif); + pref_ip_addr = mbed_lwip_get_ipv4_addr(netif); + npref_ip_addr = mbed_lwip_get_ipv6_addr(netif); #else - pref_ip_addr = lwip_get_ipv6_addr(netif); - npref_ip_addr = lwip_get_ipv4_addr(netif); + pref_ip_addr = mbed_lwip_get_ipv6_addr(netif); + npref_ip_addr = mbed_lwip_get_ipv4_addr(netif); #endif if (pref_ip_addr) { @@ -223,7 +233,7 @@ const ip_addr_t *lwip_get_ip_addr(bool any_addr, const struct netif *netif) #if LWIP_IPV6 void add_dns_addr(struct netif *lwip_netif) { - const ip_addr_t *ip_addr = lwip_get_ip_addr(true, lwip_netif); + const ip_addr_t *ip_addr = mbed_lwip_get_ip_addr(true, lwip_netif); if (ip_addr) { if (IP_IS_V6(ip_addr)) { const ip_addr_t *dns_ip_addr; @@ -252,13 +262,13 @@ void add_dns_addr(struct netif *lwip_netif) #endif static sys_sem_t lwip_tcpip_inited; -static void lwip_tcpip_init_irq(void *eh) +static void mbed_lwip_tcpip_init_irq(void *eh) { sys_sem_signal(&lwip_tcpip_inited); } static sys_sem_t lwip_netif_linked; -static void lwip_netif_link_irq(struct netif *lwip_netif) +static void mbed_lwip_netif_link_irq(struct netif *lwip_netif) { if (netif_is_link_up(lwip_netif)) { sys_sem_signal(&lwip_netif_linked); @@ -266,24 +276,24 @@ static void lwip_netif_link_irq(struct netif *lwip_netif) } static sys_sem_t lwip_netif_has_addr; -static void lwip_netif_status_irq(struct netif *lwip_netif) +static void mbed_lwip_netif_status_irq(struct netif *lwip_netif) { static bool any_addr = true; // Indicates that has address - if (any_addr == true && lwip_get_ip_addr(true, lwip_netif)) { + if (any_addr == true && mbed_lwip_get_ip_addr(true, lwip_netif)) { sys_sem_signal(&lwip_netif_has_addr); any_addr = false; return; } // Indicates that has preferred address - if (lwip_get_ip_addr(false, lwip_netif)) { + if (mbed_lwip_get_ip_addr(false, lwip_netif)) { sys_sem_signal(&lwip_netif_has_addr); } } -static void lwip_set_mac_address(void) +static void mbed_lwip_set_mac_address(void) { #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) snprintf(lwip_mac_address, 19, "%02x:%02x:%02x:%02x:%02x:%02x", @@ -298,14 +308,14 @@ static void lwip_set_mac_address(void) } /* LWIP interface implementation */ -const char *lwip_get_mac_address(void) +const char *mbed_lwip_get_mac_address(void) { return lwip_mac_address[0] ? lwip_mac_address : 0; } -char *lwip_get_ip_address(char *buf, int buflen) +char *mbed_lwip_get_ip_address(char *buf, int buflen) { - const ip_addr_t *addr = lwip_get_ip_addr(true, &lwip_netif); + const ip_addr_t *addr = mbed_lwip_get_ip_addr(true, &lwip_netif); if (!addr) { return NULL; } @@ -322,12 +332,12 @@ char *lwip_get_ip_address(char *buf, int buflen) return NULL; } -const char *lwip_get_netmask(char *buf, int buflen) +const char *mbed_lwip_get_netmask(char *buf, int buflen) { #if LWIP_IPV4 const ip4_addr_t *addr = netif_ip4_netmask(&lwip_netif); if (!ip4_addr_isany(addr)) { - return inet_ntoa_r(addr, buf, buflen); + return ip4addr_ntoa_r(addr, buf, buflen); } else { return NULL; } @@ -336,12 +346,12 @@ const char *lwip_get_netmask(char *buf, int buflen) #endif } -char *lwip_get_gateway(char *buf, int buflen) +char *mbed_lwip_get_gateway(char *buf, int buflen) { #if LWIP_IPV4 const ip4_addr_t *addr = netif_ip4_gw(&lwip_netif); if (!ip4_addr_isany(addr)) { - return inet_ntoa_r(addr, buf, buflen); + return ip4addr_ntoa_r(addr, buf, buflen); } else { return NULL; } @@ -350,23 +360,18 @@ char *lwip_get_gateway(char *buf, int buflen) #endif } -int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) +int mbed_lwip_init(emac_interface_t *emac) { - // Check if we've already connected - if (lwip_connected) { - return NSAPI_ERROR_PARAMETER; - } - // Check if we've already brought up lwip - if (!lwip_get_mac_address()) { + if (!mbed_lwip_get_mac_address()) { // Set up network - lwip_set_mac_address(); + mbed_lwip_set_mac_address(); sys_sem_new(&lwip_tcpip_inited, 0); sys_sem_new(&lwip_netif_linked, 0); sys_sem_new(&lwip_netif_has_addr, 0); - tcpip_init(lwip_tcpip_init_irq, NULL); + tcpip_init(mbed_lwip_tcpip_init_irq, NULL); sys_arch_sem_wait(&lwip_tcpip_inited, 0); memset(&lwip_netif, 0, sizeof lwip_netif); @@ -374,19 +379,36 @@ int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) #if LWIP_IPV4 0, 0, 0, #endif - NULL, eth_arch_enetif_init, tcpip_input)) { - return -1; + emac, MBED_NETIF_INIT_FN, tcpip_input)) { + return NSAPI_ERROR_DEVICE_ERROR; } + netif_set_default(&lwip_netif); - netif_set_link_callback (&lwip_netif, lwip_netif_link_irq); - netif_set_status_callback(&lwip_netif, lwip_netif_status_irq); + netif_set_link_callback(&lwip_netif, mbed_lwip_netif_link_irq); + netif_set_status_callback(&lwip_netif, mbed_lwip_netif_status_irq); +#if !DEVICE_EMAC eth_arch_enable_interrupts(); +#endif + } + + return NSAPI_ERROR_OK; +} + +int mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) +{ + // Check if we've already connected + if (lwip_connected) { + return NSAPI_ERROR_PARAMETER; + } + + if(mbed_lwip_init(NULL) != NSAPI_ERROR_OK) { + return NSAPI_ERROR_DEVICE_ERROR; } // Zero out socket set - lwip_arena_init(); + mbed_lwip_arena_init(); #if LWIP_IPV6 netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/); @@ -451,9 +473,8 @@ int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) #endif // If doesn't have address - if (!lwip_get_ip_addr(true, &lwip_netif)) { - //ret = sys_arch_sem_wait(&lwip_netif_has_addr, 15000); - ret = sys_arch_sem_wait(&lwip_netif_has_addr, 30000); + if (!mbed_lwip_get_ip_addr(true, &lwip_netif)) { + ret = sys_arch_sem_wait(&lwip_netif_has_addr, 15000); if (ret == SYS_ARCH_TIMEOUT) { return NSAPI_ERROR_DHCP_FAILURE; } @@ -463,7 +484,7 @@ int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) #if ADDR_TIMEOUT // If address is not for preferred stack waits a while to see // if preferred stack address is acquired - if (!lwip_get_ip_addr(false, &lwip_netif)) { + if (!mbed_lwip_get_ip_addr(false, &lwip_netif)) { ret = sys_arch_sem_wait(&lwip_netif_has_addr, ADDR_TIMEOUT * 1000); } #endif @@ -475,7 +496,7 @@ int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw) return 0; } -int lwip_bringdown(void) +int mbed_lwip_bringdown(void) { // Check if we've connected if (!lwip_connected) { @@ -499,7 +520,7 @@ int lwip_bringdown(void) } /* LWIP error remapping */ -static int lwip_err_remap(err_t err) { +static int mbed_lwip_err_remap(err_t err) { switch (err) { case ERR_OK: case ERR_CLSD: @@ -525,7 +546,7 @@ static int lwip_err_remap(err_t err) { } /* LWIP network stack implementation */ -static int lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr, nsapi_version_t version) +static int mbed_lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr, nsapi_version_t version) { ip_addr_t lwip_addr; @@ -533,7 +554,7 @@ static int lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi_addr u8_t addr_type; if (version == NSAPI_UNSPEC) { const ip_addr_t *ip_addr; - ip_addr = lwip_get_ip_addr(true, &lwip_netif); + ip_addr = mbed_lwip_get_ip_addr(true, &lwip_netif); if (IP_IS_V6(ip_addr)) { addr_type = NETCONN_DNS_IPV6; } else { @@ -566,7 +587,7 @@ static int lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi_addr return 0; } -static int lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_protocol_t proto) +static int mbed_lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_protocol_t proto) { // check if network is connected if (!lwip_connected) { @@ -574,7 +595,7 @@ static int lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_ } // allocate a socket - struct lwip_socket *s = lwip_arena_alloc(); + struct lwip_socket *s = mbed_lwip_arena_alloc(); if (!s) { return NSAPI_ERROR_NO_SOCKET; } @@ -583,7 +604,7 @@ static int lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_ #if LWIP_IPV6 && LWIP_IPV4 const ip_addr_t *ip_addr; - ip_addr = lwip_get_ip_addr(true, &lwip_netif); + ip_addr = mbed_lwip_get_ip_addr(true, &lwip_netif); if (IP_IS_V6(ip_addr)) { // Enable IPv6 (or dual-stack). LWIP dual-stack support is @@ -597,10 +618,10 @@ static int lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_ lwip_proto |= NETCONN_TYPE_IPV6; #endif - s->conn = netconn_new_with_callback(lwip_proto, lwip_socket_callback); + s->conn = netconn_new_with_callback(lwip_proto, mbed_lwip_socket_callback); if (!s->conn) { - lwip_arena_dealloc(s); + mbed_lwip_arena_dealloc(s); return NSAPI_ERROR_NO_SOCKET; } @@ -609,16 +630,16 @@ static int lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_ return 0; } -static int lwip_socket_close(nsapi_stack_t *stack, nsapi_socket_t handle) +static int mbed_lwip_socket_close(nsapi_stack_t *stack, nsapi_socket_t handle) { struct lwip_socket *s = (struct lwip_socket *)handle; err_t err = netconn_delete(s->conn); - lwip_arena_dealloc(s); - return lwip_err_remap(err); + mbed_lwip_arena_dealloc(s); + return mbed_lwip_err_remap(err); } -static int lwip_socket_bind(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port) +static int mbed_lwip_socket_bind(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port) { struct lwip_socket *s = (struct lwip_socket *)handle; ip_addr_t ip_addr; @@ -633,18 +654,18 @@ static int lwip_socket_bind(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_a } err_t err = netconn_bind(s->conn, &ip_addr, port); - return lwip_err_remap(err); + return mbed_lwip_err_remap(err); } -static int lwip_socket_listen(nsapi_stack_t *stack, nsapi_socket_t handle, int backlog) +static int mbed_lwip_socket_listen(nsapi_stack_t *stack, nsapi_socket_t handle, int backlog) { struct lwip_socket *s = (struct lwip_socket *)handle; err_t err = netconn_listen_with_backlog(s->conn, backlog); - return lwip_err_remap(err); + return mbed_lwip_err_remap(err); } -static int lwip_socket_connect(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port) +static int mbed_lwip_socket_connect(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port) { struct lwip_socket *s = (struct lwip_socket *)handle; ip_addr_t ip_addr; @@ -657,21 +678,21 @@ static int lwip_socket_connect(nsapi_stack_t *stack, nsapi_socket_t handle, nsap err_t err = netconn_connect(s->conn, &ip_addr, port); netconn_set_nonblocking(s->conn, true); - return lwip_err_remap(err); + return mbed_lwip_err_remap(err); } -static int lwip_socket_accept(nsapi_stack_t *stack, nsapi_socket_t server, nsapi_socket_t *handle, nsapi_addr_t *addr, uint16_t *port) +static int mbed_lwip_socket_accept(nsapi_stack_t *stack, nsapi_socket_t server, nsapi_socket_t *handle, nsapi_addr_t *addr, uint16_t *port) { struct lwip_socket *s = (struct lwip_socket *)server; - struct lwip_socket *ns = lwip_arena_alloc(); + struct lwip_socket *ns = mbed_lwip_arena_alloc(); if (!ns) { return NSAPI_ERROR_NO_SOCKET; } err_t err = netconn_accept(s->conn, &ns->conn); if (err != ERR_OK) { - lwip_arena_dealloc(ns); - return lwip_err_remap(err); + mbed_lwip_arena_dealloc(ns); + return mbed_lwip_err_remap(err); } netconn_set_recvtimeout(ns->conn, 1); @@ -683,20 +704,20 @@ static int lwip_socket_accept(nsapi_stack_t *stack, nsapi_socket_t server, nsapi return 0; } -static int lwip_socket_send(nsapi_stack_t *stack, nsapi_socket_t handle, const void *data, unsigned size) +static int mbed_lwip_socket_send(nsapi_stack_t *stack, nsapi_socket_t handle, const void *data, unsigned size) { struct lwip_socket *s = (struct lwip_socket *)handle; size_t bytes_written = 0; err_t err = netconn_write_partly(s->conn, data, size, NETCONN_COPY, &bytes_written); if (err != ERR_OK) { - return lwip_err_remap(err); + return mbed_lwip_err_remap(err); } return (int)bytes_written; } -static int lwip_socket_recv(nsapi_stack_t *stack, nsapi_socket_t handle, void *data, unsigned size) +static int mbed_lwip_socket_recv(nsapi_stack_t *stack, nsapi_socket_t handle, void *data, unsigned size) { struct lwip_socket *s = (struct lwip_socket *)handle; @@ -705,7 +726,7 @@ static int lwip_socket_recv(nsapi_stack_t *stack, nsapi_socket_t handle, void *d s->offset = 0; if (err != ERR_OK) { - return lwip_err_remap(err); + return mbed_lwip_err_remap(err); } } @@ -720,7 +741,7 @@ static int lwip_socket_recv(nsapi_stack_t *stack, nsapi_socket_t handle, void *d return recv; } -static int lwip_socket_sendto(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port, const void *data, unsigned size) +static int mbed_lwip_socket_sendto(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t addr, uint16_t port, const void *data, unsigned size) { struct lwip_socket *s = (struct lwip_socket *)handle; ip_addr_t ip_addr; @@ -733,26 +754,26 @@ static int lwip_socket_sendto(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi err_t err = netbuf_ref(buf, data, (u16_t)size); if (err != ERR_OK) { netbuf_free(buf); - return lwip_err_remap(err); + return mbed_lwip_err_remap(err); } err = netconn_sendto(s->conn, buf, &ip_addr, port); netbuf_delete(buf); if (err != ERR_OK) { - return lwip_err_remap(err); + return mbed_lwip_err_remap(err); } return size; } -static int lwip_socket_recvfrom(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t *addr, uint16_t *port, void *data, unsigned size) +static int mbed_lwip_socket_recvfrom(nsapi_stack_t *stack, nsapi_socket_t handle, nsapi_addr_t *addr, uint16_t *port, void *data, unsigned size) { struct lwip_socket *s = (struct lwip_socket *)handle; struct netbuf *buf; err_t err = netconn_recv(s->conn, &buf); if (err != ERR_OK) { - return lwip_err_remap(err); + return mbed_lwip_err_remap(err); } convert_lwip_addr_to_mbed(addr, netbuf_fromaddr(buf)); @@ -764,7 +785,7 @@ static int lwip_socket_recvfrom(nsapi_stack_t *stack, nsapi_socket_t handle, nsa return recv; } -static int lwip_setsockopt(nsapi_stack_t *stack, nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen) +static int mbed_lwip_setsockopt(nsapi_stack_t *stack, nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen) { struct lwip_socket *s = (struct lwip_socket *)handle; @@ -810,7 +831,7 @@ static int lwip_setsockopt(nsapi_stack_t *stack, nsapi_socket_t handle, int leve } } -static void lwip_socket_attach(nsapi_stack_t *stack, nsapi_socket_t handle, void (*callback)(void *), void *data) +static void mbed_lwip_socket_attach(nsapi_stack_t *stack, nsapi_socket_t handle, void (*callback)(void *), void *data) { struct lwip_socket *s = (struct lwip_socket *)handle; @@ -820,19 +841,19 @@ static void lwip_socket_attach(nsapi_stack_t *stack, nsapi_socket_t handle, void /* LWIP network stack */ const nsapi_stack_api_t lwip_stack_api = { - .gethostbyname = lwip_gethostbyname, - .socket_open = lwip_socket_open, - .socket_close = lwip_socket_close, - .socket_bind = lwip_socket_bind, - .socket_listen = lwip_socket_listen, - .socket_connect = lwip_socket_connect, - .socket_accept = lwip_socket_accept, - .socket_send = lwip_socket_send, - .socket_recv = lwip_socket_recv, - .socket_sendto = lwip_socket_sendto, - .socket_recvfrom = lwip_socket_recvfrom, - .setsockopt = lwip_setsockopt, - .socket_attach = lwip_socket_attach, + .gethostbyname = mbed_lwip_gethostbyname, + .socket_open = mbed_lwip_socket_open, + .socket_close = mbed_lwip_socket_close, + .socket_bind = mbed_lwip_socket_bind, + .socket_listen = mbed_lwip_socket_listen, + .socket_connect = mbed_lwip_socket_connect, + .socket_accept = mbed_lwip_socket_accept, + .socket_send = mbed_lwip_socket_send, + .socket_recv = mbed_lwip_socket_recv, + .socket_sendto = mbed_lwip_socket_sendto, + .socket_recvfrom = mbed_lwip_socket_recvfrom, + .setsockopt = mbed_lwip_setsockopt, + .socket_attach = mbed_lwip_socket_attach, }; nsapi_stack_t lwip_stack = { diff --git a/features/FEATURE_LWIP/lwip-interface/lwip_stack.h b/features/FEATURE_LWIP/lwip-interface/lwip_stack.h index 969bc2a250..89161f61f4 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip_stack.h +++ b/features/FEATURE_LWIP/lwip-interface/lwip_stack.h @@ -18,20 +18,21 @@ #define LWIP_STACK_H #include "nsapi.h" +#include "emac_api.h" #ifdef __cplusplus extern "C" { #endif - // Access to lwip through the nsapi -int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw); -int lwip_bringdown(void); +int mbed_lwip_init(emac_interface_t *emac); +int mbed_lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw); +int mbed_lwip_bringdown(void); -const char *lwip_get_mac_address(void); -char *lwip_get_ip_address(char *buf, int buflen); -char *lwip_get_netmask(char *buf, int buflen); -char *lwip_get_gateway(char *buf, int buflen); +const char *mbed_lwip_get_mac_address(void); +char *mbed_lwip_get_ip_address(char *buf, int buflen); +char *mbed_lwip_get_netmask(char *buf, int buflen); +char *mbed_lwip_get_gateway(char *buf, int buflen); extern nsapi_stack_t lwip_stack; diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h index 8e7dff9406..48cb655b48 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h +++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h @@ -81,9 +81,9 @@ #define DEFAULT_ACCEPTMBOX_SIZE 8 #ifdef LWIP_DEBUG -#define TCPIP_THREAD_STACKSIZE 1024*2 +#define TCPIP_THREAD_STACKSIZE 1200*2 #else -#define TCPIP_THREAD_STACKSIZE 1024 +#define TCPIP_THREAD_STACKSIZE 1200 #endif #define TCPIP_THREAD_PRIO (osPriorityNormal) diff --git a/features/netsocket/CellularInterface.cpp b/features/netsocket/CellularInterface.cpp deleted file mode 100644 index 9a9ea45633..0000000000 --- a/features/netsocket/CellularInterface.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* Socket - * Copyright (c) 2015 ARM Limited - * - * 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 "netsocket/CellularInterface.h" -#include -#include - - -CellularInterface::CellularInterface() - : _apn(0), _user(0), _pass(0) -{ -} - -CellularInterface::~CellularInterface() -{ - free(_apn); - free(_user); - free(_pass); -} - -int CellularInterface::set_credentials(const char *apn, const char *user, const char *pass) -{ - free(_apn); - _apn = 0; - free(_user); - _user = 0; - free(_pass); - _pass = 0; - - if (apn) { - _apn = (char*)malloc(strlen(apn)+1); - if (!_apn) { - return NSAPI_ERROR_NO_MEMORY; - } - - strcpy(_apn, apn); - } - - if (user) { - _user = (char*)malloc(strlen(user)+1); - if (!_user) { - return NSAPI_ERROR_NO_MEMORY; - } - - strcpy(_user, user); - } - - if (pass) { - _pass = (char*)malloc(strlen(pass)+1); - if (!_pass) { - return NSAPI_ERROR_NO_MEMORY; - } - - strcpy(_pass, pass); - } - - return 0; -} - -int CellularInterface::connect() -{ - return connect(_apn, _user, _pass); -} - diff --git a/features/netsocket/CellularInterface.h b/features/netsocket/CellularInterface.h index e4c69bb493..9d48f29f99 100644 --- a/features/netsocket/CellularInterface.h +++ b/features/netsocket/CellularInterface.h @@ -29,8 +29,7 @@ class CellularInterface : public NetworkInterface public: /** CellularInterface lifetime */ - CellularInterface(); - virtual ~CellularInterface(); + virtual ~CellularInterface() {}; /** Set the cellular network APN and credentials * @@ -38,7 +37,7 @@ public: * @param user Optional username for the APN * @param pass Optional password fot the APN */ - virtual int set_credentials(const char *apn, const char *user = 0, const char *pass = 0); + virtual int set_credentials(const char *apn, const char *user = 0, const char *pass = 0) = 0; /** Start the interface * @@ -55,18 +54,13 @@ public: * * @return 0 on success, negative error code on failure */ - virtual int connect(); + virtual int connect() = 0; /** Stop the interface * * @return 0 on success, negative error code on failure */ virtual int disconnect() = 0; - -private: - char *_apn; - char *_user; - char *_pass; }; diff --git a/features/netsocket/WiFiAccessPoint.cpp b/features/netsocket/WiFiAccessPoint.cpp new file mode 100644 index 0000000000..49c62c6868 --- /dev/null +++ b/features/netsocket/WiFiAccessPoint.cpp @@ -0,0 +1,37 @@ +#include "netsocket/WiFiAccessPoint.h" + +WiFiAccessPoint::WiFiAccessPoint() +{ + memset(&_ap, 0, sizeof(_ap)); +} + +WiFiAccessPoint::WiFiAccessPoint(nsapi_wifi_ap_t ap) +{ + _ap = ap; +} + +const char *WiFiAccessPoint::get_ssid() const +{ + return _ap.ssid; +} + +const uint8_t *WiFiAccessPoint::get_bssid() const +{ + return _ap.bssid; +} + +nsapi_security_t WiFiAccessPoint::get_security() const +{ + return _ap.security; +} + +int8_t WiFiAccessPoint::get_rssi() const +{ + return _ap.rssi; +} + +uint8_t WiFiAccessPoint::get_channel() const +{ + return _ap.channel; +} + diff --git a/features/netsocket/WiFiAccessPoint.h b/features/netsocket/WiFiAccessPoint.h new file mode 100644 index 0000000000..b590c45aa2 --- /dev/null +++ b/features/netsocket/WiFiAccessPoint.h @@ -0,0 +1,71 @@ +/* WiFiInterface + * Copyright (c) 2015 - 2016 ARM Limited + * + * 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 WIFI_ACCESS_POINT_H +#define WIFI_ACCESS_POINT_H + +#include +#include "netsocket/nsapi_types.h" + +/** WiFiAccessPoint class + * + * Class that represents a WiFi Access Point + * Common interface that is shared between WiFi devices + */ +class WiFiAccessPoint +{ + /** WiFiAccessPoint lifetime + */ +public: + WiFiAccessPoint(); + WiFiAccessPoint(nsapi_wifi_ap_t ap); + + /** Get an access point's ssid + * + * @return The ssid of the access point + */ + const char *get_ssid() const; + + /** Get an access point's bssid + * + * @return The bssid of the access point + */ + const uint8_t *get_bssid() const; + + /** Get an access point's security + * + * @return The security type of the access point + */ + nsapi_security_t get_security() const; + + /** Gets the radio signal strength for the access point + * + * @return Connection strength in dBm (negative value), + * or 0 if measurement impossible + */ + int8_t get_rssi() const; + + /** Get the access point's channel + * + * @return The channel of the access point + */ + uint8_t get_channel() const; + +private: + nsapi_wifi_ap_t _ap; +}; + +#endif diff --git a/features/netsocket/WiFiInterface.cpp b/features/netsocket/WiFiInterface.cpp deleted file mode 100644 index 9747e5fc7f..0000000000 --- a/features/netsocket/WiFiInterface.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* Socket - * Copyright (c) 2015 ARM Limited - * - * 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 "netsocket/WiFiInterface.h" -#include -#include - - -WiFiInterface::WiFiInterface() - : _ssid(0), _pass(0), _security(NSAPI_SECURITY_NONE) -{ -} - -WiFiInterface::~WiFiInterface() -{ - free(_ssid); - free(_pass); -} - -int WiFiInterface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) -{ - free(_ssid); - _ssid = 0; - free(_pass); - _pass = 0; - - if (ssid) { - _ssid = (char*)malloc(strlen(ssid)+1); - if (!_ssid) { - return NSAPI_ERROR_NO_MEMORY; - } - - strcpy(_ssid, ssid); - } - - if (pass) { - _pass = (char*)malloc(strlen(pass)+1); - if (!_pass) { - return NSAPI_ERROR_NO_MEMORY; - } - - strcpy(_pass, pass); - } - - _security = security; - - return 0; -} - -int WiFiInterface::connect() -{ - if (!_ssid || !_pass) { - return NSAPI_ERROR_PARAMETER; - } - - return connect(_ssid, _pass, _security); -} - diff --git a/features/netsocket/WiFiInterface.h b/features/netsocket/WiFiInterface.h index 108756b89d..faaf4f8854 100644 --- a/features/netsocket/WiFiInterface.h +++ b/features/netsocket/WiFiInterface.h @@ -1,5 +1,5 @@ /* WiFiInterface - * Copyright (c) 2015 ARM Limited + * Copyright (c) 2015 - 2016 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,22 +17,10 @@ #ifndef WIFI_INTERFACE_H #define WIFI_INTERFACE_H +#include +#include "Callback.h" #include "netsocket/NetworkInterface.h" - - -/** Enum of WiFi encryption types - * - * The security type specifies a particular security to use when - * connected to a WiFi network - * - * @enum nsapi_protocol_t - */ -enum nsapi_security_t { - NSAPI_SECURITY_NONE = 0, /*!< open access point */ - NSAPI_SECURITY_WEP, /*!< phrase conforms to WEP */ - NSAPI_SECURITY_WPA, /*!< phrase conforms to WPA */ - NSAPI_SECURITY_WPA2, /*!< phrase conforms to WPA2 */ -}; +#include "netsocket/WiFiAccessPoint.h" /** WiFiInterface class * @@ -43,29 +31,45 @@ class WiFiInterface: public NetworkInterface public: /** WiFiInterface lifetime */ - WiFiInterface(); - virtual ~WiFiInterface(); + virtual ~WiFiInterface() {}; /** Set the WiFi network credentials - * - * @param ssid Name of the network to connect to - * @param pass Security passphrase to connect to the network - * @param security Type of encryption for connection - * (defaults to NSAPI_SECURITY_NONE) - */ - virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE); - - /** Start the interface - * - * Attempts to connect to a WiFi network. If passphrase is invalid, - * NSAPI_ERROR_AUTH_ERROR is returned. * * @param ssid Name of the network to connect to * @param pass Security passphrase to connect to the network * @param security Type of encryption for connection - * @return 0 on success, negative error code on failure + * (defaults to NSAPI_SECURITY_NONE) + * @return 0 on success, or error code on failure */ - virtual int connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE) = 0; + virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE) = 0; + + /** Set the WiFi network channel + * + * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) + * @return 0 on success, or error code on failure + */ + virtual int set_channel(uint8_t channel) = 0; + + /** Gets the current radio signal strength for active connection + * + * @return Connection strength in dBm (negative value), + * or 0 if measurement impossible + */ + virtual int8_t get_rssi() = 0; + + /** Start the interface + * + * Attempts to connect to a WiFi network. + * + * @param ssid Name of the network to connect to + * @param pass Security passphrase to connect to the network + * @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE) + * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) + * @return 0 on success, or error code on failure + */ + virtual int connect(const char *ssid, const char *pass, + nsapi_security_t security = NSAPI_SECURITY_NONE, + uint8_t channel = 0) = 0; /** Start the interface * @@ -74,19 +78,28 @@ public: * * @return 0 on success, negative error code on failure */ - virtual int connect(); + virtual int connect() = 0; /** Stop the interface * - * @return 0 on success, negative error code on failure + * @return 0 on success, or error code on failure */ virtual int disconnect() = 0; -private: - char *_ssid; - char *_pass; - nsapi_security_t _security; + /** Scan for available networks + * + * The scan will + * If the network interface is set to non-blocking mode, scan will attempt to scan + * for WiFi networks asynchronously and return NSAPI_ERROR_WOULD_BLOCK. If a callback + * is attached, the callback will be called when the operation has completed. + * + * @param ap Pointer to allocated array to store discovered AP + * @param count Size of allocated @a res array, or 0 to only count available AP + * @param timeout Timeout in milliseconds; 0 for no timeout (Default: 0) + * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error + * see @a nsapi_error + */ + virtual int scan(WiFiAccessPoint *res, unsigned count) = 0; }; - #endif diff --git a/features/netsocket/emac_stack_mem.h b/features/netsocket/emac_stack_mem.h new file mode 100644 index 0000000000..b407308fd5 --- /dev/null +++ b/features/netsocket/emac_stack_mem.h @@ -0,0 +1,109 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * 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 MBED_EMAC_STACK_MEM_H +#define MBED_EMAC_STACK_MEM_H + +#include "platform.h" + +#if DEVICE_EMAC + +#include + +/** + * Stack memory module + * + * This interface provides abstraction for memory modules used in different IP stacks (often to accommodate zero copy). + * Emac interface may be required to accept output packets and provide received data using this stack specific API. + * This header should be implemented for each IP stack, so that we keep emacs module independent. + */ +typedef void emac_stack_mem_t; +typedef void emac_stack_mem_chain_t; +typedef void emac_stack_t; + +/** + * Allocates stack memory + * + * @param stack Emac stack context + * @param size Size of memory to allocate + * @param align Memory alignment requirements + * @return Allocated memory struct, or NULL in case of error + */ +emac_stack_mem_t *emac_stack_mem_alloc(emac_stack_t* stack, uint32_t size, uint32_t align); + +/** + * Free memory allocated using @a stack_mem_alloc + * + * @param stack Emac stack context + * @param mem Memory to be freed + */ +void emac_stack_mem_free(emac_stack_t* stack, emac_stack_mem_t *mem); + +/** + * Return pointer to the payload + * + * @param stack Emac stack context + * @param mem Memory structure + * @return Pointer to the payload + */ +void *emac_stack_mem_ptr(emac_stack_t* stack, emac_stack_mem_t *mem); + +/** + * Return actual payload size + * + * @param stack Emac stack context + * @param mem Memory structure + * @return Size in bytes + */ +uint32_t emac_stack_mem_len(emac_stack_t* stack, emac_stack_mem_t *mem); + +/** + * Sets the actual payload size (the allocated payload size will not change) + * + * @param stack Emac stack context + * @param mem Memory structure + * @param len Actual payload size + */ +void emac_stack_mem_set_len(emac_stack_t* stack, emac_stack_mem_t *mem, uint32_t len); + +/** + * Returns first memory structure from the list and move the head to point to the next node + * + * @param stack Emac stack context + * @param list Pointer to the list + * @return First memory structure from the list + */ +emac_stack_mem_t *emac_stack_mem_chain_dequeue(emac_stack_t* stack, emac_stack_mem_chain_t **chain); + +/** + * Return total length of the memory chain + * + * @param stack Emac stack context + * @param chain Memory chain + * @return Chain length + */ +uint32_t emac_stack_mem_chain_len(emac_stack_t* stack, emac_stack_mem_chain_t *chain); + +/** + * Increases the reference counter for the memory + * + * @param stack Emac stack context + * @param mem Memory structure + */ +void emac_stack_mem_ref(emac_stack_t* stack, emac_stack_mem_t *mem); + +#endif /* DEVICE_EMAC */ + +#endif /* EMAC_MBED_STACK_MEM_h */ diff --git a/features/netsocket/nsapi_types.h b/features/netsocket/nsapi_types.h index 4324bae68d..57e8f32622 100644 --- a/features/netsocket/nsapi_types.h +++ b/features/netsocket/nsapi_types.h @@ -24,7 +24,7 @@ extern "C" { #endif -/** Enum of standardized error codes +/** Enum of standardized error codes * * Valid error codes have negative values and may * be returned by any network operation. @@ -32,6 +32,7 @@ extern "C" { * @enum nsapi_error_t */ typedef enum nsapi_error { + NSAPI_ERROR_OK = 0, /*!< no error */ NSAPI_ERROR_WOULD_BLOCK = -3001, /*!< no data is not available but call is non-blocking */ NSAPI_ERROR_UNSUPPORTED = -3002, /*!< unsupported functionality */ NSAPI_ERROR_PARAMETER = -3003, /*!< invalid configuration */ @@ -39,12 +40,26 @@ typedef enum nsapi_error { NSAPI_ERROR_NO_SOCKET = -3005, /*!< socket not available for use */ NSAPI_ERROR_NO_ADDRESS = -3006, /*!< IP address is not known */ NSAPI_ERROR_NO_MEMORY = -3007, /*!< memory resource not available */ - NSAPI_ERROR_DNS_FAILURE = -3008, /*!< DNS failed to complete successfully */ - NSAPI_ERROR_DHCP_FAILURE = -3009, /*!< DHCP failed to complete successfully */ - NSAPI_ERROR_AUTH_FAILURE = -3010, /*!< connection to access point faield */ - NSAPI_ERROR_DEVICE_ERROR = -3011, /*!< failure interfacing with the network procesor */ + NSAPI_ERROR_NO_SSID = -3008, /*!< ssid not found */ + NSAPI_ERROR_DNS_FAILURE = -3009, /*!< DNS failed to complete successfully */ + NSAPI_ERROR_DHCP_FAILURE = -3010, /*!< DHCP failed to complete successfully */ + NSAPI_ERROR_AUTH_FAILURE = -3011, /*!< connection to access point failed */ + NSAPI_ERROR_DEVICE_ERROR = -3012, /*!< failure interfacing with the network processor */ } nsapi_error_t; +/** Enum of encryption types + * + * The security type specifies a particular security to use when + * connected to a WiFi network + */ +typedef enum nsapi_security { + NSAPI_SECURITY_NONE = 0x0, /*!< open access point */ + NSAPI_SECURITY_WEP = 0x1, /*!< phrase conforms to WEP */ + NSAPI_SECURITY_WPA = 0x2, /*!< phrase conforms to WPA */ + NSAPI_SECURITY_WPA2 = 0x3, /*!< phrase conforms to WPA2 */ + NSAPI_SECURITY_WPA_WPA2 = 0x4, /*!< phrase conforms to WPA/WPA2 */ + NSAPI_SECURITY_UNKNOWN = 0xFF, /*!< unknown/unsupported security in scan results */ +} nsapi_security_t; /** Maximum size of IP address representation */ @@ -148,6 +163,18 @@ typedef enum nsapi_option { NSAPI_RCVBUF, /*!< Sets recv buffer size */ } nsapi_option_t; +/** nsapi_wifi_ap structure + * + * Structure representing a WiFi Access Point + */ +typedef struct nsapi_wifi_ap { + char ssid[33]; /* 32 is what 802.11 defines as longest possible name; +1 for the \0 */ + uint8_t bssid[6]; + nsapi_security_t security; + int8_t rssi; + uint8_t channel; +} nsapi_wifi_ap_t; + /** nsapi_stack structure * diff --git a/features/unsupported/net/eth/EthernetInterface/eth_arch.h b/features/unsupported/net/eth/EthernetInterface/eth_arch.h index 1ff54b1d38..25bdde38dd 100644 --- a/features/unsupported/net/eth/EthernetInterface/eth_arch.h +++ b/features/unsupported/net/eth/EthernetInterface/eth_arch.h @@ -29,13 +29,17 @@ extern "C" { #endif +#if DEVICE_EMAC +err_t emac_lwip_if_init(struct netif *netif); + +#else /* DEVICE_EMAC */ void eth_arch_enable_interrupts(void); void eth_arch_disable_interrupts(void); err_t eth_arch_enetif_init(struct netif *netif); +#endif #ifdef __cplusplus } #endif #endif // #ifndef ETHARCHINTERFACE_H_ - diff --git a/hal/hal/emac_api.h b/hal/hal/emac_api.h new file mode 100644 index 0000000000..bebd56f707 --- /dev/null +++ b/hal/hal/emac_api.h @@ -0,0 +1,163 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 ARM Limited + * + * 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 MBED_EMAC_API_H +#define MBED_EMAC_API_H + +#include "platform.h" + + +#if DEVICE_EMAC + +#include +#include "emac_stack_mem.h" + +typedef struct emac_interface emac_interface_t; + +/** + * EmacInterface + * + * This interface should be used to abstract low level access to networking hardware + */ + +/** + * Callback to be register with Emac interface and to be called fore received packets + * + * @param data Arbitrary user data (IP stack) + * @param buf Received data + */ +typedef void (*emac_link_input_fn)(void *data, emac_stack_mem_chain_t *buf); + +/** + * Callback to be register with Emac interface and to be called for link status changes + * + * @param data Arbitrary user data (IP stack) + * @param up Link status + */ +typedef void (*emac_link_state_change_fn)(void *data, bool up); + +/** + * Return maximum transmission unit + * + * @param emac Emac interface + * @return MTU in bytes + */ +typedef uint32_t (*emac_get_mtu_size_fn)(emac_interface_t *emac); + +/** + * Return interface name + * + * @param emac Emac interface + * @param name Pointer to where the name should be written + * @param size Maximum number of character to copy + */ +typedef void (*emac_get_ifname_fn)(emac_interface_t *emac, char *name, uint8_t size); + +/** + * Returns size of the underlying interface HW address size + * + * @param emac Emac interface + * @return HW address size in bytes + */ +typedef uint8_t (*emac_get_hwaddr_size_fn)(emac_interface_t *emac); + +/** + * Return interface hw address + * + * Copies HW address to provided memory, @param addr has to be of correct size see @a get_hwaddr_size + * + * @param emac Emac interface + * @param addr HW address for underlying interface + */ +typedef void (*emac_get_hwaddr_fn)(emac_interface_t *emac, uint8_t *addr); + +/** + * Set HW address for interface + * + * Provided address has to be of correct size, see @a get_hwaddr_size + * + * @param emac Emac interface + * @param addr Address to be set + */ +typedef void (*emac_set_hwaddr_fn)(emac_interface_t *emac, uint8_t *addr); + +/** + * Sends the packet over the link + * + * That can not be called from an interrupt context. + * + * @param emac Emac interface + * @param buf Packet to be send + * @return True if the packet was send successfully, False otherwise + */ +typedef bool (*emac_link_out_fn)(emac_interface_t *emac, emac_stack_mem_t *buf); + +/** + * Initializes the HW + * + * @return True on success, False in case of an error. + */ +typedef bool (*emac_power_up_fn)(emac_interface_t *emac); + +/** + * Deinitializes the HW + * + * @param emac Emac interface + */ +typedef void (*emac_power_down_fn)(emac_interface_t *emac); + +/** + * Sets a callback that needs to be called for packets received for that interface + * + * @param emac Emac interface + * @param input_cb Function to be register as a callback + * @param data Arbitrary user data to be passed to the callback + */ +typedef void (*emac_set_link_input_cb_fn)(emac_interface_t *emac, emac_link_input_fn input_cb, void *data); + +/** + * Sets a callback that needs to be called on link status changes for given interface + * + * @param emac Emac interface + * @param state_cb Function to be register as a callback + * @param data Arbitrary user data to be passed to the callback + */ +typedef void (*emac_set_link_state_cb_fn)(emac_interface_t *emac, emac_link_state_change_fn state_cb, void *data); + +typedef struct emac_interface_ops { + emac_get_mtu_size_fn get_mtu_size; + emac_get_ifname_fn get_ifname; + emac_get_hwaddr_size_fn get_hwaddr_size; + emac_get_hwaddr_fn get_hwaddr; + emac_set_hwaddr_fn set_hwaddr; + emac_link_out_fn link_out; + emac_power_up_fn power_up; + emac_power_down_fn power_down; + emac_set_link_input_cb_fn set_link_input_cb; + emac_set_link_state_cb_fn set_link_state_cb; +} emac_interface_ops_t; + +typedef struct emac_interface { + const emac_interface_ops_t ops; + void *hw; +} emac_interface_t; + +#else + +typedef void *emac_interface_t; + +#endif /* DEVICE_EMAC */ +#endif /* MBED_EMAC_API_H */