diff options
author | Corey Tabaka <corey.tabaka@gmail.com> | 2013-07-15 23:04:34 -0700 |
---|---|---|
committer | Corey Tabaka <corey.tabaka@gmail.com> | 2013-07-18 02:30:41 -0700 |
commit | f09a432ebe651a3e209b8f4cc44fa4c4caf082a3 (patch) | |
tree | dea8ce242b98ef0fdb96fe1a2b603555d92e073e | |
parent | 98bce07fb5495876233e4c70add2a096db7331c2 (diff) | |
download | lk-f09a432ebe651a3e209b8f4cc44fa4c4caf082a3.tar.gz |
[lib][lwip] Add arch/sys support for LK to LWIP.
-rw-r--r-- | lib/lwip/include/arch/cc.h | 56 | ||||
-rw-r--r-- | lib/lwip/include/arch/perf.h | 8 | ||||
-rw-r--r-- | lib/lwip/include/arch/sys_arch.h | 36 | ||||
-rw-r--r-- | lib/lwip/include/lwipopts.h | 49 | ||||
-rw-r--r-- | lib/lwip/netif.c | 151 | ||||
-rw-r--r-- | lib/lwip/rules.mk | 60 | ||||
-rw-r--r-- | lib/lwip/sys_arch.c | 217 |
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); +} + |