1 /* csip.c - CAP Commander specific VCP mocks */
2 
3 /*
4  * Copyright (c) 2023 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/bluetooth/audio/vcp.h>
10 
11 static struct bt_vcp_vol_ctlr_cb *vcp_cb;
12 
13 static struct bt_vcp_vol_ctlr {
14 	struct bt_conn *conn;
15 	struct bt_vocs *vocs[CONFIG_BT_VCP_VOL_CTLR_MAX_VOCS_INST];
16 	struct bt_aics *aics[CONFIG_BT_VCP_VOL_CTLR_MAX_AICS_INST];
17 } vol_ctlrs[CONFIG_BT_MAX_CONN];
18 
bt_vcp_vol_ctlr_get_by_conn(const struct bt_conn * conn)19 struct bt_vcp_vol_ctlr *bt_vcp_vol_ctlr_get_by_conn(const struct bt_conn *conn)
20 {
21 	for (size_t i = 0; i < ARRAY_SIZE(vol_ctlrs); i++) {
22 		if (vol_ctlrs[i].conn == conn) {
23 			return &vol_ctlrs[i];
24 		}
25 	}
26 
27 	return NULL;
28 }
29 
bt_vcp_vol_ctlr_conn_get(const struct bt_vcp_vol_ctlr * vol_ctlr,struct bt_conn ** conn)30 int bt_vcp_vol_ctlr_conn_get(const struct bt_vcp_vol_ctlr *vol_ctlr, struct bt_conn **conn)
31 {
32 	*conn = vol_ctlr->conn;
33 
34 	return 0;
35 }
36 
bt_vcp_vol_ctlr_set_vol(struct bt_vcp_vol_ctlr * vol_ctlr,uint8_t volume)37 int bt_vcp_vol_ctlr_set_vol(struct bt_vcp_vol_ctlr *vol_ctlr, uint8_t volume)
38 {
39 	if (vcp_cb != NULL && vcp_cb->vol_set != NULL) {
40 		vcp_cb->vol_set(vol_ctlr, 0);
41 	}
42 
43 	return 0;
44 }
45 
bt_vcp_vol_ctlr_mute(struct bt_vcp_vol_ctlr * vol_ctlr)46 int bt_vcp_vol_ctlr_mute(struct bt_vcp_vol_ctlr *vol_ctlr)
47 {
48 	if (vcp_cb != NULL && vcp_cb->mute != NULL) {
49 		vcp_cb->mute(vol_ctlr, 0);
50 	}
51 
52 	return 0;
53 }
54 
bt_vcp_vol_ctlr_unmute(struct bt_vcp_vol_ctlr * vol_ctlr)55 int bt_vcp_vol_ctlr_unmute(struct bt_vcp_vol_ctlr *vol_ctlr)
56 {
57 	if (vcp_cb != NULL && vcp_cb->unmute != NULL) {
58 		vcp_cb->unmute(vol_ctlr, 0);
59 	}
60 
61 	return 0;
62 }
63 
bt_vcp_vol_ctlr_discover(struct bt_conn * conn,struct bt_vcp_vol_ctlr ** vol_ctlr)64 int bt_vcp_vol_ctlr_discover(struct bt_conn *conn, struct bt_vcp_vol_ctlr **vol_ctlr)
65 {
66 	for (size_t i = 0; i < ARRAY_SIZE(vol_ctlrs); i++) {
67 		if (vol_ctlrs[i].conn == NULL) {
68 			for (size_t j = 0U; j < ARRAY_SIZE(vol_ctlrs[i].vocs); j++) {
69 				const int err = bt_vocs_discover(conn, vol_ctlrs[i].vocs[j], NULL);
70 
71 				if (err != 0) {
72 					return err;
73 				}
74 			}
75 
76 			vol_ctlrs[i].conn = conn;
77 			*vol_ctlr = &vol_ctlrs[i];
78 
79 			return 0;
80 		}
81 	}
82 
83 	return -ENOMEM;
84 }
85 
bt_vcp_vol_ctlr_cb_register(struct bt_vcp_vol_ctlr_cb * cb)86 int bt_vcp_vol_ctlr_cb_register(struct bt_vcp_vol_ctlr_cb *cb)
87 {
88 	vcp_cb = cb;
89 
90 	if (IS_ENABLED(CONFIG_BT_VCP_VOL_CTLR_VOCS)) {
91 		for (size_t i = 0U; i < ARRAY_SIZE(vol_ctlrs); i++) {
92 			for (size_t j = 0U; j < ARRAY_SIZE(vol_ctlrs[i].vocs); j++) {
93 				bt_vocs_client_cb_register(vol_ctlrs[i].vocs[j], &cb->vocs_cb);
94 			}
95 		}
96 	}
97 
98 	return 0;
99 }
100 
bt_vcp_vol_ctlr_included_get(struct bt_vcp_vol_ctlr * vol_ctlr,struct bt_vcp_included * included)101 int bt_vcp_vol_ctlr_included_get(struct bt_vcp_vol_ctlr *vol_ctlr, struct bt_vcp_included *included)
102 {
103 	included->vocs_cnt = ARRAY_SIZE(vol_ctlr->vocs);
104 	included->vocs = vol_ctlr->vocs;
105 
106 	included->aics_cnt = ARRAY_SIZE(vol_ctlr->aics);
107 	included->aics = vol_ctlr->aics;
108 
109 	return 0;
110 }
111 
mock_bt_vcp_init(void)112 void mock_bt_vcp_init(void)
113 {
114 	if (IS_ENABLED(CONFIG_BT_VCP_VOL_CTLR_VOCS)) {
115 		for (size_t i = 0U; i < ARRAY_SIZE(vol_ctlrs); i++) {
116 			for (size_t j = 0U; j < ARRAY_SIZE(vol_ctlrs[i].vocs); j++) {
117 				vol_ctlrs[i].vocs[j] = bt_vocs_client_free_instance_get();
118 
119 				__ASSERT(vol_ctlrs[i].vocs[j],
120 					 "Could not allocate VOCS client instance");
121 			}
122 		}
123 	}
124 }
125 
mock_bt_vcp_cleanup(void)126 void mock_bt_vcp_cleanup(void)
127 {
128 	memset(vol_ctlrs, 0, sizeof(vol_ctlrs));
129 }
130