15deb0bb6SMatthias Ringwald /* 25deb0bb6SMatthias Ringwald * Copyright (C) 2022 BlueKitchen GmbH 35deb0bb6SMatthias Ringwald * 45deb0bb6SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 55deb0bb6SMatthias Ringwald * modification, are permitted provided that the following conditions 65deb0bb6SMatthias Ringwald * are met: 75deb0bb6SMatthias Ringwald * 85deb0bb6SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 95deb0bb6SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 105deb0bb6SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 115deb0bb6SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 125deb0bb6SMatthias Ringwald * documentation and/or other materials provided with the distribution. 135deb0bb6SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 145deb0bb6SMatthias Ringwald * contributors may be used to endorse or promote products derived 155deb0bb6SMatthias Ringwald * from this software without specific prior written permission. 165deb0bb6SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 175deb0bb6SMatthias Ringwald * personal benefit and not for any commercial purpose or for 185deb0bb6SMatthias Ringwald * monetary gain. 195deb0bb6SMatthias Ringwald * 205deb0bb6SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 215deb0bb6SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 225deb0bb6SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 235deb0bb6SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 245deb0bb6SMatthias Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 255deb0bb6SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 265deb0bb6SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 275deb0bb6SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 285deb0bb6SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 295deb0bb6SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 305deb0bb6SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 315deb0bb6SMatthias Ringwald * SUCH DAMAGE. 325deb0bb6SMatthias Ringwald * 335deb0bb6SMatthias Ringwald * Please inquire about commercial licensing options at 345deb0bb6SMatthias Ringwald * [email protected] 355deb0bb6SMatthias Ringwald * 365deb0bb6SMatthias Ringwald */ 375deb0bb6SMatthias Ringwald 385deb0bb6SMatthias Ringwald /** 395deb0bb6SMatthias Ringwald * @title Audio Stream Control Service Client 405deb0bb6SMatthias Ringwald * 415deb0bb6SMatthias Ringwald */ 425deb0bb6SMatthias Ringwald 435deb0bb6SMatthias Ringwald #ifndef BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_H 445deb0bb6SMatthias Ringwald #define BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_H 455deb0bb6SMatthias Ringwald 465deb0bb6SMatthias Ringwald #include <stdint.h> 475deb0bb6SMatthias Ringwald #include "ble/gatt_client.h" 485deb0bb6SMatthias Ringwald #include "btstack_defines.h" 495deb0bb6SMatthias Ringwald #include "le-audio/le_audio.h" 505deb0bb6SMatthias Ringwald #include "le-audio/gatt-service/broadcast_audio_scan_service_util.h" 515deb0bb6SMatthias Ringwald 525deb0bb6SMatthias Ringwald #if defined __cplusplus 535deb0bb6SMatthias Ringwald extern "C" { 545deb0bb6SMatthias Ringwald #endif 555deb0bb6SMatthias Ringwald 565deb0bb6SMatthias Ringwald #define BASS_CLIENT_MAX_ATT_BUFFER_SIZE 512 575deb0bb6SMatthias Ringwald /* API_START */ 585deb0bb6SMatthias Ringwald 595deb0bb6SMatthias Ringwald typedef enum { 60*59e9e2d1SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_IDLE = 0, 615deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE, 625deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT, 635deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS, 645deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_RESULT, 655deb0bb6SMatthias Ringwald 665deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTIC_DESCRIPTORS, 675deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_DESCRIPTORS_RESULT, 685deb0bb6SMatthias Ringwald 695deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W2_REGISTER_NOTIFICATION, 705deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_W4_NOTIFICATION_REGISTERED, 71*59e9e2d1SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_STATE_READY, 725deb0bb6SMatthias Ringwald 735deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_READ_CHARACTERISTIC_CONFIGURATION, 745deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_CHARACTERISTIC_CONFIGURATION_RESULT, 755deb0bb6SMatthias Ringwald 765deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_START_SCAN, 775deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_START_SCAN, 785deb0bb6SMatthias Ringwald 795deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_STOP_SCAN, 805deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_STOP_SCAN, 815deb0bb6SMatthias Ringwald 825deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_ADD_SOURCE, 835deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_ADD_SOURCE, 845deb0bb6SMatthias Ringwald 855deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_MODIFY_SOURCE, 865deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_MODIFY_SOURCE, 875deb0bb6SMatthias Ringwald 885deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_SET_BROADCAST_CODE, 895deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_SET_BROADCAST_CODE, 905deb0bb6SMatthias Ringwald 915deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_WRITE_CONTROL_POINT_REMOVE_SOURCE, 925deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_WRITE_CONTROL_POINT_REMOVE_SOURCE, 935deb0bb6SMatthias Ringwald 945deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W2_READE_RECEIVE_STATE, 955deb0bb6SMatthias Ringwald BROADCAST_AUDIO_SCAN_SERVICE_CLIENT_W4_READE_RECEIVE_STATE, 965deb0bb6SMatthias Ringwald 975deb0bb6SMatthias Ringwald } broadcast_audio_scan_service_client_state_t; 985deb0bb6SMatthias Ringwald 995deb0bb6SMatthias Ringwald typedef struct { 1005deb0bb6SMatthias Ringwald // used for add source command 1015deb0bb6SMatthias Ringwald bass_source_data_t data; 1025deb0bb6SMatthias Ringwald 1035deb0bb6SMatthias Ringwald // received via notification 1045deb0bb6SMatthias Ringwald bool in_use; 1055deb0bb6SMatthias Ringwald uint8_t source_id; 1065deb0bb6SMatthias Ringwald le_audio_big_encryption_t big_encryption; 1075deb0bb6SMatthias Ringwald uint8_t bad_code[16]; 1085deb0bb6SMatthias Ringwald 1095deb0bb6SMatthias Ringwald // characteristic 1105deb0bb6SMatthias Ringwald uint16_t receive_state_value_handle; 1115deb0bb6SMatthias Ringwald uint16_t receive_state_ccc_handle; 1125deb0bb6SMatthias Ringwald uint16_t receive_state_properties; 113b0c37fffSMilanka Ringwald uint16_t receive_state_end_handle; 1145deb0bb6SMatthias Ringwald } bass_client_source_t; 1155deb0bb6SMatthias Ringwald 1165deb0bb6SMatthias Ringwald typedef struct { 1175deb0bb6SMatthias Ringwald btstack_linked_item_t item; 1185deb0bb6SMatthias Ringwald 1195deb0bb6SMatthias Ringwald hci_con_handle_t con_handle; 1205deb0bb6SMatthias Ringwald uint16_t cid; 1215deb0bb6SMatthias Ringwald uint16_t mtu; 1225deb0bb6SMatthias Ringwald broadcast_audio_scan_service_client_state_t state; 1235deb0bb6SMatthias Ringwald 1245deb0bb6SMatthias Ringwald // service 1255deb0bb6SMatthias Ringwald uint16_t start_handle; 1265deb0bb6SMatthias Ringwald uint16_t end_handle; 1275deb0bb6SMatthias Ringwald uint16_t control_point_value_handle; 1285deb0bb6SMatthias Ringwald 1295deb0bb6SMatthias Ringwald // used for memory capacity checking 1305deb0bb6SMatthias Ringwald uint8_t service_instances_num; 1315deb0bb6SMatthias Ringwald uint8_t receive_states_instances_num; 1325deb0bb6SMatthias Ringwald // used for notification registration 1335deb0bb6SMatthias Ringwald uint8_t receive_states_index; 1345deb0bb6SMatthias Ringwald 1355deb0bb6SMatthias Ringwald uint8_t max_receive_states_num; 1365deb0bb6SMatthias Ringwald bass_client_source_t * receive_states; 1375deb0bb6SMatthias Ringwald 1385deb0bb6SMatthias Ringwald // used for write segmentation 1395deb0bb6SMatthias Ringwald uint8_t buffer[BASS_CLIENT_MAX_ATT_BUFFER_SIZE]; 1405deb0bb6SMatthias Ringwald uint16_t buffer_offset; 1415deb0bb6SMatthias Ringwald uint16_t data_size; 1425deb0bb6SMatthias Ringwald 1435deb0bb6SMatthias Ringwald gatt_client_notification_t notification_listener; 1445deb0bb6SMatthias Ringwald 1455deb0bb6SMatthias Ringwald // used for adding and modifying source 1465deb0bb6SMatthias Ringwald const bass_source_data_t * control_point_operation_data; 1475deb0bb6SMatthias Ringwald uint8_t control_point_operation_source_id; 1485deb0bb6SMatthias Ringwald // used for setting the broadcast code 1495deb0bb6SMatthias Ringwald const uint8_t * broadcast_code; 1505deb0bb6SMatthias Ringwald } bass_client_connection_t; 1515deb0bb6SMatthias Ringwald 1525deb0bb6SMatthias Ringwald /** 153017eba9cSMilanka Ringwald * @brief Init Broadcast Audio Scan Service Client. Register packet handler to receive events: 154ae304283SMilanka Ringwald * - LEAUDIO_SUBEVENT_BASS_CLIENT_CONNECTED 155ae304283SMilanka Ringwald * - LEAUDIO_SUBEVENT_BASS_CLIENT_DISCONNECTED 156ae304283SMilanka Ringwald * - LEAUDIO_SUBEVENT_BASS_CLIENT_SCAN_OPERATION_COMPLETE 157ae304283SMilanka Ringwald * - LEAUDIO_SUBEVENT_BASS_CLIENT_SOURCE_OPERATION_COMPLETE 158ae304283SMilanka Ringwald * - LEAUDIO_SUBEVENT_BASS_CLIENT_NOTIFICATION_COMPLETE 1595deb0bb6SMatthias Ringwald * @param packet_handler for events 1605deb0bb6SMatthias Ringwald */ 1615deb0bb6SMatthias Ringwald void broadcast_audio_scan_service_client_init(btstack_packet_handler_t packet_handler); 1625deb0bb6SMatthias Ringwald 1635deb0bb6SMatthias Ringwald /** 1645deb0bb6SMatthias Ringwald * @brief Connect to BASS Service on remote device 165ae304283SMilanka Ringwald * @note LEAUDIO_SUBEVENT_BASS_CLIENT_CONNECTED will be emitted 1665deb0bb6SMatthias Ringwald * @param connection struct provided by user, needs to stay valid until disconnect event is received 1675deb0bb6SMatthias Ringwald * @param sources buffer to store information on Broadcast Sources on the service 1685deb0bb6SMatthias Ringwald * @param num_sources 1695deb0bb6SMatthias Ringwald * @param con_handle to connect to 1705deb0bb6SMatthias Ringwald * @param bass_cid connection id for this connection for other functions 1715deb0bb6SMatthias Ringwald * @return status 1725deb0bb6SMatthias Ringwald */ 1735deb0bb6SMatthias Ringwald 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); 1745deb0bb6SMatthias Ringwald 1755deb0bb6SMatthias Ringwald /** 1765deb0bb6SMatthias Ringwald * @brief Notify BASS Service that scanning has started 1775deb0bb6SMatthias Ringwald * @param bass_cid 1785deb0bb6SMatthias Ringwald * @return status 1795deb0bb6SMatthias Ringwald */ 1805deb0bb6SMatthias Ringwald uint8_t broadcast_audio_scan_service_client_scanning_started(uint16_t bass_cid); 1815deb0bb6SMatthias Ringwald 1825deb0bb6SMatthias Ringwald /** 1835deb0bb6SMatthias Ringwald * @brief Notify BASS Service that scanning has stopped 184ae304283SMilanka Ringwald * @note emits LEAUDIO_SUBEVENT_BASS_CLIENT_SOURCE_OPERATION_COMPLETE 1855deb0bb6SMatthias Ringwald * @param bass_cid 1865deb0bb6SMatthias Ringwald * @return status 1875deb0bb6SMatthias Ringwald */ 1885deb0bb6SMatthias Ringwald uint8_t broadcast_audio_scan_service_client_scanning_stopped(uint16_t bass_cid); 1895deb0bb6SMatthias Ringwald 1905deb0bb6SMatthias Ringwald /** 1915deb0bb6SMatthias Ringwald * @brief Add Broadcast Source on service 192*59e9e2d1SMatthias Ringwald * @note LEAUDIO_SUBEVENT_BASS_NOTIFICATION_COMPLETE will contain source_id for other functions 1935deb0bb6SMatthias Ringwald * @param bass_cid 194ae304283SMilanka Ringwald * @param add_source_data data to add, needs to stay valid until LEAUDIO_SUBEVENT_BASS_CLIENT_SOURCE_OPERATION_COMPLETE 1955deb0bb6SMatthias Ringwald * @return status 1965deb0bb6SMatthias Ringwald */ 1975deb0bb6SMatthias Ringwald uint8_t broadcast_audio_scan_service_client_add_source(uint16_t bass_cid, const bass_source_data_t * add_source_data); 1985deb0bb6SMatthias Ringwald 1995deb0bb6SMatthias Ringwald /** 2005deb0bb6SMatthias Ringwald * @brief Modify information about Broadcast Source on service 2015deb0bb6SMatthias Ringwald * @param bass_cid 2025deb0bb6SMatthias Ringwald * @param source_id 203ae304283SMilanka Ringwald * @param modify_source_data data to modify, needs to stay valid until LEAUDIO_SUBEVENT_BASS_CLIENT_SOURCE_OPERATION_COMPLETE 2045deb0bb6SMatthias Ringwald * @return status 2055deb0bb6SMatthias Ringwald */ 2065deb0bb6SMatthias Ringwald 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); 2075deb0bb6SMatthias Ringwald 2085deb0bb6SMatthias Ringwald /** 2095deb0bb6SMatthias Ringwald * @brief Set Broadcast Code for a Broadcast Source to allow remote do decrypt audio stream 2105deb0bb6SMatthias Ringwald * @param bass_cid 2115deb0bb6SMatthias Ringwald * @param source_id 2125deb0bb6SMatthias Ringwald * @param broadcast_code 2135deb0bb6SMatthias Ringwald * @return status 2145deb0bb6SMatthias Ringwald */ 2155deb0bb6SMatthias Ringwald uint8_t broadcast_audio_scan_service_client_set_broadcast_code(uint16_t bass_cid, uint8_t source_id, const uint8_t * broadcast_code); 2165deb0bb6SMatthias Ringwald 2175deb0bb6SMatthias Ringwald /** 2185deb0bb6SMatthias Ringwald * @brief Remove information about Broadcast Source 2195deb0bb6SMatthias Ringwald * @param bass_cid 2205deb0bb6SMatthias Ringwald * @param source_id 2215deb0bb6SMatthias Ringwald * @return status 2225deb0bb6SMatthias Ringwald */ 2235deb0bb6SMatthias Ringwald uint8_t broadcast_audio_scan_service_client_remove_source(uint16_t bass_cid, uint8_t source_id); 2245deb0bb6SMatthias Ringwald 2255deb0bb6SMatthias Ringwald /** 2265deb0bb6SMatthias Ringwald * @param Provide read-only access to Broadcast Receive State of given Broadcast Source on service 2275deb0bb6SMatthias Ringwald * @param bass_cid 2285deb0bb6SMatthias Ringwald * @param source_id 2295deb0bb6SMatthias Ringwald * @return pointer to source data or NULL, if source_id not found 2305deb0bb6SMatthias Ringwald */ 2315deb0bb6SMatthias Ringwald const bass_source_data_t * broadcast_audio_scan_service_client_get_source_data(uint16_t bass_cid, uint8_t source_id); 2325deb0bb6SMatthias Ringwald 2335deb0bb6SMatthias Ringwald /** 2345deb0bb6SMatthias Ringwald * @param Get BIG Encryption and Bad Code from Broadcast Receive State of given Broadcast Source on service 2355deb0bb6SMatthias Ringwald * @param bass_cid 2365deb0bb6SMatthias Ringwald * @param source_id 2375deb0bb6SMatthias Ringwald * @param out_big_encryption 2385deb0bb6SMatthias Ringwald * @param out_bad_code 16-byte buffer 2395deb0bb6SMatthias Ringwald * @return status 2405deb0bb6SMatthias Ringwald */ 2415deb0bb6SMatthias Ringwald uint8_t broadcast_audio_scan_service_client_get_encryption_state(uint16_t bass_cid, uint8_t source_id, 2425deb0bb6SMatthias Ringwald le_audio_big_encryption_t * out_big_encryption, uint8_t * out_bad_code); 2435deb0bb6SMatthias Ringwald 2445deb0bb6SMatthias Ringwald /** 2455deb0bb6SMatthias Ringwald * @brief Deinit Broadcast Audio Scan Service Client 2465deb0bb6SMatthias Ringwald */ 2475deb0bb6SMatthias Ringwald void broadcast_audio_scan_service_client_deinit(uint16_t bass_cid); 2485deb0bb6SMatthias Ringwald 2495deb0bb6SMatthias Ringwald /* API_END */ 2505deb0bb6SMatthias Ringwald 2515deb0bb6SMatthias Ringwald #if defined __cplusplus 2525deb0bb6SMatthias Ringwald } 2535deb0bb6SMatthias Ringwald #endif 2545deb0bb6SMatthias Ringwald 2555deb0bb6SMatthias Ringwald #endif 2565deb0bb6SMatthias Ringwald 257