Wrapper of NetworkSocketAPI for BSD sockets on POSIX systems
Dependents: BSDInterfaceTests HelloBSDInterface
Revision 1:29c61c1420c8, committed 2016-02-27
- Comitter:
- Christopher Haster
- Date:
- Sat Feb 27 21:01:54 2016 -0600
- Parent:
- 0:d92b89886434
- Child:
- 2:0978e139e1c5
- Commit message:
- Added base implementation of BSDInterface
Changed in this revision
BSDInterface.cpp | Show annotated file Show diff for this revision Revisions of this file |
BSDInterface.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/BSDInterface.cpp Sun Feb 28 02:00:46 2016 +0000 +++ b/BSDInterface.cpp Sat Feb 27 21:01:54 2016 -0600 @@ -1,4 +1,4 @@ -/* LWIP implementation of NetworkInterfaceAPI +/* BSD implementation of NetworkInterfaceAPI * Copyright (c) 2015 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,148 +14,71 @@ * limitations under the License. */ -#include "LWIPInterface.h" +#include "BSDInterface.h" -#include "mbed.h" -#include "lwip/inet.h" -#include "lwip/netif.h" -#include "lwip/dhcp.h" -#include "lwip/tcpip.h" -#include "lwip/sockets.h" -#include "lwip/netdb.h" -#include "netif/etharp.h" -#include "eth_arch.h" - - -#define LWIP_TIMEOUT 15000 +#include <sys/ioctl.h> +#include <net/if.h> +#include <unistd.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <errno.h> +#include <string.h> +#include <stdio.h> -/* TCP/IP and Network Interface Initialisation */ -static LWIPInterface *iface = 0; -static struct netif netif; - -static char mac_addr[NS_MAC_SIZE] = "\0"; - -static Semaphore tcpip_inited(0); -static Semaphore netif_linked(0); -static Semaphore netif_up(0); - -static void tcpip_init_done(void *) { - tcpip_inited.release(); -} - -static void netif_link_callback(struct netif *netif) { - if (netif_is_link_up(netif)) { - netif_linked.release(); +// BSDInterface implementation +const char *BSDInterface::getMACAddress() +{ + static char mac_address[NS_MAC_SIZE] = "\0"; + if (mac_address[0]) { + return mac_address; } -} - -static void netif_status_callback(struct netif *netif) { - if (netif_is_up(netif)) { - iface->setIPAddress (inet_ntoa(netif->ip_addr)); - iface->setNetworkMask(inet_ntoa(netif->netmask)); - iface->setGateway (inet_ntoa(netif->gw)); - netif_up.release(); - } -} -static void init_netif(ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw) { - tcpip_init(tcpip_init_done, NULL); - tcpip_inited.wait(); - - memset((void*) &netif, 0, sizeof(netif)); - netif_add(&netif, ipaddr, netmask, gw, NULL, eth_arch_enetif_init, tcpip_input); - netif_set_default(&netif); - - netif_set_link_callback (&netif, netif_link_callback); - netif_set_status_callback(&netif, netif_status_callback); -} + struct ifreq ifr; + struct ifconf ifc; + char buffer[1024]; -static void set_mac_address(void) { -#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) - snprintf(mac_addr, 19, "%02x:%02x:%02x:%02x:%02x:%02x", MBED_MAC_ADDR_0, MBED_MAC_ADDR_1, MBED_MAC_ADDR_2, - MBED_MAC_ADDR_3, MBED_MAC_ADDR_4, MBED_MAC_ADDR_5); -#else - char mac[6]; - mbed_mac_address(mac); - snprintf(mac_addr, 19, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -#endif -} - - -// LWIPInterface implementation -int32_t LWIPInterface::connect() -{ - // Only one instance of LWIP is currently supported - if (iface) { - return NS_ERROR_DEVICE_ERROR; + int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) { + return 0; } - iface = this; - - // Set up network - set_mac_address(); - - if (getDHCP()) { - init_netif(0, 0, 0); - } else { - ip_addr_t ip_n, mask_n, gateway_n; - inet_aton(getIPAddress(), &ip_n); - inet_aton(getNetworkMask(), &mask_n); - inet_aton(getGateway(), &gateway_n); - init_netif(&ip_n, &mask_n, &gateway_n); + ifc.ifc_buf = buffer; + ifc.ifc_len = sizeof buffer; + if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { + return 0; } - // Connect to network - eth_arch_enable_interrupts(); + for (int i = 0; i < ifc.ifc_len; i++) { + strcpy(ifr.ifr_name, ifc.ifc_req[i].ifr_name); + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0 + && !(ifr.ifr_flags & IFF_LOOPBACK) + && ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) { - if (getDHCP()) { - dhcp_start(&netif); - - // Wait for an IP Address - // -1: error, 0: timeout - if (netif_up.wait(LWIP_TIMEOUT) < 0) { - return NS_ERROR_TIMEOUT; - } - } else { - netif_set_up(&netif); - - // Wait for the link up - if (netif_linked.wait(LWIP_TIMEOUT) < 0) { - return NS_ERROR_TIMEOUT; + sprintf(mac_address, "%02x:%02x:%02x:%02x:%02x:%02x", + ifr.ifr_hwaddr.sa_data[0], + ifr.ifr_hwaddr.sa_data[1], + ifr.ifr_hwaddr.sa_data[2], + ifr.ifr_hwaddr.sa_data[3], + ifr.ifr_hwaddr.sa_data[4], + ifr.ifr_hwaddr.sa_data[5]); + return mac_address; } } return 0; } -int32_t LWIPInterface::disconnect() -{ - if (getDHCP()) { - dhcp_release(&netif); - dhcp_stop(&netif); - } else { - netif_set_down(&netif); - } - - eth_arch_disable_interrupts(); - - return 0; -} -const char *LWIPInterface::getMACAddress() -{ - return mac_addr; -} - - -/** LWIPSocket class - * Implementation of the TCP SocketInterface for LWIP +/** BSDSocket class + * Implementation of the SocketInterface for BSD */ -class LWIPSocket : public SocketInterface +class BSDSocket : public SocketInterface { public: - LWIPSocket(int fd) : fd(fd) {} + BSDSocket(int fd) : fd(fd) {} // Implementation of SocketInterface virtual int32_t open(const char *ip, uint16_t port); @@ -168,77 +91,62 @@ }; -SocketInterface *LWIPInterface::createSocket(socket_protocol_t proto) +SocketInterface *BSDInterface::createSocket(socket_protocol_t proto) { int type = (proto == SOCK_UDP) ? SOCK_DGRAM : SOCK_STREAM; - int fd = lwip_socket(AF_INET, type, 0); - + int prot = (proto == SOCK_UDP) ? IPPROTO_UDP : IPPROTO_TCP; + int fd = socket(PF_INET, type, prot); if (fd < 0) { return 0; } - return new LWIPSocket(fd); + return new BSDSocket(fd); } -void LWIPInterface::destroySocket(SocketInterface *siface) +void BSDInterface::destroySocket(SocketInterface *socket) { - LWIPSocket *socket = (LWIPSocket *)siface; - lwip_close(socket->fd); - + close(((BSDSocket*)socket)->fd); delete socket; } -// TCP SocketInterface implementation -int32_t LWIPSocket::open(const char *ip, uint16_t port) +// UDP SocketInterface implementation +int32_t BSDSocket::open(const char *ip, uint16_t port) { - struct sockaddr_in host; + struct sockaddr_in host; memset(&host, 0, sizeof host); - inet_aton(ip, &host.sin_addr); host.sin_family = AF_INET; host.sin_port = htons(port); + inet_pton(AF_INET, ip, &host.sin_addr); - if (lwip_connect(fd, (const struct sockaddr *)&host, sizeof host) < 0) { + if (connect(fd, (struct sockaddr *)&host, sizeof host) < 0) { return NS_ERROR_NO_CONNECTION; } return 0; } -int32_t LWIPSocket::close() +int32_t BSDSocket::close() { return 0; } -int32_t LWIPSocket::send(const void *voiddata, uint32_t size) +int32_t BSDSocket::send(const void *data, uint32_t size) { - uint8_t *data = (uint8_t *)voiddata; - uint32_t writtenLen = 0; - - while (writtenLen < size) { - int ret = lwip_send(fd, data + writtenLen, size - writtenLen, 0); - - if (ret > 0) { - writtenLen += ret; - } else if (ret == 0) { - return NS_ERROR_NO_CONNECTION; - } else { - return NS_ERROR_DEVICE_ERROR; - } + if (::send(fd, data, size, 0) < 0) { + return NS_ERROR_DEVICE_ERROR; } return 0; } -int32_t LWIPSocket::recv(void *data, uint32_t size) +int32_t BSDSocket::recv(void *data, uint32_t size) { - int ret = lwip_recv(fd, data, size, MSG_DONTWAIT); + int ret = ::recv(fd, data, size, MSG_DONTWAIT); if (ret > 0) { return ret; - } else if (ret == 0) { - return NS_ERROR_NO_CONNECTION; - } else if (ret == -1) { + } else if (errno == EAGAIN) { return 0; } else { return NS_ERROR_DEVICE_ERROR;
--- a/BSDInterface.h Sun Feb 28 02:00:46 2016 +0000 +++ b/BSDInterface.h Sat Feb 27 21:01:54 2016 -0600 @@ -1,4 +1,4 @@ -/* LWIP implementation of NetworkInterfaceAPI +/* BSD implementation of NetworkInterfaceAPI * Copyright (c) 2015 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,24 +14,18 @@ * limitations under the License. */ -#ifndef LWIP_INTERFACE_H -#define LWIP_INTERFACE_H +#ifndef BSD_INTERFACE_H +#define BSD_INTERFACE_H #include "EthernetInterface.h" -#include "rtos.h" -#include "lwip/netif.h" -/** LWIPInterface class - * Implementation of the NetworkInterface for LWIP +/** BSDInterface class + * Implementation of the NetworkInterface for BSD sockets */ -class LWIPInterface : public EthernetInterface +class BSDInterface : public NetworkInterface { public: - // Implementation of EthernetInterface - virtual int32_t connect(); - virtual int32_t disconnect(); - // Implementation of NetworkInterface virtual const char *getMACAddress();