mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-16 07:20:52 +00:00
avrcp: add all operation IDs, accept all valid operation IDs
This commit is contained in:
parent
7e3c67e67b
commit
0b578d060f
@ -111,19 +111,19 @@ const char * avrcp_event2str(uint16_t index){
|
||||
}
|
||||
|
||||
static const char * avrcp_operation_name[] = {
|
||||
NULL, // 0x3B
|
||||
"SKIP", NULL, NULL, NULL, NULL,
|
||||
"VOLUME_UP", "VOLUME_DOWN", "MUTE", "PLAY", "STOP", "PAUSE", NULL,
|
||||
"REWIND", "FAST_FORWARD", NULL, "FORWARD", "BACKWARD" // 0x4C
|
||||
};
|
||||
const char * avrcp_operation2str(uint8_t index){
|
||||
|
||||
const char * avrcp_operation2str(uint8_t operation_id){
|
||||
char * name = NULL;
|
||||
if ((index >= 0x3B) && (index <= 0x4C)){
|
||||
name = (char *)avrcp_operation_name[index - 0x3B];
|
||||
if ((operation_id >= AVRCP_OPERATION_ID_SKIP) && (operation_id <= AVRCP_OPERATION_ID_BACKWARD)){
|
||||
name = (char *)avrcp_operation_name[operation_id - AVRCP_OPERATION_ID_SKIP];
|
||||
}
|
||||
if (name == NULL){
|
||||
static char buffer[13];
|
||||
snprintf(buffer, sizeof(buffer), "Unknown 0x%02x", index);
|
||||
snprintf(buffer, sizeof(buffer), "Unknown 0x%02x", operation_id);
|
||||
buffer[sizeof(buffer)-1] = 0;
|
||||
return buffer;
|
||||
} else {
|
||||
|
@ -246,28 +246,80 @@ typedef enum {
|
||||
} avrcp_command_opcode_t;
|
||||
|
||||
typedef enum {
|
||||
AVRCP_OPERATION_ID_CHANNEL_UP = 0x30,
|
||||
AVRCP_OPERATION_ID_CHANNEL_DOWN = 0x31,
|
||||
AVRCP_OPERATION_ID_SELECT = 0x00,
|
||||
AVRCP_OPERATION_ID_UP = 0x01,
|
||||
AVRCP_OPERATION_ID_DOWN = 0x02,
|
||||
AVRCP_OPERATION_ID_LEFT = 0x03,
|
||||
AVRCP_OPERATION_ID_RIGHT = 0x04,
|
||||
AVRCP_OPERATION_ID_RIGHT_UP = 0x05,
|
||||
AVRCP_OPERATION_ID_RIGHT_DOWN = 0x06,
|
||||
AVRCP_OPERATION_ID_LEFT_UP = 0x07,
|
||||
AVRCP_OPERATION_ID_LEFT_DOWN = 0x07,
|
||||
AVRCP_OPERATION_ID_ROOT_MENU = 0x09,
|
||||
AVRCP_OPERATION_ID_SETUP_MENU = 0x0A,
|
||||
AVRCP_OPERATION_ID_CONTENTS_MENU = 0x0B,
|
||||
AVRCP_OPERATION_ID_FAVORITE_MENU = 0x0C,
|
||||
AVRCP_OPERATION_ID_EXIT = 0x0D,
|
||||
|
||||
AVRCP_OPERATION_ID_RESERVED_1 = 0x0E,
|
||||
|
||||
AVRCP_OPERATION_ID_0 = 0x20,
|
||||
AVRCP_OPERATION_ID_1 = 0x21,
|
||||
AVRCP_OPERATION_ID_2 = 0x22,
|
||||
AVRCP_OPERATION_ID_3 = 0x23,
|
||||
AVRCP_OPERATION_ID_4 = 0x24,
|
||||
AVRCP_OPERATION_ID_5 = 0x25,
|
||||
AVRCP_OPERATION_ID_6 = 0x26,
|
||||
AVRCP_OPERATION_ID_7 = 0x27,
|
||||
AVRCP_OPERATION_ID_8 = 0x28,
|
||||
AVRCP_OPERATION_ID_9 = 0x29,
|
||||
AVRCP_OPERATION_ID_DOT = 0x2A,
|
||||
AVRCP_OPERATION_ID_ENTER = 0x2B,
|
||||
AVRCP_OPERATION_ID_CLEAR = 0x2C,
|
||||
|
||||
AVRCP_OPERATION_ID_RESERVED_2 = 0x2D,
|
||||
|
||||
AVRCP_OPERATION_ID_CHANNEL_UP = 0x30,
|
||||
AVRCP_OPERATION_ID_CHANNEL_DOWN = 0x31,
|
||||
AVRCP_OPERATION_ID_PREVIOUS_CHANNEL = 0x32,
|
||||
AVRCP_OPERATION_ID_SOUND_SELECT = 0x33,
|
||||
AVRCP_OPERATION_ID_INPUT_SELECT = 0x34,
|
||||
AVRCP_OPERATION_ID_DISPLAY_INFORMATION = 0x35,
|
||||
AVRCP_OPERATION_ID_HELP = 0x36,
|
||||
AVRCP_OPERATION_ID_PAGE_UP = 0x37,
|
||||
AVRCP_OPERATION_ID_PAGE_DOWN = 0x38,
|
||||
|
||||
AVRCP_OPERATION_ID_RESERVED_3 = 0x39,
|
||||
|
||||
AVRCP_OPERATION_ID_SKIP = 0x3C,
|
||||
|
||||
AVRCP_OPERATION_ID_POWER = 0x40,
|
||||
AVRCP_OPERATION_ID_VOLUME_UP = 0x41,
|
||||
AVRCP_OPERATION_ID_VOLUME_DOWN = 0x42,
|
||||
AVRCP_OPERATION_ID_MUTE = 0x43,
|
||||
|
||||
AVRCP_OPERATION_ID_PLAY = 0x44,
|
||||
AVRCP_OPERATION_ID_STOP = 0x45,
|
||||
AVRCP_OPERATION_ID_PAUSE = 0x46,
|
||||
AVRCP_OPERATION_ID_RECORD = 0x47,
|
||||
AVRCP_OPERATION_ID_REWIND = 0x48,
|
||||
AVRCP_OPERATION_ID_FAST_FORWARD = 0x49,
|
||||
AVRCP_OPERATION_ID_EJECT = 0x4A,
|
||||
AVRCP_OPERATION_ID_FORWARD = 0x4B,
|
||||
AVRCP_OPERATION_ID_BACKWARD = 0x4C,
|
||||
AVRCP_OPERATION_ID_UNDEFINED = 0xFF
|
||||
|
||||
AVRCP_OPERATION_ID_RESERVED_4 = 0x4D,
|
||||
|
||||
AVRCP_OPERATION_ID_ANGLE = 0x50,
|
||||
AVRCP_OPERATION_ID_SUBPICTURE = 0x51,
|
||||
|
||||
AVRCP_OPERATION_ID_RESERVED_5 = 0x3D,
|
||||
|
||||
AVRCP_OPERATION_ID_F1 = 0xF1,
|
||||
AVRCP_OPERATION_ID_F2 = 0xF2,
|
||||
AVRCP_OPERATION_ID_F3 = 0xF3,
|
||||
AVRCP_OPERATION_ID_F4 = 0xF4,
|
||||
AVRCP_OPERATION_ID_F5 = 0xF5,
|
||||
AVRCP_OPERATION_ID_RESERVED_6 = 0xF7
|
||||
} avrcp_operation_id_t;
|
||||
|
||||
typedef enum{
|
||||
|
@ -741,6 +741,33 @@ static uint8_t avrcp_target_get_transaction_label_for_notification(avrcp_connect
|
||||
return connection->notifications_transaction_label[notification];
|
||||
}
|
||||
|
||||
static bool avcrp_operation_id_is_valid(avrcp_operation_id_t operation_id){
|
||||
if (operation_id < AVRCP_OPERATION_ID_RESERVED_1) return true;
|
||||
|
||||
if (operation_id < AVRCP_OPERATION_ID_0) return false;
|
||||
if (operation_id < AVRCP_OPERATION_ID_RESERVED_2) return true;
|
||||
|
||||
if (operation_id < AVRCP_OPERATION_ID_CHANNEL_UP) return false;
|
||||
if (operation_id < AVRCP_OPERATION_ID_RESERVED_3) return true;
|
||||
|
||||
if (operation_id < AVRCP_OPERATION_ID_CHANNEL_UP) return false;
|
||||
if (operation_id < AVRCP_OPERATION_ID_RESERVED_3) return true;
|
||||
|
||||
if (operation_id < AVRCP_OPERATION_ID_SKIP) return false;
|
||||
if (operation_id == AVRCP_OPERATION_ID_SKIP) return true;
|
||||
|
||||
if (operation_id < AVRCP_OPERATION_ID_POWER) return false;
|
||||
if (operation_id < AVRCP_OPERATION_ID_RESERVED_4) return true;
|
||||
|
||||
if (operation_id < AVRCP_OPERATION_ID_ANGLE) return false;
|
||||
if (operation_id < AVRCP_OPERATION_ID_RESERVED_5) return true;
|
||||
|
||||
if (operation_id < AVRCP_OPERATION_ID_F1) return false;
|
||||
if (operation_id < AVRCP_OPERATION_ID_RESERVED_6) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){
|
||||
|
||||
if (size < 6u) return;
|
||||
@ -790,6 +817,7 @@ static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connec
|
||||
avrcp_pdu_id_t pdu_id;
|
||||
connection->cmd_operands_length = 0;
|
||||
uint8_t offset;
|
||||
uint8_t operand;
|
||||
|
||||
switch (opcode){
|
||||
case AVRCP_CMD_OPCODE_UNIT_INFO:
|
||||
@ -804,49 +832,26 @@ static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connec
|
||||
avrcp_target_subunit_info(connection, offset);
|
||||
break;
|
||||
|
||||
case AVRCP_CMD_OPCODE_PASS_THROUGH:{
|
||||
case AVRCP_CMD_OPCODE_PASS_THROUGH:
|
||||
if (size < 8) return;
|
||||
log_info("AVRCP_OPERATION_ID 0x%02x, operands length %d", packet[6], packet[7]);
|
||||
avrcp_operation_id_t operation_id = (avrcp_operation_id_t) (packet[6] & 0x7f);
|
||||
bool button_pressed = (packet[6] & 0x80) == 0;
|
||||
uint8_t operand = 0;
|
||||
operand = 0;
|
||||
if ((packet[7] >= 1) && (size >= 9)){
|
||||
operand = packet[8];
|
||||
}
|
||||
|
||||
switch (operation_id){
|
||||
case AVRCP_OPERATION_ID_PLAY:
|
||||
case AVRCP_OPERATION_ID_PAUSE:
|
||||
case AVRCP_OPERATION_ID_STOP:
|
||||
case AVRCP_OPERATION_ID_VOLUME_UP:
|
||||
case AVRCP_OPERATION_ID_VOLUME_DOWN:
|
||||
case AVRCP_OPERATION_ID_REWIND:
|
||||
case AVRCP_OPERATION_ID_FAST_FORWARD:
|
||||
case AVRCP_OPERATION_ID_FORWARD:
|
||||
case AVRCP_OPERATION_ID_BACKWARD:
|
||||
case AVRCP_OPERATION_ID_SKIP:
|
||||
case AVRCP_OPERATION_ID_MUTE:
|
||||
case AVRCP_OPERATION_ID_CHANNEL_UP:
|
||||
case AVRCP_OPERATION_ID_CHANNEL_DOWN:
|
||||
case AVRCP_OPERATION_ID_SELECT:
|
||||
case AVRCP_OPERATION_ID_UP:
|
||||
case AVRCP_OPERATION_ID_DOWN:
|
||||
case AVRCP_OPERATION_ID_LEFT:
|
||||
case AVRCP_OPERATION_ID_RIGHT:
|
||||
case AVRCP_OPERATION_ID_ROOT_MENU:
|
||||
avrcp_target_operation_accepted(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand);
|
||||
avrcp_target_emit_operation(avrcp_target_context.avrcp_callback, connection->avrcp_cid,
|
||||
if (avcrp_operation_id_is_valid(operation_id)){
|
||||
bool button_pressed = (packet[6] & 0x80) == 0;
|
||||
|
||||
avrcp_target_operation_accepted(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand);
|
||||
avrcp_target_emit_operation(avrcp_target_context.avrcp_callback, connection->avrcp_cid,
|
||||
operation_id, button_pressed, packet[7], operand);
|
||||
break;
|
||||
case AVRCP_OPERATION_ID_UNDEFINED:
|
||||
avrcp_target_operation_not_implemented(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand);
|
||||
return;
|
||||
default:
|
||||
avrcp_target_operation_not_implemented(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand);
|
||||
return;
|
||||
} else {
|
||||
avrcp_target_operation_not_implemented(connection->avrcp_cid, (avrcp_operation_id_t) packet[6], packet[7], operand);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case AVRCP_CMD_OPCODE_VENDOR_DEPENDENT:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user