2014-01-16 22:17:05

by Petri Gynther

[permalink] [raw]
Subject: Questions on BlueZ 5.13: device creation API + persistent hid/input pipeline

linux-bluetooth:

I'm running BlueZ 5.13 userland + backported BlueZ kernel modules on
an embedded system that I'm working on. The kernel on the system is
2.6.37-based. I ported uhid driver manually from 3.12.

I'm successfully using Bluetooth classic HID remote control and
Bluetooth LE HoG remote control on this system. However, I have two
questions:

1) The Bluetooth classic remote that I'm using is not discoverable. It
is only connectable. When the remote is not paired, it sends its
Bluetooth MAC address to the host via IR, and the host needs to add
this device to BlueZ's discovered devices database. But, how can I do
that via D-Bus API? BlueZ 5 porting guide specifically mentions that "
... we decided to simply get rid of explicit CreateDevice /
CreatePairedDevice methods and instead dynamically create device
objects as they are discovered during device discovery."

So, is there no API available to add non-discoverable devices in BlueZ 5?

I have worked around this issue by manually adding this remote to
<storage path>, so that bluetoothd creates the device on reboot via
device_create_from_storage(). But, I would prefer not to restart
bluetoothd every time a non-discoverable device needs to be added.


2) There is a difference in HID vs HoG hid/input pipeline persistence.
When the Bluetooth classic HID remote disconnects, the corresponding
hid and input kernel devices are destroyed. And when it reconnects,
hid and input devices are created again. This adds a lot of
unnecessary delay at reconnect. And, the first keypress is always lost
on reconnect.

In contrast, for the Bluetooth LE HoG remote, the hid/input pipeline
is persistent. When HoG remote disconnects, hid and input devices
remain in the system and are reused when the HoG remote reconnects.

Is there a way to make Bluetooth classic HID behave the same as HoG,
i.e. retain the hid and input kernel devices on disconnect and reuse
them on reconnect?


2014-01-16 23:42:52

by Marcel Holtmann

[permalink] [raw]
Subject: Re: Questions on BlueZ 5.13: device creation API + persistent hid/input pipeline

Hi Petri,

>>> 2) There is a difference in HID vs HoG hid/input pipeline persistence.
>>> When the Bluetooth classic HID remote disconnects, the corresponding
>>> hid and input kernel devices are destroyed. And when it reconnects,
>>> hid and input devices are created again. This adds a lot of
>>> unnecessary delay at reconnect. And, the first keypress is always lost
>>> on reconnect.
>>>
>>> In contrast, for the Bluetooth LE HoG remote, the hid/input pipeline
>>> is persistent. When HoG remote disconnects, hid and input devices
>>> remain in the system and are reused when the HoG remote reconnects.
>>>
>>> Is there a way to make Bluetooth classic HID behave the same as HoG,
>>> i.e. retain the hid and input kernel devices on disconnect and reuse
>>> them on reconnect?
>>
>> HID and HoG work a little bit different. HID uses a kernel transport driver while HoG uses /dev/uhid to do the work. Porting HID over to use /dev/uhid is certainly a possibility. We have considered that, but nobody has done that work yet.
>>
>> Please remember that HID (with HIDP) is finding its right place in /sys device tree. While all HoG using /dev/uhid are considered virtual devices. There is a semi proposal that we agreed on New Orleans during the PlumbersConf, but I have no idea if David actually implemented it.
>>
>> Another option is to make the HIDP transport smarter and persistent by integrating it into BlueZ 5?s kernel mgmt support. That however means you will need a much more recent Bluetooth subsystem. So 2.6.37 is not getting you anywhere near that even if we change HIDP support.
>
> I'm using BlueZ kernel modules (bluetooth, hidp) from Linux
> backports-3.13-rc2-1, so that is pretty recent code. Works fine on top
> of 2.6.37. However, my HID and input drivers come from 2.6.37, as they
> are not available in backports-3.13-rc2-1.
>
> I understand the difference between HID and HoG. Both hidp and uhid
> are hid_ll_drivers. HID input reports stay entirely in kernel, whereas
> HoG is handled in bluetoothd and input reports are passed back to
> kernel via /dev/uhid.
>
> Assuming the latest HIDP code, what kind of effort would it be to make
> the hid/input pipeline persistent when HID remote disconnects and
> reconnects?

