From 6a737fb6dffb35739dfc90427773a58b014bc75d Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 16 Jul 2021 14:36:12 +0200 Subject: [PATCH] avdtp: separate media codec validator for sink and source --- CHANGELOG.md | 2 +- src/classic/avdtp.c | 27 ++++++++++++++++++++------- src/classic/avdtp.h | 9 --------- src/classic/avdtp_sink.h | 9 +++++++++ src/classic/avdtp_source.h | 9 +++++++++ 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d6f220ab..3585adfcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - HFP: removed one parameter from hfp_ag/hf_activate_voice_recognition function, instead introduced hfp_ag/hf_deactivate_voice_recognition - HFP: event HFP_SUBEVENT_VOICE_RECOGNITION_STATUS emitted on (enhanced) voice recognition status change. Field "activated" replaced with "state". Added additional "status" field that indicates if the command was successful. - HFP: streamlined enhanced voice recognition function names -- AVDTP: media config validator is called with preview of media codec configuration event +- AVDTP: media config validator is called with preview of media codec configuration event and configured separately for sink/source - Run Loop: new functionality for HCI transport drivers and inter-process communication - *btstack_run_loop_poll_data_sources_from_irq*: used to transfer control from IRQ handler to main thread/run loop - *btstack_run_loop_execute_on_main_thread*: schedule code execution on main thread from other thread diff --git a/src/classic/avdtp.c b/src/classic/avdtp.c index f5d2f32a9..9b1f329f6 100644 --- a/src/classic/avdtp.c +++ b/src/classic/avdtp.c @@ -60,9 +60,10 @@ static bool l2cap_registered; static btstack_packet_handler_t avdtp_source_callback; static btstack_packet_handler_t avdtp_sink_callback; -static btstack_context_callback_registration_t avdtp_handle_sdp_client_query_request; -static uint8_t (*avdtp_media_config_validator)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size); +static uint8_t (*avdtp_sink_media_config_validator)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size); +static uint8_t (*avdtp_source_media_config_validator)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size); +static btstack_context_callback_registration_t avdtp_handle_sdp_client_query_request; static uint16_t sdp_query_context_avdtp_cid = 0; static uint16_t stream_endpoints_id_counter = 0; @@ -433,18 +434,29 @@ void avdtp_register_media_handler(void (*callback)(uint8_t local_seid, uint8_t * avdtp_sink_handle_media_data = callback; } -void avdtp_register_media_config_validator(uint8_t (*callback)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size)){ - avdtp_media_config_validator = callback; +void avdtp_sink_register_media_config_validator(uint8_t (*callback)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size)){ + avdtp_sink_media_config_validator = callback; +} + +void avdtp_source_register_media_config_validator(uint8_t (*callback)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size)){ + avdtp_source_media_config_validator = callback; } uint8_t avdtp_validate_media_configuration(const avdtp_stream_endpoint_t *stream_endpoint, uint16_t avdtp_cid, uint8_t reconfigure, const adtvp_media_codec_capabilities_t *media_codec) { - if (avdtp_media_config_validator == NULL) { + uint8_t (*callback)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size); + if (stream_endpoint->sep.type == AVDTP_SOURCE){ + callback = avdtp_source_media_config_validator; + } else { + callback = avdtp_sink_media_config_validator; + } + if (callback == NULL) { + // config valid return 0; } uint8_t event[AVDTP_MEDIA_CONFIG_OTHER_EVENT_LEN]; uint16_t size = avdtp_setup_media_codec_config_event(event, sizeof(event), stream_endpoint, avdtp_cid, reconfigure, media_codec); - return (*avdtp_media_config_validator)(stream_endpoint, event, size); + return (*callback)(stream_endpoint, event, size); } /* START: tracking can send now requests per l2cap cid */ @@ -1550,7 +1562,8 @@ void avdtp_deinit(void){ stream_endpoints = NULL; connections = NULL; avdtp_sink_handle_media_data = NULL; - avdtp_media_config_validator = NULL; + avdtp_sink_media_config_validator = NULL; + avdtp_source_media_config_validator = NULL; sdp_query_context_avdtp_cid = 0; stream_endpoints_id_counter = 0; diff --git a/src/classic/avdtp.h b/src/classic/avdtp.h index c45e42bd8..e6a6059c6 100644 --- a/src/classic/avdtp.h +++ b/src/classic/avdtp.h @@ -625,15 +625,6 @@ void avdtp_register_multiplexing_category(avdtp_stream_endpoint_t * stream_endpo // sink only void avdtp_register_media_handler(void (*callback)(uint8_t local_seid, uint8_t *packet, uint16_t size)); -/** - * @brief Register media configuration validator. Can reject insuitable configuration or report stream endpoint as currently busy - * @note validator has to return AVDTP error codes like: AVDTP_ERROR_CODE_SEP_IN_USE or AVDTP_ERROR_CODE_UNSUPPORTED_CONFIGURATION - * the callback receives the media configuration in the same format as the existing AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION - * and similar - * @param callback - */ -void avdtp_register_media_config_validator(uint8_t (*callback)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size)); - void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); avdtp_stream_endpoint_t * avdtp_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type); void avdtp_finalize_stream_endpoint(avdtp_stream_endpoint_t * stream_endpoint); diff --git a/src/classic/avdtp_sink.h b/src/classic/avdtp_sink.h index 5398fbe45..e16387aea 100644 --- a/src/classic/avdtp_sink.h +++ b/src/classic/avdtp_sink.h @@ -176,6 +176,15 @@ uint8_t avdtp_sink_suspend(uint16_t avdtp_cid, uint8_t local_seid); */ uint8_t avdtp_sink_delay_report(uint16_t avdtp_cid, uint8_t local_seid, uint16_t delay_100us); +/** + * @brief Register media configuration validator. Can reject insuitable configuration or report stream endpoint as currently busy + * @note validator has to return AVDTP error codes like: AVDTP_ERROR_CODE_SEP_IN_USE or AVDTP_ERROR_CODE_UNSUPPORTED_CONFIGURATION + * the callback receives the media configuration in the same format as the existing AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION + * and similar + * @param callback + */ +void avdtp_sink_register_media_config_validator(uint8_t (*callback)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size)); + /** * @brief De-Init AVDTP Sink. */ diff --git a/src/classic/avdtp_source.h b/src/classic/avdtp_source.h index 672cce32e..fea097856 100644 --- a/src/classic/avdtp_source.h +++ b/src/classic/avdtp_source.h @@ -286,6 +286,15 @@ void avdtp_source_stream_endpoint_request_can_send_now(uint16_t avddp_cid, uint8 */ int avdtp_max_media_payload_size(uint16_t avdtp_cid, uint8_t local_seid); +/** + * @brief Register media configuration validator. Can reject insuitable configuration or report stream endpoint as currently busy + * @note validator has to return AVDTP error codes like: AVDTP_ERROR_CODE_SEP_IN_USE or AVDTP_ERROR_CODE_UNSUPPORTED_CONFIGURATION + * the callback receives the media configuration in the same format as the existing AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION + * and similar + * @param callback + */ +void avdtp_source_register_media_config_validator(uint8_t (*callback)(const avdtp_stream_endpoint_t * stream_endpoint, const uint8_t * event, uint16_t size)); + /** * @brief De-Init AVDTP Source. */