Line data Source code
1 1 : /**
2 : * @file
3 : * @brief Bluetooth Volume Control Profile (VCP) APIs.
4 : */
5 :
6 : /*
7 : * Copyright (c) 2020-2024 Nordic Semiconductor ASA
8 : *
9 : * SPDX-License-Identifier: Apache-2.0
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VCP_H_
13 : #define ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VCP_H_
14 :
15 : /**
16 : * @brief Volume Control Profile (VCP)
17 : *
18 : * @defgroup bt_vcp Volume Control Profile (VCP)
19 : *
20 : * @since 2.7
21 : * @version 0.8.0
22 : *
23 : * @ingroup bluetooth
24 : * @{
25 : *
26 : * The Volume Control Profile (VCP) provides procedures to control the volume level and mute state
27 : * on audio devices.
28 : */
29 :
30 : #include <stdint.h>
31 :
32 : #include <zephyr/bluetooth/audio/aics.h>
33 : #include <zephyr/bluetooth/audio/vocs.h>
34 : #include <zephyr/bluetooth/conn.h>
35 : #include <zephyr/sys/slist.h>
36 :
37 : #ifdef __cplusplus
38 : extern "C" {
39 : #endif
40 :
41 : /**
42 : * Defines the maximum number of Volume Offset Control service instances for the
43 : * Volume Control Profile Volume Renderer
44 : */
45 : #if defined(CONFIG_BT_VCP_VOL_REND)
46 : #define BT_VCP_VOL_REND_VOCS_CNT CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT
47 : #else
48 1 : #define BT_VCP_VOL_REND_VOCS_CNT 0
49 : #endif /* CONFIG_BT_VCP_VOL_REND */
50 :
51 : /**
52 : * Defines the maximum number of Audio Input Control service instances for the
53 : * Volume Control Profile Volume Renderer
54 : */
55 : #if defined(CONFIG_BT_VCP_VOL_REND)
56 : #define BT_VCP_VOL_REND_AICS_CNT CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT
57 : #else
58 1 : #define BT_VCP_VOL_REND_AICS_CNT 0
59 : #endif /* CONFIG_BT_VCP_VOL_REND */
60 :
61 : /**
62 : * @name Volume Control Service Error codes
63 : * @{
64 : */
65 : /**
66 : * The Change_Counter operand value does not match the Change_Counter field value of the Volume
67 : * State characteristic.
68 : */
69 1 : #define BT_VCP_ERR_INVALID_COUNTER 0x80
70 : /** An invalid opcode has been used in a control point procedure. */
71 1 : #define BT_VCP_ERR_OP_NOT_SUPPORTED 0x81
72 : /** @} */
73 :
74 : /**
75 : * @name Volume Control Service Mute Values
76 : * @{
77 : */
78 : /** The volume state is unmuted */
79 1 : #define BT_VCP_STATE_UNMUTED 0x00
80 : /** The volume state is muted */
81 1 : #define BT_VCP_STATE_MUTED 0x01
82 : /** @} */
83 :
84 : /** @brief Opaque Volume Control Service instance. */
85 : struct bt_vcp_vol_ctlr;
86 :
87 : /** Register structure for Volume Control Service */
88 1 : struct bt_vcp_vol_rend_register_param {
89 : /** Initial step size (1-255) */
90 1 : uint8_t step;
91 :
92 : /** Initial mute state (0-1) */
93 1 : uint8_t mute;
94 :
95 : /** Initial volume level (0-255) */
96 1 : uint8_t volume;
97 :
98 : /** Register parameters for Volume Offset Control Services */
99 1 : struct bt_vocs_register_param vocs_param[BT_VCP_VOL_REND_VOCS_CNT];
100 :
101 : /** Register parameters for Audio Input Control Services */
102 1 : struct bt_aics_register_param aics_param[BT_VCP_VOL_REND_AICS_CNT];
103 :
104 : /** Volume Control Service callback structure. */
105 1 : struct bt_vcp_vol_rend_cb *cb;
106 : };
107 :
108 : /**
109 : * @brief Volume Control Service included services
110 : *
111 : * Used for to represent the Volume Control Service included service instances,
112 : * for either a client or a server. The instance pointers either represent
113 : * local server instances, or remote service instances.
114 : */
115 1 : struct bt_vcp_included {
116 : /** Number of Volume Offset Control Service instances */
117 1 : uint8_t vocs_cnt;
118 : /** Array of pointers to Volume Offset Control Service instances */
119 1 : struct bt_vocs **vocs;
120 :
121 : /** Number of Audio Input Control Service instances */
122 1 : uint8_t aics_cnt;
123 : /** Array of pointers to Audio Input Control Service instances */
124 1 : struct bt_aics **aics;
125 : };
126 :
127 : /**
128 : * @brief Get Volume Control Service included services.
129 : *
130 : * Returns a pointer to a struct that contains information about the
131 : * Volume Control Service included service instances, such as pointers to the
132 : * Volume Offset Control Service (Volume Offset Control Service) or
133 : * Audio Input Control Service (AICS) instances.
134 : *
135 : * @param[out] included Pointer to store the result in.
136 : *
137 : * @return 0 if success, errno on failure.
138 : */
139 1 : int bt_vcp_vol_rend_included_get(struct bt_vcp_included *included);
140 :
141 : /**
142 : * @brief Register the Volume Control Service.
143 : *
144 : * This will register and enable the service and make it discoverable by
145 : * clients.
146 : *
147 : * @param param Volume Control Service register parameters.
148 : *
149 : * @return 0 if success, errno on failure.
150 : */
151 1 : int bt_vcp_vol_rend_register(struct bt_vcp_vol_rend_register_param *param);
152 :
153 : /**
154 : * @brief Struct to hold the Volume Renderer callbacks
155 : *
156 : * These can be registered for usage with bt_vcp_vol_rend_register().
157 : */
158 1 : struct bt_vcp_vol_rend_cb {
159 : /**
160 : * @brief Callback function for Volume Control Service volume state.
161 : *
162 : * Called when the value is locally read with
163 : * bt_vcp_vol_rend_get_state(), or if the state is changed by either
164 : * the Volume Renderer or a remote Volume Controller.
165 : *
166 : * @param conn Pointer to the connection to a remote device if
167 : * the change was caused by it, otherwise NULL.
168 : * @param err Error value. 0 on success, GATT error on positive value
169 : * or errno on negative value.
170 : * @param volume The volume of the Volume Control Service server.
171 : * @param mute The mute setting of the Volume Control Service server.
172 : */
173 1 : void (*state)(struct bt_conn *conn, int err, uint8_t volume, uint8_t mute);
174 :
175 : /**
176 : * @brief Callback function for Volume Control Service flags.
177 : *
178 : * Called when the value is locally read as the server.
179 : * Called when the value is remotely read as the client.
180 : * Called if the value is changed by either the server or client.
181 : *
182 : * @param conn Pointer to the connection to a remote device if
183 : * the change was caused by it, otherwise NULL.
184 : * @param err Error value. 0 on success, GATT error on positive value
185 : * or errno on negative value.
186 : * @param flags The flags of the Volume Control Service server.
187 : */
188 1 : void (*flags)(struct bt_conn *conn, int err, uint8_t flags);
189 : };
190 :
191 : /**
192 : * @brief Set the Volume Control Service volume step size.
193 : *
194 : * Set the value that the volume changes, when changed relatively with e.g.
195 : * @ref bt_vcp_vol_rend_vol_down or @ref bt_vcp_vol_rend_vol_up.
196 : *
197 : * This can only be done as the server.
198 : *
199 : * @param volume_step The volume step size (1-255).
200 : *
201 : * @return 0 if success, errno on failure.
202 : */
203 1 : int bt_vcp_vol_rend_set_step(uint8_t volume_step);
204 :
205 : /**
206 : * @brief Get the Volume Control Service volume state.
207 : *
208 : * @return 0 if success, errno on failure.
209 : */
210 1 : int bt_vcp_vol_rend_get_state(void);
211 :
212 : /**
213 : * @brief Get the Volume Control Service flags.
214 : *
215 : * @return 0 if success, errno on failure.
216 : */
217 1 : int bt_vcp_vol_rend_get_flags(void);
218 :
219 : /**
220 : * @brief Turn the volume down by one step on the server.
221 : *
222 : * @return 0 if success, errno on failure.
223 : */
224 1 : int bt_vcp_vol_rend_vol_down(void);
225 :
226 : /**
227 : * @brief Turn the volume up by one step on the server.
228 : *
229 : * @return 0 if success, errno on failure.
230 : */
231 1 : int bt_vcp_vol_rend_vol_up(void);
232 :
233 : /**
234 : * @brief Turn the volume down and unmute the server.
235 : *
236 : * @return 0 if success, errno on failure.
237 : */
238 1 : int bt_vcp_vol_rend_unmute_vol_down(void);
239 :
240 : /**
241 : * @brief Turn the volume up and unmute the server.
242 : *
243 : * @return 0 if success, errno on failure.
244 : */
245 1 : int bt_vcp_vol_rend_unmute_vol_up(void);
246 :
247 : /**
248 : * @brief Set the volume on the server
249 : *
250 : * @param volume The absolute volume to set.
251 : *
252 : * @return 0 if success, errno on failure.
253 : */
254 1 : int bt_vcp_vol_rend_set_vol(uint8_t volume);
255 :
256 : /**
257 : * @brief Unmute the server.
258 : *
259 : * @return 0 if success, errno on failure.
260 : */
261 1 : int bt_vcp_vol_rend_unmute(void);
262 :
263 : /**
264 : * @brief Mute the server.
265 : *
266 : * @return 0 if success, errno on failure.
267 : */
268 1 : int bt_vcp_vol_rend_mute(void);
269 :
270 : /**
271 : * @brief Struct to hold the Volume Controller callbacks
272 : *
273 : * These can be registered for usage with bt_vcp_vol_ctlr_cb_register().
274 : */
275 1 : struct bt_vcp_vol_ctlr_cb {
276 : /**
277 : * @brief Callback function for Volume Control Profile volume state.
278 : *
279 : * Called when the value is remotely read as the Volume Controller.
280 : * Called if the value is changed by either the Volume Renderer or
281 : * Volume Controller, and notified to the to Volume Controller.
282 : *
283 : * @param vol_ctlr Volume Controller instance pointer.
284 : * @param err Error value. 0 on success, GATT error on positive
285 : * value or errno on negative value.
286 : * @param volume The volume of the Volume Renderer.
287 : * @param mute The mute setting of the Volume Renderer.
288 : */
289 1 : void (*state)(struct bt_vcp_vol_ctlr *vol_ctlr, int err, uint8_t volume,
290 : uint8_t mute);
291 :
292 : /**
293 : * @brief Callback function for Volume Control Profile volume flags.
294 : *
295 : * Called when the value is remotely read as the Volume Controller.
296 : * Called if the value is changed by the Volume Renderer.
297 : *
298 : * A non-zero value indicates the volume has been changed on the
299 : * Volume Renderer since it was booted.
300 : *
301 : * @param vol_ctlr Volume Controller instance pointer.
302 : * @param err Error value. 0 on success, GATT error on positive
303 : * value or errno on negative value.
304 : * @param flags The flags of the Volume Renderer.
305 : */
306 :
307 1 : void (*flags)(struct bt_vcp_vol_ctlr *vol_ctlr, int err, uint8_t flags);
308 :
309 : /**
310 : * @brief Callback function for bt_vcp_vol_ctlr_discover().
311 : *
312 : * This callback is called once the discovery procedure is completed.
313 : *
314 : * @param vol_ctlr Volume Controller instance pointer.
315 : * @param err Error value. 0 on success, GATT error on positive
316 : * value or errno on negative value.
317 : * @param vocs_count Number of Volume Offset Control Service instances
318 : * on the remote Volume Renderer.
319 : * @param aics_count Number of Audio Input Control Service instances
320 : * the remote Volume Renderer.
321 : */
322 1 : void (*discover)(struct bt_vcp_vol_ctlr *vol_ctlr, int err, uint8_t vocs_count,
323 : uint8_t aics_count);
324 :
325 : /**
326 : * @brief Callback function for bt_vcp_vol_ctlr_vol_down().
327 : *
328 : * Called when the volume down procedure is completed.
329 : *
330 : * @param vol_ctlr Volume Controller instance pointer.
331 : * @param err Error value. 0 on success, GATT error on positive
332 : * value or errno on negative value.
333 : */
334 1 : void (*vol_down)(struct bt_vcp_vol_ctlr *vol_ctlr, int err);
335 :
336 : /**
337 : * @brief Callback function for bt_vcp_vol_ctlr_vol_up().
338 : *
339 : * Called when the volume up procedure is completed.
340 : *
341 : * @param vol_ctlr Volume Controller instance pointer.
342 : * @param err Error value. 0 on success, GATT error on positive
343 : * value or errno on negative value.
344 : */
345 1 : void (*vol_up)(struct bt_vcp_vol_ctlr *vol_ctlr, int err);
346 :
347 : /**
348 : * @brief Callback function for bt_vcp_vol_ctlr_mute().
349 : *
350 : * Called when the mute procedure is completed.
351 : *
352 : * @param vol_ctlr Volume Controller instance pointer.
353 : * @param err Error value. 0 on success, GATT error on positive
354 : * value or errno on negative value.
355 : */
356 1 : void (*mute)(struct bt_vcp_vol_ctlr *vol_ctlr, int err);
357 :
358 : /**
359 : * @brief Callback function for bt_vcp_vol_ctlr_unmute().
360 : *
361 : * Called when the unmute procedure is completed.
362 : *
363 : * @param vol_ctlr Volume Controller instance pointer.
364 : * @param err Error value. 0 on success, GATT error on positive
365 : * value or errno on negative value.
366 : */
367 1 : void (*unmute)(struct bt_vcp_vol_ctlr *vol_ctlr, int err);
368 :
369 : /**
370 : * @brief Callback function for bt_vcp_vol_ctlr_vol_down_unmute().
371 : *
372 : * Called when the volume down and unmute procedure is completed.
373 : *
374 : * @param vol_ctlr Volume Controller instance pointer.
375 : * @param err Error value. 0 on success, GATT error on positive
376 : * value or errno on negative value.
377 : */
378 1 : void (*vol_down_unmute)(struct bt_vcp_vol_ctlr *vol_ctlr, int err);
379 :
380 : /**
381 : * @brief Callback function for bt_vcp_vol_ctlr_vol_up_unmute().
382 : *
383 : * Called when the volume up and unmute procedure is completed.
384 : *
385 : * @param vol_ctlr Volume Controller instance pointer.
386 : * @param err Error value. 0 on success, GATT error on positive
387 : * value or errno on negative value.
388 : */
389 1 : void (*vol_up_unmute)(struct bt_vcp_vol_ctlr *vol_ctlr, int err);
390 :
391 : /**
392 : * @brief Callback function for bt_vcp_vol_ctlr_vol_set().
393 : *
394 : * Called when the set absolute volume procedure is completed.
395 : *
396 : * @param vol_ctlr Volume Controller instance pointer.
397 : * @param err Error value. 0 on success, GATT error on positive
398 : * value or errno on negative value.
399 : */
400 1 : void (*vol_set)(struct bt_vcp_vol_ctlr *vol_ctlr, int err);
401 :
402 : /** Volume Offset Control Service callbacks */
403 1 : struct bt_vocs_cb vocs_cb;
404 :
405 : /** Audio Input Control Service callbacks */
406 1 : struct bt_aics_cb aics_cb;
407 :
408 : /** @internal Internally used field for list handling */
409 : sys_snode_t _node;
410 : };
411 :
412 : /**
413 : * @brief Registers the callbacks used by the Volume Controller.
414 : *
415 : * @param cb The callback structure.
416 : *
417 : * @retval 0 on success
418 : * @retval -EINVAL if @p cb is NULL
419 : * @retval -EALREADY if @p cb was already registered
420 : */
421 1 : int bt_vcp_vol_ctlr_cb_register(struct bt_vcp_vol_ctlr_cb *cb);
422 :
423 : /**
424 : * @brief Unregisters the callbacks used by the Volume Controller.
425 : *
426 : * @param cb The callback structure.
427 : *
428 : * @retval 0 on success
429 : * @retval -EINVAL if @p cb is NULL
430 : * @retval -EALREADY if @p cb was not registered
431 : */
432 1 : int bt_vcp_vol_ctlr_cb_unregister(struct bt_vcp_vol_ctlr_cb *cb);
433 :
434 : /**
435 : * @brief Discover Volume Control Service and included services.
436 : *
437 : * This will start a GATT discovery and setup handles and subscriptions.
438 : * This shall be called once before any other actions can be
439 : * executed for the peer device, and the
440 : * @ref bt_vcp_vol_ctlr_cb.discover callback will notify when it is possible to
441 : * start remote operations.
442 : *
443 : * This shall only be done as the client,
444 : *
445 : * @param conn The connection to discover Volume Control Service for.
446 : * @param[out] vol_ctlr Valid remote instance object on success.
447 : *
448 : * @return 0 if success, errno on failure.
449 : */
450 1 : int bt_vcp_vol_ctlr_discover(struct bt_conn *conn,
451 : struct bt_vcp_vol_ctlr **vol_ctlr);
452 :
453 : /**
454 : * @brief Get the volume controller from a connection pointer
455 : *
456 : * Get the Volume Control Profile Volume Controller pointer from a connection pointer.
457 : * Only volume controllers that have been initiated via bt_vcp_vol_ctlr_discover() can be
458 : * retrieved.
459 : *
460 : * @param conn Connection pointer.
461 : *
462 : * @retval Pointer to a Volume Control Profile Volume Controller instance
463 : * @retval NULL if @p conn is NULL or if the connection has not done discovery yet
464 : */
465 1 : struct bt_vcp_vol_ctlr *bt_vcp_vol_ctlr_get_by_conn(const struct bt_conn *conn);
466 :
467 : /**
468 : * @brief Get the connection pointer of a client instance
469 : *
470 : * Get the Bluetooth connection pointer of a Volume Control Service
471 : * client instance.
472 : *
473 : * @param vol_ctlr Volume Controller instance pointer.
474 : * @param[out] conn Connection pointer.
475 : *
476 : * @return 0 if success, errno on failure.
477 : */
478 1 : int bt_vcp_vol_ctlr_conn_get(const struct bt_vcp_vol_ctlr *vol_ctlr,
479 : struct bt_conn **conn);
480 :
481 : /**
482 : * @brief Get Volume Control Service included services.
483 : *
484 : * Returns a pointer to a struct that contains information about the
485 : * Volume Control Service included service instances, such as pointers to the
486 : * Volume Offset Control Service (Volume Offset Control Service) or
487 : * Audio Input Control Service (AICS) instances.
488 : *
489 : * Requires that @kconfig{CONFIG_BT_VCP_VOL_CTLR_VOCS} or @kconfig{CONFIG_BT_VCP_VOL_CTLR_AICS} is
490 : * enabled.
491 : *
492 : * @param vol_ctlr Volume Controller instance pointer.
493 : * @param[out] included Pointer to store the result in.
494 : *
495 : * @return 0 if success, errno on failure.
496 : */
497 1 : int bt_vcp_vol_ctlr_included_get(struct bt_vcp_vol_ctlr *vol_ctlr,
498 : struct bt_vcp_included *included);
499 :
500 : /**
501 : * @brief Read the volume state of a remote Volume Renderer.
502 : *
503 : * @param vol_ctlr Volume Controller instance pointer.
504 : *
505 : * @return 0 if success, errno on failure.
506 : */
507 1 : int bt_vcp_vol_ctlr_read_state(struct bt_vcp_vol_ctlr *vol_ctlr);
508 :
509 : /**
510 : * @brief Read the volume flags of a remote Volume Renderer.
511 : *
512 : * @param vol_ctlr Volume Controller instance pointer.
513 : *
514 : * @return 0 if success, errno on failure.
515 : */
516 1 : int bt_vcp_vol_ctlr_read_flags(struct bt_vcp_vol_ctlr *vol_ctlr);
517 :
518 : /**
519 : * @brief Turn the volume down one step on a remote Volume Renderer
520 : *
521 : * @param vol_ctlr Volume Controller instance pointer.
522 : *
523 : * @return 0 if success, errno on failure.
524 : */
525 1 : int bt_vcp_vol_ctlr_vol_down(struct bt_vcp_vol_ctlr *vol_ctlr);
526 :
527 : /**
528 : * @brief Turn the volume up one step on a remote Volume Renderer
529 : *
530 : * @param vol_ctlr Volume Controller instance pointer.
531 : *
532 : * @return 0 if success, errno on failure.
533 : */
534 1 : int bt_vcp_vol_ctlr_vol_up(struct bt_vcp_vol_ctlr *vol_ctlr);
535 :
536 : /**
537 : * @brief Turn the volume down one step and unmute on a remote Volume Renderer
538 : *
539 : * @param vol_ctlr Volume Controller instance pointer.
540 : *
541 : * @return 0 if success, errno on failure.
542 : */
543 1 : int bt_vcp_vol_ctlr_unmute_vol_down(struct bt_vcp_vol_ctlr *vol_ctlr);
544 :
545 : /**
546 : * @brief Turn the volume up one step and unmute on a remote Volume Renderer
547 : *
548 : * @param vol_ctlr Volume Controller instance pointer.
549 : *
550 : * @return 0 if success, errno on failure.
551 : */
552 1 : int bt_vcp_vol_ctlr_unmute_vol_up(struct bt_vcp_vol_ctlr *vol_ctlr);
553 :
554 : /**
555 : * @brief Set the absolute volume on a remote Volume Renderer
556 : *
557 : * @param vol_ctlr Volume Controller instance pointer.
558 : * @param volume The absolute volume to set.
559 : *
560 : * @return 0 if success, errno on failure.
561 : */
562 1 : int bt_vcp_vol_ctlr_set_vol(struct bt_vcp_vol_ctlr *vol_ctlr, uint8_t volume);
563 :
564 : /**
565 : * @brief Unmute a remote Volume Renderer.
566 : *
567 : * @param vol_ctlr Volume Controller instance pointer.
568 : *
569 : * @return 0 if success, errno on failure.
570 : */
571 1 : int bt_vcp_vol_ctlr_unmute(struct bt_vcp_vol_ctlr *vol_ctlr);
572 :
573 : /**
574 : * @brief Mute a remote Volume Renderer.
575 : *
576 : * @param vol_ctlr Volume Controller instance pointer.
577 : *
578 : * @return 0 if success, errno on failure.
579 : */
580 1 : int bt_vcp_vol_ctlr_mute(struct bt_vcp_vol_ctlr *vol_ctlr);
581 :
582 : #ifdef __cplusplus
583 : }
584 : #endif
585 :
586 : /**
587 : * @}
588 : */
589 :
590 : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VCP_H_ */
|