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