blob: feb3c255d5ecc14e6a57806cc71b9c4304b4f6be [file] [log] [blame]
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include "bs_types.h"
#include "bs_tracing.h"
#include "time_machine.h"
#include "bstests.h"
#define FAIL(...) \
do { \
bst_result = Failed; \
bs_trace_error_time_line(__VA_ARGS__); \
} while (0)
#define PASS(...) \
do { \
bst_result = Passed; \
bs_trace_info_time(1, __VA_ARGS__); \
} while (0)
#define NAME_LEN 30
#define BT_AD_DATA_NAME_SIZE (sizeof(CONFIG_BT_DEVICE_NAME) - 1U + 2U)
#define BT_AD_DATA_MFG_DATA_SIZE (254U + 2U)
#define DATA_LEN MIN((BT_AD_DATA_NAME_SIZE + \
BT_AD_DATA_MFG_DATA_SIZE), \
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX)
static K_SEM_DEFINE(sem_recv, 0, 1);
extern enum bst_result_t bst_result;
static void test_adv_main(void)
{
extern int broadcaster_multiple(void);
int err;
err = broadcaster_multiple();
if (err) {
FAIL("Adv tests failed\n");
bs_trace_silent_exit(err);
return;
}
/* Successfully started advertising multiple sets */
PASS("Adv tests passed\n");
/* Let the scanner receive the reports */
k_sleep(K_SECONDS(10));
}
static bool data_cb(struct bt_data *data, void *user_data)
{
char *name = user_data;
uint8_t len;
switch (data->type) {
case BT_DATA_NAME_SHORTENED:
case BT_DATA_NAME_COMPLETE:
len = MIN(data->data_len, NAME_LEN - 1);
(void)memcpy(name, data->data, len);
name[len] = '\0';
return false;
default:
return true;
}
}
static void scan_recv(const struct bt_le_scan_recv_info *info,
struct net_buf_simple *buf)
{
static uint8_t sid[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
static uint8_t sid_count;
char name[NAME_LEN];
uint8_t data_status;
uint16_t data_len;
data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS(info->adv_props);
if (data_status) {
return;
}
data_len = buf->len;
if (data_len != DATA_LEN) {
return;
}
(void)memset(name, 0, sizeof(name));
bt_data_parse(buf, data_cb, name);
if (strcmp(name, CONFIG_BT_DEVICE_NAME)) {
return;
}
for (uint8_t i = 0; i < sid_count; i++) {
if (sid[i] == info->sid) {
return;
}
}
sid[sid_count++] = info->sid;
if (sid_count < CONFIG_BT_EXT_ADV_MAX_ADV_SET) {
return;
}
k_sem_give(&sem_recv);
}
static struct bt_le_scan_cb scan_callbacks = {
.recv = scan_recv,
};
static void test_scan_main(void)
{
extern int observer_start(void);
int err;
err = bt_enable(NULL);
if (err) {
FAIL("Bluetooth init failed\n");
bs_trace_silent_exit(err);
return;
}
bt_le_scan_cb_register(&scan_callbacks);
err = observer_start();
if (err) {
FAIL("Observer start failed\n");
bs_trace_silent_exit(err);
return;
}
/* Let the recv callback verify the reports */
k_sleep(K_SECONDS(10));
err = k_sem_take(&sem_recv, K_NO_WAIT);
if (err) {
FAIL("Scan receive failed\n");
bs_trace_silent_exit(err);
return;
}
PASS("Scan tests passed\n");
bs_trace_silent_exit(0);
}
static void test_adv_chain_init(void)
{
bst_ticker_set_next_tick_absolute(60e6);
bst_result = In_progress;
}
static void test_adv_chain_tick(bs_time_t HW_device_time)
{
bst_result = Failed;
bs_trace_error_line("Test GATT Write finished.\n");
}
static const struct bst_test_instance test_def[] = {
{
.test_id = "adv",
.test_descr = "Central GATT Write",
.test_post_init_f = test_adv_chain_init,
.test_tick_f = test_adv_chain_tick,
.test_main_f = test_adv_main
},
{
.test_id = "scan",
.test_descr = "Peripheral GATT Write",
.test_post_init_f = test_adv_chain_init,
.test_tick_f = test_adv_chain_tick,
.test_main_f = test_scan_main
},
BSTEST_END_MARKER
};
struct bst_test_list *test_adv_chain_install(struct bst_test_list *tests)
{
return bst_add_tests(tests, test_def);
}
bst_test_install_t test_installers[] = {
test_adv_chain_install,
NULL
};
void main(void)
{
bst_main();
}