From e172a06f62c932851de65bbc79a31d229578d3eb Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Tue, 23 Sep 2025 18:42:02 +0800 Subject: [PATCH] Bluetooth: Classic: HFP_HF: Fix `AT+CLCC` can not be sent issue Due to the flag `BT_HFP_HF_FLAG_CLCC_PENDING` is set when receiving the +CIEV or +CIND notification, the command `AT+CLCC` will be pending due to the flag is not cleared. Add a flag `BT_HFP_HF_FLAG_INITIATING` to indicate the HF initialization is ongoing. Add a flag `BT_HFP_HF_FLAG_QUERY_CALLS` to indicate the current calls list needs to be queried. Set the flag `BT_HFP_HF_FLAG_INITIATING` at the beginning of the HF initialization. Set the flag `BT_HFP_HF_FLAG_QUERY_CALLS` instead of setting the flag `BT_HFP_HF_FLAG_CLCC_PENDING` if the current calls list needs to be queried and the flag `BT_HFP_HF_FLAG_INITIATING` is set. After the HF initialization is done, query list of the current calls by calling the function `hf_query_current_calls()` if the flag `BT_HFP_HF_FLAG_QUERY_CALLS` is set. Set the flag `BT_HFP_HF_FLAG_CLCC_PENDING` if it is not set in the function `hf_query_current_calls()`. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/hfp_hf.c | 27 ++++++++++++------- .../bluetooth/host/classic/hfp_hf_internal.h | 2 ++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/subsys/bluetooth/host/classic/hfp_hf.c b/subsys/bluetooth/host/classic/hfp_hf.c index 40f6523f44b84..dc6aed6a55831 100644 --- a/subsys/bluetooth/host/classic/hfp_hf.c +++ b/subsys/bluetooth/host/classic/hfp_hf.c @@ -552,7 +552,7 @@ static void hf_query_current_calls(struct bt_hfp_hf *hf) return; } - if (atomic_test_bit(hf->flags, BT_HFP_HF_FLAG_CLCC_PENDING)) { + if (atomic_test_and_set_bit(hf->flags, BT_HFP_HF_FLAG_CLCC_PENDING)) { k_work_reschedule(&hf->deferred_work, K_MSEC(HF_ENHANCED_CALL_STATUS_TIMEOUT)); return; } @@ -1091,8 +1091,8 @@ static void ag_indicator_handle_call(struct bt_hfp_hf *hf, uint32_t value) LOG_DBG("call %d", value); - if (value != 0) { - atomic_set_bit(hf->flags, BT_HFP_HF_FLAG_CLCC_PENDING); + if ((value != 0) && atomic_test_bit(hf->flags, BT_HFP_HF_FLAG_INITIATING)) { + atomic_set_bit(hf->flags, BT_HFP_HF_FLAG_QUERY_CALLS); } if (value) { @@ -1153,8 +1153,9 @@ static void ag_indicator_handle_call_setup(struct bt_hfp_hf *hf, uint32_t value) LOG_DBG("call setup %d", value); - if (value != BT_HFP_CALL_SETUP_NONE) { - atomic_set_bit(hf->flags, BT_HFP_HF_FLAG_CLCC_PENDING); + if ((value != BT_HFP_CALL_SETUP_NONE) && + atomic_test_bit(hf->flags, BT_HFP_HF_FLAG_INITIATING)) { + atomic_set_bit(hf->flags, BT_HFP_HF_FLAG_QUERY_CALLS); } switch (value) { @@ -1258,8 +1259,9 @@ static void ag_indicator_handle_call_held(struct bt_hfp_hf *hf, uint32_t value) LOG_DBG("call setup %d", value); - if (value != BT_HFP_CALL_HELD_NONE) { - atomic_set_bit(hf->flags, BT_HFP_HF_FLAG_CLCC_PENDING); + if ((value != BT_HFP_CALL_HELD_NONE) && + atomic_test_bit(hf->flags, BT_HFP_HF_FLAG_INITIATING)) { + atomic_set_bit(hf->flags, BT_HFP_HF_FLAG_QUERY_CALLS); } switch (value) { @@ -2077,9 +2079,12 @@ static int at_cmd_init_start(struct bt_hfp_hf *hf) hf->cmd_init_seq++; } - if ((ARRAY_SIZE(cmd_init_list) <= hf->cmd_init_seq) && - atomic_test_and_clear_bit(hf->flags, BT_HFP_HF_FLAG_CLCC_PENDING)) { - k_work_reschedule(&hf->deferred_work, K_MSEC(HF_ENHANCED_CALL_STATUS_TIMEOUT)); + if (ARRAY_SIZE(cmd_init_list) <= hf->cmd_init_seq) { + atomic_clear_bit(hf->flags, BT_HFP_HF_FLAG_INITIATING); + if (atomic_test_and_clear_bit(hf->flags, BT_HFP_HF_FLAG_QUERY_CALLS)) { + k_work_reschedule(&hf->deferred_work, + K_MSEC(HF_ENHANCED_CALL_STATUS_TIMEOUT)); + } } return err; @@ -2308,6 +2313,8 @@ int hf_slc_establish(struct bt_hfp_hf *hf) LOG_DBG(""); + atomic_set_bit(hf->flags, BT_HFP_HF_FLAG_INITIATING); + hf->cmd_init_seq = 0; err = slc_init_start(hf); if (err < 0) { diff --git a/subsys/bluetooth/host/classic/hfp_hf_internal.h b/subsys/bluetooth/host/classic/hfp_hf_internal.h index caecc60dac9fa..54c594d0d0504 100644 --- a/subsys/bluetooth/host/classic/hfp_hf_internal.h +++ b/subsys/bluetooth/host/classic/hfp_hf_internal.h @@ -143,6 +143,8 @@ enum { BT_HFP_HF_FLAG_CLCC_PENDING, /* HFP HF CLCC is pending */ BT_HFP_HF_FLAG_VRE_ACTIVATE, /* VRE is activated */ BT_HFP_HF_FLAG_BINP, /* +BINP result code is received */ + BT_HFP_HF_FLAG_INITIATING, /* HF is in initiating state */ + BT_HFP_HF_FLAG_QUERY_CALLS, /* Require to query list of current calls */ /* Total number of flags - must be at the end of the enum */ BT_HFP_HF_NUM_FLAGS, };