diff --git a/src/adapter.c b/src/adapter.c
index fd425e6..a107214 100644
--- a/src/adapter.c
+++ b/src/adapter.c
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;
return;
}
- device_remove_connection(device, bdaddr_type, &remove_device);
+ device_remove_connection(device, bdaddr_type, &remove_device, reason);
device_cancel_authentication(device, TRUE);
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,
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 56583f7..2ecf145 100644
--- a/src/device.c
+++ b/src/device.c
{ }
};
+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)
dev, NULL);
}
+static void device_disconnected(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 = "Unspecified";
+ break;
+ case MGMT_DEV_DISCONN_TIMEOUT:
+ name = "org.bluez.Reason.Timeout";
+ message = "Connection timeout";
+ break;
+ case MGMT_DEV_DISCONN_LOCAL_HOST:
+ name = "org.bluez.Reason.Local";
+ message = "Connection terminated by local host";
+ break;
+ case MGMT_DEV_DISCONN_REMOTE:
+ name = "org.bluez.Reason.Remote";
+ message = "Connection terminated by remote user";
+ break;
+ case MGMT_DEV_DISCONN_AUTH_FAILURE:
+ name = "org.bluez.Reason.Authentication";
+ message = "Connection terminated due to authentication failure";
+ break;
+ case MGMT_DEV_DISCONN_LOCAL_HOST_SUSPEND:
+ name = "org.bluez.Reason.Suspend";
+ message = "Connection terminated by local host for suspend";
+ break;
+ default:
+ warn("Unknown disconnection value: %u", reason);
+ name = "org.bluez.Reason.Unknown";
+ message = "Unspecified";
+ }
+
+ 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;
g_slist_free_full(device->eir_uuids, g_free);
device->eir_uuids = NULL;
+ device_disconnected(device, reason);
+
g_dbus_emit_property_changed(dbus_conn, device->path,
DEVICE_INTERFACE, "Connected");
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 a35bb13..4eebceb 100644
--- a/src/device.h
+++ b/src/device.h
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],