From 9cf9ddd2d0205df80cf3eaf3cdadd5a12f99beb4 Mon Sep 17 00:00:00 2001 From: Junhwan Park Date: Mon, 1 May 2017 16:56:11 +0900 Subject: [PATCH] examples: add an application for libtuv This patch includes an example application for libtuv. Change-Id: I28f5921aeec8b4b245c3c4daf6b31afb339c3bc8 Signed-off-by: Junhwan Park --- apps/examples/libtuv/Kconfig | 6 ++ apps/examples/libtuv/Make.defs | 21 +++++ apps/examples/libtuv/Makefile | 163 ++++++++++++++++++++++++++++++++ apps/examples/libtuv/libtuv_main.c | 118 +++++++++++++++++++++++ apps/examples/libtuv/libtuvapi.c | 187 +++++++++++++++++++++++++++++++++++++ apps/examples/libtuv/libtuvapi.h | 37 ++++++++ 6 files changed, 532 insertions(+) create mode 100644 apps/examples/libtuv/Kconfig create mode 100644 apps/examples/libtuv/Make.defs create mode 100644 apps/examples/libtuv/Makefile create mode 100644 apps/examples/libtuv/libtuv_main.c create mode 100644 apps/examples/libtuv/libtuvapi.c create mode 100644 apps/examples/libtuv/libtuvapi.h diff --git a/apps/examples/libtuv/Kconfig b/apps/examples/libtuv/Kconfig new file mode 100644 index 0000000..9dcde6b --- /dev/null +++ b/apps/examples/libtuv/Kconfig @@ -0,0 +1,6 @@ +config EXAMPLES_LIBTUV + bool "libtuv Example" + select LIBTUV + default n + ---help--- + Enable the libtuv Example diff --git a/apps/examples/libtuv/Make.defs b/apps/examples/libtuv/Make.defs new file mode 100644 index 0000000..5d31593 --- /dev/null +++ b/apps/examples/libtuv/Make.defs @@ -0,0 +1,21 @@ +########################################################################### +# +# Copyright 2017 Samsung Electronics All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +# +########################################################################### + +ifeq ($(CONFIG_EXAMPLES_LIBTUV),y) +CONFIGURED_APPS += examples/libtuv +endif diff --git a/apps/examples/libtuv/Makefile b/apps/examples/libtuv/Makefile new file mode 100644 index 0000000..f8cba32 --- /dev/null +++ b/apps/examples/libtuv/Makefile @@ -0,0 +1,163 @@ +############################################################################ +# +# Copyright 2017 Samsung Electronics All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +# +############################################################################ +############################################################################ +# apps/examples/libtuv/Makefile +# +# Copyright (C) 2008, 2010-2013 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# built-in application info + +APPNAME = libtuv +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 +THREADEXEC = TASH_EXECMD_SYNC + +# Example + +ASRCS = +CSRCS = libtuvapi.c +MAINSRC = libtuv_main.c + +CFLAGS += -I$(TOPDIR)/../external/libtuv/include +CFLAGS += -I$(TOPDIR)/../external/libtuv/source/tinyara + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) +OBJS = $(AOBJS) $(COBJS) + +ifneq ($(CONFIG_BUILD_KERNEL),y) + OBJS += $(MAINOBJ) +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +CONFIG_EXAMPLES_LIBTUV_PROGNAME ?= libtuv$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_LIBTUV_PROGNAME) + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend distclean preconfig + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + @touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) + @echo "LD: $(PROGNAME)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME) + +else +install: + +endif + +ifeq ($(CONFIG_EXAMPLES_LIBTUV),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME),$(APPNAME)_main,$(THREADEXEC)) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat + +else +context: + +endif + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep + +preconfig: + diff --git a/apps/examples/libtuv/libtuv_main.c b/apps/examples/libtuv/libtuv_main.c new file mode 100644 index 0000000..48512cc --- /dev/null +++ b/apps/examples/libtuv/libtuv_main.c @@ -0,0 +1,118 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PORT 5683 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +int socket_send; +int socket_receive; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void on_interval_send_callback_2s(void *user_data) +{ + printf("%s\n", __func__); + + int send_len = 0; + struct sockaddr_in address; + + bzero(&address, sizeof(address)); + address.sin_family = AF_INET; + address.sin_addr.s_addr = inet_addr("127.0.0.1"); + address.sin_port = htons(PORT); + + socket_send = socket(AF_INET, SOCK_DGRAM, 0); + send_len = sendto(socket_send, "hello", sizeof("hello"), 0, (struct sockaddr *)&address, sizeof(address)); + + printf("test_time upsend_len: %d\n", send_len); +} + +static void on_interval_send_callback_5s(void *user_data) +{ + printf("%s\n", __func__); + + libtuv_loop_quit(); +} + +static int os_watch_io_receive_callback(int fd, enum watch_io io, void *user_data) +{ + printf("%s, in para fd: %d, global fd: %d\n", __func__, fd, socket_receive); + + int sin_len; + char message[256]; + struct sockaddr_in sin; + int recv_len; + + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(PORT); + + sin_len = sizeof(sin); + recv_len = recvfrom(fd, message, sizeof(message), 0, (struct sockaddr *)&sin, (socklen_t *)&sin_len); + + printf("Response from server:%s, len: %d\n", message, recv_len); + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char *argv[]) +#else +int libtuv_main(int argc, FAR char *argv[]) +#endif +{ + int fd_watch = -1; + struct sockaddr_in sin; + + bzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(PORT); + + socket_receive = socket(AF_INET, SOCK_DGRAM, 0); + bind(socket_receive, (struct sockaddr *)&sin, sizeof(sin)); + printf("socket_receive = %d\n", socket_receive); + + libtuv_add_timeout_callback(2000, on_interval_send_callback_2s, NULL); + libtuv_add_timeout_callback(5000, on_interval_send_callback_5s, NULL); + libtuv_add_fd_watch(socket_receive, WATCH_IO_IN, os_watch_io_receive_callback, NULL, &fd_watch); + + libtuv_loop_run(); + + close(socket_receive); + + return 0; +} diff --git a/apps/examples/libtuv/libtuvapi.c b/apps/examples/libtuv/libtuvapi.c new file mode 100644 index 0000000..3dbb082 --- /dev/null +++ b/apps/examples/libtuv/libtuvapi.c @@ -0,0 +1,187 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +#include +#include +#include + +struct _timeout { + timeout_callback func; + void *user_data; + uv_timer_t *handle; +}; + +struct _watch { + watch_callback func; + void *user_data; + uv_poll_t *handle; + int fd; +}; + +struct _idle { + idle_callback func; + void *user_data; + uv_idle_t *handle; +}; + +static uv_loop_t *_loop; + +static void _check_loop(void) +{ + if (_loop == NULL) { + _loop = uv_default_loop(); + } +} + +static uv_loop_t *_get_loop(void) +{ + _check_loop(); + return _loop; +} + +void libtuv_loop_run(void) +{ + uv_run(_get_loop(), UV_RUN_DEFAULT); +} + +void libtuv_loop_quit(void) +{ + if (_loop) { + uv_loop_close(_loop); + } + + _loop = NULL; +} + +static void _timeout_callback(uv_timer_t *handle) +{ + struct _timeout *timeout = handle->data; + + if (timeout->func) { + timeout->func(timeout->user_data); + } + + uv_timer_stop(timeout->handle); + free(timeout->handle); + + memset(timeout, 0, sizeof(struct _timeout)); + free(timeout); +} + +int libtuv_add_timeout_callback(unsigned int msec, timeout_callback func, void *user_data) +{ + struct _timeout *timeout = NULL; + + timeout = (struct _timeout *)malloc(sizeof(struct _timeout)); + timeout->func = func; + timeout->user_data = user_data; + timeout->handle = (uv_timer_t *)malloc(sizeof(uv_timer_t)); + timeout->handle->data = timeout; + + uv_update_time(_get_loop()); + uv_timer_init(_get_loop(), timeout->handle); + uv_timer_start(timeout->handle, _timeout_callback, msec, 0); + + return 0; +} + +static void _watch_callback(uv_poll_t *handle, int status, int events) +{ + struct _watch *watch = handle->data; + enum watch_io io = 0; + int ret; + + if (events & UV_READABLE) { + io |= WATCH_IO_IN; + } + if (events & UV_WRITABLE) { + io |= WATCH_IO_OUT; + } + if (events & UV_DISCONNECT) { + io |= WATCH_IO_HUP; + } + + ret = watch->func(watch->fd, io, watch->user_data); + if (!ret) { + uv_poll_stop(watch->handle); + free(watch->handle); + + memset(watch, 0, sizeof(struct _watch)); + free(watch); + } +} + +int libtuv_add_fd_watch(int fd, enum watch_io io, watch_callback func, void *user_data, int *watch_id) +{ + struct _watch *watch; + int events = 0; + + watch = (struct _watch *)malloc(sizeof(struct _watch)); + watch->func = func; + watch->user_data = user_data; + watch->handle = (uv_poll_t *)malloc(sizeof(uv_poll_t)); + watch->handle->data = watch; + + if (io & WATCH_IO_IN) { + events |= UV_READABLE; + } + if (io & WATCH_IO_OUT) { + events |= UV_WRITABLE; + } + if (io & WATCH_IO_HUP) { + events |= UV_DISCONNECT; + } + + uv_poll_init_socket(_get_loop(), watch->handle, fd); + uv_poll_start(watch->handle, events, _watch_callback); + + watch->fd = fd; + + return 0; +} + +static void _idle_callback(uv_idle_t *handle) +{ + struct _idle *idle = handle->data; + int ret; + + ret = idle->func(idle->user_data); + if (!ret) { + uv_idle_stop(idle->handle); + free(idle->handle); + + memset(idle, 0, sizeof(struct _idle)); + free(idle); + } +} + +int libtuv_add_idle_callback(idle_callback func, void *user_data) +{ + struct _idle *idle; + + idle = (struct _idle *)malloc(sizeof(struct _idle)); + idle->func = func; + idle->user_data = user_data; + idle->handle = (uv_idle_t *)malloc(sizeof(uv_idle_t)); + idle->handle->data = idle; + + uv_idle_init(_get_loop(), idle->handle); + uv_idle_start(idle->handle, _idle_callback); + + return 0; +} diff --git a/apps/examples/libtuv/libtuvapi.h b/apps/examples/libtuv/libtuvapi.h new file mode 100644 index 0000000..e58d9f4 --- /dev/null +++ b/apps/examples/libtuv/libtuvapi.h @@ -0,0 +1,37 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ + +enum watch_io { + WATCH_IO_IN = (1 << 0), /**< data input available */ + WATCH_IO_OUT = (1 << 1), /**< data can be written */ + WATCH_IO_PRI = (1 << 2), /**< high priority input available */ + WATCH_IO_ERR = (1 << 3), /**< i/o error */ + WATCH_IO_HUP = (1 << 4), /**< Hung up. device disconnected */ + WATCH_IO_NVAL = (1 << 5) + /**< invalid request. the file descriptor is not open */ +}; + +typedef void (*timeout_callback)(void *user_data); +typedef int (*watch_callback)(int fd, enum watch_io io, void *user_data); +typedef int (*idle_callback)(void *user_data); + +void libtuv_loop_run(void); +void libtuv_loop_quit(void); +int libtuv_add_timeout_callback(unsigned int msec, timeout_callback func, void *user_data); +int libtuv_add_fd_watch(int fd, enum watch_io io, watch_callback func, void *user_data, int *watch_id); +int libtuv_add_idle_callback(idle_callback func, void *user_data); -- 2.7.4