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/att.h>
10 #include <zephyr/bluetooth/l2cap.h>
11 #include <zephyr/bluetooth/uuid.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/sys/__assert.h>
14
15 #include <zephyr/logging/log.h>
16 LOG_MODULE_REGISTER(bt_testlib_att_write, LOG_LEVEL_DBG);
17
18 struct bt_testlib_att_write_closure {
19 uint8_t att_err;
20 struct bt_gatt_write_params params;
21 struct k_mutex lock;
22 struct k_condvar done;
23 };
24
att_write_cb(struct bt_conn * conn,uint8_t att_err,struct bt_gatt_write_params * params)25 static void att_write_cb(struct bt_conn *conn, uint8_t att_err, struct bt_gatt_write_params *params)
26 {
27 struct bt_testlib_att_write_closure *ctx =
28 CONTAINER_OF(params, struct bt_testlib_att_write_closure, params);
29
30 k_mutex_lock(&ctx->lock, K_FOREVER);
31
32 ctx->att_err = att_err;
33
34 k_condvar_signal(&ctx->done);
35 k_mutex_unlock(&ctx->lock);
36 }
37
bt_testlib_att_write(struct bt_conn * conn,enum bt_att_chan_opt bearer,uint16_t handle,uint8_t * data,uint16_t size)38 int bt_testlib_att_write(struct bt_conn *conn, enum bt_att_chan_opt bearer, uint16_t handle,
39 uint8_t *data, uint16_t size)
40 {
41 int api_err;
42 struct bt_testlib_att_write_closure ctx_val = {.params = {
43 .handle = handle,
44 .offset = 0,
45 .func = att_write_cb,
46 .data = data,
47 .length = size,
48 }};
49 struct bt_testlib_att_write_closure *const ctx = &ctx_val;
50
51 k_mutex_init(&ctx->lock);
52 k_condvar_init(&ctx->done);
53
54 __ASSERT_NO_MSG(conn);
55 __ASSERT_NO_MSG(
56 IN_RANGE(handle, BT_ATT_FIRST_ATTRIBUTE_HANDLE, BT_ATT_LAST_ATTRIBUTE_HANDLE));
57
58 k_mutex_lock(&ctx->lock, K_FOREVER);
59
60 api_err = bt_gatt_write(conn, &ctx->params);
61
62 if (!api_err) {
63 k_condvar_wait(&ctx->done, &ctx->lock, K_FOREVER);
64 }
65
66 k_mutex_unlock(&ctx->lock);
67
68 if (api_err) {
69 __ASSERT_NO_MSG(api_err < 0);
70 return api_err;
71 }
72 __ASSERT_NO_MSG(ctx->att_err >= 0);
73 return ctx->att_err;
74 }
75