1 /*
2  * Copyright (c) 2020 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_AICS_H_
8 #define ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_AICS_H_
9 
10 /**
11  * @brief Audio Input Control Service (AICS)
12  *
13  * @defgroup bt_gatt_aics Audio Input Control Service (AICS)
14  *
15  * @ingroup bluetooth
16  * @{
17  *
18  * The Audio Input Control Service is a secondary service, and as such should not be used on 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 audio input 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 #include <bluetooth/bluetooth.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /** Audio Input Control Service mute states */
37 #define BT_AICS_STATE_UNMUTED                      0x00
38 #define BT_AICS_STATE_MUTED                        0x01
39 #define BT_AICS_STATE_MUTE_DISABLED                0x02
40 
41 /** Audio Input Control Service input modes */
42 #define BT_AICS_MODE_MANUAL_ONLY                   0x00
43 #define BT_AICS_MODE_AUTO_ONLY                     0x01
44 #define BT_AICS_MODE_MANUAL                        0x02
45 #define BT_AICS_MODE_AUTO                          0x03
46 
47 /** Audio Input Control Service input types */
48 #define BT_AICS_INPUT_TYPE_UNSPECIFIED             0x00
49 #define BT_AICS_INPUT_TYPE_BLUETOOTH               0x01
50 #define BT_AICS_INPUT_TYPE_MICROPHONE              0x02
51 #define BT_AICS_INPUT_TYPE_ANALOG                  0x03
52 #define BT_AICS_INPUT_TYPE_DIGITAL                 0x04
53 #define BT_AICS_INPUT_TYPE_RADIO                   0x05
54 #define BT_AICS_INPUT_TYPE_STREAMING               0x06
55 
56 /** Audio Input Control Service Error codes */
57 #define BT_AICS_ERR_INVALID_COUNTER                0x80
58 #define BT_AICS_ERR_OP_NOT_SUPPORTED               0x81
59 #define BT_AICS_ERR_MUTE_DISABLED                  0x82
60 #define BT_AICS_ERR_OUT_OF_RANGE                   0x83
61 #define BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED          0x84
62 
63 /** @brief Opaque Audio Input Control Service instance. */
64 struct bt_aics;
65 
66 /** @brief Structure for initializing a Audio Input Control Service instance. */
67 struct bt_aics_register_param {
68 	/** Initial audio input gain (-128 to 127) */
69 	int8_t gain;
70 
71 	/** Initial audio input mute state */
72 	uint8_t mute;
73 
74 	/** Initial audio input mode */
75 	uint8_t gain_mode;
76 
77 	/** Initial audio input gain units (N * 0.1 dB) */
78 	uint8_t units;
79 
80 	/** Initial audio input minimum gain */
81 	int8_t min_gain;
82 
83 	/** Initial audio input maximum gain */
84 	int8_t max_gain;
85 
86 	/** Initial audio input type */
87 	uint8_t type;
88 
89 	/** Initial audio input status (active/inactive) */
90 	bool status;
91 
92 	/** Boolean to set whether the description is writable by clients */
93 	bool desc_writable;
94 
95 	/** Initial audio input description */
96 	char *description;
97 
98 	/** Pointer to the callback structure. */
99 	struct bt_aics_cb *cb;
100 };
101 
102 /** @brief Structure for discovering a Audio Input Control Service instance. */
103 struct bt_aics_discover_param {
104 	/** @brief The start handle of the discovering.
105 	 *
106 	 * Typically the @p start_handle of a @ref bt_gatt_include.
107 	 */
108 	uint16_t start_handle;
109 	/** @brief The end handle of the discovering.
110 	 *
111 	 * Typically the @p end_handle of a @ref bt_gatt_include.
112 	 */
113 	uint16_t end_handle;
114 };
115 
116 /**
117  * @brief Get a free instance of Audio Input Control Service from the pool.
118  *
119  * @return Audio Input Control Service instance in case of success or NULL in case of error.
120  */
121 struct bt_aics *bt_aics_free_instance_get(void);
122 
123 /**
124  * @brief Get the service declaration attribute.
125  *
126  * The first service attribute returned can be included in any other GATT service.
127  *
128  * @param aics Audio Input Control Service instance.
129  *
130  * @return Pointer to the attributes of the service.
131  */
132 void *bt_aics_svc_decl_get(struct bt_aics *aics);
133 
134 /**
135  * @brief Get the connection pointer of a client instance
136  *
137  * Get the Bluetooth connection pointer of a Audio Input Control Service
138  * client instance.
139  *
140  * @param aics    Audio Input Control Service client instance pointer.
141  * @param conn    Connection pointer.
142  *
143  * @return 0 if success, errno on failure.
144  */
145 int bt_aics_client_conn_get(const struct bt_aics *aics, struct bt_conn **conn);
146 
147 /**
148  * @brief Initialize the Audio Input Control Service instance.
149  *
150  * @param aics      Audio Input Control Service instance.
151  * @param param     Audio Input Control Service register parameters.
152  *
153  * @return 0 if success, errno on failure.
154  */
155 int bt_aics_register(struct bt_aics *aics, struct bt_aics_register_param *param);
156 
157 /**
158  * @brief Callback function for writes.
159  *
160  * @param inst         The instance pointer.
161  * @param err          Error value. 0 on success, GATT error on positive value
162  *                     or errno on negative value.
163  */
164 typedef void (*bt_aics_write_cb)(struct bt_aics *inst, int err);
165 
166 /**
167  * @brief Callback function for the input state.
168  *
169  * Called when the value is read,
170  * or if the value is changed by either the server or client.
171  *
172  * @param inst         The instance pointer.
173  * @param err          Error value. 0 on success, GATT error on positive value
174  *                     or errno on negative value.
175  *                     For notifications, this will always be 0.
176  * @param gain         The gain setting value.
177  * @param mute         The mute value.
178  * @param mode         The mode value.
179  */
180 typedef void (*bt_aics_state_cb)(struct bt_aics *inst, int err, int8_t gain,
181 				 uint8_t mute, uint8_t mode);
182 
183 /**
184  * @brief Callback function for the gain settings.
185  *
186  * Called when the value is read,
187  * or if the value is changed by either the server or client.
188  *
189  * @param inst         The instance pointer.
190  * @param err          Error value. 0 on success, GATT error on positive value
191  *                     or errno on negative value.
192  *                     For notifications, this will always be 0.
193  * @param units        The value that reflect the size of a single increment or decrement of the
194  *                     Gain Setting value in 0.1 decibel units.
195  * @param minimum      The minimum gain allowed for the gain setting.
196  * @param maximum      The maximum gain allowed for the gain setting.
197  */
198 typedef void (*bt_aics_gain_setting_cb)(struct bt_aics *inst, int err,
199 					uint8_t units, int8_t minimum,
200 					int8_t maximum);
201 
202 /**
203  * @brief Callback function for the input type.
204  *
205  * Called when the value is read, or if the value is changed by either the server or client.
206  *
207  * @param inst         The instance pointer.
208  * @param err          Error value. 0 on success, GATT error on positive value
209  *                     or errno on negative value.
210  *                     For notifications, this will always be 0.
211  * @param type   The input type.
212  */
213 typedef void (*bt_aics_type_cb)(struct bt_aics *inst, int err, uint8_t type);
214 
215 /**
216  * @brief Callback function for the input status.
217  *
218  * Called when the value is read, or if the value is changed by either the server or client.
219  *
220  * @param inst         The instance pointer.
221  * @param err          Error value. 0 on success, GATT error on positive value
222  *                     or errno on negative value.
223  *                     For notifications, this will always be 0.
224  * @param active       Whether the instance is active or inactive.
225  */
226 typedef void (*bt_aics_status_cb)(struct bt_aics *inst, int err, bool active);
227 
228 /**
229  * @brief Callback function for the description.
230  *
231  * Called when the value is read, or if the value is changed by either the server or client.
232  *
233  * @param inst         The instance pointer.
234  * @param err          Error value. 0 on success, GATT error on positive value
235  *                     or errno on negative value.
236  *                     For notifications, this will always be 0.
237  * @param description  The description as an UTF-8 encoded string (may have been clipped).
238  */
239 typedef void (*bt_aics_description_cb)(struct bt_aics *inst, int err,
240 				       char *description);
241 
242 /**
243  * @brief Callback function for bt_aics_discover.
244  *
245  * This callback will usually be overwritten by the primary service that
246  * includes the Audio Input Control Service client.
247  *
248  * @param inst         The instance pointer.
249  * @param err          Error value. 0 on success, GATT error on positive value
250  *                     or errno on negative value.
251  *                     For notifications, this will always be 0.
252  */
253 typedef void (*bt_aics_discover_cb)(struct bt_aics *inst, int err);
254 
255 struct bt_aics_cb {
256 	bt_aics_state_cb                 state;
257 	bt_aics_gain_setting_cb          gain_setting;
258 	bt_aics_type_cb                  type;
259 	bt_aics_status_cb                status;
260 	bt_aics_description_cb           description;
261 
262 #if defined(CONFIG_BT_AICS_CLIENT)
263 	bt_aics_discover_cb              discover;
264 	bt_aics_write_cb                 set_gain;
265 	bt_aics_write_cb                 unmute;
266 	bt_aics_write_cb                 mute;
267 	bt_aics_write_cb                 set_manual_mode;
268 	bt_aics_write_cb                 set_auto_mode;
269 #endif /* CONFIG_BT_AICS_CLIENT */
270 };
271 
272 
273 /**
274  * @brief Discover a Audio Input Control Service.
275  *
276  * Attempts to discover a Audio Input Control Service on a server given the
277  * @p param.
278  *
279  * @param conn      Connection to the peer with the Audio Input Control Service.
280  * @param inst      The instance pointer.
281  * @param param     Pointer to the parameters.
282  *
283  * @return 0 on success, errno on fail.
284  */
285 int bt_aics_discover(struct bt_conn *conn, struct bt_aics *inst,
286 		     const struct bt_aics_discover_param *param);
287 
288 /**
289  * @brief Deactivates a Audio Input Control Service instance.
290  *
291  * Audio Input Control Services are activated by default, but this will allow
292  * the server to deactivate an Audio Input Control Service.
293  *
294  * @param inst         The instance pointer.
295  *
296  * @return 0 if success, errno on failure.
297  */
298 int bt_aics_deactivate(struct bt_aics *inst);
299 
300 /**
301  * @brief Activates a Audio Input Control Service instance.
302  *
303  * Audio Input Control Services are activated by default, but this will allow
304  * the server reactivate a Audio Input Control Service instance after it has
305  * been deactivated with @ref bt_aics_deactivate.
306  *
307  * @param inst         The instance pointer.
308  *
309  * @return 0 if success, errno on failure.
310  */
311 int bt_aics_activate(struct bt_aics *inst);
312 
313 /**
314  * @brief Read the Audio Input Control Service input state.
315  *
316  * @param inst          The instance pointer.
317  *
318  * @return 0 on success, GATT error value on fail.
319  */
320 int bt_aics_state_get(struct bt_aics *inst);
321 
322 /**
323  * @brief Read the Audio Input Control Service gain settings.
324  *
325  * @param inst          The instance pointer.
326  *
327  * @return 0 on success, GATT error value on fail.
328  */
329 int bt_aics_gain_setting_get(struct bt_aics *inst);
330 
331 /**
332  * @brief Read the Audio Input Control Service input type.
333  *
334  * @param inst          The instance pointer.
335  *
336  * @return 0 on success, GATT error value on fail.
337  */
338 int bt_aics_type_get(struct bt_aics *inst);
339 
340 /**
341  * @brief Read the Audio Input Control Service input status.
342  *
343  * @param inst          The instance pointer.
344  *
345  * @return 0 on success, GATT error value on fail.
346  */
347 int bt_aics_status_get(struct bt_aics *inst);
348 
349 /**
350  * @brief Unmute the Audio Input Control Service input.
351  *
352  * @param inst          The instance pointer.
353  *
354  * @return 0 on success, GATT error value on fail.
355  */
356 int bt_aics_unmute(struct bt_aics *inst);
357 
358 /**
359  * @brief Mute the Audio Input Control Service input.
360  *
361  * @param inst          The instance pointer.
362  *
363  * @return 0 on success, GATT error value on fail.
364  */
365 int bt_aics_mute(struct bt_aics *inst);
366 
367 /**
368  * @brief Set input gain to manual.
369  *
370  * @param inst          The instance pointer.
371  *
372  * @return 0 on success, GATT error value on fail.
373  */
374 int bt_aics_manual_gain_set(struct bt_aics *inst);
375 
376 /**
377  * @brief Set the input gain to automatic.
378  *
379  * @param inst          The instance pointer.
380  *
381  * @return 0 on success, GATT error value on fail.
382  */
383 int bt_aics_automatic_gain_set(struct bt_aics *inst);
384 
385 /**
386  * @brief Set the input gain.
387  *
388  * @param inst          The instance pointer.
389  * @param gain          The gain to set (-128 to 127) in gain setting units
390  *                      (see @ref bt_aics_gain_setting_cb).
391  *
392  * @return 0 on success, GATT error value on fail.
393  */
394 int bt_aics_gain_set(struct bt_aics *inst, int8_t gain);
395 
396 /**
397  * @brief Read the Audio Input Control Service description.
398  *
399  * @param inst          The instance pointer.
400  *
401  * @return 0 on success, GATT error value on fail.
402  */
403 int bt_aics_description_get(struct bt_aics *inst);
404 
405 /**
406  * @brief Set the Audio Input Control Service description.
407  *
408  * @param inst          The instance pointer.
409  * @param description   The description as an UTF-8 encoded string.
410  *
411  * @return 0 on success, GATT error value on fail.
412  */
413 int bt_aics_description_set(struct bt_aics *inst, const char *description);
414 
415 /**
416  * @brief Get a new Audio Input Control Service client instance.
417  *
418  * @return Pointer to the instance, or NULL if no free instances are left.
419  */
420 struct bt_aics *bt_aics_client_free_instance_get(void);
421 
422 /**
423  * @brief Registers the callbacks for the Audio Input Control Service client.
424  *
425  * @param inst      The instance pointer.
426  * @param cb        Pointer to the callback structure.
427  */
428 void bt_aics_client_cb_register(struct bt_aics *inst, struct bt_aics_cb *cb);
429 
430 #ifdef __cplusplus
431 }
432 #endif
433 
434 /**
435  * @}
436  */
437 
438 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_AICS_H_ */
439