for the HIDP code itself there is actually a lot of work. It does not have the model of persistent connections. It is designed to disconnect and reconnect. Since normally when you disconnect your device it is off. Otherwise you just sniff the connection. It is also a bit legacy reason from where L2CAP only had a concept of sockets and not l2cap_chan that only recently got introduced.

Why you are loosing your first input, that sounds like a bug we should look into. That should actually not happen.

To be honest, the easiest for you might be to run HID over /dev/uhid as well. So HoG and HID are both using /dev/uhid. A port of the input plugin to use /dev/uhid for HID should be straight forward. All the building blocks should be already there.

Regards

Marcel


2014-01-16 23:03:15

by Petri Gynther

[permalink] [raw]
Subject: Re: Questions on BlueZ 5.13: device creation API + persistent hid/input pipeline

Hi Marcel,

Thanks for your reply. Please see inline.

On Thu, Jan 16, 2014 at 2:30 PM, Marcel Holtmann <[email protected]> wrot=
e:
> Hi Petri,
>
>> I'm running BlueZ 5.13 userland + backported BlueZ kernel modules on
>> an embedded system that I'm working on. The kernel on the system is
>> 2.6.37-based. I ported uhid driver manually from 3.12.
>>
>> I'm successfully using Bluetooth classic HID remote control and
>> Bluetooth LE HoG remote control on this system. However, I have two
>> questions:
>>
>> 1) The Bluetooth classic remote that I'm using is not discoverable. It
>> is only connectable. When the remote is not paired, it sends its
>> Bluetooth MAC address to the host via IR, and the host needs to add
>> this device to BlueZ's discovered devices database. But, how can I do
>> that via D-Bus API? BlueZ 5 porting guide specifically mentions that "
>> ... we decided to simply get rid of explicit CreateDevice /
>> CreatePairedDevice methods and instead dynamically create device
>> objects as they are discovered during device discovery."
>>
>> So, is there no API available to add non-discoverable devices in BlueZ 5=
?
>>
>> I have worked around this issue by manually adding this remote to
>> <storage path>, so that bluetoothd creates the device on reboot via
>> device_create_from_storage(). But, I would prefer not to restart
>> bluetoothd every time a non-discoverable device needs to be added.
>
> I have never heard of a remote that uses IR to setup the pairing. A creat=
ive way of doing out-of-band pairing.
>
> What I think you are looking for is what the PS3 controllers do when the =
share their details over USB and then after that connect over Bluetooth HID=
. Have a look at plugins/sixaxis.c to see how they do it. BlueZ has a plugi=
n API for doing exactly these kind of automated setup/pairing type of cases=
.
>
> So you want to write a plugin for this remote.
>
> The other plugin you might want to look at is plugins/autopair.c if it ac=
tually requires to also create an encrypted link.
>

Thank you for this info. I will look into plugins/sixaxis.c and
plugins/autopair.c.

>> 2) There is a difference in HID vs HoG hid/input pipeline persistence.
>> When the Bluetooth classic HID remote disconnects, the corresponding
>> hid and input kernel devices are destroyed. And when it reconnects,
>> hid and input devices are created again. This adds a lot of
>> unnecessary delay at reconnect. And, the first keypress is always lost
>> on reconnect.
>>
>> In contrast, for the Bluetooth LE HoG remote, the hid/input pipeline
>> is persistent. When HoG remote disconnects, hid and input devices
>> remain in the system and are reused when the HoG remote reconnects.
>>
>> Is there a way to make Bluetooth classic HID behave the same as HoG,
>> i.e. retain the hid and input kernel devices on disconnect and reuse
>> them on reconnect?
>
> HID and HoG work a little bit different. HID uses a kernel transport driv=
er while HoG uses /dev/uhid to do the work. Porting HID over to use /dev/uh=
id is certainly a possibility. We have considered that, but nobody has done=
that work yet.
>
> Please remember that HID (with HIDP) is finding its right place in /sys d=
evice tree. While all HoG using /dev/uhid are considered virtual devices. T=
here is a semi proposal that we agreed on New Orleans during the PlumbersCo=
nf, but I have no idea if David actually implemented it.
>
> Another option is to make the HIDP transport smarter and persistent by in=
tegrating it into BlueZ 5=E2=80=99s kernel mgmt support. That however means=
you will need a much more recent Bluetooth subsystem. So 2.6.37 is not get=
ting you anywhere near that even if we change HIDP support.
>
> Regards
>
> Marcel
>

