This is an RFC for introducing a new D-Bus api for manipulating the LE
Advertising data that is sent. Implementing this will mean some MGMT level
changes to support sending the HCI command correctly and not overwriting the
data when switching modes.
This is meant to be a generic API for setting the data and not specifically
targetted for any particular application, so the goal is completeness to the
spec and clarity while introducing a higher level of abstraction than
"use these bytes".
Michael Janssen (1):
doc: Add Advertising API documentation
doc/advertising-api.txt | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 124 insertions(+)
create mode 100644 doc/advertising-api.txt
--
2.2.0.rc0.207.ga3a616c
Hi Marcel,
On Thu, Jan 29, 2015 at 5:03 AM, Marcel Holtmann <[email protected]> wrot=
e:
> Hi Michael,
>
>>>> doc/advertising-api.txt | 124 ++++++++++++++++++++++++++++++++++++++++=
++++++++
>>>> 1 file changed, 124 insertions(+)
>>>> create mode 100644 doc/advertising-api.txt
>>>>
>>>> diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
>>>> new file mode 100644
>>>> index 0000000..6a325c7
>>>> --- /dev/null
>>>> +++ b/doc/advertising-api.txt
>>>> @@ -0,0 +1,124 @@
>>>> +LE Advertising Manager
>>>> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>>>> +
>>>> +LE Advertising Manager allows external applications to control the ac=
tivity and
>>>> +the content of LE Advertising Events. Applications may use the prope=
rties of
>>>> +this object to modify the advertising data elements included in Adver=
tising
>>>> +Events, and enable and disable advertising.
>>>> +
>>>
>>> I was looking into this the other day. And what we really want is multi=
ple advertising instances. So that if you have hardware support, the kernel=
can map it to a hardware feature, if you don't, then the kernel will emula=
te it with rotating the advertising information.
>>>
>>> From a low-level LE link layer that is all valid since you can have mul=
tiple LL state machines active at the same time. It is just currently there=
is not HCI to actually handle this.
>>>
>>> Where I am sitting right now, this should be done with the API that pro=
vides the support for GATT service application.
>>>
>>> What this means is that when you want to use the D-Bus GATT API to writ=
e a GATT service in an application, then this service should be able to say=
, I want to advertise with these settings. And then bluetoothd and the kern=
el will manage this for the lifetime of this GATT service application.
>>
>> I'm not opposed to this, but how would we deal with advertising data
>> that is not tied to a specific GATT service, i.e. iBeacon or similar?
>> Also if we are rotating between all the advertising packets, having a
>> lot of services may be a problem for rotating. I'm also unclear on
>> what receivers of the advertisement data will do if they are from the
>> same address (non-random). The idea behind having a single manager
>> was that the bytes in the advertising data are limited, so managed
>> through a single point to ensure exact data is in there.
>
> iBeacon would be just a special case. We do want reference count an app w=
anting to publish an iBeacon frame. Also keep in mind that with iBeacons we=
would need the whole AD since it is actually rather large.
>
> And of course it would be optional for service to advertise with special =
entries. Some service might not want to ever advertise. For example battery=
service or something that is there and can be utilized, but does not reall=
y have a counterpart on the other side that requires it to be discovered. F=
or me this just means that the GATT service/application will tell bluetooth=
d that is requires to include this UUID or service data or something else. =
Or if it is optional. I think what is more important is that if you want to=
advertise without being connectable like for iBeacons (or broadcaster role=
in LE speak).
>
> Advertising different data with the same address is valid, but should be =
avoided if we can. However in some cases we might not have a chance since A=
D and scan response fields are tiny.
>
>>> From the kernel side this means we just allow multiple combinations of =
advertising type, interval, address, advertising data, scan response data a=
nd something new I can not talk about in public yet.
>>
>> This sounds good to me, I was also considering to have scan response
>> data, since it is related and similar.
>>
>>> I want to include advertising type here since you might want to use ADV=
_NONCONN_IND with a non-resolvable random address for some broadcast detail=
s every 10 minutes, but that should interfere with the details you might wa=
nt to broadcast for your weight scale application that is looking for a mas=
ter to reconnect.
>>>
>>> While the kernel always has the default advertising data and scan respo=
nse data as it does right now (which I would call application/service 0), w=
e want to allow for multiple application/services in addition to that. And =
I do have a basic idea on how to do this from a mgmt API point of view. How=
ever there is some new Bluetooth SIG work ongoing that I might want to be p=
repared for before posting this.
>>
>> I'd rather not wait for BT SIG work to land before we do something
>> here. Advertisement has been in the spec for a long time and BlueZ
>> can't do anything but the basic flags and TX power (advertisement) and
>> name (scan response).
>> Yes, looking at this closer there's nothing an app can control, and
>> it's doubly mandatory so probably remove this and just tack it on the
>> front of any advertising data that gets sent when it's required.
>>
>>>> +
>>>> + array(array{byte}) ManufacturerSpecificData
>>>> +
>>>> + Manufacturer specific data. Each entry is trans=
mitted
>>>> + as a a separate advertisement data type.
>>>
>>> You need to define the manufacturer ID here as well.
>>
>> The array is meant to include the Manufacturer ID placed in the first
>> two bytes of each entry.
>
> That would mean exposing little endian data to an application. That is go=
ing to break. Apple already did not figure out on how to encode their own m=
anufacturer id correctly ;)
>
> So you really want a array{struct(uint16,array{byte}} here.
>
>>>> +
>>>> + array(string) SolicitUUIDs
>>>> +
>>>> + List of UUIDs to include in the
>>>> + "service-solicitation" advertisement data.
>>>> +
>>>> + dict(string,array{byte}) ServiceData
>>>> +
>>>> + Dictionary of Service UUIDs attached to data ass=
ociated
>>>> + with that service to include in the "service-dat=
a"
>>>> + advertisement data.
>>>
>>> If I remember this correctly, then this allows multiple instances for t=
he same UUID.
>>
>> array(struct(string,array{byte})) then
>>
>>>> +
>>>> + array{byte} TargetAddress
>>>> +
>>>> + Target Address to use in the "random-target-addr=
ess" or
>>>> + "public-target-address"
>>>
>>> The reason why the AD types have two here is that you need to worry abo=
ut the actual address type in LE. And honestly I would not worry about this=
at all since it is not used in anywhere at the moment.
>>
>> I was confused by these two Advertising Types anyway because why
>> wouldn't you just use ADV_DIRECT_IND instead. I'm okay with removing
>> them.
>
> Actually they can contain multiple address. So it would be say you use AD=
V_IND and then put 2 or more addresses in the list so you see who these are=
for. But as I said, I have not seen these used ever.
>
> And HID devices utilize ADV_DIRECT_IND since that makes more sense. In ad=
dition with Bluetooth 4.1 you get low-duty cycle directed advertising. So a=
lot more value in using ADV_DIRECT_IND.
>
>>>> +
>>>> + int AdvertisingInterval
>>>> +
>>>> + The interval to advertise at, in 0.625ms units. =
Minimum
>>>> + is 32 (20ms), maximum is 16384 (10.24s)
>>>> +
>>>> + Possible Errors: org.bluez.Error.InvalidArgument
>>>
>>> This is something that should be fundamentally taken from the basic inp=
ut. If we are running multiple instances of advertising, then providing the=
min and max values are important. However this one has a big problem. The =
HCI side takes an interval so that they controller can move it. The AD expe=
cts to give you the exact one. This is not something that can be used succe=
ssful.
>>>
>>> And actually this has a technical change coming that I can not talk abo=
ut in public.
>>>
>>> However what we do want to provide is the slave connection interval (in=
case we want to allow connections with this instance), but right now we ar=
e not even utilizing this from the central side. Which is something we shou=
ld be doing. However it means that we need to scan before calling LE connec=
t. Hint hint hint ;)
>>>
>>>> +
>>>> + array{byte} LEAddress
>>>> +
>>>> + Address to advertise as the LE Address for this =
device.
>>>
>>> This is for LE out-of-band pairing and has nothing to do with advertisi=
ng.
>>>
>>>> +
>>>> + string LEPreferred
>>>> +
>>>> + The preferred role of this device if it supports=
both
>>>> + Central and Peripheral roles. One of "central" =
or
>>>> + "peripheral". This influences the advertised va=
lue of
>>>> + the "le-role" advertising data type when both mo=
des are
>>>> + supported.
>>>
>>> Same here. This is for LE out-of-band pairing.
>>
>> Both of these aren't prohibited (like the other OOB data fields) from
>> being in the advertisement / scan response. I included them for
>> completeness. If they aren't going to be used in practice (like the
>> target address fields) we can remove them.
>
> There are prohibited. It is just that the CSS document does not explicitl=
y say it. We most likely should just file an errata against it and get this=
fixed.
>
>>
>>>> +
>>>> + int AdvertisingLength (read-only)
>>>> +
>>>> + Calculated length of the Advertising Data packet=
.
>>>
>>> Seems rather useless information. Also does not really factor in the ca=
se that some data might be in the scan response packet.
>>
>> This would be useful to see whether the packet is too long with
>> current data in it. I guess it would be clarified that it is the
>> calculated response length if everything was included. As for scan
>> response, this wasn't meant to handle that but it does have close ties
>> to this doesn't it.
>
> Personally I would never do it this way. I would do it like this:
>
> app -> bluetoothd: I need a, b, c fields included
>
> bluetoothd -> app: Okay, but I can only do b and c at the moment
>
> app: I am okay with that / I am not okay with that
>
I was thinking about org.bluez.GattManager1.RegisterService taking
that as options e.g. {"Data", "..."}, {"ManufacturerData", (...)},
etc, or we can have an agent interface with these details which would
help if these can change over time since then the app just need to
emit PropertiesChanged signal so bluetoothd can update them without
having to remove and add them back, we could actually handle the
advertising implicitly if there is any agent with data we advertise
all of them remove we stop advertising. Obviously this goes in
addition to GattService1, GattCharacteristic1, etc. In the other hand
if we have this in GattManager this may look like GATT specific so
perhaps renaming it to ServiceManager or LEServiceManager would be
better, but overall I think it is a much cleaner API to control
Advertisement Data, well cleaner and less error prone because setting
a property + calling Advertise seems prone to races.
--=20
Luiz Augusto von Dentz
Hi Michael,
>>> doc/advertising-api.txt | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 124 insertions(+)
>>> create mode 100644 doc/advertising-api.txt
>>>
>>> diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
>>> new file mode 100644
>>> index 0000000..6a325c7
>>> --- /dev/null
>>> +++ b/doc/advertising-api.txt
>>> @@ -0,0 +1,124 @@
>>> +LE Advertising Manager
>>> +======================
>>> +
>>> +LE Advertising Manager allows external applications to control the activity and
>>> +the content of LE Advertising Events. Applications may use the properties of
>>> +this object to modify the advertising data elements included in Advertising
>>> +Events, and enable and disable advertising.
>>> +
>>
>> I was looking into this the other day. And what we really want is multiple advertising instances. So that if you have hardware support, the kernel can map it to a hardware feature, if you don't, then the kernel will emulate it with rotating the advertising information.
>>
>> From a low-level LE link layer that is all valid since you can have multiple LL state machines active at the same time. It is just currently there is not HCI to actually handle this.
>>
>> Where I am sitting right now, this should be done with the API that provides the support for GATT service application.
>>
>> What this means is that when you want to use the D-Bus GATT API to write a GATT service in an application, then this service should be able to say, I want to advertise with these settings. And then bluetoothd and the kernel will manage this for the lifetime of this GATT service application.
>
> I'm not opposed to this, but how would we deal with advertising data
> that is not tied to a specific GATT service, i.e. iBeacon or similar?
> Also if we are rotating between all the advertising packets, having a
> lot of services may be a problem for rotating. I'm also unclear on
> what receivers of the advertisement data will do if they are from the
> same address (non-random). The idea behind having a single manager
> was that the bytes in the advertising data are limited, so managed
> through a single point to ensure exact data is in there.
iBeacon would be just a special case. We do want reference count an app wanting to publish an iBeacon frame. Also keep in mind that with iBeacons we would need the whole AD since it is actually rather large.
And of course it would be optional for service to advertise with special entries. Some service might not want to ever advertise. For example battery service or something that is there and can be utilized, but does not really have a counterpart on the other side that requires it to be discovered. For me this just means that the GATT service/application will tell bluetoothd that is requires to include this UUID or service data or something else. Or if it is optional. I think what is more important is that if you want to advertise without being connectable like for iBeacons (or broadcaster role in LE speak).
Advertising different data with the same address is valid, but should be avoided if we can. However in some cases we might not have a chance since AD and scan response fields are tiny.
>> From the kernel side this means we just allow multiple combinations of advertising type, interval, address, advertising data, scan response data and something new I can not talk about in public yet.
>
> This sounds good to me, I was also considering to have scan response
> data, since it is related and similar.
>
>> I want to include advertising type here since you might want to use ADV_NONCONN_IND with a non-resolvable random address for some broadcast details every 10 minutes, but that should interfere with the details you might want to broadcast for your weight scale application that is looking for a master to reconnect.
>>
>> While the kernel always has the default advertising data and scan response data as it does right now (which I would call application/service 0), we want to allow for multiple application/services in addition to that. And I do have a basic idea on how to do this from a mgmt API point of view. However there is some new Bluetooth SIG work ongoing that I might want to be prepared for before posting this.
>
> I'd rather not wait for BT SIG work to land before we do something
> here. Advertisement has been in the spec for a long time and BlueZ
> can't do anything but the basic flags and TX power (advertisement) and
> name (scan response).
> Yes, looking at this closer there's nothing an app can control, and
> it's doubly mandatory so probably remove this and just tack it on the
> front of any advertising data that gets sent when it's required.
>
>>> +
>>> + array(array{byte}) ManufacturerSpecificData
>>> +
>>> + Manufacturer specific data. Each entry is transmitted
>>> + as a a separate advertisement data type.
>>
>> You need to define the manufacturer ID here as well.
>
> The array is meant to include the Manufacturer ID placed in the first
> two bytes of each entry.
That would mean exposing little endian data to an application. That is going to break. Apple already did not figure out on how to encode their own manufacturer id correctly ;)
So you really want a array{struct(uint16,array{byte}} here.
>>> +
>>> + array(string) SolicitUUIDs
>>> +
>>> + List of UUIDs to include in the
>>> + "service-solicitation" advertisement data.
>>> +
>>> + dict(string,array{byte}) ServiceData
>>> +
>>> + Dictionary of Service UUIDs attached to data associated
>>> + with that service to include in the "service-data"
>>> + advertisement data.
>>
>> If I remember this correctly, then this allows multiple instances for the same UUID.
>
> array(struct(string,array{byte})) then
>
>>> +
>>> + array{byte} TargetAddress
>>> +
>>> + Target Address to use in the "random-target-address" or
>>> + "public-target-address"
>>
>> The reason why the AD types have two here is that you need to worry about the actual address type in LE. And honestly I would not worry about this at all since it is not used in anywhere at the moment.
>
> I was confused by these two Advertising Types anyway because why
> wouldn't you just use ADV_DIRECT_IND instead. I'm okay with removing
> them.
Actually they can contain multiple address. So it would be say you use ADV_IND and then put 2 or more addresses in the list so you see who these are for. But as I said, I have not seen these used ever.
And HID devices utilize ADV_DIRECT_IND since that makes more sense. In addition with Bluetooth 4.1 you get low-duty cycle directed advertising. So a lot more value in using ADV_DIRECT_IND.
>>> +
>>> + int AdvertisingInterval
>>> +
>>> + The interval to advertise at, in 0.625ms units. Minimum
>>> + is 32 (20ms), maximum is 16384 (10.24s)
>>> +
>>> + Possible Errors: org.bluez.Error.InvalidArgument
>>
>> This is something that should be fundamentally taken from the basic input. If we are running multiple instances of advertising, then providing the min and max values are important. However this one has a big problem. The HCI side takes an interval so that they controller can move it. The AD expects to give you the exact one. This is not something that can be used successful.
>>
>> And actually this has a technical change coming that I can not talk about in public.
>>
>> However what we do want to provide is the slave connection interval (in case we want to allow connections with this instance), but right now we are not even utilizing this from the central side. Which is something we should be doing. However it means that we need to scan before calling LE connect. Hint hint hint ;)
>>
>>> +
>>> + array{byte} LEAddress
>>> +
>>> + Address to advertise as the LE Address for this device.
>>
>> This is for LE out-of-band pairing and has nothing to do with advertising.
>>
>>> +
>>> + string LEPreferred
>>> +
>>> + The preferred role of this device if it supports both
>>> + Central and Peripheral roles. One of "central" or
>>> + "peripheral". This influences the advertised value of
>>> + the "le-role" advertising data type when both modes are
>>> + supported.
>>
>> Same here. This is for LE out-of-band pairing.
>
> Both of these aren't prohibited (like the other OOB data fields) from
> being in the advertisement / scan response. I included them for
> completeness. If they aren't going to be used in practice (like the
> target address fields) we can remove them.
There are prohibited. It is just that the CSS document does not explicitly say it. We most likely should just file an errata against it and get this fixed.
>
>>> +
>>> + int AdvertisingLength (read-only)
>>> +
>>> + Calculated length of the Advertising Data packet.
>>
>> Seems rather useless information. Also does not really factor in the case that some data might be in the scan response packet.
>
> This would be useful to see whether the packet is too long with
> current data in it. I guess it would be clarified that it is the
> calculated response length if everything was included. As for scan
> response, this wasn't meant to handle that but it does have close ties
> to this doesn't it.
Personally I would never do it this way. I would do it like this:
app -> bluetoothd: I need a, b, c fields included
bluetoothd -> app: Okay, but I can only do b and c at the moment
app: I am okay with that / I am not okay with that
Regards
Marcel
Hi Michael,
> doc/advertising-api.txt | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 124 insertions(+)
> create mode 100644 doc/advertising-api.txt
>
> diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
> new file mode 100644
> index 0000000..6a325c7
> --- /dev/null
> +++ b/doc/advertising-api.txt
> @@ -0,0 +1,124 @@
> +LE Advertising Manager
> +======================
> +
> +LE Advertising Manager allows external applications to control the activity and
> +the content of LE Advertising Events. Applications may use the properties of
> +this object to modify the advertising data elements included in Advertising
> +Events, and enable and disable advertising.
> +
I was looking into this the other day. And what we really want is multiple advertising instances. So that if you have hardware support, the kernel can map it to a hardware feature, if you don't, then the kernel will emulate it with rotating the advertising information.
>From a low-level LE link layer that is all valid since you can have multiple LL state machines active at the same time. It is just currently there is not HCI to actually handle this.
Where I am sitting right now, this should be done with the API that provides the support for GATT service application.
What this means is that when you want to use the D-Bus GATT API to write a GATT service in an application, then this service should be able to say, I want to advertise with these settings. And then bluetoothd and the kernel will manage this for the lifetime of this GATT service application.
>From the kernel side this means we just allow multiple combinations of advertising type, interval, address, advertising data, scan response data and something new I can not talk about in public yet.
I want to include advertising type here since you might want to use ADV_NONCONN_IND with a non-resolvable random address for some broadcast details every 10 minutes, but that should interfere with the details you might want to broadcast for your weight scale application that is looking for a master to reconnect.
While the kernel always has the default advertising data and scan response data as it does right now (which I would call application/service 0), we want to allow for multiple application/services in addition to that. And I do have a basic idea on how to do this from a mgmt API point of view. However there is some new Bluetooth SIG work ongoing that I might want to be prepared for before posting this.
On side note, we could go as far as allowing an application for peripheral type of task to provide a static random address and we ensure that the controller advertise with that address when in use. This is a bit advanced and crazy stuff, but it is in theory possible.
> +Service org.bluez
> +Interface org.bluez.LEAdvertisingManager1
> +Object path /org/bluez/hciX
> +
> +Methods bool Advertise(int duration)
> +
> + Begins advertising this device according to the
> + settings. Advertisement is enabled for duration seconds
> + from method invocation. A duration of -1 will
> + continuously advertise. To disable advertisement early,
> + set duration to 0.
> +
> + Possible errors: org.bluez.Error.NoData
> +
> + void AdvertiseServiceUUID(string)
> +
> + This method adds a UUID to the set of services which
> + should be included in the advertisement. Use
> + UnadvertiseServiceUUID to remove items from the list.
> + GAP and GATT services cannot be added to the list.
> +
> + Possible errors: org.bluez.Error.AlreadyExists
> + org.bluez.Error.InvalidArgument
> +
> + void UnadvertiseServiceUUID(string)
> + This method removes a UUID from the set of services
> + which are included in the advertisement.
> +
> + Possible errors: org.bluez.Error.DoesNotExist
> +
> +Properties array{string} IncludedTypes
> +
> + Indicates the data types which are included in the
> + advertising data, and their order in the packet. If the
> + advertising data is too long, types that do not fit will
> + be ignored, and the next type will be included if it
> + does fit. An exception to this is the "service-uuids"
> + and the "local-name" type which will be shortened to fit
> + as allowed by the specification.
> +
> + The strings used for each type defined in the Core
> + Specification Supplement and are indicated by these
> + strings:
> + * "service-uuids" - A list of Service UUIDs
> + * "local-name" - Device name as defined by GAP
> + * "flags" - the Advertising data flags
> + * "manufacturer-data" - Manufacturer specific data
> + * "tx-power" - TX Power Level
> + * "slave-connection-interval" - Slave connection
> + interval range for logical connections
> + * "solicit-uuids" - Service Solicitation UUIDs
> + * "service-data" - Service Data
> + * "appearance" - Appearance as defined by GAP
> + * "public-target-address" - Public Target Address
> + * "random-target-address" - Random Target Address
> + * "advertising-interval" - Advertising Interval
> + * "le-address" - LE Device Address
> + * "le-role" - LE Role
> +
> + Defaults to: ["flags", "local-name"]
> +
> + Possible Errors: org.bluez.Error.InvalidArguments
> +
> + array(string) AdvertisedUUIDs (read-only)
> +
> + Sorted List of UUIDs which are currently included in the
> + "service-uuids" advertisement data type.
> +
> + int Flags
> +
> + bitfield of Boolean flags as defined in the Core
> + Specification Supplement, Part A.1.3.2
There are actually pretty much controlled by the core settings of being discoverable or limited discoverable. So nothing really an application should control. Also the LE not supported one is something that always needs to be set and they are mandatory.
> +
> + array(array{byte}) ManufacturerSpecificData
> +
> + Manufacturer specific data. Each entry is transmitted
> + as a a separate advertisement data type.
You need to define the manufacturer ID here as well.
> +
> + array(string) SolicitUUIDs
> +
> + List of UUIDs to include in the
> + "service-solicitation" advertisement data.
> +
> + dict(string,array{byte}) ServiceData
> +
> + Dictionary of Service UUIDs attached to data associated
> + with that service to include in the "service-data"
> + advertisement data.
If I remember this correctly, then this allows multiple instances for the same UUID.
> +
> + array{byte} TargetAddress
> +
> + Target Address to use in the "random-target-address" or
> + "public-target-address"
The reason why the AD types have two here is that you need to worry about the actual address type in LE. And honestly I would not worry about this at all since it is not used in anywhere at the moment.
> +
> + int AdvertisingInterval
> +
> + The interval to advertise at, in 0.625ms units. Minimum
> + is 32 (20ms), maximum is 16384 (10.24s)
> +
> + Possible Errors: org.bluez.Error.InvalidArgument
This is something that should be fundamentally taken from the basic input. If we are running multiple instances of advertising, then providing the min and max values are important. However this one has a big problem. The HCI side takes an interval so that they controller can move it. The AD expects to give you the exact one. This is not something that can be used successful.
And actually this has a technical change coming that I can not talk about in public.
However what we do want to provide is the slave connection interval (in case we want to allow connections with this instance), but right now we are not even utilizing this from the central side. Which is something we should be doing. However it means that we need to scan before calling LE connect. Hint hint hint ;)
> +
> + array{byte} LEAddress
> +
> + Address to advertise as the LE Address for this device.
This is for LE out-of-band pairing and has nothing to do with advertising.
> +
> + string LEPreferred
> +
> + The preferred role of this device if it supports both
> + Central and Peripheral roles. One of "central" or
> + "peripheral". This influences the advertised value of
> + the "le-role" advertising data type when both modes are
> + supported.
Same here. This is for LE out-of-band pairing.
> +
> + int AdvertisingLength (read-only)
> +
> + Calculated length of the Advertising Data packet.
Seems rather useless information. Also does not really factor in the case that some data might be in the scan response packet.
Regards
Marcel
Hi Marcel,
On Wed, Jan 28, 2015 at 1:10 PM, Marcel Holtmann <[email protected]> wrot=
e:
> Hi Michael,
>
>> doc/advertising-api.txt | 124 ++++++++++++++++++++++++++++++++++++++++++=
++++++
>> 1 file changed, 124 insertions(+)
>> create mode 100644 doc/advertising-api.txt
>>
>> diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
>> new file mode 100644
>> index 0000000..6a325c7
>> --- /dev/null
>> +++ b/doc/advertising-api.txt
>> @@ -0,0 +1,124 @@
>> +LE Advertising Manager
>> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>> +
>> +LE Advertising Manager allows external applications to control the acti=
vity and
>> +the content of LE Advertising Events. Applications may use the propert=
ies of
>> +this object to modify the advertising data elements included in Adverti=
sing
>> +Events, and enable and disable advertising.
>> +
>
> I was looking into this the other day. And what we really want is multipl=
e advertising instances. So that if you have hardware support, the kernel c=
an map it to a hardware feature, if you don't, then the kernel will emulate=
it with rotating the advertising information.
>
> From a low-level LE link layer that is all valid since you can have multi=
ple LL state machines active at the same time. It is just currently there i=
s not HCI to actually handle this.
>
> Where I am sitting right now, this should be done with the API that provi=
des the support for GATT service application.
>
> What this means is that when you want to use the D-Bus GATT API to write =
a GATT service in an application, then this service should be able to say, =
I want to advertise with these settings. And then bluetoothd and the kernel=
will manage this for the lifetime of this GATT service application.
I'm not opposed to this, but how would we deal with advertising data
that is not tied to a specific GATT service, i.e. iBeacon or similar?
Also if we are rotating between all the advertising packets, having a
lot of services may be a problem for rotating. I'm also unclear on
what receivers of the advertisement data will do if they are from the
same address (non-random). The idea behind having a single manager
was that the bytes in the advertising data are limited, so managed
through a single point to ensure exact data is in there.
> From the kernel side this means we just allow multiple combinations of ad=
vertising type, interval, address, advertising data, scan response data and=
something new I can not talk about in public yet.
This sounds good to me, I was also considering to have scan response
data, since it is related and similar.
> I want to include advertising type here since you might want to use ADV_N=
ONCONN_IND with a non-resolvable random address for some broadcast details =
every 10 minutes, but that should interfere with the details you might want=
to broadcast for your weight scale application that is looking for a maste=
r to reconnect.
>
> While the kernel always has the default advertising data and scan respons=
e data as it does right now (which I would call application/service 0), we =
want to allow for multiple application/services in addition to that. And I =
do have a basic idea on how to do this from a mgmt API point of view. Howev=
er there is some new Bluetooth SIG work ongoing that I might want to be pre=
pared for before posting this.
I'd rather not wait for BT SIG work to land before we do something
here. Advertisement has been in the spec for a long time and BlueZ
can't do anything but the basic flags and TX power (advertisement) and
name (scan response).
Yes, looking at this closer there's nothing an app can control, and
it's doubly mandatory so probably remove this and just tack it on the
front of any advertising data that gets sent when it's required.
>> +
>> + array(array{byte}) ManufacturerSpecificData
>> +
>> + Manufacturer specific data. Each entry is transmi=
tted
>> + as a a separate advertisement data type.
>
> You need to define the manufacturer ID here as well.
The array is meant to include the Manufacturer ID placed in the first
two bytes of each entry.
>> +
>> + array(string) SolicitUUIDs
>> +
>> + List of UUIDs to include in the
>> + "service-solicitation" advertisement data.
>> +
>> + dict(string,array{byte}) ServiceData
>> +
>> + Dictionary of Service UUIDs attached to data assoc=
iated
>> + with that service to include in the "service-data"
>> + advertisement data.
>
> If I remember this correctly, then this allows multiple instances for the=
same UUID.
array(struct(string,array{byte})) then
>> +
>> + array{byte} TargetAddress
>> +
>> + Target Address to use in the "random-target-addres=
s" or
>> + "public-target-address"
>
> The reason why the AD types have two here is that you need to worry about=
the actual address type in LE. And honestly I would not worry about this a=
t all since it is not used in anywhere at the moment.
I was confused by these two Advertising Types anyway because why
wouldn't you just use ADV_DIRECT_IND instead. I'm okay with removing
them.
>> +
>> + int AdvertisingInterval
>> +
>> + The interval to advertise at, in 0.625ms units. M=
inimum
>> + is 32 (20ms), maximum is 16384 (10.24s)
>> +
>> + Possible Errors: org.bluez.Error.InvalidArgument
>
> This is something that should be fundamentally taken from the basic input=
. If we are running multiple instances of advertising, then providing the m=
in and max values are important. However this one has a big problem. The HC=
I side takes an interval so that they controller can move it. The AD expect=
s to give you the exact one. This is not something that can be used success=
ful.
>
> And actually this has a technical change coming that I can not talk about=
in public.
>
> However what we do want to provide is the slave connection interval (in c=
ase we want to allow connections with this instance), but right now we are =
not even utilizing this from the central side. Which is something we should=
be doing. However it means that we need to scan before calling LE connect.=
Hint hint hint ;)
>
>> +
>> + array{byte} LEAddress
>> +
>> + Address to advertise as the LE Address for this de=
vice.
>
> This is for LE out-of-band pairing and has nothing to do with advertising=
.
>
>> +
>> + string LEPreferred
>> +
>> + The preferred role of this device if it supports b=
oth
>> + Central and Peripheral roles. One of "central" or
>> + "peripheral". This influences the advertised valu=
e of
>> + the "le-role" advertising data type when both mode=
s are
>> + supported.
>
> Same here. This is for LE out-of-band pairing.
Both of these aren't prohibited (like the other OOB data fields) from
being in the advertisement / scan response. I included them for
completeness. If they aren't going to be used in practice (like the
target address fields) we can remove them.
>> +
>> + int AdvertisingLength (read-only)
>> +
>> + Calculated length of the Advertising Data packet.
>
> Seems rather useless information. Also does not really factor in the case=
that some data might be in the scan response packet.
This would be useful to see whether the packet is too long with
current data in it. I guess it would be clarified that it is the
calculated response length if everything was included. As for scan
response, this wasn't meant to handle that but it does have close ties
to this doesn't it.
Cheers,
Mike
---
doc/advertising-api.txt | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 124 insertions(+)
create mode 100644 doc/advertising-api.txt
diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
new file mode 100644
index 0000000..6a325c7
--- /dev/null
+++ b/doc/advertising-api.txt
@@ -0,0 +1,124 @@
+LE Advertising Manager
+======================
+
+LE Advertising Manager allows external applications to control the activity and
+the content of LE Advertising Events. Applications may use the properties of
+this object to modify the advertising data elements included in Advertising
+Events, and enable and disable advertising.
+
+Service org.bluez
+Interface org.bluez.LEAdvertisingManager1
+Object path /org/bluez/hciX
+
+Methods bool Advertise(int duration)
+
+ Begins advertising this device according to the
+ settings. Advertisement is enabled for duration seconds
+ from method invocation. A duration of -1 will
+ continuously advertise. To disable advertisement early,
+ set duration to 0.
+
+ Possible errors: org.bluez.Error.NoData
+
+ void AdvertiseServiceUUID(string)
+
+ This method adds a UUID to the set of services which
+ should be included in the advertisement. Use
+ UnadvertiseServiceUUID to remove items from the list.
+ GAP and GATT services cannot be added to the list.
+
+ Possible errors: org.bluez.Error.AlreadyExists
+ org.bluez.Error.InvalidArgument
+
+ void UnadvertiseServiceUUID(string)
+ This method removes a UUID from the set of services
+ which are included in the advertisement.
+
+ Possible errors: org.bluez.Error.DoesNotExist
+
+Properties array{string} IncludedTypes
+
+ Indicates the data types which are included in the
+ advertising data, and their order in the packet. If the
+ advertising data is too long, types that do not fit will
+ be ignored, and the next type will be included if it
+ does fit. An exception to this is the "service-uuids"
+ and the "local-name" type which will be shortened to fit
+ as allowed by the specification.
+
+ The strings used for each type defined in the Core
+ Specification Supplement and are indicated by these
+ strings:
+ * "service-uuids" - A list of Service UUIDs
+ * "local-name" - Device name as defined by GAP
+ * "flags" - the Advertising data flags
+ * "manufacturer-data" - Manufacturer specific data
+ * "tx-power" - TX Power Level
+ * "slave-connection-interval" - Slave connection
+ interval range for logical connections
+ * "solicit-uuids" - Service Solicitation UUIDs
+ * "service-data" - Service Data
+ * "appearance" - Appearance as defined by GAP
+ * "public-target-address" - Public Target Address
+ * "random-target-address" - Random Target Address
+ * "advertising-interval" - Advertising Interval
+ * "le-address" - LE Device Address
+ * "le-role" - LE Role
+
+ Defaults to: ["flags", "local-name"]
+
+ Possible Errors: org.bluez.Error.InvalidArguments
+
+ array(string) AdvertisedUUIDs (read-only)
+
+ Sorted List of UUIDs which are currently included in the
+ "service-uuids" advertisement data type.
+
+ int Flags
+
+ bitfield of Boolean flags as defined in the Core
+ Specification Supplement, Part A.1.3.2
+
+ array(array{byte}) ManufacturerSpecificData
+
+ Manufacturer specific data. Each entry is transmitted
+ as a a separate advertisement data type.
+
+ array(string) SolicitUUIDs
+
+ List of UUIDs to include in the
+ "service-solicitation" advertisement data.
+
+ dict(string,array{byte}) ServiceData
+
+ Dictionary of Service UUIDs attached to data associated
+ with that service to include in the "service-data"
+ advertisement data.
+
+ array{byte} TargetAddress
+
+ Target Address to use in the "random-target-address" or
+ "public-target-address"
+
+ int AdvertisingInterval
+
+ The interval to advertise at, in 0.625ms units. Minimum
+ is 32 (20ms), maximum is 16384 (10.24s)
+
+ Possible Errors: org.bluez.Error.InvalidArgument
+
+ array{byte} LEAddress
+
+ Address to advertise as the LE Address for this device.
+
+ string LEPreferred
+
+ The preferred role of this device if it supports both
+ Central and Peripheral roles. One of "central" or
+ "peripheral". This influences the advertised value of
+ the "le-role" advertising data type when both modes are
+ supported.
+
+ int AdvertisingLength (read-only)
+
+ Calculated length of the Advertising Data packet.
--
2.2.0.rc0.207.ga3a616c