1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "bs_bt_utils.h"
8 #include <zephyr/bluetooth/addr.h>
9 #include <zephyr/bluetooth/conn.h>
10 #include <stdint.h>
11 #include <zephyr/bluetooth/bluetooth.h>
12 
13 #include "common/bt_str.h"
14 
15 #define EXPECTED_NUM_ROTATIONS 5
16 
17 #include <zephyr/logging/log.h>
18 LOG_MODULE_REGISTER(tester, 4);
19 
20 struct test_data_t {
21 	bool		id_addr_ok;
22 	bt_addr_le_t	old_addr;
23 	int64_t		old_time;
24 	int		rpa_rotations;
25 	bool            addr_set;
26 } static test_data;
27 
28 extern bt_addr_le_t dut_addr;
29 
print_address(const bt_addr_le_t * addr)30 void print_address(const bt_addr_le_t *addr)
31 {
32 	char array[BT_ADDR_LE_STR_LEN];
33 
34 	bt_addr_le_to_str(addr, array, sizeof(array));
35 	LOG_DBG("Address : %s", array);
36 }
37 
cb_expect_rpa(const bt_addr_le_t * addr,int8_t rssi,uint8_t type,struct net_buf_simple * ad)38 static void cb_expect_rpa(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
39 			  struct net_buf_simple *ad)
40 {
41 	int64_t diff_ms, rpa_timeout_ms;
42 
43 	if (bt_addr_le_eq(addr, &dut_addr)) {
44 		FAIL("DUT used identity addr instead of RPA\n");
45 	}
46 
47 	/* Only save the address + time if this is the first scan */
48 	if (bt_addr_le_eq(&test_data.old_addr, BT_ADDR_LE_ANY)) {
49 		bt_addr_le_copy(&test_data.old_addr, addr);
50 		test_data.old_time = k_uptime_get();
51 		return;
52 	}
53 
54 	/* Compare old and new address */
55 	if (bt_addr_le_eq(&test_data.old_addr, addr)) {
56 		return;
57 	}
58 	test_data.addr_set = true;
59 	LOG_DBG("Old ");
60 	print_address(&test_data.old_addr);
61 	LOG_DBG("New ");
62 	print_address(addr);
63 
64 	test_data.rpa_rotations++;
65 
66 	/* Ensure the RPA rotation occurs within +-10% of CONFIG_BT_RPA_TIMEOUT */
67 	diff_ms = k_uptime_get() - test_data.old_time;
68 	rpa_timeout_ms = CONFIG_BT_RPA_TIMEOUT * MSEC_PER_SEC;
69 
70 	if (abs(diff_ms - rpa_timeout_ms) > (rpa_timeout_ms / 10)) {
71 		FAIL("RPA rotation did not occur within +-10% of CONFIG_BT_RPA_TIMEOUT\n");
72 	}
73 
74 	bt_addr_le_copy(&test_data.old_addr, addr);
75 	test_data.old_time = k_uptime_get();
76 
77 	if (test_data.rpa_rotations > EXPECTED_NUM_ROTATIONS) {
78 		PASS("PASS\n");
79 	}
80 }
81 
cb_expect_id(const bt_addr_le_t * addr,int8_t rssi,uint8_t type,struct net_buf_simple * ad)82 static void cb_expect_id(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
83 			 struct net_buf_simple *ad)
84 {
85 	LOG_DBG("expecting addr:");
86 	print_address(&dut_addr);
87 	LOG_DBG("got addr:");
88 	print_address(addr);
89 
90 	if (addr->type != BT_ADDR_LE_RANDOM) {
91 		FAIL("Expected public address (0x%x) got 0x%x\n",
92 		     BT_ADDR_LE_RANDOM, addr->type);
93 	}
94 
95 	if (!bt_addr_le_eq(&dut_addr, addr)) {
96 		FAIL("DUT not using identity address\n");
97 	}
98 }
99 
scan_cb(const bt_addr_le_t * addr,int8_t rssi,uint8_t type,struct net_buf_simple * ad)100 static void scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, struct net_buf_simple *ad)
101 {
102 	/* The DUT advertises with the identity address first, to test
103 	 * that option, but also to allow the DUT time to start its
104 	 * scanner. The scanner must be ready to capture the one of
105 	 * first RPA advertisements to accurately judge the RPA
106 	 * timeout, which is measured from the first RPA advertisement.
107 	 */
108 	if (!test_data.id_addr_ok) {
109 		cb_expect_id(addr, rssi, type, ad);
110 
111 		/* Tell DUT to switch to RPA */
112 		backchannel_sync_send();
113 		test_data.id_addr_ok = true;
114 	} else {
115 		cb_expect_rpa(addr, rssi, type, ad);
116 	}
117 }
118 
tester_procedure(void)119 void tester_procedure(void)
120 {
121 	int err;
122 
123 	/* open a backchannel to the peer */
124 	backchannel_init(PERIPHERAL_SIM_ID);
125 
126 	err = bt_enable(NULL);
127 	if (err) {
128 		FAIL("Failed to enable bluetooth (err %d\n)", err);
129 	}
130 
131 	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE_CONTINUOUS, scan_cb);
132 
133 	if (err) {
134 		FAIL("Failed to start scanning\n");
135 	}
136 }
137