avrcp: add 2sec resend timeout for fast forward and rewind

This commit is contained in:
Milanka Ringwald 2017-02-01 16:44:09 +01:00 committed by Matthias Ringwald
parent 746b4852b8
commit a85ed257c2
3 changed files with 93 additions and 17 deletions

View File

@ -293,10 +293,39 @@ static void avrcp_request_can_send_now(avrcp_connection_t * connection, uint16_t
l2cap_request_can_send_now_event(l2cap_cid);
}
static void avrcp_press_and_hold_timeout_handler(btstack_timer_source_t * timer){
UNUSED(timer);
avrcp_connection_t * connection = btstack_run_loop_get_timer_context(timer);
btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout
btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer);
connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
}
static void avrcp_press_and_hold_timer_start(avrcp_connection_t * connection){
btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer);
btstack_run_loop_set_timer_handler(&connection->press_and_hold_cmd_timer, avrcp_press_and_hold_timeout_handler);
btstack_run_loop_set_timer_context(&connection->press_and_hold_cmd_timer, connection);
btstack_run_loop_set_timer(&connection->press_and_hold_cmd_timer, 2000); // 2 seconds timeout
btstack_run_loop_add_timer(&connection->press_and_hold_cmd_timer);
}
static void avrcp_press_and_hold_timer_stop(avrcp_connection_t * connection){
btstack_run_loop_remove_timer(&connection->press_and_hold_cmd_timer);
}
static void request_pass_through_release_control_cmd(avrcp_connection_t * connection){
connection->state = AVCTP_W2_SEND_RELEASE_COMMAND;
connection->transaction_label++;
switch (connection->cmd_operands[0]){
case AVRCP_OPERATION_ID_REWIND:
case AVRCP_OPERATION_ID_FAST_FORWARD:
avrcp_press_and_hold_timer_stop(connection);
break;
default:
break;
}
connection->cmd_operands[0] = 0x80 | connection->cmd_operands[0];
connection->transaction_label++;
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
}
@ -308,8 +337,6 @@ static void request_pass_through_press_control_cmd(uint16_t con_handle, avrcp_op
}
if (connection->state != AVCTP_CONNECTION_OPENED) return;
connection->state = AVCTP_W2_SEND_PRESS_COMMAND;
connection->transaction_label++;
connection->cmd_to_send = AVRCP_CMD_OPCODE_PASS_THROUGH;
connection->command_type = AVRCP_CTYPE_CONTROL;
connection->subunit_type = AVRCP_SUBUNIT_TYPE_PANEL;
@ -323,6 +350,16 @@ static void request_pass_through_press_control_cmd(uint16_t con_handle, avrcp_op
connection->cmd_operands_lenght++;
}
connection->cmd_operands[1] = connection->cmd_operands_lenght - 2;
switch (connection->cmd_operands[0]){
case AVRCP_OPERATION_ID_REWIND:
case AVRCP_OPERATION_ID_FAST_FORWARD:
avrcp_press_and_hold_timer_start(connection);
break;
default:
break;
}
connection->transaction_label++;
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
}
@ -354,8 +391,16 @@ static int avrcp_send_cmd(uint16_t cid, avrcp_connection_t * connection){
static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connection_t * connection, uint8_t *packet, uint16_t size){
switch (connection->state){
case AVCTP_W2_RECEIVE_PRESS_RESPONSE:
switch (connection->cmd_operands[0]){
case AVRCP_OPERATION_ID_REWIND:
case AVRCP_OPERATION_ID_FAST_FORWARD:
connection->state = AVCTP_W4_STOP;
break;
default:
connection->state = AVCTP_W2_SEND_RELEASE_COMMAND;
break;
}
break;
case AVCTP_W2_RECEIVE_RESPONSE:
connection->state = AVCTP_CONNECTION_OPENED;
break;
@ -601,14 +646,6 @@ void avrcp_pause(uint16_t con_handle){
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_PAUSE, 0);
}
void avrcp_rewind(uint16_t con_handle){
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_REWIND, 0);
}
void avrcp_fast_forward(uint16_t con_handle){
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
}
void avrcp_forward(uint16_t con_handle){
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_FORWARD, 0);
}
@ -616,3 +653,31 @@ void avrcp_forward(uint16_t con_handle){
void avrcp_backward(uint16_t con_handle){
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_BACKWARD, 0);
}
void avrcp_start_rewind(uint16_t con_handle){
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_REWIND, 0);
}
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.");
return;
}
if (connection->state != AVCTP_W4_STOP) return;
request_pass_through_release_control_cmd(connection);
}
void avrcp_start_fast_forward(uint16_t con_handle){
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
}
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.");
return;
}
if (connection->state != AVCTP_W4_STOP) return;
request_pass_through_release_control_cmd(connection);
}

View File

@ -126,6 +126,7 @@ typedef enum {
AVCTP_CONNECTION_OPENED,
AVCTP_W2_SEND_PRESS_COMMAND,
AVCTP_W2_SEND_RELEASE_COMMAND,
AVCTP_W4_STOP,
AVCTP_W2_SEND_COMMAND,
AVCTP_W2_RECEIVE_PRESS_RESPONSE,
AVCTP_W2_RECEIVE_RESPONSE,
@ -149,6 +150,7 @@ typedef struct {
avrcp_subunit_id_t subunit_id;
uint8_t cmd_operands[20];
uint8_t cmd_operands_lenght;
btstack_timer_source_t press_and_hold_cmd_timer;
} avrcp_connection_t;
/**
@ -225,13 +227,15 @@ void avrcp_pause(uint16_t con_handle);
* @brief Fast forward.
* @param con_handle
*/
void avrcp_fast_forward(uint16_t con_handle);
void avrcp_start_fast_forward(uint16_t con_handle);
void avrcp_stop_fast_forward(uint16_t con_handle);
/**
* @brief Rewind.
* @param con_handle
*/
void avrcp_rewind(uint16_t con_handle);
void avrcp_start_rewind(uint16_t con_handle);
void avrcp_stop_rewind(uint16_t con_handle);
/**
* @brief Forward.

View File

@ -119,7 +119,8 @@ static void show_usage(void){
printf("s - avrcp_stop\n");
printf("p - avrcp_pause\n");
printf("w - avrcp_fast_forward\n");
printf("r - avrcp_rewind\n");
printf("r - avrcp_start_rewind\n");
printf("R - avrcp_stop_rewind\n");
printf("f - avrcp_forward\n");
printf("b - avrcp_backward\n");
printf("Ctrl-c - exit\n");
@ -152,10 +153,16 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac
avrcp_pause(con_handle);
break;
case 'w':
avrcp_fast_forward(con_handle);
avrcp_start_fast_forward(con_handle);
break;
case 'W':
avrcp_stop_fast_forward(con_handle);
break;
case 'r':
avrcp_rewind(con_handle);
avrcp_start_rewind(con_handle);
break;
case 'R':
avrcp_stop_rewind(con_handle);
break;
case 'f':
avrcp_forward(con_handle);