18ef7100fSMilanka Ringwald /* 28ef7100fSMilanka Ringwald * Copyright (C) 2016 BlueKitchen GmbH 38ef7100fSMilanka Ringwald * 48ef7100fSMilanka Ringwald * Redistribution and use in source and binary forms, with or without 58ef7100fSMilanka Ringwald * modification, are permitted provided that the following conditions 68ef7100fSMilanka Ringwald * are met: 78ef7100fSMilanka Ringwald * 88ef7100fSMilanka Ringwald * 1. Redistributions of source code must retain the above copyright 98ef7100fSMilanka Ringwald * notice, this list of conditions and the following disclaimer. 108ef7100fSMilanka Ringwald * 2. Redistributions in binary form must reproduce the above copyright 118ef7100fSMilanka Ringwald * notice, this list of conditions and the following disclaimer in the 128ef7100fSMilanka Ringwald * documentation and/or other materials provided with the distribution. 138ef7100fSMilanka Ringwald * 3. Neither the name of the copyright holders nor the names of 148ef7100fSMilanka Ringwald * contributors may be used to endorse or promote products derived 158ef7100fSMilanka Ringwald * from this software without specific prior written permission. 168ef7100fSMilanka Ringwald * 4. Any redistribution, use, or modification is done solely for 178ef7100fSMilanka Ringwald * personal benefit and not for any commercial purpose or for 188ef7100fSMilanka Ringwald * monetary gain. 198ef7100fSMilanka Ringwald * 208ef7100fSMilanka Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 218ef7100fSMilanka Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 228ef7100fSMilanka Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 238ef7100fSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 248ef7100fSMilanka Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 258ef7100fSMilanka Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 268ef7100fSMilanka Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 278ef7100fSMilanka Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 288ef7100fSMilanka Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 298ef7100fSMilanka Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 308ef7100fSMilanka Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 318ef7100fSMilanka Ringwald * SUCH DAMAGE. 328ef7100fSMilanka Ringwald * 338ef7100fSMilanka Ringwald * Please inquire about commercial licensing options at 348ef7100fSMilanka Ringwald * [email protected] 358ef7100fSMilanka Ringwald * 368ef7100fSMilanka Ringwald */ 378ef7100fSMilanka Ringwald 38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "avdtp_sink.c" 39ab2c6ae4SMatthias Ringwald 408ef7100fSMilanka Ringwald #include <stdint.h> 418ef7100fSMilanka Ringwald #include <string.h> 428ef7100fSMilanka Ringwald 4384e3541eSMilanka Ringwald #include "bluetooth_psm.h" 4484e3541eSMilanka Ringwald #include "bluetooth_sdp.h" 4584e3541eSMilanka Ringwald #include "btstack_debug.h" 4684e3541eSMilanka Ringwald #include "btstack_event.h" 4784e3541eSMilanka Ringwald #include "l2cap.h" 4884e3541eSMilanka Ringwald 494cb889a5SMilanka Ringwald #include "classic/avdtp.h" 5084e3541eSMilanka Ringwald #include "classic/avdtp_acceptor.h" 5184e3541eSMilanka Ringwald #include "classic/avdtp_initiator.h" 524cb889a5SMilanka Ringwald #include "classic/avdtp_sink.h" 534cb889a5SMilanka Ringwald #include "classic/avdtp_util.h" 548ef7100fSMilanka Ringwald 558ef7100fSMilanka Ringwald void avdtp_sink_register_media_transport_category(uint8_t seid){ 56d8e15394SMilanka Ringwald avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(seid); 57747ec646SMilanka Ringwald avdtp_register_media_transport_category(stream_endpoint); 588ef7100fSMilanka Ringwald } 598ef7100fSMilanka Ringwald 608ef7100fSMilanka Ringwald void avdtp_sink_register_reporting_category(uint8_t seid){ 61d8e15394SMilanka Ringwald avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(seid); 62747ec646SMilanka Ringwald avdtp_register_reporting_category(stream_endpoint); 638ef7100fSMilanka Ringwald } 648ef7100fSMilanka Ringwald 658ef7100fSMilanka Ringwald void avdtp_sink_register_delay_reporting_category(uint8_t seid){ 66d8e15394SMilanka Ringwald avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(seid); 67747ec646SMilanka Ringwald avdtp_register_delay_reporting_category(stream_endpoint); 688ef7100fSMilanka Ringwald } 698ef7100fSMilanka Ringwald 708ef7100fSMilanka Ringwald void avdtp_sink_register_recovery_category(uint8_t seid, uint8_t maximum_recovery_window_size, uint8_t maximum_number_media_packets){ 71d8e15394SMilanka Ringwald avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(seid); 72747ec646SMilanka Ringwald avdtp_register_recovery_category(stream_endpoint, maximum_recovery_window_size, maximum_number_media_packets); 738ef7100fSMilanka Ringwald } 748ef7100fSMilanka Ringwald 758ef7100fSMilanka Ringwald void avdtp_sink_register_content_protection_category(uint8_t seid, uint16_t cp_type, const uint8_t * cp_type_value, uint8_t cp_type_value_len){ 76d8e15394SMilanka Ringwald avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(seid); 77747ec646SMilanka Ringwald avdtp_register_content_protection_category(stream_endpoint, cp_type, cp_type_value, cp_type_value_len); 788ef7100fSMilanka Ringwald } 798ef7100fSMilanka Ringwald 808ef7100fSMilanka Ringwald void avdtp_sink_register_header_compression_category(uint8_t seid, uint8_t back_ch, uint8_t media, uint8_t recovery){ 81d8e15394SMilanka Ringwald avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(seid); 82747ec646SMilanka Ringwald avdtp_register_header_compression_category(stream_endpoint, back_ch, media, recovery); 838ef7100fSMilanka Ringwald } 848ef7100fSMilanka Ringwald 8578d08d09SMilanka Ringwald void avdtp_sink_register_media_codec_category(uint8_t seid, avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type, uint8_t * media_codec_info, uint16_t media_codec_info_len){ 86d8e15394SMilanka Ringwald avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(seid); 87747ec646SMilanka Ringwald avdtp_register_media_codec_category(stream_endpoint, media_type, media_codec_type, media_codec_info, media_codec_info_len); 888ef7100fSMilanka Ringwald } 898ef7100fSMilanka Ringwald 908ef7100fSMilanka Ringwald void avdtp_sink_register_multiplexing_category(uint8_t seid, uint8_t fragmentation){ 91d8e15394SMilanka Ringwald avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_for_seid(seid); 92747ec646SMilanka Ringwald avdtp_register_multiplexing_category(stream_endpoint, fragmentation); 938ef7100fSMilanka Ringwald } 948ef7100fSMilanka Ringwald /* END: tracking can send now requests pro l2cap cid */ 95a1fb0563SMilanka Ringwald 96a1fb0563SMilanka Ringwald void avdtp_sink_register_packet_handler(btstack_packet_handler_t callback){ 97a1fb0563SMilanka Ringwald btstack_assert(callback != NULL); 98a1fb0563SMilanka Ringwald 99a1fb0563SMilanka Ringwald avdtp_register_sink_packet_handler(callback); 100a1fb0563SMilanka Ringwald } 1018ef7100fSMilanka Ringwald 10277092f3eSMatthias Ringwald void avdtp_sink_init(void) { 1038322fb3aSMatthias Ringwald avdtp_init(); 1048ef7100fSMilanka Ringwald } 1058ef7100fSMilanka Ringwald 106747ec646SMilanka Ringwald avdtp_stream_endpoint_t * avdtp_sink_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type){ 107297feb5fSMilanka Ringwald return avdtp_create_stream_endpoint(sep_type, media_type); 108747ec646SMilanka Ringwald } 109747ec646SMilanka Ringwald 11017ddf501SMatthias Ringwald void avdtp_sink_finalize_stream_endpoint(avdtp_stream_endpoint_t * stream_endpoint){ 11117ddf501SMatthias Ringwald avdtp_finalize_stream_endpoint(stream_endpoint); 11217ddf501SMatthias Ringwald } 11317ddf501SMatthias Ringwald 114fd58c900SMilanka Ringwald void avdtp_sink_register_media_handler(void (*callback)(uint8_t local_seid, uint8_t *packet, uint16_t size)){ 115951d2774SMatthias Ringwald avdtp_register_media_handler(callback); 1168ef7100fSMilanka Ringwald } 1178ef7100fSMilanka Ringwald 1184ccacc40SMilanka Ringwald uint8_t avdtp_sink_connect(bd_addr_t remote, uint16_t * avdtp_cid){ 119a1fb0563SMilanka Ringwald return avdtp_connect(remote, AVDTP_ROLE_SINK, avdtp_cid); 1208ef7100fSMilanka Ringwald } 1218ef7100fSMilanka Ringwald 1224ccacc40SMilanka Ringwald uint8_t avdtp_sink_disconnect(uint16_t avdtp_cid){ 123b401ff59SMilanka Ringwald return avdtp_disconnect(avdtp_cid); 1248ef7100fSMilanka Ringwald } 1258ef7100fSMilanka Ringwald 1264ccacc40SMilanka Ringwald uint8_t avdtp_sink_open_stream(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){ 127297feb5fSMilanka Ringwald return avdtp_open_stream(avdtp_cid, local_seid, remote_seid); 1288ef7100fSMilanka Ringwald } 1298ef7100fSMilanka Ringwald 1304ccacc40SMilanka Ringwald uint8_t avdtp_sink_start_stream(uint16_t avdtp_cid, uint8_t local_seid){ 131297feb5fSMilanka Ringwald return avdtp_start_stream(avdtp_cid, local_seid); 1328ef7100fSMilanka Ringwald } 1338ef7100fSMilanka Ringwald 1344ccacc40SMilanka Ringwald uint8_t avdtp_sink_stop_stream(uint16_t avdtp_cid, uint8_t local_seid){ 135297feb5fSMilanka Ringwald return avdtp_stop_stream(avdtp_cid, local_seid); 1368ef7100fSMilanka Ringwald } 1378ef7100fSMilanka Ringwald 1384ccacc40SMilanka Ringwald uint8_t avdtp_sink_abort_stream(uint16_t avdtp_cid, uint8_t local_seid){ 139297feb5fSMilanka Ringwald return avdtp_abort_stream(avdtp_cid, local_seid); 14060ec20d0SMilanka Ringwald } 14160ec20d0SMilanka Ringwald 1424ccacc40SMilanka Ringwald uint8_t avdtp_sink_suspend(uint16_t avdtp_cid, uint8_t local_seid){ 143297feb5fSMilanka Ringwald return avdtp_suspend_stream(avdtp_cid, local_seid); 1448ef7100fSMilanka Ringwald } 1458ef7100fSMilanka Ringwald 1469974aee0SMilanka Ringwald uint8_t avdtp_sink_discover_stream_endpoints(uint16_t avdtp_cid){ 1475ace758fSMilanka Ringwald return avdtp_discover_stream_endpoints(avdtp_cid); 1488ef7100fSMilanka Ringwald } 1498ef7100fSMilanka Ringwald 1509974aee0SMilanka Ringwald uint8_t avdtp_sink_get_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){ 15133948a42SMilanka Ringwald return avdtp_get_capabilities(avdtp_cid, remote_seid); 1528ef7100fSMilanka Ringwald } 1538ef7100fSMilanka Ringwald 1549974aee0SMilanka Ringwald uint8_t avdtp_sink_get_all_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){ 15533948a42SMilanka Ringwald return avdtp_get_all_capabilities(avdtp_cid, remote_seid); 1568ef7100fSMilanka Ringwald } 1578ef7100fSMilanka Ringwald 1589974aee0SMilanka Ringwald uint8_t avdtp_sink_get_configuration(uint16_t avdtp_cid, uint8_t remote_seid){ 15933948a42SMilanka Ringwald return avdtp_get_configuration(avdtp_cid, remote_seid); 1608ef7100fSMilanka Ringwald } 1618ef7100fSMilanka Ringwald 1629974aee0SMilanka Ringwald uint8_t avdtp_sink_set_configuration(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){ 163cec76c5bSMilanka Ringwald return avdtp_set_configuration(avdtp_cid, local_seid, remote_seid, configured_services_bitmap, configuration); 1648ef7100fSMilanka Ringwald } 1658ef7100fSMilanka Ringwald 1669974aee0SMilanka Ringwald uint8_t avdtp_sink_reconfigure(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){ 167cec76c5bSMilanka Ringwald return avdtp_reconfigure(avdtp_cid, local_seid, remote_seid, configured_services_bitmap, configuration); 1688ef7100fSMilanka Ringwald } 1698ef7100fSMilanka Ringwald 170522706d7SMilanka Ringwald uint8_t avdtp_sink_delay_report(uint16_t avdtp_cid, uint8_t local_seid, uint16_t delay_100us){ 1715ace758fSMilanka Ringwald avdtp_connection_t * connection = avdtp_get_connection_for_avdtp_cid(avdtp_cid); 17219af95b4SMilanka Ringwald if (!connection){ 17319af95b4SMilanka Ringwald log_error("delay_report: no connection for signaling cid 0x%02x found", avdtp_cid); 17423edb87eSMilanka Ringwald return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 17519af95b4SMilanka Ringwald } 176522706d7SMilanka Ringwald 1770e588213SMatthias Ringwald if ((connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) || 178c1ab6cc1SMatthias Ringwald (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE)) { 17919af95b4SMilanka Ringwald log_error("delay_report: connection in wrong state, state %d, initiator state %d", connection->state, connection->initiator_connection_state); 18023edb87eSMilanka Ringwald return ERROR_CODE_COMMAND_DISALLOWED; 18119af95b4SMilanka Ringwald } 18219af95b4SMilanka Ringwald 1836f98b084SMilanka Ringwald avdtp_stream_endpoint_t * stream_endpoint = avdtp_get_stream_endpoint_with_seid(local_seid); 18419af95b4SMilanka Ringwald if (!stream_endpoint) { 18519af95b4SMilanka Ringwald log_error("delay_report: no stream_endpoint with seid %d found", local_seid); 18623edb87eSMilanka Ringwald return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 18719af95b4SMilanka Ringwald } 18819af95b4SMilanka Ringwald 18919af95b4SMilanka Ringwald if (stream_endpoint->state < AVDTP_STREAM_ENDPOINT_CONFIGURED){ 19019af95b4SMilanka Ringwald log_error("Stream endpoint seid %d in wrong state %d", local_seid, stream_endpoint->state); 19123edb87eSMilanka Ringwald return ERROR_CODE_COMMAND_DISALLOWED; 19219af95b4SMilanka Ringwald } 19319af95b4SMilanka Ringwald 19419af95b4SMilanka Ringwald connection->initiator_transaction_label++; 19519af95b4SMilanka Ringwald connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_SEND_DELAY_REPORT; 196522706d7SMilanka Ringwald connection->delay_ms = delay_100us; 1975bd73fa2SMatthias Ringwald connection->initiator_local_seid = local_seid; 19896dcd0f4SMatthias Ringwald connection->initiator_remote_seid = stream_endpoint->remote_sep.seid; 199*d80ccd43SMatthias Ringwald avdtp_request_can_send_now_initiator(connection); 20019af95b4SMilanka Ringwald return ERROR_CODE_SUCCESS; 20119af95b4SMilanka Ringwald } 20219af95b4SMilanka Ringwald 203