I'm using BlueZ kernel modules (bluetooth, hidp) from Linux
backports-3.13-rc2-1, so that is pretty recent code. Works fine on top
of 2.6.37. However, my HID and input drivers come from 2.6.37, as they
are not available in backports-3.13-rc2-1.

I understand the difference between HID and HoG. Both hidp and uhid
are hid_ll_drivers. HID input reports stay entirely in kernel, whereas
HoG is handled in bluetoothd and input reports are passed back to
kernel via /dev/uhid.

Assuming the latest HIDP code, what kind of effort would it be to make
the hid/input pipeline persistent when HID remote disconnects and
reconnects?

-- Petri

2014-01-16 22:30:52

by Marcel Holtmann

[permalink] [raw]
Subject: Re: Questions on BlueZ 5.13: device creation API + persistent hid/input pipeline

Hi Petri,

> I'm running BlueZ 5.13 userland + backported BlueZ kernel modules on
> an embedded system that I'm working on. The kernel on the system is
> 2.6.37-based. I ported uhid driver manually from 3.12.
>
> I'm successfully using Bluetooth classic HID remote control and
> Bluetooth LE HoG remote control on this system. However, I have two
> questions:
>
> 1) The Bluetooth classic remote that I'm using is not discoverable. It
> is only connectable. When the remote is not paired, it sends its
> Bluetooth MAC address to the host via IR, and the host needs to add
> this device to BlueZ's discovered devices database. But, how can I do
> that via D-Bus API? BlueZ 5 porting guide specifically mentions that "
> ... we decided to simply get rid of explicit CreateDevice /
> CreatePairedDevice methods and instead dynamically create device
> objects as they are discovered during device discovery."
>
> So, is there no API available to add non-discoverable devices in BlueZ 5?
>
> I have worked around this issue by manually adding this remote to
> <storage path>, so that bluetoothd creates the device on reboot via
> device_create_from_storage(). But, I would prefer not to restart
> bluetoothd every time a non-discoverable device needs to be added.

I have never heard of a remote that uses IR to setup the pairing. A creative way of doing out-of-band pairing.

What I think you are looking for is what the PS3 controllers do when the share their details over USB and then after that connect over Bluetooth HID. Have a look at plugins/sixaxis.c to see how they do it. BlueZ has a plugin API for doing exactly these kind of automated setup/pairing type of cases.

So you want to write a plugin for this remote.

The other plugin you might want to look at is plugins/autopair.c if it actually requires to also create an encrypted link.

> 2) There is a difference in HID vs HoG hid/input pipeline persistence.
> When the Bluetooth classic HID remote disconnects, the corresponding
> hid and input kernel devices are destroyed. And when it reconnects,
> hid and input devices are created again. This adds a lot of
> unnecessary delay at reconnect. And, the first keypress is always lost
> on reconnect.
>
> In contrast, for the Bluetooth LE HoG remote, the hid/input pipeline
> is persistent. When HoG remote disconnects, hid and input devices
> remain in the system and are reused when the HoG remote reconnects.
>
> Is there a way to make Bluetooth classic HID behave the same as HoG,
> i.e. retain the hid and input kernel devices on disconnect and reuse
> them on reconnect?

HID and HoG work a little bit different. HID uses a kernel transport driver while HoG uses /dev/uhid to do the work. Porting HID over to use /dev/uhid is certainly a possibility. We have considered that, but nobody has done that work yet.

Please remember that HID (with HIDP) is finding its right place in /sys device tree. While all HoG using /dev/uhid are considered virtual devices. There is a semi proposal that we agreed on New Orleans during the PlumbersConf, but I have no idea if David actually implemented it.

Another option is to make the HIDP transport smarter and persistent by integrating it into BlueZ 5?s kernel mgmt support. That however means you will need a much more recent Bluetooth subsystem. So 2.6.37 is not getting you anywhere near that even if we change HIDP support.

Regards

Marcel