mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-01 10:13:29 +00:00
avdtp: avdtp_register_media_config_validator allows to validate media codec configuration
This commit is contained in:
parent
cdc66b5eb8
commit
1ef2d533ff
@ -25,6 +25,7 @@ GAP: add `gap_set_page_scan_activity` and `gap_set_page_scan_type`
|
||||
AVRCP: new field `button_pressed` in `AVRCP_SUBEVENT_OPERATION`
|
||||
AVRCP: `AVRCP_SUBEVENT_OPERATION` emitted for button release
|
||||
AVRCP Controller: avrcp_controller_start_press_and_hold_cmd helps to support device buttons
|
||||
AVDTP: `avdtp_register_media_config_validator` allows to validate media codec configuration
|
||||
|
||||
### Fixed
|
||||
HCI: handle start inquiry failure
|
||||
|
@ -60,6 +60,7 @@ 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, avdtp_media_codec_type_t media_codec_type, const uint8_t * media_codec_info, uint16_t media_codec_info_len);
|
||||
|
||||
static uint16_t sdp_query_context_avdtp_cid = 0;
|
||||
|
||||
@ -429,6 +430,17 @@ 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, avdtp_media_codec_type_t media_codec_type, const uint8_t * media_codec_info, uint16_t media_codec_info_len)){
|
||||
avdtp_media_config_validator = callback;
|
||||
}
|
||||
|
||||
uint8_t avdtp_validate_media_configuration(const avdtp_stream_endpoint_t * stream_endpoint, avdtp_media_codec_type_t media_codec_type, const uint8_t * media_codec_info, uint16_t media_codec_info_len){
|
||||
if (avdtp_media_config_validator == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return (*avdtp_media_config_validator)(stream_endpoint, media_codec_type, media_codec_info, media_codec_info_len);
|
||||
}
|
||||
|
||||
/* START: tracking can send now requests per l2cap cid */
|
||||
static void avdtp_handle_can_send_now(uint16_t l2cap_cid) {
|
||||
|
||||
@ -1517,6 +1529,7 @@ void avdtp_deinit(void){
|
||||
stream_endpoints = NULL;
|
||||
connections = NULL;
|
||||
avdtp_sink_handle_media_data = NULL;
|
||||
avdtp_media_config_validator = NULL;
|
||||
|
||||
sdp_query_context_avdtp_cid = 0;
|
||||
stream_endpoints_id_counter = 0;
|
||||
|
@ -621,6 +621,13 @@ 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: SEP_IN_USE or UNSUPPORTED_CONFIGURATION
|
||||
* @param callback
|
||||
*/
|
||||
void avdtp_register_media_config_validator(uint8_t (*callback)(const avdtp_stream_endpoint_t * stream_endpoint, avdtp_media_codec_type_t media_codec_type, const uint8_t * media_codec_info, uint16_t media_codec_info_len));
|
||||
|
||||
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);
|
||||
@ -642,6 +649,7 @@ uint8_t avdtp_get_all_capabilities(uint16_t avdtp_cid, uint8_t remote_seid);
|
||||
uint8_t avdtp_get_configuration(uint16_t avdtp_cid, uint8_t remote_seid);
|
||||
uint8_t avdtp_set_configuration(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration);
|
||||
uint8_t avdtp_reconfigure(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration);
|
||||
uint8_t avdtp_validate_media_configuration(const avdtp_stream_endpoint_t * stream_endpoint, avdtp_media_codec_type_t media_codec_type, const uint8_t * media_codec_info, uint16_t media_codec_info_len);
|
||||
|
||||
// frequency will be used by avdtp_choose_sbc_sampling_frequency (if supported by both endpoints)
|
||||
void avdtp_set_preferred_sampling_frequeny(avdtp_stream_endpoint_t * stream_endpoint, uint32_t sampling_frequency);
|
||||
|
@ -89,20 +89,35 @@ static void
|
||||
avdtp_acceptor_handle_configuration_command(avdtp_connection_t *connection, int offset, uint16_t packet_size, avdtp_stream_endpoint_t *stream_endpoint) {
|
||||
log_info("W2_ANSWER_SET_CONFIGURATION cid 0x%02x", connection->avdtp_cid);
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_CONFIGURATION_SUBSTATEMACHINE;
|
||||
stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ANSWER_SET_CONFIGURATION;
|
||||
connection->reject_service_category = 0;
|
||||
stream_endpoint->connection = connection;
|
||||
|
||||
// process capabilities, first rejected service category is stored in connection
|
||||
connection->reject_service_category = 0;
|
||||
avdtp_sep_t sep;
|
||||
sep.seid = connection->acceptor_signaling_packet.command[offset++] >> 2;
|
||||
sep.configured_service_categories = avdtp_unpack_service_capabilities(connection, connection->acceptor_signaling_packet.signal_identifier, &sep.configuration, connection->acceptor_signaling_packet.command+offset, packet_size-offset);
|
||||
sep.in_use = 1;
|
||||
|
||||
// let application validate media configuration as well
|
||||
if (connection->error_code == 0){
|
||||
if ((sep.configured_service_categories & (1 << AVDTP_MEDIA_CODEC)) != 0){
|
||||
adtvp_media_codec_capabilities_t * media = & sep.configuration.media_codec;
|
||||
uint8_t error_code = avdtp_validate_media_configuration(stream_endpoint, media->media_codec_type, media->media_codec_information, media->media_codec_information_len);
|
||||
if (error_code != 0){
|
||||
log_info("media codec rejected by validator, error 0x%02x", error_code);
|
||||
connection->reject_service_category = AVDTP_MEDIA_CODEC;
|
||||
connection->error_code = error_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (connection->error_code){
|
||||
log_info("fire configuration parsing errors ");
|
||||
connection->reject_signal_identifier = connection->acceptor_signaling_packet.signal_identifier;
|
||||
stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||
return;
|
||||
}
|
||||
|
||||
stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ANSWER_SET_CONFIGURATION;
|
||||
// find or add sep
|
||||
|
||||
log_info("local seid %d, remote seid %d", connection->acceptor_local_seid, sep.seid);
|
||||
|
Loading…
x
Reference in New Issue
Block a user