1 /* Copyright (c) 2023 Nordic Semiconductor ASA
2  * SPDX-License-Identifier: Apache-2.0
3  */
4 
5 #include <stddef.h>
6 #include <stdint.h>
7 #include <string.h>
8 #include <zephyr/bluetooth/bluetooth.h>
9 #include <zephyr/bluetooth/conn.h>
10 #include <zephyr/bluetooth/gap.h>
11 #include <zephyr/bluetooth/gatt.h>
12 #include <zephyr/bluetooth/l2cap.h>
13 #include <zephyr/bluetooth/uuid.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/sys/__assert.h>
16 
17 struct bt_testlib_adv_ctx {
18 	struct bt_conn **result;
19 	struct k_condvar done;
20 };
21 
22 /* Context pool (with capacity of one). */
23 static K_SEM_DEFINE(g_ctx_free, 1, 1);
24 static K_MUTEX_DEFINE(g_ctx_lock);
25 static struct bt_testlib_adv_ctx *g_ctx;
26 
connected_cb(struct bt_le_ext_adv * adv,struct bt_le_ext_adv_connected_info * info)27 static void connected_cb(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_connected_info *info)
28 {
29 	k_mutex_lock(&g_ctx_lock, K_FOREVER);
30 
31 	if (g_ctx->result) {
32 		*g_ctx->result = bt_conn_ref(info->conn);
33 	}
34 	k_condvar_signal(&g_ctx->done);
35 
36 	k_mutex_unlock(&g_ctx_lock);
37 }
38 
bt_testlib_adv_conn(struct bt_conn ** conn,int id,const char * name)39 int bt_testlib_adv_conn(struct bt_conn **conn, int id, const char *name)
40 {
41 	int api_err;
42 	struct bt_le_ext_adv *adv = NULL;
43 	struct bt_le_adv_param param = {};
44 	struct bt_testlib_adv_ctx ctx = {
45 		.result = conn,
46 	};
47 	static const struct bt_le_ext_adv_cb cb = {
48 		.connected = connected_cb,
49 	};
50 
51 	param.id = id;
52 	param.interval_min = BT_GAP_ADV_FAST_INT_MIN_1;
53 	param.interval_max = BT_GAP_ADV_FAST_INT_MAX_1;
54 	param.options |= BT_LE_ADV_OPT_CONN;
55 
56 	k_condvar_init(&ctx.done);
57 
58 	k_sem_take(&g_ctx_free, K_FOREVER);
59 	k_mutex_lock(&g_ctx_lock, K_FOREVER);
60 	g_ctx = &ctx;
61 
62 	api_err = bt_le_ext_adv_create(&param, &cb, &adv);
63 	if (!api_err && name != NULL) {
64 		struct bt_data ad;
65 
66 		ad.type = BT_DATA_NAME_COMPLETE;
67 		ad.data_len = strlen(name);
68 		ad.data = (const uint8_t *)name;
69 
70 		api_err = bt_le_ext_adv_set_data(adv, &ad, 1, NULL, 0);
71 	}
72 
73 	if (!api_err) {
74 		api_err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
75 	}
76 
77 	if (!api_err) {
78 		k_condvar_wait(&ctx.done, &g_ctx_lock, K_FOREVER);
79 	}
80 
81 	/* Delete adv before giving semaphore so that it's potentially available
82 	 * for the next taker of the semaphore.
83 	 */
84 	if (adv) {
85 		bt_le_ext_adv_delete(adv);
86 	}
87 
88 	g_ctx = NULL;
89 	k_mutex_unlock(&g_ctx_lock);
90 	k_sem_give(&g_ctx_free);
91 
92 	return api_err;
93 }
94