Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: lwip-eth lwip-sys lwip
Fork of LWIPInterface by
Diff: LWIPInterface.cpp
- Revision:
- 2:7fb7e78cb17f
- Parent:
- 1:2fbcfc9c12dd
- Child:
- 3:774869068511
--- 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;
+ }
+}
+
+
