mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-17 02:42:33 +00:00
avrcp browsing target: send get folder items
This commit is contained in:
parent
8a51819492
commit
baf4362140
@ -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
|
||||
|
@ -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;
|
||||
*/
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user