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