mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-10 06:40:23 +00:00
avrcp: get play status
This commit is contained in:
parent
a85ed257c2
commit
1270af140e
@ -412,7 +412,7 @@ static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connec
|
||||
avrcp_subunit_type_t subunit_type;
|
||||
avrcp_subunit_type_t subunit_id;
|
||||
|
||||
uint8_t operands[5];
|
||||
uint8_t operands[20];
|
||||
uint8_t opcode;
|
||||
uint8_t value;
|
||||
int pos = 0;
|
||||
@ -448,10 +448,48 @@ static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connec
|
||||
break;
|
||||
}
|
||||
case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT:
|
||||
ctype = packet[pos++];
|
||||
value = packet[pos++];
|
||||
subunit_type = value >> 3;
|
||||
subunit_id = value & 0x07;
|
||||
opcode = packet[pos++];
|
||||
|
||||
if (size - pos < 7) {
|
||||
log_error("avrcp: wrong packet size");
|
||||
return;
|
||||
};
|
||||
// operands:
|
||||
memcpy(operands, packet+pos, 7);
|
||||
pos += 7;
|
||||
// uint32_t company_id = operands[0] << 16 | operands[1] << 8 | operands[2];
|
||||
uint8_t pdu_id = operands[3];
|
||||
// uint8_t unit_type = operands[4] >> 3;
|
||||
// uint8_t unit = operands[4] & 0x07;
|
||||
uint16_t param_length = big_endian_read_16(operands, 5);
|
||||
|
||||
// printf(" VENDOR DEPENDENT response: ctype 0x%02x (0C), subunit_type 0x%02x (1F), subunit_id 0x%02x (07), opcode 0x%02x (30), unit_type 0x%02x, unit %d, company_id 0x%06x\n",
|
||||
// ctype, subunit_type, subunit_id, opcode, unit_type, unit, company_id );
|
||||
|
||||
printf(" VENDOR DEPENDENT response: pdu id 0x%02x, param_length %d\n", pdu_id, param_length);
|
||||
switch (pdu_id){
|
||||
case AVRCP_PDU_ID_GET_PLAY_STATUS:{
|
||||
uint32_t song_length = big_endian_read_32(packet, pos);
|
||||
pos += 32;
|
||||
uint32_t song_position = big_endian_read_32(packet, pos);
|
||||
pos += 32;
|
||||
uint8_t status = packet[pos];
|
||||
printf_hexdump(packet+pos, size - pos);
|
||||
printf(" GET_PLAY_STATUS length 0x%04X, position 0x%04X, status %d\n", song_length, song_position, status);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AVRCP_CMD_OPCODE_PASS_THROUGH:
|
||||
if (connection->state == AVCTP_W2_SEND_RELEASE_COMMAND){
|
||||
request_pass_through_release_control_cmd(connection);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -613,7 +651,7 @@ void avrcp_unit_info(uint16_t con_handle){
|
||||
void avrcp_get_capabilities(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
if (!connection){
|
||||
log_error("avrcp_unit_info: coud not find a connection.");
|
||||
log_error("avrcp_get_capabilities: coud not find a connection.");
|
||||
return;
|
||||
}
|
||||
if (connection->state != AVCTP_CONNECTION_OPENED) return;
|
||||
@ -625,7 +663,7 @@ void avrcp_get_capabilities(uint16_t con_handle){
|
||||
connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
|
||||
connection->subunit_id = 0;
|
||||
big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
|
||||
connection->cmd_operands[3] = 0x10;
|
||||
connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID
|
||||
connection->cmd_operands[4] = 0;
|
||||
big_endian_store_16(connection->cmd_operands, 5, 1);
|
||||
connection->cmd_operands[7] = 0x02;
|
||||
@ -661,7 +699,7 @@ void avrcp_start_rewind(uint16_t con_handle){
|
||||
void avrcp_stop_rewind(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
if (!connection){
|
||||
log_error("avrcp_unit_info: coud not find a connection.");
|
||||
log_error("avrcp_stop_rewind: coud not find a connection.");
|
||||
return;
|
||||
}
|
||||
if (connection->state != AVCTP_W4_STOP) return;
|
||||
@ -675,9 +713,31 @@ void avrcp_start_fast_forward(uint16_t con_handle){
|
||||
void avrcp_stop_fast_forward(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
if (!connection){
|
||||
log_error("avrcp_unit_info: coud not find a connection.");
|
||||
log_error("avrcp_stop_fast_forward: coud not find a connection.");
|
||||
return;
|
||||
}
|
||||
if (connection->state != AVCTP_W4_STOP) return;
|
||||
request_pass_through_release_control_cmd(connection);
|
||||
}
|
||||
|
||||
void avrcp_get_play_status(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_play_status: coud not find a connection.");
|
||||
return;
|
||||
}
|
||||
if (connection->state != AVCTP_CONNECTION_OPENED) return;
|
||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||
|
||||
connection->transaction_label++;
|
||||
connection->cmd_to_send = AVRCP_CMD_OPCODE_VENDOR_DEPENDENT;
|
||||
connection->command_type = AVRCP_CTYPE_STATUS;
|
||||
connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
|
||||
connection->subunit_id = 0;
|
||||
big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
|
||||
connection->cmd_operands[3] = AVRCP_PDU_ID_GET_PLAY_STATUS;
|
||||
connection->cmd_operands[4] = 0; // reserved(upper 6) | packet_type -> 0
|
||||
big_endian_store_16(connection->cmd_operands, 5, 0); // parameter length
|
||||
connection->cmd_operands_lenght = 7;
|
||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||
}
|
||||
|
@ -53,6 +53,23 @@ extern "C" {
|
||||
|
||||
#define BT_SIG_COMPANY_ID 0x001958
|
||||
/* API_START */
|
||||
|
||||
|
||||
typedef enum {
|
||||
AVRCP_PDU_ID_GET_CAPABILITIES = 0x10,
|
||||
AVRCP_PDU_ID_GET_PLAY_STATUS = 0x30,
|
||||
AVRCP_PDU_ID_REGISTER_NOTIFICATION = 0x31
|
||||
} avrcp_pdu_id_t;
|
||||
|
||||
typedef enum {
|
||||
AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED ,
|
||||
AVRCP_NOTIFICATION_EVENT_TRACK_CHANGED,
|
||||
AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED,
|
||||
AVRCP_NOTIFICATION_EVENT_AVAILABLE_PLAYERS_CHANGED,
|
||||
AVRCP_NOTIFICATION_EVENT_ADDRESSED_PLAYER_CHANGED,
|
||||
AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED
|
||||
} avrcp_notification_event_t;
|
||||
|
||||
typedef enum {
|
||||
AVRCP_CTYPE_CONTROL = 0,
|
||||
AVRCP_CTYPE_STATUS,
|
||||
@ -153,6 +170,15 @@ typedef struct {
|
||||
btstack_timer_source_t press_and_hold_cmd_timer;
|
||||
} avrcp_connection_t;
|
||||
|
||||
typedef enum {
|
||||
AVRCP_PLAY_STATUS_STOPPED = 0x00,
|
||||
AVRCP_PLAY_STATUS_PLAYING,
|
||||
AVRCP_PLAY_STATUS_PAUSED,
|
||||
AVRCP_PLAY_STATUS_FWD_SEEK,
|
||||
AVRCP_PLAY_STATUS_REV_SEEK,
|
||||
AVRCP_PLAY_STATUS_ERROR = 0xFF
|
||||
} avrcp_play_status_t;
|
||||
|
||||
/**
|
||||
* @brief AVDTP Sink service record.
|
||||
* @param service
|
||||
@ -250,6 +276,13 @@ void avrcp_forward(uint16_t con_handle);
|
||||
void avrcp_backward(uint16_t con_handle);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get play status. Returns event of type AVRCP_SUBEVENT_PLAY_STATUS (length, position, play_status).
|
||||
* If TG does not support SongLength And SongPosition on TG, then TG shall return 0xFFFFFFFF.
|
||||
* @param con_handle
|
||||
*/
|
||||
void avrcp_get_play_status(uint16_t con_handle);
|
||||
|
||||
/**
|
||||
* @brief Register notification.
|
||||
* - EVENT_PLAYBACK_STATUS_CHANGED
|
||||
|
@ -61,11 +61,12 @@ static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
// mac 2013: static bd_addr_t remote = {0x84, 0x38, 0x35, 0x65, 0xd1, 0x15};
|
||||
// phone: static bd_addr_t remote = {0x84, 0x38, 0x35, 0x65, 0xd1, 0x15};
|
||||
|
||||
static bd_addr_t remote = {0xD8, 0xBB, 0x2C, 0xDF, 0xF1, 0x08};
|
||||
// static bd_addr_t remote = {0xD8, 0xBB, 0x2C, 0xDF, 0xF1, 0x08};
|
||||
|
||||
static uint16_t con_handle = 0;
|
||||
static uint8_t sdp_avrcp_controller_service_buffer[150];
|
||||
|
||||
|
||||
static bd_addr_t remote = {0x84, 0x38, 0x35, 0x65, 0xd1, 0x15};
|
||||
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
UNUSED(channel);
|
||||
UNUSED(size);
|
||||
@ -91,6 +92,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
printf("AVRCP_SUBEVENT_CONNECTION_RELEASED: con_handle 0x%02x\n", avrcp_subevent_connection_closed_get_con_handle(packet));
|
||||
con_handle = 0;
|
||||
break;
|
||||
// case AVRCP_SUBEVENT_PLAY_STATUS:
|
||||
// printf("AVRCP_SUBEVENT_PLAY_STATUS\n");
|
||||
// break;
|
||||
default:
|
||||
printf("--- avrcp_test: Not implemented\n");
|
||||
break;
|
||||
@ -123,6 +127,7 @@ static void show_usage(void){
|
||||
printf("R - avrcp_stop_rewind\n");
|
||||
printf("f - avrcp_forward\n");
|
||||
printf("b - avrcp_backward\n");
|
||||
printf("S - get play status\n");
|
||||
printf("Ctrl-c - exit\n");
|
||||
printf("---\n");
|
||||
}
|
||||
@ -170,7 +175,9 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac
|
||||
case 'b':
|
||||
avrcp_backward(con_handle);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
avrcp_get_play_status(con_handle);
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user