1 /**
2  * @file
3  * @brief Bluetooth Audio Input Control Service 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_AICS_H_
13 #define ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_AICS_H_
14 
15 /**
16  * @brief Audio Input Control Service (AICS)
17  *
18  * @defgroup bt_aics Audio Input Control Service (AICS)
19  *
20  * @since 2.6
21  * @version 0.8.0
22  *
23  * @ingroup bluetooth
24  * @{
25  *
26  * The Audio Input Control Service is a secondary service, and as such should not be used on its
27  * own, but rather in the context of another (primary) service.
28  *
29  * This API implements both the server and client functionality.
30  * Note that the API abstracts away the change counter in the audio input control state and will
31  * automatically handle any changes to that. If out of date, the client implementation will
32  * autonomously read the change counter value when executing a write request.
33  *
34  */
35 #include <stdint.h>
36 #include <stdbool.h>
37 
38 #include <zephyr/autoconf.h>
39 #include <zephyr/bluetooth/bluetooth.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /**
46  * @name Audio Input Control Service mute states
47  * @{
48  */
49 /** The mute state is unmuted */
50 #define BT_AICS_STATE_UNMUTED                      0x00
51 /** The mute state is muted */
52 #define BT_AICS_STATE_MUTED                        0x01
53 /** The mute state is disabled */
54 #define BT_AICS_STATE_MUTE_DISABLED                0x02
55 /** @} */
56 
57 /**
58  * @name Audio Input Control Service input modes
59  * @{
60  */
61 /**
62  * @brief The gain mode is manual only and cannot be changed to automatic.
63  *
64  * The gain can be controlled by the client.
65  */
66 #define BT_AICS_MODE_MANUAL_ONLY                   0x00
67 /**
68  * @brief The gain mode is automatic only and cannot be changed to manual.
69  *
70  * The gain cannot be controlled by the client.
71  */
72 #define BT_AICS_MODE_AUTO_ONLY                     0x01
73 /**
74  * @brief The gain mode is manual.
75  *
76  * The gain can be controlled by the client.
77  */
78 #define BT_AICS_MODE_MANUAL                        0x02
79 /**
80  * @brief The gain mode is automatic.
81  *
82  * The gain cannot be controlled by the client.
83  */
84 #define BT_AICS_MODE_AUTO                          0x03
85 /** @} */
86 
87 /**
88  * @name Audio Input Control Service input types
89  * @{
90  */
91 /** The input is unspecified */
92 #define BT_AICS_INPUT_TYPE_UNSPECIFIED             0x00
93 /** The input is a Bluetooth Audio Stream */
94 #define BT_AICS_INPUT_TYPE_BLUETOOTH               0x01
95 /** The input is a microphone */
96 #define BT_AICS_INPUT_TYPE_MICROPHONE              0x02
97 /** The input is analog */
98 #define BT_AICS_INPUT_TYPE_ANALOG                  0x03
99 /** The input is digital */
100 #define BT_AICS_INPUT_TYPE_DIGITAL                 0x04
101 /** The input is a radio (AM/FM/XM/etc.) */
102 #define BT_AICS_INPUT_TYPE_RADIO                   0x05
103 /** The input is a Streaming Audio Source */
104 #define BT_AICS_INPUT_TYPE_STREAMING               0x06
105 /** The input is transparent / pass-through */
106 #define BT_AICS_INPUT_TYPE_AMBIENT                 0x07
107 /** @} */
108 
109 /**
110  * @name Audio Input Control Service Error codes
111  * @{
112  */
113 /**
114  * The Change_Counter operand value does not match the Change_Counter field value of the
115  * Audio Input State characteristic.
116  */
117 #define BT_AICS_ERR_INVALID_COUNTER                0x80
118 /** An invalid opcode has been used in a control point procedure */
119 #define BT_AICS_ERR_OP_NOT_SUPPORTED               0x81
120 /** Mute/unmute commands are disabled.(see @ref BT_AICS_STATE_MUTE_DISABLED) */
121 #define BT_AICS_ERR_MUTE_DISABLED                  0x82
122 /** An operand value used in a control point procedure is outside the permissible range */
123 #define BT_AICS_ERR_OUT_OF_RANGE                   0x83
124 /** A requested gain mode change is not allowed */
125 #define BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED          0x84
126 /** @} */
127 
128 /** @brief Opaque Audio Input Control Service instance. */
129 struct bt_aics;
130 
131 /** @brief Structure for initializing a Audio Input Control Service instance. */
132 struct bt_aics_register_param {
133 	/** Initial audio input gain (-128 to 127) */
134 	int8_t gain;
135 
136 	/** Initial audio input mute state */
137 	uint8_t mute;
138 
139 	/** Initial audio input mode */
140 	uint8_t gain_mode;
141 
142 	/** Initial audio input gain units (N * 0.1 dB) */
143 	uint8_t units;
144 
145 	/** Initial audio input minimum gain */
146 	int8_t min_gain;
147 
148 	/** Initial audio input maximum gain */
149 	int8_t max_gain;
150 
151 	/** Initial audio input type */
152 	uint8_t type;
153 
154 	/** Initial audio input status (active/inactive) */
155 	bool status;
156 
157 	/** Boolean to set whether the description is writable by clients */
158 	bool desc_writable;
159 
160 	/** Initial audio input description */
161 	char *description;
162 
163 	/** Pointer to the callback structure. */
164 	struct bt_aics_cb *cb;
165 };
166 
167 /** @brief Structure for discovering a Audio Input Control Service instance. */
168 struct bt_aics_discover_param {
169 	/**
170 	 * @brief The start handle of the discovering.
171 	 *
172 	 * Typically the @p start_handle of a @ref bt_gatt_include.
173 	 */
174 	uint16_t start_handle;
175 	/**
176 	 * @brief The end handle of the discovering.
177 	 *
178 	 * Typically the @p end_handle of a @ref bt_gatt_include.
179 	 */
180 	uint16_t end_handle;
181 };
182 
183 /**
184  * @brief Get a free instance of Audio Input Control Service from the pool.
185  *
186  * @return Audio Input Control Service instance in case of success or NULL in case of error.
187  */
188 struct bt_aics *bt_aics_free_instance_get(void);
189 
190 /**
191  * @brief Get the service declaration attribute.
192  *
193  * The first service attribute returned can be included in any other GATT service.
194  *
195  * @param aics Audio Input Control Service instance.
196  *
197  * @return Pointer to the attributes of the service.
198  */
199 void *bt_aics_svc_decl_get(struct bt_aics *aics);
200 
201 /**
202  * @brief Get the connection pointer of a client instance
203  *
204  * Get the Bluetooth connection pointer of a Audio Input Control Service
205  * client instance.
206  *
207  * @param aics    Audio Input Control Service client instance pointer.
208  * @param conn    Connection pointer.
209  *
210  * @return 0 if success, errno on failure.
211  */
212 int bt_aics_client_conn_get(const struct bt_aics *aics, struct bt_conn **conn);
213 
214 /**
215  * @brief Initialize the Audio Input Control Service instance.
216  *
217  * @param aics      Audio Input Control Service instance.
218  * @param param     Audio Input Control Service register parameters.
219  *
220  * @return 0 if success, errno on failure.
221  */
222 int bt_aics_register(struct bt_aics *aics, struct bt_aics_register_param *param);
223 
224 /**
225  * @brief Callback function for writes.
226  *
227  * @param inst         The instance pointer.
228  * @param err          Error value. 0 on success, GATT error on positive value
229  *                     or errno on negative value.
230  */
231 typedef void (*bt_aics_write_cb)(struct bt_aics *inst, int err);
232 
233 /**
234  * @brief Callback function for the input state.
235  *
236  * Called when the value is read,
237  * or if the value is changed by either the server or client.
238  *
239  * @param inst         The instance pointer.
240  * @param err          Error value. 0 on success, GATT error on positive value
241  *                     or errno on negative value.
242  *                     For notifications, this will always be 0.
243  * @param gain         The gain setting value.
244  * @param mute         The mute value.
245  * @param mode         The mode value.
246  */
247 typedef void (*bt_aics_state_cb)(struct bt_aics *inst, int err, int8_t gain,
248 				 uint8_t mute, uint8_t mode);
249 
250 /**
251  * @brief Callback function for the gain settings.
252  *
253  * Called when the value is read,
254  * or if the value is changed by either the server or client.
255  *
256  * @param inst         The instance pointer.
257  * @param err          Error value. 0 on success, GATT error on positive value
258  *                     or errno on negative value.
259  *                     For notifications, this will always be 0.
260  * @param units        The value that reflect the size of a single increment or decrement of the
261  *                     Gain Setting value in 0.1 decibel units.
262  * @param minimum      The minimum gain allowed for the gain setting.
263  * @param maximum      The maximum gain allowed for the gain setting.
264  */
265 typedef void (*bt_aics_gain_setting_cb)(struct bt_aics *inst, int err,
266 					uint8_t units, int8_t minimum,
267 					int8_t maximum);
268 
269 /**
270  * @brief Callback function for the input type.
271  *
272  * Called when the value is read, or if the value is changed by either the server or client.
273  *
274  * @param inst         The instance pointer.
275  * @param err          Error value. 0 on success, GATT error on positive value
276  *                     or errno on negative value.
277  *                     For notifications, this will always be 0.
278  * @param type   The input type.
279  */
280 typedef void (*bt_aics_type_cb)(struct bt_aics *inst, int err, uint8_t type);
281 
282 /**
283  * @brief Callback function for the input status.
284  *
285  * Called when the value is read, or if the value is changed by either the server or client.
286  *
287  * @param inst         The instance pointer.
288  * @param err          Error value. 0 on success, GATT error on positive value
289  *                     or errno on negative value.
290  *                     For notifications, this will always be 0.
291  * @param active       Whether the instance is active or inactive.
292  */
293 typedef void (*bt_aics_status_cb)(struct bt_aics *inst, int err, bool active);
294 
295 /**
296  * @brief Callback function for the description.
297  *
298  * Called when the value is read, or if the value is changed by either the server or client.
299  *
300  * @param inst         The instance pointer.
301  * @param err          Error value. 0 on success, GATT error on positive value
302  *                     or errno on negative value.
303  *                     For notifications, this will always be 0.
304  * @param description  The description as an UTF-8 encoded string (may have been clipped).
305  */
306 typedef void (*bt_aics_description_cb)(struct bt_aics *inst, int err,
307 				       char *description);
308 
309 /**
310  * @brief Callback function for bt_aics_discover.
311  *
312  * This callback will usually be overwritten by the primary service that
313  * includes the Audio Input Control Service client.
314  *
315  * @param inst         The instance pointer.
316  * @param err          Error value. 0 on success, GATT error on positive value
317  *                     or errno on negative value.
318  *                     For notifications, this will always be 0.
319  */
320 typedef void (*bt_aics_discover_cb)(struct bt_aics *inst, int err);
321 
322 /**
323  * @brief Struct to hold callbacks for the Audio Input Control Service.
324  *
325  * Used by both clients and servers
326  */
327 struct bt_aics_cb {
328 	/** The audio input state has changed */
329 	bt_aics_state_cb                 state;
330 	/** The gain setting has changed */
331 	bt_aics_gain_setting_cb          gain_setting;
332 	/** The audio input type has changed */
333 	bt_aics_type_cb                  type;
334 	/** The audio input status has changed */
335 	bt_aics_status_cb                status;
336 	/** The audio input decscription has changed */
337 	bt_aics_description_cb           description;
338 
339 #if defined(CONFIG_BT_AICS_CLIENT) || defined(__DOXYGEN__)
340 	/** The discovery has completed */
341 	bt_aics_discover_cb              discover;
342 	/** The set gain operation has completed */
343 	bt_aics_write_cb                 set_gain;
344 	/** The unmute operation has completed */
345 	bt_aics_write_cb                 unmute;
346 	/** The mut operation has completed */
347 	bt_aics_write_cb                 mute;
348 	/** The set manual mode operation has completed */
349 	bt_aics_write_cb                 set_manual_mode;
350 	/** The set automatic mode has completed */
351 	bt_aics_write_cb                 set_auto_mode;
352 #endif /* CONFIG_BT_AICS_CLIENT */
353 };
354 
355 
356 /**
357  * @brief Discover a Audio Input Control Service.
358  *
359  * Attempts to discover a Audio Input Control Service on a server given the
360  * @p param.
361  *
362  * @param conn      Connection to the peer with the Audio Input Control Service.
363  * @param inst      The instance pointer.
364  * @param param     Pointer to the parameters.
365  *
366  * @return 0 on success, errno on fail.
367  */
368 int bt_aics_discover(struct bt_conn *conn, struct bt_aics *inst,
369 		     const struct bt_aics_discover_param *param);
370 
371 /**
372  * @brief Deactivates a Audio Input Control Service instance.
373  *
374  * Audio Input Control Services are activated by default, but this will allow
375  * the server to deactivate an Audio Input Control Service.
376  *
377  * @param inst         The instance pointer.
378  *
379  * @return 0 if success, errno on failure.
380  */
381 int bt_aics_deactivate(struct bt_aics *inst);
382 
383 /**
384  * @brief Activates a Audio Input Control Service instance.
385  *
386  * Audio Input Control Services are activated by default, but this will allow
387  * the server reactivate a Audio Input Control Service instance after it has
388  * been deactivated with @ref bt_aics_deactivate.
389  *
390  * @param inst         The instance pointer.
391  *
392  * @return 0 if success, errno on failure.
393  */
394 int bt_aics_activate(struct bt_aics *inst);
395 
396 /**
397  * @brief Read the Audio Input Control Service input state.
398  *
399  * @param inst          The instance pointer.
400  *
401  * @return 0 on success, GATT error value on fail.
402  */
403 int bt_aics_state_get(struct bt_aics *inst);
404 
405 /**
406  * @brief Read the Audio Input Control Service gain settings.
407  *
408  * @param inst          The instance pointer.
409  *
410  * @return 0 on success, GATT error value on fail.
411  */
412 int bt_aics_gain_setting_get(struct bt_aics *inst);
413 
414 /**
415  * @brief Read the Audio Input Control Service input type.
416  *
417  * @param inst          The instance pointer.
418  *
419  * @return 0 on success, GATT error value on fail.
420  */
421 int bt_aics_type_get(struct bt_aics *inst);
422 
423 /**
424  * @brief Read the Audio Input Control Service input status.
425  *
426  * @param inst          The instance pointer.
427  *
428  * @return 0 on success, GATT error value on fail.
429  */
430 int bt_aics_status_get(struct bt_aics *inst);
431 
432 /**
433  * @brief Disable mute in the Audio Input Control Service.
434  *
435  * Calling bt_aics_unmute() or bt_aics_mute() will enable
436  * mute again and set the mute state to either unmuted or muted.
437  *
438  * @param inst          The instance pointer.
439  *
440  * @return 0 on success, errno value on fail.
441  */
442 int bt_aics_disable_mute(struct bt_aics *inst);
443 
444 /**
445  * @brief Unmute the Audio Input Control Service input.
446  *
447  * @param inst          The instance pointer.
448  *
449  * @return 0 on success, GATT error value on fail.
450  */
451 int bt_aics_unmute(struct bt_aics *inst);
452 
453 /**
454  * @brief Mute the Audio Input Control Service input.
455  *
456  * @param inst          The instance pointer.
457  *
458  * @return 0 on success, GATT error value on fail.
459  */
460 int bt_aics_mute(struct bt_aics *inst);
461 
462 /**
463  * @brief Set manual only gain mode in Audio Input Control Service.
464  *
465  * @param inst          The instance pointer.
466  *
467  * @return 0 on success, errno value on fail.
468  */
469 int bt_aics_gain_set_manual_only(struct bt_aics *inst);
470 
471 /**
472  * @brief Set automatic only gain mode in Audio Input Control Service.
473  *
474  * Using this function and enabling automatic only gain disables
475  * setting the gain with bt_aics_gain_set
476  *
477  * @param inst          The instance pointer.
478  *
479  * @return 0 on success, errno value on fail.
480  */
481 int bt_aics_gain_set_auto_only(struct bt_aics *inst);
482 
483 /**
484  * @brief Set input gain to manual.
485  *
486  * @param inst          The instance pointer.
487  *
488  * @return 0 on success, GATT error value on fail.
489  */
490 int bt_aics_manual_gain_set(struct bt_aics *inst);
491 
492 /**
493  * @brief Set the input gain to automatic.
494  *
495  * @param inst          The instance pointer.
496  *
497  * @return 0 on success, GATT error value on fail.
498  */
499 int bt_aics_automatic_gain_set(struct bt_aics *inst);
500 
501 /**
502  * @brief Set the input gain.
503  *
504  * @param inst          The instance pointer.
505  * @param gain          The gain to set (-128 to 127) in gain setting units
506  *                      (see @ref bt_aics_gain_setting_cb).
507  *
508  * @return 0 on success, GATT error value on fail.
509  */
510 int bt_aics_gain_set(struct bt_aics *inst, int8_t gain);
511 
512 /**
513  * @brief Read the Audio Input Control Service description.
514  *
515  * @param inst          The instance pointer.
516  *
517  * @return 0 on success, GATT error value on fail.
518  */
519 int bt_aics_description_get(struct bt_aics *inst);
520 
521 /**
522  * @brief Set the Audio Input Control Service description.
523  *
524  * @param inst          The instance pointer.
525  * @param description   The description as an UTF-8 encoded string.
526  *
527  * @return 0 on success, GATT error value on fail.
528  */
529 int bt_aics_description_set(struct bt_aics *inst, const char *description);
530 
531 /**
532  * @brief Get a new Audio Input Control Service client instance.
533  *
534  * @return Pointer to the instance, or NULL if no free instances are left.
535  */
536 struct bt_aics *bt_aics_client_free_instance_get(void);
537 
538 /**
539  * @brief Registers the callbacks for the Audio Input Control Service client.
540  *
541  * @param inst      The instance pointer.
542  * @param cb        Pointer to the callback structure.
543  */
544 void bt_aics_client_cb_register(struct bt_aics *inst, struct bt_aics_cb *cb);
545 
546 #ifdef __cplusplus
547 }
548 #endif
549 
550 /**
551  * @}
552  */
553 
554 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_AICS_H_ */
555