mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-14 01:27:41 +00:00
reject invalid reconfigure
This commit is contained in:
parent
e900f5b791
commit
479a52ee79
@ -331,7 +331,7 @@ typedef struct {
|
||||
uint8_t in_use; // 1 bit, 0 - not in use, 1 - in use
|
||||
avdtp_media_type_t media_type; // 4 bit
|
||||
avdtp_sep_type_t type; // 1 bit, 0 - SRC, 1 - SNK
|
||||
|
||||
|
||||
uint16_t registered_service_categories;
|
||||
avdtp_capabilities_t capabilities;
|
||||
} avdtp_sep_t;
|
||||
@ -347,7 +347,8 @@ typedef enum {
|
||||
typedef enum {
|
||||
AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE,
|
||||
AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS,
|
||||
AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE
|
||||
AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE,
|
||||
AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE
|
||||
} avdtp_acceptor_connection_state_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -97,11 +97,19 @@ static uint16_t avdtp_unpack_service_capabilities(avdtp_connection_t * connectio
|
||||
uint16_t registered_service_categories = 0;
|
||||
int pos = 0;
|
||||
avdtp_service_category_t category = (avdtp_service_category_t)packet[pos++];
|
||||
|
||||
connection->error_code = 0;
|
||||
if (category < AVDTP_MEDIA_TRANSPORT || category > AVDTP_DELAY_REPORTING){
|
||||
printf(" avdtp_unpack_service_capabilities wrong category %d\n", category);
|
||||
printf(" ACP: BAD SERVICE CATEGORY %d\n", category);
|
||||
connection->reject_service_category = category;
|
||||
connection->error_code = BAD_SERV_CATEGORY;
|
||||
return 0;
|
||||
}
|
||||
if (connection->signaling_packet.signal_identifier == AVDTP_SI_RECONFIGURE){
|
||||
if (category != AVDTP_CONTENT_PROTECTION && category != AVDTP_MEDIA_CODEC){
|
||||
connection->reject_service_category = category;
|
||||
connection->error_code = INVALID_CAPABILITIES;
|
||||
}
|
||||
}
|
||||
int i;
|
||||
uint8_t cap_len = packet[pos++];
|
||||
printf(" ACP: avdtp_unpack_service_capabilities: category %d, capability len %d, record size %d\n", category, cap_len, size);
|
||||
@ -166,13 +174,13 @@ static uint16_t avdtp_unpack_service_capabilities(avdtp_connection_t * connectio
|
||||
|
||||
registered_service_categories = store_bit16(registered_service_categories, category, 1);
|
||||
processed_cap_len = pos - processed_cap_len;
|
||||
printf(" ACP: avdtp_unpack_service_capabilities 2: category %d, processed_cap_len %d, pos %d\n", category, processed_cap_len, pos);
|
||||
if (cap_len <= processed_cap_len && pos < size-2){
|
||||
category = (avdtp_service_category_t)packet[pos++];
|
||||
cap_len = packet[pos++];
|
||||
printf(" ACP: avdtp_unpack_service_capabilities: category %d, capability len %d, remaining record size %d\n", category, cap_len, size-pos);
|
||||
}
|
||||
}
|
||||
// printf(" avdtp_unpack_service_capabilities done\n");
|
||||
printf(" avdtp_unpack_service_capabilities done error %d\n", connection->error_code);
|
||||
return registered_service_categories;
|
||||
}
|
||||
|
||||
@ -217,6 +225,7 @@ static int avdtp_acceptor_process_chunk(avdtp_signaling_packet_t * signaling_pac
|
||||
return signaling_packet->packet_type == AVDTP_SINGLE_PACKET || signaling_packet->packet_type == AVDTP_END_PACKET;
|
||||
}
|
||||
|
||||
|
||||
int avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint, uint8_t * packet, uint16_t size){
|
||||
if (!stream_endpoint) return 0;
|
||||
|
||||
@ -275,7 +284,6 @@ int avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, avdtp_st
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||
}
|
||||
@ -304,9 +312,17 @@ int avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, avdtp_st
|
||||
|
||||
printf(" ACP: AVDTP_ACCEPTOR_W2_ANSWER_RECONFIGURE %p in state %d (AVDTP_STREAM_ENDPOINT_OPENED %d)\n", stream_endpoint, stream_endpoint->state, AVDTP_STREAM_ENDPOINT_OPENED);
|
||||
avdtp_sep_t sep;
|
||||
sep.seid = packet[3] >> 2;
|
||||
sep.registered_service_categories = avdtp_unpack_service_capabilities(connection, &sep.capabilities, packet+4, packet_size-4);
|
||||
sep.seid = packet[2] >> 2;
|
||||
sep.registered_service_categories = avdtp_unpack_service_capabilities(connection, &sep.capabilities, connection->signaling_packet.command+3, packet_size-3);
|
||||
|
||||
if (connection->error_code){
|
||||
// fire capabilities parsing errors
|
||||
printf(" ACP: REJECT CATEGORY, error code by upacking\n");
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||
break;
|
||||
}
|
||||
|
||||
// find sep or raise error
|
||||
int i;
|
||||
for (i = 0; i < stream_endpoint->remote_seps_num; i++){
|
||||
@ -316,29 +332,12 @@ int avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, avdtp_st
|
||||
}
|
||||
|
||||
if (stream_endpoint->remote_sep_index == 0xFF){
|
||||
printf(" ACP: AVDTP_SI_RECONFIGURE, bad state seid %d not found\n", sep.seid);
|
||||
printf(" ACP: REJECT AVDTP_SI_RECONFIGURE, BAD_ACP_SEID\n");
|
||||
stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||
connection->error_code = BAD_ACP_SEID;
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
break;
|
||||
}
|
||||
|
||||
// only codec, and
|
||||
uint16_t remaining_service_categories = sep.registered_service_categories;
|
||||
if (get_bit16(sep.registered_service_categories, AVDTP_MEDIA_CODEC-1)){
|
||||
remaining_service_categories = store_bit16(sep.registered_service_categories, AVDTP_MEDIA_CODEC-1, 0);
|
||||
}
|
||||
if (get_bit16(sep.registered_service_categories, AVDTP_CONTENT_PROTECTION-1)){
|
||||
remaining_service_categories = store_bit16(sep.registered_service_categories, AVDTP_CONTENT_PROTECTION-1, 0);
|
||||
}
|
||||
if (!remaining_service_categories) break;
|
||||
|
||||
// find first category that shouldn't be reconfigured
|
||||
for (i = 1; i < 9; i++){
|
||||
if (get_bit16(sep.registered_service_categories, i-1)){
|
||||
connection->reject_service_category = i;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AVDTP_SI_OPEN:
|
||||
@ -394,7 +393,7 @@ int avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, avdtp_st
|
||||
return request_to_send;
|
||||
}
|
||||
|
||||
static int avdtp_acceptor_send_response_reject_service_category(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t category, uint8_t error_code, uint8_t transaction_label){
|
||||
int avdtp_acceptor_send_response_reject_service_category(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t category, uint8_t error_code, uint8_t transaction_label){
|
||||
uint8_t command[4];
|
||||
command[0] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_RESPONSE_REJECT_MSG);
|
||||
command[1] = (uint8_t)identifier;
|
||||
|
@ -55,6 +55,7 @@ int avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, avdtp_s
|
||||
int avdtp_acceptor_stream_config_subsm_run(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint);
|
||||
|
||||
int avdtp_acceptor_send_response_reject_with_error_code(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t error_code, uint8_t transaction_label);
|
||||
int avdtp_acceptor_send_response_reject_service_category(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t category, uint8_t error_code, uint8_t transaction_label);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
|
@ -435,6 +435,10 @@ static void avdtp_sink_handle_can_send_now(avdtp_connection_t * connection, uint
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
||||
avdtp_acceptor_send_response_reject_with_error_code(connection->l2cap_signaling_cid, connection->reject_signal_identifier, connection->error_code, connection->acceptor_transaction_label);
|
||||
break;
|
||||
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE:
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
||||
avdtp_acceptor_send_response_reject_service_category(connection->l2cap_signaling_cid, connection->reject_signal_identifier, connection->reject_service_category, connection->error_code, connection->acceptor_transaction_label);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -483,13 +487,14 @@ static int handle_l2cap_data_packet_for_signaling_connection(avdtp_connection_t
|
||||
|
||||
avdtp_stream_endpoint_t * stream_endpoint = NULL;
|
||||
avdtp_read_signaling_header(&connection->signaling_packet, packet, size);
|
||||
|
||||
switch (connection->signaling_packet.message_type){
|
||||
case AVDTP_CMD_MSG:
|
||||
printf("AVDTP_CMD_MSG: ");
|
||||
printf_hexdump(packet, size);
|
||||
printf("\n");
|
||||
connection->acceptor_transaction_label = connection->signaling_packet.transaction_label;
|
||||
switch (connection->signaling_packet.signal_identifier){
|
||||
case AVDTP_SI_DISCOVER:
|
||||
printf(" -> AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS\n");
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return 0;
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS;
|
||||
avdtp_sink_request_can_send_now_self(connection, connection->l2cap_signaling_cid);
|
||||
@ -500,18 +505,32 @@ static int handle_l2cap_data_packet_for_signaling_connection(avdtp_connection_t
|
||||
case AVDTP_SI_GET_CONFIGURATION:
|
||||
case AVDTP_SI_OPEN:
|
||||
case AVDTP_SI_START:
|
||||
case AVDTP_SI_RECONFIGURE:
|
||||
case AVDTP_SI_CLOSE:
|
||||
case AVDTP_SI_ABORT:
|
||||
connection->query_seid = packet[2] >> 2;
|
||||
stream_endpoint = get_avdtp_stream_endpoint_for_active_seid(connection->query_seid);
|
||||
if (!stream_endpoint){
|
||||
printf(" ACP: RESPONSE REJECT BAD_ACP_SEID\n");
|
||||
connection->error_code = BAD_ACP_SEID;
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
return handle_l2cap_data_packet_for_stream_endpoint(connection, stream_endpoint, packet, size);
|
||||
case AVDTP_SI_RECONFIGURE:
|
||||
connection->query_seid = packet[2] >> 2;
|
||||
stream_endpoint = get_avdtp_stream_endpoint_for_active_seid(connection->query_seid);
|
||||
if (!stream_endpoint){
|
||||
printf(" ACP: CATEGORY RESPONSE REJECT BAD_ACP_SEID\n");
|
||||
connection->error_code = BAD_ACP_SEID;
|
||||
connection->reject_service_category = 0;
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
return 0;
|
||||
}
|
||||
return handle_l2cap_data_packet_for_stream_endpoint(connection, stream_endpoint, packet, size);
|
||||
|
||||
break;
|
||||
case AVDTP_SI_SUSPEND:{
|
||||
int i;
|
||||
for (i=2; i<size; i++){
|
||||
@ -529,6 +548,8 @@ static int handle_l2cap_data_packet_for_signaling_connection(avdtp_connection_t
|
||||
}
|
||||
break;
|
||||
case AVDTP_RESPONSE_ACCEPT_MSG:
|
||||
printf("handle_l2cap_data_packet_for_signaling_connection AVDTP_RESPONSE_ACCEPT_MSG\n");
|
||||
|
||||
switch (connection->signaling_packet.signal_identifier){
|
||||
case AVDTP_SI_DISCOVER:
|
||||
if (connection->signaling_packet.transaction_label != connection->initiator_transaction_label){
|
||||
@ -645,16 +666,15 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
stream_endpoint = get_avdtp_stream_endpoint_for_l2cap_cid(channel);
|
||||
if (!stream_endpoint){
|
||||
if (!connection) break;
|
||||
printf("avdtp L2CAP_DATA_PACKET: no stream enpoint for local cid 0x%02x found\n", channel);
|
||||
connection->error_code = BAD_ACP_SEID;
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||
avdtp_sink_request_can_send_now_self(connection, channel);
|
||||
printf("avdtp L2CAP_DATA_PACKET: no stream enpoint for local cid 0x%02x found", channel);
|
||||
break;
|
||||
}
|
||||
|
||||
if (channel == stream_endpoint->connection->l2cap_signaling_cid){
|
||||
printf(" handle_l2cap_data_packet_for_signaling_connection 1\n");
|
||||
stream_endpoint_state_machine(stream_endpoint->connection, stream_endpoint, L2CAP_DATA_PACKET, 0, packet, size);
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user