2014-06-27 19:16:29

by Scott James Remnant

[permalink] [raw]
Subject: [PATCH] [RFC] doc: Add StartDiscoveryWithOptions

This patch proposes an extension to the D-Bus Adapter API to permit
the application to specify whether it wishes to discover BR/EDR
or LE devices.

Rationale is to permit an application, only interested in an LE device
with intent on using GATT to not cause the large power drain of
performing BR/EDR Inquiry.
---
doc/adapter-api.txt | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)

diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt
index 74d235a..668644d 100644
--- a/doc/adapter-api.txt
+++ b/doc/adapter-api.txt
@@ -22,6 +22,29 @@ Methods void StartDiscovery()
Possible errors: org.bluez.Error.NotReady
org.bluez.Error.Failed

+ void StartDiscoveryWithOptions(dict options)
+
+ This method starts the device discovery session, as
+ StartDiscovery(), but lets the client specify
+ additional options. Use StopDiscovery to release the
+ sessions acquired.
+
+ possible options:
+
+ boolean Classic:
+
+ Specifies whether discovery of BR/EDR
+ devices should be performed.
+
+ boolean LowEnergy:
+
+ Specifies whether discovery of LE
+ devices should be performed.
+
+ Possible errors: org.bluez.Error.NotReady
+ org.bluez.Error.Failed
+
+
void StopDiscovery()

This method will cancel any previous StartDiscovery
--
1.9.3 (Apple Git-50)



2014-06-30 20:16:34

by Scott James Remnant

[permalink] [raw]
Subject: Re: [PATCH] [RFC] doc: Add StartDiscoveryWithOptions

On Fri, Jun 27, 2014 at 1:15 PM, Marcel Holtmann <[email protected]> wrot=
e:

>
> The reason why I like to keep discovery separate from searching for a kno=
wn device, these are separate operations. There is subtle difference betwee=
n advertising non-discoverable and advertising discoverable. While many dev=
ices always advertise discoverable, they do not need it. And StartDiscovery=
will not report non-discoverable devices back. However a FindDevice of cou=
rse can look for a specific device matching its search pattern even if it i=
s not discoverable.
>

Thinking about this a bit more, does StartDiscovery return devices
advertising with non-connectable undirected advertising? If the goal
of that method is for the UI then does it make sense for it to be
returning devices we can't connect to as well?

Scott
--=20
Have you ever, ever felt like this?
Had strange things happen? Are you going round the twist?

2014-06-27 20:49:08

by Scott James Remnant

[permalink] [raw]
Subject: Re: [PATCH] [RFC] doc: Add StartDiscoveryWithOptions

On Fri, Jun 27, 2014 at 1:15 PM, Marcel Holtmann <[email protected]> wrot=
e:

>> Rationale is to permit an application, only interested in an LE device
>> with intent on using GATT to not cause the large power drain of
>> performing BR/EDR Inquiry.

> If I take one step back and look from an application point of view, then =
I might actually want something totally different. I think what really want=
is a FindDevices method that will return a list of objects that fulfill my=
search pattern. So each application can start their own FindDevices method=
and bluetoothd will take care of making sure that each application is serv=
ed properly.
>

This kind of API makes sense too.

Would you just want the method to return a list of objects, in which
case what would the timeout be? Or would you want a session-like API
as with discovery?

It seems to fit typical use cases:

- FindDevices( { health heart rate profile } ) -> list of nearby
heart rate monitors

- FindDevices( { BR/EDR profile } ) -> list of paired devices that support=
it

What about the "I lost my keys" use case?

1. FindDevices( { profile id of stickies } ) -> list of nearby stickies
2. Check objects EIR for the specific UUID of the beacon attached to
your keys, repeat until it's visible
3. Watch for DeviceChanged notifications on that object, checking the
RSSI property each time, until you're on top of them

If the beacon-ish profile the particular sticky you're using has
decided to just use a completely custom field in the AD with no
standard fields (who'd do that, I mean, seriously?!), I guess you'd
just FindDevices() and filter them all by hand.

> Keep also in mind that it might be neat to have a feature where you regis=
ter an observer like agent that gets notified when a device with certain pa=
ttern is found. Once we have all the background scanning figured out in the=
kernel, this becomes a possibility. And that is a better approach than alw=
ays triggering active scanning. The simplest pattern could just be the iden=
tity address of a device. With all this beacon stuff you might want to find=
a device, but have no need to connect since all the data is present the ad=
vertising data. Or it could be simply that the service data contains a sequ=
ence counter that allows you to tell if connection is required or not.
>

This would suggest more of an observer API, than a method call to
return devices. The thing I like here is that it could even map
directly to controller methods, so for certain searches the controller
could remain in passive scan even while the host is in a sleep state,
and wake the host using the usual mechanisms when found.

e.g. this would be more like

<- org.bluez.Search1.RegisterSearch(object searcher, dict search)

-> org.bluez.Search1.DeviceFound(object device)
-> org.bluez.Search1.DeviceFound(object device)
-> org.bluez.Search1.DeviceFound(object device)

than

<- org.bluez.Adapter1.FindDevices(dict search)
-> object[]


If the search dictionary has the option to search by address, e.g. :

<- org.bluez.Search1.RegisterSearch(this, { address: "addr" })

then that would cutely map to:

HCI LE Set Scan Parameters( ScanningFilter=3D0x01 )
HCI LE Add Device To White List( address=3Daddr )

if no other searches were ongoing, and assumedly just extend the white
list for paired HoG devices if those were already being passively
scanned that way.

Scott
--=20
Have you ever, ever felt like this?
Had strange things happen? Are you going round the twist?

2014-06-27 20:15:09

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH] [RFC] doc: Add StartDiscoveryWithOptions

