mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-19 16:21:06 +00:00
avrcp: set addressed player, get total num items
This commit is contained in:
parent
73fba53895
commit
864d08b05a
@ -110,7 +110,7 @@ typedef enum {
|
|||||||
AVRCP_MEDIA_ATTR_ARTIST,
|
AVRCP_MEDIA_ATTR_ARTIST,
|
||||||
AVRCP_MEDIA_ATTR_ALBUM,
|
AVRCP_MEDIA_ATTR_ALBUM,
|
||||||
AVRCP_MEDIA_ATTR_TRACK,
|
AVRCP_MEDIA_ATTR_TRACK,
|
||||||
AVRCP_MEDIA_ATTR_TOTAL_TRACKS,
|
AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS,
|
||||||
AVRCP_MEDIA_ATTR_GENRE,
|
AVRCP_MEDIA_ATTR_GENRE,
|
||||||
AVRCP_MEDIA_ATTR_SONG_LENGTH_MS,
|
AVRCP_MEDIA_ATTR_SONG_LENGTH_MS,
|
||||||
AVRCP_MEDIA_ATTR_NONE = 0xFFFFFFFF
|
AVRCP_MEDIA_ATTR_NONE = 0xFFFFFFFF
|
||||||
@ -130,7 +130,9 @@ typedef enum {
|
|||||||
AVRCP_PDU_ID_SET_BROWSED_PLAYER = 0x70,
|
AVRCP_PDU_ID_SET_BROWSED_PLAYER = 0x70,
|
||||||
AVRCP_PDU_ID_GET_FOLDER_ITEMS = 0x71,
|
AVRCP_PDU_ID_GET_FOLDER_ITEMS = 0x71,
|
||||||
AVRCP_PDU_ID_CHANGE_PATH = 0x72,
|
AVRCP_PDU_ID_CHANGE_PATH = 0x72,
|
||||||
|
AVRCP_PDU_ID_GET_ITEM_ATTRIBUTES = 0x73,
|
||||||
AVRCP_PDU_ID_PLAY_ITEM = 0x74,
|
AVRCP_PDU_ID_PLAY_ITEM = 0x74,
|
||||||
|
AVRCP_PDU_ID_GET_TOTAL_NUMBER_OF_ITEMS = 0x75,
|
||||||
AVRCP_PDU_ID_SEARCH = 0x80,
|
AVRCP_PDU_ID_SEARCH = 0x80,
|
||||||
AVRCP_PDU_ID_UNDEFINED = 0xFF
|
AVRCP_PDU_ID_UNDEFINED = 0xFF
|
||||||
} avrcp_pdu_id_t;
|
} avrcp_pdu_id_t;
|
||||||
@ -305,10 +307,7 @@ typedef struct {
|
|||||||
l2cap_ertm_config_t ertm_config;
|
l2cap_ertm_config_t ertm_config;
|
||||||
|
|
||||||
// players
|
// players
|
||||||
uint8_t set_addressed_player_id;
|
|
||||||
uint8_t set_browsed_player_id;
|
uint8_t set_browsed_player_id;
|
||||||
|
|
||||||
uint16_t addressed_player_id;
|
|
||||||
uint16_t browsed_player_id;
|
uint16_t browsed_player_id;
|
||||||
uint16_t browsed_player_uid_counter;
|
uint16_t browsed_player_uid_counter;
|
||||||
|
|
||||||
@ -330,6 +329,10 @@ typedef struct {
|
|||||||
uint8_t search_str[20];
|
uint8_t search_str[20];
|
||||||
uint8_t search;
|
uint8_t search;
|
||||||
|
|
||||||
|
// get_item_attributes
|
||||||
|
uint8_t get_total_nr_items;
|
||||||
|
avrcp_browsing_scope_t get_total_nr_items_scope;
|
||||||
|
|
||||||
// fragmentation
|
// fragmentation
|
||||||
uint8_t fragmented;
|
uint8_t fragmented;
|
||||||
avrcp_pdu_id_t fragmented_pdu_id;
|
avrcp_pdu_id_t fragmented_pdu_id;
|
||||||
|
@ -360,8 +360,8 @@ static int avrcp_browsing_controller_send_set_browsed_player_cmd(uint16_t cid, a
|
|||||||
return l2cap_send(cid, command, pos);
|
return l2cap_send(cid, command, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int avrcp_browsing_controller_send_set_addressed_player_cmd(uint16_t cid, avrcp_browsing_connection_t * connection){
|
static int avrcp_browsing_controller_send_get_total_nr_items_cmd(uint16_t cid, avrcp_browsing_connection_t * connection){
|
||||||
uint8_t command[100];
|
uint8_t command[7];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
// transport header
|
// transport header
|
||||||
// Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
|
// Transaction label | Packet_type | C/R | IPID (1 == invalid profile identifier)
|
||||||
@ -369,12 +369,11 @@ static int avrcp_browsing_controller_send_set_addressed_player_cmd(uint16_t cid,
|
|||||||
// Profile IDentifier (PID)
|
// Profile IDentifier (PID)
|
||||||
command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
|
command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL >> 8;
|
||||||
command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
|
command[pos++] = BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL & 0x00FF;
|
||||||
command[pos++] = AVRCP_PDU_ID_SET_ADDRESSED_PLAYER;
|
command[pos++] = AVRCP_PDU_ID_GET_TOTAL_NUMBER_OF_ITEMS;
|
||||||
|
|
||||||
big_endian_store_16(command, pos, 2);
|
big_endian_store_16(command, pos, 1);
|
||||||
pos += 2;
|
|
||||||
big_endian_store_16(command, pos, connection->addressed_player_id);
|
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
command[pos++] = connection->get_total_nr_items_scope;
|
||||||
return l2cap_send(cid, command, pos);
|
return l2cap_send(cid, command, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,10 +387,10 @@ static void avrcp_browsing_controller_handle_can_send_now(avrcp_browsing_connect
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection->set_addressed_player_id){
|
if (connection->get_total_nr_items){
|
||||||
connection->state = AVCTP_W2_RECEIVE_RESPONSE;
|
connection->state = AVCTP_W2_RECEIVE_RESPONSE;
|
||||||
connection->set_addressed_player_id = 0;
|
connection->get_total_nr_items = 0;
|
||||||
avrcp_browsing_controller_send_set_addressed_player_cmd(connection->l2cap_browsing_cid, connection);
|
avrcp_browsing_controller_send_get_total_nr_items_cmd(connection->l2cap_browsing_cid, connection);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,6 +494,12 @@ static void avrcp_browsing_controller_packet_handler(uint8_t packet_type, uint16
|
|||||||
case AVRCP_PDU_ID_SET_ADDRESSED_PLAYER:
|
case AVRCP_PDU_ID_SET_ADDRESSED_PLAYER:
|
||||||
printf("AVRCP_PDU_ID_SET_ADDRESSED_PLAYER \n");
|
printf("AVRCP_PDU_ID_SET_ADDRESSED_PLAYER \n");
|
||||||
break;
|
break;
|
||||||
|
case AVRCP_PDU_ID_GET_TOTAL_NUMBER_OF_ITEMS:{
|
||||||
|
uint32_t num_items = big_endian_read_32(packet, pos);
|
||||||
|
pos += 4;
|
||||||
|
printf("TDO: send event, uid_counter %d, num_items %d\n", uid_counter, num_items);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case AVRCP_PDU_ID_SET_BROWSED_PLAYER:{
|
case AVRCP_PDU_ID_SET_BROWSED_PLAYER:{
|
||||||
browsing_connection->browsed_player_uid_counter = uid_counter;
|
browsing_connection->browsed_player_uid_counter = uid_counter;
|
||||||
// uint32_t num_items = big_endian_read_32(packet, pos);
|
// uint32_t num_items = big_endian_read_32(packet, pos);
|
||||||
@ -736,25 +741,6 @@ uint8_t avrcp_browsing_controller_set_browsed_player(uint16_t avrcp_browsing_cid
|
|||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t avrcp_browsing_controller_set_addressed_player(uint16_t avrcp_browsing_cid, uint16_t addressed_player_id){
|
|
||||||
avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid(avrcp_browsing_cid, &avrcp_controller_context);
|
|
||||||
if (!avrcp_connection){
|
|
||||||
log_error("avrcp_browsing_controller_change_path: could not find a connection.");
|
|
||||||
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
|
||||||
}
|
|
||||||
|
|
||||||
avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection;
|
|
||||||
if (!connection || connection->state != AVCTP_CONNECTION_OPENED){
|
|
||||||
log_error("avrcp_browsing_controller_change_path: connection in wrong state.");
|
|
||||||
return ERROR_CODE_COMMAND_DISALLOWED;
|
|
||||||
}
|
|
||||||
|
|
||||||
connection->set_addressed_player_id = 1;
|
|
||||||
connection->addressed_player_id = addressed_player_id;
|
|
||||||
avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
|
|
||||||
return ERROR_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieve a listing of the contents of a folder.
|
* @brief Retrieve a listing of the contents of a folder.
|
||||||
* @param direction 0-folder up, 1-folder down
|
* @param direction 0-folder up, 1-folder down
|
||||||
@ -827,4 +813,28 @@ uint8_t avrcp_browsing_controller_search(uint16_t avrcp_browsing_cid, uint16_t s
|
|||||||
memcpy(connection->search_str, search_str, connection->search_str_len);
|
memcpy(connection->search_str, search_str, connection->search_str_len);
|
||||||
avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
|
avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t avrcp_browsing_controller_get_total_nr_items(uint16_t avrcp_browsing_cid, avrcp_browsing_scope_t scope){
|
||||||
|
avrcp_connection_t * avrcp_connection = get_avrcp_connection_for_browsing_cid(avrcp_browsing_cid, &avrcp_controller_context);
|
||||||
|
if (!avrcp_connection){
|
||||||
|
log_error("avrcp_browsing_controller_change_path: could not find a connection.");
|
||||||
|
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||||
|
}
|
||||||
|
|
||||||
|
avrcp_browsing_connection_t * connection = avrcp_connection->browsing_connection;
|
||||||
|
|
||||||
|
if (!connection || connection->state != AVCTP_CONNECTION_OPENED){
|
||||||
|
log_error("avrcp_browsing_controller_change_path: connection in wrong state.");
|
||||||
|
return ERROR_CODE_COMMAND_DISALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!connection->browsed_player_id){
|
||||||
|
log_error("avrcp_browsing_controller_change_path: no browsed player set.");
|
||||||
|
return ERROR_CODE_COMMAND_DISALLOWED;
|
||||||
|
}
|
||||||
|
connection->get_total_nr_items = 1;
|
||||||
|
connection->get_total_nr_items_scope = scope;
|
||||||
|
avrcp_request_can_send_now(avrcp_connection, connection->l2cap_browsing_cid);
|
||||||
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
@ -188,11 +188,10 @@ uint8_t avrcp_browsing_controller_browse_now_playing_list(uint16_t avrcp_browsin
|
|||||||
uint8_t avrcp_browsing_controller_set_browsed_player(uint16_t avrcp_browsing_cid, uint16_t browsed_player_id);
|
uint8_t avrcp_browsing_controller_set_browsed_player(uint16_t avrcp_browsing_cid, uint16_t browsed_player_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set addressed player.
|
* @brief Get total num attributes
|
||||||
* @param avrcp_browsing_cid
|
* @param scope
|
||||||
* @param addressed_player_id
|
|
||||||
*/
|
*/
|
||||||
uint8_t avrcp_browsing_controller_set_addressed_player(uint16_t avrcp_browsing_cid, uint16_t addressed_player_id);
|
uint8_t avrcp_browsing_controller_get_total_nr_items(uint16_t avrcp_browsing_cid, avrcp_browsing_scope_t scope);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Navigate one level up or down in thhe virtual filesystem. Requires that s browsed player is set.
|
* @brief Navigate one level up or down in thhe virtual filesystem. Requires that s browsed player is set.
|
||||||
|
@ -283,7 +283,7 @@ static void avrcp_controller_emit_now_playing_info_event(btstack_packet_handler_
|
|||||||
event[pos++] = 0;
|
event[pos++] = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AVRCP_MEDIA_ATTR_TOTAL_TRACKS:
|
case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS:
|
||||||
event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TOTAL_TRACKS_INFO;
|
event[subevent_type_pos] = AVRCP_SUBEVENT_NOW_PLAYING_TOTAL_TRACKS_INFO;
|
||||||
if (value){
|
if (value){
|
||||||
event[pos++] = btstack_atoi((char *)value);
|
event[pos++] = btstack_atoi((char *)value);
|
||||||
@ -1034,6 +1034,37 @@ uint8_t avrcp_controller_disable_notification(uint16_t avrcp_cid, avrcp_notifica
|
|||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t avrcp_controller_set_addressed_player(uint16_t avrcp_cid, uint16_t addressed_player_id){
|
||||||
|
avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
|
||||||
|
if (!connection){
|
||||||
|
log_error("avrcp_get_capabilities: could not find a connection.");
|
||||||
|
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||||
|
}
|
||||||
|
if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
|
||||||
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
|
|
||||||
|
connection->transaction_label++;
|
||||||
|
connection->command_opcode = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
|
||||||
|
connection->command_type = AVRCP_CTYPE_CONTROL;
|
||||||
|
connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
|
||||||
|
connection->subunit_id = AVRCP_SUBUNIT_ID;
|
||||||
|
int pos = 0;
|
||||||
|
big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
|
||||||
|
pos += 3;
|
||||||
|
connection->cmd_operands[pos++] = AVRCP_PDU_ID_SET_ADDRESSED_PLAYER; // PDU ID
|
||||||
|
connection->cmd_operands[pos++] = 0;
|
||||||
|
|
||||||
|
// Parameter Length
|
||||||
|
big_endian_store_16(connection->cmd_operands, pos, 2);
|
||||||
|
pos += 2;
|
||||||
|
|
||||||
|
big_endian_store_16(connection->cmd_operands, pos, addressed_player_id);
|
||||||
|
pos += 2;
|
||||||
|
|
||||||
|
connection->cmd_operands_length = pos;
|
||||||
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
|
return ERROR_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t avrcp_controller_get_now_playing_info(uint16_t avrcp_cid){
|
uint8_t avrcp_controller_get_now_playing_info(uint16_t avrcp_cid){
|
||||||
avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
|
avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(avrcp_cid, &avrcp_controller_context);
|
||||||
|
@ -294,6 +294,15 @@ uint8_t avrcp_controller_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t
|
|||||||
* @return status
|
* @return status
|
||||||
**/
|
**/
|
||||||
uint8_t avrcp_controller_play_item(uint16_t avrcp_cid, avrcp_browsing_scope_t scope, uint8_t * uid, uint16_t uid_counter);
|
uint8_t avrcp_controller_play_item(uint16_t avrcp_cid, avrcp_browsing_scope_t scope, uint8_t * uid, uint16_t uid_counter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set addressed player.
|
||||||
|
* @param avrcp_cid
|
||||||
|
* @param addressed_player_id
|
||||||
|
*/
|
||||||
|
uint8_t avrcp_controller_set_addressed_player(uint16_t avrcp_cid, uint16_t addressed_player_id);
|
||||||
|
|
||||||
|
|
||||||
/* API_END */
|
/* API_END */
|
||||||
|
|
||||||
// Used by AVRCP controller and AVRCP browsing controller
|
// Used by AVRCP controller and AVRCP browsing controller
|
||||||
|
@ -209,7 +209,7 @@ static int avrcp_target_send_now_playing_info(uint16_t cid, avrcp_connection_t *
|
|||||||
fragmented = 1;
|
fragmented = 1;
|
||||||
connection->attribute_value_offset = 0;
|
connection->attribute_value_offset = 0;
|
||||||
break;
|
break;
|
||||||
case AVRCP_MEDIA_ATTR_TOTAL_TRACKS:
|
case AVRCP_MEDIA_ATTR_TOTAL_NUM_ITEMS:
|
||||||
num_bytes_to_write = AVRCP_ATTR_HEADER_LEN + MAX_NUMBER_ATTR_LEN;
|
num_bytes_to_write = AVRCP_ATTR_HEADER_LEN + MAX_NUMBER_ATTR_LEN;
|
||||||
if (num_free_bytes >= num_bytes_to_write){
|
if (num_free_bytes >= num_bytes_to_write){
|
||||||
num_written_bytes = avrcp_target_pack_single_element_attribute_number(packet, pos, attr_id, connection->total_tracks);
|
num_written_bytes = avrcp_target_pack_single_element_attribute_number(packet, pos, attr_id, connection->total_tracks);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user