All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Frédéric Danis" <frederic.danis@collabora.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v2 4/5] audio/hfp-hf: Add HFP SLC connection and event support
Date: Thu, 11 Dec 2025 19:34:28 +0100	[thread overview]
Message-ID: <20251211183429.419619-4-frederic.danis@collabora.com> (raw)
In-Reply-To: <20251211183429.419619-1-frederic.danis@collabora.com>

This implements the HFP HF SLC connection and events support for the
Telephony DBus interface.
---
v1->v2: Improve commit message

 profiles/audio/hfp-hf.c | 96 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/profiles/audio/hfp-hf.c b/profiles/audio/hfp-hf.c
index 5375168cf..d25cda389 100644
--- a/profiles/audio/hfp-hf.c
+++ b/profiles/audio/hfp-hf.c
@@ -40,6 +40,7 @@
 #include "src/plugin.h"
 #include "src/profile.h"
 #include "src/service.h"
+#include "src/shared/hfp.h"
 
 #include "telephony.h"
 
@@ -50,12 +51,25 @@ struct hfp_device {
 	struct telephony	*telephony;
 	uint16_t		version;
 	GIOChannel		*io;
+	struct hfp_hf		*hf;
 };
 
+static void hfp_hf_debug(const char *str, void *user_data)
+{
+	DBG_IDX(0xffff, "%s", str);
+}
+
 static void device_destroy(struct hfp_device *dev)
 {
 	DBG("%s", telephony_get_path(dev->telephony));
 
+	telephony_set_state(dev->telephony, DISCONNECTING);
+
+	if (dev->hf) {
+		hfp_hf_unref(dev->hf);
+		dev->hf = NULL;
+	}
+
 	if (dev->io) {
 		g_io_channel_unref(dev->io);
 		dev->io = NULL;
@@ -64,6 +78,62 @@ static void device_destroy(struct hfp_device *dev)
 	telephony_unregister_interface(dev->telephony);
 }
 
+static void hfp_hf_update_indicator(enum hfp_indicator indicator, uint32_t val,
+							void *user_data)
+{
+	struct hfp_device *dev = user_data;
+
+	switch (indicator) {
+	case HFP_INDICATOR_SERVICE:
+		telephony_set_network_service(dev->telephony, val);
+		break;
+	case HFP_INDICATOR_CALL:
+		break;
+	case HFP_INDICATOR_CALLSETUP:
+		break;
+	case HFP_INDICATOR_CALLHELD:
+		break;
+	case HFP_INDICATOR_SIGNAL:
+		telephony_set_signal(dev->telephony, val);
+		break;
+	case HFP_INDICATOR_ROAM:
+		telephony_set_roaming(dev->telephony, val);
+		break;
+	case HFP_INDICATOR_BATTCHG:
+		telephony_set_battchg(dev->telephony, val);
+		break;
+	case HFP_INDICATOR_LAST:
+	default:
+		DBG("Unknown signal indicator: %u", indicator);
+	}
+}
+
+static void hfp_hf_session_ready_cb(enum hfp_result res, enum hfp_error cme_err,
+							void *user_data)
+{
+	struct hfp_device *dev = user_data;
+
+	if (res != HFP_RESULT_OK) {
+		error("Session setup error: %d, dropping connection", res);
+		hfp_hf_disconnect(dev->hf);
+		return;
+	}
+
+	telephony_set_state(dev->telephony, CONNECTED);
+}
+
+static struct hfp_hf_callbacks hf_session_callbacks = {
+	.session_ready = hfp_hf_session_ready_cb,
+	.update_indicator = hfp_hf_update_indicator,
+};
+
+static void hfp_disconnect_watch(void *user_data)
+{
+	DBG("");
+
+	device_destroy(user_data);
+}
+
 static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	struct hfp_device *dev = user_data;
@@ -76,8 +146,27 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 		goto failed;
 	}
 
+	dev->hf = hfp_hf_new(g_io_channel_unix_get_fd(chan));
+	if (!dev->hf) {
+		error("Could not create hfp io");
+		goto failed;
+	}
+
+	hfp_hf_set_debug(dev->hf, hfp_hf_debug, NULL, NULL);
 	g_io_channel_set_close_on_unref(chan, FALSE);
 
+	hfp_hf_set_close_on_unref(dev->hf, true);
+	hfp_hf_set_disconnect_handler(dev->hf, hfp_disconnect_watch,
+					dev, NULL);
+	hfp_hf_session_register(dev->hf, &hf_session_callbacks, dev);
+
+	if (!hfp_hf_session(dev->hf)) {
+		error("Could not start SLC creation");
+		hfp_hf_disconnect(dev->hf);
+		goto failed;
+	}
+
+	telephony_set_state(dev->telephony, SESSION_CONNECTING);
 	btd_service_connecting_complete(service, 0);
 
 	return;
@@ -149,8 +238,15 @@ static int hfp_connect(struct btd_service *service)
 
 static int hfp_disconnect(struct btd_service *service)
 {
+	struct hfp_device *dev;
+
 	DBG("");
 
+	dev = btd_service_get_user_data(service);
+
+	if (dev->hf)
+		hfp_hf_disconnect(dev->hf);
+
 	btd_service_disconnecting_complete(service, 0);
 
 	return 0;
-- 
2.43.0


  parent reply	other threads:[~2025-12-11 18:34 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-11 18:34 [PATCH BlueZ v2 1/5] doc: Add new telephony related profiles interfaces Frédéric Danis
2025-12-11 18:34 ` [PATCH BlueZ v2 2/5] audio/telephony: Add shared interfaces implementation Frédéric Danis
2025-12-11 18:34 ` [PATCH BlueZ v2 3/5] audio/hfp-hf: Add skeleton for HFP profile Frédéric Danis
2025-12-11 18:34 ` Frédéric Danis [this message]
2025-12-11 18:34 ` [PATCH BlueZ v2 5/5] client/telephony: Add new submenu Frédéric Danis
2025-12-11 19:37 ` [BlueZ,v2,1/5] doc: Add new telephony related profiles interfaces bluez.test.bot
2025-12-12 15:30 ` [PATCH BlueZ v2 1/5] " patchwork-bot+bluetooth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251211183429.419619-4-frederic.danis@collabora.com \
    --to=frederic.danis@collabora.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.