/* * Copyright (c) 2022 Codecoup * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_HAS_H_ #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_HAS_H_ /** * @brief Hearing Access Service (HAS) * * @defgroup bt_has Hearing Access Service (HAS) * * @ingroup bluetooth * @{ * * The Hearing Access Service is used to identify a hearing aid and optionally * to control hearing aid presets. * * [Experimental] Users should note that the APIs can change as a part of * ongoing development. */ #include #include #include #ifdef __cplusplus extern "C" { #endif /** Preset index definitions */ #define BT_HAS_PRESET_INDEX_NONE 0x00 #define BT_HAS_PRESET_INDEX_FIRST 0x01 #define BT_HAS_PRESET_INDEX_LAST 0xFF /** Preset name minimum length */ #define BT_HAS_PRESET_NAME_MIN 1 /** Preset name maximum length */ #define BT_HAS_PRESET_NAME_MAX 40 /** @brief Opaque Hearing Access Service object. */ struct bt_has; /** Hearing Aid device type */ enum bt_has_hearing_aid_type { BT_HAS_HEARING_AID_TYPE_BINAURAL = 0x00, BT_HAS_HEARING_AID_TYPE_MONAURAL = 0x01, BT_HAS_HEARING_AID_TYPE_BANDED = 0x02, }; /** Preset Properties values */ enum bt_has_properties { /** No properties set */ BT_HAS_PROP_NONE = 0, /** Preset name can be written by the client */ BT_HAS_PROP_WRITABLE = BIT(0), /** Preset availability */ BT_HAS_PROP_AVAILABLE = BIT(1), }; /** Hearing Aid device capablilities */ enum bt_has_capabilities { BT_HAS_PRESET_SUPPORT = BIT(0), }; /** @brief Structure for registering features of a Hearing Access Service instance. */ struct bt_has_features_param { /** Hearing Aid Type value */ enum bt_has_hearing_aid_type type; /** * @brief Preset Synchronization Support. * * Only applicable if @p type is @ref BT_HAS_HEARING_AID_TYPE_BINAURAL * and @kconfig{CONFIG_BT_HAS_PRESET_COUNT} is non-zero. */ bool preset_sync_support; /** * @brief Independent Presets. * * Only applicable if @p type is @ref BT_HAS_HEARING_AID_TYPE_BINAURAL * and @kconfig{CONFIG_BT_HAS_PRESET_COUNT} is non-zero. */ bool independent_presets; }; /** @brief Preset record definition */ struct bt_has_preset_record { /** Unique preset index. */ uint8_t index; /** Bitfield of preset properties. */ enum bt_has_properties properties; /** Preset name. */ const char *name; }; /** @brief Hearing Access Service Client callback structure. */ struct bt_has_client_cb { /** * @brief Callback function for bt_has_discover. * * This callback is called when discovery procedure is complete. * * @param conn Bluetooth connection object. * @param err 0 on success, ATT error or negative errno otherwise. * @param has Pointer to the Hearing Access Service object or NULL on errors. * @param type Hearing Aid type. * @param caps Hearing Aid capabilities. */ void (*discover)(struct bt_conn *conn, int err, struct bt_has *has, enum bt_has_hearing_aid_type type, enum bt_has_capabilities caps); /** * @brief Callback function for Hearing Access Service active preset changes. * * Optional callback called when the active preset is changed by the remote server when the * preset switch procedure is complete. The callback must be set to receive active preset * changes and enable support for switching presets. If the callback is not set, the Active * Index and Control Point characteristics will not be discovered by * @ref bt_has_client_discover. * * @param has Pointer to the Hearing Access Service object. * @param err 0 on success, ATT error or negative errno otherwise. * @param index Active preset index. */ void (*preset_switch)(struct bt_has *has, int err, uint8_t index); /** * @brief Callback function for presets read operation. * * The callback is called when the preset read response is sent by the remote server. * The record object as well as its members are temporary and must be copied to in order * to cache its information. * * @param has Pointer to the Hearing Access Service object. * @param err 0 on success, ATT error or negative errno otherwise. * @param record Preset record or NULL on errors. * @param is_last True if Read Presets operation can be considered concluded. */ void (*preset_read_rsp)(struct bt_has *has, int err, const struct bt_has_preset_record *record, bool is_last); /** * @brief Callback function for preset update notifications. * * The callback is called when the preset record update is notified by the remote server. * The record object as well as its objects are temporary and must be copied to in order * to cache its information. * * @param has Pointer to the Hearing Access Service object. * @param index_prev Index of the previous preset in the list. * @param record Preset record. * @param is_last True if preset list update operation can be considered concluded. */ void (*preset_update)(struct bt_has *has, uint8_t index_prev, const struct bt_has_preset_record *record, bool is_last); /** * @brief Callback function for preset deletion notifications. * * The callback is called when the preset has been deleted by the remote server. * * @param has Pointer to the Hearing Access Service object. * @param index Preset index. * @param is_last True if preset list update operation can be considered concluded. */ void (*preset_deleted)(struct bt_has *has, uint8_t index, bool is_last); /** * @brief Callback function for preset availability notifications. * * The callback is called when the preset availability change is notified by the remote * server. * * @param has Pointer to the Hearing Access Service object. * @param index Preset index. * @param available True if available, false otherwise. * @param is_last True if preset list update operation can be considered concluded. */ void (*preset_availability)(struct bt_has *has, uint8_t index, bool available, bool is_last); }; /** @brief Registers the callbacks used by the Hearing Access Service client. * * @param cb The callback structure. * * @return 0 in case of success or negative value in case of error. */ int bt_has_client_cb_register(const struct bt_has_client_cb *cb); /** * @brief Discover Hearing Access Service on a remote device. * * Client method to find a Hearing Access Service on a server identified by @p conn. * The @ref bt_has_client_cb.discover callback will be called when the discovery procedure * is complete to provide user a @ref bt_has object. * * @param conn Bluetooth connection object. * * @return 0 if success, errno on failure. */ int bt_has_client_discover(struct bt_conn *conn); /** * @brief Get the Bluetooth connection object of the service object. * * The caller gets a new reference to the connection object which must be * released with bt_conn_unref() once done using the object. * * @param[in] has Pointer to the Hearing Access Service object. * @param[out] conn Connection object. * * @return 0 in case of success or negative value in case of error. */ int bt_has_client_conn_get(const struct bt_has *has, struct bt_conn **conn); /** * @brief Read Preset Records. * * Client method to read up to @p max_count presets starting from given @p index. * The preset records are returned in the @ref bt_has_client_cb.preset_read_rsp callback * (called once for each preset). * * @param has Pointer to the Hearing Access Service object. * @param index The index to start with. * @param max_count Maximum number of presets to read. * * @return 0 in case of success or negative value in case of error. */ int bt_has_client_presets_read(struct bt_has *has, uint8_t index, uint8_t max_count); /** * @brief Set Active Preset. * * Client procedure to set preset identified by @p index as active. * The status is returned in the @ref bt_has_client_cb.preset_switch callback. * * @param has Pointer to the Hearing Access Service object. * @param index Preset index to activate. * @param sync Request active preset synchronization in set. * * @return 0 in case of success or negative value in case of error. */ int bt_has_client_preset_set(struct bt_has *has, uint8_t index, bool sync); /** * @brief Activate Next Preset. * * Client procedure to set next available preset as active. * The status is returned in the @ref bt_has_client_cb.preset_switch callback. * * @param has Pointer to the Hearing Access Service object. * @param sync Request active preset synchronization in set. * * @return 0 in case of success or negative value in case of error. */ int bt_has_client_preset_next(struct bt_has *has, bool sync); /** * @brief Activate Previous Preset. * * Client procedure to set previous available preset as active. * The status is returned in the @ref bt_has_client_cb.preset_switch callback. * * @param has Pointer to the Hearing Access Service object. * @param sync Request active preset synchronization in set. * * @return 0 in case of success or negative value in case of error. */ int bt_has_client_preset_prev(struct bt_has *has, bool sync); /** @brief Preset operations structure. */ struct bt_has_preset_ops { /** * @brief Preset select callback. * * This callback is called when the client requests to select preset identified by * @p index. * * @param index Preset index requested to activate. * @param sync Whether the server must relay this change to the other member of the * Binaural Hearing Aid Set. * * @return 0 in case of success or negative value in case of error. * @return -EBUSY if operation cannot be performed at the time. * @return -EINPROGRESS in case where user has to confirm once the requested preset * becomes active by calling @ref bt_has_preset_active_set. */ int (*select)(uint8_t index, bool sync); /** * @brief Preset name changed callback * * This callback is called when the name of the preset identified by @p index has changed. * * @param index Preset index that name has been changed. * @param name Preset current name. */ void (*name_changed)(uint8_t index, const char *name); }; /** @brief Register structure for preset. */ struct bt_has_preset_register_param { /** * @brief Preset index. * * Unique preset identifier. The value shall be other than @ref BT_HAS_PRESET_INDEX_NONE. */ uint8_t index; /** * @brief Preset properties. * * Bitfield of preset properties. */ enum bt_has_properties properties; /** * @brief Preset name. * * Preset name that further can be changed by either server or client if * @kconfig{CONFIG_BT_HAS_PRESET_NAME_DYNAMIC} configuration option has been enabled. * It's length shall be greater than @ref BT_HAS_PRESET_NAME_MIN. If the length exceeds * @ref BT_HAS_PRESET_NAME_MAX, the name will be truncated. */ const char *name; /** Preset operations structure. */ const struct bt_has_preset_ops *ops; }; /** * @brief Register the Hearing Access Service instance. * * @param features Hearing Access Service register parameters. * * @return 0 if success, errno on failure. */ int bt_has_register(const struct bt_has_features_param *features); /** * @brief Register preset. * * Register preset. The preset will be a added to the list of exposed preset records. * This symbol is linkable if @kconfig{CONFIG_BT_HAS_PRESET_COUNT} is non-zero. * * @param param Preset registration parameter. * * @return 0 if success, errno on failure. */ int bt_has_preset_register(const struct bt_has_preset_register_param *param); /** * @brief Unregister Preset. * * Unregister preset. The preset will be removed from the list of preset records. * * @param index The index of preset that's being requested to unregister. * * @return 0 if success, errno on failure. */ int bt_has_preset_unregister(uint8_t index); /** * @brief Set the preset as available. * * Set the @ref BT_HAS_PROP_AVAILABLE property bit. This will notify preset availability * to peer devices. Only available preset can be selected as active preset. * * @param index The index of preset that's became available. * * @return 0 in case of success or negative value in case of error. */ int bt_has_preset_available(uint8_t index); /** * @brief Set the preset as unavailable. * * Clear the @ref BT_HAS_PROP_AVAILABLE property bit. This will notify preset availability * to peer devices. Unavailable preset cannot be selected as active preset. * * @param index The index of preset that's became unavailable. * * @return 0 in case of success or negative value in case of error. */ int bt_has_preset_unavailable(uint8_t index); enum { BT_HAS_PRESET_ITER_STOP = 0, BT_HAS_PRESET_ITER_CONTINUE, }; /** * @typedef bt_has_preset_func_t * @brief Preset iterator callback. * * @param index The index of preset found. * @param properties Preset properties. * @param name Preset name. * @param user_data Data given. * * @return BT_HAS_PRESET_ITER_CONTINUE if should continue to the next preset. * @return BT_HAS_PRESET_ITER_STOP to stop. */ typedef uint8_t (*bt_has_preset_func_t)(uint8_t index, enum bt_has_properties properties, const char *name, void *user_data); /** * @brief Preset iterator. * * Iterate presets. Optionally, match non-zero index if given. * * @param index Preset index, passing @ref BT_HAS_PRESET_INDEX_NONE skips index matching. * @param func Callback function. * @param user_data Data to pass to the callback. */ void bt_has_preset_foreach(uint8_t index, bt_has_preset_func_t func, void *user_data); /** * @brief Set active preset. * * Function used to set the preset identified by the @p index as the active preset. * The preset index will be notified to peer devices. * * @param index Preset index. * * @return 0 in case of success or negative value in case of error. */ int bt_has_preset_active_set(uint8_t index); /** * @brief Get active preset. * * Function used to get the currently active preset index. * * @return Active preset index. */ uint8_t bt_has_preset_active_get(void); /** * @brief Clear out active preset. * * Used by server to deactivate currently active preset. * * @return 0 in case of success or negative value in case of error. */ static inline int bt_has_preset_active_clear(void) { return bt_has_preset_active_set(BT_HAS_PRESET_INDEX_NONE); } /** * @brief Change the Preset Name. * * Change the name of the preset identified by @p index. * * @param index The index of the preset to change the name of. * @param name Name to write. * * @return 0 in case of success or negative value in case of error. */ int bt_has_preset_name_change(uint8_t index, const char *name); /** * @brief Change the Hearing Aid Features. * * Change the hearing aid features. * * @param features The features to be set. * * @return 0 in case of success or negative value in case of error. */ int bt_has_features_set(const struct bt_has_features_param *features); #ifdef __cplusplus } #endif /** * @} */ #endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_HAS_H_ */