1 /* csip.c - CAP Commander specific MICP mocks */
2 
3 /*
4  * Copyright (c) 2023 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 #include <errno.h>
9 #include <stddef.h>
10 #include <string.h>
11 
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/audio/aics.h>
14 #include <zephyr/bluetooth/audio/micp.h>
15 #include <zephyr/bluetooth/conn.h>
16 #include <zephyr/sys/__assert.h>
17 #include <zephyr/sys/util.h>
18 #include <zephyr/sys/util_macro.h>
19 
20 static struct bt_micp_mic_ctlr_cb *micp_cb;
21 
22 static struct bt_micp_mic_ctlr {
23 	struct bt_conn *conn;
24 	struct bt_aics *aics[CONFIG_BT_MICP_MIC_CTLR_MAX_AICS_INST];
25 } mic_ctlrs[CONFIG_BT_MAX_CONN];
26 
bt_micp_mic_ctlr_get_by_conn(const struct bt_conn * conn)27 struct bt_micp_mic_ctlr *bt_micp_mic_ctlr_get_by_conn(const struct bt_conn *conn)
28 {
29 	for (size_t i = 0; i < ARRAY_SIZE(mic_ctlrs); i++) {
30 		if (mic_ctlrs[i].conn == conn) {
31 			return &mic_ctlrs[i];
32 		}
33 	}
34 
35 	return NULL;
36 }
37 
bt_micp_mic_ctlr_conn_get(const struct bt_micp_mic_ctlr * mic_ctlr,struct bt_conn ** conn)38 int bt_micp_mic_ctlr_conn_get(const struct bt_micp_mic_ctlr *mic_ctlr, struct bt_conn **conn)
39 {
40 	*conn = mic_ctlr->conn;
41 
42 	return 0;
43 }
44 
bt_micp_mic_ctlr_mute(struct bt_micp_mic_ctlr * mic_ctlr)45 int bt_micp_mic_ctlr_mute(struct bt_micp_mic_ctlr *mic_ctlr)
46 {
47 	if (micp_cb != NULL && micp_cb->mute_written != NULL) {
48 		micp_cb->mute_written(mic_ctlr, 0);
49 	}
50 
51 	return 0;
52 }
53 
bt_micp_mic_ctlr_unmute(struct bt_micp_mic_ctlr * mic_ctlr)54 int bt_micp_mic_ctlr_unmute(struct bt_micp_mic_ctlr *mic_ctlr)
55 {
56 	if (micp_cb != NULL && micp_cb->unmute_written != NULL) {
57 		micp_cb->unmute_written(mic_ctlr, 0);
58 	}
59 
60 	return 0;
61 }
62 
bt_micp_mic_ctlr_discover(struct bt_conn * conn,struct bt_micp_mic_ctlr ** mic_ctlr)63 int bt_micp_mic_ctlr_discover(struct bt_conn *conn, struct bt_micp_mic_ctlr **mic_ctlr)
64 {
65 	for (size_t i = 0; i < ARRAY_SIZE(mic_ctlrs); i++) {
66 		if (mic_ctlrs[i].conn == NULL) {
67 			for (size_t j = 0U; j < ARRAY_SIZE(mic_ctlrs[i].aics); j++) {
68 				const int err = bt_aics_discover(conn, mic_ctlrs[i].aics[j], NULL);
69 
70 				if (err != 0) {
71 					return err;
72 				}
73 			}
74 
75 			mic_ctlrs[i].conn = conn;
76 			*mic_ctlr = &mic_ctlrs[i];
77 
78 			return 0;
79 		}
80 	}
81 
82 	return -ENOMEM;
83 }
84 
bt_micp_mic_ctlr_cb_register(struct bt_micp_mic_ctlr_cb * cb)85 int bt_micp_mic_ctlr_cb_register(struct bt_micp_mic_ctlr_cb *cb)
86 {
87 	micp_cb = cb;
88 
89 	if (IS_ENABLED(CONFIG_BT_MICP_MIC_CTLR_AICS)) {
90 		for (size_t i = 0U; i < ARRAY_SIZE(mic_ctlrs); i++) {
91 			for (size_t j = 0U; j < ARRAY_SIZE(mic_ctlrs[i].aics); j++) {
92 				bt_aics_client_cb_register(mic_ctlrs[i].aics[j], &cb->aics_cb);
93 			}
94 		}
95 	}
96 
97 	return 0;
98 }
99 
bt_micp_mic_ctlr_included_get(struct bt_micp_mic_ctlr * mic_ctlr,struct bt_micp_included * included)100 int bt_micp_mic_ctlr_included_get(struct bt_micp_mic_ctlr *mic_ctlr,
101 				  struct bt_micp_included *included)
102 {
103 	included->aics_cnt = ARRAY_SIZE(mic_ctlr->aics);
104 	included->aics = mic_ctlr->aics;
105 
106 	return 0;
107 }
108 
mock_bt_micp_init(void)109 void mock_bt_micp_init(void)
110 {
111 	if (IS_ENABLED(CONFIG_BT_MICP_MIC_CTLR_AICS)) {
112 		for (size_t i = 0U; i < ARRAY_SIZE(mic_ctlrs); i++) {
113 			for (size_t j = 0U; j < ARRAY_SIZE(mic_ctlrs[i].aics); j++) {
114 				mic_ctlrs[i].aics[j] = bt_aics_client_free_instance_get();
115 
116 				__ASSERT(mic_ctlrs[i].aics[j],
117 					 "Could not allocate AICS client instance");
118 			}
119 		}
120 	}
121 }
122 
mock_bt_micp_cleanup(void)123 void mock_bt_micp_cleanup(void)
124 {
125 	memset(mic_ctlrs, 0, sizeof(mic_ctlrs));
126 }
127