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 uint16_t receive_state_end_handle; 114 } bass_client_source_t; 115 116 117 typedef struct { 118 btstack_linked_item_t item; 119 120 hci_con_handle_t con_handle; 121 uint16_t cid; 122 uint16_t mtu; 123 broadcast_audio_scan_service_client_state_t state; 124 125 // service 126 uint16_t start_handle; 127 uint16_t end_handle; 128 uint16_t control_point_value_handle; 129 130 // used for memory capacity checking 131 uint8_t service_instances_num; 132 uint8_t receive_states_instances_num; 133 // used for notification registration 134 uint8_t receive_states_index; 135 136 uint8_t max_receive_states_num; 137 bass_client_source_t * receive_states; 138 139 // used for write segmentation 140 uint8_t buffer[BASS_CLIENT_MAX_ATT_BUFFER_SIZE]; 141 uint16_t buffer_offset; 142 uint16_t data_size; 143 144 gatt_client_notification_t notification_listener; 145 146 // used for adding and modifying source 147 const bass_source_data_t * control_point_operation_data; 148 uint8_t control_point_operation_source_id; 149 // used for setting the broadcast code 150 const uint8_t * broadcast_code; 151 } bass_client_connection_t; 152 153 /** 154 * @brief Init Broadcast Audio Scan Service Client 155 * @param packet_handler for events 156 */ 157 void broadcast_audio_scan_service_client_init(btstack_packet_handler_t packet_handler); 158 159 /** 160 * @brief Connect to BASS Service on remote device 161 * @note GATTSERVICE_SUBEVENT_BASS_CONNECTED will be emitted 162 * @param connection struct provided by user, needs to stay valid until disconnect event is received 163 * @param sources buffer to store information on Broadcast Sources on the service 164 * @param num_sources 165 * @param con_handle to connect to 166 * @param bass_cid connection id for this connection for other functions 167 * @return status 168 */ 169 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); 170 171 /** 172 * @brief Notify BASS Service that scanning has started 173 * @param bass_cid 174 * @return status 175 */ 176 uint8_t broadcast_audio_scan_service_client_scanning_started(uint16_t bass_cid); 177 178 /** 179 * @brief Notify BASS Service that scanning has stopped 180 * @note emits GATTSERVICE_SUBEVENT_BASS_SOURCE_OPERATION_COMPLETE 181 * @param bass_cid 182 * @return status 183 */ 184 uint8_t broadcast_audio_scan_service_client_scanning_stopped(uint16_t bass_cid); 185 186 /** 187 * @brief Add Broadcast Source on service 188 * @note GATTSERVICE_SUBEVENT_BASS_NOTIFICATION_COMPLETE will contain source_id for other functions 189 * @param bass_cid 190 * @param add_source_data data to add, needs to stay valid until GATTSERVICE_SUBEVENT_BASS_SOURCE_OPERATION_COMPLETE 191 * @return status 192 */ 193 uint8_t broadcast_audio_scan_service_client_add_source(uint16_t bass_cid, const bass_source_data_t * add_source_data); 194 195 /** 196 * @brief Modify information about Broadcast Source on service 197 * @param bass_cid 198 * @param source_id 199 * @param modify_source_data data to modify, needs to stay valid until GATTSERVICE_SUBEVENT_BASS_SOURCE_OPERATION_COMPLETE 200 * @return status 201 */ 202 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); 203 204 /** 205 * @brief Set Broadcast Code for a Broadcast Source to allow remote do decrypt audio stream 206 * @param bass_cid 207 * @param source_id 208 * @param broadcast_code 209 * @return status 210 */ 211 uint8_t broadcast_audio_scan_service_client_set_broadcast_code(uint16_t bass_cid, uint8_t source_id, const uint8_t * broadcast_code); 212 213 /** 214 * @brief Remove information about Broadcast Source 215 * @param bass_cid 216 * @param source_id 217 * @return status 218 */ 219 uint8_t broadcast_audio_scan_service_client_remove_source(uint16_t bass_cid, uint8_t source_id); 220 221 /** 222 * @param Provide read-only access to Broadcast Receive State of given Broadcast Source on service 223 * @param bass_cid 224 * @param source_id 225 * @return pointer to source data or NULL, if source_id not found 226 */ 227 const bass_source_data_t * broadcast_audio_scan_service_client_get_source_data(uint16_t bass_cid, uint8_t source_id); 228 229 /** 230 * @param Get BIG Encryption and Bad Code from Broadcast Receive State of given Broadcast Source on service 231 * @param bass_cid 232 * @param source_id 233 * @param out_big_encryption 234 * @param out_bad_code 16-byte buffer 235 * @return status 236 */ 237 uint8_t broadcast_audio_scan_service_client_get_encryption_state(uint16_t bass_cid, uint8_t source_id, 238 le_audio_big_encryption_t * out_big_encryption, uint8_t * out_bad_code); 239 240 /** 241 * @brief Deinit Broadcast Audio Scan Service Client 242 */ 243 void broadcast_audio_scan_service_client_deinit(uint16_t bass_cid); 244 245 /* API_END */ 246 247 #if defined __cplusplus 248 } 249 #endif 250 251 #endif 252 253