Merged nuttx/apps/master into master
This commit is contained in:
commit
3e53181302
@ -12,21 +12,37 @@ config EXAMPLES_NETTEST
|
||||
|
||||
if EXAMPLES_NETTEST
|
||||
|
||||
config EXAMPLES_NETTEST_PROGNAME
|
||||
string "Program name"
|
||||
default "nettest"
|
||||
depends on BUILD_KERNEL
|
||||
---help---
|
||||
This is the name of the program that will be use when the Nettest
|
||||
program is installed.
|
||||
|
||||
config EXAMPLES_NETTEST_STACKSIZE
|
||||
int "Nettest stack size"
|
||||
default 2048
|
||||
|
||||
config EXAMPLES_NETTEST_PRIORITY
|
||||
int "Nettest priority"
|
||||
default 100
|
||||
|
||||
config EXAMPLES_NETTEST_LOOPBACK
|
||||
bool "Loopback test"
|
||||
default n
|
||||
depends on NET_LOOPBACK
|
||||
depends on NET_LOOPBACK || IEEE802154_LOOPBACK
|
||||
---help---
|
||||
Perform the test using the local loopback device. In this case,
|
||||
both the client and the server reside on the target.
|
||||
|
||||
if EXAMPLES_NETTEST_LOOPBACK
|
||||
|
||||
config EXAMPLES_NETTEST_STACKSIZE
|
||||
config EXAMPLES_NETTEST_SERVER_STACKSIZE
|
||||
int "Server stack size"
|
||||
default 2048
|
||||
|
||||
config EXAMPLES_NETTEST_PRIORITY
|
||||
config EXAMPLES_NETTEST_SERVER_PRIORITY
|
||||
int "Server priority"
|
||||
default 100
|
||||
|
||||
@ -369,7 +385,7 @@ config EXAMPLES_NETTEST_IPv6NETMASK_8
|
||||
endif # NET_ICMPv6_AUTOCONF
|
||||
endif # EXAMPLES_NETTEST_INIT
|
||||
|
||||
if !EXAMPLES_NETTEST_LOOPBACK
|
||||
if !EXAMPLES_NETTEST_LOOPBACK || !NET_LOOPBACK
|
||||
|
||||
comment "Client IPv6 address"
|
||||
|
||||
|
@ -106,9 +106,15 @@ ROOTDEPPATH = --dep-path .
|
||||
|
||||
# NET test built-in application info
|
||||
|
||||
CONFIG_EXAMPLES_NETTEST_STACKSIZE ?= 2048
|
||||
CONFIG_EXAMPLES_NETTEST_PRIORITY ?= 100
|
||||
|
||||
APPNAME = nettest
|
||||
PRIORITY = SCHED_PRIORITY_DEFAULT
|
||||
STACKSIZE = 2048
|
||||
PRIORITY = $(CONFIG_EXAMPLES_NETTEST_PRIORITY)
|
||||
STACKSIZE = $(CONFIG_EXAMPLES_NETTEST_STACKSIZE)
|
||||
|
||||
CONFIG_EXAMPLES_NETTEST_PROGNAME ?= nettest$(EXEEXT)
|
||||
PROGNAME = $(CONFIG_EXAMPLES_HELLO_PROGNAME)
|
||||
|
||||
# Common build
|
||||
|
||||
|
@ -219,8 +219,8 @@ int nettest_main(int argc, char *argv[])
|
||||
#if defined(CONFIG_EXAMPLES_NETTEST_LOOPBACK)
|
||||
/* Then perform the server side of the test on a child task */
|
||||
|
||||
child = task_create("Nettest Child", CONFIG_EXAMPLES_NETTEST_PRIORITY,
|
||||
CONFIG_EXAMPLES_NETTEST_STACKSIZE, server_child,
|
||||
child = task_create("Nettest Child", CONFIG_EXAMPLES_NETTEST_SERVER_PRIORITY,
|
||||
CONFIG_EXAMPLES_NETTEST_SERVER_STACKSIZE, server_child,
|
||||
NULL);
|
||||
if (child < 0)
|
||||
{
|
||||
|
@ -106,8 +106,8 @@ void send_client(void)
|
||||
myaddr.sin6_family = AF_INET6;
|
||||
myaddr.sin6_port = HTONS(PORTNO);
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_NETTEST_LOOPBACK
|
||||
myaddr.sin6_addr.s6_addr16[0] = 0;
|
||||
#if defined(CONFIG_EXAMPLES_NETTEST_LOOPBACK) && defined(NET_LOOPBACK)
|
||||
myaddr.sin6_addr.s6_addr16[0] = 0; /* Use the loopback address */
|
||||
myaddr.sin6_addr.s6_addr16[1] = 0;
|
||||
myaddr.sin6_addr.s6_addr16[2] = 0;
|
||||
myaddr.sin6_addr.s6_addr16[3] = 0;
|
||||
@ -126,17 +126,25 @@ void send_client(void)
|
||||
myaddr.sin6_addr.s6_addr16[7] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_8);
|
||||
#endif
|
||||
|
||||
printf("IPv6 Address: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||
myaddr.sin6_addr.s6_addr16[0], myaddr.sin6_addr.s6_addr16[1],
|
||||
myaddr.sin6_addr.s6_addr16[2], myaddr.sin6_addr.s6_addr16[3],
|
||||
myaddr.sin6_addr.s6_addr16[4], myaddr.sin6_addr.s6_addr16[5],
|
||||
myaddr.sin6_addr.s6_addr16[6], myaddr.sin6_addr.s6_addr16[7]);
|
||||
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
#else
|
||||
myaddr.sin_family = AF_INET;
|
||||
myaddr.sin_port = HTONS(PORTNO);
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_NETTEST_LOOPBACK
|
||||
#ifdef CONFIG_EXAMPLES_NETTEST_LOOPBACK && defined(NET_LOOPBACK)
|
||||
myaddr.sin_addr.s_addr = HTONL(0x7f000001);
|
||||
#else
|
||||
myaddr.sin_addr.s_addr = HTONL(CONFIG_EXAMPLES_NETTEST_CLIENTIP);
|
||||
#endif
|
||||
|
||||
printf("IPv4 Address: %08x\n", myaddr.sin_addr.s_addr);
|
||||
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
|
||||
|
@ -110,15 +110,33 @@ void recv_server(void)
|
||||
/* Bind the socket to a local address */
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_NETTEST_IPv6
|
||||
myaddr.sin6_family = AF_INET6;
|
||||
myaddr.sin6_port = HTONS(PORTNO);
|
||||
|
||||
myaddr.sin6_family = AF_INET6;
|
||||
myaddr.sin6_port = HTONS(PORTNO);
|
||||
|
||||
#if defined(CONFIG_EXAMPLES_NETTEST_LOOPBACK) && !defined(NET_LOOPBACK)
|
||||
myaddr.sin6_addr.s6_addr16[0] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_1);
|
||||
myaddr.sin6_addr.s6_addr16[1] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_2);
|
||||
myaddr.sin6_addr.s6_addr16[2] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_3);
|
||||
myaddr.sin6_addr.s6_addr16[3] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_4);
|
||||
myaddr.sin6_addr.s6_addr16[4] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_5);
|
||||
myaddr.sin6_addr.s6_addr16[5] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_6);
|
||||
myaddr.sin6_addr.s6_addr16[6] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_7);
|
||||
myaddr.sin6_addr.s6_addr16[7] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_8);
|
||||
#else
|
||||
memset(&myaddr.sin6_addr, 0, sizeof(struct in6_addr));
|
||||
#endif
|
||||
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
#else
|
||||
myaddr.sin_family = AF_INET;
|
||||
myaddr.sin_port = HTONS(PORTNO);
|
||||
myaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
myaddr.sin_family = AF_INET;
|
||||
myaddr.sin_port = HTONS(PORTNO);
|
||||
|
||||
#if defined(CONFIG_EXAMPLES_NETTEST_LOOPBACK) && !defined(NET_LOOPBACK)
|
||||
myaddr.sin_addr.s_addr = HTONL(CONFIG_EXAMPLES_NETTEST_CLIENTIP);
|
||||
#else
|
||||
myaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
#endif
|
||||
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
|
14
examples/usrsocktest/.gitignore
vendored
Normal file
14
examples/usrsocktest/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/Make.dep
|
||||
/.depend
|
||||
/.built
|
||||
/*.asm
|
||||
/*.obj
|
||||
/*.rel
|
||||
/*.lst
|
||||
/*.sym
|
||||
/*.adb
|
||||
/*.lib
|
||||
/*.src
|
||||
/*.hobj
|
||||
/*.exe
|
||||
/*.dSYM
|
36
examples/usrsocktest/Kconfig
Normal file
36
examples/usrsocktest/Kconfig
Normal file
@ -0,0 +1,36 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
config EXAMPLES_USRSOCKTEST
|
||||
bool "USRSOCK test example"
|
||||
default n
|
||||
depends on NET && NET_USRSOCK && !DISABLE_POLL
|
||||
select NET_USRSOCK_TCP
|
||||
select NET_USRSOCK_UDP
|
||||
select NET_SOCKOPTS
|
||||
select PIPES
|
||||
---help---
|
||||
Enable the User Socket test example. This example application runs
|
||||
unit-tests for /dev/usrsock.
|
||||
|
||||
if EXAMPLES_USRSOCKTEST
|
||||
|
||||
config EXAMPLES_USRSOCKTEST_PROGNAME
|
||||
string "Program name"
|
||||
default "usrsocktest"
|
||||
depends on BUILD_KERNEL
|
||||
---help---
|
||||
This is the name of the program that will be use when the NSH ELF
|
||||
program is installed.
|
||||
|
||||
config EXAMPLES_USRSOCKTEST_PRIORITY
|
||||
int "usrsocktest task priority"
|
||||
default 100
|
||||
|
||||
config EXAMPLES_USRSOCKTEST_STACKSIZE
|
||||
int "usrsocktest stack size"
|
||||
default 4096
|
||||
|
||||
endif
|
39
examples/usrsocktest/Make.defs
Normal file
39
examples/usrsocktest/Make.defs
Normal file
@ -0,0 +1,39 @@
|
||||
############################################################################
|
||||
# examples/usrsocktest/Make.defs
|
||||
# Adds selected applications to apps/ build
|
||||
#
|
||||
# Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifeq ($(CONFIG_EXAMPLES_USRSOCKTEST),y)
|
||||
CONFIGURED_APPS += examples/usrsocktest
|
||||
endif
|
65
examples/usrsocktest/Makefile
Normal file
65
examples/usrsocktest/Makefile
Normal file
@ -0,0 +1,65 @@
|
||||
############################################################################
|
||||
# apps/examples/usrsocktest/Makefile
|
||||
#
|
||||
# Copyright (C) 2008, 2010-2013 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# 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)/Make.defs
|
||||
|
||||
# USRSOCK Test built-in application info
|
||||
|
||||
CONFIG_EXAMPLES_USRSOCKTEST_PRIORITY ?= SCHED_PRIORITY_DEFAULT
|
||||
CONFIG_EXAMPLES_USRSOCKTEST_STACKSIZE ?= 4096
|
||||
|
||||
APPNAME = usrsocktest
|
||||
PRIORITY = $(CONFIG_EXAMPLES_USRSOCKTEST_PRIORITY)
|
||||
STACKSIZE = $(CONFIG_EXAMPLES_USRSOCKTEST_STACKSIZE)
|
||||
|
||||
# NuttX USRSOCK Test
|
||||
|
||||
ASRCS =
|
||||
CSRCS = usrsocktest_daemon.c usrsocktest_basic_connect.c
|
||||
CSRCS += usrsocktest_basic_daemon.c usrsocktest_basic_getsockname.c
|
||||
CSRCS += usrsocktest_basic_getsockopt.c usrsocktest_basic_send.c
|
||||
CSRCS += usrsocktest_basic_setsockopt.c usrsocktest_block_recv.c
|
||||
CSRCS += usrsocktest_block_send.c usrsocktest_chardev.c
|
||||
CSRCS += usrsocktest_multi_thread.c usrsocktest_noblock_connect.c
|
||||
CSRCS += usrsocktest_noblock_recv.c usrsocktest_noblock_send.c
|
||||
CSRCS += usrsocktest_nodaemon.c usrsocktest_poll.c
|
||||
CSRCS += usrsocktest_remote_disconnect.c usrsocktest_wake_with_signal.c
|
||||
|
||||
MAINSRC = usrsocktest_main.c
|
||||
|
||||
CONFIG_EXAMPLES_USRSOCKTEST_PROGNAME ?= usrsocktest$(EXEEXT)
|
||||
PROGNAME = $(CONFIG_EXAMPLES_USRSOCKTEST_PROGNAME)
|
||||
|
||||
include $(APPDIR)/Application.mk
|
212
examples/usrsocktest/defines.h
Normal file
212
examples/usrsocktest/defines.h
Normal file
@ -0,0 +1,212 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/defines.h
|
||||
* Common defines for all usrsock testcases
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Author: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __EXAMPLES_USRSOCKTEST_DEFINES_H
|
||||
#define __EXAMPLES_USRSOCKTEST_DEFINES_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define USRSOCK_NODE "/dev/usrsock"
|
||||
|
||||
#define USRSOCKTEST_DAEMON_CONF_DEFAULTS \
|
||||
{ \
|
||||
.max_sockets = UINT_MAX, \
|
||||
.supported_domain = AF_INET, \
|
||||
.supported_type = SOCK_STREAM, \
|
||||
.supported_protocol = 0, \
|
||||
.delay_all_responses = false, \
|
||||
.endpoint_addr = "127.0.0.1", \
|
||||
.endpoint_port = 255, \
|
||||
.endpoint_block_connect = false, \
|
||||
.endpoint_block_send = false, \
|
||||
.endpoint_recv_avail_from_start = true, \
|
||||
.endpoint_recv_avail = 4, \
|
||||
}
|
||||
|
||||
/* Test case macros */
|
||||
|
||||
#define utest_match(type, should_be_value, test_value) do { \
|
||||
type tmp_utest_test_value = (type)(test_value); \
|
||||
type tmp_utest_should_value = (type)(should_be_value); \
|
||||
if (!usrsocktest_assert_print_value(__func__, __LINE__, \
|
||||
"(" #type ")(" #test_value ") == " \
|
||||
"(" #type ")(" #should_be_value ")", \
|
||||
tmp_utest_test_value, \
|
||||
tmp_utest_should_value)) \
|
||||
{ \
|
||||
usrsocktest_test_failed = true; \
|
||||
return; \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
#define utest_match_buf(should_be_valuebuf, test_valuebuf, test_valuebuflen) do { \
|
||||
if (!usrsocktest_assert_print_buf(__func__, __LINE__, \
|
||||
"memcmp(" #should_be_valuebuf ", " \
|
||||
#test_valuebuf ", " \
|
||||
#test_valuebuflen ") == 0", \
|
||||
should_be_valuebuf, \
|
||||
test_valuebuf, \
|
||||
test_valuebuflen)) \
|
||||
{ \
|
||||
usrsocktest_test_failed = true; \
|
||||
return; \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
#define RUN_TEST_CASE(g,t) do { \
|
||||
if (usrsocktest_test_failed) \
|
||||
{ \
|
||||
return; \
|
||||
} \
|
||||
usrsocktest_group_##g##_setup(); \
|
||||
usrsocktest_test_##g##_##t(); \
|
||||
usrsocktest_group_##g##_teardown(); \
|
||||
if (usrsocktest_test_failed) \
|
||||
{ \
|
||||
return; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define RUN_TEST_GROUP(g) do { \
|
||||
extern const char *usrsocktest_group_##g; \
|
||||
void usrsocktest_group_##g##_run(void); \
|
||||
run_tests(usrsocktest_group_##g, usrsocktest_group_##g##_run); \
|
||||
} while (false)
|
||||
|
||||
#define TEST_GROUP(g) const char *usrsocktest_group_##g = #g; \
|
||||
void usrsocktest_group_##g##_run(void)
|
||||
#define TEST_SETUP(g) static void usrsocktest_group_##g##_setup(void)
|
||||
#define TEST_TEAR_DOWN(g) static void usrsocktest_group_##g##_teardown(void)
|
||||
#define TEST(g,t) static void usrsocktest_test_##g##_##t(void)
|
||||
|
||||
#define TEST_ASSERT_TRUE(v) utest_match(bool, true, (v))
|
||||
#define TEST_ASSERT_FALSE(v) utest_match(bool, false, (v))
|
||||
#define TEST_ASSERT_EQUAL(e,v) utest_match(ssize_t, (e), (v))
|
||||
#define TEST_ASSERT_EQUAL_UINT8_ARRAY(e,v,s) utest_match_buf((e), (v), (s))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct usrsocktest_daemon_conf_s
|
||||
{
|
||||
unsigned int max_sockets;
|
||||
int8_t supported_domain:8;
|
||||
int8_t supported_type:8;
|
||||
int8_t supported_protocol:8;
|
||||
bool delay_all_responses:1;
|
||||
bool endpoint_block_connect:1;
|
||||
bool endpoint_block_send:1;
|
||||
bool endpoint_recv_avail_from_start:1;
|
||||
uint8_t endpoint_recv_avail:8;
|
||||
const char *endpoint_addr;
|
||||
uint16_t endpoint_port;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern int usrsocktest_endp_malloc_cnt;
|
||||
extern int usrsocktest_dcmd_malloc_cnt;
|
||||
extern const struct usrsocktest_daemon_conf_s usrsocktest_daemon_defconf;
|
||||
extern struct usrsocktest_daemon_conf_s usrsocktest_daemon_config;
|
||||
|
||||
extern bool usrsocktest_test_failed;
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
bool usrsocktest_assert_print_value(FAR const char *func,
|
||||
const int line,
|
||||
FAR const char *check_str,
|
||||
long int test_value,
|
||||
long int should_be);
|
||||
|
||||
bool usrsocktest_assert_print_buf(FAR const char *func,
|
||||
const int line,
|
||||
FAR const char *check_str,
|
||||
FAR const void *test_buf,
|
||||
FAR const void *expect_buf,
|
||||
size_t buflen);
|
||||
|
||||
int usrsocktest_daemon_start(FAR const struct usrsocktest_daemon_conf_s *conf);
|
||||
|
||||
int usrsocktest_daemon_stop(void);
|
||||
|
||||
int usrsocktest_daemon_get_num_active_sockets(void);
|
||||
|
||||
int usrsocktest_daemon_get_num_connected_sockets(void);
|
||||
|
||||
int usrsocktest_daemon_get_num_waiting_connect_sockets(void);
|
||||
|
||||
int usrsocktest_daemon_get_num_recv_empty_sockets(void);
|
||||
|
||||
ssize_t usrsocktest_daemon_get_send_bytes(void);
|
||||
|
||||
ssize_t usrsocktest_daemon_get_recv_bytes(void);
|
||||
|
||||
int usrsocktest_daemon_get_num_unreachable_sockets(void);
|
||||
|
||||
int usrsocktest_daemon_get_num_remote_disconnected_sockets(void);
|
||||
|
||||
bool usrsocktest_daemon_establish_waiting_connections(void);
|
||||
|
||||
bool usrsocktest_send_delayed_command(char cmd, unsigned int delay_msec);
|
||||
|
||||
int usrsocktest_daemon_pause_usrsock_handling(bool pause);
|
||||
|
||||
#endif /* __EXAMPLES_USRSOCKTEST_DEFINES_H */
|
488
examples/usrsocktest/usrsocktest_basic_connect.c
Normal file
488
examples/usrsocktest/usrsocktest_basic_connect.c
Normal file
@ -0,0 +1,488 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_basic_connect.c
|
||||
* Basic connect tests with socket daemon
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Setup
|
||||
*
|
||||
* Description:
|
||||
* Run before every testcase
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - test daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Setup(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Teardown
|
||||
*
|
||||
* Description:
|
||||
* Run after every testcase
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Teardown(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NotConnected
|
||||
*
|
||||
* Description:
|
||||
* Opened socket is not connected
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void NotConnected(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Connect
|
||||
*
|
||||
* Description:
|
||||
* Open and connect the socket
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Connect(void)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Attempt reconnect to same address */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Attempt reconnect to different address */
|
||||
|
||||
inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(1);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: WrongAF
|
||||
*
|
||||
* Description:
|
||||
* Open and connect the socket with wrong AF
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void WrongAF(void)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Try connect socket with wrong AF */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_UNIX;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EAFNOSUPPORT, errno);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: WrongPort
|
||||
*
|
||||
* Description:
|
||||
* Open and connect the socket with wrong port
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void WrongPort(void)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Try connect socket to wrong port */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(127);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(ECONNREFUSED, errno);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: WrongEndpoint
|
||||
*
|
||||
* Description:
|
||||
* Open and connect the socket with wrong endpoint
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void WrongEndpoint(void)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Try connect socket to unreachable endpoint */
|
||||
|
||||
inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(1);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(ENETUNREACH, errno);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Connect */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
TEST_SETUP(BasicConnect)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Setup(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST_TEAR_DOWN(BasicConnect)
|
||||
{
|
||||
Teardown();
|
||||
}
|
||||
|
||||
TEST(BasicConnect, NotConnected)
|
||||
{
|
||||
NotConnected();
|
||||
}
|
||||
|
||||
TEST(BasicConnect, Connect)
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST(BasicConnect, WrongAF)
|
||||
{
|
||||
WrongAF();
|
||||
}
|
||||
|
||||
TEST(BasicConnect, WrongPort)
|
||||
{
|
||||
WrongPort();
|
||||
}
|
||||
|
||||
TEST(BasicConnect, WrongEndpoint)
|
||||
{
|
||||
WrongEndpoint();
|
||||
}
|
||||
|
||||
TEST_SETUP(BasicConnectDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Setup(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST_TEAR_DOWN(BasicConnectDelay)
|
||||
{
|
||||
Teardown();
|
||||
}
|
||||
|
||||
TEST(BasicConnectDelay, NotConnected)
|
||||
{
|
||||
NotConnected();
|
||||
}
|
||||
|
||||
TEST(BasicConnectDelay, Connect)
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST(BasicConnectDelay, WrongAF)
|
||||
{
|
||||
WrongAF();
|
||||
}
|
||||
|
||||
TEST(BasicConnectDelay, WrongPort)
|
||||
{
|
||||
WrongPort();
|
||||
}
|
||||
|
||||
TEST(BasicConnectDelay, WrongEndpoint)
|
||||
{
|
||||
WrongEndpoint();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(BasicConnect)
|
||||
{
|
||||
RUN_TEST_CASE(BasicConnect, NotConnected);
|
||||
RUN_TEST_CASE(BasicConnect, Connect);
|
||||
RUN_TEST_CASE(BasicConnect, WrongAF);
|
||||
RUN_TEST_CASE(BasicConnect, WrongPort);
|
||||
RUN_TEST_CASE(BasicConnect, WrongEndpoint);
|
||||
}
|
||||
|
||||
TEST_GROUP(BasicConnectDelay)
|
||||
{
|
||||
RUN_TEST_CASE(BasicConnectDelay, NotConnected);
|
||||
RUN_TEST_CASE(BasicConnectDelay, Connect);
|
||||
RUN_TEST_CASE(BasicConnectDelay, WrongAF);
|
||||
RUN_TEST_CASE(BasicConnectDelay, WrongPort);
|
||||
RUN_TEST_CASE(BasicConnectDelay, WrongEndpoint);
|
||||
}
|
||||
|
686
examples/usrsocktest/usrsocktest_basic_daemon.c
Normal file
686
examples/usrsocktest/usrsocktest_basic_daemon.c
Normal file
@ -0,0 +1,686 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_basic_daemon.c
|
||||
* Basic tests with socket daemon
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd, sd2, sd3;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoActiveSockets
|
||||
*
|
||||
* Description:
|
||||
* Checks there is no active sockets on daemon startup
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void NoActiveSockets(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: OpenClose
|
||||
*
|
||||
* Description:
|
||||
* Open and close AF_INET socket, check active socket counter updates
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void OpenClose(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: UnsupportedType
|
||||
*
|
||||
* Description:
|
||||
* Try open socket for unsupported type
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void UnsupportedType(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
sd = socket(AF_INET, SOCK_RDM, 0);
|
||||
TEST_ASSERT_TRUE(sd < 0);
|
||||
TEST_ASSERT_EQUAL(EPROTONOSUPPORT, errno);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: UnsupportedProto
|
||||
*
|
||||
* Description:
|
||||
* Try open socket for unsupported protocol
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void UnsupportedProto(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 1);
|
||||
TEST_ASSERT_TRUE(sd < 0);
|
||||
TEST_ASSERT_EQUAL(EPROTONOSUPPORT, errno);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: OpenThree
|
||||
*
|
||||
* Description:
|
||||
* Open multiple sockets
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void OpenThree(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dconf->max_sockets = 3;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
sd2 = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd2 >= 0);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
sd3 = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd3 >= 0);
|
||||
TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_num_active_sockets());
|
||||
ret = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_FALSE(ret >= 0);
|
||||
TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
ret = close(sd2);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
sd2 = -1;
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
ret = close(sd);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
ret = close(sd3);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
sd3 = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Dup
|
||||
*
|
||||
* Description:
|
||||
* Dup opened socket
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Dup(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
sd2 = dup(sd);
|
||||
TEST_ASSERT_TRUE(sd2 >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
sd3 = dup(sd);
|
||||
TEST_ASSERT_TRUE(sd3 >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
ret = close(sd2);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
sd2 = -1;
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
ret = close(sd);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
ret = close(sd3);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
sd3 = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Dup2
|
||||
*
|
||||
* Description:
|
||||
* Clone opened socket with dup2
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Dup2(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
sd2 = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
ret = dup2(sd2, sd);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
ret = close(sd2);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
sd2 = -1;
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
ret = close(sd);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Stops
|
||||
*
|
||||
* Description:
|
||||
* Daemon stops unexpectedly
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Stops(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
sd2 = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd2 >= 0);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
ret = usrsocktest_daemon_stop();
|
||||
TEST_ASSERT_EQUAL(OK, ret);
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
|
||||
|
||||
TEST_ASSERT_EQUAL(0, close(sd));
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, close(sd2));
|
||||
sd2 = -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: StopsStarts
|
||||
*
|
||||
* Description:
|
||||
* Daemon stops and restarts unexpectedly
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void StopsStarts(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
sd2 = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd2 >= 0);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 255;
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EPIPE, errno);
|
||||
|
||||
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EPIPE, errno);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, close(sd));
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, close(sd2));
|
||||
sd2 = -1;
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicDaemon test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(BasicDaemon)
|
||||
{
|
||||
sd = -1;
|
||||
sd2 = -1;
|
||||
sd3 = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicDaemon test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(BasicDaemon)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (sd2 >= 0)
|
||||
{
|
||||
ret = close(sd2);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (sd3 >= 0)
|
||||
{
|
||||
ret = close(sd3);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, NoActiveSockets)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
NoActiveSockets(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, NoActiveSocketsDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
NoActiveSockets(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, OpenClose)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
OpenClose(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, OpenCloseDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
OpenClose(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, UnsupportedType)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
UnsupportedType(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, UnsupportedTypeDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
UnsupportedType(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, UnsupportedProto)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
UnsupportedProto(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, UnsupportedProtoDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
UnsupportedProto(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, OpenThree)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
OpenThree(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, OpenThreeDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
OpenThree(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, Dup)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Dup(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, DupDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Dup(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, Dup2)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Dup2(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, Dup2Delay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Dup2(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, Stops)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Stops(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, StopsDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Stops(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, StopsStarts)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
StopsStarts(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicDaemon, StopsStartsDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
StopsStarts(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(BasicDaemon)
|
||||
{
|
||||
RUN_TEST_CASE(BasicDaemon, NoActiveSockets);
|
||||
RUN_TEST_CASE(BasicDaemon, NoActiveSocketsDelay);
|
||||
RUN_TEST_CASE(BasicDaemon, OpenClose);
|
||||
RUN_TEST_CASE(BasicDaemon, OpenCloseDelay);
|
||||
RUN_TEST_CASE(BasicDaemon, UnsupportedType);
|
||||
RUN_TEST_CASE(BasicDaemon, UnsupportedTypeDelay);
|
||||
RUN_TEST_CASE(BasicDaemon, UnsupportedProto);
|
||||
RUN_TEST_CASE(BasicDaemon, UnsupportedProtoDelay);
|
||||
RUN_TEST_CASE(BasicDaemon, OpenThree);
|
||||
RUN_TEST_CASE(BasicDaemon, OpenThreeDelay);
|
||||
RUN_TEST_CASE(BasicDaemon, Dup);
|
||||
RUN_TEST_CASE(BasicDaemon, DupDelay);
|
||||
RUN_TEST_CASE(BasicDaemon, Dup2);
|
||||
RUN_TEST_CASE(BasicDaemon, Dup2Delay);
|
||||
RUN_TEST_CASE(BasicDaemon, Stops);
|
||||
RUN_TEST_CASE(BasicDaemon, StopsDelay);
|
||||
RUN_TEST_CASE(BasicDaemon, StopsStarts);
|
||||
RUN_TEST_CASE(BasicDaemon, StopsStartsDelay);
|
||||
}
|
||||
|
287
examples/usrsocktest/usrsocktest_basic_getsockname.c
Normal file
287
examples/usrsocktest/usrsocktest_basic_getsockname.c
Normal file
@ -0,0 +1,287 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_basic_getsockname.c
|
||||
* Basic getsockname tests
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Open
|
||||
*
|
||||
* Description:
|
||||
* Open and get socket options
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Open(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int ret;
|
||||
socklen_t addrlen;
|
||||
union {
|
||||
struct sockaddr_storage storage;
|
||||
struct sockaddr_in in;
|
||||
} addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get socket name */
|
||||
|
||||
memset(&addr, 0xff, sizeof(addr));
|
||||
addrlen = sizeof(addr.in);
|
||||
ret = getsockname(sd, (FAR void *)&addr.in, &addrlen);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen);
|
||||
TEST_ASSERT_EQUAL(AF_INET, addr.in.sin_family);
|
||||
TEST_ASSERT_EQUAL(htons(12345), addr.in.sin_port);
|
||||
TEST_ASSERT_EQUAL(htonl(0x7f000001), addr.in.sin_addr.s_addr);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get socket name, short buffer */
|
||||
|
||||
memset(&addr, 0xff, sizeof(addr));
|
||||
addrlen = 1;
|
||||
ret = getsockname(sd, (FAR void *)&addr.in, &addrlen);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen);
|
||||
TEST_ASSERT_EQUAL(AF_INET, ((FAR uint8_t *)&addr.in.sin_family)[0]);
|
||||
TEST_ASSERT_EQUAL(0xff, ((FAR uint8_t *)&addr.in.sin_family)[1]);
|
||||
TEST_ASSERT_EQUAL(htons(0xffff), addr.in.sin_port);
|
||||
TEST_ASSERT_EQUAL(htonl(0xffffffff), addr.in.sin_addr.s_addr);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get socket name, larger buffer */
|
||||
|
||||
memset(&addr, 0xff, sizeof(addr));
|
||||
addrlen = sizeof(addr.storage);
|
||||
ret = getsockname(sd, (FAR void *)&addr.in, &addrlen);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen);
|
||||
TEST_ASSERT_EQUAL(AF_INET, addr.in.sin_family);
|
||||
TEST_ASSERT_EQUAL(htons(12345), addr.in.sin_port);
|
||||
TEST_ASSERT_EQUAL(htonl(0x7f000001), addr.in.sin_addr.s_addr);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get socket name, NULL addr */
|
||||
|
||||
memset(&addr, 0xff, sizeof(addr));
|
||||
addrlen = sizeof(addr.in);
|
||||
ret = getsockname(sd, NULL, &addrlen);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINVAL, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get socket name, NULL addrlen */
|
||||
|
||||
memset(&addr, 0xff, sizeof(addr));
|
||||
addrlen = sizeof(addr.in);
|
||||
ret = getsockname(sd, (FAR void *)&addr.in, NULL);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINVAL, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get socket name, zero length buffer */
|
||||
|
||||
memset(&addr, 0xff, sizeof(addr));
|
||||
addrlen = 0;
|
||||
ret = getsockname(sd, (FAR void *)&addr.in, &addrlen);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen);
|
||||
TEST_ASSERT_EQUAL(0xffff, addr.in.sin_family);
|
||||
TEST_ASSERT_EQUAL(htons(0xffff), addr.in.sin_port);
|
||||
TEST_ASSERT_EQUAL(htonl(0xffffffff), addr.in.sin_addr.s_addr);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicGetSockName test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(BasicGetSockName)
|
||||
{
|
||||
sd = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicGetSockName test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(BasicGetSockName)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BasicGetSockName, Open)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Open(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicGetSockName, OpenDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Open(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(BasicGetSockName)
|
||||
{
|
||||
RUN_TEST_CASE(BasicGetSockName, Open);
|
||||
RUN_TEST_CASE(BasicGetSockName, OpenDelay);
|
||||
}
|
266
examples/usrsocktest/usrsocktest_basic_getsockopt.c
Normal file
266
examples/usrsocktest/usrsocktest_basic_getsockopt.c
Normal file
@ -0,0 +1,266 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_basic_getsockopt.c
|
||||
* Basic getsockopt tests
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Open
|
||||
*
|
||||
* Description:
|
||||
* Open and get socket options
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Open(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int ret;
|
||||
int value;
|
||||
int valuelarge[2];
|
||||
socklen_t valuelen;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get supported option (SO_TYPE handled by nuttx) */
|
||||
|
||||
value = -2;
|
||||
valuelen = sizeof(value);
|
||||
ret = getsockopt(sd, SOL_SOCKET, SO_TYPE, &value, &valuelen);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(sizeof(value), valuelen);
|
||||
TEST_ASSERT_EQUAL(SOCK_STREAM, value);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get supported option */
|
||||
|
||||
value = -1;
|
||||
valuelen = sizeof(value);
|
||||
ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, &valuelen);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(sizeof(value), valuelen);
|
||||
TEST_ASSERT_EQUAL(0, value);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get supported option, too short buffer */
|
||||
|
||||
value = -1;
|
||||
valuelen = 1;
|
||||
ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, &valuelen);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINVAL, errno);
|
||||
TEST_ASSERT_EQUAL(-1, value);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get supported option, larger buffer */
|
||||
|
||||
valuelarge[0] = -1;
|
||||
valuelarge[1] = -1;
|
||||
valuelen = sizeof(valuelarge);
|
||||
ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, valuelarge, &valuelen);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(sizeof(value), valuelen);
|
||||
TEST_ASSERT_EQUAL(0, valuelarge[0]);
|
||||
TEST_ASSERT_EQUAL(-1, valuelarge[1]);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Get unsupported option */
|
||||
|
||||
value = -1;
|
||||
valuelen = sizeof(value);
|
||||
ret = getsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, &valuelen);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(ENOPROTOOPT, errno);
|
||||
TEST_ASSERT_EQUAL(-1, value);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicGetSockOpt test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(BasicGetSockOpt)
|
||||
{
|
||||
sd = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicGetSockOpt test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(BasicGetSockOpt)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BasicGetSockOpt, Open)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Open(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicGetSockOpt, OpenDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Open(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(BasicGetSockOpt)
|
||||
{
|
||||
RUN_TEST_CASE(BasicGetSockOpt, Open);
|
||||
RUN_TEST_CASE(BasicGetSockOpt, OpenDelay);
|
||||
}
|
359
examples/usrsocktest/usrsocktest_basic_send.c
Normal file
359
examples/usrsocktest/usrsocktest_basic_send.c
Normal file
@ -0,0 +1,359 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_basic_send.c
|
||||
* Basic sending tests
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Send
|
||||
*
|
||||
* Description:
|
||||
* Open socket and send
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Send(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
const void *data;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Send on non-connected socket */
|
||||
|
||||
data = "data";
|
||||
datalen = strlen("data");
|
||||
ret = send(sd, data, datalen, 0);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(ENOTCONN, errno);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Sendto with address */
|
||||
|
||||
data = "data";
|
||||
datalen = strlen("data");
|
||||
ret = sendto(sd, data, datalen, 0, (FAR const struct sockaddr *)&addr,
|
||||
sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(ENOTCONN, errno);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Connect socket to available endpoint */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Sendto with address */
|
||||
|
||||
data = "data";
|
||||
datalen = strlen("data");
|
||||
ret = sendto(sd, data, datalen, 0, (FAR const struct sockaddr *)&addr,
|
||||
sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV,
|
||||
usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_send_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ConnectSend
|
||||
*
|
||||
* Description:
|
||||
* Send over connected socket
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
static void ConnectSend(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
const void *data;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Connect socket to available endpoint */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Send data to remote */
|
||||
|
||||
data = "data";
|
||||
datalen = strlen("data");
|
||||
ret = send(sd, data, datalen, 0);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV,
|
||||
usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicSend test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(BasicSend)
|
||||
{
|
||||
sd = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicSend test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(BasicSend)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BasicSend, Send)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Send(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicSend, SendDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Send(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicSend, ConnectSend)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
ConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicSend, ConnectSendDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
ConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(BasicSend)
|
||||
{
|
||||
RUN_TEST_CASE(BasicSend, Send);
|
||||
RUN_TEST_CASE(BasicSend, SendDelay);
|
||||
RUN_TEST_CASE(BasicSend, ConnectSend);
|
||||
RUN_TEST_CASE(BasicSend, ConnectSendDelay);
|
||||
}
|
235
examples/usrsocktest/usrsocktest_basic_setsockopt.c
Normal file
235
examples/usrsocktest/usrsocktest_basic_setsockopt.c
Normal file
@ -0,0 +1,235 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_basic_setsockopt.c
|
||||
* Basic setsockopt tests
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Open
|
||||
*
|
||||
* Description:
|
||||
* Open and set socket options
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Open(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int ret;
|
||||
int value;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Set supported option */
|
||||
|
||||
value = 1;
|
||||
ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Set supported option, too small buffer */
|
||||
|
||||
value = 1;
|
||||
ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, 1);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINVAL, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Set unsupported option */
|
||||
|
||||
value = 1;
|
||||
ret = setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(ENOPROTOOPT, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicSetSockOpt test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(BasicSetSockOpt)
|
||||
{
|
||||
sd = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BasicSetSockOpt test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(BasicSetSockOpt)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BasicSetSockOpt, Open)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Open(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BasicSetSockOpt, OpenDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Open(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(BasicSetSockOpt)
|
||||
{
|
||||
RUN_TEST_CASE(BasicSetSockOpt, Open);
|
||||
RUN_TEST_CASE(BasicSetSockOpt, OpenDelay);
|
||||
}
|
||||
|
514
examples/usrsocktest/usrsocktest_block_recv.c
Normal file
514
examples/usrsocktest/usrsocktest_block_recv.c
Normal file
@ -0,0 +1,514 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_block_recv.c
|
||||
* Receive from the socket in blocking mode
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ConnectReceive
|
||||
*
|
||||
* Description:
|
||||
* Blocking connect and receive
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ConnectReceive(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
struct sockaddr_in addr;
|
||||
char databuf[5];
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_block_connect = true;
|
||||
dconf->endpoint_block_send = true;
|
||||
dconf->endpoint_recv_avail_from_start = false;
|
||||
dconf->endpoint_recv_avail = 7;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Do connect, should succeed (after connect block released). */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Receive data from remote */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100));
|
||||
ret = recvfrom(sd, data, datalen, 0, NULL, 0);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(5, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(5, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Receive data from remote */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = recvfrom(sd, data, datalen, 0, NULL, 0);
|
||||
TEST_ASSERT_EQUAL(2, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("ab", data, 2);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoBlockConnect
|
||||
*
|
||||
* Description:
|
||||
* Non-blocking connect and blocking receive
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void NoBlockConnect(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
struct sockaddr_in addr;
|
||||
char databuf[5];
|
||||
struct sockaddr_in remoteaddr;
|
||||
socklen_t addrlen;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_block_connect = true;
|
||||
dconf->endpoint_block_send = true;
|
||||
dconf->endpoint_recv_avail_from_start = true;
|
||||
dconf->endpoint_recv_avail = 6;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Do connect, should succeed (after connect block released). */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100));
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Receive data from remote */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = read(sd, data, datalen);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(5, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(5, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Receive data from remote */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
addrlen = sizeof(remoteaddr);
|
||||
ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr,
|
||||
&addrlen);
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("a", data, 1);
|
||||
TEST_ASSERT_EQUAL(sizeof(remoteaddr), addrlen);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Receive data from remote */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
addrlen = sizeof(remoteaddr);
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100));
|
||||
ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr,
|
||||
&addrlen);
|
||||
TEST_ASSERT_EQUAL(5, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5);
|
||||
TEST_ASSERT_EQUAL(sizeof(remoteaddr), addrlen);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(11, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(11, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ReceiveTimeout
|
||||
*
|
||||
* Description:
|
||||
* Blocking connect and receive with SO_RCVTIMEO
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ReceiveTimeout(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
struct sockaddr_in addr;
|
||||
char databuf[5];
|
||||
struct timeval tv;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_block_connect = true;
|
||||
dconf->endpoint_block_send = true;
|
||||
dconf->endpoint_recv_avail_from_start = false;
|
||||
dconf->endpoint_recv_avail = 7;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Do connect, should succeed (after connect block released). */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Setup recv timeout. */
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100 * 1000;
|
||||
ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (FAR const void *)&tv,
|
||||
sizeof(tv));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
|
||||
/* Receive data from remote */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = recvfrom(sd, data, datalen, 0, NULL, 0);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EAGAIN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BlockRecv test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(BlockRecv)
|
||||
{
|
||||
sd = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BlockRecv test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(BlockRecv)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BlockRecv, ConnectReceive)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
ConnectReceive(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockRecv, ConnectReceiveDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
ConnectReceive(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockRecv, NoBlockConnect)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
NoBlockConnect(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockRecv, NoBlockConnectDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
NoBlockConnect(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockRecv, ReceiveTimeout)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
ReceiveTimeout(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockRecv, ReceiveTimeoutDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
ReceiveTimeout(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(BlockRecv)
|
||||
{
|
||||
RUN_TEST_CASE(BlockRecv, ConnectReceive);
|
||||
RUN_TEST_CASE(BlockRecv, ConnectReceiveDelay);
|
||||
RUN_TEST_CASE(BlockRecv, NoBlockConnect);
|
||||
RUN_TEST_CASE(BlockRecv, NoBlockConnectDelay);
|
||||
RUN_TEST_CASE(BlockRecv, ReceiveTimeout);
|
||||
RUN_TEST_CASE(BlockRecv, ReceiveTimeoutDelay);
|
||||
}
|
||||
|
442
examples/usrsocktest/usrsocktest_block_send.c
Normal file
442
examples/usrsocktest/usrsocktest_block_send.c
Normal file
@ -0,0 +1,442 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_block_send.c
|
||||
* Send through the socket in blocking mode
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ConnectSend
|
||||
*
|
||||
* Description:
|
||||
* Open socket, connect in blocking mode and send
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ConnectSend(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
const void *data;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_block_connect = true;
|
||||
dconf->endpoint_block_send = true;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Do connect, should succeed (after connect block released). */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Send data to remote, */
|
||||
|
||||
data = "abcde";
|
||||
datalen = strlen("abcde");
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100));
|
||||
ret = sendto(sd, data, datalen, 0, NULL, 0);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NonBlockConnectSend
|
||||
*
|
||||
* Description:
|
||||
* Open socket, connect in non-blocking mode and send
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void NonBlockConnectSend(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
const void *data;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_block_connect = true;
|
||||
dconf->endpoint_block_send = false;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Do connect, should succeed (after connect block released). */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100));
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Send data to remote. */
|
||||
|
||||
data = "abcde";
|
||||
datalen = strlen("abcde");
|
||||
ret = write(sd, data, datalen);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: SendTimeout
|
||||
*
|
||||
* Description:
|
||||
* Open socket, connect in blocking mode and send with SO_SNDTIMEO
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void SendTimeout(FAR struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
const void *data;
|
||||
struct sockaddr_in addr;
|
||||
struct timeval tv;
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_block_connect = true;
|
||||
dconf->endpoint_block_send = true;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Do connect, should succeed (after connect block released). */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Setup send timeout. */
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100 * 1000;
|
||||
ret = setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO, (FAR const void *)&tv,
|
||||
sizeof(tv));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
|
||||
/* Try send data to remote. */
|
||||
|
||||
data = "abcde";
|
||||
datalen = strlen("abcde");
|
||||
ret = sendto(sd, data, datalen, 0, NULL, 0);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EAGAIN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BlockSend test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(BlockSend)
|
||||
{
|
||||
sd = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: BlockSend test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(BlockSend)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BlockSend, ConnectSend)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
ConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockSend, ConnectSendDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
ConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockSend, NonBlockConnectSend)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
NonBlockConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockSend, NonBlockConnectSendDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
NonBlockConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockSend, SendTimeout)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
SendTimeout(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(BlockSend, SendTimeoutDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
SendTimeout(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(BlockSend)
|
||||
{
|
||||
RUN_TEST_CASE(BlockSend, ConnectSend);
|
||||
RUN_TEST_CASE(BlockSend, ConnectSendDelay);
|
||||
RUN_TEST_CASE(BlockSend, NonBlockConnectSend);
|
||||
RUN_TEST_CASE(BlockSend, NonBlockConnectSendDelay);
|
||||
RUN_TEST_CASE(BlockSend, SendTimeout);
|
||||
RUN_TEST_CASE(BlockSend, SendTimeoutDelay);
|
||||
}
|
||||
|
234
examples/usrsocktest/usrsocktest_chardev.c
Normal file
234
examples/usrsocktest/usrsocktest_chardev.c
Normal file
@ -0,0 +1,234 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_chardev.c
|
||||
* Character device node tests
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static int us_fd;
|
||||
static int us_fd_two;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: CharDev test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(CharDev)
|
||||
{
|
||||
us_fd = -1;
|
||||
us_fd_two = -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: CharDev test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(CharDev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (us_fd >= 0)
|
||||
{
|
||||
ret = close(us_fd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (us_fd_two >= 0)
|
||||
{
|
||||
ret = close(us_fd_two);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: OpenRw
|
||||
*
|
||||
* Description:
|
||||
* Simple test for opening and closing usrsock node
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST(CharDev, OpenRw)
|
||||
{
|
||||
int ret;
|
||||
|
||||
us_fd = open(USRSOCK_NODE, O_RDWR);
|
||||
TEST_ASSERT_TRUE(us_fd >= 0);
|
||||
|
||||
ret = close(us_fd);
|
||||
TEST_ASSERT_TRUE(ret >= 0);
|
||||
us_fd = -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ReopenRw
|
||||
*
|
||||
* Description:
|
||||
* Repeated simple test for opening and closing usrsock node, reopen should
|
||||
* work
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST(CharDev, ReopenRw)
|
||||
{
|
||||
int ret;
|
||||
|
||||
us_fd = open(USRSOCK_NODE, O_RDWR);
|
||||
TEST_ASSERT_TRUE(us_fd >= 0);
|
||||
|
||||
ret = close(us_fd);
|
||||
TEST_ASSERT_TRUE(ret >= 0);
|
||||
us_fd = -1;
|
||||
|
||||
us_fd = open(USRSOCK_NODE, O_RDWR);
|
||||
TEST_ASSERT_TRUE(us_fd >= 0);
|
||||
|
||||
ret = close(us_fd);
|
||||
TEST_ASSERT_TRUE(ret >= 0);
|
||||
us_fd = -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoMultipleOpen
|
||||
*
|
||||
* Description:
|
||||
* No permission for multiple access,
|
||||
* first user should be only user.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST(CharDev, NoMultipleOpen)
|
||||
{
|
||||
us_fd = open(USRSOCK_NODE, O_RDWR);
|
||||
TEST_ASSERT_TRUE(us_fd >= 0);
|
||||
|
||||
us_fd_two = open(USRSOCK_NODE, O_RDWR);
|
||||
TEST_ASSERT_FALSE(us_fd_two >= 0);
|
||||
TEST_ASSERT_EQUAL(EPERM, errno);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(CharDev)
|
||||
{
|
||||
RUN_TEST_CASE(CharDev, OpenRw);
|
||||
RUN_TEST_CASE(CharDev, ReopenRw);
|
||||
RUN_TEST_CASE(CharDev, NoMultipleOpen);
|
||||
}
|
||||
|
1948
examples/usrsocktest/usrsocktest_daemon.c
Normal file
1948
examples/usrsocktest/usrsocktest_daemon.c
Normal file
File diff suppressed because it is too large
Load Diff
284
examples/usrsocktest/usrsocktest_main.c
Normal file
284
examples/usrsocktest/usrsocktest_main.c
Normal file
@ -0,0 +1,284 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_main.c
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Author: Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <debug.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef dbg
|
||||
#define dbg _warn
|
||||
#endif
|
||||
|
||||
#define usrsocktest_dbg(...) ((void)0)
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct
|
||||
{
|
||||
unsigned int ok;
|
||||
unsigned int failed;
|
||||
|
||||
unsigned int nchecks;
|
||||
} overall;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
int usrsocktest_endp_malloc_cnt = 0;
|
||||
int usrsocktest_dcmd_malloc_cnt = 0;
|
||||
bool usrsocktest_test_failed = false;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void get_mallinfo(struct mallinfo *mem)
|
||||
{
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
*mem = mallinfo();
|
||||
#else
|
||||
(void)mallinfo(mem);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_mallinfo(const struct mallinfo *mem, const char *title)
|
||||
{
|
||||
if (title)
|
||||
printf("%s:\n", title);
|
||||
printf(" %11s%11s%11s%11s\n", "total", "used", "free", "largest");
|
||||
printf("Mem: %11d%11d%11d%11d\n",
|
||||
mem->arena, mem->uordblks, mem->fordblks, mem->mxordblk);
|
||||
}
|
||||
|
||||
static void utest_assert_print_head(FAR const char *func, const int line,
|
||||
FAR const char *check_str)
|
||||
{
|
||||
printf("\t[TEST ASSERT FAILED!]\n"
|
||||
"\t\tIn function \"%s\":\n"
|
||||
"\t\tline %d: Assertion `%s' failed.\n", func, line, check_str);
|
||||
}
|
||||
|
||||
static void run_tests(FAR const char *name, void (CODE *test_fn)(void))
|
||||
{
|
||||
printf("Testing group \"%s\" =>\n", name);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
usrsocktest_test_failed = false;
|
||||
test_fn();
|
||||
if (!usrsocktest_test_failed)
|
||||
{
|
||||
printf("\tGroup \"%s\": [OK]\n", name);
|
||||
overall.ok++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tGroup \"%s\": [FAILED]\n", name);
|
||||
overall.failed++;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: runAllTests
|
||||
*
|
||||
* Description:
|
||||
* Sequentially runs all included test groups
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void runAllTests(void)
|
||||
{
|
||||
RUN_TEST_GROUP(CharDev);
|
||||
RUN_TEST_GROUP(NoDaemon);
|
||||
RUN_TEST_GROUP(BasicDaemon);
|
||||
RUN_TEST_GROUP(BasicConnect);
|
||||
RUN_TEST_GROUP(BasicConnectDelay);
|
||||
RUN_TEST_GROUP(NoBlockConnect);
|
||||
RUN_TEST_GROUP(BasicSend);
|
||||
RUN_TEST_GROUP(NoBlockSend);
|
||||
RUN_TEST_GROUP(BlockSend);
|
||||
RUN_TEST_GROUP(NoBlockRecv);
|
||||
RUN_TEST_GROUP(BlockRecv);
|
||||
RUN_TEST_GROUP(RemoteDisconnect);
|
||||
RUN_TEST_GROUP(BasicSetSockOpt);
|
||||
RUN_TEST_GROUP(BasicGetSockOpt);
|
||||
RUN_TEST_GROUP(BasicGetSockName);
|
||||
RUN_TEST_GROUP(WakeWithSignal);
|
||||
RUN_TEST_GROUP(MultiThread);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
bool usrsocktest_assert_print_value(FAR const char *func,
|
||||
const int line,
|
||||
FAR const char *check_str,
|
||||
long int test_value,
|
||||
long int should_be)
|
||||
{
|
||||
++overall.nchecks;
|
||||
|
||||
if (test_value == should_be)
|
||||
{
|
||||
int keep_errno = errno;
|
||||
|
||||
usrsocktest_dbg("%d => OK.\n", line);
|
||||
|
||||
errno = keep_errno;
|
||||
return true;
|
||||
}
|
||||
|
||||
utest_assert_print_head(func, line, check_str);
|
||||
|
||||
printf("\t\t\tgot value: %ld\n", test_value);
|
||||
printf("\t\t\tshould be: %ld\n", should_be);
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool usrsocktest_assert_print_buf(FAR const char *func,
|
||||
const int line,
|
||||
FAR const char *check_str,
|
||||
FAR const void *test_buf,
|
||||
FAR const void *expect_buf,
|
||||
size_t buflen)
|
||||
{
|
||||
++overall.nchecks;
|
||||
|
||||
if (memcmp(test_buf, expect_buf, buflen) == 0)
|
||||
{
|
||||
int keep_errno = errno;
|
||||
|
||||
usrsocktest_dbg("%d => OK.\n", line);
|
||||
|
||||
errno = keep_errno;
|
||||
return true;
|
||||
}
|
||||
|
||||
utest_assert_print_head(func, line, check_str);
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* usrsocktest_main
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
int main(int argc, FAR char *argv[])
|
||||
#else
|
||||
int usrsocktest_main(int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
struct mallinfo mem_before, mem_after;
|
||||
|
||||
memset(&overall, 0, sizeof(overall));
|
||||
|
||||
printf("Starting unit-tests...\n");
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
get_mallinfo(&mem_before);
|
||||
|
||||
runAllTests();
|
||||
|
||||
printf("Unit-test groups done... OK:%d, FAILED:%d, TOTAL:%d\n",
|
||||
overall.ok, overall.failed, overall.ok + overall.failed);
|
||||
printf(" -- number of checks made: %d\n", overall.nchecks);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
get_mallinfo(&mem_after);
|
||||
|
||||
print_mallinfo(&mem_before, "HEAP BEFORE TESTS");
|
||||
print_mallinfo(&mem_after, "HEAP AFTER TESTS");
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
exit(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
267
examples/usrsocktest/usrsocktest_multi_thread.c
Normal file
267
examples/usrsocktest/usrsocktest_multi_thread.c
Normal file
@ -0,0 +1,267 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_multi_thread.c
|
||||
* Multi-threaded access to sockets
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <assert.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static pthread_t tids[4];
|
||||
static int sds[4];
|
||||
static bool started;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void usrsock_socket_multitask_do_work(int *sd)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
/* Simple test for opening socket with usrsock daemon running. */
|
||||
|
||||
*sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(*sd >= 0);
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(*sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(*sd) >= 0);
|
||||
*sd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static FAR void *usrsock_socket_multitask_thread(FAR void *param)
|
||||
{
|
||||
usrsock_socket_multitask_do_work((int*)param);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: MultiThread test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(MultiThread)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(sds); i++)
|
||||
{
|
||||
sds[i] = -1;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(tids); i++)
|
||||
{
|
||||
tids[i] = -1;
|
||||
}
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: MultiThread test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(MultiThread)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tids); i++)
|
||||
{
|
||||
if (tids[i] != -1)
|
||||
{
|
||||
ret = pthread_cancel(tids[i]);
|
||||
assert(ret == OK);
|
||||
ret = pthread_join(tids[i], NULL);
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(sds); i++)
|
||||
{
|
||||
if (sds[i] != -1)
|
||||
{
|
||||
ret = close(sds[i]);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: OpenClose
|
||||
*
|
||||
* Description:
|
||||
* Open and close socket with multiple threads
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST(MultiThread, OpenClose)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
usrsocktest_daemon_config.endpoint_block_send = false;
|
||||
usrsocktest_daemon_config.endpoint_block_connect = false;
|
||||
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
|
||||
usrsocktest_daemon_config.endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Launch worker threads. */
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tids); i++)
|
||||
{
|
||||
ret = pthread_create(&tids[i], NULL, usrsock_socket_multitask_thread,
|
||||
sds + i);
|
||||
TEST_ASSERT_EQUAL(OK, ret);
|
||||
}
|
||||
|
||||
/* Wait threads to complete work. */
|
||||
|
||||
while (--i > -1)
|
||||
{
|
||||
pthread_addr_t tparam;
|
||||
|
||||
ret = pthread_join(tids[i], &tparam);
|
||||
TEST_ASSERT_EQUAL(OK, ret);
|
||||
tids[i] = -1;
|
||||
|
||||
/* This flag is set whenever a test fails, otherwise it is not touched
|
||||
* No need for synchronization. Here we bail from main test thread on
|
||||
* first failure in any thread.
|
||||
*/
|
||||
|
||||
TEST_ASSERT_FALSE(usrsocktest_test_failed);
|
||||
}
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(MultiThread)
|
||||
{
|
||||
RUN_TEST_CASE(MultiThread, OpenClose);
|
||||
}
|
||||
|
816
examples/usrsocktest/usrsocktest_noblock_connect.c
Normal file
816
examples/usrsocktest/usrsocktest_noblock_connect.c
Normal file
@ -0,0 +1,816 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_noblock_connect.c
|
||||
* Socket connect tests in non-blocking mode
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd, sd2;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(NoBlockConnect)
|
||||
{
|
||||
sd = -1;
|
||||
sd2 = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
TEST_TEAR_DOWN(NoBlockConnect)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret == 0);
|
||||
}
|
||||
if (sd2 >= 0)
|
||||
{
|
||||
ret = close(sd2);
|
||||
assert(ret == 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NoBlockConnect, InstantConnect)
|
||||
{
|
||||
int flags;
|
||||
int ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
|
||||
usrsocktest_daemon_config.endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Do connect, should succeed instantly. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
TEST(NoBlockConnect, DelayedConnect)
|
||||
{
|
||||
int flags, ret, count;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.endpoint_block_connect = true;
|
||||
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
|
||||
usrsocktest_daemon_config.endpoint_port = 255;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Launch connect attempt, daemon delays actual connection until triggered. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Another connect attempt results EALREADY. */
|
||||
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EALREADY, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Release delayed connect. */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
|
||||
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Another connect attempt results EISCONN. */
|
||||
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
|
||||
/* Close socket. */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
TEST(NoBlockConnect, CloseNotConnected)
|
||||
{
|
||||
int flags, ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.endpoint_block_connect = true;
|
||||
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
|
||||
usrsocktest_daemon_config.endpoint_port = 255;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Launch connect attempt, daemon delays actual connection until triggered. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Close socket. */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
TEST(NoBlockConnect, EarlyDrop)
|
||||
{
|
||||
int flags, ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.endpoint_block_connect = true;
|
||||
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
|
||||
usrsocktest_daemon_config.endpoint_port = 255;
|
||||
usrsocktest_daemon_config.delay_all_responses = false;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Launch connect attempt, daemon delays actual connection until triggered. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
|
||||
/* Close socket. */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
}
|
||||
|
||||
TEST(NoBlockConnect, Multiple)
|
||||
{
|
||||
int flags, ret, count;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.endpoint_block_connect = true;
|
||||
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
|
||||
usrsocktest_daemon_config.endpoint_port = 255;
|
||||
usrsocktest_daemon_config.delay_all_responses = false;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open sockets */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
sd2 = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd2 >= 0);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
flags = fcntl(sd2, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd2, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Launch connect attempts, daemon delays actual connection until triggered. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Release delayed connections. */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
|
||||
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Release delayed connections. */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
|
||||
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0;
|
||||
count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Close sockets. */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd2) >= 0);
|
||||
sd2 = -1;
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Open sockets */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
sd2 = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd2 >= 0);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
flags = fcntl(sd2, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd2, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Launch connect attempts, daemon delays actual connection until triggered. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Release delayed connections. */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
|
||||
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Close sockets. */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd2) >= 0);
|
||||
sd2 = -1;
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Open sockets */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
sd2 = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd2 >= 0);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
flags = fcntl(sd2, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd2, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Launch connect attempt, daemon delays actual connection until triggered. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Release delayed connections. */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
|
||||
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Launch another connect attempt, daemon delays actual connection until triggered. */
|
||||
|
||||
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Close sockets. */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_TRUE(close(sd2) >= 0);
|
||||
sd2 = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
TEST(NoBlockConnect, Dup2)
|
||||
{
|
||||
int flags, ret, count;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.endpoint_block_connect = true;
|
||||
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
|
||||
usrsocktest_daemon_config.endpoint_port = 255;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Duplicate socket */
|
||||
|
||||
sd2 = dup(sd);
|
||||
TEST_ASSERT_TRUE(sd2 >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Launch connect attempt, daemon delays actual connection until triggered. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Another connect attempt results EALREADY. */
|
||||
|
||||
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EALREADY, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Release delayed connect. */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
|
||||
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Another connect attempt results EISCONN. */
|
||||
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
|
||||
/* Close sockets. */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd2) >= 0);
|
||||
sd2 = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(NoBlockConnect)
|
||||
{
|
||||
RUN_TEST_CASE(NoBlockConnect, InstantConnect);
|
||||
RUN_TEST_CASE(NoBlockConnect, DelayedConnect);
|
||||
RUN_TEST_CASE(NoBlockConnect, CloseNotConnected);
|
||||
RUN_TEST_CASE(NoBlockConnect, EarlyDrop);
|
||||
RUN_TEST_CASE(NoBlockConnect, Multiple);
|
||||
RUN_TEST_CASE(NoBlockConnect, Dup2);
|
||||
}
|
521
examples/usrsocktest/usrsocktest_noblock_recv.c
Normal file
521
examples/usrsocktest/usrsocktest_noblock_recv.c
Normal file
@ -0,0 +1,521 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_noblock_recv.c
|
||||
* Receive from the socket in non-blocking mode
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Receive
|
||||
*
|
||||
* Description:
|
||||
* Non-blocking & instant connect+recv
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Receive(struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int flags;
|
||||
int count;
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
struct sockaddr_in addr;
|
||||
char databuf[4];
|
||||
struct sockaddr_in remoteaddr;
|
||||
socklen_t addrlen;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_recv_avail_from_start = true;
|
||||
dconf->endpoint_recv_avail = 7;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Do connect, should succeed instantly. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
if (!dconf->delay_all_responses)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0,
|
||||
usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0,
|
||||
usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1;
|
||||
count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 3);
|
||||
usleep(25 * 1000);
|
||||
}
|
||||
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
}
|
||||
|
||||
/* Receive data from remote, daemon returns 4 bytes. */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(4, datalen);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(4, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Receive data from remote with address, daemon returns 3 bytes. */
|
||||
|
||||
addrlen = sizeof(remoteaddr);
|
||||
ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr,
|
||||
&addrlen);
|
||||
TEST_ASSERT_EQUAL(3, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3);
|
||||
TEST_ASSERT_EQUAL(addrlen, sizeof(remoteaddr));
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(datalen + ret, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Receive data from remote, daemon has 0 bytes buffered => -EAGAIN */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EAGAIN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Receive data from remote, daemon has 0 bytes buffered => -EAGAIN */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = read(sd, data, datalen);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EAGAIN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Reset recv buffer for open sockets */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0));
|
||||
for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(5 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Receive data from remote, daemon returns 4 bytes. */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(4, datalen);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(7 + 4, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(7 + 4, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: DelayedConnect
|
||||
*
|
||||
* Description:
|
||||
* Non-blocking & delayed connect
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void DelayedConnect(struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int flags;
|
||||
int count;
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
struct sockaddr_in addr;
|
||||
char databuf[4];
|
||||
struct sockaddr_in remoteaddr;
|
||||
socklen_t addrlen;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_block_connect = true;
|
||||
dconf->endpoint_recv_avail_from_start = false;
|
||||
dconf->endpoint_recv_avail = 4;
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Launch connect attempt, daemon delays actual connection until triggered. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Try receive data, not connected yet. */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = read(sd, data, datalen);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EAGAIN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Release delayed connect. */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
|
||||
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0;
|
||||
count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Try receive data, not received data yet. */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
addrlen = sizeof(remoteaddr);
|
||||
ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr,
|
||||
&addrlen);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EAGAIN, errno);
|
||||
TEST_ASSERT_EQUAL(0, addrlen);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Reset recv buffer for open sockets */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0));
|
||||
for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(5 * 1000);
|
||||
}
|
||||
|
||||
/* Receive data from remote, daemon returns 4 bytes. */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(4, datalen);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(4, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Close socket. */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV,
|
||||
usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoBlockRecv test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(NoBlockRecv)
|
||||
{
|
||||
sd = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoBlockRecv test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(NoBlockRecv)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NoBlockRecv, Receive)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Receive(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(NoBlockRecv, ReceiveDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Receive(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(NoBlockRecv, DelayedConnect)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
DelayedConnect(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(NoBlockRecv, DelayedConnectDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
DelayedConnect(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(NoBlockRecv)
|
||||
{
|
||||
RUN_TEST_CASE(NoBlockRecv, Receive);
|
||||
RUN_TEST_CASE(NoBlockRecv, ReceiveDelay);
|
||||
RUN_TEST_CASE(NoBlockRecv, DelayedConnect);
|
||||
RUN_TEST_CASE(NoBlockRecv, DelayedConnectDelay);
|
||||
}
|
414
examples/usrsocktest/usrsocktest_noblock_send.c
Normal file
414
examples/usrsocktest/usrsocktest_noblock_send.c
Normal file
@ -0,0 +1,414 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_noblock_send.c
|
||||
* Send through the socket in non-blocking mode
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Send
|
||||
*
|
||||
* Description:
|
||||
* Open socket, connect instantly and send
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void Send(struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int flags;
|
||||
int count;
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
const void *data;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Do connect, should succeed instantly. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
if (!dconf->delay_all_responses)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1;
|
||||
count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 3);
|
||||
usleep(25 * 1000);
|
||||
}
|
||||
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
}
|
||||
|
||||
/* Send data to remote */
|
||||
|
||||
data = "abcde";
|
||||
datalen = strlen("abcde");
|
||||
ret = sendto(sd, data, datalen, 0, NULL, 0);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ConnectSend
|
||||
*
|
||||
* Description:
|
||||
* Open socket, connect is delayed and send
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int flags;
|
||||
int count;
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
const void *data;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_block_connect = true;
|
||||
dconf->endpoint_block_send = true;
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Launch connect attempt, daemon delays actual connection until triggered. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Send data to remote, not connected yet. */
|
||||
|
||||
data = "abcde";
|
||||
datalen = strlen("abcde");
|
||||
ret = write(sd, data, datalen);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EAGAIN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Release delayed connect. */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
|
||||
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0;
|
||||
count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 5);
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Send data to remote */
|
||||
|
||||
data = "abcde";
|
||||
datalen = strlen("abcde");
|
||||
ret = write(sd, data, datalen);
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EAGAIN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Close socket. */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV,
|
||||
usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoBlockSend test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(NoBlockSend)
|
||||
{
|
||||
sd = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoBlockSend test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(NoBlockSend)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NoBlockSend, Send)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
Send(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(NoBlockSend, SendDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
Send(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(NoBlockSend, ConnectSend)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
ConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(NoBlockSend, ConnectSendDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
ConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(NoBlockSend)
|
||||
{
|
||||
RUN_TEST_CASE(NoBlockSend, Send);
|
||||
RUN_TEST_CASE(NoBlockSend, SendDelay);
|
||||
RUN_TEST_CASE(NoBlockSend, ConnectSend);
|
||||
RUN_TEST_CASE(NoBlockSend, ConnectSendDelay);
|
||||
}
|
154
examples/usrsocktest/usrsocktest_nodaemon.c
Normal file
154
examples/usrsocktest/usrsocktest_nodaemon.c
Normal file
@ -0,0 +1,154 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_nodaemon.c
|
||||
* Tests without user socket daemon
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoDaemon test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(NoDaemon)
|
||||
{
|
||||
sd = -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoDaemon test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(NoDaemon)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: NoSocket
|
||||
*
|
||||
* Description:
|
||||
* Simple test for opening socket without usrsock daemon running
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST(NoDaemon, NoSocket)
|
||||
{
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_EQUAL(-1, sd);
|
||||
TEST_ASSERT_TRUE(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT || errno == ENETDOWN);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(NoDaemon)
|
||||
{
|
||||
RUN_TEST_CASE(NoDaemon, NoSocket);
|
||||
}
|
646
examples/usrsocktest/usrsocktest_poll.c
Normal file
646
examples/usrsocktest/usrsocktest_poll.c
Normal file
@ -0,0 +1,646 @@
|
||||
/****************************************************************************
|
||||
* examples/usrsocktest/usrsocktest_poll.c
|
||||
* User socket polling tests
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
|
||||
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
|
||||
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static bool started;
|
||||
static int sd;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ConnectReceive
|
||||
*
|
||||
* Description:
|
||||
* Non-blocking connect and receive
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ConnectReceive(struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int flags;
|
||||
int count;
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
struct sockaddr_in addr;
|
||||
char databuf[4];
|
||||
struct pollfd pfd;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_recv_avail_from_start = false;
|
||||
dconf->endpoint_recv_avail = 3;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Poll for input (instant timeout). */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLIN;
|
||||
ret = poll(&pfd, 1, 0);
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR);
|
||||
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
|
||||
TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN);
|
||||
TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT);
|
||||
|
||||
/* Do connect, should succeed instantly. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
if (!dconf->delay_all_responses)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
|
||||
for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 3);
|
||||
usleep(25 * 1000);
|
||||
}
|
||||
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
}
|
||||
|
||||
/* Poll for input (instant timeout). */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLIN;
|
||||
ret = poll(&pfd, 1, 0);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
|
||||
/* Poll for input (with timeout). */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLIN;
|
||||
ret = poll(&pfd, 1, 10);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
|
||||
/* Poll for input (no timeout). */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLIN;
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100));
|
||||
ret = poll(&pfd, 1, -1);
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(POLLIN, pfd.revents);
|
||||
|
||||
/* Receive data from remote, daemon returns 3 bytes. */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL(3, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Poll for input (instant timeout). */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLIN;
|
||||
ret = poll(&pfd, 1, 0);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
|
||||
/* Make more data avail */
|
||||
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0));
|
||||
for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(count <= 3);
|
||||
usleep(5 * 1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Poll for input (no timeout). */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLIN;
|
||||
ret = poll(&pfd, 1, -1);
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(POLLIN, pfd.revents);
|
||||
|
||||
/* Receive data from remote, daemon returns 3 bytes. */
|
||||
|
||||
data = databuf;
|
||||
datalen = sizeof(databuf);
|
||||
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
|
||||
TEST_ASSERT_EQUAL(3, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ConnectSend
|
||||
*
|
||||
* Description:
|
||||
* Non-blocking connect and receive
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int flags;
|
||||
ssize_t ret;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
struct sockaddr_in addr;
|
||||
struct pollfd pfd;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_recv_avail_from_start = true;
|
||||
dconf->endpoint_recv_avail = 3;
|
||||
dconf->endpoint_block_send = false;
|
||||
dconf->endpoint_block_connect = true;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Poll for input (instant timeout). */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLIN;
|
||||
ret = poll(&pfd, 1, 0);
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR);
|
||||
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
|
||||
TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN);
|
||||
TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT);
|
||||
|
||||
/* Start non-blocking connect. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Poll for input (no timeout). As send is ready after established connection,
|
||||
* poll will exit with POLLOUT. */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLOUT;
|
||||
ret = poll(&pfd, 1, -1);
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(POLLOUT, pfd.revents);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EISCONN, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Send data to remote. */
|
||||
|
||||
data = "abcdeFG";
|
||||
datalen = strlen(data);
|
||||
ret = write(sd, data, datalen);
|
||||
TEST_ASSERT_EQUAL(datalen, ret);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: DaemonAbort
|
||||
*
|
||||
* Description:
|
||||
* Poll with daemon abort
|
||||
*
|
||||
* Input Parameters:
|
||||
* dconf - socket daemon configuration
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void DaemonAbort(struct usrsocktest_daemon_conf_s *dconf)
|
||||
{
|
||||
int flags;
|
||||
ssize_t ret;
|
||||
struct sockaddr_in addr;
|
||||
struct pollfd pfd;
|
||||
|
||||
/* Start test daemon. */
|
||||
|
||||
dconf->endpoint_addr = "127.0.0.1";
|
||||
dconf->endpoint_port = 255;
|
||||
dconf->endpoint_recv_avail_from_start = false;
|
||||
dconf->endpoint_recv_avail = 3;
|
||||
dconf->endpoint_block_send = false;
|
||||
dconf->endpoint_block_connect = true;
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
|
||||
started = true;
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
|
||||
|
||||
/* Open socket */
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
TEST_ASSERT_TRUE(sd >= 0);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Make socket non-blocking */
|
||||
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
|
||||
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
|
||||
TEST_ASSERT_EQUAL(0, ret);
|
||||
flags = fcntl(sd, F_GETFL, 0);
|
||||
TEST_ASSERT_TRUE(flags >= 0);
|
||||
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
|
||||
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
|
||||
|
||||
/* Poll for input (instant timeout). */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLIN;
|
||||
ret = poll(&pfd, 1, 0);
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR);
|
||||
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
|
||||
TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN);
|
||||
TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT);
|
||||
|
||||
/* Start non-blocking connect. */
|
||||
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(255);
|
||||
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
|
||||
TEST_ASSERT_EQUAL(-1, ret);
|
||||
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
|
||||
|
||||
/* Poll for input (no timeout). Stop daemon forcefully. */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('S', 100));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLOUT;
|
||||
ret = poll(&pfd, 1, -1);
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR);
|
||||
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
|
||||
|
||||
/* Stopping daemon should succeed. */
|
||||
|
||||
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
|
||||
started = false;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
|
||||
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
|
||||
|
||||
/* Poll for input (no timeout). */
|
||||
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = sd;
|
||||
pfd.events = POLLOUT;
|
||||
ret = poll(&pfd, 1, -1);
|
||||
TEST_ASSERT_EQUAL(1, ret);
|
||||
TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR);
|
||||
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
|
||||
TEST_ASSERT_EQUAL(0, pfd.revents & POLLIN);
|
||||
TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT);
|
||||
|
||||
/* Close socket */
|
||||
|
||||
TEST_ASSERT_TRUE(close(sd) >= 0);
|
||||
sd = -1;
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_send_bytes());
|
||||
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_recv_empty_sockets());
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Poll test group setup
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed before each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_SETUP(Poll)
|
||||
{
|
||||
sd = -1;
|
||||
started = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Poll test group teardown
|
||||
*
|
||||
* Description:
|
||||
* Setup function executed after each testcase in this test group
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
TEST_TEAR_DOWN(Poll)
|
||||
{
|
||||
int ret;
|
||||
if (sd >= 0)
|
||||
{
|
||||
ret = close(sd);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
if (started)
|
||||
{
|
||||
ret = usrsocktest_daemon_stop();
|
||||
assert(ret == OK);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Poll, ConnectReceive)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
ConnectReceive(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(Poll, ConnectReceiveDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
ConnectReceive(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(Poll, ConnectSend)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
ConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(Poll, ConnectSendDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
ConnectSend(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(Poll, DaemonAbort)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
DaemonAbort(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
TEST(Poll, DaemonAbortDelay)
|
||||
{
|
||||
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
|
||||
usrsocktest_daemon_config.delay_all_responses = true;
|
||||
DaemonAbort(&usrsocktest_daemon_config);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
TEST_GROUP(Poll)
|
||||
{
|
||||
RUN_TEST_CASE(Poll, ConnectReceive);
|
||||
RUN_TEST_CASE(Poll, ConnectReceiveDelay);
|
||||
RUN_TEST_CASE(Poll, ConnectSend);
|
||||
RUN_TEST_CASE(Poll, ConnectSendDelay);
|
||||
RUN_TEST_CASE(Poll, DaemonAbort);
|
||||
RUN_TEST_CASE(Poll, DaemonAbortDelay);
|
||||
}
|
1082
examples/usrsocktest/usrsocktest_remote_disconnect.c
Normal file
1082
examples/usrsocktest/usrsocktest_remote_disconnect.c
Normal file
File diff suppressed because it is too large
Load Diff
1658
examples/usrsocktest/usrsocktest_wake_with_signal.c
Normal file
1658
examples/usrsocktest/usrsocktest_wake_with_signal.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -48,6 +48,8 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <nuttx/net/netconfig.h>
|
||||
#include <nuttx/net/ethernet.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
@ -1017,10 +1017,10 @@ o rmmod <module-name>
|
||||
NAME INIT UNINIT ARG TEXT SIZE DATA SIZE
|
||||
nsh>
|
||||
|
||||
o set <name> <value>
|
||||
o set [{+|-}{e|x|xe|ex}] [<name> <value>]
|
||||
|
||||
Set the environment variable <name> to the sting <value>.
|
||||
For example,
|
||||
Set the environment variable <name> to the sting <value> and or set NSH
|
||||
parser control options. For example,
|
||||
|
||||
nsh> echo $foobar
|
||||
|
||||
@ -1029,6 +1029,38 @@ o set <name> <value>
|
||||
foovalue
|
||||
nsh>
|
||||
|
||||
Set the 'exit on error control' and/or 'print a trace' of commands when parsing
|
||||
scripts in NSH. The settinngs are in effect from the point of exection, until
|
||||
they are changed again, or in the case of the init script, the settings are
|
||||
returned to the default settings when it exits. Included child scripts will run
|
||||
with the parents settings and changes made in the child script will effect the
|
||||
parent on return.
|
||||
|
||||
Use 'set -e' to enable and 'set +e' to disable (ignore) the exit condition on commands.
|
||||
The default is -e. Errors cause script to exit.
|
||||
|
||||
Use 'set -x' to enable and 'set +x' to disable (silence) printing a trace of the script
|
||||
commands as they are ececuted.
|
||||
The default is +x. No printing of a trace of script commands as they are executed.
|
||||
|
||||
Example 1 - no exit on command not found
|
||||
set +e
|
||||
notacommand
|
||||
|
||||
Example 2 - will exit on command not found
|
||||
set -e
|
||||
notacommand
|
||||
|
||||
Example 3 - will exit on command not found, and print a trace of the script commmands
|
||||
set -ex
|
||||
|
||||
Example 4 - will exit on command not found, and print a trace of the script commmands
|
||||
and set foobar to foovalue.
|
||||
set -ex foobar foovalue
|
||||
nsh> echo $foobar
|
||||
foovalue
|
||||
|
||||
|
||||
o sh <script-path>
|
||||
|
||||
Execute the sequence of NSH commands in the file referred
|
||||
|
34
nshlib/nsh.h
34
nshlib/nsh.h
@ -690,6 +690,15 @@
|
||||
# undef NSH_HAVE_TRIMSPACES
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||
# define NSH_NP_SET_OPTIONS "ex" /* Maintain order see nsh_npflags_e */
|
||||
# define NSH_NP_SET_OPTIONS_INIT (NSH_PFLAG_SILENT)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_NSH_DISABLESCRIPT)
|
||||
# define CONFIG_NSH_DISABLE_SET
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
@ -741,6 +750,22 @@ struct nsh_loop_s
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||
/* Define the bits that correspond to the option defined in
|
||||
* NSH_NP_SET_OPTIONS. The bit value is 1 shifted left the offset
|
||||
* of the char in NSH_NP_SET_OPTIONS string.
|
||||
*/
|
||||
|
||||
enum nsh_npflags_e
|
||||
{
|
||||
NSH_PFLAG_IGNORE = 1, /* set for +e no exit on errors,
|
||||
* cleared -e exit on error */
|
||||
NSH_PFLAG_SILENT = 2, /* cleared -x print a trace of commands
|
||||
* when parsing.
|
||||
* set +x no print a trace of commands */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* These structure provides the overall state of the parser */
|
||||
|
||||
struct nsh_parser_s
|
||||
@ -752,6 +777,9 @@ struct nsh_parser_s
|
||||
bool np_redirect; /* true: Output from the last command was re-directed */
|
||||
#endif
|
||||
bool np_fail; /* true: The last command failed */
|
||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||
uint8_t np_flags; /* See nsh_npflags_e above */
|
||||
#endif
|
||||
#ifndef CONFIG_NSH_DISABLEBG
|
||||
int np_nice; /* "nice" value applied to last background cmd */
|
||||
#endif
|
||||
@ -1175,10 +1203,10 @@ int cmd_lsmod(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||
int cmd_uname(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
# ifndef CONFIG_NSH_DISABLE_SET
|
||||
#ifndef CONFIG_NSH_DISABLE_SET
|
||||
int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||
# endif
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
# ifndef CONFIG_NSH_DISABLE_UNSET
|
||||
int cmd_unset(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
|
||||
# endif
|
||||
|
@ -436,10 +436,14 @@ static const struct cmdmap_s g_cmdmap[] =
|
||||
{ "rmmod", cmd_rmmod, 2, 2, "<module-name>" },
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
# ifndef CONFIG_NSH_DISABLE_SET
|
||||
#ifndef CONFIG_NSH_DISABLE_SET
|
||||
# if !defined(CONFIG_DISABLE_ENVIRON) && !defined(CONFIG_NSH_DISABLESCRIPT)
|
||||
{ "set", cmd_set, 2, 4, "[{+|-}{e|x|xe|ex}] [<name> <value>]" },
|
||||
# elif !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_NSH_DISABLESCRIPT)
|
||||
{ "set", cmd_set, 3, 3, "<name> <value>" },
|
||||
# endif
|
||||
# elif defined(CONFIG_DISABLE_ENVIRON) && !defined(CONFIG_NSH_DISABLESCRIPT)
|
||||
{ "set", cmd_set, 2, 2, "{+|-}{e|x|xe|ex}" },
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_NSH_DISABLESCRIPT)
|
||||
|
@ -480,5 +480,11 @@ FAR struct console_stdio_s *nsh_newconsole(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||
/* Set the initial option flags */
|
||||
|
||||
pstate->cn_vtbl.np.np_flags = NSH_NP_SET_OPTIONS_INIT;
|
||||
#endif
|
||||
|
||||
return pstate;
|
||||
}
|
||||
|
@ -85,6 +85,12 @@ int nsh_consolemain(int argc, char *argv[])
|
||||
/* Execute the start-up script */
|
||||
|
||||
(void)nsh_initscript(&pstate->cn_vtbl);
|
||||
|
||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||
/* Reset the option flags */
|
||||
|
||||
pstate->cn_vtbl.np.np_flags = NSH_NP_SET_OPTIONS_INIT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NSH_USBDEV_TRACE
|
||||
|
@ -311,29 +311,86 @@ int cmd_pwd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||
* Name: cmd_set
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
#ifndef CONFIG_NSH_DISABLE_SET
|
||||
int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||
{
|
||||
FAR char *value;
|
||||
int ret;
|
||||
int ret = OK;
|
||||
int ndx = 1;
|
||||
#ifndef CONFIG_NSH_DISABLESCRIPT
|
||||
FAR char *popt;
|
||||
const char opts[] = NSH_NP_SET_OPTIONS;
|
||||
int op;
|
||||
|
||||
/* Trim whitespace from the value */
|
||||
/* Support set [{+|-}{e|x|xe|ex}] [<name> <value>] */
|
||||
|
||||
value = nsh_trimspaces(argv[2]);
|
||||
|
||||
/* Set the environment variable */
|
||||
|
||||
ret = setenv(argv[1], value, TRUE);
|
||||
if (ret < 0)
|
||||
if (argc == 2 || argc == 4)
|
||||
{
|
||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "setenv", NSH_ERRNO);
|
||||
}
|
||||
if (strlen(argv[1]) < 2)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
nsh_output(vtbl, g_fmtargrequired, argv[0], "set", NSH_ERRNO);
|
||||
}
|
||||
else
|
||||
{
|
||||
op = argv[1][0];
|
||||
if (op != '-' && op != '+')
|
||||
{
|
||||
ret = -EINVAL;
|
||||
nsh_output(vtbl, g_fmtarginvalid, argv[0], "set", NSH_ERRNO);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = &argv[1][1];
|
||||
while(*value && *value != ' ')
|
||||
{
|
||||
popt = strchr(opts, *value++);
|
||||
if (popt == NULL)
|
||||
{
|
||||
nsh_output(vtbl, g_fmtarginvalid, argv[0], "set", NSH_ERRNO);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (op == '+')
|
||||
{
|
||||
vtbl->np.np_flags |= 1 << (popt-opts);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtbl->np.np_flags &= ~(1 << (popt-opts));
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == OK)
|
||||
{
|
||||
ndx = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# ifndef CONFIG_DISABLE_ENVIRON
|
||||
if (ret == OK && (argc == 3 || argc == 4))
|
||||
# endif
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
{
|
||||
/* Trim whitespace from the value */
|
||||
|
||||
value = nsh_trimspaces(argv[ndx+1]);
|
||||
|
||||
/* Set the environment variable */
|
||||
|
||||
ret = setenv(argv[ndx], value, TRUE);
|
||||
if (ret < 0)
|
||||
{
|
||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "setenv", NSH_ERRNO);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cmd_unset
|
||||
|
@ -575,7 +575,7 @@ static int nsh_gethostip(FAR char *hostname, FAR union ip_addr_u *ipaddr,
|
||||
static void wget_callback(FAR char **buffer, int offset, int datend,
|
||||
FAR int *buflen, FAR void *arg)
|
||||
{
|
||||
(void)write((int)arg, &((*buffer)[offset]), datend - offset);
|
||||
(void)write((int)((intptr_t)arg), &((*buffer)[offset]), datend - offset);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@ -1668,7 +1668,7 @@ int cmd_wget(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||
|
||||
/* And perform the wget */
|
||||
|
||||
ret = wget(url, buffer, 512, wget_callback, (FAR void *)fd);
|
||||
ret = wget(url, buffer, 512, wget_callback, (FAR void *)((intptr_t)fd));
|
||||
if (ret < 0)
|
||||
{
|
||||
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "wget", NSH_ERRNO);
|
||||
|
@ -101,13 +101,17 @@
|
||||
|
||||
/* Select the single network device name supported this this network
|
||||
* initialization logci. If multiple interfaces are present with different
|
||||
* link types, the the orider of definition in the following conditional
|
||||
* logic will select the one interface that will be used.
|
||||
* link types, the the order of definition in the following conditional
|
||||
* logic will select the one interface that will be used (which might
|
||||
* not be the one that you want).
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_ETHERNET)
|
||||
# define NET_DEVNAME "eth0"
|
||||
# define NSH_HAVE_NETDEV
|
||||
#elif defined(CONFIG_NET_6LOWPAN)
|
||||
# define NET_DEVNAME "wpan0"
|
||||
# define NSH_HAVE_NETDEV
|
||||
#elif defined(CONFIG_NET_SLIP)
|
||||
# define NET_DEVNAME "sl0"
|
||||
# ifndef CONFIG_NSH_NOMAC
|
||||
@ -120,6 +124,8 @@
|
||||
#elif defined(CONFIG_NET_LOCAL)
|
||||
# define NET_DEVNAME "lo"
|
||||
# define NSH_HAVE_NETDEV
|
||||
#elif defined(CONFIG_NET_USRSOCK)
|
||||
# undef NSH_HAVE_NETDEV
|
||||
#elif !defined(CONFIG_NET_LOOPBACK)
|
||||
# error ERROR: No link layer protocol defined
|
||||
#endif
|
||||
@ -200,7 +206,7 @@ static const uint16_t g_ipv6_netmask[8] =
|
||||
HTONS(CONFIG_NSH_IPv6NETMASK_7),
|
||||
HTONS(CONFIG_NSH_IPv6NETMASK_8),
|
||||
};
|
||||
#endif /* CONFIG_NET_IPv6 && !CONFIG_NET_ICMPv6_AUTOCONF*/
|
||||
#endif /* CONFIG_NET_IPv6 && !CONFIG_NET_ICMPv6_AUTOCONF */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -1169,6 +1169,11 @@ static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
|
||||
|
||||
envstr = nsh_envexpand(vtbl, ptr);
|
||||
|
||||
if ((vtbl->np.np_flags & NSH_PFLAG_SILENT) == 0)
|
||||
{
|
||||
nsh_output(vtbl," %s=%s\n", ptr, envstr ? envstr :"(null)");
|
||||
}
|
||||
|
||||
/* Concatenate the result of the operation with the accumulated
|
||||
* string. On failures to allocation memory, nsh_strcat will
|
||||
* just return value value of argument
|
||||
|
@ -136,10 +136,15 @@ int nsh_script(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
* considerable amount of stack may be used.
|
||||
*/
|
||||
|
||||
if ((vtbl->np.np_flags & NSH_PFLAG_SILENT) == 0)
|
||||
{
|
||||
nsh_output(vtbl,"%s", buffer);
|
||||
}
|
||||
|
||||
ret = nsh_parse(vtbl, buffer);
|
||||
}
|
||||
}
|
||||
while (pret && ret == OK);
|
||||
while (pret && (ret == OK || (vtbl->np.np_flags & NSH_PFLAG_IGNORE)));
|
||||
|
||||
/* Close the script file */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user