avrcp browsing target: send get folder items

This commit is contained in:
Milanka Ringwald 2018-04-26 11:03:56 +02:00
parent 8a51819492
commit baf4362140
4 changed files with 97 additions and 43 deletions

View File

@ -364,7 +364,9 @@ typedef struct {
uint16_t parsed_attribute_value_offset;
uint8_t parsed_num_attributes;
// get folder items data
uint8_t * attr_list;
uint16_t attr_list_size;
// command
// uint8_t transaction_label;
avrcp_command_opcode_t command_opcode;
@ -372,7 +374,7 @@ typedef struct {
avrcp_subunit_type_t subunit_type;
avrcp_subunit_id_t subunit_id;
avrcp_packet_type_t packet_type;
uint8_t cmd_operands[20];
uint8_t cmd_operands[200];
uint8_t cmd_operands_length;
} avrcp_browsing_connection_t;
// BROWSING END

View File

@ -58,9 +58,12 @@ static void avrcp_browsing_target_request_can_send_now(avrcp_browsing_connection
static int avrcp_browsing_target_handle_can_send_now(avrcp_browsing_connection_t * connection){
int pos = 0;
// printf("avrcp_browsing_target_handle_can_send_now, cmd_operands_length %d\n", connection->cmd_operands_length);
// printf_hexdump(connection->cmd_operands, connection->cmd_operands_length);
// l2cap_reserve_packet_buffer();
// uint8_t * packet = l2cap_get_outgoing_buffer();
uint8_t packet[100];
uint8_t packet[300];
connection->packet_type = AVRCP_SINGLE_PACKET;
packet[pos++] = (connection->transaction_label << 4) | (connection->packet_type << 2) | (AVRCP_RESPONSE_FRAME << 1) | 0;
@ -68,8 +71,7 @@ static int avrcp_browsing_target_handle_can_send_now(avrcp_browsing_connection_t
packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
packet[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
memcpy(packet+pos, connection->cmd_operands, connection->cmd_operands_length);
// printf_hexdump(packet+pos, connection->cmd_operands_length);
pos += connection->cmd_operands_length;
connection->wait_to_send = 0;
// return l2cap_send_prepared(connection->l2cap_browsing_cid, pos);
@ -343,36 +345,35 @@ static void avrcp_browsing_target_packet_handler(uint8_t packet_type, uint16_t c
}
printf("pdu id 0x%2x\n", browsing_connection->pdu_id);
// uint32_t i;
switch(browsing_connection->pdu_id){
case AVRCP_PDU_ID_GET_FOLDER_ITEMS:
printf("\n");
browsing_connection->scope = packet[pos++];
browsing_connection->start_item = big_endian_read_32(packet, pos);
pos += 4;
browsing_connection->end_item = big_endian_read_32(packet, pos);
pos += 4;
uint8_t attr_count = packet[pos++];
while (attr_count){
uint32_t attr_id = big_endian_read_32(packet, pos);
pos += 4;
browsing_connection->attr_bitmap |= (1 << attr_id);
attr_count--;
}
avrcp_browsing_target_emit_get_folder_items(avrcp_target_context.browsing_avrcp_callback, channel, browsing_connection);
break;
default:
printf(" not parsed pdu ID 0x%02x\n", browsing_connection->pdu_id);
break;
}
switch (avctp_packet_type){
case AVRCP_SINGLE_PACKET:
case AVRCP_END_PACKET:
printf("send avrcp_browsing_target_response_general_reject\n");
switch(browsing_connection->pdu_id){
case AVRCP_PDU_ID_GET_FOLDER_ITEMS:
printf("\n");
browsing_connection->scope = packet[pos++];
browsing_connection->start_item = big_endian_read_32(packet, pos);
pos += 4;
browsing_connection->end_item = big_endian_read_32(packet, pos);
pos += 4;
uint8_t attr_count = packet[pos++];
while (attr_count){
uint32_t attr_id = big_endian_read_32(packet, pos);
pos += 4;
browsing_connection->attr_bitmap |= (1 << attr_id);
attr_count--;
}
avrcp_browsing_target_emit_get_folder_items(avrcp_target_context.browsing_avrcp_callback, channel, browsing_connection);
break;
default:
printf("send avrcp_browsing_target_response_general_reject\n");
avrcp_browsing_target_response_general_reject(browsing_connection, AVRCP_STATUS_INVALID_COMMAND);
printf(" not parsed pdu ID 0x%02x\n", browsing_connection->pdu_id);
break;
}
browsing_connection->state = AVCTP_CONNECTION_OPENED;
avrcp_browsing_target_response_general_reject(browsing_connection, AVRCP_STATUS_INVALID_COMMAND);
// avrcp_browsing_target_emit_done_with_uid_counter(avrcp_target_context.browsing_avrcp_callback, channel, browsing_connection->uid_counter, browsing_connection->browsing_status, ERROR_CODE_SUCCESS);
break;
default:
@ -471,11 +472,61 @@ uint8_t avrcp_browsing_target_decline_incoming_connection(uint16_t avrcp_browsin
return ERROR_CODE_SUCCESS;
}
uint8_t avrcp_subevent_browsing_get_folder_items_response(uint16_t browsing_cid, uint8_t * attr_list, uint16_t attr_list_size){
UNUSED(browsing_cid);
UNUSED(attr_list);
UNUSED(attr_list_size);
uint8_t avrcp_subevent_browsing_get_folder_items_response(uint16_t avrcp_browsing_cid, uint16_t uid_counter, uint8_t * attr_list, uint16_t attr_list_size){
avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid(avrcp_browsing_cid, &avrcp_target_context);
if (!avrcp_connection){
log_error("avrcp_browsing_controller_disconnect: could not find a connection.");
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
}
avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection;
if (!connection){
printf("avrcp_subevent_browsing_get_folder_items_response: could not find a connection.\n");
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
}
if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
if (connection->state != AVCTP_CONNECTION_OPENED) {
printf("avrcp_subevent_browsing_get_folder_items_response: wrong state.\n");
return ERROR_CODE_COMMAND_DISALLOWED;
}
int pos = 0;
connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_FOLDER_ITEMS;
big_endian_store_16(connection->cmd_operands, pos, attr_list_size);
pos += 2;
connection->cmd_operands[pos++] = AVRCP_STATUS_SUCCESS;
big_endian_store_16(connection->cmd_operands, pos, uid_counter);
pos += 2;
// TODO: fragmentation
if (attr_list_size > sizeof(connection->cmd_operands)){
connection->attr_list = attr_list;
connection->attr_list_size = attr_list_size;
printf(" todo: list too big, invoke fragmentation\n");
return 1;
}
memcpy(&connection->cmd_operands[pos], attr_list, attr_list_size);
pos += attr_list_size;
connection->cmd_operands_length = pos;
// printf_hexdump(connection->cmd_operands, connection->cmd_operands_length);
connection->state = AVCTP_W2_SEND_RESPONSE;
avrcp_browsing_target_request_can_send_now(connection, connection->l2cap_browsing_cid);
return ERROR_CODE_SUCCESS;
}
/*
int pos = 0;
connection->cmd_operands[pos++] = AVRCP_PDU_ID_GENERAL_REJECT;
// connection->cmd_operands[pos++] = 0;
// param length
big_endian_store_16(connection->cmd_operands, pos, 1);
pos += 2;
connection->cmd_operands[pos++] = status;
connection->cmd_operands_length = 4;
connection->state = AVCTP_W2_SEND_RESPONSE;
*/

View File

@ -102,7 +102,7 @@ uint8_t avrcp_browsing_target_decline_incoming_connection(uint16_t avrcp_browsin
*/
uint8_t avrcp_browsing_target_disconnect(uint16_t avrcp_browsing_cid);
uint8_t avrcp_subevent_browsing_get_folder_items_response(uint16_t browsing_cid, uint8_t * attr_list, uint16_t attr_list_size);
uint8_t avrcp_subevent_browsing_get_folder_items_response(uint16_t browsing_cid, uint16_t uid_counter, uint8_t * attr_list, uint16_t attr_list_size);
/* API_END */

View File

@ -176,7 +176,7 @@ static a2dp_media_sending_context_t media_tracker;
static uint16_t avrcp_cid;
static uint8_t avrcp_connected;
static uint16_t uid_counter = 0x5A73;
static stream_data_source_t data_source;
// static int sine_phase;
@ -198,8 +198,8 @@ static const uint8_t subunit_info[] = {
7,7,7,7
};
static uint8_t media_player_list[] = {};
static uint8_t virtual_filesystem_list[] = {};
static uint8_t media_player_list[] = { 0x00, 0x02, 0x01, 0x00, 0x2A, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x0E, 0x42, 0x72, 0x6F, 0x77, 0x73, 0x65, 0x64, 0x20, 0x50, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x01, 0x00, 0x2C, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x10, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x50, 0x6C, 0x61, 0x79, 0x65, 0x72}; // 0x71, 0x00, 0x61,0x04, 0x5A, 0x73,
static uint8_t virtual_filesystem_list[] ={ 0x00, 0x07, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x6A, 0x00, 0x06, 0x41, 0x6C, 0x62, 0x75, 0x6D, 0x73, 0x02, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x6A, 0x00, 0x07, 0x41, 0x72, 0x74, 0x69, 0x73, 0x74, 0x73, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x6A, 0x00, 0x06, 0x47, 0x65, 0x6E, 0x72, 0x65, 0x73, 0x02, 0x00, 0x17, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x6A, 0x00, 0x09, 0x50, 0x6C, 0x61, 0x79, 0x6C, 0x69, 0x73, 0x74, 0x73, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x01, 0x01, 0x00, 0x6A, 0x00, 0x05, 0x53, 0x6F, 0x6E, 0x67, 0x73, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00}; // 0x71, 0x00, 0xA7, 0x04, 0x5A, 0x73,
static uint8_t search_list[] = {};
static uint8_t now_playing_list[] = {};
@ -556,16 +556,17 @@ static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, u
avrcp_browsing_scope_t scope = avrcp_subevent_browsing_get_folder_items_get_scope(packet);
switch (scope){
case AVRCP_BROWSING_MEDIA_PLAYER_LIST:
avrcp_subevent_browsing_get_folder_items_response(browsing_cid, media_player_list, sizeof(media_player_list));
printf("send media_player_list, size %lu\n", sizeof(media_player_list));
avrcp_subevent_browsing_get_folder_items_response(browsing_cid, uid_counter, media_player_list, sizeof(media_player_list));
break;
case AVRCP_BROWSING_MEDIA_PLAYER_VIRTUAL_FILESYSTEM:
avrcp_subevent_browsing_get_folder_items_response(browsing_cid, virtual_filesystem_list, sizeof(virtual_filesystem_list));
avrcp_subevent_browsing_get_folder_items_response(browsing_cid, uid_counter, virtual_filesystem_list, sizeof(virtual_filesystem_list));
break;
case AVRCP_BROWSING_SEARCH:
avrcp_subevent_browsing_get_folder_items_response(browsing_cid, search_list, sizeof(search_list));
avrcp_subevent_browsing_get_folder_items_response(browsing_cid, uid_counter, search_list, sizeof(search_list));
break;
case AVRCP_BROWSING_NOW_PLAYING:
avrcp_subevent_browsing_get_folder_items_response(browsing_cid, now_playing_list, sizeof(now_playing_list));
avrcp_subevent_browsing_get_folder_items_response(browsing_cid, uid_counter, now_playing_list, sizeof(now_playing_list));
break;
}
printf(" AVRCP_SUBEVENT_BROWSING_GET_FOLDER_ITEMS \n");