Commit 649a6250 authored by Vinayak Kariappa Chettimada's avatar Vinayak Kariappa Chettimada Committed by Carles Cufi
Browse files

tests: Bluetooth: bsim: Verify multiple broadcaster and chain PDU



Added BabbleSim test to reuse the Broadcaster Multiple and
Oberver samples to verify multiple advertising sets and
transmission of Extended Advertising Chain PDU.

Signed-off-by: default avatarVinayak Kariappa Chettimada <vich@nordicsemi.no>
parent e80ff5ff
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

if (NOT DEFINED ENV{BSIM_COMPONENTS_PATH})
  message(FATAL_ERROR "This test requires the BabbleSim simulator. Please set  \
          the  environment variable BSIM_COMPONENTS_PATH to point to its       \
          components folder. More information can be found in                  \
          https://babblesim.github.io/folder_structure_and_env.html")
endif()

find_package(Zephyr HINTS $ENV{ZEPHYR_BASE})
project(bsim_test_adv_chain)

target_sources(app PRIVATE
  src/main.c
  ${ZEPHYR_BASE}/samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c
  ${ZEPHYR_BASE}/samples/bluetooth/observer/src/observer.c
)

zephyr_include_directories(
  $ENV{BSIM_COMPONENTS_PATH}/libUtilv1/src/
  $ENV{BSIM_COMPONENTS_PATH}/libPhyComv1/src/
)
+36 −0
Original line number Diff line number Diff line
CONFIG_BT=y
CONFIG_BT_BROADCASTER=y
CONFIG_BT_OBSERVER=y
CONFIG_BT_EXT_ADV=y
CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
CONFIG_BT_DEVICE_NAME="Broadcaster Multiple"

# Zephyr Bluetooth LE Controller will need to use chain PDUs when AD data
# length > 191 bytes
# - 31 bytes will use 22 bytes for the default name in this sample plus 9 bytes
#   for manufacturer data
# - 191 bytes will use 22 bytes for the default name in this sample plus 169
#   bytes for manufacturer data
# - 277 bytes will use 22 bytes for the default name in this sample plus 255
#   bytes for manufacturer data
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=1650

# Increase Advertising PDU buffers to number of advertising sets times the
# number of chain PDUs per advertising set when using Zephyr Bluetooth LE
# Controller
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=2

# Maximum Extended Scanning buffer size
CONFIG_BT_EXT_SCAN_BUF_SIZE=1650

# Set maximum scan data length for Extended Scanning in Bluetooth LE Controller
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650

# Zephyr Bluetooth LE Controller needs 16 event buffers to generate Extended
# Advertising Report for receiving the complete 1650 bytes of data
CONFIG_BT_BUF_EVT_RX_COUNT=16

# Increase Zephyr Bluetooth LE Controller Rx buffer to receive complete chain
# of PDUs
CONFIG_BT_CTLR_RX_BUFFERS=9
+208 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stddef.h>

#include <zephyr/zephyr.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();
}
+39 −0
Original line number Diff line number Diff line
#!/usr/bin/env bash
# Copyright 2018 Oticon A/S
# SPDX-License-Identifier: Apache-2.0

# Validate Extended Advertising AD Data fragment operation, PDU chaining and
# Extended Scanning of chain PDUs
simulation_id="adv_chain"
verbosity_level=2
process_ids=""; exit_code=0

function Execute(){
  if [ ! -f $1 ]; then
    echo -e "  \e[91m`pwd`/`basename $1` cannot be found (did you forget to\
 compile it?)\e[39m"
    exit 1
  fi
  timeout 10 $@ & process_ids="$process_ids $!"
}

: "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}"

#Give a default value to BOARD if it does not have one yet:
BOARD="${BOARD:-nrf52_bsim}"

cd ${BSIM_OUT_PATH}/bin

Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_adv_chain_prj_conf \
  -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=adv

Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_adv_chain_prj_conf\
  -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=scan

Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
  -D=2 -sim_length=10e6 $@

for process_id in $process_ids; do
  wait $process_id || let "exit_code=$?"
done
exit $exit_code #the last exit code != 0
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ app=tests/bluetooth/bsim_bt/bsim_test_app conf_file=prj_split_low_lat.conf \
  compile
app=tests/bluetooth/bsim_bt/bsim_test_multiple compile
app=tests/bluetooth/bsim_bt/bsim_test_advx compile
app=tests/bluetooth/bsim_bt/bsim_test_adv_chain compile
app=tests/bluetooth/bsim_bt/bsim_test_gatt compile
app=tests/bluetooth/bsim_bt/bsim_test_gatt_write compile
app=tests/bluetooth/bsim_bt/bsim_test_l2cap compile