mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 13:20:39 +00:00
hfp: support ECC
This commit is contained in:
parent
0268f3d369
commit
4b60c8c50d
31
src/hfp.c
31
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){
|
static void parse_sequence(hfp_connection_t * context){
|
||||||
int value;
|
int value;
|
||||||
switch (context->command){
|
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:
|
case HFP_CMD_SET_MICROPHONE_GAIN:
|
||||||
value = atoi((char *)&context->line_buffer[0]);
|
value = atoi((char *)&context->line_buffer[0]);
|
||||||
context->microphone_gain = value;
|
context->microphone_gain = value;
|
||||||
|
10
src/hfp.h
10
src/hfp.h
@ -563,8 +563,11 @@ typedef struct hfp_connection {
|
|||||||
uint8_t hf_send_chld_2;
|
uint8_t hf_send_chld_2;
|
||||||
uint8_t hf_send_chld_3;
|
uint8_t hf_send_chld_3;
|
||||||
uint8_t hf_send_chld_4;
|
uint8_t hf_send_chld_4;
|
||||||
|
uint8_t hf_send_chld_x;
|
||||||
|
uint8_t hf_send_chld_x_index;
|
||||||
char hf_send_dtmf_code;
|
char hf_send_dtmf_code;
|
||||||
uint8_t hf_send_binp;
|
uint8_t hf_send_binp;
|
||||||
|
uint8_t hf_send_clcc;
|
||||||
uint8_t hf_activate_call_waiting_notification;
|
uint8_t hf_activate_call_waiting_notification;
|
||||||
uint8_t hf_deactivate_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_activate_voice_recognition_notification;
|
||||||
uint8_t hf_deactivate_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
|
uint8_t bnip_type; // 0 == not set
|
||||||
char bnip_number[25]; //
|
char bnip_number[25]; //
|
||||||
|
|
||||||
|
63
src/hfp_hf.c
63
src/hfp_hf.c
@ -319,6 +319,12 @@ static int hfp_hf_send_binp(uint16_t cid){
|
|||||||
return send_str_over_rfcomm(cid, buffer);
|
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){
|
static void hfp_emit_ag_indicator_event(hfp_callback_t callback, int status, hfp_ag_indicator_t indicator){
|
||||||
if (!callback) return;
|
if (!callback) return;
|
||||||
uint8_t event[6+HFP_MAX_INDICATOR_DESC_SIZE+1];
|
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;
|
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){
|
if (context->hf_send_dtmf_code){
|
||||||
char code = context->hf_send_dtmf_code;
|
char code = context->hf_send_dtmf_code;
|
||||||
context->hf_send_dtmf_code = 0;
|
context->hf_send_dtmf_code = 0;
|
||||||
@ -694,6 +707,13 @@ static void hfp_run_for_context(hfp_connection_t * context){
|
|||||||
return;
|
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;
|
if (done) return;
|
||||||
// deal with disconnect
|
// deal with disconnect
|
||||||
switch (context->state){
|
switch (context->state){
|
||||||
@ -853,6 +873,11 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (context->command){
|
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:
|
case HFP_CMD_SET_SPEAKER_GAIN:
|
||||||
context->command = HFP_CMD_NONE;
|
context->command = HFP_CMD_NONE;
|
||||||
value = atoi((char*)context->line_buffer);
|
value = atoi((char*)context->line_buffer);
|
||||||
@ -1176,10 +1201,29 @@ void hfp_hf_connect_calls(bd_addr_t addr){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void hfp_hf_release_call_with_index(bd_addr_t addr, int index){
|
||||||
* @brief
|
hfp_hf_establish_service_level_connection(addr);
|
||||||
*/
|
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr);
|
||||||
void hfp_hf_connect_calls(bd_addr_t 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){
|
void hfp_hf_dial_number(bd_addr_t bd_addr, char * number){
|
||||||
hfp_hf_establish_service_level_connection(bd_addr);
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
15
src/hfp_hf.h
15
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);
|
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 */
|
/* API_END */
|
||||||
|
|
||||||
#if defined __cplusplus
|
#if defined __cplusplus
|
||||||
|
@ -153,6 +153,9 @@ static void show_usage(void){
|
|||||||
printf("0123456789#*-+ - send DTMF dial tones\n");
|
printf("0123456789#*-+ - send DTMF dial tones\n");
|
||||||
|
|
||||||
printf("x - request phone number for voice tag\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("---\n");
|
||||||
printf("Ctrl-c - exit\n");
|
printf("Ctrl-c - exit\n");
|
||||||
@ -235,10 +238,6 @@ static int stdin_process(struct data_source *ds){
|
|||||||
printf("Terminate HCI connection.\n");
|
printf("Terminate HCI connection.\n");
|
||||||
gap_disconnect(handle);
|
gap_disconnect(handle);
|
||||||
break;
|
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':
|
case 'i':
|
||||||
printf("Dial 1234567\n");
|
printf("Dial 1234567\n");
|
||||||
hfp_hf_dial_number(device_addr, "1234567");
|
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");
|
printf("Request phone number for voice tag\n");
|
||||||
hfp_hf_request_phone_number_for_voice_tag(device_addr);
|
hfp_hf_request_phone_number_for_voice_tag(device_addr);
|
||||||
break;
|
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:
|
default:
|
||||||
show_usage();
|
show_usage();
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user