diff --git a/src/hfp.c b/src/hfp.c index fc537ca5a..e5207a8ac 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -1066,6 +1066,37 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){ static void parse_sequence(hfp_connection_t * context){ int value; switch (context->command){ + case HFP_CMD_LIST_CURRENT_CALLS: + switch(context->parser_item_index){ + case 0: + value = atoi((char *)&context->line_buffer[0]); + context->clcc_idx = value; + break; + case 1: + value = atoi((char *)&context->line_buffer[0]); + context->clcc_dir = value; + break; + case 2: + value = atoi((char *)&context->line_buffer[0]); + context->clcc_status = value; + break; + case 3: + value = atoi((char *)&context->line_buffer[0]); + context->clcc_mpty = value; + break; + case 4: + strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); + context->bnip_number[sizeof(context->bnip_number)-1] = 0; + break; + case 5: + value = atoi((char *)&context->line_buffer[0]); + context->bnip_type = value; + break; + default: + break; + } + context->parser_item_index++; + break; case HFP_CMD_SET_MICROPHONE_GAIN: value = atoi((char *)&context->line_buffer[0]); context->microphone_gain = value; diff --git a/src/hfp.h b/src/hfp.h index 57babe29f..8decf2401 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -563,8 +563,11 @@ typedef struct hfp_connection { uint8_t hf_send_chld_2; uint8_t hf_send_chld_3; uint8_t hf_send_chld_4; + uint8_t hf_send_chld_x; + uint8_t hf_send_chld_x_index; char hf_send_dtmf_code; uint8_t hf_send_binp; + uint8_t hf_send_clcc; uint8_t hf_activate_call_waiting_notification; uint8_t hf_deactivate_call_waiting_notification; @@ -575,6 +578,13 @@ typedef struct hfp_connection { uint8_t hf_activate_voice_recognition_notification; uint8_t hf_deactivate_voice_recognition_notification; + uint8_t clcc_idx; + uint8_t clcc_dir; + uint8_t clcc_status; + uint8_t clcc_mode; + uint8_t clcc_mpty; + + // also used for CLCC if set uint8_t bnip_type; // 0 == not set char bnip_number[25]; // diff --git a/src/hfp_hf.c b/src/hfp_hf.c index ff8ffb757..0532f9f9b 100644 --- a/src/hfp_hf.c +++ b/src/hfp_hf.c @@ -319,6 +319,12 @@ static int hfp_hf_send_binp(uint16_t cid){ return send_str_over_rfcomm(cid, buffer); } +static int hfp_hf_send_clcc(uint16_t cid){ + char buffer[20]; + sprintf(buffer, "AT%s\r\n", HFP_LIST_CURRENT_CALLS); + 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]; @@ -679,6 +685,13 @@ static void hfp_run_for_context(hfp_connection_t * context){ return; } + if (context->hf_send_chld_x){ + context->hf_send_chld_x = 0; + context->ok_pending = 1; + hfp_hf_send_chld(context->rfcomm_cid, context->hf_send_chld_x_index); + return; + } + if (context->hf_send_dtmf_code){ char code = context->hf_send_dtmf_code; context->hf_send_dtmf_code = 0; @@ -694,6 +707,13 @@ static void hfp_run_for_context(hfp_connection_t * context){ return; } + if (context->hf_send_clcc){ + context->hf_send_clcc = 0; + context->ok_pending = 1; + hfp_hf_send_clcc(context->rfcomm_cid); + return; + } + if (done) return; // deal with disconnect switch (context->state){ @@ -853,6 +873,11 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8 } switch (context->command){ + case HFP_CMD_LIST_CURRENT_CALLS: + printf("Enhanced Call Status: idx %u, dir %u, status %u, mpty %u, number %s, type %u\n", + context->clcc_idx, context->clcc_dir, context->clcc_status, context->clcc_mpty, + context->bnip_number, context->bnip_type); + break; case HFP_CMD_SET_SPEAKER_GAIN: context->command = HFP_CMD_NONE; value = atoi((char*)context->line_buffer); @@ -1176,10 +1201,29 @@ void hfp_hf_connect_calls(bd_addr_t addr){ } } -/** - * @brief - */ -void hfp_hf_connect_calls(bd_addr_t addr); +void hfp_hf_release_call_with_index(bd_addr_t addr, int index){ + 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_x = 1; + connection->hf_send_chld_x_index = 10 + index; + hfp_run_for_context(connection); + } +} + +void hfp_hf_private_consultation_with_call(bd_addr_t addr, int index){ + 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_x = 1; + connection->hf_send_chld_x_index = 20 + index; + hfp_run_for_context(connection); + } +} void hfp_hf_dial_number(bd_addr_t bd_addr, char * number){ hfp_hf_establish_service_level_connection(bd_addr); @@ -1335,3 +1379,14 @@ void hfp_hf_request_phone_number_for_voice_tag(bd_addr_t addr){ hfp_run_for_context(connection); } +/* + * @brief + */ +void hfp_hf_query_current_call_status(bd_addr_t addr){ + hfp_hf_establish_service_level_connection(addr); + hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + connection->hf_send_clcc = 1; + hfp_run_for_context(connection); +} + + diff --git a/src/hfp_hf.h b/src/hfp_hf.h index 7a95b219b..ccf2a6686 100644 --- a/src/hfp_hf.h +++ b/src/hfp_hf.h @@ -265,6 +265,21 @@ void hfp_hf_send_dtmf_code(bd_addr_t bd_addr, char code); */ void hfp_hf_request_phone_number_for_voice_tag(bd_addr_t addr); +/* + * @brief + */ +void hfp_hf_query_current_call_status(bd_addr_t addr); + +/* + * @brief + */ +void hfp_hf_release_call_with_index(bd_addr_t addr, int index); + +/* + * @brief + */ +void hfp_hf_private_consultation_with_call(bd_addr_t addr, int index); + /* API_END */ #if defined __cplusplus diff --git a/test/pts/hfp_hf_test.c b/test/pts/hfp_hf_test.c index 5bf3c7061..bb3e788e8 100644 --- a/test/pts/hfp_hf_test.c +++ b/test/pts/hfp_hf_test.c @@ -153,6 +153,9 @@ static void show_usage(void){ printf("0123456789#*-+ - send DTMF dial tones\n"); printf("x - request phone number for voice tag\n"); + printf("X - current call status\n"); + printf("y - release call with index 2 (ECC)\n"); + printf("Y - private consulation with call 2(ECC)\n"); printf("---\n"); printf("Ctrl-c - exit\n"); @@ -235,10 +238,6 @@ static int stdin_process(struct data_source *ds){ printf("Terminate HCI connection.\n"); gap_disconnect(handle); break; - case 'y': - memcpy(device_addr, phone_addr, 6); - printf("Use iPhone %s as Audiogateway.\n", bd_addr_to_str(device_addr)); - break; case 'i': printf("Dial 1234567\n"); hfp_hf_dial_number(device_addr, "1234567"); @@ -347,6 +346,22 @@ static int stdin_process(struct data_source *ds){ printf("Request phone number for voice tag\n"); hfp_hf_request_phone_number_for_voice_tag(device_addr); break; + case 'X': + printf("Query current call status\n"); + hfp_hf_query_current_call_status(device_addr); + break; + case 'y': + printf("Release call with index 2\n"); + hfp_hf_release_call_with_index(device_addr, 2); + break; + case 'Y': + printf("Private consulation with call 2\n"); + hfp_hf_private_consultation_with_call(device_addr, 2); + break; + case 'z': + memcpy(device_addr, phone_addr, 6); + printf("Use iPhone %s as Audiogateway.\n", bd_addr_to_str(device_addr)); + break; default: show_usage(); break;