1 /**
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 
9 #include <zephyr/bluetooth/gap.h>
10 #include <zephyr/bluetooth/conn.h>
11 #include <zephyr/bluetooth/bluetooth.h>
12 #include <zephyr/bluetooth/hci_types.h>
13 
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(test_utils, LOG_LEVEL_DBG);
16 
17 #include "bs_bt_utils.h"
18 
19 struct bt_conn *g_conn;
20 DEFINE_FLAG(flag_is_connected);
21 
wait_connected(void)22 void wait_connected(void)
23 {
24 	LOG_DBG("Wait for connection...");
25 	WAIT_FOR_FLAG(flag_is_connected);
26 }
27 
wait_disconnected(void)28 void wait_disconnected(void)
29 {
30 	LOG_DBG("Wait for disconnection...");
31 	WAIT_FOR_FLAG_UNSET(flag_is_connected);
32 }
33 
security_changed(struct bt_conn * conn,bt_security_t level,enum bt_security_err err)34 static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err)
35 {
36 	LOG_DBG("security changed");
37 }
38 
disconnected(struct bt_conn * conn,uint8_t reason)39 static void disconnected(struct bt_conn *conn, uint8_t reason)
40 {
41 	UNSET_FLAG(flag_is_connected);
42 }
43 
get_g_conn(void)44 struct bt_conn *get_g_conn(void)
45 {
46 	return g_conn;
47 }
48 
clear_g_conn(void)49 void clear_g_conn(void)
50 {
51 	struct bt_conn *conn;
52 
53 	conn = g_conn;
54 	g_conn = NULL;
55 	BSIM_ASSERT(conn, "Test error: no g_conn!\n");
56 	bt_conn_unref(conn);
57 }
58 
connected(struct bt_conn * conn,uint8_t err)59 static void connected(struct bt_conn *conn, uint8_t err)
60 {
61 	BSIM_ASSERT((!g_conn || (conn == g_conn)), "Unexpected new connection.");
62 
63 	if (!g_conn) {
64 		g_conn = bt_conn_ref(conn);
65 	}
66 
67 	if (err != 0) {
68 		clear_g_conn();
69 		return;
70 	}
71 
72 	SET_FLAG(flag_is_connected);
73 }
74 
75 BT_CONN_CB_DEFINE(conn_callbacks) = {
76 	.connected = connected,
77 	.disconnected = disconnected,
78 	.security_changed = security_changed,
79 };
80 
stop_scan_and_connect(const bt_addr_le_t * addr,int8_t rssi,uint8_t type,struct net_buf_simple * ad)81 static void stop_scan_and_connect(const bt_addr_le_t *addr,
82 				  int8_t rssi,
83 				  uint8_t type,
84 				  struct net_buf_simple *ad)
85 {
86 	char addr_str[BT_ADDR_LE_STR_LEN];
87 	int err;
88 
89 	if (g_conn != NULL) {
90 		return;
91 	}
92 
93 	bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
94 	printk("Got scan result, connecting.. dst %s, RSSI %d\n", addr_str, rssi);
95 
96 	err = bt_le_scan_stop();
97 	BSIM_ASSERT(!err, "Err bt_le_scan_stop %d", err);
98 
99 	err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, &g_conn);
100 	BSIM_ASSERT(!err, "Err bt_conn_le_create %d", err);
101 }
102 
scan_connect_to_first_result(void)103 void scan_connect_to_first_result(void)
104 {
105 	int err;
106 
107 	err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, stop_scan_and_connect);
108 	BSIM_ASSERT(!err, "Err bt_le_scan_start %d", err);
109 }
110 
disconnect(void)111 void disconnect(void)
112 {
113 	int err;
114 
115 	err = bt_conn_disconnect(g_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
116 	BSIM_ASSERT(!err, "bt_conn_disconnect failed (%d)\n", err);
117 }
118 
set_security(bt_security_t sec)119 void set_security(bt_security_t sec)
120 {
121 	int err;
122 
123 	err = bt_conn_set_security(g_conn, sec);
124 	BSIM_ASSERT(!err, "Err bt_conn_set_security %d", err);
125 }
126 
create_adv(struct bt_le_ext_adv ** adv)127 void create_adv(struct bt_le_ext_adv **adv)
128 {
129 	int err;
130 	struct bt_le_adv_param params = {};
131 
132 	params.options |= BT_LE_ADV_OPT_CONN;
133 	params.options |= BT_LE_ADV_OPT_EXT_ADV;
134 
135 	params.id = BT_ID_DEFAULT;
136 	params.sid = 0;
137 	params.interval_min = BT_GAP_ADV_FAST_INT_MIN_2;
138 	params.interval_max = BT_GAP_ADV_FAST_INT_MAX_2;
139 
140 	err = bt_le_ext_adv_create(&params, NULL, adv);
141 	BSIM_ASSERT(!err, "bt_le_ext_adv_create failed (%d)\n", err);
142 }
143 
start_adv(struct bt_le_ext_adv * adv)144 void start_adv(struct bt_le_ext_adv *adv)
145 {
146 	int err;
147 
148 	err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
149 	BSIM_ASSERT(!err, "bt_le_ext_adv_start failed (%d)\n", err);
150 }
151 
stop_adv(struct bt_le_ext_adv * adv)152 void stop_adv(struct bt_le_ext_adv *adv)
153 {
154 	int err;
155 
156 	err = bt_le_ext_adv_stop(adv);
157 	BSIM_ASSERT(!err, "bt_le_ext_adv_stop failed (%d)\n", err);
158 }
159 
160 /* The following flags are raised by events and lowered by test code. */
161 DEFINE_FLAG(flag_pairing_complete);
162 DEFINE_FLAG(flag_bonded);
163 DEFINE_FLAG(flag_not_bonded);
164 
pairing_complete(struct bt_conn * conn,bool bonded)165 void pairing_complete(struct bt_conn *conn, bool bonded)
166 {
167 	LOG_DBG("pairing complete");
168 	SET_FLAG(flag_pairing_complete);
169 
170 	if (bonded) {
171 		SET_FLAG(flag_bonded);
172 		LOG_DBG("Bonded status: true");
173 	} else {
174 		SET_FLAG(flag_not_bonded);
175 		LOG_DBG("Bonded status: false");
176 	}
177 }
178 
pairing_failed(struct bt_conn * conn,enum bt_security_err err)179 void pairing_failed(struct bt_conn *conn, enum bt_security_err err)
180 {
181 	FAIL("Pairing failed\n");
182 }
183