From 76cc15274392add77ec93c747c2efc1957e935a3 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 12 Oct 2020 12:09:29 +0200 Subject: [PATCH] hfp: sort code, use assert --- src/classic/hfp_ag.c | 104 ++++++++++++------------- src/classic/hfp_hf.c | 180 ++++++++++++++++++++++--------------------- 2 files changed, 145 insertions(+), 139 deletions(-) diff --git a/src/classic/hfp_ag.c b/src/classic/hfp_ag.c index 565db085e..a77079edf 100644 --- a/src/classic/hfp_ag.c +++ b/src/classic/hfp_ag.c @@ -109,6 +109,15 @@ static int subscriber_numbers_count = 0; hfp_ag_indicator_t * hfp_ag_get_ag_indicators(hfp_connection_t * hfp_connection); +static void hfp_ag_emit_simple_event(uint8_t event_subtype){ + uint8_t event[3]; + event[0] = HCI_EVENT_HFP_META; + event[1] = sizeof(event) - 2; + event[2] = event_subtype; + if (!hfp_ag_callback) return; + (*hfp_ag_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); +} + static int hfp_ag_get_ag_indicators_nr(hfp_connection_t * hfp_connection){ if (hfp_connection->ag_indicators_nr != hfp_ag_indicators_nr){ hfp_connection->ag_indicators_nr = hfp_ag_indicators_nr; @@ -160,15 +169,6 @@ static hfp_connection_t * get_hfp_ag_connection_context_for_acl_handle(uint16_t return NULL; } -void hfp_ag_register_packet_handler(btstack_packet_handler_t callback){ - if (callback == NULL){ - log_error("hfp_ag_register_packet_handler called with NULL callback"); - return; - } - hfp_ag_callback = callback; - hfp_set_ag_callback(callback); -} - static int use_in_band_tone(void){ return get_bit(hfp_supported_features, HFP_AGSF_IN_BAND_RING_TONE); } @@ -191,33 +191,7 @@ static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){ return hf && ag; } -void hfp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features, int wide_band_speech){ - if (!name){ - name = default_hfp_ag_service_name; - } - hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, rfcomm_channel_nr, name); - - /* - * 0x01 – Ability to reject a call - * 0x00 – No ability to reject a call - */ - de_add_number(service, DE_UINT, DE_SIZE_16, 0x0301); // Hands-Free Profile - Network - de_add_number(service, DE_UINT, DE_SIZE_8, ability_to_reject_call); - - // Construct SupportedFeatures for SDP bitmap: - // - // "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values - // of the Bits 0 to 4 of the unsolicited result code +BRSF" - // - // Wide band speech (bit 5) requires Codec negotiation - // - uint16_t sdp_features = supported_features & 0x1f; - if (wide_band_speech && (supported_features & (1 << HFP_AGSF_CODEC_NEGOTIATION))){ - sdp_features |= 1 << 5; - } - de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures - de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features); -} +/* unsolicited responses */ static int hfp_ag_send_change_in_band_ring_tone_setting_cmd(uint16_t cid){ char buffer[20]; @@ -516,6 +490,8 @@ static uint8_t hfp_ag_suggest_codec(hfp_connection_t *hfp_connection){ return HFP_CODEC_CVSD; } +/* state machines */ + static uint8_t hfp_ag_esco_s4_supported(hfp_connection_t * hfp_connection){ return (hfp_connection->remote_supported_features & (1<local_role == HFP_ROLE_AG); - if (!hfp_connection->rfcomm_cid) return; - - if (hfp_connection->local_role != HFP_ROLE_AG) { - log_info("HFP AG%p, wrong role %u", hfp_connection, hfp_connection->local_role); - return; - } + // during SDP query, RFCOMM CID is not set + if (hfp_connection->rfcomm_cid == 0) return; if (!rfcomm_can_send_packet_now(hfp_connection->rfcomm_cid)) { log_info("hfp_ag_run_for_context: request can send for 0x%02x", hfp_connection->rfcomm_cid); @@ -2407,3 +2371,39 @@ void hfp_ag_notify_incoming_call_waiting(hci_con_handle_t acl_handle){ hfp_ag_run_for_context(hfp_connection); } +void hfp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features, int wide_band_speech){ + if (!name){ + name = default_hfp_ag_service_name; + } + hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, rfcomm_channel_nr, name); + + /* + * 0x01 – Ability to reject a call + * 0x00 – No ability to reject a call + */ + de_add_number(service, DE_UINT, DE_SIZE_16, 0x0301); // Hands-Free Profile - Network + de_add_number(service, DE_UINT, DE_SIZE_8, ability_to_reject_call); + + // Construct SupportedFeatures for SDP bitmap: + // + // "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values + // of the Bits 0 to 4 of the unsolicited result code +BRSF" + // + // Wide band speech (bit 5) requires Codec negotiation + // + uint16_t sdp_features = supported_features & 0x1f; + if (wide_band_speech && (supported_features & (1 << HFP_AGSF_CODEC_NEGOTIATION))){ + sdp_features |= 1 << 5; + } + de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures + de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features); +} + +void hfp_ag_register_packet_handler(btstack_packet_handler_t callback){ + if (callback == NULL){ + log_error("hfp_ag_register_packet_handler called with NULL callback"); + return; + } + hfp_ag_callback = callback; + hfp_set_ag_callback(callback); +} diff --git a/src/classic/hfp_hf.c b/src/classic/hfp_hf.c index e5895dd39..687513aff 100644 --- a/src/classic/hfp_hf.c +++ b/src/classic/hfp_hf.c @@ -84,7 +84,27 @@ static hfp_call_status_t hfp_call_status; static hfp_callsetup_status_t hfp_callsetup_status; static hfp_callheld_status_t hfp_callheld_status; -static char phone_number[25]; +static char phone_number[25]; + +static int has_codec_negotiation_feature(hfp_connection_t * hfp_connection){ + int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION); + int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION); + return hf && ag; +} + +static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * hfp_connection){ + int hf = get_bit(hfp_supported_features, HFP_HFSF_THREE_WAY_CALLING); + int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING); + return hf && ag; +} + + +static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){ + int hf = get_bit(hfp_supported_features, HFP_HFSF_HF_INDICATORS); + int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_HF_INDICATORS); + return hf && ag; +} + static hfp_connection_t * get_hfp_hf_connection_context_for_acl_handle(uint16_t handle){ btstack_linked_list_iterator_t it; @@ -98,14 +118,7 @@ static hfp_connection_t * get_hfp_hf_connection_context_for_acl_handle(uint16_t return NULL; } -void hfp_hf_register_packet_handler(btstack_packet_handler_t callback){ - if (callback == NULL){ - log_error("hfp_hf_register_packet_handler called with NULL callback"); - return; - } - hfp_hf_callback = callback; - hfp_set_hf_callback(callback); -} +/* emit functinos */ static void hfp_hf_emit_subscriber_information(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t status, uint8_t bnip_type, const char * bnip_number){ if (!callback) return; @@ -154,46 +167,41 @@ static void hfp_hf_emit_enhanced_call_status(btstack_packet_handler_t callback, (*callback)(HCI_EVENT_PACKET, 0, event, pos); } -static int has_codec_negotiation_feature(hfp_connection_t * hfp_connection){ - int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION); - int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION); - return hf && ag; + +static void hfp_emit_ag_indicator_event(btstack_packet_handler_t callback, hfp_ag_indicator_t indicator){ + if (!callback) return; + uint8_t event[10+HFP_MAX_INDICATOR_DESC_SIZE+1]; + int pos = 0; + event[pos++] = HCI_EVENT_HFP_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED; + event[pos++] = indicator.index; + event[pos++] = indicator.status; + event[pos++] = indicator.min_range; + event[pos++] = indicator.max_range; + event[pos++] = indicator.mandatory; + event[pos++] = indicator.enabled; + event[pos++] = indicator.status_changed; + strncpy((char*)&event[pos], indicator.name, HFP_MAX_INDICATOR_DESC_SIZE); + pos += HFP_MAX_INDICATOR_DESC_SIZE; + event[pos] = 0; + (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); } -static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * hfp_connection){ - int hf = get_bit(hfp_supported_features, HFP_HFSF_THREE_WAY_CALLING); - int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING); - return hf && ag; -} - - -static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){ - int hf = get_bit(hfp_supported_features, HFP_HFSF_HF_INDICATORS); - int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_HF_INDICATORS); - return hf && ag; -} - -void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features, int wide_band_speech){ - if (!name){ - name = default_hfp_hf_service_name; - } - hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE, rfcomm_channel_nr, name); - - // Construct SupportedFeatures for SDP bitmap: - // - // "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values - // of the Bits 0 to 4 of the unsolicited result code +BRSF" - // - // Wide band speech (bit 5) requires Codec negotiation - // - uint16_t sdp_features = supported_features & 0x1f; - if (wide_band_speech && (supported_features & (1 << HFP_HFSF_CODEC_NEGOTIATION))){ - sdp_features |= 1 << 5; - } - de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures - de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features); +static void hfp_emit_network_operator_event(btstack_packet_handler_t callback, hfp_network_opearator_t network_operator){ + if (!callback) return; + uint8_t event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE+1]; + event[0] = HCI_EVENT_HFP_META; + event[1] = sizeof(event) - 2; + event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED; + event[3] = network_operator.mode; + event[4] = network_operator.format; + strncpy((char*)&event[5], network_operator.name, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE); + event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE] = 0; + (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); } +/* send commands */ static inline int hfp_hf_send_cmd(uint16_t cid, const char * cmd){ char buffer[20]; @@ -358,38 +366,7 @@ static int hfp_hf_send_clcc(uint16_t cid){ return hfp_hf_send_cmd(cid, HFP_LIST_CURRENT_CALLS); } -static void hfp_emit_ag_indicator_event(btstack_packet_handler_t callback, hfp_ag_indicator_t indicator){ - if (!callback) return; - uint8_t event[10+HFP_MAX_INDICATOR_DESC_SIZE+1]; - int pos = 0; - event[pos++] = HCI_EVENT_HFP_META; - event[pos++] = sizeof(event) - 2; - event[pos++] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED; - event[pos++] = indicator.index; - event[pos++] = indicator.status; - event[pos++] = indicator.min_range; - event[pos++] = indicator.max_range; - event[pos++] = indicator.mandatory; - event[pos++] = indicator.enabled; - event[pos++] = indicator.status_changed; - strncpy((char*)&event[pos], indicator.name, HFP_MAX_INDICATOR_DESC_SIZE); - pos += HFP_MAX_INDICATOR_DESC_SIZE; - event[pos] = 0; - (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); -} - -static void hfp_emit_network_operator_event(btstack_packet_handler_t callback, hfp_network_opearator_t network_operator){ - if (!callback) return; - uint8_t event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE+1]; - event[0] = HCI_EVENT_HFP_META; - event[1] = sizeof(event) - 2; - event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED; - event[3] = network_operator.mode; - event[4] = network_operator.format; - strncpy((char*)&event[5], network_operator.name, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE); - event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE] = 0; - (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); -} +/* state machines */ static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * hfp_connection){ if (hfp_connection->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0; @@ -580,13 +557,12 @@ static int call_setup_state_machine(hfp_connection_t * hfp_connection){ } static void hfp_run_for_context(hfp_connection_t * hfp_connection){ - if (!hfp_connection) return; - if (!hfp_connection->rfcomm_cid) return; - if (hfp_connection->local_role != HFP_ROLE_HF) { - log_info("HFP HF%p, wrong role %u", hfp_connection, hfp_connection->local_role); - return; - } + btstack_assert(hfp_connection != NULL); + btstack_assert(hfp_connection->local_role == HFP_ROLE_HF); + + // during SDP query, RFCOMM CID is not set + if (hfp_connection->rfcomm_cid == 0) return; if (hfp_connection->hf_accept_sco && hci_can_send_command_packet_now()){ @@ -998,10 +974,6 @@ static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){ hfp_connection->command = HFP_CMD_NONE; } -static int hfp_parser_is_end_of_line(uint8_t byte){ - return (byte == '\n') || (byte == '\r'); -} - static void hfp_hf_handle_transfer_ag_indicator_status(hfp_connection_t * hfp_connection) { uint16_t i; for (i = 0; i < hfp_connection->ag_indicators_nr; i++){ @@ -1107,6 +1079,10 @@ static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){ } } +static int hfp_parser_is_end_of_line(uint8_t byte){ + return (byte == '\n') || (byte == '\r'); +} + static void hfp_hf_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ UNUSED(packet_type); // ok: only called with RFCOMM_DATA_PACKET // assertion: size >= 1 as rfcomm.c does not deliver empty packets @@ -1760,3 +1736,33 @@ int hfp_hf_in_band_ringtone_active(hci_con_handle_t acl_handle){ } return get_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE); } + +void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features, int wide_band_speech){ + if (!name){ + name = default_hfp_hf_service_name; + } + hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE, rfcomm_channel_nr, name); + + // Construct SupportedFeatures for SDP bitmap: + // + // "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values + // of the Bits 0 to 4 of the unsolicited result code +BRSF" + // + // Wide band speech (bit 5) requires Codec negotiation + // + uint16_t sdp_features = supported_features & 0x1f; + if (wide_band_speech && (supported_features & (1 << HFP_HFSF_CODEC_NEGOTIATION))){ + sdp_features |= 1 << 5; + } + de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures + de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features); +} + +void hfp_hf_register_packet_handler(btstack_packet_handler_t callback){ + if (callback == NULL){ + log_error("hfp_hf_register_packet_handler called with NULL callback"); + return; + } + hfp_hf_callback = callback; + hfp_set_hf_callback(callback); +} \ No newline at end of file