mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-23 02:42:36 +00:00
hfp: report extended AG error result code
This commit is contained in:
parent
d89553ebba
commit
8ca6f17bb0
@ -625,6 +625,7 @@ extern "C" {
|
|||||||
#define HFP_SUBEVENT_COMPLETE 0x03
|
#define HFP_SUBEVENT_COMPLETE 0x03
|
||||||
#define HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED 0x04
|
#define HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED 0x04
|
||||||
#define HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED 0x05
|
#define HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED 0x05
|
||||||
|
#define HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR 0x06
|
||||||
|
|
||||||
// ANCS Client
|
// ANCS Client
|
||||||
#define ANCS_CLIENT_CONNECTED 0xF0
|
#define ANCS_CLIENT_CONNECTED 0xF0
|
||||||
|
28
src/hfp.c
28
src/hfp.c
@ -509,7 +509,7 @@ void process_command(hfp_connection_t * context){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp((char *)context->line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){
|
if (isHandsFree && strncmp((char *)context->line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){
|
||||||
//printf("parsed HFP_CMD_OK \n");
|
//printf("parsed HFP_CMD_OK \n");
|
||||||
context->command = HFP_CMD_OK;
|
context->command = HFP_CMD_OK;
|
||||||
return;
|
return;
|
||||||
@ -593,6 +593,19 @@ void process_command(hfp_connection_t * context){
|
|||||||
context->command = HFP_CMD_TRANSFER_AG_INDICATOR_STATUS;
|
context->command = HFP_CMD_TRANSFER_AG_INDICATOR_STATUS;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isHandsFree && strncmp((char *)context->line_buffer+offset, HFP_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){
|
||||||
|
printf(" process command 1 %s \n", context->line_buffer);
|
||||||
|
context->command = HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isHandsFree && strncmp((char *)context->line_buffer+offset, HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){
|
||||||
|
printf(" process command 2 %s \n", context->line_buffer);
|
||||||
|
context->command = HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf(" process unknown command 3 %s \n", context->line_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fromBinary(char *s) {
|
uint32_t fromBinary(char *s) {
|
||||||
@ -679,7 +692,7 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
|
|||||||
int value;
|
int value;
|
||||||
|
|
||||||
// TODO: handle space inside word
|
// TODO: handle space inside word
|
||||||
if (byte == ' ') return;
|
if (byte == ' ' && context->parser_state > HFP_PARSER_CMD_HEADER) return;
|
||||||
|
|
||||||
if (!hfp_parser_found_separator(context, byte)){
|
if (!hfp_parser_found_separator(context, byte)){
|
||||||
hfp_parser_store_byte(context, byte);
|
hfp_parser_store_byte(context, byte);
|
||||||
@ -805,7 +818,16 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case HFP_CMD_ERROR:
|
||||||
|
break;
|
||||||
|
case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
|
||||||
|
context->extended_audio_gateway_error = (uint8_t)atoi((char*)context->line_buffer);
|
||||||
|
break;
|
||||||
|
case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR:
|
||||||
|
context->enable_extended_audio_gateway_error_report = (uint8_t)atoi((char*)context->line_buffer);
|
||||||
|
context->send_ok = 1;
|
||||||
|
context->extended_audio_gateway_error = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
52
src/hfp.h
52
src/hfp.h
@ -110,7 +110,8 @@ extern "C" {
|
|||||||
#define HFP_GENERIC_STATUS_INDICATOR "+BIND"
|
#define HFP_GENERIC_STATUS_INDICATOR "+BIND"
|
||||||
#define HFP_TRANSFER_AG_INDICATOR_STATUS "+CIEV" // +CIEV: <index>,<value>
|
#define HFP_TRANSFER_AG_INDICATOR_STATUS "+CIEV" // +CIEV: <index>,<value>
|
||||||
#define HFP_QUERY_OPERATOR_SELECTION "+COPS" // +COPS: <mode>,0,<opearator>
|
#define HFP_QUERY_OPERATOR_SELECTION "+COPS" // +COPS: <mode>,0,<opearator>
|
||||||
|
#define HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR "+CMEE"
|
||||||
|
#define HFP_EXTENDED_AUDIO_GATEWAY_ERROR "+CME ERROR"
|
||||||
|
|
||||||
#define HFP_OK "OK"
|
#define HFP_OK "OK"
|
||||||
#define HFP_ERROR "ERROR"
|
#define HFP_ERROR "ERROR"
|
||||||
@ -133,9 +134,49 @@ typedef enum {
|
|||||||
HFP_CMD_GENERIC_STATUS_INDICATOR,
|
HFP_CMD_GENERIC_STATUS_INDICATOR,
|
||||||
|
|
||||||
HFP_CMD_TRANSFER_AG_INDICATOR_STATUS,
|
HFP_CMD_TRANSFER_AG_INDICATOR_STATUS,
|
||||||
HFP_CMD_QUERY_OPERATOR_SELECTION
|
HFP_CMD_QUERY_OPERATOR_SELECTION,
|
||||||
|
|
||||||
|
HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR,
|
||||||
|
HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR
|
||||||
|
|
||||||
} hfp_command_t;
|
} hfp_command_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HFP_CME_ERROR_AG_FAILURE = 0,
|
||||||
|
HFP_CME_ERROR_NO_CONNECTION_TO_PHONE,
|
||||||
|
HFP_CME_ERROR_2,
|
||||||
|
HFP_CME_ERROR_OPERATION_NOT_ALLOWED,
|
||||||
|
HFP_CME_ERROR_OPERATION_NOT_SUPPORTED,
|
||||||
|
HFP_CME_ERROR_PH_SIM_PIN_REQUIRED,
|
||||||
|
HFP_CME_ERROR_6,
|
||||||
|
HFP_CME_ERROR_7,
|
||||||
|
HFP_CME_ERROR_8,
|
||||||
|
HFP_CME_ERROR_9,
|
||||||
|
HFP_CME_ERROR_SIM_NOT_INSERTED,
|
||||||
|
HFP_CME_ERROR_SIM_PIN_REQUIRED,
|
||||||
|
HFP_CME_ERROR_SIM_PUK_REQUIRED,
|
||||||
|
HFP_CME_ERROR_SIM_FAILURE,
|
||||||
|
HFP_CME_ERROR_SIM_BUSY,
|
||||||
|
HFP_CME_ERROR_15,
|
||||||
|
HFP_CME_ERROR_INCORRECT_PASSWORD,
|
||||||
|
HFP_CME_ERROR_SIM_PIN2_REQUIRED,
|
||||||
|
HFP_CME_ERROR_SIM_PUK2_REQUIRED,
|
||||||
|
HFP_CME_ERROR_19,
|
||||||
|
HFP_CME_ERROR_MEMORY_FULL,
|
||||||
|
HFP_CME_ERROR_INVALID_INDEX,
|
||||||
|
HFP_CME_ERROR_22,
|
||||||
|
HFP_CME_ERROR_MEMORY_FAILURE,
|
||||||
|
HFP_CME_ERROR_TEXT_STRING_TOO_LONG,
|
||||||
|
HFP_CME_ERROR_INVALID_CHARACTERS_IN_TEXT_STRING,
|
||||||
|
HFP_CME_ERROR_DIAL_STRING_TOO_LONG,
|
||||||
|
HFP_CME_ERROR_INVALID_CHARACTERS_IN_DIAL_STRING,
|
||||||
|
HFP_CME_ERROR_28,
|
||||||
|
HFP_CME_ERROR_29,
|
||||||
|
HFP_CME_ERROR_NO_NETWORK_SERVICE,
|
||||||
|
HFP_CME_ERROR_NETWORK_TIMEOUT,
|
||||||
|
HFP_CME_ERROR_NETWORK_NOT_ALLOWED_EMERGENCY_CALLS_ONLY
|
||||||
|
} hfp_cme_error_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HFP_PARSER_CMD_HEADER = 0,
|
HFP_PARSER_CMD_HEADER = 0,
|
||||||
HFP_PARSER_CMD_SEQUENCE,
|
HFP_PARSER_CMD_SEQUENCE,
|
||||||
@ -254,6 +295,8 @@ typedef struct hfp_connection {
|
|||||||
|
|
||||||
// TODO: put these bit flags in a bitmap
|
// TODO: put these bit flags in a bitmap
|
||||||
uint8_t wait_ok;
|
uint8_t wait_ok;
|
||||||
|
uint8_t send_ok;
|
||||||
|
uint8_t send_error;
|
||||||
|
|
||||||
uint8_t keep_separator;
|
uint8_t keep_separator;
|
||||||
|
|
||||||
@ -264,11 +307,14 @@ typedef struct hfp_connection {
|
|||||||
uint8_t retrieve_generic_status_indicators; // HFP_CMD_GENERIC_STATUS_INDICATOR
|
uint8_t retrieve_generic_status_indicators; // HFP_CMD_GENERIC_STATUS_INDICATOR
|
||||||
uint8_t retrieve_generic_status_indicators_state; // HFP_CMD_GENERIC_STATUS_INDICATOR_STATE
|
uint8_t retrieve_generic_status_indicators_state; // HFP_CMD_GENERIC_STATUS_INDICATOR_STATE
|
||||||
|
|
||||||
|
uint8_t change_status_update_for_individual_ag_indicators;
|
||||||
|
|
||||||
uint8_t operator_name_format;
|
uint8_t operator_name_format;
|
||||||
uint8_t operator_name;
|
uint8_t operator_name;
|
||||||
uint8_t operator_name_changed;
|
uint8_t operator_name_changed;
|
||||||
|
|
||||||
uint8_t change_status_update_for_individual_ag_indicators;
|
uint8_t enable_extended_audio_gateway_error_report;
|
||||||
|
uint8_t extended_audio_gateway_error;
|
||||||
|
|
||||||
} hfp_connection_t;
|
} hfp_connection_t;
|
||||||
|
|
||||||
|
42
src/hfp_ag.c
42
src/hfp_ag.c
@ -163,6 +163,12 @@ int hfp_ag_error(uint16_t cid){
|
|||||||
return send_str_over_rfcomm(cid, buffer);
|
return send_str_over_rfcomm(cid, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hfp_ag_report_extended_audio_gateway_error(uint16_t cid, uint8_t error){
|
||||||
|
char buffer[20];
|
||||||
|
sprintf(buffer, "\r\n%s=%d\r\n", HFP_EXTENDED_AUDIO_GATEWAY_ERROR, error);
|
||||||
|
return send_str_over_rfcomm(cid, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
int hfp_ag_retrieve_codec_cmd(uint16_t cid){
|
int hfp_ag_retrieve_codec_cmd(uint16_t cid){
|
||||||
return hfp_ag_ok(cid);
|
return hfp_ag_ok(cid);
|
||||||
}
|
}
|
||||||
@ -333,17 +339,36 @@ void hfp_run_for_context(hfp_connection_t *context){
|
|||||||
//printf(" hfp_run_for_context 1 state %d, command %d\n", context->state, context->command);
|
//printf(" hfp_run_for_context 1 state %d, command %d\n", context->state, context->command);
|
||||||
|
|
||||||
if (context->state == HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){
|
if (context->state == HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){
|
||||||
if (context->enable_status_update_for_ag_indicators == 1){
|
if (context->send_ok){
|
||||||
|
hfp_ag_ok(context->rfcomm_cid);
|
||||||
|
context->send_ok = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->send_error){
|
||||||
|
hfp_ag_error(context->rfcomm_cid);
|
||||||
|
context->send_error = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->enable_status_update_for_ag_indicators){
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < context->ag_indicators_nr; i++){
|
for (i = 0; i < context->ag_indicators_nr; i++){
|
||||||
if (context->ag_indicators[i].enabled == 0) continue;
|
if (context->ag_indicators[i].enabled == 0) continue;
|
||||||
if (context->ag_indicators[i].status_changed == 0) continue;
|
if (context->ag_indicators[i].status_changed == 0) continue;
|
||||||
|
|
||||||
hfp_ag_transfer_ag_indicators_status_cmd(context->rfcomm_cid, context->ag_indicators[i]);
|
hfp_ag_transfer_ag_indicators_status_cmd(context->rfcomm_cid, context->ag_indicators[i]);
|
||||||
context->ag_indicators[i].status_changed = 0;
|
context->ag_indicators[i].status_changed = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context->enable_extended_audio_gateway_error_report){
|
||||||
|
if (context->extended_audio_gateway_error){
|
||||||
|
hfp_ag_report_extended_audio_gateway_error(context->rfcomm_cid, context->extended_audio_gateway_error);
|
||||||
|
context->extended_audio_gateway_error = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(context->command){
|
switch(context->command){
|
||||||
@ -568,3 +593,16 @@ void hfp_ag_release_service_level_connection(bd_addr_t bd_addr){
|
|||||||
hfp_run_for_context(connection);
|
hfp_run_for_context(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error){
|
||||||
|
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
|
||||||
|
if (!connection){
|
||||||
|
log_error("HFP HF: connection doesn't exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connection->extended_audio_gateway_error = 0;
|
||||||
|
if (!connection->enable_extended_audio_gateway_error_report){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connection->extended_audio_gateway_error = error;
|
||||||
|
hfp_run_for_context(connection);
|
||||||
|
}
|
||||||
|
31
src/hfp_ag.h
31
src/hfp_ag.h
@ -92,6 +92,37 @@ void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr);
|
|||||||
*/
|
*/
|
||||||
void hfp_ag_release_service_level_connection(bd_addr_t bd_addr);
|
void hfp_ag_release_service_level_connection(bd_addr_t bd_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Report Extended Audio Gateway Error result codes in the AG.
|
||||||
|
* Whenever there is an error relating to the functionality of the AG as a
|
||||||
|
* result of AT command, the AG shall send +CME ERROR:
|
||||||
|
* - +CME ERROR: 0 - AG failure
|
||||||
|
* - +CME ERROR: 1 - no connection to phone
|
||||||
|
* - +CME ERROR: 3 - operation not allowed
|
||||||
|
* - +CME ERROR: 4 - operation not supported
|
||||||
|
* - +CME ERROR: 5 - PH-SIM PIN required
|
||||||
|
* - +CME ERROR: 10 - SIM not inserted
|
||||||
|
* - +CME ERROR: 11 - SIM PIN required
|
||||||
|
* - +CME ERROR: 12 - SIM PUK required
|
||||||
|
* - +CME ERROR: 13 - SIM failure
|
||||||
|
* - +CME ERROR: 14 - SIM busy
|
||||||
|
* - +CME ERROR: 16 - incorrect password
|
||||||
|
* - +CME ERROR: 17 - SIM PIN2 required
|
||||||
|
* - +CME ERROR: 18 - SIM PUK2 required
|
||||||
|
* - +CME ERROR: 20 - memory full
|
||||||
|
* - +CME ERROR: 21 - invalid index
|
||||||
|
* - +CME ERROR: 23 - memory failure
|
||||||
|
* - +CME ERROR: 24 - text string too long
|
||||||
|
* - +CME ERROR: 25 - invalid characters in text string
|
||||||
|
* - +CME ERROR: 26 - dial string too long
|
||||||
|
* - +CME ERROR: 27 - invalid characters in dial string
|
||||||
|
* - +CME ERROR: 30 - no network service
|
||||||
|
* - +CME ERROR: 31 - network Timeout.
|
||||||
|
* - +CME ERROR: 32 - network not allowed – Emergency calls only
|
||||||
|
*/
|
||||||
|
void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error);
|
||||||
|
|
||||||
|
|
||||||
/* API_END */
|
/* API_END */
|
||||||
|
|
||||||
#if defined __cplusplus
|
#if defined __cplusplus
|
||||||
|
64
src/hfp_hf.c
64
src/hfp_hf.c
@ -200,6 +200,11 @@ int hfp_hs_query_operator_name_cmd(uint16_t cid){
|
|||||||
return send_str_over_rfcomm(cid, buffer);
|
return send_str_over_rfcomm(cid, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hfp_hs_enable_extended_audio_gateway_error_report_cmd(uint16_t cid, uint8_t enable){
|
||||||
|
char buffer[20];
|
||||||
|
sprintf(buffer, "AT%s=%d\r\n", HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, enable);
|
||||||
|
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;
|
||||||
@ -289,21 +294,21 @@ static void hfp_run_for_context(hfp_connection_t * context){
|
|||||||
case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:{
|
case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < context->ag_indicators_nr; i++){
|
for (i = 0; i < context->ag_indicators_nr; i++){
|
||||||
if (context->ag_indicators[i].status_changed == 1) {
|
if (context->ag_indicators[i].status_changed) {
|
||||||
hfp_emit_ag_indicator_event(hfp_callback, 0, context->ag_indicators[i]);
|
hfp_emit_ag_indicator_event(hfp_callback, 0, context->ag_indicators[i]);
|
||||||
context->ag_indicators[i].status_changed = 0;
|
context->ag_indicators[i].status_changed = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->wait_ok == 1) return;
|
if (context->wait_ok) return;
|
||||||
|
|
||||||
if (context->enable_status_update_for_ag_indicators != 0xFF){
|
if (context->enable_status_update_for_ag_indicators != 0xFF){
|
||||||
hfp_hs_activate_status_update_for_all_ag_indicators_cmd(context->rfcomm_cid, context->enable_status_update_for_ag_indicators);
|
hfp_hs_activate_status_update_for_all_ag_indicators_cmd(context->rfcomm_cid, context->enable_status_update_for_ag_indicators);
|
||||||
context->wait_ok = 1;
|
context->wait_ok = 1;
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
if (context->change_status_update_for_individual_ag_indicators == 1){
|
if (context->change_status_update_for_individual_ag_indicators){
|
||||||
hfp_hs_activate_status_update_for_ag_indicator_cmd(context->rfcomm_cid,
|
hfp_hs_activate_status_update_for_ag_indicator_cmd(context->rfcomm_cid,
|
||||||
context->ag_indicators_status_update_bitmap,
|
context->ag_indicators_status_update_bitmap,
|
||||||
context->ag_indicators_nr);
|
context->ag_indicators_nr);
|
||||||
@ -311,15 +316,23 @@ static void hfp_run_for_context(hfp_connection_t * context){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->operator_name_format == 1){
|
if (context->operator_name_format){
|
||||||
hfp_hs_query_operator_name_format_cmd(context->rfcomm_cid);
|
hfp_hs_query_operator_name_format_cmd(context->rfcomm_cid);
|
||||||
context->wait_ok = 1;
|
context->wait_ok = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (context->operator_name == 1){
|
if (context->operator_name){
|
||||||
hfp_hs_query_operator_name_cmd(context->rfcomm_cid);
|
hfp_hs_query_operator_name_cmd(context->rfcomm_cid);
|
||||||
context->wait_ok = 1;
|
context->wait_ok = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context->enable_extended_audio_gateway_error_report){
|
||||||
|
hfp_hs_enable_extended_audio_gateway_error_report_cmd(context->rfcomm_cid, context->enable_extended_audio_gateway_error_report);
|
||||||
|
context->wait_ok = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -398,22 +411,28 @@ void handle_switch_on_ok(hfp_connection_t *context){
|
|||||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
|
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (context->change_status_update_for_individual_ag_indicators == 1){
|
if (context->change_status_update_for_individual_ag_indicators == 1){
|
||||||
context->change_status_update_for_individual_ag_indicators = 0;
|
context->change_status_update_for_individual_ag_indicators = 0;
|
||||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
|
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->operator_name_format == 1){
|
if (context->operator_name_format){
|
||||||
context->operator_name_format = 0;
|
context->operator_name_format = 0;
|
||||||
context->operator_name = 1;
|
context->operator_name = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (context->operator_name == 1){
|
|
||||||
|
if (context->operator_name){
|
||||||
context->operator_name = 0;
|
context->operator_name = 0;
|
||||||
hfp_emit_network_operator_event(hfp_callback, 0, context->network_operator);
|
hfp_emit_network_operator_event(hfp_callback, 0, context->network_operator);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (context->enable_extended_audio_gateway_error_report){
|
||||||
|
context->enable_extended_audio_gateway_error_report = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -435,14 +454,17 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8
|
|||||||
hfp_parse(context, packet[pos]);
|
hfp_parse(context, packet[pos]);
|
||||||
|
|
||||||
if (context->command == HFP_CMD_ERROR){
|
if (context->command == HFP_CMD_ERROR){
|
||||||
if (context->state == HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){
|
context->wait_ok = 0;
|
||||||
context->wait_ok = 0;
|
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1);
|
||||||
// TODO: reset state? repeat commands? restore bitmaps? get ERROR codes.
|
return;
|
||||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (context->command == HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR){
|
||||||
|
context->wait_ok = 0;
|
||||||
|
hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, context->extended_audio_gateway_error);
|
||||||
|
context->extended_audio_gateway_error = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (context->command != HFP_CMD_OK) continue;
|
if (context->command != HFP_CMD_OK) continue;
|
||||||
handle_switch_on_ok(context);
|
handle_switch_on_ok(context);
|
||||||
}
|
}
|
||||||
@ -510,7 +532,7 @@ void hfp_hf_enable_status_update_for_all_ag_indicators(bd_addr_t bd_addr, uint8_
|
|||||||
log_error("HFP HF: connection doesn't exist.");
|
log_error("HFP HF: connection doesn't exist.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
connection->enable_status_update_for_ag_indicators = 1;
|
connection->enable_status_update_for_ag_indicators = enable;
|
||||||
hfp_run_for_context(connection);
|
hfp_run_for_context(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,3 +559,15 @@ void hfp_hf_query_operator_selection(bd_addr_t bd_addr){
|
|||||||
connection->operator_name_format = 1;
|
connection->operator_name_format = 1;
|
||||||
hfp_run_for_context(connection);
|
hfp_run_for_context(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hfp_hf_enable_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, uint8_t enable){
|
||||||
|
hfp_hf_establish_service_level_connection(bd_addr);
|
||||||
|
hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
|
||||||
|
if (!connection){
|
||||||
|
log_error("HFP HF: connection doesn't exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connection->enable_extended_audio_gateway_error_report = enable;
|
||||||
|
hfp_run_for_context(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
29
src/hfp_hf.h
29
src/hfp_hf.h
@ -107,6 +107,35 @@ void hfp_hf_enable_status_update_for_individual_ag_indicators(bd_addr_t bd_addr,
|
|||||||
*/
|
*/
|
||||||
void hfp_hf_query_operator_selection(bd_addr_t bd_addr);
|
void hfp_hf_query_operator_selection(bd_addr_t bd_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable/disable Extended Audio Gateway Error result codes in the AG.
|
||||||
|
* Whenever there is an error relating to the functionality of the AG as a
|
||||||
|
* result of AT command, the AG shall send +CME ERROR:
|
||||||
|
* - +CME ERROR: 0 - AG failure
|
||||||
|
* - +CME ERROR: 1 - no connection to phone
|
||||||
|
* - +CME ERROR: 3 - operation not allowed
|
||||||
|
* - +CME ERROR: 4 - operation not supported
|
||||||
|
* - +CME ERROR: 5 - PH-SIM PIN required
|
||||||
|
* - +CME ERROR: 10 - SIM not inserted
|
||||||
|
* - +CME ERROR: 11 - SIM PIN required
|
||||||
|
* - +CME ERROR: 12 - SIM PUK required
|
||||||
|
* - +CME ERROR: 13 - SIM failure
|
||||||
|
* - +CME ERROR: 14 - SIM busy
|
||||||
|
* - +CME ERROR: 16 - incorrect password
|
||||||
|
* - +CME ERROR: 17 - SIM PIN2 required
|
||||||
|
* - +CME ERROR: 18 - SIM PUK2 required
|
||||||
|
* - +CME ERROR: 20 - memory full
|
||||||
|
* - +CME ERROR: 21 - invalid index
|
||||||
|
* - +CME ERROR: 23 - memory failure
|
||||||
|
* - +CME ERROR: 24 - text string too long
|
||||||
|
* - +CME ERROR: 25 - invalid characters in text string
|
||||||
|
* - +CME ERROR: 26 - dial string too long
|
||||||
|
* - +CME ERROR: 27 - invalid characters in dial string
|
||||||
|
* - +CME ERROR: 30 - no network service
|
||||||
|
* - +CME ERROR: 31 - network Timeout.
|
||||||
|
* - +CME ERROR: 32 - network not allowed – Emergency calls only
|
||||||
|
*/
|
||||||
|
void hfp_hf_enable_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, uint8_t enable);
|
||||||
|
|
||||||
|
|
||||||
/* API_END */
|
/* API_END */
|
||||||
|
@ -211,6 +211,18 @@ TEST(HFPParser, HFP_AG_HF_QUERY_OPERATOR_SELECTION){
|
|||||||
CHECK_EQUAL(context.operator_name_changed, 0);
|
CHECK_EQUAL(context.operator_name_changed, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(HFPParser, HFP_AG_EXTENDED_AUDIO_GATEWAY_ERROR){
|
||||||
|
sprintf(packet, "\r\nAT%s=1\r\n", HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR);
|
||||||
|
|
||||||
|
for (pos = 0; pos < strlen(packet); pos++){
|
||||||
|
hfp_parse(&context, packet[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_EQUAL(context.command, HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR);
|
||||||
|
CHECK_EQUAL(context.enable_extended_audio_gateway_error_report, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, const char * argv[]){
|
int main (int argc, const char * argv[]){
|
||||||
return CommandLineTestRunner::RunAllTests(argc, argv);
|
return CommandLineTestRunner::RunAllTests(argc, argv);
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,6 @@ TEST(HFPParser, HFP_HF_INDICATORS){
|
|||||||
}
|
}
|
||||||
offset += snprintf(packet+offset, sizeof(packet)-offset, "\"%s\", (%d, %d)\r\n\r\nOK\r\n", hfp_ag_indicators[pos].name, hfp_ag_indicators[pos].min_range, hfp_ag_indicators[pos].max_range);
|
offset += snprintf(packet+offset, sizeof(packet)-offset, "\"%s\", (%d, %d)\r\n\r\nOK\r\n", hfp_ag_indicators[pos].name, hfp_ag_indicators[pos].min_range, hfp_ag_indicators[pos].max_range);
|
||||||
|
|
||||||
context.command = HFP_CMD_INDICATOR;
|
|
||||||
context.retrieve_ag_indicators = 1;
|
context.retrieve_ag_indicators = 1;
|
||||||
context.retrieve_ag_indicators_status = 0;
|
context.retrieve_ag_indicators_status = 0;
|
||||||
|
|
||||||
@ -161,8 +160,6 @@ TEST(HFPParser, HFP_HF_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES){
|
|||||||
|
|
||||||
TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR){
|
TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR){
|
||||||
sprintf(packet, "\r\n%s:0,1,2,3,4\r\n\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR);
|
sprintf(packet, "\r\n%s:0,1,2,3,4\r\n\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR);
|
||||||
|
|
||||||
context.command = HFP_CMD_GENERIC_STATUS_INDICATOR;
|
|
||||||
context.list_generic_status_indicators = 0;
|
context.list_generic_status_indicators = 0;
|
||||||
context.retrieve_generic_status_indicators = 1;
|
context.retrieve_generic_status_indicators = 1;
|
||||||
context.retrieve_generic_status_indicators_state = 0;
|
context.retrieve_generic_status_indicators_state = 0;
|
||||||
@ -181,7 +178,6 @@ TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR){
|
|||||||
|
|
||||||
TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR_STATE){
|
TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR_STATE){
|
||||||
sprintf(packet, "\r\n%s:0,1\r\n\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR);
|
sprintf(packet, "\r\n%s:0,1\r\n\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR);
|
||||||
context.command = HFP_CMD_GENERIC_STATUS_INDICATOR;
|
|
||||||
context.list_generic_status_indicators = 0;
|
context.list_generic_status_indicators = 0;
|
||||||
context.retrieve_generic_status_indicators = 0;
|
context.retrieve_generic_status_indicators = 0;
|
||||||
context.retrieve_generic_status_indicators_state = 1;
|
context.retrieve_generic_status_indicators_state = 1;
|
||||||
@ -211,7 +207,7 @@ TEST(HFPParser, HFP_HF_AG_INDICATOR_STATUS_UPDATE){
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(HFPParser, HFP_HF_AG_QUERY_OPERATOR_SELECTION){
|
TEST(HFPParser, HFP_HF_AG_QUERY_OPERATOR_SELECTION){
|
||||||
sprintf(packet, "\r\n%s:1,0,sunrise\r\n\r\nOK\r\n", HFP_QUERY_OPERATOR_SELECTION);
|
sprintf(packet, "\r\n%s:1,0,\"sunrise\"\r\n\r\nOK\r\n", HFP_QUERY_OPERATOR_SELECTION);
|
||||||
|
|
||||||
for (pos = 0; pos < strlen(packet); pos++){
|
for (pos = 0; pos < strlen(packet); pos++){
|
||||||
hfp_parse(&context, packet[pos]);
|
hfp_parse(&context, packet[pos]);
|
||||||
@ -224,6 +220,27 @@ TEST(HFPParser, HFP_HF_AG_QUERY_OPERATOR_SELECTION){
|
|||||||
CHECK_EQUAL( strcmp("sunrise", context.network_operator.name), 0);
|
CHECK_EQUAL( strcmp("sunrise", context.network_operator.name), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(HFPParser, HFP_HF_ERROR){
|
||||||
|
sprintf(packet, "\r\n%s\r\n", HFP_ERROR);
|
||||||
|
|
||||||
|
for (pos = 0; pos < strlen(packet); pos++){
|
||||||
|
hfp_parse(&context, packet[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_EQUAL(context.command, HFP_CMD_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HFPParser, HFP_HF_EXTENDED_AUDIO_GATEWAY_ERROR){
|
||||||
|
sprintf(packet, "\r\n%s:%d\r\n", HFP_EXTENDED_AUDIO_GATEWAY_ERROR, HFP_CME_ERROR_NO_NETWORK_SERVICE);
|
||||||
|
|
||||||
|
for (pos = 0; pos < strlen(packet); pos++){
|
||||||
|
hfp_parse(&context, packet[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_EQUAL(context.command, HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR);
|
||||||
|
CHECK_EQUAL(context.extended_audio_gateway_error, HFP_CME_ERROR_NO_NETWORK_SERVICE);
|
||||||
|
}
|
||||||
|
|
||||||
int main (int argc, const char * argv[]){
|
int main (int argc, const char * argv[]){
|
||||||
return CommandLineTestRunner::RunAllTests(argc, argv);
|
return CommandLineTestRunner::RunAllTests(argc, argv);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,7 @@ const uint32_t hfp_service_buffer[150/4]; // implicit alignment to 4-byte memo
|
|||||||
const uint8_t rfcomm_channel_nr = 1;
|
const uint8_t rfcomm_channel_nr = 1;
|
||||||
const char hfp_ag_service_name[] = "BTstack HFP AG Test";
|
const char hfp_ag_service_name[] = "BTstack HFP AG Test";
|
||||||
|
|
||||||
|
static bd_addr_t device_addr;
|
||||||
static bd_addr_t pts_addr = {0x00,0x1b,0xDC,0x07,0x32,0xEF};
|
static bd_addr_t pts_addr = {0x00,0x1b,0xDC,0x07,0x32,0xEF};
|
||||||
static bd_addr_t speaker = {0x00, 0x21, 0x3C, 0xAC, 0xF7, 0x38};
|
static bd_addr_t speaker = {0x00, 0x21, 0x3C, 0xAC, 0xF7, 0x38};
|
||||||
static uint8_t codecs[1] = {HFP_CODEC_CVSD};
|
static uint8_t codecs[1] = {HFP_CODEC_CVSD};
|
||||||
@ -96,37 +97,65 @@ static hfp_generic_status_indicator_t hf_indicators[] = {
|
|||||||
{2, 1},
|
{2, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint8_t hfp_connect = 1;
|
||||||
|
|
||||||
|
char cmd;
|
||||||
// prototypes
|
// prototypes
|
||||||
static void show_usage(void);
|
static void show_usage();
|
||||||
|
|
||||||
|
static void reset_pst_flags(){
|
||||||
|
hfp_connect = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Testig User Interface
|
// Testig User Interface
|
||||||
static void show_usage(void){
|
static void show_usage(void){
|
||||||
printf("\n--- Bluetooth HFP Hands-Free (HF) unit Test Console ---\n");
|
printf("\n--- Bluetooth HFP Hands-Free (HF) unit Test Console ---\n");
|
||||||
printf("---\n");
|
printf("---\n");
|
||||||
printf("p - establish HFP connection to PTS module\n");
|
if (hfp_connect){
|
||||||
printf("e - establish HFP connection to local mac\n");
|
printf("p - establish HFP connection to PTS module\n");
|
||||||
printf("d - release HFP connection\n");
|
printf("c - establish HFP connection to local mac\n");
|
||||||
|
} else {
|
||||||
|
printf("p - release HFP connection to PTS module\n");
|
||||||
|
printf("c - release HFP connection to local mac\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("d - report AG failure\n");
|
||||||
|
|
||||||
printf("---\n");
|
printf("---\n");
|
||||||
printf("Ctrl-c - exit\n");
|
printf("Ctrl-c - exit\n");
|
||||||
printf("---\n");
|
printf("---\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stdin_process(struct data_source *ds){
|
static int stdin_process(struct data_source *ds){
|
||||||
char buffer;
|
read(ds->fd, &cmd, 1);
|
||||||
read(ds->fd, &buffer, 1);
|
switch (cmd){
|
||||||
switch (buffer){
|
|
||||||
case 'p':
|
case 'p':
|
||||||
printf("Establishing HFP service level connection to PTS module %s...\n", bd_addr_to_str(pts_addr));
|
memcpy(device_addr, pts_addr, 6);
|
||||||
hfp_ag_establish_service_level_connection(pts_addr);
|
if (hfp_connect){
|
||||||
|
printf("Establish HFP service level connection to PTS module %s...\n", bd_addr_to_str(device_addr));
|
||||||
|
hfp_ag_establish_service_level_connection(device_addr);
|
||||||
|
} else {
|
||||||
|
printf("Release HFP service level connection.\n");
|
||||||
|
hfp_ag_release_service_level_connection(device_addr);
|
||||||
|
}
|
||||||
|
hfp_connect = !hfp_connect;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'c':
|
||||||
printf("Establishing HFP service level connection to %s...\n", bd_addr_to_str(speaker));
|
memcpy(device_addr, speaker, 6);
|
||||||
hfp_ag_establish_service_level_connection(speaker);
|
if (hfp_connect){
|
||||||
|
printf("Establish HFP service level connection to %s...\n", bd_addr_to_str(device_addr));
|
||||||
|
hfp_ag_establish_service_level_connection(device_addr);
|
||||||
|
} else {
|
||||||
|
printf("Release HFP service level connection.\n");
|
||||||
|
hfp_ag_release_service_level_connection(device_addr);
|
||||||
|
}
|
||||||
|
hfp_connect = !hfp_connect;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
printf("Releasing HFP service level connection.\n");
|
printf("Report AG failure\n");
|
||||||
hfp_ag_release_service_level_connection(speaker);
|
hfp_ag_report_extended_audio_gateway_error_result_code(device_addr, HFP_CME_ERROR_AG_FAILURE);
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
show_usage();
|
show_usage();
|
||||||
break;
|
break;
|
||||||
@ -135,23 +164,21 @@ static int stdin_process(struct data_source *ds){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void packet_handler(uint8_t * event, uint16_t event_size){
|
void packet_handler(uint8_t * event, uint16_t event_size){
|
||||||
if (event[0] != HCI_EVENT_HFP_META) return;
|
if (event[0] != HCI_EVENT_HFP_META) return;
|
||||||
|
if (event[3]){
|
||||||
|
printf("ERROR, status: %u\n", event[3]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (event[2]) {
|
switch (event[2]) {
|
||||||
case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
|
case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
|
||||||
if (event[3] == 0){
|
printf("Service level connection established.\n\n");
|
||||||
printf("Service level connection established.\n\n");
|
|
||||||
} else {
|
|
||||||
printf("Service level connection establishment failed with status %u\n", event[3]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED:
|
case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED:
|
||||||
if (event[3] == 0){
|
printf("Service level connection released.\n\n");
|
||||||
printf("Service level connection released.\n\n");
|
reset_pst_flags();
|
||||||
} else {
|
|
||||||
printf("Service level connection releasing failed with status %u\n", event[3]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("event not handled %u\n", event[2]);
|
printf("event not handled %u\n", event[2]);
|
||||||
|
@ -81,21 +81,45 @@ static uint16_t indicators[1] = {0x01};
|
|||||||
|
|
||||||
char cmd;
|
char cmd;
|
||||||
|
|
||||||
|
uint8_t hfp_enable_extended_audio_gateway_error_report = 1;
|
||||||
|
uint8_t hfp_connect = 1;
|
||||||
|
uint8_t hfp_enable_status_update_for_all_ag_indicators = 1;
|
||||||
|
|
||||||
// prototypes
|
// prototypes
|
||||||
static void show_usage();
|
static void show_usage();
|
||||||
|
|
||||||
|
static void reset_pst_flags(){
|
||||||
|
hfp_enable_extended_audio_gateway_error_report = 1;
|
||||||
|
hfp_connect = 1;
|
||||||
|
hfp_enable_status_update_for_all_ag_indicators = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Testig User Interface
|
// Testig User Interface
|
||||||
static void show_usage(void){
|
static void show_usage(void){
|
||||||
printf("\n--- Bluetooth HFP Hands-Free (HF) unit Test Console ---\n");
|
printf("\n--- Bluetooth HFP Hands-Free (HF) unit Test Console ---\n");
|
||||||
printf("---\n");
|
printf("---\n");
|
||||||
printf("p - establish HFP connection to PTS module\n");
|
if (hfp_connect){
|
||||||
printf("e - establish HFP connection to local mac\n");
|
printf("p - establish HFP connection to PTS module\n");
|
||||||
printf("r - enable registration status update\n");
|
printf("c - establish HFP connection to local mac\n");
|
||||||
printf("d - release HFP connection\n");
|
} else {
|
||||||
printf("i - enabling HFP AG registration status update for individual indicators\n");
|
printf("p - release HFP connection to PTS module\n");
|
||||||
printf("o - query network operator\n");
|
printf("c - release HFP connection to local mac\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hfp_enable_status_update_for_all_ag_indicators){
|
||||||
|
printf("d - enable registration status update\n");
|
||||||
|
} else {
|
||||||
|
printf("d - disable registration status update\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("e - enable HFP AG registration status update for individual indicators\n");
|
||||||
|
|
||||||
|
printf("f - query network operator\n");
|
||||||
|
if (hfp_enable_extended_audio_gateway_error_report){
|
||||||
|
printf("g - enable reporting of the extended AG error result code\n");
|
||||||
|
} else {
|
||||||
|
printf("g - disable reporting of the extended AG error result code\n");
|
||||||
|
}
|
||||||
printf("---\n");
|
printf("---\n");
|
||||||
printf("Ctrl-c - exit\n");
|
printf("Ctrl-c - exit\n");
|
||||||
printf("---\n");
|
printf("---\n");
|
||||||
@ -106,31 +130,52 @@ static int stdin_process(struct data_source *ds){
|
|||||||
switch (cmd){
|
switch (cmd){
|
||||||
case 'p':
|
case 'p':
|
||||||
memcpy(device_addr, pts_addr, 6);
|
memcpy(device_addr, pts_addr, 6);
|
||||||
printf("Establishing HFP service level connection to PTS module %s...\n", bd_addr_to_str(device_addr));
|
if (hfp_connect){
|
||||||
hfp_hf_establish_service_level_connection(device_addr);
|
printf("Establish HFP service level connection to PTS module %s...\n", bd_addr_to_str(device_addr));
|
||||||
|
hfp_hf_establish_service_level_connection(device_addr);
|
||||||
|
} else {
|
||||||
|
printf("Release HFP service level connection.\n");
|
||||||
|
hfp_hf_release_service_level_connection(device_addr);
|
||||||
|
}
|
||||||
|
hfp_connect = !hfp_connect;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'c':
|
||||||
memcpy(device_addr, phone_addr, 6);
|
memcpy(device_addr, phone_addr, 6);
|
||||||
printf("Establishing HFP service level connection to %s...\n", bd_addr_to_str(device_addr));
|
if (hfp_connect){
|
||||||
hfp_hf_establish_service_level_connection(device_addr);
|
printf("Establish HFP service level connection to %s...\n", bd_addr_to_str(device_addr));
|
||||||
|
hfp_hf_establish_service_level_connection(device_addr);
|
||||||
|
} else {
|
||||||
|
printf("Release HFP service level connection.\n");
|
||||||
|
hfp_hf_release_service_level_connection(device_addr);
|
||||||
|
}
|
||||||
|
hfp_connect = !hfp_connect;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
printf("Releasing HFP service level connection.\n");
|
if (hfp_enable_status_update_for_all_ag_indicators){
|
||||||
hfp_hf_release_service_level_connection(device_addr);
|
printf("Enable HFP AG registration status update.\n");
|
||||||
|
} else {
|
||||||
|
printf("Disable HFP AG registration status update.\n");
|
||||||
|
}
|
||||||
|
hfp_hf_enable_status_update_for_all_ag_indicators(device_addr, hfp_enable_status_update_for_all_ag_indicators);
|
||||||
|
hfp_enable_status_update_for_all_ag_indicators = !hfp_enable_status_update_for_all_ag_indicators;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'e':
|
||||||
printf("Enabling HFP AG registration status update.\n");
|
printf("Enable HFP AG registration status update for individual indicators.\n");
|
||||||
hfp_hf_enable_status_update_for_all_ag_indicators(device_addr, 1);
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
printf("Enabling HFP AG registration status update for individual indicators.\n");
|
|
||||||
hfp_hf_enable_status_update_for_individual_ag_indicators(device_addr, 63);
|
hfp_hf_enable_status_update_for_individual_ag_indicators(device_addr, 63);
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'f':
|
||||||
printf("Query network operator.\n");
|
printf("Query network operator.\n");
|
||||||
hfp_hf_query_operator_selection(device_addr);
|
hfp_hf_query_operator_selection(device_addr);
|
||||||
break;
|
break;
|
||||||
|
case 'g':
|
||||||
|
if (hfp_enable_extended_audio_gateway_error_report){
|
||||||
|
printf("Enable reporting of the extended AG error result code.\n");
|
||||||
|
} else {
|
||||||
|
printf("Disable reporting of the extended AG error result code.\n");
|
||||||
|
}
|
||||||
|
hfp_hf_enable_report_extended_audio_gateway_error_result_code(device_addr, hfp_enable_extended_audio_gateway_error_report);
|
||||||
|
hfp_enable_extended_audio_gateway_error_report = !hfp_enable_extended_audio_gateway_error_report;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
show_usage();
|
show_usage();
|
||||||
break;
|
break;
|
||||||
@ -142,8 +187,8 @@ static int stdin_process(struct data_source *ds){
|
|||||||
|
|
||||||
void packet_handler(uint8_t * event, uint16_t event_size){
|
void packet_handler(uint8_t * event, uint16_t event_size){
|
||||||
if (event[0] != HCI_EVENT_HFP_META) return;
|
if (event[0] != HCI_EVENT_HFP_META) return;
|
||||||
if (event[3]){
|
if (event[3] && event[2] != HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR){
|
||||||
printf("Command \'%c\' failed with status %u\n", cmd, event[3]);
|
printf("ERROR, status: %u\n", event[3]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (event[2]) {
|
switch (event[2]) {
|
||||||
@ -152,13 +197,14 @@ void packet_handler(uint8_t * event, uint16_t event_size){
|
|||||||
break;
|
break;
|
||||||
case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED:
|
case HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED:
|
||||||
printf("Service level connection released.\n\n");
|
printf("Service level connection released.\n\n");
|
||||||
|
reset_pst_flags();
|
||||||
break;
|
break;
|
||||||
case HFP_SUBEVENT_COMPLETE:
|
case HFP_SUBEVENT_COMPLETE:
|
||||||
switch (cmd){
|
switch (cmd){
|
||||||
case 'r':
|
case 'd':
|
||||||
printf("HFP AG registration status update enabled.\n");
|
printf("HFP AG registration status update enabled.\n");
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'e':
|
||||||
printf("HFP AG registration status update for individual indicators set.\n");
|
printf("HFP AG registration status update for individual indicators set.\n");
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -168,7 +214,11 @@ void packet_handler(uint8_t * event, uint16_t event_size){
|
|||||||
printf("AG_INDICATOR_STATUS_CHANGED, AG indicator index: %d, status: %d\n", event[4], event[5]);
|
printf("AG_INDICATOR_STATUS_CHANGED, AG indicator index: %d, status: %d\n", event[4], event[5]);
|
||||||
break;
|
break;
|
||||||
case HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED:
|
case HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED:
|
||||||
printf("HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n", event[4], event[5], (char *) &event[6]);
|
printf("NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n", event[4], event[5], (char *) &event[6]);
|
||||||
|
break;
|
||||||
|
case HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR:
|
||||||
|
if (event[4])
|
||||||
|
printf("EXTENDED_AUDIO_GATEWAY_ERROR_REPORT, status : %d\n", event[3]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("event not handled %u\n", event[2]);
|
printf("event not handled %u\n", event[2]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user