aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Tabaka <corey.tabaka@gmail.com>2013-07-15 23:04:34 -0700
committerCorey Tabaka <corey.tabaka@gmail.com>2013-07-18 02:30:41 -0700
commitf09a432ebe651a3e209b8f4cc44fa4c4caf082a3 (patch)
treedea8ce242b98ef0fdb96fe1a2b603555d92e073e
parent98bce07fb5495876233e4c70add2a096db7331c2 (diff)
downloadlk-f09a432ebe651a3e209b8f4cc44fa4c4caf082a3.tar.gz
[lib][lwip] Add arch/sys support for LK to LWIP.
-rw-r--r--lib/lwip/include/arch/cc.h56
-rw-r--r--lib/lwip/include/arch/perf.h8
-rw-r--r--lib/lwip/include/arch/sys_arch.h36
-rw-r--r--lib/lwip/include/lwipopts.h49
-rw-r--r--lib/lwip/netif.c151
-rw-r--r--lib/lwip/rules.mk60
-rw-r--r--lib/lwip/sys_arch.c217
7 files changed, 577 insertions, 0 deletions
diff --git a/lib/lwip/include/arch/cc.h b/lib/lwip/include/arch/cc.h
new file mode 100644
index 00000000..bcb3fe62
--- /dev/null
+++ b/lib/lwip/include/arch/cc.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIB_LWIP_ARCH_CC_H
+#define __LIB_LWIP_ARCH_CC_H
+
+#include <stdint.h>
+#include <endian.h>
+#include <stdio.h>
+#include <compiler.h>
+
+typedef uint8_t u8_t;
+typedef uint16_t u16_t;
+typedef uint32_t u32_t;
+typedef int8_t s8_t;
+typedef int16_t s16_t;
+typedef int32_t s32_t;
+
+typedef intptr_t mem_ptr_t;
+
+#define U16_F "u"
+#define S16_F "d"
+#define X16_F "x"
+#define U32_F "u"
+#define S32_F "d"
+#define X32_F "x"
+#define SZT_F "zu"
+
+#define LWIP_CHKSUM_ALGORITHM 2
+
+#define LWIP_PLATFORM_DIAG(x) do {} while (0)
+#define LWIP_PLATFORM_ASSERT(x) do {} while (0)
+
+#define PACK_STRUCT_STRUCT __PACKED
+
+#endif
+
diff --git a/lib/lwip/include/arch/perf.h b/lib/lwip/include/arch/perf.h
new file mode 100644
index 00000000..2a023ac8
--- /dev/null
+++ b/lib/lwip/include/arch/perf.h
@@ -0,0 +1,8 @@
+#ifndef __LIB_LWIP_ARCH_PERF_H
+#define __LIB_LWIP_ARCH_PERF_H
+
+#define PERF_START do {} while (0)
+#define PERF_STOP(x) do {} while (0)
+
+#endif
+
diff --git a/lib/lwip/include/arch/sys_arch.h b/lib/lwip/include/arch/sys_arch.h
new file mode 100644
index 00000000..1ea40f71
--- /dev/null
+++ b/lib/lwip/include/arch/sys_arch.h
@@ -0,0 +1,36 @@
+#ifndef __LIB_LWIP_ARCH_SYS_ARCH_H
+#define __LIB_LWIP_ARCH_SYS_ARCH_H
+
+#include <kernel/thread.h>
+#include <kernel/semaphore.h>
+#include <kernel/mutex.h>
+
+typedef semaphore_t sys_sem_t;
+typedef mutex_t sys_mutex_t;
+
+typedef struct {
+ semaphore_t empty;
+ semaphore_t full;
+ mutex_t lock;
+
+ int head;
+ int tail;
+
+ int size;
+
+ void **queue;
+} sys_mbox_t;
+
+struct sys_thread {
+ thread_t *t;
+
+ void (*func)(void *);
+ void *arg;
+
+ struct sys_timeouts *timeouts;
+};
+
+typedef struct sys_thread * sys_thread_t;
+
+#endif
+
diff --git a/lib/lwip/include/lwipopts.h b/lib/lwip/include/lwipopts.h
new file mode 100644
index 00000000..40827c27
--- /dev/null
+++ b/lib/lwip/include/lwipopts.h
@@ -0,0 +1,49 @@
+#ifndef __LIB_LWIP_LWIPOPTS_H
+#define __LIB_LWIP_LWIPOPTS_H
+
+#include <errno.h>
+#include <malloc.h>
+#include <kernel/thread.h>
+
+#define MEM_LIBC_MALLOC 1
+#define MEM_SIZE (256 * 1024 * 1024)
+
+#define MEMP_NUM_UDP_PCB 128
+#define MEMP_NUM_TCP_PCB 128
+#define MEMP_NUM_TCP_PCB_LISTEN 128
+
+#define MEMP_NUM_NETBUF 32
+#define MEMP_NUM_NETCONN 32
+
+#define MEMP_NUM_NETDB 32
+
+#define LWIP_COMPAT_SOCKETS 0
+
+#define LWIP_DHCP 1
+#define LWIP_AUTOIP 1
+#define LWIP_DHCP_AUTOIP_COOP 1
+
+#define LWIP_DNS 1
+
+#define LWIP_NETIF_HOSTNAME 1
+#define LWIP_NETIF_API 1
+#define LWIP_NETIF_STATUS_CALLBACK 1
+#define LWIP_NETIF_HWADDRHINT 1
+#define LWIP_NETIF_LOOPBACK 1
+
+#define LWIP_HAVE_LOOPIF 1
+
+#define TCPIP_THREAD_STACKSIZE DEFAULT_STACK_SIZE
+#define TCPIP_THREAD_PRIO DEFAULT_PRIORITY
+
+#define TCPIP_MBOX_SIZE 16
+
+#define DEFAULT_THREAD_STACKSIZE DEFAULT_STACK_SIZE
+
+#define DEFAULT_UDP_RECVMBOX_SIZE 16
+#define DEFAULT_TCP_RECVMBOX_SIZE 16
+#define DEFAULT_ACCEPTMBOX_SIZE 16
+
+#define LWIP_STATS_DISPLAY 0
+#endif
+
diff --git a/lib/lwip/netif.c b/lib/lwip/netif.c
new file mode 100644
index 00000000..150e0fce
--- /dev/null
+++ b/lib/lwip/netif.c
@@ -0,0 +1,151 @@
+#include <dev/class/netif.h>
+#include <kernel/event.h>
+#include <arch/ops.h>
+#include <netif/etharp.h>
+#include <lwip/netif.h>
+#include <lwip/dhcp.h>
+#include <debug.h>
+#include <assert.h>
+#include <list.h>
+#include <err.h>
+
+#define LOCAL_TRACE 0
+
+struct local_netif {
+ struct netif netif;
+ struct device *dev;
+};
+
+static event_t netif_up_event = EVENT_INITIAL_VALUE(netif_up_event, false, 0);
+static volatile int netif_up_count = 0;
+
+static err_t local_linkoutput(struct netif *netif, struct pbuf *p)
+{
+ LTRACE_ENTRY;
+
+ struct local_netif *nif = containerof(netif, struct local_netif, netif);
+ DEBUG_ASSERT(nif);
+
+ status_t res = class_netif_output(nif->dev, p);
+
+ LTRACE_EXIT;
+
+ switch (res) {
+ case NO_ERROR: return ERR_OK;
+ case ERR_NO_MEMORY: return ERR_MEM;
+ case ERR_TIMED_OUT: return ERR_TIMEOUT;
+ default: return ERR_IF;
+ }
+}
+
+static void local_netif_status(struct netif *netif)
+{
+ struct local_netif *nif = containerof(netif, struct local_netif, netif);
+ DEBUG_ASSERT(nif);
+
+ if (netif->flags & NETIF_FLAG_UP) {
+ TRACEF("netif %c%c ip %u.%u.%u.%u netmask %u.%u.%u.%u gw %u.%u.%u.%u\n",
+ netif->name[0], netif->name[1],
+ ip4_addr1_16(&netif->ip_addr),
+ ip4_addr2_16(&netif->ip_addr),
+ ip4_addr3_16(&netif->ip_addr),
+ ip4_addr4_16(&netif->ip_addr),
+ ip4_addr1_16(&netif->netmask),
+ ip4_addr2_16(&netif->netmask),
+ ip4_addr3_16(&netif->netmask),
+ ip4_addr4_16(&netif->netmask),
+ ip4_addr1_16(&netif->gw),
+ ip4_addr2_16(&netif->gw),
+ ip4_addr3_16(&netif->gw),
+ ip4_addr4_16(&netif->gw));
+
+ if (atomic_add(&netif_up_count, 1) >= 0)
+ event_signal(&netif_up_event, true);
+ } else {
+ if (atomic_add(&netif_up_count, -1) == 1)
+ event_unsignal(&netif_up_event);
+ }
+}
+
+static err_t local_netif_init(struct netif *netif)
+{
+ LTRACE_ENTRY;
+
+ struct local_netif *nif = containerof(netif, struct local_netif, netif);
+ DEBUG_ASSERT(nif);
+
+ netif->linkoutput = local_linkoutput;
+ netif->output = etharp_output;
+
+ netif->hwaddr_len = class_netif_get_hwaddr(nif->dev, netif->hwaddr, sizeof(netif->hwaddr));
+ netif->mtu = class_netif_get_mtu(nif->dev);
+
+ netif->name[0] = 'e';
+ netif->name[1] = 'n';
+ netif->num = 0;
+ netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
+
+ LTRACE_EXIT;
+
+ return ERR_OK;
+}
+
+status_t class_netstack_wait_for_network(lk_time_t timeout)
+{
+ status_t res;
+
+ LTRACE_ENTRY;
+
+ res = event_wait_timeout(&netif_up_event, timeout);
+ LTRACEF("res=%d\n", res);
+
+ LTRACE_EXIT;
+ return res;
+}
+
+status_t class_netif_add(struct device *dev)
+{
+ status_t err;
+ ip_addr_t ipaddr, netmask, gw;
+
+ struct local_netif *nif = malloc(sizeof(struct local_netif));
+ if (!nif)
+ return ERR_NO_MEMORY;
+
+ nif->dev = dev;
+
+ err = class_netif_set_state(dev, (struct netstack_state *) nif);
+ if (err)
+ goto done;
+
+ IP4_ADDR(&gw, 0, 0, 0, 0);
+ IP4_ADDR(&ipaddr, 0, 0, 0, 0);
+ IP4_ADDR(&netmask, 255, 255, 255, 255);
+
+ netif_add(&nif->netif, &ipaddr, &netmask, &gw, nif, local_netif_init, ethernet_input);
+ netif_set_default(&nif->netif);
+ netif_set_status_callback(&nif->netif, local_netif_status);
+ dhcp_start(&nif->netif);
+
+ err = NO_ERROR;
+
+done:
+ return err;
+}
+
+status_t class_netstack_input(struct device *dev, struct netstack_state *state, struct pbuf *p)
+{
+ LTRACE_ENTRY;
+
+ struct local_netif *nif = (struct local_netif *) state;
+ if (!nif)
+ return ERR_INVALID_ARGS;
+
+ if (nif->netif.input(p, &nif->netif) != ERR_OK)
+ pbuf_free(p);
+
+ LTRACE_EXIT;
+
+ return NO_ERROR;
+}
+
diff --git a/lib/lwip/rules.mk b/lib/lwip/rules.mk
new file mode 100644
index 00000000..400fab14
--- /dev/null
+++ b/lib/lwip/rules.mk
@@ -0,0 +1,60 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULES += \
+
+INCLUDES += \
+ -I$(LOCAL_DIR)/include \
+ -I$(LOCAL_DIR)/include/lwip \
+ -I$(LOCAL_DIR)/include/posix \
+
+MODULE_SRCS += \
+ $(LOCAL_DIR)/sys_arch.c \
+ $(LOCAL_DIR)/netif.c \
+ $(LOCAL_DIR)/api/api_lib.c \
+ $(LOCAL_DIR)/api/api_msg.c \
+ $(LOCAL_DIR)/api/err.c \
+ $(LOCAL_DIR)/api/netbuf.c \
+ $(LOCAL_DIR)/api/netifapi.c \
+ $(LOCAL_DIR)/api/sockets.c \
+ $(LOCAL_DIR)/api/tcpip.c \
+ $(LOCAL_DIR)/core/def.c \
+ $(LOCAL_DIR)/core/dhcp.c \
+ $(LOCAL_DIR)/core/dns.c \
+ $(LOCAL_DIR)/core/init.c \
+ $(LOCAL_DIR)/core/mem.c \
+ $(LOCAL_DIR)/core/memp.c \
+ $(LOCAL_DIR)/core/netif.c \
+ $(LOCAL_DIR)/core/pbuf.c \
+ $(LOCAL_DIR)/core/raw.c \
+ $(LOCAL_DIR)/core/stats.c \
+ $(LOCAL_DIR)/core/sys.c \
+ $(LOCAL_DIR)/core/tcp.c \
+ $(LOCAL_DIR)/core/tcp_in.c \
+ $(LOCAL_DIR)/core/tcp_out.c \
+ $(LOCAL_DIR)/core/timers.c \
+ $(LOCAL_DIR)/core/udp.c \
+ $(LOCAL_DIR)/netif/etharp.c \
+
+LWIP_IP_TYPE := IPV4
+
+ifeq ($(LWIP_IP_TYPE),IPV4)
+
+INCLUDES += \
+ -I$(LOCAL_DIR)/include/ipv4 \
+
+MODULE_SRCS += \
+ $(LOCAL_DIR)/core/ipv4/autoip.c \
+ $(LOCAL_DIR)/core/ipv4/icmp.c \
+ $(LOCAL_DIR)/core/ipv4/igmp.c \
+ $(LOCAL_DIR)/core/ipv4/inet.c \
+ $(LOCAL_DIR)/core/ipv4/inet_chksum.c \
+ $(LOCAL_DIR)/core/ipv4/ip.c \
+ $(LOCAL_DIR)/core/ipv4/ip_addr.c \
+ $(LOCAL_DIR)/core/ipv4/ip_frag.c \
+
+endif
+
+include make/module.mk
+
diff --git a/lib/lwip/sys_arch.c b/lib/lwip/sys_arch.c
new file mode 100644
index 00000000..09f17536
--- /dev/null
+++ b/lib/lwip/sys_arch.c
@@ -0,0 +1,217 @@
+#include <arch/sys_arch.h>
+#include <lwip/err.h>
+#include <lwip/sys.h>
+#include <platform.h>
+#include <assert.h>
+#include <debug.h>
+#include <err.h>
+#include <stdbool.h>
+
+#define LOCAL_TRACE 1
+
+void sys_init(void)
+{
+}
+
+static int sys_thread_func(void *arg)
+{
+ LTRACE_ENTRY;
+
+ struct sys_thread *st = arg;
+ DEBUG_ASSERT(st);
+
+ tls_set(0, (uint32_t) st);
+
+ st->func(st->arg);
+
+ LTRACE_EXIT;
+ return 0;
+}
+
+sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
+{
+ struct sys_thread *st = malloc(sizeof(struct sys_thread));
+ DEBUG_ASSERT(st);
+
+ thread_t *t = thread_create(name, sys_thread_func, st, prio, stacksize);
+ DEBUG_ASSERT(t);
+
+ st->t = t;
+ st->func = thread;
+ st->arg = arg;
+
+ thread_detach(t);
+ thread_resume(t);
+
+ return st;
+}
+
+err_t sys_sem_new(sys_sem_t *sem, u8_t count)
+{
+ sem_init(sem, count);
+ return ERR_OK;
+}
+
+void sys_sem_free(sys_sem_t * sem)
+{
+ sem_destroy(sem);
+}
+
+int sys_sem_valid(sys_sem_t *sem)
+{
+ return 1;
+}
+
+void sys_sem_set_invalid(sys_sem_t *sem)
+{
+}
+
+void sys_sem_signal(sys_sem_t * sem)
+{
+ sem_post(sem);
+}
+
+u32_t sys_arch_sem_wait(sys_sem_t * sem, u32_t timeout)
+{
+ lk_time_t start = current_time();
+
+ status_t err = sem_timedwait(sem, timeout ? timeout : INFINITE_TIME);
+ if (err == ERR_TIMED_OUT)
+ return SYS_ARCH_TIMEOUT;
+
+ return current_time() - start;
+}
+
+err_t sys_mbox_new(sys_mbox_t * mbox, int size)
+{
+ sem_init(&mbox->empty, size);
+ sem_init(&mbox->full, 0);
+ mutex_init(&mbox->lock);
+
+ mbox->head = 0;
+ mbox->tail = 0;
+ mbox->size = size;
+
+ mbox->queue = calloc(size, sizeof(void *));
+ if (!mbox->queue)
+ return ERR_MEM;
+
+ return ERR_OK;
+}
+
+void sys_mbox_free(sys_mbox_t *mbox)
+{
+ free(mbox->queue);
+ mbox->queue = NULL;
+}
+
+void sys_mbox_post(sys_mbox_t * mbox, void *msg)
+{
+ sem_wait(&mbox->empty);
+ mutex_acquire(&mbox->lock);
+
+ mbox->queue[mbox->head] = msg;
+ mbox->head = (mbox->head + 1) % mbox->size;
+
+ mutex_release(&mbox->lock);
+ sem_post(&mbox->full);
+}
+
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t * mbox, void **msg)
+{
+ //LTRACE_ENTRY;
+
+ status_t res;
+
+ res = sem_trywait(&mbox->full);
+ if (res == ERR_NOT_READY) {
+ //LTRACE_EXIT;
+ return SYS_MBOX_EMPTY;
+ }
+
+ mutex_acquire(&mbox->lock);
+
+ *msg = mbox->queue[mbox->tail];
+ mbox->tail = (mbox->tail + 1) % mbox->size;
+
+ mutex_release(&mbox->lock);
+ sem_post(&mbox->empty);
+
+ //LTRACE_EXIT;
+ return 0;
+}
+
+u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
+{
+ //LTRACE_ENTRY;
+
+ status_t res;
+ lk_time_t start = current_time();
+
+ res = sem_timedwait(&mbox->full, timeout ? timeout : INFINITE_TIME);
+ if (res == ERR_TIMED_OUT) {
+ //LTRACE_EXIT;
+ return SYS_ARCH_TIMEOUT; //timeout ? SYS_ARCH_TIMEOUT : 0;
+ }
+
+ mutex_acquire(&mbox->lock);
+
+ *msg = mbox->queue[mbox->tail];
+ mbox->tail = (mbox->tail + 1) % mbox->size;
+
+ mutex_release(&mbox->lock);
+ sem_post(&mbox->empty);
+
+ //LTRACE_EXIT;
+ return current_time() - start;
+}
+
+err_t sys_mbox_trypost(sys_mbox_t * mbox, void *msg)
+{
+ status_t res;
+
+ res = sem_trywait(&mbox->empty);
+ if (res == ERR_NOT_READY)
+ return ERR_TIMEOUT;
+
+ mutex_acquire(&mbox->lock);
+
+ mbox->queue[mbox->head] = msg;
+ mbox->head = (mbox->head + 1) % mbox->size;
+
+ mutex_release(&mbox->lock);
+ sem_post(&mbox->full);
+
+ return ERR_OK;
+}
+
+int sys_mbox_valid(sys_mbox_t *mbox)
+{
+ return mbox->queue != NULL;
+}
+
+void sys_mbox_set_invalid(sys_mbox_t *mbox)
+{
+}
+
+err_t sys_mutex_new(sys_mutex_t *mutex)
+{
+ mutex_init(mutex);
+ return ERR_OK;
+}
+
+void sys_mutex_lock(sys_mutex_t *mutex)
+{
+ mutex_acquire(mutex);
+}
+
+void sys_mutex_unlock(sys_mutex_t *mutex)
+{
+ mutex_release(mutex);
+}
+
+void sys_mutex_free(sys_mutex_t *mutex)
+{
+ mutex_destroy(mutex);
+}
+