Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
halinterface/
rdk-wifi-hal/

.cache/
compile_commands.json
133 changes: 133 additions & 0 deletions test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
OW = $(PWD)/../source
HALIF = $(PWD)/halinterface
HAL = $(PWD)/rdk-wifi-hal

INCLUDE = \
-I $(OW)/db \
-I $(OW)/stubs \
-I $(OW)/../include \
-I $(OW)/core/services/ \
-I $(OW)/core \
-I $(OW)/stats \
-I $(OW)/utils \
-I $(OW)/platform/common/ \
-I $(OW)/platform/linux/ \
-I $(OW)/platform/linux/he_bus/inc \
-I $(OW)/ccsp/ \
-I $(OW)/apps/ \
-I $(OW)/apps/analytics/ \
-I $(OW)/apps/levl/ \
-I $(OW)/apps/csi/ \
-I $(OW)/apps/sm \
-I $(OW)/apps/motion/ \
-I $(OW)/apps/whix/ \
-I $(OW)/apps/harvester/ \
-I $(OW)/apps/ocs/ \
-I $(OW)/dml/linux/ \
-I $(HALIF)/include \
-I $(HAL)/src/

CFLAGS = \
-Og -g3 -ggdb -pipe \
-Wno-implicit-function-declaration \
-DSTATIC=static

CC = gcc

ifneq ($(COV),)
CFLAGS += --coverage
endif

all::
@true

clean::
@true

distclean:: clean
@true

FORCE:

LIBOW_SO = \
$(OW)/core/wifi_ctrl.c \
$(OW)/core/wifi_events.c \
$(OW)/utils/collection.c

libow.so: $(LIBOW_SO)
$(CC) $(INCLUDE) $(CFLAGS) \
-shared -fPIC \
-o $@ \
$(LIBOW_SO)

clean::
rm -f libow.so

libstubs.so: stubs.c
$(CC) $(CFLAGS) -shared -fPIC -o $@ stubs.c

clean::
rm -f libstubs.so

libs:: libow.so libstubs.so

ctrl-queue: ctrl-queue.c libow.so libstubs.so
$(CC) $(INCLUDE) $(CFLAGS) -o ctrl-queue ctrl-queue.c -L. -low -lstubs

clean::
rm -f ctrl-queue

