blob: d511202c4506ebe91b0db98af6abc5e66d05d1c6 [file] [log] [blame]
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "bs_bt_utils.h"
#include <stdint.h>
#include <string.h>
#include <zephyr/bluetooth/addr.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/toolchain/gcc.h>
DEFINE_FLAG(flag_new_address);
void scanned_cb(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_scanned_info *info)
{
static bool init;
static int64_t old_time;
static bt_addr_le_t old_addr;
bt_addr_le_t new_addr;
if (bst_result == Passed) {
return;
}
if (!init) {
old_addr = *info->addr;
old_time = k_uptime_get();
init = true;
}
new_addr = *info->addr;
/* Check if the scan request comes from a new address */
if (bt_addr_le_cmp(&old_addr, &new_addr)) {
int64_t new_time, diff, time_diff_ms, rpa_timeout_ms;
printk("Scanned request from new ");
print_address(info->addr);
/* Ensure the RPA rotation occurs within +-10% of CONFIG_BT_RPA_TIMEOUT */
new_time = k_uptime_get();
time_diff_ms = new_time - old_time;
rpa_timeout_ms = CONFIG_BT_RPA_TIMEOUT * MSEC_PER_SEC;
if (time_diff_ms > rpa_timeout_ms) {
diff = time_diff_ms - rpa_timeout_ms;
} else {
diff = rpa_timeout_ms - time_diff_ms;
}
if (diff > rpa_timeout_ms * 0.10) {
FAIL("RPA rotation did not occur within +-10%% of CONFIG_BT_RPA_TIMEOUT");
}
old_time = new_time;
SET_FLAG(flag_new_address);
}
old_addr = new_addr;
}
static struct bt_le_ext_adv_cb adv_callbacks = {
.scanned = scanned_cb,
};
void start_advertising(void)
{
int err;
uint8_t mfg_data[] = {0xAB, 0xCD, 0xEF};
const struct bt_data sd[] = {BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, 3)};
struct bt_le_adv_param params;
struct bt_le_ext_adv_start_param start_params;
struct bt_le_ext_adv *adv;
/* Enable bluetooth */
err = bt_enable(NULL);
if (err) {
FAIL("Failed to enable bluetooth (err %d\n)", err);
}
/* Create advertising set */
params.id = BT_ID_DEFAULT;
params.sid = 0;
params.secondary_max_skip = 0;
params.options = BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_SCANNABLE |
BT_LE_ADV_OPT_NOTIFY_SCAN_REQ | BT_LE_ADV_OPT_USE_NAME;
params.interval_min = BT_GAP_ADV_FAST_INT_MIN_1;
params.interval_max = BT_GAP_ADV_FAST_INT_MAX_1;
params.peer = NULL;
err = bt_le_ext_adv_create(&params, &adv_callbacks, &adv);
if (err) {
FAIL("Failed to create advertising set (err %d)\n", err);
}
/* Set scan data */
err = bt_le_ext_adv_set_data(adv, NULL, 0, sd, ARRAY_SIZE(sd));
if (err) {
FAIL("Failed to set advertising data (err %d)", err);
}
/* Start advertising */
start_params.timeout = 0;
start_params.num_events = 0;
err = bt_le_ext_adv_start(adv, &start_params);
if (err) {
FAIL("Failed to start advertising (err %d)\n", err);
}
}
void tester_procedure(void)
{
start_advertising();
for (int i = 0; i < 5; i++) {
WAIT_FOR_FLAG(flag_new_address);
UNSET_FLAG(flag_new_address);
}
PASS("PASS\n");
}