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(¶m, &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