1 /* btp_micp.c - Bluetooth MICP Tester */
2 
3 /*
4  * Copyright (c) 2023 Codecoup
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <stddef.h>
10 #include <errno.h>
11 #include <stdio.h>
12 
13 #include <zephyr/types.h>
14 #include <zephyr/kernel.h>
15 
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/audio/audio.h>
18 #include <zephyr/bluetooth/audio/micp.h>
19 #include <zephyr/bluetooth/audio/aics.h>
20 
21 #include <zephyr/logging/log.h>
22 #include <zephyr/sys/byteorder.h>
23 
24 #include <../../subsys/bluetooth/audio/micp_internal.h>
25 #include <../../subsys/bluetooth/audio/aics_internal.h>
26 
27 #include "bap_endpoint.h"
28 #include "btp/btp.h"
29 
30 #define LOG_MODULE_NAME bttester_micp
31 LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
32 
33 static struct bt_micp_mic_ctlr *mic_ctlr;
34 static struct bt_micp_mic_dev_register_param mic_dev_register_param;
35 
36 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
37 static struct bt_micp_included micp_included;
38 struct chrc_handles {
39 	uint16_t mute_handle;
40 	uint16_t state_handle;
41 	uint16_t gain_handle;
42 	uint16_t type_handle;
43 	uint16_t status_handle;
44 	uint16_t control_handle;
45 	uint16_t desc_handle;
46 };
47 struct chrc_handles micp_handles;
48 extern struct btp_aics_instance aics_client_instance;
49 extern struct bt_aics_cb aics_client_cb;
50 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
51 
52 /* Microphone Control Profile */
btp_send_micp_found_ev(struct bt_conn * conn,uint8_t att_status,const struct chrc_handles * micp_handles)53 static void btp_send_micp_found_ev(struct bt_conn *conn, uint8_t att_status,
54 				   const struct chrc_handles *micp_handles)
55 {
56 	struct btp_micp_discovered_ev ev;
57 
58 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
59 
60 	ev.att_status = att_status;
61 	ev.mute_handle = sys_cpu_to_le16(micp_handles->mute_handle);
62 	ev.state_handle = sys_cpu_to_le16(micp_handles->state_handle);
63 	ev.gain_handle = sys_cpu_to_le16(micp_handles->gain_handle);
64 	ev.type_handle = sys_cpu_to_le16(micp_handles->type_handle);
65 	ev.status_handle = sys_cpu_to_le16(micp_handles->status_handle);
66 	ev.control_handle = sys_cpu_to_le16(micp_handles->control_handle);
67 	ev.desc_handle = sys_cpu_to_le16(micp_handles->desc_handle);
68 
69 	tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_DISCOVERED_EV, &ev, sizeof(ev));
70 }
71 
btp_send_micp_mute_state_ev(struct bt_conn * conn,uint8_t att_status,uint8_t mute)72 static void btp_send_micp_mute_state_ev(struct bt_conn *conn, uint8_t att_status, uint8_t mute)
73 {
74 	struct btp_micp_mute_state_ev ev;
75 
76 	bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
77 
78 	ev.att_status = att_status;
79 	ev.mute = mute;
80 
81 	tester_event(BTP_SERVICE_ID_MICP, BTP_MICP_MUTE_STATE_EV, &ev, sizeof(ev));
82 }
83 
micp_mic_ctlr_mute_cb(struct bt_micp_mic_ctlr * mic_ctlr,int err,uint8_t mute)84 static void micp_mic_ctlr_mute_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err, uint8_t mute)
85 {
86 	struct bt_conn *conn;
87 
88 	bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn);
89 	btp_send_micp_mute_state_ev(conn, err, mute);
90 
91 	LOG_DBG("MICP Mute cb (%d)", err);
92 }
93 
micp_mic_ctlr_mute_written_cb(struct bt_micp_mic_ctlr * mic_ctlr,int err)94 static void micp_mic_ctlr_mute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err)
95 {
96 	struct bt_conn *conn;
97 	uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr);
98 
99 	bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn);
100 	btp_send_micp_mute_state_ev(conn, err, mute_state);
101 
102 	LOG_DBG("MICP Mute Written cb (%d))", err);
103 }
104 
micp_mic_ctlr_unmute_written_cb(struct bt_micp_mic_ctlr * mic_ctlr,int err)105 static void micp_mic_ctlr_unmute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err)
106 {
107 	struct bt_conn *conn;
108 	uint8_t mute_state = bt_micp_mic_ctlr_mute_get(mic_ctlr);
109 
110 	bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn);
111 	btp_send_micp_mute_state_ev(conn, err, mute_state);
112 
113 	LOG_DBG("MICP Mute Unwritten cb (%d))", err);
114 }
115 
micp_mic_ctlr_discover_cb(struct bt_micp_mic_ctlr * mic_ctlr,int err,uint8_t aics_count)116 static void micp_mic_ctlr_discover_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err,
117 				      uint8_t aics_count)
118 {
119 	struct bt_conn *conn;
120 
121 	if (err) {
122 		LOG_DBG("Discovery failed (%d)", err);
123 		return;
124 	}
125 
126 	LOG_DBG("Discovery done with %u AICS",
127 		aics_count);
128 
129 	bt_micp_mic_ctlr_conn_get(mic_ctlr, &conn);
130 
131 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
132 	if (bt_micp_mic_ctlr_included_get(mic_ctlr, &micp_included) != 0) {
133 		LOG_DBG("Could not get included services");
134 		memset(&micp_handles, 0, sizeof(micp_handles));
135 	} else {
136 		aics_client_instance.aics_cnt = micp_included.aics_cnt;
137 		aics_client_instance.aics = micp_included.aics;
138 		bt_aics_client_cb_register(aics_client_instance.aics[0], &aics_client_cb);
139 
140 		micp_handles.state_handle = micp_included.aics[0]->cli.state_handle;
141 		micp_handles.gain_handle = micp_included.aics[0]->cli.gain_handle;
142 		micp_handles.type_handle = micp_included.aics[0]->cli.type_handle;
143 		micp_handles.status_handle = micp_included.aics[0]->cli.status_handle;
144 		micp_handles.control_handle = micp_included.aics[0]->cli.control_handle;
145 		micp_handles.desc_handle = micp_included.aics[0]->cli.desc_handle;
146 	}
147 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
148 
149 	micp_handles.mute_handle = mic_ctlr->mute_handle;
150 	btp_send_micp_found_ev(conn, err, &micp_handles);
151 }
152 
153 static struct bt_micp_mic_ctlr_cb micp_cbs = {
154 	.discover = micp_mic_ctlr_discover_cb,
155 	.mute = micp_mic_ctlr_mute_cb,
156 	.mute_written = micp_mic_ctlr_mute_written_cb,
157 	.unmute_written = micp_mic_ctlr_unmute_written_cb,
158 };
159 
micp_supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)160 static uint8_t micp_supported_commands(const void *cmd, uint16_t cmd_len, void *rsp,
161 				       uint16_t *rsp_len)
162 {
163 	struct btp_micp_read_supported_commands_rp *rp = rsp;
164 
165 	/* octet 0 */
166 	tester_set_bit(rp->data, BTP_MICP_READ_SUPPORTED_COMMANDS);
167 	tester_set_bit(rp->data, BTP_MICP_CTLR_DISCOVER);
168 	tester_set_bit(rp->data, BTP_MICP_CTLR_MUTE_READ);
169 	tester_set_bit(rp->data, BTP_MICP_CTLR_MUTE);
170 
171 	*rsp_len = sizeof(*rp) + 1;
172 
173 	return BTP_STATUS_SUCCESS;
174 }
175 
micp_discover(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)176 static uint8_t micp_discover(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
177 {
178 	const struct btp_micp_discover_cmd *cp = cmd;
179 	struct bt_conn *conn;
180 	int err;
181 
182 	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
183 	if (!conn) {
184 		LOG_ERR("Unknown connection");
185 		return BTP_STATUS_FAILED;
186 	}
187 
188 	err = bt_micp_mic_ctlr_discover(conn, &mic_ctlr);
189 	if (err) {
190 		LOG_DBG("Fail: %d", err);
191 		return BTP_STATUS_FAILED;
192 	}
193 
194 	return BTP_STATUS_SUCCESS;
195 }
196 
micp_mute_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)197 static uint8_t micp_mute_read(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
198 {
199 	int err;
200 
201 	LOG_DBG("Read mute");
202 
203 	err = bt_micp_mic_ctlr_mute_get(mic_ctlr);
204 	if (err) {
205 		return BTP_STATUS_FAILED;
206 	}
207 
208 	return BTP_STATUS_SUCCESS;
209 }
210 
micp_mute(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)211 static uint8_t micp_mute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
212 {
213 	int err;
214 
215 	LOG_DBG("MICP Mute");
216 
217 	err = bt_micp_mic_ctlr_mute(mic_ctlr);
218 	if (err) {
219 		return BTP_STATUS_FAILED;
220 	}
221 
222 	return BTP_STATUS_SUCCESS;
223 }
224 
225 static const struct btp_handler micp_handlers[] = {
226 	{
227 		.opcode = BTP_MICP_READ_SUPPORTED_COMMANDS,
228 		.index = BTP_INDEX_NONE,
229 		.expect_len = 0,
230 		.func = micp_supported_commands,
231 	},
232 	{
233 		.opcode = BTP_MICP_CTLR_DISCOVER,
234 		.expect_len = sizeof(struct btp_micp_discover_cmd),
235 		.func = micp_discover,
236 	},
237 	{
238 		.opcode = BTP_MICP_CTLR_MUTE_READ,
239 		.expect_len = sizeof(struct btp_micp_mute_read_cmd),
240 		.func = micp_mute_read,
241 	},
242 	{
243 		.opcode = BTP_MICP_CTLR_MUTE,
244 		.expect_len = sizeof(struct btp_micp_mute_cmd),
245 		.func = micp_mute,
246 	},
247 };
248 
tester_init_micp(void)249 uint8_t tester_init_micp(void)
250 {
251 	int err;
252 
253 	err = bt_micp_mic_ctlr_cb_register(&micp_cbs);
254 
255 	if (err) {
256 		LOG_DBG("Failed to register callbacks: %d", err);
257 		return BTP_STATUS_FAILED;
258 	}
259 
260 	tester_register_command_handlers(BTP_SERVICE_ID_MICP, micp_handlers,
261 					 ARRAY_SIZE(micp_handlers));
262 
263 	return BTP_STATUS_SUCCESS;
264 }
265 
tester_unregister_micp(void)266 uint8_t tester_unregister_micp(void)
267 {
268 	(void)bt_micp_mic_ctlr_cb_register(NULL);
269 	return BTP_STATUS_SUCCESS;
270 }
271 
272 /* Microphone Control Service */
mics_supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)273 static uint8_t mics_supported_commands(const void *cmd, uint16_t cmd_len, void *rsp,
274 				       uint16_t *rsp_len)
275 {
276 	struct btp_mics_read_supported_commands_rp *rp = rsp;
277 
278 	/* octet 0 */
279 	tester_set_bit(rp->data, BTP_MICS_READ_SUPPORTED_COMMANDS);
280 	tester_set_bit(rp->data, BTP_MICS_DEV_MUTE_DISABLE);
281 	tester_set_bit(rp->data, BTP_MICS_DEV_MUTE_READ);
282 	tester_set_bit(rp->data, BTP_MICS_DEV_MUTE);
283 	tester_set_bit(rp->data, BTP_MICS_DEV_UNMUTE);
284 
285 	*rsp_len = sizeof(*rp) + 1;
286 
287 	return BTP_STATUS_SUCCESS;
288 }
289 
mics_mute_disable(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)290 static uint8_t mics_mute_disable(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
291 {
292 	int err;
293 
294 	LOG_DBG("MICP Mute disable");
295 
296 	err = bt_micp_mic_dev_mute_disable();
297 	if (err) {
298 		return BTP_STATUS_FAILED;
299 	}
300 
301 	return BTP_STATUS_SUCCESS;
302 }
303 
mics_mute_read(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)304 static uint8_t mics_mute_read(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
305 {
306 	int err;
307 
308 	LOG_DBG("MICS Mute state read");
309 
310 	err = bt_micp_mic_dev_mute_get();
311 	if (err) {
312 		return BTP_STATUS_FAILED;
313 	}
314 
315 	return BTP_STATUS_SUCCESS;
316 }
317 
mics_mute(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)318 static uint8_t mics_mute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
319 {
320 	int err;
321 
322 	LOG_DBG("MICS Mute");
323 
324 	err = bt_micp_mic_dev_mute();
325 	if (err) {
326 		return BTP_STATUS_FAILED;
327 	}
328 
329 	return BTP_STATUS_SUCCESS;
330 }
331 
mics_unmute(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)332 static uint8_t mics_unmute(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
333 {
334 	int err;
335 
336 	LOG_DBG("MICS Mute");
337 
338 	err = bt_micp_mic_dev_unmute();
339 	if (err) {
340 		return BTP_STATUS_FAILED;
341 	}
342 
343 	return BTP_STATUS_SUCCESS;
344 }
345 
btp_send_mics_mute_state_ev(uint8_t mute)346 static void btp_send_mics_mute_state_ev(uint8_t mute)
347 {
348 	struct btp_mics_mute_state_ev ev;
349 
350 	ev.mute = mute;
351 
352 	tester_event(BTP_SERVICE_ID_MICS, BTP_MICS_MUTE_STATE_EV, &ev, sizeof(ev));
353 }
354 
mic_dev_mute_cb(uint8_t mute)355 static void mic_dev_mute_cb(uint8_t mute)
356 {
357 	LOG_DBG("Microphone Device Mute cb");
358 
359 	btp_send_mics_mute_state_ev(mute);
360 }
361 
362 static struct bt_micp_mic_dev_cb mic_dev_cb = {
363 	.mute = mic_dev_mute_cb,
364 };
365 
366 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
aics_state_cb(struct bt_aics * inst,int err,int8_t gain,uint8_t mute,uint8_t mode)367 static void aics_state_cb(struct bt_aics *inst, int err, int8_t gain,
368 			  uint8_t mute, uint8_t mode)
369 {
370 	LOG_DBG("AICS state callback (%d)", err);
371 }
372 
aics_gain_setting_cb(struct bt_aics * inst,int err,uint8_t units,int8_t minimum,int8_t maximum)373 static void aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units,
374 				 int8_t minimum, int8_t maximum)
375 {
376 	LOG_DBG("AICS gain setting callback (%d)", err);
377 }
378 
aics_input_type_cb(struct bt_aics * inst,int err,uint8_t input_type)379 static void aics_input_type_cb(struct bt_aics *inst, int err,
380 			       uint8_t input_type)
381 {
382 	LOG_DBG("AICS input type callback (%d)", err);
383 }
384 
aics_status_cb(struct bt_aics * inst,int err,bool active)385 static void aics_status_cb(struct bt_aics *inst, int err, bool active)
386 {
387 	LOG_DBG("AICS status callback (%d)", err);
388 }
389 
aics_description_cb(struct bt_aics * inst,int err,char * description)390 static void aics_description_cb(struct bt_aics *inst, int err,
391 				char *description)
392 {
393 	LOG_DBG("AICS description callback (%d)", err);
394 }
395 
396 struct bt_aics_cb aics_mic_dev_cb = {
397 	.state = aics_state_cb,
398 	.gain_setting = aics_gain_setting_cb,
399 	.type = aics_input_type_cb,
400 	.status = aics_status_cb,
401 	.description = aics_description_cb,
402 };
403 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
404 
405 static const struct btp_handler mics_handlers[] = {
406 	{
407 		.opcode = BTP_MICS_READ_SUPPORTED_COMMANDS,
408 		.index = BTP_INDEX_NONE,
409 		.expect_len = 0,
410 		.func = mics_supported_commands,
411 	},
412 	{
413 		.opcode = BTP_MICS_DEV_MUTE_DISABLE,
414 		.expect_len = 0,
415 		.func = mics_mute_disable,
416 	},
417 	{
418 		.opcode = BTP_MICS_DEV_MUTE_READ,
419 		.expect_len = 0,
420 		.func = mics_mute_read,
421 	},
422 	{
423 		.opcode = BTP_MICS_DEV_MUTE,
424 		.expect_len = 0,
425 		.func = mics_mute,
426 	},
427 	{
428 		.opcode = BTP_MICS_DEV_UNMUTE,
429 		.expect_len = 0,
430 		.func = mics_unmute,
431 	},
432 };
433 
tester_init_mics(void)434 uint8_t tester_init_mics(void)
435 {
436 	int err;
437 
438 	memset(&mic_dev_register_param, 0, sizeof(mic_dev_register_param));
439 
440 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
441 	char input_desc[CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT][16];
442 
443 	for (size_t i = 0; i < ARRAY_SIZE(mic_dev_register_param.aics_param); i++) {
444 		mic_dev_register_param.aics_param[i].desc_writable = true;
445 		snprintf(input_desc[i], sizeof(input_desc[i]),
446 			 "Input %zu", i + 1);
447 		mic_dev_register_param.aics_param[i].description = input_desc[i];
448 		mic_dev_register_param.aics_param[i].type = BT_AICS_INPUT_TYPE_DIGITAL;
449 		mic_dev_register_param.aics_param[i].status = 1;
450 		mic_dev_register_param.aics_param[i].gain_mode = BT_AICS_MODE_MANUAL;
451 		mic_dev_register_param.aics_param[i].units = 1;
452 		mic_dev_register_param.aics_param[i].min_gain = 0;
453 		mic_dev_register_param.aics_param[i].max_gain = 100;
454 		mic_dev_register_param.aics_param[i].cb = &aics_mic_dev_cb;
455 	}
456 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
457 
458 	mic_dev_register_param.cb = &mic_dev_cb;
459 
460 	err = bt_micp_mic_dev_register(&mic_dev_register_param);
461 	if (err) {
462 		return BTP_STATUS_FAILED;
463 	}
464 
465 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
466 	err = bt_micp_mic_dev_included_get(&micp_included);
467 	if (err) {
468 		return BTP_STATUS_FAILED;
469 	}
470 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
471 
472 	tester_register_command_handlers(BTP_SERVICE_ID_MICS, mics_handlers,
473 					 ARRAY_SIZE(mics_handlers));
474 
475 	return BTP_STATUS_SUCCESS;
476 }
477 
tester_unregister_mics(void)478 uint8_t tester_unregister_mics(void)
479 {
480 	return BTP_STATUS_SUCCESS;
481 }
482