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 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. Register packet handler to receive events: 154 * - LEAUDIO_SUBEVENT_BASS_CLIENT_CONNECTED 155 * - LEAUDIO_SUBEVENT_BASS_CLIENT_DISCONNECTED 156 * - LEAUDIO_SUBEVENT_BASS_CLIENT_SCAN_OPERATION_COMPLETE 157 * - LEAUDIO_SUBEVENT_BASS_CLIENT_SOURCE_OPERATION_COMPLETE 158 * - LEAUDIO_SUBEVENT_BASS_CLIENT_NOTIFICATION_COMPLETE 159 * @param packet_handler for events 160 */ 161 void broadcast_audio_scan_service_client_init(btstack_packet_handler_t packet_handler); 162 163 /** 164 * @brief Connect to BASS Service on remote device 165 * @note LEAUDIO_SUBEVENT_BASS_CLIENT_CONNECTED will be emitted 166 * @param connection struct provided by user, needs to stay valid until disconnect event is received 167 * @param sources buffer to store information on Broadcast Sources on the service 168 * @param num_sources 169 * @param con_handle to connect to 170 * @param bass_cid connection id for this connection for other functions 171 * @return status 172 */ 173 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); 174 175 /** 176 * @brief Notify BASS Service that scanning has started 177 * @param bass_cid 178 * @return status 179 */ 180 uint8_t broadcast_audio_scan_service_client_scanning_started(uint16_t bass_cid); 181 182 /** 183 * @brief Notify BASS Service that scanning has stopped 184 * @note emits LEAUDIO_SUBEVENT_BASS_CLIENT_SOURCE_OPERATION_COMPLETE 185 * @param bass_cid 186 * @return status 187 */ 188 uint8_t broadcast_audio_scan_service_client_scanning_stopped(uint16_t bass_cid); 189 190 /** 191 * @brief Add Broadcast Source on service 192 * @note GATTSERVICE_SUBEVENT_BASS_NOTIFICATION_COMPLETE will contain source_id for other functions 193 * @param bass_cid 194 * @param add_source_data data to add, needs to stay valid until LEAUDIO_SUBEVENT_BASS_CLIENT_SOURCE_OPERATION_COMPLETE 195 * @return status 196 */ 197 uint8_t broadcast_audio_scan_service_client_add_source(uint16_t bass_cid, const bass_source_data_t * add_source_data); 198 199 /** 200 * @brief Modify information about Broadcast Source on service 201 * @param bass_cid 202 * @param source_id 203 * @param modify_source_data data to modify, needs to stay valid until LEAUDIO_SUBEVENT_BASS_CLIENT_SOURCE_OPERATION_COMPLETE 204 * @return status 205 */ 206 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); 207 208 /** 209 * @brief Set Broadcast Code for a Broadcast Source to allow remote do decrypt audio stream 210 * @param bass_cid 211 * @param source_id 212 * @param broadcast_code 213 * @return status 214 */ 215 uint8_t broadcast_audio_scan_service_client_set_broadcast_code(uint16_t bass_cid, uint8_t source_id, const uint8_t * broadcast_code); 216 217 /** 218 * @brief Remove information about Broadcast Source 219 * @param bass_cid 220 * @param source_id 221 * @return status 222 */ 223 uint8_t broadcast_audio_scan_service_client_remove_source(uint16_t bass_cid, uint8_t source_id); 224 225 /** 226 * @param Provide read-only access to Broadcast Receive State of given Broadcast Source on service 227 * @param bass_cid 228 * @param source_id 229 * @return pointer to source data or NULL, if source_id not found 230 */ 231 const bass_source_data_t * broadcast_audio_scan_service_client_get_source_data(uint16_t bass_cid, uint8_t source_id); 232 233 /** 234 * @param Get BIG Encryption and Bad Code from Broadcast Receive State of given Broadcast Source on service 235 * @param bass_cid 236 * @param source_id 237 * @param out_big_encryption 238 * @param out_bad_code 16-byte buffer 239 * @return status 240 */ 241 uint8_t broadcast_audio_scan_service_client_get_encryption_state(uint16_t bass_cid, uint8_t source_id, 242 le_audio_big_encryption_t * out_big_encryption, uint8_t * out_bad_code); 243 244 /** 245 * @brief Deinit Broadcast Audio Scan Service Client 246 */ 247 void broadcast_audio_scan_service_client_deinit(uint16_t bass_cid); 248 249 /* API_END */ 250 251 #if defined __cplusplus 252 } 253 #endif 254 255 #endif 256 257