mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-30 07:21:20 +00:00
avrcp: new avrcp target fragmentation
This commit is contained in:
parent
4d7cf3906f
commit
aeb999167a
@ -332,21 +332,21 @@ void avrcp_create_sdp_record(uint8_t controller, uint8_t * service, uint32_t ser
|
||||
de_add_number(service, DE_UINT, DE_SIZE_16, supported_features);
|
||||
}
|
||||
|
||||
static uint16_t avctp_get_header_offset(avctp_packet_type_t avctp_packet_type) {
|
||||
uint16_t offset; // AVCTP message: header (1), num_packets (1), pid (2)
|
||||
uint16_t avctp_get_num_bytes_for_header(avctp_packet_type_t avctp_packet_type) {
|
||||
switch (avctp_packet_type){
|
||||
case AVCTP_SINGLE_PACKET:
|
||||
// AVCTP message: transport header (1), pid (2)
|
||||
return 3;
|
||||
case AVCTP_START_PACKET:
|
||||
offset = 4;
|
||||
break;
|
||||
// AVCTP message: transport header (1), num_packets (1), pid (2)
|
||||
return 4;
|
||||
default:
|
||||
offset = 1;
|
||||
break;
|
||||
// AVCTP message: transport header (1)
|
||||
return 1;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static uint16_t avctp_get_message_offset(avrcp_command_opcode_t command_opcode, avctp_packet_type_t avctp_packet_type) {
|
||||
uint16_t avrcp_get_num_bytes_for_header(avrcp_command_opcode_t command_opcode, avctp_packet_type_t avctp_packet_type) {
|
||||
switch (avctp_packet_type){
|
||||
case AVCTP_SINGLE_PACKET:
|
||||
case AVCTP_START_PACKET:
|
||||
@ -369,33 +369,62 @@ static uint16_t avctp_get_message_offset(avrcp_command_opcode_t command_opcode,
|
||||
return offset;
|
||||
}
|
||||
|
||||
static uint16_t avctp_get_max_payload_size(uint16_t l2cap_cid, avrcp_command_opcode_t command_opcode, avctp_packet_type_t avctp_packet_type){
|
||||
static uint16_t avrcp_get_num_free_bytes_for_payload(uint16_t l2cap_cid, avrcp_command_opcode_t command_opcode, avctp_packet_type_t avctp_packet_type){
|
||||
uint16_t max_frame_size = btstack_min(l2cap_get_remote_mtu_for_local_cid(l2cap_cid), AVRCP_MAX_AV_C_MESSAGE_FRAME_SIZE);
|
||||
uint16_t offset = avctp_get_header_offset(avctp_packet_type) + avctp_get_message_offset(command_opcode, avctp_packet_type);
|
||||
uint16_t payload_offset = avctp_get_num_bytes_for_header(avctp_packet_type) +
|
||||
avrcp_get_num_bytes_for_header(command_opcode, avctp_packet_type);
|
||||
|
||||
btstack_assert( max_frame_size >= offset);
|
||||
return (max_frame_size - offset);
|
||||
btstack_assert(max_frame_size >= payload_offset);
|
||||
return (max_frame_size - payload_offset);
|
||||
}
|
||||
|
||||
|
||||
avctp_packet_type_t avctp_get_packet_type(avrcp_connection_t * connection, uint16_t * max_payload_size){
|
||||
if (connection->data_offset == 0){
|
||||
*max_payload_size = avctp_get_max_payload_size(connection->l2cap_signaling_cid, connection->command_opcode, AVCTP_SINGLE_PACKET);
|
||||
*max_payload_size = avrcp_get_num_free_bytes_for_payload(connection->l2cap_signaling_cid,
|
||||
connection->command_opcode,
|
||||
AVCTP_SINGLE_PACKET);
|
||||
if (*max_payload_size >= connection->data_len){
|
||||
return AVCTP_SINGLE_PACKET;
|
||||
} else {
|
||||
return AVCTP_START_PACKET;
|
||||
}
|
||||
} else {
|
||||
*max_payload_size = avctp_get_max_payload_size(connection->l2cap_signaling_cid, connection->command_opcode, AVCTP_CONTINUE_PACKET);
|
||||
*max_payload_size = avrcp_get_num_free_bytes_for_payload(connection->l2cap_signaling_cid,
|
||||
connection->command_opcode,
|
||||
AVCTP_CONTINUE_PACKET);
|
||||
if ((connection->data_len - connection->data_offset) > *max_payload_size){
|
||||
return AVCTP_CONTINUE_PACKET;
|
||||
return AVCTP_CONTINUE_PACKET;
|
||||
} else {
|
||||
return AVCTP_END_PACKET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
avrcp_packet_type_t avrcp_get_packet_type(avrcp_connection_t * connection){
|
||||
switch (connection->avctp_packet_type) {
|
||||
case AVCTP_SINGLE_PACKET:
|
||||
case AVCTP_START_PACKET:
|
||||
break;
|
||||
default:
|
||||
return connection->packet_type;
|
||||
}
|
||||
|
||||
if (connection->data_offset == 0){
|
||||
if (AVRCP_MAX_AV_C_MESSAGE_FRAME_SIZE >= connection->data_len){
|
||||
return AVRCP_SINGLE_PACKET;
|
||||
} else {
|
||||
return AVRCP_START_PACKET;
|
||||
}
|
||||
} else {
|
||||
if ((connection->data_len - connection->data_offset) > AVRCP_MAX_AV_C_MESSAGE_FRAME_SIZE){
|
||||
return AVRCP_CONTINUE_PACKET;
|
||||
} else {
|
||||
return AVRCP_END_PACKET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
avrcp_connection_t * avrcp_get_connection_for_bd_addr_for_role(avrcp_role_t role, bd_addr_t addr){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avrcp_connections);
|
||||
|
@ -63,7 +63,7 @@ extern "C" {
|
||||
#define AVRCP_MAX_COMMAND_PARAMETER_LENGTH 11
|
||||
#define BT_SIG_COMPANY_ID 0x001958
|
||||
#define AVRCP_MEDIA_ATTR_COUNT 7
|
||||
#define AVRCP_MAX_ATTRIBUTTE_SIZE 130
|
||||
#define AVRCP_MAX_ATTRIBUTE_SIZE 130
|
||||
#define AVRCP_ATTRIBUTE_HEADER_LEN 8
|
||||
#define AVRCP_MAX_FOLDER_NAME_SIZE 20
|
||||
|
||||
@ -481,7 +481,7 @@ typedef struct {
|
||||
avrcp_parser_state_t parser_state;
|
||||
uint8_t parser_attribute_header[AVRCP_BROWSING_ITEM_HEADER_LEN];
|
||||
uint8_t parser_attribute_header_pos;
|
||||
uint8_t parsed_attribute_value[AVRCP_MAX_ATTRIBUTTE_SIZE];
|
||||
uint8_t parsed_attribute_value[AVRCP_MAX_ATTRIBUTE_SIZE];
|
||||
uint16_t parsed_attribute_value_len;
|
||||
uint16_t parsed_attribute_value_offset;
|
||||
uint8_t parsed_num_attributes;
|
||||
@ -552,9 +552,13 @@ typedef struct {
|
||||
|
||||
uint8_t * data;
|
||||
uint16_t data_len;
|
||||
|
||||
|
||||
// long/fragmented commands
|
||||
uint16_t data_offset;
|
||||
|
||||
uint16_t avrcp_frame_bytes_sent;
|
||||
avctp_packet_type_t avctp_packet_type;
|
||||
|
||||
btstack_timer_source_t retry_timer;
|
||||
btstack_timer_source_t press_and_hold_cmd_timer;
|
||||
bool press_and_hold_cmd_active;
|
||||
@ -611,7 +615,7 @@ typedef struct {
|
||||
|
||||
uint16_t list_size;
|
||||
uint16_t list_offset;
|
||||
uint8_t attribute_value[AVRCP_MAX_ATTRIBUTTE_SIZE];
|
||||
uint8_t attribute_value[AVRCP_MAX_ATTRIBUTE_SIZE];
|
||||
uint16_t attribute_value_len;
|
||||
uint16_t attribute_value_offset;
|
||||
|
||||
@ -659,6 +663,9 @@ const char * avrcp_shuffle2str(uint8_t index);
|
||||
|
||||
|
||||
avctp_packet_type_t avctp_get_packet_type(avrcp_connection_t * connection, uint16_t * max_payload_size);
|
||||
avrcp_packet_type_t avrcp_get_packet_type(avrcp_connection_t * connection);
|
||||
uint16_t avctp_get_num_bytes_for_header(avctp_packet_type_t avctp_packet_type);
|
||||
uint16_t avrcp_get_num_bytes_for_header(avrcp_command_opcode_t command_opcode, avctp_packet_type_t avctp_packet_type);
|
||||
|
||||
void avrcp_register_controller_packet_handler(btstack_packet_handler_t avrcp_controller_packet_handler);
|
||||
void avrcp_register_target_packet_handler(btstack_packet_handler_t avrcp_target_packet_handler);
|
||||
|
@ -316,7 +316,7 @@ static void avrcp_browsing_parser_process_byte(uint8_t byte, avrcp_browsing_conn
|
||||
|
||||
attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 1);
|
||||
connection->parsed_attribute_value[connection->parsed_attribute_value_offset++] = connection->parser_attribute_header[0]; // prepend with item type
|
||||
connection->parsed_attribute_value_len = btstack_min(attribute_total_value_len, AVRCP_MAX_ATTRIBUTTE_SIZE - prepended_header_size); // reduce AVRCP_MAX_ATTRIBUTTE_SIZE for the size ot item type
|
||||
connection->parsed_attribute_value_len = btstack_min(attribute_total_value_len, AVRCP_MAX_ATTRIBUTE_SIZE - prepended_header_size); // reduce AVRCP_MAX_ATTRIBUTE_SIZE for the size ot item type
|
||||
connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_VALUE;
|
||||
break;
|
||||
|
||||
|
@ -463,7 +463,7 @@ static void avrcp_parser_process_byte(uint8_t byte, avrcp_connection_t * connect
|
||||
if (connection->parser_attribute_header_pos < AVRCP_ATTRIBUTE_HEADER_LEN) return;
|
||||
|
||||
attribute_total_value_len = big_endian_read_16(connection->parser_attribute_header, 6);
|
||||
connection->attribute_value_len = btstack_min(attribute_total_value_len, AVRCP_MAX_ATTRIBUTTE_SIZE);
|
||||
connection->attribute_value_len = btstack_min(attribute_total_value_len, AVRCP_MAX_ATTRIBUTE_SIZE);
|
||||
if (connection->attribute_value_len > 0){
|
||||
// get ready for attribute value
|
||||
connection->parser_state = AVRCP_PARSER_GET_ATTRIBUTE_VALUE;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -322,10 +322,10 @@ typedef struct {
|
||||
} avrcp_play_status_info_t;
|
||||
|
||||
// python -c "print('a'*512)"
|
||||
static const char title[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
static const char title[] = "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
|
||||
|
||||
avrcp_track_t tracks[] = {
|
||||
{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 1, "Sine", "Generated", "AVRCP Demo", "monotone", 12345},
|
||||
{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 1, "Sine0Sine1", "Generated01 Generated02 Generated3 Generated4 Generated5 Generated6 Generated7 Generated8 Generated9", "AVRCP Demo", "monotone01", 1234567890},
|
||||
{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, 2, "Nao-deceased", "Decease", "AVRCP Demo", "vivid", 12345},
|
||||
{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}, 3, (char *)title, "Decease", "AVRCP Demo", "vivid", 12345},
|
||||
};
|
||||
|
@ -35,6 +35,7 @@
|
||||
#define ENABLE_SCO_OVER_HCI
|
||||
#define ENABLE_SDP_DES_DUMP
|
||||
#define ENABLE_SOFTWARE_AES128
|
||||
#define ENABLE_AVCTP_FRAGMENTATION
|
||||
|
||||
// BTstack configuration. buffers, sizes, ...
|
||||
#define HCI_ACL_PAYLOAD_SIZE (1691 + 4)
|
||||
|
Loading…
x
Reference in New Issue
Block a user