1 /*
2  * Copyright (c) 2024 Croxel, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/bluetooth/bluetooth.h>
8 #include <zephyr/bluetooth/gatt.h>
9 #include <zephyr/bluetooth/services/nus.h>
10 #include "nus_internal.h"
11 
nus_bt_chr_write(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)12 ssize_t nus_bt_chr_write(struct bt_conn *conn, const struct bt_gatt_attr *attr,
13 	const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
14 {
15 	struct bt_nus_cb *listener = NULL;
16 	struct bt_nus_inst *instance = NULL;
17 
18 	instance = bt_nus_inst_get_from_attr(attr);
19 	__ASSERT_NO_MSG(instance);
20 
21 	SYS_SLIST_FOR_EACH_CONTAINER(instance->cbs, listener, _node) {
22 		if (listener->received) {
23 			listener->received(conn, buf, len, listener->ctx);
24 		}
25 	}
26 
27 	return len;
28 }
29 
nus_ccc_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)30 void nus_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
31 {
32 	struct bt_nus_cb *listener = NULL;
33 	struct bt_nus_inst *instance = NULL;
34 
35 	instance = bt_nus_inst_get_from_attr(attr);
36 	__ASSERT_NO_MSG(instance);
37 
38 	SYS_SLIST_FOR_EACH_CONTAINER(instance->cbs, listener, _node) {
39 		if (listener->notif_enabled) {
40 			listener->notif_enabled((value == 1), listener->ctx);
41 		}
42 	}
43 }
44 
bt_nus_inst_cb_register(struct bt_nus_inst * instance,struct bt_nus_cb * cb,void * ctx)45 int bt_nus_inst_cb_register(struct bt_nus_inst *instance, struct bt_nus_cb *cb, void *ctx)
46 {
47 	if (!cb) {
48 		return -EINVAL;
49 	}
50 
51 	if (!instance) {
52 		if (IS_ENABLED(CONFIG_BT_ZEPHYR_NUS_DEFAULT_INSTANCE)) {
53 			instance = bt_nus_inst_default();
54 		} else {
55 			return -ENOTSUP;
56 		}
57 	}
58 
59 	cb->ctx = ctx;
60 	sys_slist_append(instance->cbs, &cb->_node);
61 
62 	return 0;
63 }
64 
bt_nus_inst_send(struct bt_conn * conn,struct bt_nus_inst * instance,const void * data,uint16_t len)65 int bt_nus_inst_send(struct bt_conn *conn,
66 		     struct bt_nus_inst *instance,
67 		     const void *data,
68 		     uint16_t len)
69 {
70 	if (!data || !len) {
71 		return -EINVAL;
72 	}
73 
74 	if (!instance) {
75 		if (IS_ENABLED(CONFIG_BT_ZEPHYR_NUS_DEFAULT_INSTANCE)) {
76 			instance = bt_nus_inst_default();
77 		} else {
78 			return -ENOTSUP;
79 		}
80 	}
81 
82 	return bt_gatt_notify(conn, &instance->svc->attrs[1], data, len);
83 }
84