From 2011dcb3eef3dcf1b6a6435281cb39e19dfc2cba Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 28 Aug 2024 16:04:45 +0800 Subject: [PATCH] Bluetooth: HFP_HF: Activate/deactivate AG indicators Add a function `bt_hfp_hf_indicator_status` to activate/deactivate AG indicators. Signed-off-by: Lyle Zhu --- include/zephyr/bluetooth/classic/hfp_hf.h | 29 ++++++++++ subsys/bluetooth/host/classic/hfp_hf.c | 61 ++++++++++++++++++++ subsys/bluetooth/host/classic/hfp_internal.h | 10 ---- 3 files changed, 90 insertions(+), 10 deletions(-) diff --git a/include/zephyr/bluetooth/classic/hfp_hf.h b/include/zephyr/bluetooth/classic/hfp_hf.h index 5a99cdec52b..31efb3fdf4e 100644 --- a/include/zephyr/bluetooth/classic/hfp_hf.h +++ b/include/zephyr/bluetooth/classic/hfp_hf.h @@ -848,6 +848,35 @@ int bt_hfp_hf_transmit_dtmf_code(struct bt_hfp_hf_call *call, char code); */ int bt_hfp_hf_query_subscriber(struct bt_hfp_hf *hf); +/* HFP HF Indicators */ +enum hfp_hf_ag_indicators { + HF_SERVICE_IND = 0, /* AG service indicator */ + HF_CALL_IND, /* AG call indicator */ + HF_CALL_SETUP_IND, /* AG call setup indicator */ + HF_CALL_HELD_IND, /* AG call held indicator */ + HF_SINGNAL_IND, /* AG signal indicator */ + HF_ROAM_IND, /* AG roaming indicator */ + HF_BATTERY_IND /* AG battery indicator */ +}; + +/** @brief Handsfree HF set AG indicator activated/deactivated status + * + * It allows HF to issue the AT+BIA command if it needs to change the + * activated/deactivated status of indicators in the AG. + * The index of all indicators can be activated/deactivated are + * defined in `enum hfp_hf_ag_indicators`. + * The each bit of parameter `status` represents the indicator status + * corresponding to the index. Such as, value 0b111110 of `status` + * means the AG indicator `service` is required to be deactivated. + * Others are required to be activated. + * + * @param hf HFP HF object. + * @param status The activated/deactivated bitmap status of AG indicators. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_hfp_hf_indicator_status(struct bt_hfp_hf *hf, uint8_t status); + #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/host/classic/hfp_hf.c b/subsys/bluetooth/host/classic/hfp_hf.c index 778d9a9605f..e38e3966b55 100644 --- a/subsys/bluetooth/host/classic/hfp_hf.c +++ b/subsys/bluetooth/host/classic/hfp_hf.c @@ -2461,6 +2461,67 @@ int bt_hfp_hf_query_subscriber(struct bt_hfp_hf *hf) return err; } +static int bia_finish(struct at_client *hf_at, enum at_result result, + enum at_cme cme_err) +{ + struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at); + + LOG_DBG("AT+BIA (result %d) on %p", result, hf); + + return 0; +} + +int bt_hfp_hf_indicator_status(struct bt_hfp_hf *hf, uint8_t status) +{ + int err; + size_t index; + char buffer[HF_MAX_AG_INDICATORS * 2 + 1]; + char *bia_status; + + LOG_DBG(""); + + if (!hf) { + LOG_ERR("No HF connection found"); + return -ENOTCONN; + } + + if (!atomic_test_bit(hf->flags, BT_HFP_HF_FLAG_CONNECTED)) { + LOG_ERR("SLC is not established on %p", hf); + return -ENOTCONN; + } + + bia_status = &buffer[0]; + for (index = 0; index < ARRAY_SIZE(hf->ind_table); index++) { + if ((hf->ind_table[index] != -1) && (index < NUM_BITS(sizeof(status)))) { + if (status & BIT(hf->ind_table[index])) { + *bia_status = '1'; + } else { + *bia_status = '0'; + } + bia_status++; + *bia_status = ','; + bia_status++; + } else { + break; + } + } + + if (bia_status <= &buffer[0]) { + LOG_ERR("Not found valid AG indicator on %p", hf); + return -EINVAL; + } + + bia_status--; + *bia_status = '\0'; + + err = hfp_hf_send_cmd(hf, NULL, bia_finish, "AT+BIA=%s", buffer); + if (err < 0) { + LOG_ERR("Fail to activated/deactivated AG indicators on %p", hf); + } + + return err; +} + static int ata_finish(struct at_client *hf_at, enum at_result result, enum at_cme cme_err) { diff --git a/subsys/bluetooth/host/classic/hfp_internal.h b/subsys/bluetooth/host/classic/hfp_internal.h index be776021eb8..70bee514c53 100644 --- a/subsys/bluetooth/host/classic/hfp_internal.h +++ b/subsys/bluetooth/host/classic/hfp_internal.h @@ -262,16 +262,6 @@ struct bt_hfp_hf { ATOMIC_DEFINE(flags, BT_HFP_HF_NUM_FLAGS); }; -enum hfp_hf_ag_indicators { - HF_SERVICE_IND, - HF_CALL_IND, - HF_CALL_SETUP_IND, - HF_CALL_HELD_IND, - HF_SINGNAL_IND, - HF_ROAM_IND, - HF_BATTERY_IND -}; - /* HFP call setup status */ #define BT_HFP_CALL_SETUP_NONE 0 #define BT_HFP_CALL_SETUP_INCOMING 1