Socket interface for C027Interface. Implements the NetworkSocketAPI

Dependencies:   C027_Support

Dependents:   HelloC027Interface U_Blox_DeviceConnector U_Blox_DeviceConnector U-Blox_Client

Fork of LWIPInterface by NetworkSocketAPI

Files at this revision

API Documentation at this revision

Comitter:
Christopher Haster
Date:
Thu Feb 25 11:09:49 2016 -0600
Parent:
1:2fbcfc9c12dd
Child:
3:774869068511
Commit message:
Added rudimentary implementation of the LWIPInterface

Changed in this revision

LWIPInterface.cpp Show annotated file Show diff for this revision Revisions of this file
LWIPInterface.h Show annotated file Show diff for this revision Revisions of this file
--- a/LWIPInterface.cpp	Fri Feb 26 17:40:23 2016 +0000
+++ b/LWIPInterface.cpp	Thu Feb 25 11:09:49 2016 -0600
@@ -14,4 +14,235 @@
  * limitations under the License.
  */
  
- #include "LWIPInterface.h"
\ No newline at end of file
+#include "LWIPInterface.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
+
+
+/* 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();
+    }
+}
+
+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);
+}
+
+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;
+    }
+
+    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);
+    }
+
+    // Connect to network
+    eth_arch_enable_interrupts();
+
+    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;
+        }
+    }
+
+    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
+ */
+class LWIPSocket : public SocketInterface
+{
+public:
+    LWIPSocket(int fd) : fd(fd) {}
+
+    // Implementation of SocketInterface
+    virtual int32_t open(const char *ip, uint16_t port);
+    virtual int32_t close();
+
+    virtual int32_t send(const void *data, uint32_t size);
+    virtual int32_t recv(void *data, uint32_t size);
+
+    int fd;
+};
+
+
+SocketInterface *LWIPInterface::createSocket(socket_protocol_t proto)
+{
+    int type = (proto == SOCK_UDP) ? SOCK_DGRAM : SOCK_STREAM;
+    int fd = lwip_socket(AF_INET, type, 0);
+
+    if (fd < 0) {
+        return 0;
+    }
+
+    return new LWIPSocket(fd);
+}
+
+void LWIPInterface::destroySocket(SocketInterface *siface)
+{
+    LWIPSocket *socket = (LWIPSocket *)siface;
+    lwip_close(socket->fd);
+
+    delete socket;
+}
+
+
+// TCP SocketInterface implementation
+int32_t LWIPSocket::open(const char *ip, uint16_t port)
+{
+    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);
+
+    if (lwip_connect(fd, (const struct sockaddr *)&host, sizeof host) < 0) {
+        return NS_ERROR_NO_CONNECTION;
+    }
+
+    return 0;
+}
+
+int32_t LWIPSocket::close()
+{
+    return 0;
+}
+
+int32_t LWIPSocket::send(const void *voiddata, 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;
+        }
+    }
+
+    return 0;
+}
+
+int32_t LWIPSocket::recv(void *data, uint32_t size)
+{
+    int ret = lwip_recv(fd, data, size, MSG_DONTWAIT);
+
+    if (ret > 0) {
+        return ret;
+    } else if (ret == 0) {
+        return NS_ERROR_NO_CONNECTION;
+    } else if (ret == -1) {
+        return 0;
+    } else {
+        return NS_ERROR_DEVICE_ERROR;
+    }
+}
+
+
--- a/LWIPInterface.h	Fri Feb 26 17:40:23 2016 +0000
+++ b/LWIPInterface.h	Thu Feb 25 11:09:49 2016 -0600
@@ -18,6 +18,8 @@
 #define LWIP_INTERFACE_H
 
 #include "EthernetInterface.h"
+#include "rtos.h"
+#include "lwip/netif.h"
 
 
 /** LWIPInterface class
@@ -26,9 +28,6 @@
 class LWIPInterface : public EthernetInterface
 {
 public:
-    LWIPInterface(bool debug = false);
-    virtual ~LWIPInterface();
-
     // Implementation of EthernetInterface
     virtual int32_t connect();
     virtual int32_t disconnect();