Feature/bacnet secure connect hub (#818)
* Added BACnet Secure Connect datalink. * Added BACnet/SC hub application --------- Co-authored-by: Kirill Neznamov <kirill.neznamov@dsr-corporation.com> Co-authored-by: Mikhail Antropov <michail.antropov@dsr-corporation.com> Co-authored-by: Ondřej Hruška <ondra@ondrovo.com> Co-authored-by: Patrick Grimm <patrick@lunatiki.de>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
||||
get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
|
||||
project(test_${basename}
|
||||
VERSION 1.0.0
|
||||
LANGUAGES C)
|
||||
|
||||
find_package(Threads)
|
||||
find_package(PkgConfig)
|
||||
|
||||
set(CMAKE_C_FLAGS -pthread)
|
||||
|
||||
string(REGEX REPLACE
|
||||
"/test/ports/[a-zA-Z_/-]*$"
|
||||
"/src"
|
||||
SRC_DIR
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
string(REGEX REPLACE
|
||||
"/test/ports/[a-zA-Z_/-]*$"
|
||||
"/ports"
|
||||
PORTS_DIR
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
string(REGEX REPLACE
|
||||
"/test/ports/[a-zA-Z_/-]*$"
|
||||
"/test"
|
||||
TST_DIR
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(ZTST_DIR "${TST_DIR}/ztest/src")
|
||||
|
||||
add_compile_definitions(
|
||||
BIG_ENDIAN=0
|
||||
CONFIG_ZTEST=1
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${SRC_DIR}
|
||||
${TST_DIR}/ztest/include
|
||||
)
|
||||
|
||||
message(STATUS "bsc_event test: building for linux")
|
||||
set(BACNET_PORT_DIRECTORY_PATH ${PORTS_DIR})
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
${PORTS_DIR}/linux/bsc-event.c
|
||||
${SRC_DIR}/bacnet/basic/sys/debug.c
|
||||
# Test and test library files
|
||||
./src/main.c
|
||||
${ZTST_DIR}/ztest_mock.c
|
||||
${ZTST_DIR}/ztest.c
|
||||
)
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Legrand North America, LLC.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/* @file
|
||||
* @brief test of bsc-event interface
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <zephyr/ztest.h>
|
||||
#include <bacnet/datalink/bsc/bsc-event.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef enum {
|
||||
STAGE_NONE,
|
||||
STAGE_WAIT_1,
|
||||
STAGE_WAIT_2,
|
||||
STAGE_TIMEDWAIT_TIMEOUT,
|
||||
STAGE_TIMEDWAIT_OK,
|
||||
} TEST_STAGE;
|
||||
static TEST_STAGE test_stage = STAGE_NONE;
|
||||
|
||||
#define TIMEOUT_CHILD 400
|
||||
#define TIMEOUT_MIN 200
|
||||
#define TIMEOUT_MAX 600
|
||||
#define MSEC_PER_SEC 1000
|
||||
#define USEC_PER_MSEC 1000000
|
||||
#define TIMEOUT_SLEEP 2
|
||||
#define WAITTIME_MIN (TIMEOUT_SLEEP * MSEC_PER_SEC - 100)
|
||||
#define WAITTIME_MAX (TIMEOUT_SLEEP * MSEC_PER_SEC + 100)
|
||||
#define MULTIPLE_WAIT_THREADS_NUM 50
|
||||
|
||||
static void *child_func(void *arg)
|
||||
{
|
||||
BSC_EVENT *event = (BSC_EVENT *)arg;
|
||||
zassert_not_null(event, NULL);
|
||||
|
||||
while (test_stage != STAGE_WAIT_1) {
|
||||
usleep(10);
|
||||
}
|
||||
bsc_event_signal(event);
|
||||
|
||||
while (test_stage != STAGE_WAIT_2) {
|
||||
usleep(10);
|
||||
}
|
||||
bsc_event_signal(event);
|
||||
|
||||
while (test_stage != STAGE_TIMEDWAIT_TIMEOUT) {
|
||||
usleep(10);
|
||||
}
|
||||
usleep(1000 * TIMEOUT_CHILD);
|
||||
bsc_event_signal(event);
|
||||
|
||||
while (test_stage != STAGE_TIMEDWAIT_OK) {
|
||||
usleep(10);
|
||||
}
|
||||
usleep(1000 * TIMEOUT_CHILD);
|
||||
bsc_event_signal(event);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void test_bsc_event1(void)
|
||||
{
|
||||
BSC_EVENT *event;
|
||||
pthread_t tid_child;
|
||||
bool b;
|
||||
struct timespec t1;
|
||||
struct timespec t2;
|
||||
int64_t timediff;
|
||||
|
||||
test_stage = STAGE_NONE;
|
||||
event = bsc_event_init();
|
||||
zassert_not_null(event, NULL);
|
||||
|
||||
// run child and wait when child running
|
||||
zassert_equal(
|
||||
pthread_create(&tid_child, NULL, &child_func, event), 0, NULL);
|
||||
|
||||
test_stage = STAGE_WAIT_1;
|
||||
bsc_event_wait(event);
|
||||
|
||||
test_stage = STAGE_WAIT_2;
|
||||
bsc_event_wait(event);
|
||||
|
||||
test_stage = STAGE_TIMEDWAIT_TIMEOUT;
|
||||
b = bsc_event_timedwait(event, TIMEOUT_MIN);
|
||||
zassert_false(b, NULL);
|
||||
|
||||
test_stage = STAGE_TIMEDWAIT_OK;
|
||||
b = bsc_event_timedwait(event, TIMEOUT_MAX);
|
||||
zassert_true(b, NULL);
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &t1);
|
||||
bsc_wait(TIMEOUT_SLEEP);
|
||||
clock_gettime(CLOCK_REALTIME, &t2);
|
||||
timediff = (t2.tv_sec * MSEC_PER_SEC + t2.tv_nsec / USEC_PER_MSEC) -
|
||||
(t1.tv_sec * MSEC_PER_SEC + t1.tv_nsec / USEC_PER_MSEC);
|
||||
zassert_true(timediff >= TIMEOUT_SLEEP * MSEC_PER_SEC, NULL);
|
||||
pthread_join(tid_child, NULL);
|
||||
bsc_event_deinit(event);
|
||||
}
|
||||
|
||||
static void *thread_func(void *arg)
|
||||
{
|
||||
BSC_EVENT *event = (BSC_EVENT *)arg;
|
||||
zassert_not_null(event, NULL);
|
||||
bsc_event_wait(event);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void test_bsc_event2(void)
|
||||
{
|
||||
BSC_EVENT *event;
|
||||
pthread_t tid[MULTIPLE_WAIT_THREADS_NUM];
|
||||
int i;
|
||||
|
||||
event = bsc_event_init();
|
||||
zassert_not_null(event, NULL);
|
||||
|
||||
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
|
||||
zassert_equal(
|
||||
pthread_create(&tid[i], NULL, &thread_func, event), 0, NULL);
|
||||
}
|
||||
|
||||
bsc_wait(1);
|
||||
bsc_event_signal(event);
|
||||
|
||||
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
|
||||
pthread_join(tid[i], NULL);
|
||||
}
|
||||
|
||||
bsc_event_deinit(event);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
BSC_EVENT *event;
|
||||
bool result;
|
||||
} test_param_t;
|
||||
|
||||
static void *thread_func2(void *arg)
|
||||
{
|
||||
test_param_t *p = (test_param_t *)arg;
|
||||
zassert_not_null(p->event, NULL);
|
||||
// use some big timeout value, 24 hours seems to be enough
|
||||
p->result = bsc_event_timedwait(p->event, 24 * 60 * 60 * 1000);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void test_bsc_event3(void)
|
||||
{
|
||||
BSC_EVENT *event;
|
||||
pthread_t tid[MULTIPLE_WAIT_THREADS_NUM];
|
||||
test_param_t results[MULTIPLE_WAIT_THREADS_NUM];
|
||||
int i;
|
||||
|
||||
event = bsc_event_init();
|
||||
zassert_not_null(event, NULL);
|
||||
|
||||
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
|
||||
results[i].event = event;
|
||||
results[i].result = false;
|
||||
zassert_equal(
|
||||
pthread_create(&tid[i], NULL, &thread_func2, &results[i]), 0, NULL);
|
||||
}
|
||||
|
||||
bsc_wait(1);
|
||||
bsc_event_signal(event);
|
||||
|
||||
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
|
||||
pthread_join(tid[i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < MULTIPLE_WAIT_THREADS_NUM; i++) {
|
||||
zassert_equal(results[i].result == true, true, NULL);
|
||||
}
|
||||
|
||||
bsc_event_deinit(event);
|
||||
}
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(bsc_event_test1, ztest_unit_test(test_bsc_event1));
|
||||
ztest_test_suite(bsc_event_test2, ztest_unit_test(test_bsc_event2));
|
||||
ztest_test_suite(bsc_event_test3, ztest_unit_test(test_bsc_event3));
|
||||
ztest_run_test_suite(bsc_event_test1);
|
||||
ztest_run_test_suite(bsc_event_test2);
|
||||
ztest_run_test_suite(bsc_event_test3);
|
||||
}
|
||||
Reference in New Issue
Block a user