| /* |
| * Copyright (c) 2024 Croxel, Inc. |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/bluetooth/bluetooth.h> |
| #include <zephyr/bluetooth/gatt.h> |
| #include <zephyr/bluetooth/services/nus.h> |
| #include "nus_internal.h" |
| |
| ssize_t 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) |
| { |
| struct bt_nus_cb *listener = NULL; |
| struct bt_nus_inst *instance = NULL; |
| |
| instance = bt_nus_inst_get_from_attr(attr); |
| __ASSERT_NO_MSG(instance); |
| |
| SYS_SLIST_FOR_EACH_CONTAINER(instance->cbs, listener, _node) { |
| if (listener->received) { |
| listener->received(conn, buf, len, listener->ctx); |
| } |
| } |
| |
| return len; |
| } |
| |
| void nus_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) |
| { |
| struct bt_nus_cb *listener = NULL; |
| struct bt_nus_inst *instance = NULL; |
| |
| instance = bt_nus_inst_get_from_attr(attr); |
| __ASSERT_NO_MSG(instance); |
| |
| SYS_SLIST_FOR_EACH_CONTAINER(instance->cbs, listener, _node) { |
| if (listener->notif_enabled) { |
| listener->notif_enabled((value == 1), listener->ctx); |
| } |
| } |
| } |
| |
| int bt_nus_inst_cb_register(struct bt_nus_inst *instance, struct bt_nus_cb *cb, void *ctx) |
| { |
| if (!cb) { |
| return -EINVAL; |
| } |
| |
| if (!instance) { |
| if (IS_ENABLED(CONFIG_BT_NUS_DEFAULT_INSTANCE)) { |
| instance = bt_nus_inst_default(); |
| } else { |
| return -ENOTSUP; |
| } |
| } |
| |
| cb->ctx = ctx; |
| sys_slist_append(instance->cbs, &cb->_node); |
| |
| return 0; |
| } |
| |
| int bt_nus_inst_send(struct bt_conn *conn, |
| struct bt_nus_inst *instance, |
| const void *data, |
| uint16_t len) |
| { |
| if (!data || !len) { |
| return -EINVAL; |
| } |
| |
| if (!instance) { |
| if (IS_ENABLED(CONFIG_BT_NUS_DEFAULT_INSTANCE)) { |
| instance = bt_nus_inst_default(); |
| } else { |
| return -ENOTSUP; |
| } |
| } |
| |
| return bt_gatt_notify(conn, &instance->svc->attrs[1], data, len); |
| } |