From 3f7224a926737617aa1623429d4376478d8e53ea Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Thu, 3 Apr 2025 14:55:51 +0800 Subject: [PATCH] Bluetooth: Classic: HFP_AG: Update the callback `sco_disconnected()` Change the arguments of HFP AG callback `sco_disconnected()` to SCO conn and disconnection reason. Signed-off-by: Lyle Zhu --- doc/releases/migration-guide-4.2.rst | 7 ++++ include/zephyr/bluetooth/classic/hfp_ag.h | 6 ++-- samples/bluetooth/handsfree_ag/src/main.c | 4 +-- subsys/bluetooth/host/classic/hfp_ag.c | 4 +-- subsys/bluetooth/host/classic/shell/hfp.c | 42 ++++++++++++++++++----- 5 files changed, 47 insertions(+), 16 deletions(-) diff --git a/doc/releases/migration-guide-4.2.rst b/doc/releases/migration-guide-4.2.rst index 99e64c9e017..5c625435ef1 100644 --- a/doc/releases/migration-guide-4.2.rst +++ b/doc/releases/migration-guide-4.2.rst @@ -227,6 +227,13 @@ Bluetooth Host each role may be different. Any existing uses/checks for ``BT_ISO_CHAN_TYPE_CONNECTED`` can be replaced with an ``||`` of the two. (:github:`75549`) +Bluetooth Classic +================= + +* The parameters of HFP AG callback ``sco_disconnected`` of the struct :c:struct:`bt_hfp_ag_cb` + have been changed to SCO connection object ``struct bt_conn *sco_conn`` and the disconnection + reason of the SCO connection ``uint8_t reason``. + Networking ********** diff --git a/include/zephyr/bluetooth/classic/hfp_ag.h b/include/zephyr/bluetooth/classic/hfp_ag.h index 599a1ba1aaf..9f936bef923 100644 --- a/include/zephyr/bluetooth/classic/hfp_ag.h +++ b/include/zephyr/bluetooth/classic/hfp_ag.h @@ -111,10 +111,10 @@ struct bt_hfp_ag_cb { * If this callback is provided it will be called whenever the * SCO/eSCO connection gets disconnected. * - * @param ag HFP AG object. - * @param sco_conn SCO/eSCO Connection object. + * @param conn SCO/eSCO Connection object. + * @param reason BT_HCI_ERR_* reason for the disconnection. */ - void (*sco_disconnected)(struct bt_hfp_ag *ag); + void (*sco_disconnected)(struct bt_conn *sco_conn, uint8_t reason); /** HF memory dialing request Callback * diff --git a/samples/bluetooth/handsfree_ag/src/main.c b/samples/bluetooth/handsfree_ag/src/main.c index 721b8f6e260..0adbc951595 100644 --- a/samples/bluetooth/handsfree_ag/src/main.c +++ b/samples/bluetooth/handsfree_ag/src/main.c @@ -63,9 +63,9 @@ static void ag_sco_connected(struct bt_hfp_ag *ag, struct bt_conn *sco_conn) printk("HFP AG SCO connected!\n"); } -static void ag_sco_disconnected(struct bt_hfp_ag *ag) +static void ag_sco_disconnected(struct bt_conn *sco_conn, uint8_t reason) { - printk("HFP AG SCO disconnected!\n"); + printk("HFP AG SCO disconnected %u!\n", reason); } static void ag_ringing(struct bt_hfp_ag_call *call, bool in_band) diff --git a/subsys/bluetooth/host/classic/hfp_ag.c b/subsys/bluetooth/host/classic/hfp_ag.c index 4813606f703..371923134c8 100644 --- a/subsys/bluetooth/host/classic/hfp_ag.c +++ b/subsys/bluetooth/host/classic/hfp_ag.c @@ -2029,8 +2029,8 @@ static void hfp_ag_sco_disconnected(struct bt_sco_chan *chan, uint8_t reason) call = get_call_with_flag(ag, BT_HFP_AG_CALL_OPEN_SCO, true); - if ((bt_ag) && bt_ag->sco_disconnected) { - bt_ag->sco_disconnected(ag); + if ((bt_ag != NULL) && bt_ag->sco_disconnected) { + bt_ag->sco_disconnected(chan->sco, reason); } if (!call) { diff --git a/subsys/bluetooth/host/classic/shell/hfp.c b/subsys/bluetooth/host/classic/shell/hfp.c index 7d713d81c34..104a5c8a067 100644 --- a/subsys/bluetooth/host/classic/shell/hfp.c +++ b/subsys/bluetooth/host/classic/shell/hfp.c @@ -73,14 +73,26 @@ static void hf_disconnected(struct bt_hfp_hf *hf) static void hf_sco_connected(struct bt_hfp_hf *hf, struct bt_conn *sco_conn) { - bt_shell_print("HF SCO connected"); - hf_sco_conn = sco_conn; + bt_shell_print("HF SCO connected %p", sco_conn); + + if (hf_sco_conn != NULL) { + bt_shell_warn("HF SCO conn %p exists", hf_sco_conn); + return; + } + + hf_sco_conn = bt_conn_ref(sco_conn); } static void hf_sco_disconnected(struct bt_conn *sco_conn, uint8_t reason) { - bt_shell_print("HF SCO disconnected"); - hf_sco_conn = NULL; + bt_shell_print("HF SCO disconnected %p (reason %u)", sco_conn, reason); + + if (hf_sco_conn == sco_conn) { + bt_conn_unref(hf_sco_conn); + hf_sco_conn = NULL; + } else { + bt_shell_warn("Unknown SCO disconnected (%p != %p)", hf_sco_conn, sco_conn); + } } void hf_service(struct bt_hfp_hf *hf, uint32_t value) @@ -998,14 +1010,26 @@ static void ag_disconnected(struct bt_hfp_ag *ag) static void ag_sco_connected(struct bt_hfp_ag *ag, struct bt_conn *sco_conn) { - bt_shell_print("ag sco connected"); - hfp_ag_sco_conn = sco_conn; + bt_shell_print("AG SCO connected %p", sco_conn); + + if (hfp_ag_sco_conn != NULL) { + bt_shell_warn("AG SCO conn %p exists", hfp_ag_sco_conn); + return; + } + + hfp_ag_sco_conn = bt_conn_ref(sco_conn); } -static void ag_sco_disconnected(struct bt_hfp_ag *ag) +static void ag_sco_disconnected(struct bt_conn *sco_conn, uint8_t reason) { - bt_shell_print("ag sco disconnected"); - hfp_ag_sco_conn = NULL; + bt_shell_print("AG SCO disconnected %p (reason %u)", sco_conn, reason); + + if (hfp_ag_sco_conn == sco_conn) { + bt_conn_unref(hfp_ag_sco_conn); + hfp_ag_sco_conn = NULL; + } else { + bt_shell_warn("Unknown SCO disconnected (%p != %p)", hfp_ag_sco_conn, sco_conn); + } } static int ag_memory_dial(struct bt_hfp_ag *ag, const char *location, char **number)