Wrapper of NetworkSocketAPI for BSD sockets on POSIX systems

Dependents:   BSDInterfaceTests HelloBSDInterface

Files at this revision

API Documentation at this revision

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();