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