stubs.c: libow.so
$(CC) $(INCLUDE) $(CFLAGS) -o ignore ctrl-queue.c -L. -low 2>&1 | \
grep 'undefined reference' | \
cut -d\` -f2 | cut -d\' -f1 | \
sort | uniq | \
while read n ; do \
echo "void $${n} (void) { ldk(); }" ; \
done > $@
sed -i '1i extern void ldk (void);' $@

clean::
rm -f stubs.c

all:: ctrl-queue

r:
LD_LIBRARY_PATH=$$PWD ./ctrl-queue

bt:
LD_LIBRARY_PATH=$$PWD gdb -q \
-ex 'set confirm off' \
-ex 'r' \
-ex 'bt' \
-ex 'q' \
./ctrl-queue

gdb:
LD_LIBRARY_PATH=$$PWD gdb -q \
-ex 'set confirm off' \
-ex 'b main' \
-ex 'r' \
./ctrl-queue


coverage.info: FORCE
lcov \
--quiet \
--rc branch_coverage=1 \
--no-external \
--capture \
--directory . \
--output-file coverage.info

lcov: coverage.info
genhtml \
--legend \
--rc branch_coverage=1 \
$< \
-o tmp

clean::
rm -f coverage.info
[ -d tmp ] && rm -r tmp || true
rm -f *.gcda *.gcno
146 changes: 146 additions & 0 deletions test/ctrl-queue.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <collection.h>
#include <wifi_ctrl.h>
#include <wifi_mgr.h>
#include <assert.h>
#include <sys/time.h>

#define called() \
do { \
struct timeval tv; \
gettimeofday(&tv, NULL); \
printf("%ld.%03ld:%s:%d: Called\n", tv.tv_sec, tv.tv_usec / 1000, __func__, __LINE__); \
} while (0)

static wifi_ctrl_t *ldk_wifi_ctrl_g;
extern void ctrl_queue_loop(wifi_ctrl_t *);

extern void ldk (void) {
assert(0);
}

static unsigned char scheduler_executed = false;

int scheduler_execute(struct scheduler *sched, struct timespec t_start, unsigned int timeout_ms)
{
usleep(timeout_ms * 1000);
scheduler_executed = true;
return 0;
}

wifi_ctrl_t *get_wifictrl_obj(void) {
return ldk_wifi_ctrl_g;
}

wifi_mgr_t *get_wifimgr_obj(void) {
return NULL;
}

int get_number_of_radios(wifi_platform_property_t *wifi_prop) {
return 1;
}

int apps_mgr_event(wifi_apps_mgr_t *apps_mgr, wifi_event_t *event) {
// printf("%s:%d: Called\n", __func__, __LINE__);
return -1;
}

void wifi_util_print(wifi_log_level_t level, wifi_dbg_type_t module, char *format, ...)
{
va_list ap;

va_start(ap, format);
vprintf(format, ap);
va_end(ap);
}

struct ts {
uint64_t ts;
};

void handle_hal_indication(wifi_ctrl_t *ctrl, void *data, unsigned int len,
wifi_event_subtype_t subtype) {
struct ts *ts = data;
struct timespec tv;
clock_gettime(CLOCK_MONOTONIC, &tv);
const uint64_t delay = (tv.tv_sec * 1000 + tv.tv_nsec /1000 /1000) - ts->ts;
printf("%s:%d: Processing delay: %ld\n", __func__, __LINE__, delay);
assert(delay < 200);

// simulate short event
usleep(10 * 1000);
}

void handle_webconfig_event(wifi_ctrl_t *ctrl, const char *raw, unsigned int len,
wifi_event_subtype_t subtype) {
// simulate long event
usleep(200 * 1000);
}

void * ctrl_queue_wrapper(void *arg) {
wifi_ctrl_t *ctrl = arg;
ctrl_queue_loop(ctrl);
return NULL;
}

static void push_event(const wifi_event_type_t event) {
struct ts ts;
struct timespec tv;
memset(&ts, 0x0, sizeof(ts));
clock_gettime(CLOCK_MONOTONIC, &tv);
ts.ts = tv.tv_sec * 1000 + tv.tv_nsec /1000 /1000;
push_event_to_ctrl_queue(&ts, sizeof(ts), event, 0, NULL);
}

int main(int argc, char *argv[]) {
wifi_ctrl_t ctrl;
memset(&ctrl, 0x0, sizeof(ctrl));

/* Init ctrl-queue */
clock_gettime(CLOCK_MONOTONIC, &ctrl.last_signalled_time);
clock_gettime(CLOCK_MONOTONIC, &ctrl.last_polled_time);

pthread_condattr_t cond_attr;
pthread_condattr_init(&cond_attr);
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
pthread_cond_init(&ctrl.cond, &cond_attr);
pthread_condattr_destroy(&cond_attr);

pthread_mutexattr_init(&ctrl.attr);
pthread_mutexattr_settype(&ctrl.attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&ctrl.queue_lock, &ctrl.attr);

ctrl.queue = queue_create();
ctrl.poll_period = QUEUE_WIFI_CTRL_TASK_TIMEOUT;
ldk_wifi_ctrl_g = &ctrl;

/* Event sequence */
push_event(wifi_event_type_hal_ind);
push_event(wifi_event_type_hal_ind);
push_event(wifi_event_type_hal_ind);
push_event(wifi_event_type_webconfig);
push_event(wifi_event_type_hal_ind);
push_event(wifi_event_type_hal_ind);

/* Spin thread */
pthread_t tid;
pthread_create(&tid, NULL, ctrl_queue_wrapper, &ctrl);
while (0x42) {
pthread_mutex_lock(&ctrl.queue_lock);
int len = queue_count(ctrl.queue);
if ((len == 0) && (scheduler_executed == true)) {
ctrl.exit_ctrl = true;
pthread_cond_signal(&ctrl.cond);
pthread_mutex_unlock(&ctrl.queue_lock);
break;
}
pthread_mutex_unlock(&ctrl.queue_lock);
usleep(100 * 1000);
}
pthread_join(tid, NULL);
return 0;
}
Loading