Message ID | 20200627235318.Bluez.v2.2.I16f38fd33617bbbf84d144605861b8391605a761@changeid (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | [Bluez,v2,1/2] device: add device_remove_bonding function | expand |
Hi Bluez maintainers, Could you take a look at this patch? Thanks, Archie On Sat, 27 Jun 2020 at 23:54, Archie Pusaka <apusaka@google.com> wrote: > > From: Archie Pusaka <apusaka@chromium.org> > > From Bluetooth HID Profile 1.1 Spec: If a Virtual Cable is > unplugged via a HID control Virtual Unplug command, then both the > Bluetooth HID device and Bluetooth HID Host shall destroy or > invalidate all Bluetooth bonding and Virtual Cable information > that was previously stored in persistent memory for the respective > Virtually Cabled devices and hosts. > > This patch removes the bonding information upon receiving and/or > sending a "virtual cable unplug". > > Reviewed-by: Alain Michaud <alainm@chromium.org> > --- > > Changes in v2: > - Properly pass the correct argument to device_remove_bonding > - rename unbond_on_disconnect to virtual_cable_unplug > > profiles/input/device.c | 23 ++++++++++++++++++++++- > 1 file changed, 22 insertions(+), 1 deletion(-) > > diff --git a/profiles/input/device.c b/profiles/input/device.c > index d3724ed54..a76ab90bd 100644 > --- a/profiles/input/device.c > +++ b/profiles/input/device.c > @@ -88,6 +88,7 @@ struct input_device { > uint8_t report_req_pending; > guint report_req_timer; > uint32_t report_rsp_id; > + bool virtual_cable_unplug; > }; > > static int idle_timeout = 0; > @@ -148,6 +149,14 @@ static void input_device_free(struct input_device *idev) > g_free(idev); > } > > +static void virtual_cable_unplug(struct input_device *idev) > +{ > + device_remove_bonding(idev->device, > + btd_device_get_bdaddr_type(idev->device)); > + > + idev->virtual_cable_unplug = false; > +} > + > static bool hidp_send_message(GIOChannel *chan, uint8_t hdr, > const uint8_t *data, size_t size) > { > @@ -188,6 +197,9 @@ static bool hidp_send_message(GIOChannel *chan, uint8_t hdr, > static bool hidp_send_ctrl_message(struct input_device *idev, uint8_t hdr, > const uint8_t *data, size_t size) > { > + if (hdr == (HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG)) > + idev->virtual_cable_unplug = true; > + > return hidp_send_message(idev->ctrl_io, hdr, data, size); > } > > @@ -344,6 +356,9 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data > /* Enter the auto-reconnect mode if needed */ > input_device_enter_reconnect_mode(idev); > > + if (!idev->ctrl_io && idev->virtual_cable_unplug) > + virtual_cable_unplug(idev); > + > return FALSE; > } > > @@ -408,7 +423,7 @@ static void hidp_recv_ctrl_hid_control(struct input_device *idev, uint8_t param) > DBG(""); > > if (param == HIDP_CTRL_VIRTUAL_CABLE_UNPLUG) > - connection_disconnect(idev, 0); > + connection_disconnect(idev, (1 << HIDP_VIRTUAL_CABLE_UNPLUG)); > } > > static void hidp_recv_ctrl_data(struct input_device *idev, uint8_t param, > @@ -532,6 +547,9 @@ static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data > if (idev->intr_io && !(cond & G_IO_NVAL)) > g_io_channel_shutdown(idev->intr_io, TRUE, NULL); > > + if (!idev->intr_io && idev->virtual_cable_unplug) > + virtual_cable_unplug(idev); > + > return FALSE; > } > > @@ -1042,6 +1060,9 @@ static int connection_disconnect(struct input_device *idev, uint32_t flags) > shutdown(sock, SHUT_WR); > } > > + if (flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) > + idev->virtual_cable_unplug = true; > + > if (idev->uhid) > return 0; > else > -- > 2.27.0.212.ge8ba1cc988-goog >
diff --git a/profiles/input/device.c b/profiles/input/device.c index d3724ed54..a76ab90bd 100644 --- a/profiles/input/device.c +++ b/profiles/input/device.c @@ -88,6 +88,7 @@ struct input_device { uint8_t report_req_pending; guint report_req_timer; uint32_t report_rsp_id; + bool virtual_cable_unplug; }; static int idle_timeout = 0; @@ -148,6 +149,14 @@ static void input_device_free(struct input_device *idev) g_free(idev); } +static void virtual_cable_unplug(struct input_device *idev) +{ + device_remove_bonding(idev->device, + btd_device_get_bdaddr_type(idev->device)); + + idev->virtual_cable_unplug = false; +} + static bool hidp_send_message(GIOChannel *chan, uint8_t hdr, const uint8_t *data, size_t size) { @@ -188,6 +197,9 @@ static bool hidp_send_message(GIOChannel *chan, uint8_t hdr, static bool hidp_send_ctrl_message(struct input_device *idev, uint8_t hdr, const uint8_t *data, size_t size) { + if (hdr == (HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG)) + idev->virtual_cable_unplug = true; + return hidp_send_message(idev->ctrl_io, hdr, data, size); } @@ -344,6 +356,9 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data /* Enter the auto-reconnect mode if needed */ input_device_enter_reconnect_mode(idev); + if (!idev->ctrl_io && idev->virtual_cable_unplug) + virtual_cable_unplug(idev); + return FALSE; } @@ -408,7 +423,7 @@ static void hidp_recv_ctrl_hid_control(struct input_device *idev, uint8_t param) DBG(""); if (param == HIDP_CTRL_VIRTUAL_CABLE_UNPLUG) - connection_disconnect(idev, 0); + connection_disconnect(idev, (1 << HIDP_VIRTUAL_CABLE_UNPLUG)); } static void hidp_recv_ctrl_data(struct input_device *idev, uint8_t param, @@ -532,6 +547,9 @@ static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data if (idev->intr_io && !(cond & G_IO_NVAL)) g_io_channel_shutdown(idev->intr_io, TRUE, NULL); + if (!idev->intr_io && idev->virtual_cable_unplug) + virtual_cable_unplug(idev); + return FALSE; } @@ -1042,6 +1060,9 @@ static int connection_disconnect(struct input_device *idev, uint32_t flags) shutdown(sock, SHUT_WR); } + if (flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) + idev->virtual_cable_unplug = true; + if (idev->uhid) return 0; else