mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-31 00:32:52 +00:00
avrcp_cotroller: use the same pointer for fragmented and normal commands, adapt avrcp_controller_send_custom_command to provide only parameters through data buffer
This commit is contained in:
parent
8d316b1bc5
commit
5d3671d9fb
@ -58,6 +58,7 @@ extern "C" {
|
|||||||
#define AVRCP_BROWSING_ITEM_HEADER_LEN 3
|
#define AVRCP_BROWSING_ITEM_HEADER_LEN 3
|
||||||
#define AVRCP_BROWSING_MAX_NUM_ATTR_IDS 8
|
#define AVRCP_BROWSING_MAX_NUM_ATTR_IDS 8
|
||||||
|
|
||||||
|
#define AVRCP_MAX_COMMAND_PARAMETER_LENGTH 11
|
||||||
#define BT_SIG_COMPANY_ID 0x001958
|
#define BT_SIG_COMPANY_ID 0x001958
|
||||||
#define AVRCP_MEDIA_ATTR_COUNT 7
|
#define AVRCP_MEDIA_ATTR_COUNT 7
|
||||||
#define AVRCP_MAX_ATTRIBUTTE_SIZE 100
|
#define AVRCP_MAX_ATTRIBUTTE_SIZE 100
|
||||||
@ -543,16 +544,15 @@ typedef struct {
|
|||||||
avrcp_pdu_id_t pdu_id;
|
avrcp_pdu_id_t pdu_id;
|
||||||
// needed for PASS_THROUGH
|
// needed for PASS_THROUGH
|
||||||
avrcp_operation_id_t operation_id;
|
avrcp_operation_id_t operation_id;
|
||||||
|
|
||||||
// regular commands
|
// regular commands
|
||||||
uint8_t cmd_operands[20];
|
uint8_t cmd_operands[AVRCP_MAX_COMMAND_PARAMETER_LENGTH];
|
||||||
uint8_t cmd_operands_length;
|
|
||||||
|
|
||||||
|
uint8_t * data;
|
||||||
|
uint16_t data_len;
|
||||||
// long/fragmented commands
|
// long/fragmented commands
|
||||||
const uint8_t * cmd_operands_fragmented_buffer;
|
uint16_t data_offset;
|
||||||
uint16_t cmd_operands_fragmented_pos;
|
|
||||||
uint16_t cmd_operands_fragmented_len;
|
|
||||||
|
|
||||||
btstack_timer_source_t retry_timer;
|
btstack_timer_source_t retry_timer;
|
||||||
btstack_timer_source_t press_and_hold_cmd_timer;
|
btstack_timer_source_t press_and_hold_cmd_timer;
|
||||||
bool press_and_hold_cmd_active;
|
bool press_and_hold_cmd_active;
|
||||||
|
@ -103,9 +103,9 @@ static void avrcp_custome_command_data_init(avrcp_connection_t * connection,
|
|||||||
connection->subunit_id = subunit_id;
|
connection->subunit_id = subunit_id;
|
||||||
connection->company_id = company_id << 16;
|
connection->company_id = company_id << 16;
|
||||||
connection->pdu_id = pdu_id;
|
connection->pdu_id = pdu_id;
|
||||||
connection->cmd_operands_fragmented_buffer = NULL;
|
connection->data = NULL;
|
||||||
connection->cmd_operands_fragmented_pos = 0;
|
connection->data_offset = 0;
|
||||||
connection->cmd_operands_fragmented_len = 0;
|
connection->data_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void avrcp_vendor_dependent_command_data_init(avrcp_connection_t * connection, avrcp_command_type_t command_type, avrcp_pdu_id_t pdu_id){
|
static void avrcp_vendor_dependent_command_data_init(avrcp_connection_t * connection, avrcp_command_type_t command_type, avrcp_pdu_id_t pdu_id){
|
||||||
@ -117,9 +117,9 @@ static void avrcp_vendor_dependent_command_data_init(avrcp_connection_t * connec
|
|||||||
|
|
||||||
connection->command_type = command_type;
|
connection->command_type = command_type;
|
||||||
connection->pdu_id = pdu_id;
|
connection->pdu_id = pdu_id;
|
||||||
connection->cmd_operands_fragmented_buffer = NULL;
|
connection->data = connection->cmd_operands;
|
||||||
connection->cmd_operands_fragmented_pos = 0;
|
connection->data_offset = 0;
|
||||||
connection->cmd_operands_fragmented_len = 0;
|
connection->data_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void avrcp_pass_through_command_data_init(avrcp_connection_t * connection, avrcp_operation_id_t opid){
|
static void avrcp_pass_through_command_data_init(avrcp_connection_t * connection, avrcp_operation_id_t opid){
|
||||||
@ -133,9 +133,9 @@ static void avrcp_pass_through_command_data_init(avrcp_connection_t * connection
|
|||||||
connection->pdu_id = 0;
|
connection->pdu_id = 0;
|
||||||
connection->operation_id = opid;
|
connection->operation_id = opid;
|
||||||
|
|
||||||
connection->cmd_operands_fragmented_buffer = NULL;
|
connection->data = connection->cmd_operands;
|
||||||
connection->cmd_operands_fragmented_pos = 0;
|
connection->data_offset = 0;
|
||||||
connection->cmd_operands_fragmented_len = 0;
|
connection->data_len = 0;
|
||||||
}
|
}
|
||||||
static int avrcp_controller_supports_browsing(uint16_t controller_supported_features){
|
static int avrcp_controller_supports_browsing(uint16_t controller_supported_features){
|
||||||
return controller_supported_features & AVRCP_FEATURE_MASK_BROWSING;
|
return controller_supported_features & AVRCP_FEATURE_MASK_BROWSING;
|
||||||
@ -655,7 +655,7 @@ static uint8_t avrcp_controller_request_pass_through_release_control_cmd(avrcp_c
|
|||||||
if (connection->press_and_hold_cmd_active){
|
if (connection->press_and_hold_cmd_active){
|
||||||
avrcp_press_and_hold_timer_stop(connection);
|
avrcp_press_and_hold_timer_stop(connection);
|
||||||
}
|
}
|
||||||
connection->cmd_operands[0] = 0x80 | connection->cmd_operands[0];
|
connection->operation_id = 0x80 | connection->operation_id;
|
||||||
connection->transaction_id = avrcp_controller_get_next_transaction_label(connection);
|
connection->transaction_id = avrcp_controller_get_next_transaction_label(connection);
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
@ -675,15 +675,12 @@ static uint8_t avrcp_controller_request_pass_through_press_control_cmd(uint16_t
|
|||||||
connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
|
connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
|
||||||
avrcp_pass_through_command_data_init(connection, opid);
|
avrcp_pass_through_command_data_init(connection, opid);
|
||||||
|
|
||||||
connection->press_and_hold_cmd_active = continuous_cmd;
|
|
||||||
connection->cmd_operands_length = 2;
|
|
||||||
connection->cmd_operands[0] = opid;
|
|
||||||
if (playback_speed > 0){
|
if (playback_speed > 0){
|
||||||
connection->cmd_operands[2] = playback_speed;
|
connection->data[0] = playback_speed;
|
||||||
connection->cmd_operands_length++;
|
connection->data_len = 1;
|
||||||
}
|
}
|
||||||
connection->cmd_operands[1] = connection->cmd_operands_length - 2;
|
|
||||||
|
|
||||||
|
connection->press_and_hold_cmd_active = continuous_cmd;
|
||||||
if (connection->press_and_hold_cmd_active){
|
if (connection->press_and_hold_cmd_active){
|
||||||
avrcp_press_and_hold_timer_start(connection);
|
avrcp_press_and_hold_timer_start(connection);
|
||||||
}
|
}
|
||||||
@ -704,13 +701,10 @@ static void avrcp_controller_get_capabilities_for_connection(avrcp_connection_t
|
|||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_CAPABILITIES);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_CAPABILITIES);
|
||||||
|
|
||||||
// TODO: refactor
|
// Parameter Length
|
||||||
big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
|
connection->data_len = 1;
|
||||||
connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CAPABILITIES; // PDU ID
|
connection->data[0] = capability_id; // capability ID
|
||||||
connection->cmd_operands[4] = 0;
|
|
||||||
big_endian_store_16(connection->cmd_operands, 5, 1); // parameter length
|
|
||||||
connection->cmd_operands[7] = capability_id; // capability ID
|
|
||||||
connection->cmd_operands_length = 8;
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -735,43 +729,25 @@ static uint8_t avrcp_controller_register_notification(avrcp_connection_t * conne
|
|||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t avrcp_controller_request_abort_continuation(avrcp_connection_t * connection){
|
static uint8_t avrcp_controller_request_continuation(avrcp_connection_t * connection, avrcp_pdu_id_t pdu_id){
|
||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, pdu_id);
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
int pos = 0;
|
|
||||||
big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
|
|
||||||
pos += 3;
|
|
||||||
connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE; // PDU ID
|
|
||||||
connection->cmd_operands[pos++] = 0;
|
|
||||||
// Parameter Length
|
// Parameter Length
|
||||||
connection->cmd_operands_length = 8;
|
connection->data_len = 3;
|
||||||
big_endian_store_16(connection->cmd_operands, pos, 1);
|
big_endian_store_16(connection->data, 0, 1);
|
||||||
pos += 2;
|
connection->data[2] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES;
|
||||||
connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES;
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t avrcp_controller_request_abort_continuation(avrcp_connection_t * connection){
|
||||||
|
return avrcp_controller_request_continuation(connection, AVRCP_PDU_ID_REQUEST_ABORT_CONTINUING_RESPONSE);
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t avrcp_controller_request_continue_response(avrcp_connection_t * connection){
|
static uint8_t avrcp_controller_request_continue_response(avrcp_connection_t * connection){
|
||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
return avrcp_controller_request_continuation(connection, AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE);
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE);
|
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
int pos = 0;
|
|
||||||
big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
|
|
||||||
pos += 3;
|
|
||||||
connection->cmd_operands[pos++] = AVRCP_PDU_ID_REQUEST_CONTINUING_RESPONSE; // PDU ID
|
|
||||||
connection->cmd_operands[pos++] = 0;
|
|
||||||
// Parameter Length
|
|
||||||
connection->cmd_operands_length = 8;
|
|
||||||
big_endian_store_16(connection->cmd_operands, pos, 1);
|
|
||||||
pos += 2;
|
|
||||||
connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES;
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
|
||||||
return ERROR_CODE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void avrcp_controller_handle_notification(avrcp_connection_t *connection, avrcp_command_type_t ctype, uint8_t *payload, uint16_t size) {
|
static void avrcp_controller_handle_notification(avrcp_connection_t *connection, avrcp_command_type_t ctype, uint8_t *payload, uint16_t size) {
|
||||||
@ -1446,15 +1422,12 @@ uint8_t avrcp_controller_unit_info(uint16_t avrcp_cid){
|
|||||||
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||||
}
|
}
|
||||||
if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
|
if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
|
||||||
|
|
||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
|
avrcp_custome_command_data_init(connection, AVRCP_CMD_OPCODE_UNIT_INFO, AVRCP_CTYPE_STATUS, AVRCP_SUBUNIT_TYPE_UNIT, AVRCP_SUBUNIT_ID_IGNORE, 0, 0);
|
||||||
connection->transaction_id = avrcp_controller_get_next_transaction_label(connection);
|
|
||||||
connection->command_opcode = AVRCP_CMD_OPCODE_UNIT_INFO;
|
memset(connection->data, 0xFF, 5);
|
||||||
connection->command_type = AVRCP_CTYPE_STATUS;
|
connection->data_len = 5;
|
||||||
connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique
|
|
||||||
connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE;
|
|
||||||
memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length);
|
|
||||||
connection->cmd_operands_length = 5;
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1465,16 +1438,13 @@ uint8_t avrcp_controller_subunit_info(uint16_t avrcp_cid){
|
|||||||
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||||
}
|
}
|
||||||
if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
|
if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
|
||||||
|
|
||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
|
avrcp_custome_command_data_init(connection, AVRCP_CMD_OPCODE_SUBUNIT_INFO, AVRCP_CTYPE_STATUS, AVRCP_SUBUNIT_TYPE_UNIT, AVRCP_SUBUNIT_ID_IGNORE, 0, 0);
|
||||||
connection->transaction_id = avrcp_controller_get_next_transaction_label(connection);
|
|
||||||
connection->command_opcode = AVRCP_CMD_OPCODE_SUBUNIT_INFO;
|
memset(connection->data, 0xFF, 5);
|
||||||
connection->command_type = AVRCP_CTYPE_STATUS;
|
connection->data[0] = 7; // page: 0, extention_code: 7
|
||||||
connection->subunit_type = AVRCP_SUBUNIT_TYPE_UNIT; //vendor unique
|
connection->data_len = 5;
|
||||||
connection->subunit_id = AVRCP_SUBUNIT_ID_IGNORE;
|
|
||||||
memset(connection->cmd_operands, 0xFF, connection->cmd_operands_length);
|
|
||||||
connection->cmd_operands[0] = 7; // page: 0, extention_code: 7
|
|
||||||
connection->cmd_operands_length = 5;
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1520,12 +1490,7 @@ uint8_t avrcp_controller_get_play_status(uint16_t avrcp_cid){
|
|||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_PLAY_STATUS);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_PLAY_STATUS);
|
||||||
|
|
||||||
// TODO refactor
|
connection->data_len = 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_length = 7;
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1540,21 +1505,9 @@ uint8_t avrcp_controller_set_addressed_player(uint16_t avrcp_cid, uint16_t addre
|
|||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_SET_ADDRESSED_PLAYER);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_SET_ADDRESSED_PLAYER);
|
||||||
|
|
||||||
// TODO refactor
|
connection->data_len = 2;
|
||||||
int pos = 0;
|
big_endian_store_16(connection->data, 0, addressed_player_id);
|
||||||
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);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1574,31 +1527,31 @@ uint8_t avrcp_controller_get_element_attributes(uint16_t avrcp_cid, uint8_t num_
|
|||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES);
|
||||||
|
|
||||||
// TODO refactor
|
uint8_t pos = 0;
|
||||||
int pos = 0;
|
|
||||||
big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
|
|
||||||
pos += 3;
|
|
||||||
connection->cmd_operands[pos++] = AVRCP_PDU_ID_GET_ELEMENT_ATTRIBUTES; // PDU ID
|
|
||||||
connection->cmd_operands[pos++] = 0;
|
|
||||||
|
|
||||||
// Parameter Length
|
|
||||||
big_endian_store_16(connection->cmd_operands, pos, 9);
|
|
||||||
pos += 2;
|
|
||||||
|
|
||||||
// write 8 bytes value
|
// write 8 bytes value
|
||||||
memset(connection->cmd_operands + pos, 0, 8); // identifier: PLAYING
|
memset(connection->data, pos, 8); // identifier: PLAYING
|
||||||
pos += 8;
|
pos += 8;
|
||||||
|
|
||||||
connection->cmd_operands[pos++] = num_attributes; // attribute count, if 0 get all attributes
|
uint8_t num_attributes_index = pos;
|
||||||
|
pos++;
|
||||||
int i;
|
|
||||||
|
// If num_attributes is set to zero, all attribute information shall be returned,
|
||||||
|
// and the AttributeID field is omitted
|
||||||
|
connection->data[num_attributes_index] = 0;
|
||||||
|
uint8_t i;
|
||||||
for (i = 0; i < num_attributes; i++){
|
for (i = 0; i < num_attributes; i++){
|
||||||
// every attribute is 4 bytes long
|
// ignore invalid attribute ID and "get all attributes"
|
||||||
big_endian_store_32(connection->cmd_operands, pos, attributes[i]);
|
if (AVRCP_MEDIA_ATTR_ALL > attributes[i] && attributes[i] < AVRCP_MEDIA_ATTR_RESERVED){
|
||||||
pos += 4;
|
// every attribute is 4 bytes long
|
||||||
|
big_endian_store_32(connection->data, pos, attributes[i]);
|
||||||
|
pos += 4;
|
||||||
|
connection->data[num_attributes_index]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connection->cmd_operands_length = pos;
|
// Parameter Length
|
||||||
|
connection->data_len = pos;
|
||||||
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1634,7 +1587,7 @@ uint8_t avrcp_controller_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume)
|
|||||||
if (connection->command_type != AVRCP_CTYPE_CONTROL) break;
|
if (connection->command_type != AVRCP_CTYPE_CONTROL) break;
|
||||||
if (connection->subunit_type != AVRCP_SUBUNIT_TYPE_PANEL) break;
|
if (connection->subunit_type != AVRCP_SUBUNIT_TYPE_PANEL) break;
|
||||||
if (connection->subunit_id != AVRCP_SUBUNIT_ID) break;
|
if (connection->subunit_id != AVRCP_SUBUNIT_ID) break;
|
||||||
if (connection->cmd_operands[3] != AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME) break;
|
if (connection->pdu_id != AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME) break;
|
||||||
// - is next transaction id valid in window
|
// - is next transaction id valid in window
|
||||||
if (avrcp_controller_is_transaction_id_valid(connection, avrcp_controller_calc_next_transaction_label(connection->transaction_id_counter)) == false) break;
|
if (avrcp_controller_is_transaction_id_valid(connection, avrcp_controller_calc_next_transaction_label(connection->transaction_id_counter)) == false) break;
|
||||||
status = ERROR_CODE_SUCCESS;
|
status = ERROR_CODE_SUCCESS;
|
||||||
@ -1647,19 +1600,10 @@ uint8_t avrcp_controller_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume)
|
|||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_SET_ABSOLUTE_VOLUME);
|
||||||
|
|
||||||
// TODO refactor:
|
|
||||||
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_ABSOLUTE_VOLUME; // PDU ID
|
|
||||||
connection->cmd_operands[pos++] = 0;
|
|
||||||
|
|
||||||
// Parameter Length
|
// Parameter Length
|
||||||
big_endian_store_16(connection->cmd_operands, pos, 1);
|
connection->data_len = 1;
|
||||||
pos += 2;
|
connection->data[0] = volume;
|
||||||
connection->cmd_operands[pos++] = volume;
|
|
||||||
|
|
||||||
connection->cmd_operands_length = pos;
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1674,18 +1618,14 @@ uint8_t avrcp_controller_query_shuffle_and_repeat_modes(uint16_t avrcp_cid){
|
|||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_STATUS, AVRCP_PDU_ID_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE);
|
||||||
|
|
||||||
// TODO refactor
|
connection->data_len = 5;
|
||||||
big_endian_store_24(connection->cmd_operands, 0, BT_SIG_COMPANY_ID);
|
connection->data[0] = 4; // NumPlayerApplicationSettingAttributeID
|
||||||
connection->cmd_operands[3] = AVRCP_PDU_ID_GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE; // PDU ID
|
|
||||||
connection->cmd_operands[4] = 0;
|
|
||||||
big_endian_store_16(connection->cmd_operands, 5, 5); // parameter length
|
|
||||||
connection->cmd_operands[7] = 4; // NumPlayerApplicationSettingAttributeID
|
|
||||||
// PlayerApplicationSettingAttributeID1 AVRCP Spec, Appendix F, 133
|
// PlayerApplicationSettingAttributeID1 AVRCP Spec, Appendix F, 133
|
||||||
connection->cmd_operands[8] = 0x01; // equalizer (1-OFF, 2-ON)
|
connection->data[1] = 0x01; // equalizer (1-OFF, 2-ON)
|
||||||
connection->cmd_operands[9] = 0x02; // repeat (1-off, 2-single track, 3-all tracks, 4-group repeat)
|
connection->data[2] = 0x02; // repeat (1-off, 2-single track, 3-all tracks, 4-group repeat)
|
||||||
connection->cmd_operands[10] = 0x03; // shuffle (1-off, 2-all tracks, 3-group shuffle)
|
connection->data[3] = 0x03; // shuffle (1-off, 2-all tracks, 3-group shuffle)
|
||||||
connection->cmd_operands[11] = 0x04; // scan (1-off, 2-all tracks, 3-group scan)
|
connection->data[4] = 0x04; // scan (1-off, 2-all tracks, 3-group scan)
|
||||||
connection->cmd_operands_length = 12;
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1700,20 +1640,12 @@ static uint8_t avrcp_controller_set_current_player_application_setting_value(uin
|
|||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_SET_PLAYER_APPLICATION_SETTING_VALUE);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_SET_PLAYER_APPLICATION_SETTING_VALUE);
|
||||||
|
|
||||||
// TODO refactor
|
|
||||||
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_PLAYER_APPLICATION_SETTING_VALUE; // PDU ID
|
|
||||||
connection->cmd_operands[pos++] = 0;
|
|
||||||
// Parameter Length
|
// Parameter Length
|
||||||
big_endian_store_16(connection->cmd_operands, pos, 3);
|
connection->data_len = 3;
|
||||||
pos += 2;
|
connection->data[0] = 2;
|
||||||
connection->cmd_operands[pos++] = 2;
|
connection->data[1] = attr_id;
|
||||||
connection->cmd_operands_length = pos;
|
connection->data[2] = attr_value;
|
||||||
connection->cmd_operands[pos++] = attr_id;
|
|
||||||
connection->cmd_operands[pos++] = attr_value;
|
|
||||||
connection->cmd_operands_length = pos;
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1740,25 +1672,14 @@ uint8_t avrcp_controller_play_item_for_scope(uint16_t avrcp_cid, uint8_t * uid,
|
|||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_PLAY_ITEM);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_PLAY_ITEM);
|
||||||
|
|
||||||
// TODO refactor
|
|
||||||
int pos = 0;
|
|
||||||
big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
|
|
||||||
pos += 3;
|
|
||||||
connection->cmd_operands[pos++] = AVRCP_PDU_ID_PLAY_ITEM; // PDU ID
|
|
||||||
// reserved
|
|
||||||
connection->cmd_operands[pos++] = 0;
|
|
||||||
// Parameter Length
|
// Parameter Length
|
||||||
big_endian_store_16(connection->cmd_operands, pos, 11);
|
connection->data_len = 11;
|
||||||
pos += 2;
|
connection->data[0] = scope;
|
||||||
connection->cmd_operands[pos++] = scope;
|
memset(&connection->data[1], 0, 8);
|
||||||
memset(&connection->cmd_operands[pos], 0, 8);
|
|
||||||
if (uid){
|
if (uid){
|
||||||
(void)memcpy(&connection->cmd_operands[pos], uid, 8);
|
(void)memcpy(&connection->data[1], uid, 8);
|
||||||
}
|
}
|
||||||
pos += 8;
|
big_endian_store_16(connection->data, 9, uid_counter);
|
||||||
big_endian_store_16(connection->cmd_operands, pos, uid_counter);
|
|
||||||
pos += 2;
|
|
||||||
connection->cmd_operands_length = pos;
|
|
||||||
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
@ -1777,26 +1698,15 @@ uint8_t avrcp_controller_add_item_from_scope_to_now_playing_list(uint16_t avrcp_
|
|||||||
connection->state = AVCTP_W2_SEND_COMMAND;
|
connection->state = AVCTP_W2_SEND_COMMAND;
|
||||||
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_ADD_TO_NOW_PLAYING);
|
avrcp_vendor_dependent_command_data_init(connection, AVRCP_CTYPE_CONTROL, AVRCP_PDU_ID_ADD_TO_NOW_PLAYING);
|
||||||
|
|
||||||
// TODO refactor
|
|
||||||
int pos = 0;
|
|
||||||
big_endian_store_24(connection->cmd_operands, pos, BT_SIG_COMPANY_ID);
|
|
||||||
pos += 3;
|
|
||||||
connection->cmd_operands[pos++] = AVRCP_PDU_ID_ADD_TO_NOW_PLAYING; // PDU ID
|
|
||||||
// reserved
|
|
||||||
connection->cmd_operands[pos++] = 0;
|
|
||||||
// Parameter Length
|
// Parameter Length
|
||||||
big_endian_store_16(connection->cmd_operands, pos, 11);
|
connection->data_len = 11;
|
||||||
pos += 2;
|
connection->data[0] = scope;
|
||||||
connection->cmd_operands[pos++] = scope;
|
memset(&connection->data[1], 0, 8);
|
||||||
memset(&connection->cmd_operands[pos], 0, 8);
|
|
||||||
if (uid){
|
if (uid){
|
||||||
(void)memcpy(&connection->cmd_operands[pos], uid, 8);
|
(void)memcpy(&connection->data[1], uid, 8);
|
||||||
}
|
}
|
||||||
pos += 8;
|
big_endian_store_16(connection->data, 9, uid_counter);
|
||||||
big_endian_store_16(connection->cmd_operands, pos, uid_counter);
|
|
||||||
pos += 2;
|
|
||||||
connection->cmd_operands_length = pos;
|
|
||||||
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1810,23 +1720,24 @@ uint8_t avrcp_controller_set_max_num_fragments(uint16_t avrcp_cid, uint8_t max_n
|
|||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t avrcp_controller_send_custom_command(uint16_t avrcp_cid, avrcp_command_type_t command_type, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t command_opcode, const uint8_t * command_buffer, uint16_t command_len){
|
|
||||||
|
uint8_t avrcp_controller_send_custom_command(uint16_t avrcp_cid,
|
||||||
|
avrcp_command_type_t command_type,
|
||||||
|
avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id,
|
||||||
|
avrcp_pdu_id_t pdu_id, uint32_t company_id,
|
||||||
|
const uint8_t * data, uint16_t data_len){
|
||||||
|
|
||||||
avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
|
avrcp_connection_t * connection = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, avrcp_cid);
|
||||||
if (!connection){
|
if (!connection){
|
||||||
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
|
if (connection->state != AVCTP_CONNECTION_OPENED) return ERROR_CODE_COMMAND_DISALLOWED;
|
||||||
|
|
||||||
connection->state = AVCTP_W2_SEND_AVCTP_FRAGMENTED_MESSAGE;
|
connection->state = AVCTP_W2_SEND_AVCTP_FRAGMENTED_MESSAGE;
|
||||||
|
avrcp_custome_command_data_init(connection, AVRCP_CMD_OPCODE_VENDOR_DEPENDENT, command_type, subunit_type, subunit_id, pdu_id, company_id);
|
||||||
|
|
||||||
connection->transaction_id = avrcp_controller_get_next_transaction_label(connection);
|
connection->data = (uint8_t *)data;
|
||||||
connection->command_opcode = command_opcode;
|
connection->data_len = data_len;
|
||||||
connection->command_type = command_type;
|
|
||||||
connection->subunit_type = subunit_type;
|
|
||||||
connection->subunit_id = subunit_id;
|
|
||||||
connection->cmd_operands_fragmented_buffer = command_buffer;
|
|
||||||
connection->cmd_operands_fragmented_pos = 0;
|
|
||||||
connection->cmd_operands_fragmented_len = command_len;
|
|
||||||
|
|
||||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||||
return ERROR_CODE_SUCCESS;
|
return ERROR_CODE_SUCCESS;
|
||||||
|
@ -329,12 +329,17 @@ uint8_t avrcp_controller_set_addressed_player(uint16_t avrcp_cid, uint16_t addre
|
|||||||
* @param avrcp_cid
|
* @param avrcp_cid
|
||||||
* @param command_type
|
* @param command_type
|
||||||
* @param subunit_type
|
* @param subunit_type
|
||||||
* @param subunit ID
|
* @param subunit_id
|
||||||
* @param command_opcode
|
* @param pdu_id
|
||||||
* @param command_buffer
|
* @param company_id
|
||||||
* @param command_len
|
* @param data
|
||||||
|
* @param data_len
|
||||||
*/
|
*/
|
||||||
uint8_t avrcp_controller_send_custom_command(uint16_t avrcp_cid, avrcp_command_type_t command_type, avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id, avrcp_command_opcode_t command_opcode, const uint8_t * command_buffer, uint16_t command_len);
|
uint8_t avrcp_controller_send_custom_command(uint16_t avrcp_cid,
|
||||||
|
avrcp_command_type_t command_type,
|
||||||
|
avrcp_subunit_type_t subunit_type, avrcp_subunit_id_t subunit_id,
|
||||||
|
avrcp_pdu_id_t pdu_id, uint32_t company_id,
|
||||||
|
const uint8_t * data, uint16_t data_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief De-Init AVRCP Controller
|
* @brief De-Init AVRCP Controller
|
||||||
|
Loading…
x
Reference in New Issue
Block a user