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(¶ms, 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