1 /* 2 * Copyright (C) 2022 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 /** 39 * @title Audio Stream Control Service Client 40 * 41 */ 42 43 #ifndef BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_H 44 #define BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_H 45 46 #include <stdint.h> 47 #include "ble/gatt_client.h" 48 #include "btstack_defines.h" 49 #include "le-audio/le_audio.h" 50 #include "le-audio/gatt-service/broadcast_audio_scan_service_util.h" 51 52 #if defined __cplusplus 53 extern "C" { 54 #endif 55 56 #define BASS_CLIENT_MAX_ATT_BUFFER_SIZE 512 57 /* API_START */ 58 59 typedef enum { 60 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_IDLE, 61 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE, 62 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT, 63 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS, 64 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_RESULT, 65 66 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTIC_DESCRIPTORS, 67 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_DESCRIPTORS_RESULT, 68 69 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W2_REGISTER_NOTIFICATION, 70 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W4_NOTIFICATION_REGISTERED, 71 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_CONNECTED, 72 73 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_READ_CHARACTERISTIC_CONFIGURATION, 74 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_CHARACTERISTIC_CONFIGURATION_RESULT, 75 76 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_START_SCAN, 77 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_START_SCAN, 78 79 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_STOP_SCAN, 80 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_STOP_SCAN, 81 82 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_ADD_SOURCE, 83 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_ADD_SOURCE, 84 85 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_MODIFY_SOURCE, 86 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_MODIFY_SOURCE, 87 88 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_SET_BROADCAST_CODE, 89 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_SET_BROADCAST_CODE, 90 91 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_REMOVE_SOURCE, 92 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_REMOVE_SOURCE, 93 94 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_READE_RECEIVE_STATE, 95 BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_READE_RECEIVE_STATE, 96 97 } broadcast_audio_scan_service_client_state_t; 98 99 typedef struct { 100 // used for add source command 101 bass_source_data_t data; 102 103 // received via notification 104 bool in_use; 105 uint8_t source_id; 106 le_audio_big_encryption_t big_encryption; 107 uint8_t bad_code[16]; 108 109 // characteristic 110 uint16_t receive_state_value_handle; 111 uint16_t receive_state_ccc_handle; 112 uint16_t receive_state_properties; 113 } bass_client_source_t; 114 115 116 typedef struct { 117 btstack_linked_item_t item; 118 119 hci_con_handle_t con_handle; 120 uint16_t cid; 121 uint16_t mtu; 122 broadcast_audio_scan_service_client_state_t state; 123 124 // service 125 uint16_t start_handle; 126 uint16_t end_handle; 127 uint16_t control_point_value_handle; 128 129 // used for memory capacity checking 130 uint8_t service_instances_num; 131 uint8_t receive_states_instances_num; 132 // used for notification registration 133 uint8_t receive_states_index; 134 135 uint8_t max_receive_states_num; 136 bass_client_source_t * receive_states; 137 138 // used for write segmentation 139 uint8_t buffer[BASS_CLIENT_MAX_ATT_BUFFER_SIZE]; 140 uint16_t buffer_offset; 141 uint16_t data_size; 142 143 gatt_client_notification_t notification_listener; 144 145 // used for adding and modifying source 146 const bass_source_data_t * control_point_operation_data; 147 uint8_t control_point_operation_source_id; 148 // used for setting the broadcast code 149 const uint8_t * broadcast_code; 150 } bass_client_connection_t; 151 152 /** 153 * @brief Init Broadcast Audio Scan Service Client 154 * @param packet_handler for events 155 */ 156 void broadcast_audio_scan_service_client_init(btstack_packet_handler_t packet_handler); 157 158 /** 159 * @brief Connect to BASS Service on remote device 160 * @note GATTSERVICE_SUBEVENT_BASS_CONNECTED will be emitted 161 * @param connection struct provided by user, needs to stay valid until disconnect event is received 162 * @param sources buffer to store information on Broadcast Sources on the service 163 * @param num_sources 164 * @param con_handle to connect to 165 * @param bass_cid connection id for this connection for other functions 166 * @return status 167 */ 168 uint8_t broadcast_audio_scan_service_client_connect(bass_client_connection_t * connection, bass_client_source_t * sources, uint8_t num_sources, hci_con_handle_t con_handle, uint16_t * bass_cid); 169 170 /** 171 * @brief Notify BASS Service that scanning has started 172 * @param bass_cid 173 * @return status 174 */ 175 uint8_t broadcast_audio_scan_service_client_scanning_started(uint16_t bass_cid); 176 177 /** 178 * @brief Notify BASS Service that scanning has stopped 179 * @note emits GATTSERVICE_SUBEVENT_BASS_SOURCE_OPERATION_COMPLETE 180 * @param bass_cid 181 * @return status 182 */ 183 uint8_t broadcast_audio_scan_service_client_scanning_stopped(uint16_t bass_cid); 184 185 /** 186 * @brief Add Broadcast Source on service 187 * @note GATTSERVICE_SUBEVENT_BASS_NOTIFICATION_COMPLETE will contain source_id for other functions 188 * @param bass_cid 189 * @param add_source_data data to add, needs to stay valid until GATTSERVICE_SUBEVENT_BASS_SOURCE_OPERATION_COMPLETE 190 * @return status 191 */ 192 uint8_t broadcast_audio_scan_service_client_add_source(uint16_t bass_cid, const bass_source_data_t * add_source_data); 193 194 /** 195 * @brief Modify information about Broadcast Source on service 196 * @param bass_cid 197 * @param source_id 198 * @param modify_source_data data to modify, needs to stay valid until GATTSERVICE_SUBEVENT_BASS_SOURCE_OPERATION_COMPLETE 199 * @return status 200 */ 201 uint8_t broadcast_audio_scan_service_client_modify_source(uint16_t bass_cid, uint8_t source_id, const bass_source_data_t * modify_source_data); 202 203 /** 204 * @brief Set Broadcast Code for a Broadcast Source to allow remote do decrypt audio stream 205 * @param bass_cid 206 * @param source_id 207 * @param broadcast_code 208 * @return status 209 */ 210 uint8_t broadcast_audio_scan_service_client_set_broadcast_code(uint16_t bass_cid, uint8_t source_id, const uint8_t * broadcast_code); 211 212 /** 213 * @brief Remove information about Broadcast Source 214 * @param bass_cid 215 * @param source_id 216 * @return status 217 */ 218 uint8_t broadcast_audio_scan_service_client_remove_source(uint16_t bass_cid, uint8_t source_id); 219 220 /** 221 * @param Provide read-only access to Broadcast Receive State of given Broadcast Source on service 222 * @param bass_cid 223 * @param source_id 224 * @return pointer to source data or NULL, if source_id not found 225 */ 226 const bass_source_data_t * broadcast_audio_scan_service_client_get_source_data(uint16_t bass_cid, uint8_t source_id); 227 228 /** 229 * @param Get BIG Encryption and Bad Code from Broadcast Receive State of given Broadcast Source on service 230 * @param bass_cid 231 * @param source_id 232 * @param out_big_encryption 233 * @param out_bad_code 16-byte buffer 234 * @return status 235 */ 236 uint8_t broadcast_audio_scan_service_client_get_encryption_state(uint16_t bass_cid, uint8_t source_id, 237 le_audio_big_encryption_t * out_big_encryption, uint8_t * out_bad_code); 238 239 /** 240 * @brief Deinit Broadcast Audio Scan Service Client 241 */ 242 void broadcast_audio_scan_service_client_deinit(uint16_t bass_cid); 243 244 /* API_END */ 245 246 #if defined __cplusplus 247 } 248 #endif 249 250 #endif 251 252