From: Archie Pusaka Date: Mon, 3 Aug 2020 06:52:24 +0000 (+0800) Subject: input/device: Send UHID_DESTROY upon disconnection X-Git-Tag: submit/tizen/20210606.232858~24 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c9e030fc85896794495596128e87803ecf3412e9;p=platform%2Fupstream%2Fbluez.git input/device: Send UHID_DESTROY upon disconnection According to the uhid documentation: "If your device disconnects, you should send an UHID_DESTROY event" Signed-off-by: Anuj Jain Signed-off-by: Ayush Garg --- diff --git a/profiles/input/device.c b/profiles/input/device.c index 94dba27a..dd57b763 100644 --- a/profiles/input/device.c +++ b/profiles/input/device.c @@ -119,6 +119,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) { @@ -400,6 +401,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; } @@ -976,6 +981,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) { @@ -1150,7 +1177,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); }