diff options
author | Archie Pusaka <apusaka@chromium.org> | 2020-08-03 14:52:24 +0800 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2020-08-03 12:58:54 -0700 |
commit | bd1b1d9e55976231b2a48d2a48a4cad81f4ccda5 (patch) | |
tree | e0fae2c958bba4314a8e57518e42ac473c32680f /profiles/input | |
parent | 41400986618e1534880ed0e4f1ede858e1519fe6 (diff) | |
download | bluez-bd1b1d9e55976231b2a48d2a48a4cad81f4ccda5.tar.gz |
input/device: Send UHID_DESTROY upon disconnection
According to the uhid documentation: "If your device disconnects,
you should send an UHID_DESTROY event"
Diffstat (limited to 'profiles/input')
-rw-r--r-- | profiles/input/device.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/profiles/input/device.c b/profiles/input/device.c index 757290080..8fc04be37 100644 --- a/profiles/input/device.c +++ b/profiles/input/device.c @@ -117,6 +117,7 @@ bool input_get_classic_bonded_only(void) static void input_device_enter_reconnect_mode(struct input_device *idev); static int connection_disconnect(struct input_device *idev, uint32_t flags); +static int uhid_disconnect(struct input_device *idev); static bool input_device_bonded(struct input_device *idev) { @@ -393,6 +394,10 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data if (!idev->ctrl_io && idev->virtual_cable_unplug) virtual_cable_unplug(idev); + /* If connection abruptly ended, uhid might be not yet disconnected */ + if (idev->uhid_created) + uhid_disconnect(idev); + return FALSE; } @@ -969,6 +974,28 @@ static int uhid_connadd(struct input_device *idev, struct hidp_connadd_req *req) return err; } +static int uhid_disconnect(struct input_device *idev) +{ + int err; + struct uhid_event ev; + + if (!idev->uhid_created) + return 0; + + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_DESTROY; + + err = bt_uhid_send(idev->uhid, &ev); + if (err < 0) { + error("bt_uhid_send: %s", strerror(-err)); + return err; + } + + idev->uhid_created = false; + + return err; +} + static gboolean encrypt_notify(GIOChannel *io, GIOCondition condition, gpointer data) { @@ -1127,7 +1154,7 @@ static int connection_disconnect(struct input_device *idev, uint32_t flags) idev->virtual_cable_unplug = true; if (idev->uhid) - return 0; + return uhid_disconnect(idev); else return ioctl_disconnect(idev, flags); } |