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 registering a Volume Offset Control Service instance. */
47 struct bt_vocs_register_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 	/** Pointer to the callback structure. */
64 	struct bt_vocs_cb *cb;
65 };
66 
67 /** @brief Structure for discovering a Volume Offset Control Service instance. */
68 struct bt_vocs_discover_param {
69 	/**
70 	 * @brief The start handle of the discovering.
71 	 *
72 	 * Typically the @p start_handle of a @ref bt_gatt_include.
73 	 */
74 	uint16_t start_handle;
75 	/**
76 	 * @brief The end handle of the discovering.
77 	 *
78 	 * Typically the @p end_handle of a @ref bt_gatt_include.
79 	 */
80 	uint16_t end_handle;
81 };
82 
83 /**
84  * @brief Get a free service instance of Volume Offset Control Service from the pool.
85  *
86  * @return Volume Offset Control Service instance in case of success or NULL in case of error.
87  */
88 struct bt_vocs *bt_vocs_free_instance_get(void);
89 
90 /**
91  * @brief Get the service declaration attribute.
92  *
93  * The first service attribute returned can be included in any other GATT service.
94  *
95  * @param vocs Volume Offset Control Service instance.
96  *
97  * @return Pointer to the attributes of the service.
98  */
99 void *bt_vocs_svc_decl_get(struct bt_vocs *vocs);
100 
101 /**
102  * @brief Get the connection pointer of a client instance
103  *
104  * Get the Bluetooth connection pointer of a Audio Input Control Service
105  * client instance.
106  *
107  * @param vocs    Audio Input Control Service client instance pointer.
108  * @param conn    Connection pointer.
109  *
110  * @return 0 if success, errno on failure.
111  */
112 int bt_vocs_client_conn_get(const struct bt_vocs *vocs, struct bt_conn **conn);
113 
114 /**
115  * @brief Register the Volume Offset Control Service instance.
116  *
117  * @param vocs      Volume Offset Control Service instance.
118  * @param param     Volume Offset Control Service register parameters.
119  *
120  * @return 0 if success, errno on failure.
121  */
122 int bt_vocs_register(struct bt_vocs *vocs,
123 		     const struct bt_vocs_register_param *param);
124 
125 /**
126  * @brief Callback function for the offset state.
127  *
128  * Called when the value is read, or if the value is changed by either the server or client.
129  *
130  * @param inst        The instance pointer.
131  * @param err         Error value. 0 on success, GATT error on positive value
132  *                    or errno on negative value.
133  *                    For notifications, this will always be 0.
134  * @param offset      The offset value.
135  */
136 typedef void (*bt_vocs_state_cb)(struct bt_vocs *inst, int err, int16_t offset);
137 
138 /**
139  * @brief Callback function for setting offset.
140  *
141  * @param inst        The instance pointer.
142  * @param err         Error value. 0 on success, GATT error on positive value
143  *                    or errno on negative value.
144  */
145 typedef void (*bt_vocs_set_offset_cb)(struct bt_vocs *inst, int err);
146 
147 /**
148  * @brief Callback function for the location.
149  *
150  * Called when the value is read, or if the value is changed by either the server or client.
151  *
152  * @param inst         The instance pointer.
153  * @param err          Error value. 0 on success, GATT error on positive value
154  *                     or errno on negative value.
155  *                     For notifications, this will always be 0.
156  * @param location     The location value.
157  */
158 typedef void (*bt_vocs_location_cb)(struct bt_vocs *inst, int err,
159 				    uint32_t location);
160 
161 /**
162  * @brief Callback function for the description.
163  *
164  * Called when the value is read, or if the value is changed by either the server or client.
165  *
166  * @param inst         The instance pointer.
167  * @param err          Error value. 0 on success, GATT error on positive value
168  *                     or errno on negative value.
169  *                     For notifications, this will always be 0.
170  * @param description  The description as an UTF-8 encoded string.
171  */
172 typedef void (*bt_vocs_description_cb)(struct bt_vocs *inst, int err,
173 				       char *description);
174 
175 /**
176  * @brief Callback function for bt_vocs_discover.
177  *
178  * This callback should be overwritten by the primary service that
179  * includes the Volume Control Offset Service client, and should thus not be
180  * set by the application.
181  *
182  * @param inst         The instance pointer.
183  * @param err          Error value. 0 on success, GATT error on positive value
184  *                     or errno on negative value.
185  *                     For notifications, this will always be 0.
186  */
187 typedef void (*bt_vocs_discover_cb)(struct bt_vocs *inst, int err);
188 
189 struct bt_vocs_cb {
190 	bt_vocs_state_cb                state;
191 	bt_vocs_location_cb             location;
192 	bt_vocs_description_cb          description;
193 
194 #if defined(CONFIG_BT_VOCS_CLIENT)
195 	/* Client only */
196 	bt_vocs_discover_cb             discover;
197 	bt_vocs_set_offset_cb           set_offset;
198 #endif /* CONFIG_BT_VOCS_CLIENT */
199 };
200 
201 /**
202  * @brief Read the Volume Offset Control Service offset state.
203  *
204  * The value is returned in the bt_vocs_cb.state callback.
205  *
206  * @param inst          Pointer to the Volume Offset Control Service instance.
207  *
208  * @return 0 on success, GATT error value on fail.
209  */
210 int bt_vocs_state_get(struct bt_vocs *inst);
211 
212 /**
213  * @brief Set the Volume Offset Control Service offset state.
214  *
215  * @param inst          Pointer to the Volume Offset Control Service instance.
216  * @param offset        The offset to set (-255 to 255).
217  *
218  * @return 0 on success, GATT error value on fail.
219  */
220 int bt_vocs_state_set(struct bt_vocs *inst, int16_t offset);
221 
222 /**
223  * @brief Read the Volume Offset Control Service location.
224  *
225  * The value is returned in the bt_vocs_cb.location callback.
226  *
227  * @param inst          Pointer to the Volume Offset Control Service instance.
228  *
229  * @return 0 on success, GATT error value on fail.
230  */
231 int bt_vocs_location_get(struct bt_vocs *inst);
232 
233 /**
234  * @brief Set the Volume Offset Control Service location.
235  *
236  * @param inst          Pointer to the Volume Offset Control Service instance.
237  * @param location      The location to set.
238  *
239  * @return 0 on success, GATT error value on fail.
240  */
241 int bt_vocs_location_set(struct bt_vocs *inst, uint32_t location);
242 
243 /**
244  * @brief Read the Volume Offset Control Service output description.
245  *
246  * The value is returned in the bt_vocs_cb.description callback.
247  *
248  * @param inst          Pointer to the Volume Offset Control Service instance.
249  *
250  * @return 0 on success, GATT error value on fail.
251  */
252 int bt_vocs_description_get(struct bt_vocs *inst);
253 
254 /**
255  * @brief Set the Volume Offset Control Service description.
256  *
257  * @param inst          Pointer to the Volume Offset Control Service instance.
258  * @param description   The UTF-8 encoded string description to set.
259  *
260  * @return 0 on success, GATT error value on fail.
261  */
262 int bt_vocs_description_set(struct bt_vocs *inst, const char *description);
263 
264 /**
265  * @brief Registers the callbacks for the Volume Offset Control Service client.
266  *
267  * @param inst  Pointer to the Volume Offset Control Service client instance.
268  * @param cb    Pointer to the callback structure.
269  */
270 void bt_vocs_client_cb_register(struct bt_vocs *inst, struct bt_vocs_cb *cb);
271 
272 /**
273  * @brief Returns a pointer to a Volume Offset Control Service client instance.
274  *
275  * @return Pointer to the instance, or NULL if no free instances are left.
276  */
277 struct bt_vocs *bt_vocs_client_free_instance_get(void);
278 
279 /**
280  * @brief Discover a Volume Offset Control Service.
281  *
282  * Attempts to discover a Volume Offset Control Service on a server given the @p param.
283  *
284  * @param conn  Connection to the peer with the Volume Offset Control Service.
285  * @param inst  Pointer to the Volume Offset Control Service client instance.
286  * @param param Pointer to the parameters.
287  *
288  * @return 0 on success, errno on fail.
289  */
290 int bt_vocs_discover(struct bt_conn *conn, struct bt_vocs *inst,
291 		     const struct bt_vocs_discover_param *param);
292 
293 #ifdef __cplusplus
294 }
295 #endif
296 
297 /**
298  * @}
299  */
300 
301 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VOCS_H_ */
302