From bdbc3ef668086acfde8cf29fd9a3f0e5544654a3 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Tue, 5 Dec 2017 14:28:47 +0100 Subject: [PATCH] avdtp initiator: add timer to repeat the set configuration query on reject --- src/classic/avdtp.c | 23 ++++++++++++++++++++--- src/classic/avdtp.h | 3 ++- src/classic/avdtp_acceptor.c | 6 ++---- src/classic/avdtp_initiator.c | 4 ++-- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/classic/avdtp.c b/src/classic/avdtp.c index 7b75e497a..38225c360 100644 --- a/src/classic/avdtp.c +++ b/src/classic/avdtp.c @@ -78,13 +78,27 @@ void avdtp_configuration_timeout_handler(btstack_timer_source_t * timer){ log_error("Context of avdtp_configuration_timeout_handler is NULL"); return; } - connection->is_initiator = 1; - log_info("avdtp_configuration_timeout_handler: role is_initiator %d", connection->is_initiator); + avdtp_stream_endpoint_t * stream_endpoint = (avdtp_stream_endpoint_t*) connection->active_stream_endpoint; + if (!stream_endpoint) { + log_error("avdtp_configuration_timeout_handler: no initiator stream endpoint for seid %d", connection->local_seid); + return; + } + if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_CONFIGURATION_SUBSTATEMACHINE) return; connection->is_configuration_initiated_locally = 1; + connection->is_initiator = 1; + connection->initiator_transaction_label++; + stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_SET_CONFIGURATION; avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid); } void avdtp_configuration_timer_start(avdtp_connection_t * connection){ + avdtp_stream_endpoint_t * stream_endpoint = (avdtp_stream_endpoint_t*) connection->active_stream_endpoint; + if (!stream_endpoint) { + log_error("avdtp_configuration_timeout_handler: no initiator stream endpoint for seid %d", connection->local_seid); + return; + } + if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_CONFIGURATION_SUBSTATEMACHINE) return; + btstack_run_loop_remove_timer(&connection->configuration_timer); btstack_run_loop_set_timer_handler(&connection->configuration_timer, avdtp_configuration_timeout_handler); btstack_run_loop_set_timer_context(&connection->configuration_timer, connection); @@ -665,7 +679,9 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet } if (connection){ + btstack_run_loop_remove_timer(&connection->configuration_timer); avdtp_signaling_emit_connection_released(context->avdtp_callback, connection->avdtp_cid); + btstack_linked_list_remove(avdtp_connections, (btstack_linked_item_t*) connection); btstack_linked_list_iterator_t it; btstack_linked_list_iterator_init(&it, stream_endpoints); @@ -937,7 +953,8 @@ void avdtp_set_configuration(uint16_t avdtp_cid, uint8_t local_seid, uint8_t rem if (!stream_endpoint) { log_error("avdtp_set_configuration: no initiator stream endpoint for seid %d", local_seid); return; - } + } + connection->active_stream_endpoint = (void*) stream_endpoint; connection->is_configuration_initiated_locally = 1; connection->is_initiator = 1; log_info("avdtp_set_configuration locally: role is_initiator %d", connection->is_initiator); diff --git a/src/classic/avdtp.h b/src/classic/avdtp.h index b38c1958a..4f7afe7be 100644 --- a/src/classic/avdtp.h +++ b/src/classic/avdtp.h @@ -394,6 +394,8 @@ typedef struct { uint8_t local_seid; uint8_t remote_seid; + // for repeating the set_configuration + void * active_stream_endpoint; uint8_t initiator_transaction_label; uint8_t acceptor_transaction_label; @@ -476,7 +478,6 @@ typedef struct avdtp_stream_endpoint { uint8_t suspend_stream; uint16_t sequence_number; - } avdtp_stream_endpoint_t; typedef struct { diff --git a/src/classic/avdtp_acceptor.c b/src/classic/avdtp_acceptor.c index 583ba996b..51120543d 100644 --- a/src/classic/avdtp_acceptor.c +++ b/src/classic/avdtp_acceptor.c @@ -194,8 +194,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ANSWER_GET_CAPABILITIES; break; case AVDTP_SI_SET_CONFIGURATION:{ - log_info("acceptor SM received SET_CONFIGURATION cmd: role is_initiator %d", connection->is_initiator); - + // log_info("acceptor SM received SET_CONFIGURATION cmd: role is_initiator %d", connection->is_initiator); if (connection->is_initiator){ if (connection->is_configuration_initiated_locally){ log_info("ACP: Set configuration already initiated locally, reject cmd "); @@ -209,9 +208,8 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t log_info("acceptor SM received SET_CONFIGURATION cmd: change role to acceptor, is_initiator %d", connection->is_initiator); } - log_info("ACP: AVDTP_ACCEPTOR_W2_ANSWER_SET_CONFIGURATION "); - + 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; diff --git a/src/classic/avdtp_initiator.c b/src/classic/avdtp_initiator.c index af28eb89a..a96098ed8 100644 --- a/src/classic/avdtp_initiator.c +++ b/src/classic/avdtp_initiator.c @@ -265,7 +265,7 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_ switch (connection->signaling_packet.signal_identifier){ case AVDTP_SI_SET_CONFIGURATION: connection->is_initiator = 0; - log_info("Received reject for set configuration, role changed from initiator to acceptor."); + log_info("Received reject for set configuration, role changed from initiator to acceptor. Start timer."); avdtp_configuration_timer_start(connection); break; default: @@ -399,7 +399,7 @@ int sent = 1; connection->signaling_packet.int_seid = connection->local_seid; connection->signaling_packet.signal_identifier = AVDTP_SI_SET_CONFIGURATION; - + stream_endpoint->state = AVDTP_STREAM_ENDPOINT_CONFIGURATION_SUBSTATEMACHINE; if (stream_endpoint_state == AVDTP_INITIATOR_W2_RECONFIGURE_STREAM_WITH_SEID){ connection->signaling_packet.signal_identifier = AVDTP_SI_RECONFIGURE; }