Skip to content

Commit ed2162c

Browse files
Thalleynashif
authored andcommitted
Bluetooth: Audio: Volume Offset Control Service and Client
This commit implements the secondary service Volume Offset Control Service (VOCS) server and client. Signed-off-by: Emil Gydesen <[email protected]>
1 parent cdd02a9 commit ed2162c

File tree

10 files changed

+1692
-0
lines changed

10 files changed

+1692
-0
lines changed

include/bluetooth/audio/vocs.h

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
/*
2+
* Copyright (c) 2020 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VOCS_H_
8+
#define ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VOCS_H_
9+
10+
/**
11+
* @brief Volume Offset Control Service (VOCS)
12+
*
13+
* @defgroup bt_gatt_vocs Volume Offset Control Service (VOCS)
14+
*
15+
* @ingroup bluetooth
16+
* @{
17+
*
18+
* The Volume Offset Control Service is a secondary service, and as such should not be used own its
19+
* own, but rather in the context of another (primary) service.
20+
*
21+
* This API implements both the server and client functionality.
22+
* Note that the API abstracts away the change counter in the volume offset control state and will
23+
* automatically handle any changes to that. If out of date, the client implementation will
24+
* autonomously read the change counter value when executing a write request.
25+
*
26+
* [Experimental] Users should note that the APIs can change as a part of ongoing development.
27+
*/
28+
29+
#include <zephyr/types.h>
30+
31+
#ifdef __cplusplus
32+
extern "C" {
33+
#endif
34+
35+
/** Volume Offset Control Service Error codes */
36+
#define BT_VOCS_ERR_INVALID_COUNTER 0x80
37+
#define BT_VOCS_ERR_OP_NOT_SUPPORTED 0x81
38+
#define BT_VOCS_ERR_OUT_OF_RANGE 0x82
39+
40+
#define BT_VOCS_MIN_OFFSET -255
41+
#define BT_VOCS_MAX_OFFSET 255
42+
43+
/** @brief Opaque Volume Offset Control Service instance. */
44+
struct bt_vocs;
45+
46+
/** @brief Structure for initializing a Volume Offset Control Service instance. */
47+
struct bt_vocs_init_param {
48+
/** Audio Location bitmask */
49+
uint32_t location;
50+
51+
/** Boolean to set whether the location is writable by clients */
52+
bool location_writable;
53+
54+
/** Initial volume offset (-255 to 255) */
55+
int16_t offset;
56+
57+
/** Initial audio output description */
58+
char *output_desc;
59+
60+
/** Boolean to set whether the description is writable by clients */
61+
bool desc_writable;
62+
};
63+
64+
/** @brief Structure for discovering a Volume Offset Control Service instance. */
65+
struct bt_vocs_discover_param {
66+
/**
67+
* @brief The start handle of the discovering.
68+
*
69+
* Typically the @p start_handle of a @ref bt_gatt_include.
70+
*/
71+
uint16_t start_handle;
72+
/**
73+
* @brief The end handle of the discovering.
74+
*
75+
* Typically the @p end_handle of a @ref bt_gatt_include.
76+
*/
77+
uint16_t end_handle;
78+
};
79+
80+
/**
81+
* @brief Get a free service instance of Volume Offset Control Service from the pool.
82+
*
83+
* @return Volume Offset Control Service instance in case of success or NULL in case of error.
84+
*/
85+
struct bt_vocs *bt_vocs_free_instance_get(void);
86+
87+
/**
88+
* @brief Get the service declaration attribute.
89+
*
90+
* The first service attribute returned can be included in any other GATT service.
91+
*
92+
* @param vocs Volume Offset Control Service instance.
93+
*
94+
* @return Pointer to the attributes of the service.
95+
*/
96+
void *bt_vocs_svc_decl_get(struct bt_vocs *vocs);
97+
98+
/**
99+
* @brief Initialize the Volume Offset Control Service instance.
100+
*
101+
* @param vocs Volume Offset Control Service instance.
102+
* @param init Volume Offset Control Service initialization structure.
103+
* May be NULL to use default values.
104+
*
105+
* @return 0 if success, errno on failure.
106+
*/
107+
int bt_vocs_init(struct bt_vocs *vocs, const struct bt_vocs_init_param *init);
108+
109+
/**
110+
* @brief Callback function for the offset state.
111+
*
112+
* Called when the value is read, or if the value is changed by either the server or client.
113+
*
114+
* @param conn Connection to peer device, or NULL if local server read.
115+
* @param inst The instance pointer.
116+
* @param err Error value. 0 on success, GATT error on positive value
117+
* or errno on negative value.
118+
* For notifications, this will always be 0.
119+
* @param offset The offset value.
120+
*/
121+
typedef void (*bt_vocs_state_cb_t)(struct bt_conn *conn, struct bt_vocs *inst,
122+
int err, int16_t offset);
123+
124+
/**
125+
* @brief Callback function for setting offset.
126+
*
127+
* @param conn Connection to peer device, or NULL if local server write.
128+
* @param inst The instance pointer.
129+
* @param err Error value. 0 on success, GATT error on positive value
130+
* or errno on negative value.
131+
*/
132+
typedef void (*bt_vocs_set_offset_cb_t)(struct bt_conn *conn, struct bt_vocs *inst, int err);
133+
134+
/**
135+
* @brief Callback function for the location.
136+
*
137+
* Called when the value is read, or if the value is changed by either the server or client.
138+
*
139+
* @param conn Connection to peer device, or NULL if local server read.
140+
* @param inst The instance pointer.
141+
* @param err Error value. 0 on success, GATT error on positive value
142+
* or errno on negative value.
143+
* For notifications, this will always be 0.
144+
* @param location The location value.
145+
*/
146+
typedef void (*bt_vocs_location_cb_t)(struct bt_conn *conn, struct bt_vocs *inst, int err,
147+
uint32_t location);
148+
149+
/**
150+
* @brief Callback function for the description.
151+
*
152+
* Called when the value is read, or if the value is changed by either the server or client.
153+
*
154+
* @param conn Connection to peer device, or NULL if local server read.
155+
* @param inst The instance pointer.
156+
* @param err Error value. 0 on success, GATT error on positive value
157+
* or errno on negative value.
158+
* For notifications, this will always be 0.
159+
* @param description The description as an UTF-8 encoded string.
160+
*/
161+
typedef void (*bt_vocs_description_cb_t)(struct bt_conn *conn, struct bt_vocs *inst, int err,
162+
char *description);
163+
164+
/**
165+
* @brief Callback function for bt_vocs_discover.
166+
*
167+
* This callback will usually be overwritten by the primary service that
168+
* includes the Volume Control Offset Service client.
169+
*
170+
* @param conn Connection to peer device, or NULL if local server read.
171+
* @param inst The instance pointer.
172+
* @param err Error value. 0 on success, GATT error on positive value
173+
* or errno on negative value.
174+
* For notifications, this will always be 0.
175+
*/
176+
typedef void (*bt_vocs_discover_cb_t)(struct bt_conn *conn, struct bt_vocs *inst, int err);
177+
178+
struct bt_vocs_cb {
179+
bt_vocs_state_cb_t state;
180+
bt_vocs_location_cb_t location;
181+
bt_vocs_description_cb_t description;
182+
183+
#if defined(CONFIG_BT_VOCS_CLIENT)
184+
/* Client only */
185+
bt_vocs_discover_cb_t discover;
186+
bt_vocs_set_offset_cb_t set_offset;
187+
#endif /* CONFIG_BT_VOCS_CLIENT */
188+
};
189+
190+
/**
191+
* @brief Read the Volume Offset Control Service offset state.
192+
*
193+
* The value is returned in the bt_vocs_cb.state callback.
194+
*
195+
* @param conn Connection to peer device, or NULL to read local server value.
196+
* @param inst Pointer to the Volume Offset Control Service instance.
197+
*
198+
* @return 0 on success, GATT error value on fail.
199+
*/
200+
int bt_vocs_state_get(struct bt_conn *conn, struct bt_vocs *inst);
201+
202+
/**
203+
* @brief Set the Volume Offset Control Service offset state.
204+
*
205+
* @param conn Connection to peer device, or NULL to set local server value.
206+
* @param inst Pointer to the Volume Offset Control Service instance.
207+
* @param offset The offset to set (-255 to 255).
208+
*
209+
* @return 0 on success, GATT error value on fail.
210+
*/
211+
int bt_vocs_state_set(struct bt_conn *conn, struct bt_vocs *inst, int16_t offset);
212+
213+
/**
214+
* @brief Read the Volume Offset Control Service location.
215+
*
216+
* The value is returned in the bt_vocs_cb.location callback.
217+
*
218+
* @param conn Connection to peer device, or NULL to read local server value.
219+
* @param inst Pointer to the Volume Offset Control Service instance.
220+
*
221+
* @return 0 on success, GATT error value on fail.
222+
*/
223+
int bt_vocs_location_get(struct bt_conn *conn, struct bt_vocs *inst);
224+
225+
/**
226+
* @brief Set the Volume Offset Control Service location.
227+
*
228+
* @param conn Connection to peer device, or NULL to read local server value.
229+
* @param inst Pointer to the Volume Offset Control Service instance.
230+
* @param location The location to set.
231+
*
232+
* @return 0 on success, GATT error value on fail.
233+
*/
234+
int bt_vocs_location_set(struct bt_conn *conn, struct bt_vocs *inst, uint32_t location);
235+
236+
/**
237+
* @brief Read the Volume Offset Control Service output description.
238+
*
239+
* The value is returned in the bt_vocs_cb.description callback.
240+
*
241+
* @param conn Connection to peer device, or NULL to read local server value.
242+
* @param inst Pointer to the Volume Offset Control Service instance.
243+
*
244+
* @return 0 on success, GATT error value on fail.
245+
*/
246+
int bt_vocs_description_get(struct bt_conn *conn, struct bt_vocs *inst);
247+
248+
/**
249+
* @brief Set the Volume Offset Control Service description.
250+
*
251+
* @param conn Connection to peer device, or NULL to set local server value.
252+
* @param inst Pointer to the Volume Offset Control Service instance.
253+
* @param description The UTF-8 encoded string description to set.
254+
*
255+
* @return 0 on success, GATT error value on fail.
256+
*/
257+
int bt_vocs_description_set(struct bt_conn *conn, struct bt_vocs *inst,
258+
const char *description);
259+
260+
/**
261+
* @brief Register callbacks for the Volume Offset Control Service.
262+
*
263+
* @param inst Pointer to the Volume Offset Control Service instance.
264+
* @param cb Pointer to the callback structure.
265+
*
266+
* @return 0 on success, GATT error value on fail.
267+
*/
268+
int bt_vocs_cb_register(struct bt_vocs *inst, struct bt_vocs_cb *cb);
269+
270+
/**
271+
* @brief Registers the callbacks for the Volume Offset Control Service client.
272+
*
273+
* @param inst Pointer to the Volume Offset Control Service client instance.
274+
* @param cb Pointer to the callback structure.
275+
*/
276+
void bt_vocs_client_cb_register(struct bt_vocs *inst, struct bt_vocs_cb *cb);
277+
278+
/**
279+
* @brief Returns a pointer to a Volume Offset Control Service client instance.
280+
*
281+
* @return Pointer to the instance, or NULL if no free instances are left.
282+
*/
283+
struct bt_vocs *bt_vocs_client_free_instance_get(void);
284+
285+
/**
286+
* @brief Discover a Volume Offset Control Service.
287+
*
288+
* Attempts to discover a Volume Offset Control Service on a server given the @p param.
289+
*
290+
* @param conn Connection to the peer with the Volume Offset Control Service.
291+
* @param inst Pointer to the Volume Offset Control Service client instance.
292+
* @param param Pointer to the parameters.
293+
*
294+
* @return 0 on success, errno on fail.
295+
*/
296+
int bt_vocs_discover(struct bt_conn *conn, struct bt_vocs *inst,
297+
const struct bt_vocs_discover_param *param);
298+
299+
#ifdef __cplusplus
300+
}
301+
#endif
302+
303+
/**
304+
* @}
305+
*/
306+
307+
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VOCS_H_ */

include/bluetooth/uuid.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,15 @@ struct bt_uuid_128 {
383383
*/
384384
#define BT_UUID_MESH_PROXY \
385385
BT_UUID_DECLARE_16(BT_UUID_MESH_PROXY_VAL)
386+
/** @def BT_UUID_VOCS_VAL
387+
* @brief Volume Offset Control Service value
388+
*/
389+
#define BT_UUID_VOCS_VAL 0x1845
390+
/** @def BT_UUID_VOCS
391+
* @brief Volume Offset Control Service
392+
*/
393+
#define BT_UUID_VOCS \
394+
BT_UUID_DECLARE_16(BT_UUID_VOCS_VAL)
386395
/** @def BT_UUID_GATT_PRIMARY_VAL
387396
* @brief GATT Primary Service UUID value
388397
*/
@@ -1214,6 +1223,43 @@ struct bt_uuid_128 {
12141223
#define BT_UUID_GATT_SERVER_FEATURES \
12151224
BT_UUID_DECLARE_16(BT_UUID_GATT_SERVER_FEATURES_VAL)
12161225

1226+
/** @def BT_UUID_VOCS_STATE_VAL
1227+
* @brief Volume Offset State value
1228+
*/
1229+
#define BT_UUID_VOCS_STATE_VAL 0x2B80
1230+
/** @def BT_UUID_VOCS_STATE
1231+
* @brief Volume Offset State
1232+
*/
1233+
#define BT_UUID_VOCS_STATE \
1234+
BT_UUID_DECLARE_16(BT_UUID_VOCS_STATE_VAL)
1235+
/** @def BT_UUID_VOCS_LOCATION_VAL
1236+
* @brief Audio Location value
1237+
*/
1238+
#define BT_UUID_VOCS_LOCATION_VAL 0x2B81
1239+
/** @def BT_UUID_VOCS_LOCATION
1240+
* @brief Audio Location
1241+
*/
1242+
#define BT_UUID_VOCS_LOCATION \
1243+
BT_UUID_DECLARE_16(BT_UUID_VOCS_LOCATION_VAL)
1244+
/** @def BT_UUID_VOCS_CONTROL_VAL
1245+
* @brief Volume Offset Control Point value
1246+
*/
1247+
#define BT_UUID_VOCS_CONTROL_VAL 0x2B82
1248+
/** @def BT_UUID_VOCS_CONTROL
1249+
* @brief Volume Offset Control Point
1250+
*/
1251+
#define BT_UUID_VOCS_CONTROL \
1252+
BT_UUID_DECLARE_16(BT_UUID_VOCS_CONTROL_VAL)
1253+
/** @def BT_UUID_VOCS_DESCRIPTION_VAL
1254+
* @brief Volume Offset Audio Output Description value
1255+
*/
1256+
#define BT_UUID_VOCS_DESCRIPTION_VAL 0x2B83
1257+
/** @def BT_UUID_VOCS_DESCRIPTION
1258+
* @brief Volume Offset Audio Output Description
1259+
*/
1260+
#define BT_UUID_VOCS_DESCRIPTION \
1261+
BT_UUID_DECLARE_16(BT_UUID_VOCS_DESCRIPTION_VAL)
1262+
12171263
/*
12181264
* Protocol UUIDs
12191265
*/

subsys/bluetooth/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_subdirectory_ifdef(CONFIG_BT_HCI host)
99
add_subdirectory_ifdef(CONFIG_BT_SHELL shell)
1010
add_subdirectory_ifdef(CONFIG_BT_CONN services)
1111
add_subdirectory_ifdef(CONFIG_BT_MESH mesh)
12+
add_subdirectory_ifdef(CONFIG_BT_AUDIO audio)
1213

1314
if(CONFIG_BT_CTLR AND CONFIG_BT_LL_SW_SPLIT)
1415
add_subdirectory(controller)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
zephyr_library()
4+
zephyr_library_link_libraries(subsys__bluetooth)
5+
6+
if (CONFIG_BT_VOCS OR CONFIG_BT_VOCS_CLIENT)
7+
zephyr_library_sources(vocs.c)
8+
endif()
9+
zephyr_library_sources_ifdef(CONFIG_BT_VOCS_CLIENT vocs_client.c)

subsys/bluetooth/audio/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,7 @@ config BT_AUDIO_DEBUG
5050
Use this option to enable debug logs for the Bluetooth
5151
Audio functionality.
5252

53+
54+
source "subsys/bluetooth/audio/Kconfig.vocs"
55+
5356
endif # BT_AUDIO

0 commit comments

Comments
 (0)