From: "Frédéric Danis" <frederic.danis@collabora.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v4 2/4] src/device: Add Disconnected signal to propagate disconnection reason
Date: Fri, 23 May 2025 09:26:45 +0200 [thread overview]
Message-ID: <20250523072647.689324-3-frederic.danis@collabora.com> (raw)
In-Reply-To: <20250523072647.689324-1-frederic.danis@collabora.com>
Currently a client application is informed of the disconnection by the
update of the Connected property to false.
This sends a Disconnected signal with the disconnection reason before
the property is updated.
This helps client application to know the reason for the disconnection
and to take appropriate action.
---
v1->v2: Propagate numerical reason instead of text one
v2->v3: Replace numerical value by name and message to be more consistent
with Device.Connect error reply.
src/adapter.c | 13 +++++++-----
src/device.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++--
src/device.h | 3 ++-
3 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index fd425e6d2..a10721489 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -7549,7 +7549,8 @@ struct agent *adapter_get_agent(struct btd_adapter *adapter)
static void adapter_remove_connection(struct btd_adapter *adapter,
struct btd_device *device,
- uint8_t bdaddr_type)
+ uint8_t bdaddr_type,
+ uint8_t reason)
{
bool remove_device = false;
@@ -7560,7 +7561,7 @@ static void adapter_remove_connection(struct btd_adapter *adapter,
return;
}
- device_remove_connection(device, bdaddr_type, &remove_device);
+ device_remove_connection(device, bdaddr_type, &remove_device, reason);
device_cancel_authentication(device, TRUE);
@@ -7601,9 +7602,11 @@ static void adapter_stop(struct btd_adapter *adapter)
struct btd_device *device = adapter->connections->data;
uint8_t addr_type = btd_device_get_bdaddr_type(device);
- adapter_remove_connection(adapter, device, BDADDR_BREDR);
+ adapter_remove_connection(adapter, device, BDADDR_BREDR,
+ MGMT_DEV_DISCONN_UNKNOWN);
if (addr_type != BDADDR_BREDR)
- adapter_remove_connection(adapter, device, addr_type);
+ adapter_remove_connection(adapter, device, addr_type,
+ MGMT_DEV_DISCONN_UNKNOWN);
}
g_dbus_emit_property_changed(dbus_conn, adapter->path,
@@ -8551,7 +8554,7 @@ static void dev_disconnected(struct btd_adapter *adapter,
device = btd_adapter_find_device(adapter, &addr->bdaddr, addr->type);
if (device) {
- adapter_remove_connection(adapter, device, addr->type);
+ adapter_remove_connection(adapter, device, addr->type, reason);
disconnect_notify(device, reason);
}
diff --git a/src/device.c b/src/device.c
index 56583f71a..9591fe0a7 100644
--- a/src/device.c
+++ b/src/device.c
@@ -3481,6 +3481,12 @@ static const GDBusMethodTable device_methods[] = {
{ }
};
+static const GDBusSignalTable device_signals[] = {
+ { GDBUS_SIGNAL("Disconnected",
+ GDBUS_ARGS({ "name", "s" }, { "message", "s" })) },
+ { }
+};
+
static gboolean
dev_property_get_prefer_bearer(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
@@ -3732,8 +3738,53 @@ static void set_temporary_timer(struct btd_device *dev, unsigned int timeout)
dev, NULL);
}
+static void emit_disconnect_reason(struct btd_device *device,
+ uint8_t reason)
+{
+ const char *name;
+ const char *message;
+
+ switch (reason) {
+ case MGMT_DEV_DISCONN_UNKNOWN:
+ name = "org.bluez.Reason.Unknown";
+ message = "disconnection-unknown";
+ break;
+ case MGMT_DEV_DISCONN_TIMEOUT:
+ name = "org.bluez.Reason.Timeout";
+ message = "disconnection-timeout";
+ break;
+ case MGMT_DEV_DISCONN_LOCAL_HOST:
+ name = "org.bluez.Reason.Local";
+ message = "disconnection-localhost";
+ break;
+ case MGMT_DEV_DISCONN_REMOTE:
+ name = "org.bluez.Reason.Remote";
+ message = "disconnection-remote";
+ break;
+ case MGMT_DEV_DISCONN_AUTH_FAILURE:
+ name = "org.bluez.Reason.Authentication";
+ message = "disconnection-authentication-failure";
+ break;
+ case MGMT_DEV_DISCONN_LOCAL_HOST_SUSPEND:
+ name = "org.bluez.Reason.LocalSuspend";
+ message = "disconnection-local-suspend";
+ break;
+ default:
+ warn("Unknown disconnection value: %u", reason);
+ name = "org.bluez.Reason.Unknown";
+ message = "disconnection-undefined";
+ }
+
+ g_dbus_emit_signal(dbus_conn, device->path, DEVICE_INTERFACE,
+ "Disconnected",
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &message,
+ DBUS_TYPE_INVALID);
+}
+
void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type,
- bool *remove)
+ bool *remove,
+ uint8_t reason)
{
struct bearer_state *state = get_state(device, bdaddr_type);
DBusMessage *reply;
@@ -3803,6 +3854,8 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type,
g_slist_free_full(device->eir_uuids, g_free);
device->eir_uuids = NULL;
+ emit_disconnect_reason(device, reason);
+
g_dbus_emit_property_changed(dbus_conn, device->path,
DEVICE_INTERFACE, "Connected");
@@ -4704,7 +4757,7 @@ static struct btd_device *device_new(struct btd_adapter *adapter,
if (g_dbus_register_interface(dbus_conn,
device->path, DEVICE_INTERFACE,
- device_methods, NULL,
+ device_methods, device_signals,
device_properties, device,
device_free) == FALSE) {
error("Unable to register device interface for %s", address);
diff --git a/src/device.h b/src/device.h
index a35bb1386..4eebcebe9 100644
--- a/src/device.h
+++ b/src/device.h
@@ -134,7 +134,8 @@ gboolean device_is_authenticating(struct btd_device *device);
void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type,
uint32_t flags);
void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type,
- bool *remove);
+ bool *remove,
+ uint8_t reason);
void device_request_disconnect(struct btd_device *device, DBusMessage *msg);
bool device_is_disconnecting(struct btd_device *device);
void device_set_ltk(struct btd_device *device, const uint8_t val[16],
--
2.43.0
next prev parent reply other threads:[~2025-05-23 7:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-23 7:26 [PATCH BlueZ v4 0/4] Propagate disconnection reason Frédéric Danis
2025-05-23 7:26 ` [PATCH BlueZ v4 1/4] lib/mgmt: Add MGMT_DEV_DISCONN_AUTH_FAILURE define Frédéric Danis
2025-05-23 8:46 ` Propagate disconnection reason bluez.test.bot
2025-05-23 7:26 ` Frédéric Danis [this message]
2025-05-23 7:26 ` [PATCH BlueZ v4 3/4] doc/device: Add Disconnected signal Frédéric Danis
2025-05-23 7:26 ` [PATCH BlueZ v4 4/4] client: Display disconnection reason Frédéric Danis
2025-05-23 15:20 ` [PATCH BlueZ v4 0/4] Propagate " 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=20250523072647.689324-3-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox