mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-25 16:43:28 +00:00
hfp: transfer status call, callsetup, callheld
This commit is contained in:
parent
7a4980db5e
commit
374724f4ef
20
src/hfp.h
20
src/hfp.h
@ -177,6 +177,24 @@ typedef enum {
|
||||
HFP_CME_ERROR_NETWORK_NOT_ALLOWED_EMERGENCY_CALLS_ONLY
|
||||
} hfp_cme_error_t;
|
||||
|
||||
typedef enum {
|
||||
HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS = 0,
|
||||
HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT
|
||||
} hfp_call_status_t;
|
||||
|
||||
typedef enum {
|
||||
HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS = 0,
|
||||
HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS,
|
||||
HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_DIALING_STATE,
|
||||
HFP_CALLSETUP_STATUS_OUTGOING_CALL_SETUP_IN_ALERTING_STATE
|
||||
} hfp_callsetup_status_t;
|
||||
|
||||
typedef enum {
|
||||
HFP_HELDCALL_STATUS_NO_CALLS_HELD = 0,
|
||||
HFP_HELDCALL_STATUS_CALL_ON_HOLD_OR_SWAPPED,
|
||||
HFP_HELDCALL_STATUS_CALL_ON_HOLD_AND_NO_ACTIVE_CALLS
|
||||
} hfp_callheld_status_t;
|
||||
|
||||
typedef enum {
|
||||
HFP_PARSER_CMD_HEADER = 0,
|
||||
HFP_PARSER_CMD_SEQUENCE,
|
||||
@ -287,6 +305,7 @@ typedef struct hfp_connection {
|
||||
int generic_status_indicators_nr;
|
||||
hfp_generic_status_indicator_t generic_status_indicators[HFP_MAX_INDICATOR_DESC_SIZE];
|
||||
uint8_t enable_status_update_for_ag_indicators;
|
||||
|
||||
uint32_t ag_indicators_status_update_bitmap;
|
||||
hfp_network_opearator_t network_operator;
|
||||
|
||||
@ -316,6 +335,7 @@ typedef struct hfp_connection {
|
||||
uint8_t enable_extended_audio_gateway_error_report;
|
||||
uint8_t extended_audio_gateway_error;
|
||||
|
||||
|
||||
} hfp_connection_t;
|
||||
|
||||
// UTILS_START : TODO move to utils
|
||||
|
49
src/hfp_ag.c
49
src/hfp_ag.c
@ -110,6 +110,23 @@ void hfp_ag_register_packet_handler(hfp_callback_t callback){
|
||||
hfp_callback = callback;
|
||||
}
|
||||
|
||||
static uint8_t hfp_get_indicator_index_by_name(hfp_connection_t * context, const char * name){
|
||||
int i;
|
||||
for (i=0; i<context->ag_indicators_nr; i++){
|
||||
if (strcmp(context->ag_indicators[i].name, name) == 0){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
static void hfp_ag_update_indicator_status(hfp_connection_t * context, const char * indicator_name, uint8_t status){
|
||||
int index = hfp_get_indicator_index_by_name(context, indicator_name);
|
||||
if (index == 0xFF) return;
|
||||
if (context->ag_indicators[index].status == status) return;
|
||||
context->ag_indicators[index].status = status;
|
||||
context->ag_indicators[index].status_changed = 1;
|
||||
}
|
||||
|
||||
static int has_codec_negotiation_feature(hfp_connection_t * connection){
|
||||
int hf = get_bit(connection->remote_supported_features, HFP_HFSF_CODEC_NEGOTIATION);
|
||||
@ -123,7 +140,6 @@ static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * connecti
|
||||
return hf && ag;
|
||||
}
|
||||
|
||||
|
||||
static int has_hf_indicators_feature(hfp_connection_t * connection){
|
||||
int hf = get_bit(connection->remote_supported_features, HFP_HFSF_HF_INDICATORS);
|
||||
int ag = get_bit(hfp_supported_features, HFP_AGSF_HF_INDICATORS);
|
||||
@ -606,3 +622,34 @@ void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, h
|
||||
connection->extended_audio_gateway_error = error;
|
||||
hfp_run_for_context(connection);
|
||||
}
|
||||
|
||||
void hfp_ag_transfer_call_status(bd_addr_t bd_addr, hfp_callsetup_status_t status){
|
||||
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
|
||||
if (!connection){
|
||||
log_error("HFP HF: connection doesn't exist.");
|
||||
return;
|
||||
}
|
||||
if (!connection->enable_status_update_for_ag_indicators) return;
|
||||
hfp_ag_update_indicator_status(connection, (char *)"call", status);
|
||||
}
|
||||
|
||||
void hfp_ag_transfer_callsetup_status(bd_addr_t bd_addr, hfp_callsetup_status_t status){
|
||||
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
|
||||
if (!connection){
|
||||
log_error("HFP HF: connection doesn't exist.");
|
||||
return;
|
||||
}
|
||||
if (!connection->enable_status_update_for_ag_indicators) return;
|
||||
hfp_ag_update_indicator_status(connection, (char *)"callsetup", status);
|
||||
}
|
||||
|
||||
void hfp_ag_transfer_callheld_status(bd_addr_t bd_addr, hfp_callheld_status_t status){
|
||||
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
|
||||
if (!connection){
|
||||
log_error("HFP HF: connection doesn't exist.");
|
||||
return;
|
||||
}
|
||||
if (!connection->enable_status_update_for_ag_indicators) return;
|
||||
hfp_ag_update_indicator_status(connection, (char *)"callheld", status);
|
||||
hfp_run_for_context(connection);
|
||||
}
|
||||
|
27
src/hfp_ag.h
27
src/hfp_ag.h
@ -122,6 +122,33 @@ void hfp_ag_release_service_level_connection(bd_addr_t bd_addr);
|
||||
*/
|
||||
void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error);
|
||||
|
||||
/**
|
||||
* @brief Report the change in AG's call status.
|
||||
* Call status:
|
||||
* - 0 = No calls (held or active)
|
||||
* - 1 = Call is present (active or held)
|
||||
*/
|
||||
void hfp_ag_transfer_call_status(bd_addr_t bd_addr, uint8_t index, hfp_call_status_t status);
|
||||
|
||||
/**
|
||||
* @brief Report the change in AG's call setup status.
|
||||
* Call setup status:
|
||||
* - 0 = No call setup in progress
|
||||
* - 1 = Incoming call setup in progress
|
||||
* - 2 = Outgoing call setup in dialing state
|
||||
* - 3 = Outgoing call setup in alerting state
|
||||
*/
|
||||
void hfp_ag_transfer_callsetup_status(bd_addr_t bd_addr, uint8_t index, hfp_callsetup_status_t status);
|
||||
|
||||
/**
|
||||
* @brief Report the change in AG's held call status.
|
||||
* Held call status:
|
||||
* - 0 = No calls held
|
||||
* - 1 = Call is placed on hold or active/held calls are swapped
|
||||
* - 2 = Call on hold, no active calls
|
||||
*/
|
||||
void hfp_ag_transfer_callheld_status(bd_addr_t bd_addr, uint8_t index, hfp_callheld_status_t status);
|
||||
|
||||
|
||||
/* API_END */
|
||||
|
||||
|
@ -138,6 +138,7 @@ void hfp_hf_query_operator_selection(bd_addr_t bd_addr);
|
||||
void hfp_hf_enable_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, uint8_t enable);
|
||||
|
||||
|
||||
|
||||
/* API_END */
|
||||
|
||||
#if defined __cplusplus
|
||||
|
@ -60,6 +60,10 @@ static hfp_ag_indicator_t hfp_ag_indicators[] = {
|
||||
{6, "roam", 0, 1, 0, 0, 0, 0},
|
||||
{7, "callheld", 0, 2, 0, 1, 1, 0}
|
||||
};
|
||||
static uint8_t call_status_index = 2;
|
||||
static uint8_t callsetup_status_index = 3;
|
||||
static uint8_t callheld_status_index = 7;
|
||||
|
||||
|
||||
TEST_GROUP(HFPParser){
|
||||
char packet[200];
|
||||
@ -241,6 +245,40 @@ TEST(HFPParser, HFP_HF_EXTENDED_AUDIO_GATEWAY_ERROR){
|
||||
CHECK_EQUAL(context.extended_audio_gateway_error, HFP_CME_ERROR_NO_NETWORK_SERVICE);
|
||||
}
|
||||
|
||||
|
||||
TEST(HFPParser, HFP_HF_AG_INDICATOR_CALLS_STATUS_UPDATE){
|
||||
context.ag_indicators_nr = hfp_ag_indicators_nr;
|
||||
memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t));
|
||||
uint8_t status = 1;
|
||||
|
||||
// call status
|
||||
uint8_t index = call_status_index;
|
||||
sprintf(packet, "\r\n%s:%d,%d\r\n\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status);
|
||||
for (pos = 0; pos < strlen(packet); pos++){
|
||||
hfp_parse(&context, packet[pos]);
|
||||
}
|
||||
CHECK_EQUAL(HFP_CMD_OK, context.command);
|
||||
CHECK_EQUAL(context.ag_indicators[index - 1].status, status);
|
||||
|
||||
// callsetup status
|
||||
index = callsetup_status_index;
|
||||
sprintf(packet, "\r\n%s:%d,%d\r\n\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status);
|
||||
for (pos = 0; pos < strlen(packet); pos++){
|
||||
hfp_parse(&context, packet[pos]);
|
||||
}
|
||||
CHECK_EQUAL(HFP_CMD_OK, context.command);
|
||||
CHECK_EQUAL(context.ag_indicators[index - 1].status, status);
|
||||
|
||||
// callheld status
|
||||
index = callheld_status_index;
|
||||
sprintf(packet, "\r\n%s:%d,%d\r\n\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status);
|
||||
for (pos = 0; pos < strlen(packet); pos++){
|
||||
hfp_parse(&context, packet[pos]);
|
||||
}
|
||||
CHECK_EQUAL(HFP_CMD_OK, context.command);
|
||||
CHECK_EQUAL(context.ag_indicators[index - 1].status, status);
|
||||
}
|
||||
|
||||
int main (int argc, const char * argv[]){
|
||||
return CommandLineTestRunner::RunAllTests(argc, argv);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user