1 /* Bluetooth MICS
2 *
3 * Copyright (c) 2020 Bose Corporation
4 * Copyright (c) 2020-2022 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/sys/byteorder.h>
11 #include <zephyr/sys/check.h>
12
13 #include <zephyr/device.h>
14 #include <zephyr/init.h>
15
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/conn.h>
18 #include <zephyr/bluetooth/gatt.h>
19 #include <zephyr/bluetooth/audio/micp.h>
20 #include <zephyr/bluetooth/audio/aics.h>
21
22 #include "audio_internal.h"
23
24 #include <zephyr/logging/log.h>
25
26 LOG_MODULE_REGISTER(bt_micp, CONFIG_BT_MICP_MIC_DEV_LOG_LEVEL);
27
28 struct bt_micp_server {
29 uint8_t mute;
30 struct bt_micp_mic_dev_cb *cb;
31 struct bt_gatt_service *service_p;
32 struct bt_aics *aics_insts[CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT];
33 struct k_work_delayable notify_work;
34 };
35
36 static struct bt_micp_server micp_inst;
37
mute_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)38 static void mute_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
39 {
40 LOG_DBG("value 0x%04x", value);
41 }
42
read_mute(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)43 static ssize_t read_mute(struct bt_conn *conn,
44 const struct bt_gatt_attr *attr, void *buf,
45 uint16_t len, uint16_t offset)
46 {
47 LOG_DBG("Mute %u", micp_inst.mute);
48
49 return bt_gatt_attr_read(conn, attr, buf, len, offset,
50 &micp_inst.mute, sizeof(micp_inst.mute));
51 }
52
notify_work_handler(struct k_work * work)53 static void notify_work_handler(struct k_work *work)
54 {
55 struct k_work_delayable *d_work = k_work_delayable_from_work(work);
56 struct bt_micp_server *server = CONTAINER_OF(d_work, struct bt_micp_server, notify_work);
57 int err;
58
59 err = bt_gatt_notify_uuid(NULL, BT_UUID_MICS_MUTE, server->service_p->attrs, &server->mute,
60 sizeof(server->mute));
61 if (err == 0 || err == -ENOTCONN) {
62 return;
63 }
64
65 if (err == -ENOMEM &&
66 k_work_reschedule(d_work, K_USEC(BT_AUDIO_NOTIFY_RETRY_DELAY_US)) >= 0) {
67 LOG_WRN("Out of buffers for mute state notification. Will retry in %dms",
68 BT_AUDIO_NOTIFY_RETRY_DELAY_US);
69 return;
70 }
71
72 LOG_ERR("Mute state notification err %d", err);
73 }
74
write_mute(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)75 static ssize_t write_mute(struct bt_conn *conn, const struct bt_gatt_attr *attr,
76 const void *buf, uint16_t len, uint16_t offset,
77 uint8_t flags)
78 {
79 const uint8_t *val = buf;
80
81 if (offset > 0) {
82 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
83 }
84
85 if (len != sizeof(micp_inst.mute)) {
86 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
87 }
88
89 if ((conn != NULL && *val == BT_MICP_MUTE_DISABLED) ||
90 *val > BT_MICP_MUTE_DISABLED) {
91 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
92 }
93
94 if (conn != NULL && micp_inst.mute == BT_MICP_MUTE_DISABLED) {
95 return BT_GATT_ERR(BT_MICP_ERR_MUTE_DISABLED);
96 }
97
98 LOG_DBG("%u", *val);
99
100 if (*val != micp_inst.mute) {
101 int err;
102
103 micp_inst.mute = *val;
104
105 err = k_work_reschedule(&micp_inst.notify_work, K_NO_WAIT);
106 if (err < 0) {
107 LOG_ERR("Failed to schedule mute state notification err %d", err);
108 }
109
110 if (micp_inst.cb != NULL && micp_inst.cb->mute != NULL) {
111 micp_inst.cb->mute(micp_inst.mute);
112 }
113 }
114
115 return len;
116 }
117
118
119 #define DUMMY_INCLUDE(i, _) BT_GATT_INCLUDE_SERVICE(NULL),
120 #define AICS_INCLUDES(cnt) LISTIFY(cnt, DUMMY_INCLUDE, ())
121
122 #define BT_MICP_SERVICE_DEFINITION \
123 BT_GATT_PRIMARY_SERVICE(BT_UUID_MICS), \
124 AICS_INCLUDES(CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT) \
125 BT_AUDIO_CHRC(BT_UUID_MICS_MUTE, \
126 BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY, \
127 BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \
128 read_mute, write_mute, NULL), \
129 BT_AUDIO_CCC(mute_cfg_changed)
130
131 #define MICS_ATTR_COUNT \
132 ARRAY_SIZE(((struct bt_gatt_attr []){ BT_MICP_SERVICE_DEFINITION }))
133 #define MICS_INCL_COUNT (CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT)
134
135 static struct bt_gatt_attr mics_attrs[] = { BT_MICP_SERVICE_DEFINITION };
136 static struct bt_gatt_service mics_svc;
137
138 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
prepare_aics_inst(struct bt_micp_mic_dev_register_param * param)139 static int prepare_aics_inst(struct bt_micp_mic_dev_register_param *param)
140 {
141 int i;
142 int j;
143 int err;
144
145 if (CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT == 0) {
146 return 0;
147 }
148
149 for (j = 0, i = 0; i < ARRAY_SIZE(mics_attrs); i++) {
150 if (bt_uuid_cmp(mics_attrs[i].uuid, BT_UUID_GATT_INCLUDE) == 0) {
151 micp_inst.aics_insts[j] = bt_aics_free_instance_get();
152 if (micp_inst.aics_insts[j] == NULL) {
153 LOG_DBG("Could not get free AICS instances[%u]", j);
154 return -ENOMEM;
155 }
156
157 err = bt_aics_register(micp_inst.aics_insts[j],
158 ¶m->aics_param[j]);
159 if (err != 0) {
160 LOG_DBG("Could not register AICS instance[%u]: %d", j, err);
161 return err;
162 }
163
164 mics_attrs[i].user_data = bt_aics_svc_decl_get(micp_inst.aics_insts[j]);
165 j++;
166
167 if (j == CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT) {
168 break;
169 }
170 }
171 }
172
173 __ASSERT(j == CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT,
174 "Invalid AICS instance count");
175
176 return 0;
177 }
178 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
179
180 /****************************** PUBLIC API ******************************/
bt_micp_mic_dev_register(struct bt_micp_mic_dev_register_param * param)181 int bt_micp_mic_dev_register(struct bt_micp_mic_dev_register_param *param)
182 {
183 int err;
184 static bool registered;
185
186 if (registered) {
187 return -EALREADY;
188 }
189
190 __ASSERT(param, "MICS register parameter cannot be NULL");
191
192 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
193 err = prepare_aics_inst(param);
194 if (err != 0) {
195 LOG_DBG("Failed to prepare AICS instances: %d", err);
196
197 return err;
198 }
199 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
200
201 mics_svc = (struct bt_gatt_service)BT_GATT_SERVICE(mics_attrs);
202 micp_inst.service_p = &mics_svc;
203 err = bt_gatt_service_register(&mics_svc);
204
205 if (err != 0) {
206 LOG_ERR("MICS service register failed: %d", err);
207 }
208
209 micp_inst.cb = param->cb;
210
211 k_work_init_delayable(&micp_inst.notify_work, notify_work_handler);
212
213 registered = true;
214
215 return err;
216 }
217
bt_micp_mic_dev_mute_disable(void)218 int bt_micp_mic_dev_mute_disable(void)
219 {
220 uint8_t val = BT_MICP_MUTE_DISABLED;
221 int err;
222
223 err = write_mute(NULL, NULL, &val, sizeof(val), 0, 0);
224
225 return err > 0 ? 0 : err;
226 }
227
bt_micp_mic_dev_included_get(struct bt_micp_included * included)228 int bt_micp_mic_dev_included_get(struct bt_micp_included *included)
229 {
230 CHECKIF(included == NULL) {
231 LOG_DBG("NULL service pointer");
232 return -EINVAL;
233 }
234
235 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
236 included->aics_cnt = ARRAY_SIZE(micp_inst.aics_insts);
237 included->aics = micp_inst.aics_insts;
238 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
239
240 return 0;
241 }
242
bt_micp_mic_dev_unmute(void)243 int bt_micp_mic_dev_unmute(void)
244 {
245 const uint8_t val = BT_MICP_MUTE_UNMUTED;
246 const int err = write_mute(NULL, NULL, &val, sizeof(val), 0, 0);
247
248 return err > 0 ? 0 : err;
249 }
250
bt_micp_mic_dev_mute(void)251 int bt_micp_mic_dev_mute(void)
252 {
253 const uint8_t val = BT_MICP_MUTE_MUTED;
254 const int err = write_mute(NULL, NULL, &val, sizeof(val), 0, 0);
255
256 return err > 0 ? 0 : err;
257 }
258
bt_micp_mic_dev_mute_get(void)259 int bt_micp_mic_dev_mute_get(void)
260 {
261 if (micp_inst.cb && micp_inst.cb->mute) {
262 micp_inst.cb->mute(micp_inst.mute);
263 }
264
265 return 0;
266 }
267