avdtp: on reject set configuration change role from initiator to acceptor, and set timer to repeat set configuration until successful

This commit is contained in:
Milanka Ringwald 2017-12-01 15:23:03 +01:00
parent 63331bf43d
commit d8b859a262
4 changed files with 44 additions and 6 deletions

View File

@ -49,6 +49,8 @@
#include "classic/avdtp_acceptor.h" #include "classic/avdtp_acceptor.h"
#include "classic/avdtp_initiator.h" #include "classic/avdtp_initiator.h"
#define CONFIGURATION_TIMEOUT_MS 300
static int record_id = -1; static int record_id = -1;
static uint8_t attribute_value[1000]; static uint8_t attribute_value[1000];
static const unsigned int attribute_value_buffer_size = sizeof(attribute_value); static const unsigned int attribute_value_buffer_size = sizeof(attribute_value);
@ -70,6 +72,29 @@ static uint16_t avdtp_cid_counter = 0x55;
static void (*handle_media_data)(uint8_t local_seid, uint8_t *packet, uint16_t size); static void (*handle_media_data)(uint8_t local_seid, uint8_t *packet, uint16_t size);
static void avdtp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); static void avdtp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
void avdtp_configuration_timeout_handler(btstack_timer_source_t * timer){
avdtp_connection_t * connection = (avdtp_connection_t *) btstack_run_loop_get_timer_context(timer);
if (!connection){
log_error("Context of avdtp_configuration_timeout_handler is NULL");
return;
}
connection->is_initiator = 1;
connection->is_configuration_initiated_locally = 1;
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
}
void avdtp_configuration_timer_start(avdtp_connection_t * connection){
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);
btstack_run_loop_set_timer(&connection->configuration_timer, CONFIGURATION_TIMEOUT_MS);
btstack_run_loop_add_timer(&connection->configuration_timer);
}
void avdtp_configuration_timer_stop(avdtp_connection_t * connection){
btstack_run_loop_remove_timer(&connection->configuration_timer);
}
static uint16_t avdtp_get_next_initiator_transaction_label(avdtp_context_t * context){ static uint16_t avdtp_get_next_initiator_transaction_label(avdtp_context_t * context){
context->initiator_transaction_id_counter++; context->initiator_transaction_id_counter++;
if (context->initiator_transaction_id_counter == 0){ if (context->initiator_transaction_id_counter == 0){
@ -907,7 +932,7 @@ void avdtp_set_configuration(uint16_t avdtp_cid, uint8_t local_seid, uint8_t rem
log_error("avdtp_set_configuration: no initiator stream endpoint for seid %d", local_seid); log_error("avdtp_set_configuration: no initiator stream endpoint for seid %d", local_seid);
return; return;
} }
connection->is_configuration_initiated_localy = 1; connection->is_configuration_initiated_locally = 1;
connection->is_initiator = 1; connection->is_initiator = 1;
connection->initiator_transaction_label++; connection->initiator_transaction_label++;

View File

@ -414,7 +414,8 @@ typedef struct {
// store current role // store current role
uint8_t is_initiator; uint8_t is_initiator;
uint8_t is_configuration_initiated_localy; uint8_t is_configuration_initiated_locally;
btstack_timer_source_t configuration_timer;
} avdtp_connection_t; } avdtp_connection_t;
typedef enum { typedef enum {
@ -563,6 +564,9 @@ uint8_t avdtp_choose_sbc_max_bitpool_value(avdtp_stream_endpoint_t * stream_endp
uint8_t avdtp_choose_sbc_min_bitpool_value(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_min_bitpool_value); uint8_t avdtp_choose_sbc_min_bitpool_value(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_min_bitpool_value);
uint8_t avdtp_stream_endpoint_seid(avdtp_stream_endpoint_t * stream_endpoint); uint8_t avdtp_stream_endpoint_seid(avdtp_stream_endpoint_t * stream_endpoint);
void avdtp_configuration_timeout_handler(btstack_timer_source_t * timer);
void avdtp_configuration_timer_start(avdtp_connection_t * connection);
void avdtp_configuration_timer_stop(avdtp_connection_t * connection);
#if defined __cplusplus #if defined __cplusplus
} }

View File

@ -194,7 +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; stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ANSWER_GET_CAPABILITIES;
break; break;
case AVDTP_SI_SET_CONFIGURATION:{ case AVDTP_SI_SET_CONFIGURATION:{
if (connection->is_configuration_initiated_localy){ if (connection->is_configuration_initiated_locally){
log_info("ACP: Set configuration already initiated localy, reject cmd "); log_info("ACP: Set configuration already initiated localy, reject cmd ");
// fire configuration parsing errors // fire configuration parsing errors
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier; connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;

View File

@ -37,7 +37,6 @@
#define __BTSTACK_FILE__ "avdtp_initiator.c" #define __BTSTACK_FILE__ "avdtp_initiator.c"
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -48,7 +47,6 @@
#include "classic/avdtp_util.h" #include "classic/avdtp_util.h"
#include "classic/avdtp_initiator.h" #include "classic/avdtp_initiator.h"
static int avdtp_initiator_send_signaling_cmd(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t transaction_label){ static int avdtp_initiator_send_signaling_cmd(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t transaction_label){
uint8_t command[2]; uint8_t command[2];
command[0] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_CMD_MSG); command[0] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_CMD_MSG);
@ -168,6 +166,7 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
break; break;
case AVDTP_SI_SET_CONFIGURATION:{ case AVDTP_SI_SET_CONFIGURATION:{
avdtp_configuration_timer_stop(connection);
if (!stream_endpoint){ if (!stream_endpoint){
log_error("AVDTP_SI_SET_CONFIGURATION: stream endpoint is null"); log_error("AVDTP_SI_SET_CONFIGURATION: stream endpoint is null");
break; break;
@ -260,6 +259,15 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
connection->initiator_transaction_label++; connection->initiator_transaction_label++;
break; break;
case AVDTP_RESPONSE_REJECT_MSG: case AVDTP_RESPONSE_REJECT_MSG:
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.");
avdtp_configuration_timer_start(connection);
break;
default:
break;
}
log_info(" AVDTP_RESPONSE_REJECT_MSG signal %d", connection->signaling_packet.signal_identifier); log_info(" AVDTP_RESPONSE_REJECT_MSG signal %d", connection->signaling_packet.signal_identifier);
avdtp_signaling_emit_reject(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->signaling_packet.signal_identifier); avdtp_signaling_emit_reject(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->signaling_packet.signal_identifier);
return; return;
@ -375,9 +383,10 @@ int sent = 1;
case AVDTP_INITIATOR_W2_SET_CONFIGURATION: case AVDTP_INITIATOR_W2_SET_CONFIGURATION:
case AVDTP_INITIATOR_W2_RECONFIGURE_STREAM_WITH_SEID:{ case AVDTP_INITIATOR_W2_RECONFIGURE_STREAM_WITH_SEID:{
if (!connection->is_initiator){ if (!connection->is_initiator){
connection->is_configuration_initiated_localy = 0; connection->is_configuration_initiated_locally = 0;
break; break;
} }
connection->is_configuration_initiated_locally = 1;
log_info("INT: AVDTP_INITIATOR_W2_(RE)CONFIGURATION bitmap, int seid %d, acp seid %d", connection->local_seid, connection->remote_seid); log_info("INT: AVDTP_INITIATOR_W2_(RE)CONFIGURATION bitmap, int seid %d, acp seid %d", connection->local_seid, connection->remote_seid);
// log_info_hexdump( connection->remote_capabilities.media_codec.media_codec_information, connection->remote_capabilities.media_codec.media_codec_information_len); // log_info_hexdump( connection->remote_capabilities.media_codec.media_codec_information, connection->remote_capabilities.media_codec.media_codec_information_len);