1 /** @file
2 * @brief Bluetooth Volume Control Profile (VCP) Volume Renderer role.
3 *
4 * Copyright (c) 2020 Bose Corporation
5 * Copyright (c) 2020-2022 Nordic Semiconductor ASA
6 * Copyright (c) 2022 Codecoup
7 *
8 * SPDX-License-Identifier: Apache-2.0
9 */
10
11 #include <zephyr/kernel.h>
12 #include <zephyr/sys/printk.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15
16 #include <zephyr/bluetooth/conn.h>
17 #include <zephyr/bluetooth/audio/vcp.h>
18
19 static struct bt_vcp_included vcp_included;
20
vcs_state_cb(struct bt_conn * conn,int err,uint8_t volume,uint8_t mute)21 static void vcs_state_cb(struct bt_conn *conn, int err, uint8_t volume, uint8_t mute)
22 {
23 if (err) {
24 printk("VCS state get failed (%d)\n", err);
25 } else {
26 printk("VCS volume %u, mute %u\n", volume, mute);
27 }
28 }
29
vcs_flags_cb(struct bt_conn * conn,int err,uint8_t flags)30 static void vcs_flags_cb(struct bt_conn *conn, int err, uint8_t flags)
31 {
32 if (err) {
33 printk("VCS flags get failed (%d)\n", err);
34 } else {
35 printk("VCS flags 0x%02X\n", flags);
36 }
37 }
38
aics_state_cb(struct bt_aics * inst,int err,int8_t gain,uint8_t mute,uint8_t mode)39 static void aics_state_cb(struct bt_aics *inst, int err, int8_t gain, uint8_t mute, uint8_t mode)
40 {
41 if (err) {
42 printk("AICS state get failed (%d) for inst %p\n", err, inst);
43 } else {
44 printk("AICS inst %p state gain %d, mute %u, mode %u\n",
45 inst, gain, mute, mode);
46 }
47 }
48
aics_gain_setting_cb(struct bt_aics * inst,int err,uint8_t units,int8_t minimum,int8_t maximum)49 static void aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units, int8_t minimum,
50 int8_t maximum)
51 {
52 if (err) {
53 printk("AICS gain settings get failed (%d) for inst %p\n", err, inst);
54 } else {
55 printk("AICS inst %p gain settings units %u, min %d, max %d\n",
56 inst, units, minimum, maximum);
57 }
58 }
59
aics_input_type_cb(struct bt_aics * inst,int err,uint8_t input_type)60 static void aics_input_type_cb(struct bt_aics *inst, int err, uint8_t input_type)
61 {
62 if (err) {
63 printk("AICS input type get failed (%d) for inst %p\n", err, inst);
64 } else {
65 printk("AICS inst %p input type %u\n", inst, input_type);
66 }
67 }
68
aics_status_cb(struct bt_aics * inst,int err,bool active)69 static void aics_status_cb(struct bt_aics *inst, int err, bool active)
70 {
71 if (err) {
72 printk("AICS status get failed (%d) for inst %p\n", err, inst);
73 } else {
74 printk("AICS inst %p status %s\n", inst, active ? "active" : "inactive");
75 }
76
77 }
aics_description_cb(struct bt_aics * inst,int err,char * description)78 static void aics_description_cb(struct bt_aics *inst, int err, char *description)
79 {
80 if (err) {
81 printk("AICS description get failed (%d) for inst %p\n", err, inst);
82 } else {
83 printk("AICS inst %p description %s\n", inst, description);
84 }
85 }
vocs_state_cb(struct bt_vocs * inst,int err,int16_t offset)86 static void vocs_state_cb(struct bt_vocs *inst, int err, int16_t offset)
87 {
88 if (err) {
89 printk("VOCS state get failed (%d) for inst %p\n", err, inst);
90 } else {
91 printk("VOCS inst %p offset %d\n", inst, offset);
92 }
93 }
94
vocs_location_cb(struct bt_vocs * inst,int err,uint32_t location)95 static void vocs_location_cb(struct bt_vocs *inst, int err, uint32_t location)
96 {
97 if (err) {
98 printk("VOCS location get failed (%d) for inst %p\n", err, inst);
99 } else {
100 printk("VOCS inst %p location %u\n", inst, location);
101 }
102 }
103
vocs_description_cb(struct bt_vocs * inst,int err,char * description)104 static void vocs_description_cb(struct bt_vocs *inst, int err, char *description)
105 {
106 if (err) {
107 printk("VOCS description get failed (%d) for inst %p\n", err, inst);
108 } else {
109 printk("VOCS inst %p description %s\n", inst, description);
110 }
111 }
112
113 static struct bt_vcp_vol_rend_cb vcp_cbs = {
114 .state = vcs_state_cb,
115 .flags = vcs_flags_cb,
116 };
117
118 static struct bt_aics_cb aics_cbs = {
119 .state = aics_state_cb,
120 .gain_setting = aics_gain_setting_cb,
121 .type = aics_input_type_cb,
122 .status = aics_status_cb,
123 .description = aics_description_cb
124 };
125
126 static struct bt_vocs_cb vocs_cbs = {
127 .state = vocs_state_cb,
128 .location = vocs_location_cb,
129 .description = vocs_description_cb
130 };
131
vcp_vol_renderer_init(void)132 int vcp_vol_renderer_init(void)
133 {
134 int err;
135 struct bt_vcp_vol_rend_register_param vcp_register_param;
136 char input_desc[CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT][16];
137 char output_desc[CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT][16];
138
139 memset(&vcp_register_param, 0, sizeof(vcp_register_param));
140
141 for (int i = 0; i < ARRAY_SIZE(vcp_register_param.vocs_param); i++) {
142 vcp_register_param.vocs_param[i].location_writable = true;
143 vcp_register_param.vocs_param[i].desc_writable = true;
144 snprintf(output_desc[i], sizeof(output_desc[i]), "Output %d", i + 1);
145 vcp_register_param.vocs_param[i].output_desc = output_desc[i];
146 vcp_register_param.vocs_param[i].cb = &vocs_cbs;
147 }
148
149 for (int i = 0; i < ARRAY_SIZE(vcp_register_param.aics_param); i++) {
150 vcp_register_param.aics_param[i].desc_writable = true;
151 snprintf(input_desc[i], sizeof(input_desc[i]), "Input %d", i + 1);
152 vcp_register_param.aics_param[i].description = input_desc[i];
153 vcp_register_param.aics_param[i].type = BT_AICS_INPUT_TYPE_UNSPECIFIED;
154 vcp_register_param.aics_param[i].status = true;
155 vcp_register_param.aics_param[i].gain_mode = BT_AICS_MODE_MANUAL;
156 vcp_register_param.aics_param[i].units = 1;
157 vcp_register_param.aics_param[i].min_gain = -100;
158 vcp_register_param.aics_param[i].max_gain = 100;
159 vcp_register_param.aics_param[i].cb = &aics_cbs;
160 }
161
162 vcp_register_param.step = 1;
163 vcp_register_param.mute = BT_VCP_STATE_UNMUTED;
164 vcp_register_param.volume = 100;
165 vcp_register_param.cb = &vcp_cbs;
166
167 err = bt_vcp_vol_rend_register(&vcp_register_param);
168 if (err) {
169 return err;
170 }
171
172 err = bt_vcp_vol_rend_included_get(&vcp_included);
173 if (err != 0) {
174 return err;
175 }
176
177 return 0;
178 }
179