Implementation of the NetworkSocketAPI for LWIP
Dependencies: lwip-eth lwip-sys lwip
Dependents: HelloLWIPInterface HelloLWIPInterfaceNonBlocking LWIPInterfaceTests SimpleHTTPExample ... more
Diff: LWIPInterface.cpp
- Revision:
- 13:57d9e1721826
- Parent:
- 12:899403b675fe
- Child:
- 14:67b325c56cde
--- a/LWIPInterface.cpp Tue Apr 05 19:20:42 2016 +0000 +++ b/LWIPInterface.cpp Tue Apr 05 15:29:20 2016 -0500 @@ -14,9 +14,9 @@ * limitations under the License. */ +#include "mbed.h" #include "LWIPInterface.h" -#include "mbed.h" #include "lwip/inet.h" #include "lwip/netif.h" #include "lwip/dhcp.h" @@ -26,12 +26,11 @@ #include "netif/etharp.h" #include "eth_arch.h" -#if 0 /* TCP/IP and Network Interface Initialisation */ static struct netif netif; -static char ip_addr[NS_IP_SIZE] = "\0"; -static char mac_addr[NS_MAC_SIZE] = "\0"; +static char ip_addr[SocketAddress::IP_SIZE] = "\0"; +static char mac_addr[200] = "\0"; static Semaphore tcpip_inited(0); static Semaphore netif_linked(0); @@ -82,9 +81,8 @@ #endif } -#if 0 -// LWIPInterface implementation -int32_t LWIPInterface::connect() + +int LWIPInterface::connect() { // Set up network set_mac_address(); @@ -97,14 +95,14 @@ // Wait for an IP Address // -1: error, 0: timeout - if (netif_up.wait(LWIP_TIMEOUT) < 0) { - return NS_ERROR_TIMEOUT; + if (netif_up.wait(1500) < 0) { + return NSAPI_ERROR_DHCP_FAILURE; } return 0; } -int32_t LWIPInterface::disconnect() +int LWIPInterface::disconnect() { dhcp_release(&netif); dhcp_stop(&netif); @@ -114,285 +112,190 @@ return 0; } -const char *LWIPInterface::getIPAddress() +const char *LWIPInterface::get_ip_address() { return ip_addr; } -const char *LWIPInterface::getMACAddress() +const char *LWIPInterface::get_mac_address() { return mac_addr; } -SocketInterface *LWIPInterface::createSocket(ns_protocol_t proto) +void *LWIPInterface::socket_create(protocol_t proto) { - int type = (proto == NS_UDP) ? SOCK_DGRAM : SOCK_STREAM; + int type = (proto == NetworkInterface::UDP) ? SOCK_DGRAM : SOCK_STREAM; int fd = lwip_socket(AF_INET, type, 0); if (fd < 0) { return 0; } - return new LWIPSocket(fd); + return (void *)fd; } -void LWIPInterface::destroySocket(SocketInterface *siface) +void LWIPInterface::socket_destroy(void *handle) { - LWIPSocket *socket = (LWIPSocket *)siface; - lwip_close(socket->fd); + int fd = (int)handle; + lwip_close(fd); + +} - delete socket; +int LWIPInterface::socket_set_option(void *handle, int optname, const void *optval, unsigned optlen) +{ + return lwip_setsockopt((int)handle, SOL_SOCKET, optname, optval, (socklen_t)optlen); +} + +int LWIPInterface::socket_get_option(void *handle, int optname, void *optval, unsigned *optlen) +{ + return lwip_getsockopt((int)handle, SOL_SOCKET, optname, optval, (socklen_t*)optlen); } +int LWIPInterface::socket_bind(void *handle, int port) +{ + return NSAPI_ERROR_UNSUPPORTED; +} -// TCP SocketInterface implementation -int32_t LWIPInterface::LWIPSocket::open(const char *ip, uint16_t port) +int LWIPInterface::socket_listen(void *handle, int backlog) { - 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); + return NSAPI_ERROR_UNSUPPORTED; +} - if (lwip_connect(fd, (const struct sockaddr *)&host, sizeof host) < 0) { - return NS_ERROR_NO_CONNECTION; +int LWIPInterface::socket_connect(void *handle, const SocketAddress &addr) +{ + int fd = (int)handle; + struct sockaddr_in sa; + memset(&sa, 0, sizeof sa); + inet_aton(addr.get_ip_address(), &sa.sin_addr); + sa.sin_family = AF_INET; + sa.sin_port = htons(addr.get_port()); + + if (lwip_connect(fd, (const struct sockaddr *)&sa, sizeof sa) < 0) { + return NSAPI_ERROR_NO_CONNECTION; } return 0; } + +bool LWIPInterface::socket_is_connected(void *handle) +{ + return true; +} -int32_t LWIPInterface::LWIPSocket::close() +int LWIPInterface::socket_accept(void *handle, void **connection) { - return 0; + return NSAPI_ERROR_UNSUPPORTED; } -int32_t LWIPInterface::LWIPSocket::send(const void *voiddata, uint32_t size) +int LWIPInterface::socket_send(void *handle, const void *p, unsigned size) { - uint8_t *data = (uint8_t *)voiddata; - uint32_t writtenLen = 0; + int fd = (int)handle; + uint8_t *data = (uint8_t *)p; + unsigned written = 0; - while (writtenLen < size) { - int ret = lwip_send(fd, data + writtenLen, size - writtenLen, 0); + while (written < size) { + int ret = lwip_send(fd, data + written, size - written, 0); if (ret > 0) { - writtenLen += ret; + written += ret; } else if (ret == 0) { - return NS_ERROR_NO_CONNECTION; + return NSAPI_ERROR_NO_CONNECTION; } else { - return NS_ERROR_DEVICE_ERROR; + return NSAPI_ERROR_DEVICE_ERROR; } } - return writtenLen; + return written; } -int32_t LWIPInterface::LWIPSocket::recv(void *data, uint32_t size) +int LWIPInterface::socket_recv(void *handle, void *data, unsigned size) { + int fd = (int)handle; int ret = lwip_recv(fd, data, size, MSG_DONTWAIT); if (ret > 0) { return ret; } else if (ret == 0) { - return NS_ERROR_NO_CONNECTION; + return NSAPI_ERROR_NO_CONNECTION; } else if (ret == -1) { - return NS_ERROR_WOULD_BLOCK; + return NSAPI_ERROR_WOULD_BLOCK; } else { - return NS_ERROR_DEVICE_ERROR; + return NSAPI_ERROR_DEVICE_ERROR; } } -#endif - /** Start the interface - * @return 0 on success, negative on failure - */ - virtual int connect() = 0; - - /** Stop the interface - * @return 0 on success, negative on failure - */ - virtual int disconnect() = 0; - -class NetworkInterface +int LWIPInterface::socket_sendto(void *handle, const SocketAddress &addr, const void *p, unsigned size) { -public: - virtual ~NetworkInterface() {}; + int fd = (int)handle; + uint8_t *data = (uint8_t *)p; + unsigned written = 0; - /** Get the internally stored IP address - /return IP address of the interface or null if not yet connected - */ - virtual const char *get_ip_address() = 0; + struct sockaddr_in sa; + memset(&sa, 0, sizeof sa); + inet_aton(addr.get_ip_address(), &sa.sin_addr); + sa.sin_family = AF_INET; + sa.sin_port = htons(addr.get_port()); - /** Get the internally stored MAC address - /return MAC address of the interface - */ - virtual const char *get_mac_address() = 0; + while (written < size) { + int ret = lwip_sendto(fd, data + written, size - written, 0, + (const struct sockaddr *)&sa, sizeof sa); - /** Get the current status of the interface - /return true if connected - */ - virtual bool is_connected() { - return get_ip_address() != NULL; + if (ret > 0) { + written += ret; + } else if (ret == 0) { + return NSAPI_ERROR_NO_CONNECTION; + } else { + return NSAPI_ERROR_DEVICE_ERROR; + } } - /** Looks up the specified host's IP address - /param name Hostname to lookup - /param dest Destination for IP address, must have space for SocketAddress::IP_SIZE - /return 0 on success, negative on failure - */ - virtual int gethostbyname(const char *name, char *dest); - -protected: - friend class Socket; - friend class UDPSocket; - friend class TCPSocket; - friend class TCPServer; - - /** Enum of socket protocols - /enum protocol_t - */ - enum protocol_t { - TCP, /*!< Socket is of TCP type */ - UDP, /*!< Socket is of UDP type */ - }; - - /** Create a socket - /param proto The type of socket to open, TCP or UDP - /return The alocated socket or null on failure - */ - virtual void *socket_create(protocol_t proto) = 0; - - /** Destroy a socket - /param socket Previously allocated socket - */ - virtual void socket_destroy(void *handle) = 0; + return written; +} - /** Set socket options - \param handle Socket handle - \param optname Option ID - \param optval Option value - \param optlen Length of the option value - \return 0 on success, negative on failure - */ - virtual int socket_set_option(void *handle, int optname, const void *optval, unsigned int optlen) = 0; - - /** Get socket options - \param handle Socket handle - \param optname Option ID - \param optval Buffer pointer where to write the option value - \param optlen Length of the option value - \return 0 on success, negative on failure - */ - virtual int socket_get_option(void *handle, int optname, void *optval, unsigned int *optlen) = 0; +int LWIPInterface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) +{ + int fd = (int)handle; + struct sockaddr_in sa; + socklen_t sa_len = sizeof sa; - /** Bind a server socket to a specific port - \param handle Socket handle - \param port The port to listen for incoming connections on - \return 0 on success, negative on failure. - */ - virtual int socket_bind(void *handle, int port) = 0; + int ret = lwip_recvfrom(fd, data, size, MSG_DONTWAIT, + (struct sockaddr *)&sa, &sa_len); - /** Start listening for incoming connections - \param handle Socket handle - \param backlog Number of pending connections that can be queued up at any - one time [Default: 1] - \return 0 on success, negative on failure - */ - virtual int socket_listen(void *handle, int backlog) = 0; - - /** Connects this TCP socket to the server - \param handle Socket handle - \param address SocketAddress to connect to - \return 0 on success, negative on failure - */ - virtual int socket_connect(void *handle, const SocketAddress &address) = 0; - - /** Check if the socket is connected - \param handle Socket handle - \return true if connected, false otherwise - */ - virtual bool socket_is_connected(void *handle) = 0; + if (ret > 0 && addr) { + addr->set_ip_address(inet_ntoa(sa.sin_addr)); + addr->set_port(ntohs(sa.sin_port)); + } - /** Accept a new connection. - \param handle Socket handle - \param socket A TCPSocket instance that will handle the incoming connection. - \return 0 on success, negative on failure. - \note This call is not-blocking, if this call would block, must - immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_accept(void *handle, void **connection) = 0; - - /** Send data to the remote host - \param handle Socket handle - \param data The buffer to send to the host - \param size The length of the buffer to send - \return Number of written bytes on success, negative on failure - \note This call is not-blocking, if this call would block, must - immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_send(void *handle, const void *data, unsigned size) = 0; - - /** Receive data from the remote host - \param handle Socket handle - \param data The buffer in which to store the data received from the host - \param size The maximum length of the buffer - \return Number of received bytes on success, negative on failure - \note This call is not-blocking, if this call would block, must - immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_recv(void *handle, void *data, unsigned size) = 0; - - /** Send a packet to a remote endpoint - \param handle Socket handle - \param address The remote SocketAddress - \param data The packet to be sent - \param size The length of the packet to be sent - \return the number of written bytes on success, negative on failure - \note This call is not-blocking, if this call would block, must - immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size) = 0; + if (ret > 0) { + return ret; + } else if (ret == 0) { + return NSAPI_ERROR_NO_CONNECTION; + } else if (ret == -1) { + return NSAPI_ERROR_WOULD_BLOCK; + } else { + return NSAPI_ERROR_DEVICE_ERROR; + } +} - /** Receive a packet from a remote endpoint - \param handle Socket handle - \param address Destination for the remote SocketAddress or null - \param buffer The buffer for storing the incoming packet data - If a packet is too long to fit in the supplied buffer, - excess bytes are discarded - \param size The length of the buffer - \return the number of received bytes on success, negative on failure - \note This call is not-blocking, if this call would block, must - immediately return NSAPI_ERROR_WOULD_WAIT - */ - virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size) = 0; +int LWIPInterface::socket_close(void *handle, bool shutdown) +{ + int fd = (int)handle; + if (shutdown) { + lwip_shutdown(fd, SHUT_RDWR); + } - /** Close the socket - \param handle Socket handle - \param shutdown free the left-over data in message queues - */ - virtual int socket_close(void *handle, bool shutdown) = 0; + lwip_close(fd); + return 0; +} - /** Register a callback on when a new connection is ready - \param handle Socket handle - \param callback Function to call when accept will succeed, may be called in - interrupt context. - \param id Argument to pass to callback - */ - virtual void socket_attach_accept(void *handle, void (*callback)(void *), void *id) = 0; +void LWIPInterface::socket_attach_accept(void *handle, void (*callback)(void *), void *id) +{ +} - /** Register a callback on when send is ready - \param handle Socket handle - \param callback Function to call when accept will succeed, may be called in - interrupt context. - \param id Argument to pass to callback - */ - virtual void socket_attach_send(void *handle, void (*callback)(void *), void *id) = 0; +void LWIPInterface::socket_attach_send(void *handle, void (*callback)(void *), void *id) +{ +} - /** Register a callback on when recv is ready - \param handle Socket handle - \param callback Function to call when accept will succeed, may be called in - interrupt context. - \param id Argument to pass to callback - */ - virtual void socket_attach_recv(void *handle, void (*callback)(void *), void *id) = 0; -}; -#endif +void LWIPInterface::socket_attach_recv(void *handle, void (*callback)(void *), void *id) +{ +}