1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdbool.h>
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/bluetooth/bluetooth.h>
11 #include <zephyr/bluetooth/hci.h>
12 #include <zephyr/logging/log.h>
13 
14 #include "ad.h"
15 
16 #include "babblekit/flags.h"
17 #include "babblekit/testcase.h"
18 
19 LOG_MODULE_REGISTER(scanner, LOG_LEVEL_INF);
20 
21 DEFINE_FLAG(scan_received);
22 
data_parse_cb(struct bt_data * data,void * user_data)23 static bool data_parse_cb(struct bt_data *data, void *user_data)
24 {
25 	LOG_DBG("Type: %02x (size: %d)", data->type, data->data_len);
26 	LOG_HEXDUMP_DBG(data->data, data->data_len, "Data:");
27 
28 	return true;
29 }
30 
device_found(const bt_addr_le_t * addr,int8_t rssi,uint8_t type,struct net_buf_simple * ad)31 static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
32 			 struct net_buf_simple *ad)
33 {
34 	char addr_str[BT_ADDR_LE_STR_LEN];
35 
36 	bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
37 
38 	LOG_DBG("Device found: %s (RSSI %d)", addr_str, rssi);
39 
40 	if (ad->len > 0) {
41 		LOG_INF("Received AD of size %d", ad->len);
42 
43 		TEST_ASSERT(ad->len == ARRAY_SIZE(test_ad2),
44 			    "Received %d bytes of Advertising Data %d bytes were expected", ad->len,
45 			    ARRAY_SIZE(test_ad2));
46 
47 		if (memcmp(ad->data, test_ad2, ad->len) != 0) {
48 			LOG_HEXDUMP_ERR(ad->data, ad->len, "Received AD:");
49 			LOG_HEXDUMP_ERR(test_ad2, ARRAY_SIZE(test_ad2), "Expected AD:");
50 			TEST_FAIL("Received Advertising Data doesn't match expected ones");
51 		}
52 	}
53 
54 	bt_data_parse(ad, data_parse_cb, NULL);
55 
56 	SET_FLAG(scan_received);
57 }
58 
start_scan(void)59 static void start_scan(void)
60 {
61 	int err;
62 
63 	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
64 	if (err) {
65 		TEST_FAIL("Scanning failed to start (err %d)\n", err);
66 	}
67 
68 	LOG_DBG("Scanning successfully started");
69 }
70 
entrypoint_scanner(void)71 void entrypoint_scanner(void)
72 {
73 	/* Test purpose:
74 	 *
75 	 * Verifies that we can send Advertising Data up to the size set in the
76 	 * Kconfig. And if we try to set data too large we get the correct
77 	 * error code.
78 	 *
79 	 * Two devices:
80 	 * - `advertiser`: tries to send the data
81 	 * - `scanner`: will receive the data and check that they match with the
82 	 *   data sent
83 	 *
84 	 * Procedure:
85 	 * - [advertiser] try to use `test_ad1` as advertising data
86 	 * - [advertiser] get the expected error (adv or scan resp too large)
87 	 * - [advertiser] try to use `test_ad2` as advertising data
88 	 * - [advertiser] get a success
89 	 * - [advertiser] start advertiser
90 	 * - [scanner] start scanner
91 	 * - [scanner] wait until receiving advertising data matching `test_ad2`
92 	 *
93 	 * [verdict]
94 	 * - advertiser receives the correct error code when trying to set
95 	 *   advertising data
96 	 * - scanner receives the correct data in advertising data
97 	 */
98 	int err;
99 
100 	TEST_START("scanner");
101 
102 	err = bt_enable(NULL);
103 	TEST_ASSERT(err == 0, "Can't enable Bluetooth (err %d)", err);
104 
105 	LOG_DBG("Bluetooth initialized");
106 
107 	start_scan();
108 
109 	LOG_DBG("Wait until we receive at least one AD");
110 	WAIT_FOR_FLAG(scan_received);
111 
112 	TEST_PASS_AND_EXIT("scanner");
113 }
114