diff --git a/include/btstack/hci_cmds.h b/include/btstack/hci_cmds.h index 975a8684f..57d06c1aa 100644 --- a/include/btstack/hci_cmds.h +++ b/include/btstack/hci_cmds.h @@ -733,12 +733,48 @@ extern "C" { */ #define HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR 0x08 +/** + * @format 11 + * @param subevent_code + * @param status + */ #define HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE 0x09 -#define HFP_SUBEVENT_START_RINGINIG 0x0A + +/** + * @format 11 + * @param subevent_code + * @param status + */ + #define HFP_SUBEVENT_START_RINGINIG 0x0A + +/** + * @format 11 + * @param subevent_code + * @param status + */ #define HFP_SUBEVENT_STOP_RINGINIG 0x0B -#define HFP_SUBEVENT_CALL_TERMINATED 0x0C + +/** + * @format 11 + * @param subevent_code + * @param status + */ + #define HFP_SUBEVENT_CALL_TERMINATED 0x0C + +/** + * @format 11T + * @param subevent_code + * @param status + * @param number + */ #define HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER 0x0D #define HFP_SUBEVENT_REDIAL_LAST_NUMBER 0x0E + +/** + * @format 11 + * @param subevent_code + * @param status + */ #define HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG 0x0F /** @@ -748,10 +784,30 @@ extern "C" { * @param number */ #define HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG 0x10 + +/** + * @format 11T + * @param subevent_code + * @param status + * @param dtmf code + */ #define HFP_SUBEVENT_TRANSMIT_DTMF_CODES 0x11 + #define HFP_SUBEVENT_TRANSMIT_STATUS_OF_CURRENT_CALL 0x12 #define HFP_SUBEVENT_CALL_ANSWERED 0x13 + +/** + * @format 11 + * @param subevent_code + * @param status + */ #define HFP_SUBEVENT_CONFERENCE_CALL 0x14 + +/** + * @format 11 + * @param subevent_code + * @param status + */ #define HFP_SUBEVENT_RING 0x15 /** diff --git a/src/hfp.c b/src/hfp.c index 769f48ea6..f95976873 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -762,6 +762,7 @@ static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ } if (strncmp(line_buffer+offset, HFP_ENABLE_CALL_WAITING_NOTIFICATION, strlen(HFP_ENABLE_CALL_WAITING_NOTIFICATION)) == 0){ + if (isHandsFree) return HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE; return HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION; } @@ -890,6 +891,7 @@ static void hfp_parser_next_state(hfp_connection_t * hfp_connection, uint8_t byt case HFP_PARSER_CMD_SEQUENCE: switch (hfp_connection->command){ case HFP_CMD_AG_SENT_PHONE_NUMBER: + case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT: @@ -1031,6 +1033,7 @@ void hfp_parse(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree) log_info("%s, ", hfp_connection->line_buffer); break; case HFP_CMD_AG_SENT_PHONE_NUMBER: + case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: hfp_connection->bnip_type = (uint8_t)atoi((char*)hfp_connection->line_buffer); break; default: @@ -1268,6 +1271,7 @@ static void parse_sequence(hfp_connection_t * hfp_connection){ hfp_connection->extended_audio_gateway_error = 0; break; case HFP_CMD_AG_SENT_PHONE_NUMBER: + case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number)); hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0; break; diff --git a/src/hfp.h b/src/hfp.h index cad205edd..db52d1c72 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -160,6 +160,7 @@ typedef enum { HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, HFP_CMD_ENABLE_CLIP, HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION, + HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE, HFP_CMD_LIST_GENERIC_STATUS_INDICATORS, HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS, @@ -604,7 +605,7 @@ typedef struct hfp_connection { uint8_t clcc_mpty; uint8_t call_index; - // also used for CLCC if set + // also used for CLCC, CCWA 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 fa9f49776..d76b56dff 100644 --- a/src/hfp_hf.c +++ b/src/hfp_hf.c @@ -91,12 +91,12 @@ void hfp_hf_register_packet_handler(hfp_callback_t callback){ hfp_callback = callback; } -static void hfp_hf_emit_subscriber_number(hfp_callback_t callback, uint8_t bnip_type, const char * bnip_number){ +static void hfp_hf_emit_type_and_number(hfp_callback_t callback, uint8_t event_subtype, uint8_t bnip_type, const char * bnip_number){ if (!callback) return; uint8_t event[30]; event[0] = HCI_EVENT_HFP_META; event[1] = sizeof(event) - 2; - event[2] = HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION; + event[2] = event_subtype; event[3] = bnip_type; int size = (strlen(bnip_number) < sizeof(event) - 5) ? strlen(bnip_number) : sizeof(event) - 5; strncpy((char*)&event[4], bnip_number, size); @@ -962,7 +962,7 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: hfp_connection->command = HFP_CMD_NONE; // printf("Subscriber Number: number %s, type %u\n", hfp_connection->bnip_number, hfp_connection->bnip_type); - hfp_hf_emit_subscriber_number(hfp_callback, hfp_connection->bnip_type, hfp_connection->bnip_number); + hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, hfp_connection->bnip_type, hfp_connection->bnip_number); break; case HFP_CMD_RESPONSE_AND_HOLD_STATUS: hfp_connection->command = HFP_CMD_NONE; @@ -994,6 +994,11 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8 hfp_connection->command = HFP_CMD_NONE; hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number); break; + case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE: + hfp_connection->command = HFP_CMD_NONE; + hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number); + break; + case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: hfp_connection->ok_pending = 0; hfp_connection->command = HFP_CMD_NONE; diff --git a/src/hfp_hf.h b/src/hfp_hf.h index f57f567ad..d5c606f26 100644 --- a/src/hfp_hf.h +++ b/src/hfp_hf.h @@ -151,7 +151,7 @@ void hfp_hf_disable_status_update_for_all_ag_indicators(bd_addr_t bd_addr); void hfp_hf_set_status_update_for_individual_ag_indicators(bd_addr_t bd_addr, uint32_t indicators_status_bitmap); /** - * @brief Find out the name of the currently selected Network operator by AG. + * @brief Query the name of the currently selected Network operator by AG. * * The name is restricted to max 16 characters. The result is reported via * HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED subtype @@ -209,38 +209,38 @@ void hfp_hf_answer_incoming_call(bd_addr_t bd_addr); void hfp_hf_reject_incoming_call(bd_addr_t bd_addr); /** - * @brief Releases all held calls or sets User Determined User Busy (UDUB) for a waiting call. + * @brief Release all held calls or sets User Determined User Busy (UDUB) for a waiting call. * @param bd_addr Bluetooth address of the AG */ void hfp_hf_user_busy(bd_addr_t addr); /** - * @brief Releases all active calls (if any exist) and accepts the other (held or waiting) call. + * @brief Release all active calls (if any exist) and accepts the other (held or waiting) call. * @param bd_addr Bluetooth address of the AG */ void hfp_hf_end_active_and_accept_other(bd_addr_t addr); /** - * @brief Places all active calls (if any exist) on hold and accepts the other (held or waiting) call. + * @brief Place all active calls (if any exist) on hold and accepts the other (held or waiting) call. * @param bd_addr Bluetooth address of the AG */ void hfp_hf_swap_calls(bd_addr_t addr); /** - * @brief Adds a held call to the conversation. + * @brief Add a held call to the conversation. * @param bd_addr Bluetooth address of the AG */ void hfp_hf_join_held_call(bd_addr_t addr); /** - * @brief Connects the two calls and disconnects the subscriber from both calls (Explicit Call + * @brief Connect the two calls and disconnects the subscriber from both calls (Explicit Call Transfer). * @param bd_addr Bluetooth address of the AG */ void hfp_hf_connect_calls(bd_addr_t addr); /** - * @brief Terminates an incoming or an outgoing call. + * @brief Terminate an incoming or an outgoing call. * HFP_SUBEVENT_CALL_TERMINATED is sent upon call termination. * @param bd_addr Bluetooth address of the AG */ @@ -349,15 +349,15 @@ void hfp_hf_send_dtmf_code(bd_addr_t bd_addr, char code); /* * @brief Read numbers from the AG for the purpose of creating * a unique voice tag and storing the number and its linked voice - * tag in the HF’s memory. The number is recived via - * HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG. + * tag in the HF’s memory. + * The number is reported via HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG. * @param bd_addr Bluetooth address of the AG */ void hfp_hf_request_phone_number_for_voice_tag(bd_addr_t addr); /* * @brief Query the list of current calls in AG. - * The result is received via HFP_SUBEVENT_ENHANCED_CALL_STATUS (TODO). + * The result is received via HFP_SUBEVENT_ENHANCED_CALL_STATUS. * @param bd_addr Bluetooth address of the AG */ void hfp_hf_query_current_call_status(bd_addr_t addr); @@ -379,6 +379,7 @@ void hfp_hf_private_consultation_with_call(bd_addr_t addr, int index); /* * @brief Query the status of the “Response and Hold” state of the AG. + * The result is reported via HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS. * @param bd_addr Bluetooth address of the AG */ void hfp_hf_rrh_query_status(bd_addr_t addr); @@ -403,6 +404,7 @@ void hfp_hf_rrh_reject_held_call(bd_addr_t addr); /* * @brief Query the AG subscriber number. + * The result is reported via HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION. * @param bd_addr Bluetooth address of the AG */ void hfp_hf_query_subscriber_number(bd_addr_t addr);