- 
                Notifications
    You must be signed in to change notification settings 
- Fork 8.2k
Volume offset control service and client #31893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
            nashif
  merged 1 commit into
  zephyrproject-rtos:master
from
Thalley:volume_offset_control_service
  
      
      
   
  Mar 22, 2021 
      
    
  
     Merged
                    Changes from all commits
      Commits
    
    
  File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,307 @@ | ||
| /* | ||
| * Copyright (c) 2020 Nordic Semiconductor ASA | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|  | ||
| #ifndef ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VOCS_H_ | ||
| #define ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VOCS_H_ | ||
|  | ||
| /** | ||
| * @brief Volume Offset Control Service (VOCS) | ||
| * | ||
| * @defgroup bt_gatt_vocs Volume Offset Control Service (VOCS) | ||
| * | ||
| * @ingroup bluetooth | ||
| * @{ | ||
| * | ||
| * The Volume Offset Control Service is a secondary service, and as such should not be used own its | ||
| * own, but rather in the context of another (primary) service. | ||
| * | ||
| * This API implements both the server and client functionality. | ||
| * Note that the API abstracts away the change counter in the volume offset control state and will | ||
| * automatically handle any changes to that. If out of date, the client implementation will | ||
| * autonomously read the change counter value when executing a write request. | ||
| * | ||
| * [Experimental] Users should note that the APIs can change as a part of ongoing development. | ||
| */ | ||
|  | ||
| #include <zephyr/types.h> | ||
|  | ||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|  | ||
| /** Volume Offset Control Service Error codes */ | ||
| #define BT_VOCS_ERR_INVALID_COUNTER 0x80 | ||
| #define BT_VOCS_ERR_OP_NOT_SUPPORTED 0x81 | ||
| #define BT_VOCS_ERR_OUT_OF_RANGE 0x82 | ||
|  | ||
| #define BT_VOCS_MIN_OFFSET -255 | ||
| #define BT_VOCS_MAX_OFFSET 255 | ||
|  | ||
| /** @brief Opaque Volume Offset Control Service instance. */ | ||
| struct bt_vocs; | ||
|  | ||
| /** @brief Structure for initializing a Volume Offset Control Service instance. */ | ||
| struct bt_vocs_init_param { | ||
| /** Audio Location bitmask */ | ||
| uint32_t location; | ||
|  | ||
| /** Boolean to set whether the location is writable by clients */ | ||
| bool location_writable; | ||
|  | ||
| /** Initial volume offset (-255 to 255) */ | ||
| int16_t offset; | ||
|  | ||
| /** Initial audio output description */ | ||
| char *output_desc; | ||
|  | ||
| /** Boolean to set whether the description is writable by clients */ | ||
| bool desc_writable; | ||
| }; | ||
|  | ||
| /** @brief Structure for discovering a Volume Offset Control Service instance. */ | ||
| struct bt_vocs_discover_param { | ||
| /** | ||
| * @brief The start handle of the discovering. | ||
| * | ||
| * Typically the @p start_handle of a @ref bt_gatt_include. | ||
| */ | ||
| uint16_t start_handle; | ||
| /** | ||
| * @brief The end handle of the discovering. | ||
| * | ||
| * Typically the @p end_handle of a @ref bt_gatt_include. | ||
| */ | ||
| uint16_t end_handle; | ||
| }; | ||
|  | ||
| /** | ||
| * @brief Get a free service instance of Volume Offset Control Service from the pool. | ||
| * | ||
| * @return Volume Offset Control Service instance in case of success or NULL in case of error. | ||
| */ | ||
| struct bt_vocs *bt_vocs_free_instance_get(void); | ||
|  | ||
| /** | ||
| * @brief Get the service declaration attribute. | ||
| * | ||
| * The first service attribute returned can be included in any other GATT service. | ||
| * | ||
| * @param vocs Volume Offset Control Service instance. | ||
| * | ||
| * @return Pointer to the attributes of the service. | ||
| */ | ||
| void *bt_vocs_svc_decl_get(struct bt_vocs *vocs); | ||
|  | ||
| /** | ||
| * @brief Initialize the Volume Offset Control Service instance. | ||
| * | ||
| * @param vocs Volume Offset Control Service instance. | ||
| * @param init Volume Offset Control Service initialization structure. | ||
| * May be NULL to use default values. | ||
| * | ||
|         
                  asbjornsabo marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| * @return 0 if success, errno on failure. | ||
| */ | ||
| int bt_vocs_init(struct bt_vocs *vocs, const struct bt_vocs_init_param *init); | ||
|  | ||
| /** | ||
| * @brief Callback function for the offset state. | ||
| * | ||
| * Called when the value is read, or if the value is changed by either the server or client. | ||
| * | ||
| * @param conn Connection to peer device, or NULL if local server read. | ||
| * @param inst The instance pointer. | ||
| * @param err Error value. 0 on success, GATT error on positive value | ||
| * or errno on negative value. | ||
| * For notifications, this will always be 0. | ||
| * @param offset The offset value. | ||
| */ | ||
| typedef void (*bt_vocs_state_cb_t)(struct bt_conn *conn, struct bt_vocs *inst, | ||
| int err, int16_t offset); | ||
|  | ||
| /** | ||
| * @brief Callback function for setting offset. | ||
| * | ||
|         
                  asbjornsabo marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| * @param conn Connection to peer device, or NULL if local server write. | ||
| * @param inst The instance pointer. | ||
| * @param err Error value. 0 on success, GATT error on positive value | ||
| * or errno on negative value. | ||
| */ | ||
| typedef void (*bt_vocs_set_offset_cb_t)(struct bt_conn *conn, struct bt_vocs *inst, int err); | ||
|  | ||
| /** | ||
| * @brief Callback function for the location. | ||
| * | ||
| * Called when the value is read, or if the value is changed by either the server or client. | ||
| * | ||
| * @param conn Connection to peer device, or NULL if local server read. | ||
| * @param inst The instance pointer. | ||
| * @param err Error value. 0 on success, GATT error on positive value | ||
| * or errno on negative value. | ||
| * For notifications, this will always be 0. | ||
| * @param location The location value. | ||
| */ | ||
| typedef void (*bt_vocs_location_cb_t)(struct bt_conn *conn, struct bt_vocs *inst, int err, | ||
| uint32_t location); | ||
|  | ||
|         
                  asbjornsabo marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| /** | ||
| * @brief Callback function for the description. | ||
| * | ||
| * Called when the value is read, or if the value is changed by either the server or client. | ||
| * | ||
| * @param conn Connection to peer device, or NULL if local server read. | ||
| * @param inst The instance pointer. | ||
| * @param err Error value. 0 on success, GATT error on positive value | ||
| * or errno on negative value. | ||
| * For notifications, this will always be 0. | ||
| * @param description The description as an UTF-8 encoded string. | ||
| */ | ||
| typedef void (*bt_vocs_description_cb_t)(struct bt_conn *conn, struct bt_vocs *inst, int err, | ||
| char *description); | ||
|  | ||
| /** | ||
| * @brief Callback function for bt_vocs_discover. | ||
| * | ||
| * This callback will usually be overwritten by the primary service that | ||
| * includes the Volume Control Offset Service client. | ||
| * | ||
| * @param conn Connection to peer device, or NULL if local server read. | ||
| * @param inst The instance pointer. | ||
| * @param err Error value. 0 on success, GATT error on positive value | ||
| * or errno on negative value. | ||
| * For notifications, this will always be 0. | ||
| */ | ||
| typedef void (*bt_vocs_discover_cb_t)(struct bt_conn *conn, struct bt_vocs *inst, int err); | ||
|  | ||
| struct bt_vocs_cb { | ||
| bt_vocs_state_cb_t state; | ||
| bt_vocs_location_cb_t location; | ||
| bt_vocs_description_cb_t description; | ||
|  | ||
| #if defined(CONFIG_BT_VOCS_CLIENT) | ||
| /* Client only */ | ||
| bt_vocs_discover_cb_t discover; | ||
| bt_vocs_set_offset_cb_t set_offset; | ||
| #endif /* CONFIG_BT_VOCS_CLIENT */ | ||
| }; | ||
|  | ||
| /** | ||
| * @brief Read the Volume Offset Control Service offset state. | ||
| * | ||
| * The value is returned in the bt_vocs_cb.state callback. | ||
| * | ||
| * @param conn Connection to peer device, or NULL to read local server value. | ||
| * @param inst Pointer to the Volume Offset Control Service instance. | ||
| * | ||
| * @return 0 on success, GATT error value on fail. | ||
| */ | ||
| int bt_vocs_state_get(struct bt_conn *conn, struct bt_vocs *inst); | ||
|  | ||
| /** | ||
| * @brief Set the Volume Offset Control Service offset state. | ||
| * | ||
| * @param conn Connection to peer device, or NULL to set local server value. | ||
| * @param inst Pointer to the Volume Offset Control Service instance. | ||
| * @param offset The offset to set (-255 to 255). | ||
| * | ||
| * @return 0 on success, GATT error value on fail. | ||
| */ | ||
| int bt_vocs_state_set(struct bt_conn *conn, struct bt_vocs *inst, int16_t offset); | ||
|  | ||
| /** | ||
| * @brief Read the Volume Offset Control Service location. | ||
| * | ||
| * The value is returned in the bt_vocs_cb.location callback. | ||
| * | ||
| * @param conn Connection to peer device, or NULL to read local server value. | ||
| * @param inst Pointer to the Volume Offset Control Service instance. | ||
| * | ||
| * @return 0 on success, GATT error value on fail. | ||
| */ | ||
| int bt_vocs_location_get(struct bt_conn *conn, struct bt_vocs *inst); | ||
|  | ||
| /** | ||
| * @brief Set the Volume Offset Control Service location. | ||
| * | ||
| * @param conn Connection to peer device, or NULL to read local server value. | ||
| * @param inst Pointer to the Volume Offset Control Service instance. | ||
| * @param location The location to set. | ||
| * | ||
| * @return 0 on success, GATT error value on fail. | ||
| */ | ||
| int bt_vocs_location_set(struct bt_conn *conn, struct bt_vocs *inst, uint32_t location); | ||
|  | ||
| /** | ||
| * @brief Read the Volume Offset Control Service output description. | ||
| * | ||
| * The value is returned in the bt_vocs_cb.description callback. | ||
| * | ||
| * @param conn Connection to peer device, or NULL to read local server value. | ||
| * @param inst Pointer to the Volume Offset Control Service instance. | ||
| * | ||
| * @return 0 on success, GATT error value on fail. | ||
| */ | ||
| int bt_vocs_description_get(struct bt_conn *conn, struct bt_vocs *inst); | ||
|  | ||
| /** | ||
| * @brief Set the Volume Offset Control Service description. | ||
| * | ||
| * @param conn Connection to peer device, or NULL to set local server value. | ||
| * @param inst Pointer to the Volume Offset Control Service instance. | ||
| * @param description The UTF-8 encoded string description to set. | ||
| * | ||
| * @return 0 on success, GATT error value on fail. | ||
| */ | ||
| int bt_vocs_description_set(struct bt_conn *conn, struct bt_vocs *inst, | ||
| const char *description); | ||
|  | ||
| /** | ||
| * @brief Register callbacks for the Volume Offset Control Service. | ||
| * | ||
| * @param inst Pointer to the Volume Offset Control Service instance. | ||
| * @param cb Pointer to the callback structure. | ||
| * | ||
| * @return 0 on success, GATT error value on fail. | ||
| */ | ||
| int bt_vocs_cb_register(struct bt_vocs *inst, struct bt_vocs_cb *cb); | ||
|  | ||
| /** | ||
| * @brief Registers the callbacks for the Volume Offset Control Service client. | ||
| * | ||
| * @param inst Pointer to the Volume Offset Control Service client instance. | ||
| * @param cb Pointer to the callback structure. | ||
| */ | ||
| void bt_vocs_client_cb_register(struct bt_vocs *inst, struct bt_vocs_cb *cb); | ||
|  | ||
| /** | ||
| * @brief Returns a pointer to a Volume Offset Control Service client instance. | ||
| * | ||
| * @return Pointer to the instance, or NULL if no free instances are left. | ||
| */ | ||
| struct bt_vocs *bt_vocs_client_free_instance_get(void); | ||
|  | ||
| /** | ||
| * @brief Discover a Volume Offset Control Service. | ||
| * | ||
| * Attempts to discover a Volume Offset Control Service on a server given the @p param. | ||
| * | ||
| * @param conn Connection to the peer with the Volume Offset Control Service. | ||
| * @param inst Pointer to the Volume Offset Control Service client instance. | ||
| * @param param Pointer to the parameters. | ||
| * | ||
| * @return 0 on success, errno on fail. | ||
| */ | ||
| int bt_vocs_discover(struct bt_conn *conn, struct bt_vocs *inst, | ||
| const struct bt_vocs_discover_param *param); | ||
|  | ||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|  | ||
| /** | ||
| * @} | ||
| */ | ||
|  | ||
| #endif /* ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_VOCS_H_ */ | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|  | ||
| zephyr_library() | ||
| zephyr_library_link_libraries(subsys__bluetooth) | ||
|  | ||
| if (CONFIG_BT_VOCS OR CONFIG_BT_VOCS_CLIENT) | ||
| zephyr_library_sources(vocs.c) | ||
| endif() | ||
| zephyr_library_sources_ifdef(CONFIG_BT_VOCS_CLIENT vocs_client.c) | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
              
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't take this as a blocker/mandatory comment since it's completely subjective, but I wouldn't personally have taken the recent 80 -> 100 character limit change so that one must always strive for it. E.g. I find human readable text easier to read with shorter lines (less horizontal back-and-forth eye movement), so I'd still have formatted it to less than 80 characters. The main benefit of the 80 -> 100 chance (as I see it) is for code where forcing earlier line spits would actually hurt readability. Anyway, I realise this might also be tricky to configure in an editor so that it'd auto-split code and comments differently (that said, at least for code I write I always explicitly choose where to split the code, but let the editor do the splitting for any code comments or other documentation). (rant over :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually don't have any auto-split in my editor, so any such changes I've done has been intentional. Personally I don't find liken of length 100 to be any less readable, so it is, as you say, subjective :)
From: https://www.phoronix.com/scan.php?page=news_item&px=Linux-Kernel-Deprecates-80-Col
So from the Linux Kernel point of view, 80 should still be preferred. Going forwards I'll try to keep it at max 80, unless to avoid ugly breaks :)