hfp: support three-way calls in HF tester

This commit is contained in:
Matthias Ringwald 2015-11-28 11:13:50 +01:00
parent 65323bbc45
commit 26fa4657e8
4 changed files with 165 additions and 4 deletions

View File

@ -558,6 +558,11 @@ typedef struct hfp_connection {
uint8_t hf_send_clip_enable;
uint8_t hf_send_chup;
uint8_t hf_send_chld_0;
uint8_t hf_send_chld_1;
uint8_t hf_send_chld_2;
uint8_t hf_send_chld_3;
uint8_t hf_send_chld_4;
uint8_t hf_activate_call_waiting_notification;
uint8_t hf_deactivate_call_waiting_notification;

View File

@ -298,6 +298,12 @@ static int hfp_hf_send_chup(uint16_t cid){
return send_str_over_rfcomm(cid, buffer);
}
static int hfp_hf_send_chld(uint16_t cid, int number){
char buffer[20];
sprintf(buffer, "AT%s=%u\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, number);
return send_str_over_rfcomm(cid, buffer);
}
static void hfp_emit_ag_indicator_event(hfp_callback_t callback, int status, hfp_ag_indicator_t indicator){
if (!callback) return;
uint8_t event[6+HFP_MAX_INDICATOR_DESC_SIZE+1];
@ -623,6 +629,41 @@ static void hfp_run_for_context(hfp_connection_t * context){
return;
}
if (context->hf_send_chld_0){
context->hf_send_chld_0 = 0;
context->ok_pending = 1;
hfp_hf_send_chld(context->rfcomm_cid, 0);
return;
}
if (context->hf_send_chld_1){
context->hf_send_chld_1 = 0;
context->ok_pending = 1;
hfp_hf_send_chld(context->rfcomm_cid, 1);
return;
}
if (context->hf_send_chld_2){
context->hf_send_chld_2 = 0;
context->ok_pending = 1;
hfp_hf_send_chld(context->rfcomm_cid, 2);
return;
}
if (context->hf_send_chld_3){
context->hf_send_chld_3 = 0;
context->ok_pending = 1;
hfp_hf_send_chld(context->rfcomm_cid, 3);
return;
}
if (context->hf_send_chld_4){
context->hf_send_chld_4 = 0;
context->ok_pending = 1;
hfp_hf_send_chld(context->rfcomm_cid, 4);
return;
}
if (done) return;
// deal with disconnect
switch (context->state){
@ -1027,6 +1068,65 @@ void hfp_hf_reject_call(bd_addr_t bd_addr){
}
}
void hfp_hf_user_busy(bd_addr_t addr){
hfp_hf_establish_service_level_connection(addr);
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){
connection->hf_send_chld_0 = 1;
hfp_run_for_context(connection);
}
}
void hfp_hf_end_active_and_accept_other(bd_addr_t addr){
hfp_hf_establish_service_level_connection(addr);
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
connection->hf_send_chld_1 = 1;
hfp_run_for_context(connection);
}
}
void hfp_hf_swap_calls(bd_addr_t addr){
hfp_hf_establish_service_level_connection(addr);
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
connection->hf_send_chld_2 = 1;
hfp_run_for_context(connection);
}
}
void hfp_hf_join_held_call(bd_addr_t addr){
hfp_hf_establish_service_level_connection(addr);
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
connection->hf_send_chld_3 = 1;
hfp_run_for_context(connection);
}
}
void hfp_hf_connect_calls(bd_addr_t addr){
hfp_hf_establish_service_level_connection(addr);
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
if (hfp_callsetup_status == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS ||
hfp_call_status == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
connection->hf_send_chld_4 = 1;
hfp_run_for_context(connection);
}
}
/**
* @brief
*/
void hfp_hf_connect_calls(bd_addr_t addr);
void hfp_hf_dial_number(bd_addr_t bd_addr, char * number){
hfp_hf_establish_service_level_connection(bd_addr);
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);

View File

@ -159,6 +159,31 @@ void hfp_hf_answer_incoming_call(bd_addr_t bd_addr);
*/
void hfp_hf_reject_call(bd_addr_t bd_addr);
/**
* @brief
*/
void hfp_hf_user_busy(bd_addr_t addr);
/**
* @brief
*/
void hfp_hf_end_active_and_accept_other(bd_addr_t addr);
/**
* @brief
*/
void hfp_hf_swap_calls(bd_addr_t addr);
/**
* @brief
*/
void hfp_hf_join_held_call(bd_addr_t addr);
/**
* @brief
*/
void hfp_hf_connect_calls(bd_addr_t addr);
/**
* @brief
*/

View File

@ -115,7 +115,7 @@ static void show_usage(void){
printf("G - reject call\n");
printf("i - dial 1234567\n");
printf("I - redial\n");
printf("I - dial 7654321\n");
printf("j - dial #1\n");
printf("J - dial #99\n");
@ -141,9 +141,16 @@ static void show_usage(void){
printf("Q - Set microphone gain to 9 (default)\n");
printf("s - Set microphone gain to 12 (higher)\n");
printf("S - Set microphone gain to 15 (maximum)\n");
printf("t - terminate connection\n");
printf("u - send 'user busy' (Three-Way Call 0)\n");
printf("U - end active call and accept other call' (Three-Way Call 1)\n");
printf("v - Swap active call and hold/waiting call (Three-Way Call 2)\n");
printf("V - Join held call (Three-Way Call 3)\n");
printf("w - Connect calls (Three-Way Call 4)\n");
printf("W - redial\n");
printf("---\n");
printf("Ctrl-c - exit\n");
printf("---\n");
@ -220,8 +227,8 @@ static int stdin_process(struct data_source *ds){
hfp_hf_dial_number(device_addr, "1234567");
break;
case 'I':
printf("Redial\n");
hfp_hf_redial_last_number(device_addr);
printf("Dial 7654321\n");
hfp_hf_dial_number(device_addr, "7654321");
break;
case 'j':
printf("Dial #1\n");
@ -287,6 +294,30 @@ static int stdin_process(struct data_source *ds){
printf("Set microphone gain to 9\n");
hfp_hf_set_microphone_gain(device_addr, 9);
break;
case 'u':
printf("Send 'user busy' (Three-Way Call 0)\n");
hfp_hf_user_busy(device_addr);
break;
case 'U':
printf("End active call and accept waiting/held call (Three-Way Call 1)\n");
hfp_hf_end_active_and_accept_other(device_addr);
break;
case 'v':
printf("Swap active call and hold/waiting call (Three-Way Call 2)\n");
hfp_hf_swap_calls(device_addr);
break;
case 'V':
printf("Join hold call (Three-Way Call 3)\n");
hfp_hf_join_held_call(device_addr);
break;
case 'w':
printf("Connect calls (Three-Way Call 4)\n");
hfp_hf_connect_calls(device_addr);
break;
case 'W':
printf("Redial\n");
hfp_hf_redial_last_number(device_addr);
break;
default:
show_usage();
break;