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