Hi Scott,

> This patch proposes an extension to the D-Bus Adapter API to permit
> the application to specify whether it wishes to discover BR/EDR
> or LE devices.
>
> Rationale is to permit an application, only interested in an LE device
> with intent on using GATT to not cause the large power drain of
> performing BR/EDR Inquiry.
> ---
> doc/adapter-api.txt | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt
> index 74d235a..668644d 100644
> --- a/doc/adapter-api.txt
> +++ b/doc/adapter-api.txt
> @@ -22,6 +22,29 @@ Methods void StartDiscovery()
> Possible errors: org.bluez.Error.NotReady
> org.bluez.Error.Failed
>
> + void StartDiscoveryWithOptions(dict options)
> +
> + This method starts the device discovery session, as
> + StartDiscovery(), but lets the client specify
> + additional options. Use StopDiscovery to release the
> + sessions acquired.
> +
> + possible options:
> +
> + boolean Classic:
> +
> + Specifies whether discovery of BR/EDR
> + devices should be performed.
> +
> + boolean LowEnergy:
> +
> + Specifies whether discovery of LE
> + devices should be performed.

I hoped that we will be able to avoid adding an StartDiscoveryWithOptions. However the way the LE application world is going, we need to provide application the option to search for their counterpart peripheral.

We however will most likely not need this for BR/EDR since that application model there is pretty clear that we only do discovery from the settings screen and not from a specific application.

If I take one step back and look from an application point of view, then I might actually want something totally different. I think what really want is a FindDevices method that will return a list of objects that fulfill my search pattern. So each application can start their own FindDevices method and bluetoothd will take care of making sure that each application is served properly.

I do realize that you are going for the simple approach with just starting LE active scanning and then filtering out the results in a higher layer. However I get the feeling that we better do that inside the daemon and provide the application with a pre-filtered list. And if no search patterns are given, then you get the complete list and can filter by yourself later on.

The reason why I like to keep discovery separate from searching for a known device, these are separate operations. There is subtle difference between advertising non-discoverable and advertising discoverable. While many devices always advertise discoverable, they do not need it. And StartDiscovery will not report non-discoverable devices back. However a FindDevice of course can look for a specific device matching its search pattern even if it is not discoverable.

Keep also in mind that it might be neat to have a feature where you register an observer like agent that gets notified when a device with certain pattern is found. Once we have all the background scanning figured out in the kernel, this becomes a possibility. And that is a better approach than always triggering active scanning. The simplest pattern could just be the identity address of a device. With all this beacon stuff you might want to find a device, but have no need to connect since all the data is present the advertising data. Or it could be simply that the service data contains a sequence counter that allows you to tell if connection is required or not.

These are just a few thoughts that come to mind when we are talking about LE scanning. I like to get LE passive scanning enabled in the kernel and have a mgmt API that we then can map to multiple use cases over D-Bus. And I like it to be smart and as low power consumption as possible.

Regards

Marcel


2014-07-01 15:24:15

by Scott James Remnant

[permalink] [raw]
Subject: Re: [PATCH] [RFC] doc: Add StartDiscoveryWithOptions

On Tue, Jul 1, 2014 at 3:31 AM, Marcel Holtmann <[email protected]> wrote:

> In addition to that, I am thinking that Start Discovery triggered Device Found should be limited to connectable and discoverable events. Unless of course we have them also in Add Device. Then they should be reported out always.
>

This makes sense to me too.

Scott
--
Have you ever, ever felt like this?
Had strange things happen? Are you going round the twist?

2014-07-01 10:31:36

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH] [RFC] doc: Add StartDiscoveryWithOptions

Hi Scott,

>> The reason why I like to keep discovery separate from searching for a known device, these are separate operations. There is subtle difference between advertising non-discoverable and advertising discoverable. While many devices always advertise discoverable, they do not need it. And StartDiscovery will not report non-discoverable devices back. However a FindDevice of course can look for a specific device matching its search pattern even if it is not discoverable.
>>
>
> Thinking about this a bit more, does StartDiscovery return devices
> advertising with non-connectable undirected advertising? If the goal
> of that method is for the UI then does it make sense for it to be
> returning devices we can't connect to as well?

this is an interesting question. So non-connectable or scannable undirected advertising events will not allow for any connection whatsoever. Even if they have the discoverable or limited discoverable flags set.

For the D-Bus API, I think we should only return devices with discoverable and limited discoverable flags set when calling StartDiscovery since that are the ones we are looking for at that point. Should we also return devices that are not connectable is something we might need to discuss.

I think we should not return them since you would expect users to be able to just click on these and pair them. That however will never succeed sine you can not connect to these devices. An alternative option is to just add a property Connectable that allows us to see if we can connect or not. Feels a bit weird to me.

For the kernel side, we have to report a lot of things. However since we now enabled passive scanning, we can be a bit more detailed in what we are supporting.

First thing we have to do is add a new flag to Device Found event that indicates if the device is connectable or not. That is needed no matter what. That alone will allow bluetoothd to do the right filtering and transactions.

In addition to that, I am thinking that Start Discovery triggered Device Found should be limited to connectable and discoverable events. Unless of course we have them also in Add Device. Then they should be reported out always.

And then we start building proper observer API for D-Bus and also extra filtering for the kernel side.

Regards

Marcel