2013-10-14 19:09:50

by Claudio Takahasi

[permalink] [raw]
Subject: [RFC BlueZ v0] doc: Add GATT API

This patch proposes an unified GATT API for local and remote services.
---

Partial implementation of the proposed API:
git://git.infradead.org/users/cktakahasi/bluez.git gatt-api-devel


doc/gatt-api.txt | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 158 insertions(+)
create mode 100644 doc/gatt-api.txt

diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
new file mode 100644
index 0000000..af4d68d
--- /dev/null
+++ b/doc/gatt-api.txt
@@ -0,0 +1,158 @@
+BlueZ D-Bus GATT API description
+********************************
+
+GATT local and remote services share the same high-level D-Bus API. Local
+refers to local GATT based service exported by a BlueZ plugin or an external
+application. Remote refers to GATT services exported by the peer.
+
+BlueZ acts as a proxy, translating ATT operations to D-Bus method calls and
+Properties (or the opposite). Support for D-Bus Object Manager is mandatory for
+external services to allow seamless GATT declarations (Service, Characteristic
+and Descriptors) discovery.
+
+Service hierarchy
+=================
+
+GATT remote and local service representation. Object path for local services
+is freely definable.
+
+External local services should register the services using ServiceManager1
+registration method and must implement ServiceAgent1 interface.
+
+Service org.bluez
+Interface org.bluez.Service1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX
+
+Properties string UUID [read-only]
+
+ 128-bit UUID of the GATT based service. It represents
+ the UUID of a local external service or remote GATT
+ service.
+
+ array{object} Includes [read-only]: Not implemented
+
+ Array of object paths representing the included
+ services of this service.
+
+
+Characteristic hierarchy
+========================
+
+For local GATT defined services, the object paths need to follow the service
+path hierarchy and are freely definable.
+
+Service org.bluez
+Interface org.bluez.Characteristic1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
+
+Properties string UUID [read-only]
+
+ 128-bit characteristic UUID. It represents the UUID of
+ a local external characteristic or remote GATT
+ characteristic.
+
+ object Service [read-only]
+
+ Object path of the GATT service the characteristc
+ belongs to.
+
+ array{byte} Value [read-write]
+
+ Cached Value of the characteristic. If present, the
+ value will be cached by bluetoothd and updated when the
+ PropertiesChanged signal is emitted.
+
+ External services must emit this signal when the
+ characteristic supports notification/indication, so
+ that clients can be notified of the new value.
+
+ array{string} Flags [read-only, optional]
+
+ Defines how the characteristic value can be used. See
+ Core spec page 1898, "Table 3.5: Characteristic
+ Properties bit field" and page 1900, "Table 3.8:
+ Characteristic Extended Properties bit field". Allowed
+ values: "broadcast", "read", "write-without-response",
+ "write", "notify", "indicate",
+ "authenticated-signed-writes", "reliable-write", and
+ "writable-auxiliaries".
+
+
+Characteristic Descriptors hierarchy
+====================================
+
+Local or remote GATT characteristic descriptors hierarchy.
+
+Service org.bluez
+Interface org.bluez.Descriptor1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ
+
+Properties string UUID [read-only]
+
+ 128-bit descriptor UUID. It represents the UUID of a
+ local external descriptor or remote descriptor.
+
+ object Characteristic [read-only]
+
+ Object path of the GATT characteristc the descriptor
+ belongs to.
+
+ array{byte} Value [read-write]
+
+ Raw characteristic descriptor value. For external GATT
+ services, value changes should be reported through
+ PropertiesChanged signal.
+
+ string Permissions [read-only]: To be defined
+
+ Defines read/write authentication and authorization
+ requirements.
+
+Service Manager hierarchy
+=========================
+
+ServiceManager allows external applications to register GATT based services.
+Services should follow the API for Service and Characteristic described above.
+
+For GATT local services, services and characteristics definitions are
+discovered automatically using D-Bus Object Manager.
+
+Service org.bluez
+Interface org.bluez.ServiceManager1 [Experimental]
+Object path /org/bluez
+
+Methods RegisterApplication(object application, dict options)
+
+ Registers remote application services exported under
+ the interface Service1. Characteristic objects must
+ be hierarchical to their service and must use the
+ interface Characteristic1. D-Bus Object Manager is
+ used to fetch the exported objects.
+
+ "application" object path together with the D-Bus system
+ bus connection ID define the identification of the
+ application registering a GATT based service.
+
+ Possible errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.AlreadyExists
+
+ UnregisterApplication(object application)
+
+ This unregisters the application that has been
+ previously registered. The object path parameter
+ must match the same value that has been used
+ on registration.
+
+ Possible errors: org.bluez.Error.DoesNotExist
+
+Service Agent hierarchy
+=======================
+
+Service org.bluez
+Interface org.bluez.ServiceAgent1 [Experimental]
+Object path freely definable
+
+Methods void Release()
+
+ Release this agent. At this point, it will not be used
+ by BlueZ anymore and can be destroyed by the owner.
--
1.8.3.1



2013-10-15 18:39:43

by Claudio Takahasi

[permalink] [raw]
Subject: [RFC BlueZ v1] doc: Add GATT API

This patch proposes an unified GATT API for local and remote services.
---
doc/gatt-api.txt | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 159 insertions(+)
create mode 100644 doc/gatt-api.txt

diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
new file mode 100644
index 0000000..a60d146
--- /dev/null
+++ b/doc/gatt-api.txt
@@ -0,0 +1,159 @@
+BlueZ D-Bus GATT API description
+********************************
+
+GATT local and remote services share the same high-level D-Bus API. Local
+refers to local GATT based service exported by a BlueZ plugin or an external
+application. Remote refers to GATT services exported by the peer.
+
+BlueZ acts as a proxy, translating ATT operations to D-Bus method calls and
+Properties (or the opposite). Support for D-Bus Object Manager is mandatory for
+external services to allow seamless GATT declarations (Service, Characteristic
+and Descriptors) discovery.
+
+Service hierarchy
+=================
+
+GATT remote and local service representation. Object path for local services
+is freely definable.
+
+External local services should register the services using ServiceManager1
+registration method and must implement ServiceAgent1 interface.
+
+Service org.bluez
+Interface org.bluez.Service1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX
+
+Properties string UUID [read-only]
+
+ 128-bit UUID of the GATT based service. It represents
+ the UUID of a local external service or remote GATT
+ service.
+
+ array{object} Includes [read-only]: Not implemented
+
+ Array of object paths representing the included
+ services of this service.
+
+
+Characteristic hierarchy
+========================
+
+For local GATT defined services, the object paths need to follow the service
+path hierarchy and are freely definable.
+
+Service org.bluez
+Interface org.bluez.Characteristic1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
+
+Properties string UUID [read-only]
+
+ 128-bit characteristic UUID. It represents the UUID of
+ a local external characteristic or remote GATT
+ characteristic.
+
+ object Service [read-only]
+
+ Object path of the GATT service the characteristc
+ belongs to.
+
+ array{byte} Value [read-write]
+
+ Cached Value of the characteristic. If present, the
+ value will be cached by bluetoothd and updated when the
+ PropertiesChanged signal is emitted.
+
+ External services must emit this signal when the
+ characteristic supports notification/indication, so
+ that clients can be notified of the new value.
+
+ array{string} Flags [read-only, optional]
+
+ Defines how the characteristic value can be used. See
+ Core spec page 1898, "Table 3.5: Characteristic
+ Properties bit field" and page 1900, "Table 3.8:
+ Characteristic Extended Properties bit field". Allowed
+ values: "broadcast", "read", "write-without-response",
+ "write", "notify", "indicate",
+ "authenticated-signed-writes", "reliable-write", and
+ "writable-auxiliaries".
+
+
+Characteristic Descriptors hierarchy
+====================================
+
+Local or remote GATT characteristic descriptors hierarchy.
+
+Service org.bluez
+Interface org.bluez.Descriptor1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ
+
+Properties string UUID [read-only]
+
+ 128-bit descriptor UUID. It represents the UUID of a
+ local external descriptor or remote descriptor.
+
+ object Characteristic [read-only]
+
+ Object path of the GATT characteristc the descriptor
+ belongs to.
+
+ array{byte} Value [read-write]
+
+ Raw characteristic descriptor value. For external GATT
+ services, value changes should be reported through
+ PropertiesChanged signal.
+
+ string Permissions [read-only]: To be defined
+
+ Defines read/write authentication and authorization
+ requirements.
+
+Application Manager hierarchy
+=============================
+
+Application Manager allows external applications to register GATT based
+services. Services should follow the API for Service and Characteristic
+described above.
+
+For GATT local services, services and characteristics definitions are
+discovered automatically using D-Bus Object Manager.
+
+Service org.bluez
+Interface org.bluez.ApplicationManager1 [Experimental]
+Object path /org/bluez
+
+Methods RegisterAgent(object application, dict options)
+
+ Registers remote application services exported under
+ the interface Service1. Characteristic objects must
+ be hierarchical to their service and must use the
+ interface Characteristic1. D-Bus Object Manager is
+ used to fetch the exported objects.
+
+ "application" object path together with the D-Bus system
+ bus connection ID define the identification of the
+ application registering a GATT based service.
+
+ Possible errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.AlreadyExists
+
+ UnregisterAgent(object application)
+
+ This unregisters the application that has been
+ previously registered. The object path parameter
+ must match the same value that has been used
+ on registration.
+
+ Possible errors: org.bluez.Error.DoesNotExist
+
+Application Agent hierarchy
+===========================
+
+Service unique name
+Interface org.bluez.ApplicationAgent1 [Experimental]
+Object path freely definable
+
+Methods void Release()
+
+ Release this agent. At this point, it will not be used
+ by BlueZ anymore and can be destroyed by the owner.
--
1.8.3.1


2013-10-15 18:36:30

by Claudio Takahasi

[permalink] [raw]
Subject: Re: [RFC BlueZ v0] doc: Add GATT API

Hi Johan:

On Tue, Oct 15, 2013 at 5:35 AM, Johan Hedberg <[email protected]> wrote:
> Hi Claudio,
>
> On Mon, Oct 14, 2013, Claudio Takahasi wrote:
>> +Service Manager hierarchy
>> +=========================
>> +
>> +ServiceManager allows external applications to register GATT based services.
>> +Services should follow the API for Service and Characteristic described above.
>> +
>> +For GATT local services, services and characteristics definitions are
>> +discovered automatically using D-Bus Object Manager.
>> +
>> +Service org.bluez
>> +Interface org.bluez.ServiceManager1 [Experimental]
>> +Object path /org/bluez
>> +
>> +Methods RegisterApplication(object application, dict options)
>> +
>> + Registers remote application services exported under
>> + the interface Service1. Characteristic objects must
>> + be hierarchical to their service and must use the
>> + interface Characteristic1. D-Bus Object Manager is
>> + used to fetch the exported objects.
>> +
>> + "application" object path together with the D-Bus system
>> + bus connection ID define the identification of the
>> + application registering a GATT based service.
>> +
>> + Possible errors: org.bluez.Error.InvalidArguments
>> + org.bluez.Error.AlreadyExists
>> +
>> + UnregisterApplication(object application)
>> +
>> + This unregisters the application that has been
>> + previously registered. The object path parameter
>> + must match the same value that has been used
>> + on registration.
>> +
>> + Possible errors: org.bluez.Error.DoesNotExist
>> +
>> +Service Agent hierarchy
>> +=======================
>> +
>> +Service org.bluez
>
> I suppose this should not be "org.bluez" since it's the agent that's
> providing it.

yup. Copy & paste mistake.

>
>> +Interface org.bluez.ServiceAgent1 [Experimental]
>> +Object path freely definable
>
> If this is the object registered by ServiceManager1.RegisterApplication
> I think we need some renaming. Either this interface should be called
> org.bluez.ServiceApplication1 or the registration method shoud be
> renamed to RegisterAgent.
>
> Or is the idea that an "application" is a set of objects and interfaces
> (services, characteristics, etc.) and as a minimum there must be this
> ServiceAgent1 interface at the root object? In that case the naming
> might make sense.

In my opinion we need a more flexible approach, the agent could handle
local and remote services. Replace "Service" by "Application" seems
to be more suitable.

The same application can run client and server roles. If necessary,
"option" dictionary could be used to inform wanted UUIDs (GATT
client), and connection/scanning requiments.
For server, "option" dictionary could have ID to allow handle
re-allocation. The plan is to use Object Manager, so services object
paths can be omitted and the agent path is freely definable.

Based on what we discussed my suggestion is:

Interfaces:
s/ServiceManager1/ApplicationManager1
s/ServiceAgent1/ApplicationAgent1

Methods:
s/RegisterApplication/RegisterAgent
s/UnregisterApplication/UnregisterAgent

Regards,
Claudio

2013-10-15 08:35:56

by Johan Hedberg

[permalink] [raw]
Subject: Re: [RFC BlueZ v0] doc: Add GATT API

Hi Claudio,

On Mon, Oct 14, 2013, Claudio Takahasi wrote:
> +Service Manager hierarchy
> +=========================
> +
> +ServiceManager allows external applications to register GATT based services.
> +Services should follow the API for Service and Characteristic described above.
> +
> +For GATT local services, services and characteristics definitions are
> +discovered automatically using D-Bus Object Manager.
> +
> +Service org.bluez
> +Interface org.bluez.ServiceManager1 [Experimental]
> +Object path /org/bluez
> +
> +Methods RegisterApplication(object application, dict options)
> +
> + Registers remote application services exported under
> + the interface Service1. Characteristic objects must
> + be hierarchical to their service and must use the
> + interface Characteristic1. D-Bus Object Manager is
> + used to fetch the exported objects.
> +
> + "application" object path together with the D-Bus system
> + bus connection ID define the identification of the
> + application registering a GATT based service.
> +
> + Possible errors: org.bluez.Error.InvalidArguments
> + org.bluez.Error.AlreadyExists
> +
> + UnregisterApplication(object application)
> +
> + This unregisters the application that has been
> + previously registered. The object path parameter
> + must match the same value that has been used
> + on registration.
> +
> + Possible errors: org.bluez.Error.DoesNotExist
> +
> +Service Agent hierarchy
> +=======================
> +
> +Service org.bluez

I suppose this should not be "org.bluez" since it's the agent that's
providing it.

> +Interface org.bluez.ServiceAgent1 [Experimental]
> +Object path freely definable

If this is the object registered by ServiceManager1.RegisterApplication
I think we need some renaming. Either this interface should be called
org.bluez.ServiceApplication1 or the registration method shoud be
renamed to RegisterAgent.

Or is the idea that an "application" is a set of objects and interfaces
(services, characteristics, etc.) and as a minimum there must be this
ServiceAgent1 interface at the root object? In that case the naming
might make sense.

Johan

2013-11-27 20:27:58

by Claudio Takahasi

[permalink] [raw]
Subject: [RFC BlueZ v2] doc: Add GATT API

This patch proposes an unified GATT API for local and remote services.
---
v2: API similar to Profile1 and ProfileManager1

doc/gatt-api.txt | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 145 insertions(+)
create mode 100644 doc/gatt-api.txt

diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
new file mode 100644
index 0000000..d2545b2
--- /dev/null
+++ b/doc/gatt-api.txt
@@ -0,0 +1,145 @@
+BlueZ D-Bus GATT API description
+********************************
+
+GATT local and remote services share the same high-level D-Bus API. Local
+refers to GATT based service exported by a BlueZ plugin or an external
+application. Remote refers to GATT services exported by the peer.
+
+BlueZ acts as a proxy, translating ATT operations to D-Bus method calls and
+Properties (or the opposite). Support for D-Bus Object Manager is mandatory for
+external services to allow seamless GATT declarations (Service, Characteristic
+and Descriptors) discovery.
+
+Service hierarchy
+=================
+
+GATT remote and local service representation. Object path for local services
+is freely definable.
+
+External applications implementing local services must register the services
+using ServiceManager1 registration method and must implement the methods and
+properties defined in Service1 interface.
+
+Service org.bluez
+Interface org.bluez.Service1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX
+
+Methods void Release()
+
+ Release this service. At this point, it will not be
+ used by BlueZ anymore and can be destroyed by the
+ owner. Method applicable to external GATT services
+ implementations only (GATT servers).
+
+Properties string UUID [read-only]
+
+ 128-bit service UUID.
+
+ array{object} Includes [read-only]: Not implemented
+
+ Array of object paths representing the included
+ services of this service.
+
+
+Characteristic hierarchy
+========================
+
+For local GATT defined services, the object paths need to follow the service
+path hierarchy and are freely definable.
+
+Service org.bluez
+Interface org.bluez.Characteristic1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
+
+Properties string UUID [read-only]
+
+ 128-bit characteristic UUID.
+
+ object Service [read-only]
+
+ Object path of the GATT service the characteristc
+ belongs to.
+
+ array{byte} Value [read-write]
+
+ Value read from the remote Bluetooth device or from
+ the external application implementing GATT services.
+
+ array{string} Flags [read-only, optional]
+
+ Defines how the characteristic value can be used. See
+ Core spec page 1898, "Table 3.5: Characteristic
+ Properties bit field" and page 1900, "Table 3.8:
+ Characteristic Extended Properties bit field". Allowed
+ values: "broadcast", "read", "write-without-response",
+ "write", "notify", "indicate",
+ "authenticated-signed-writes", "reliable-write", and
+ "writable-auxiliaries".
+
+
+Characteristic Descriptors hierarchy
+====================================
+
+Local or remote GATT characteristic descriptors hierarchy.
+
+Service org.bluez
+Interface org.bluez.Descriptor1 [Experimental]
+Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ
+
+Properties string UUID [read-only]
+
+ 128-bit descriptor UUID.
+
+ object Characteristic [read-only]
+
+ Object path of the GATT characteristc the descriptor
+ belongs to.
+
+ array{byte} Value [read-write]
+
+ Raw characteristic descriptor value read from the
+ remote Bluetooth device or from the external
+ application implementing GATT services.
+
+ string Permissions [read-only]: To be defined
+
+ Defines read/write authentication and authorization
+ requirements.
+
+Service Manager hierarchy
+=============================
+
+Service Manager allows external applications to register GATT based
+services. Services must follow the API for Service and Characteristic
+described above.
+
+Local GATT services, characteristics and characteristic descriptors are
+discovered automatically using the D-Bus Object Manager interface.
+
+Service org.bluez
+Interface org.bluez.ServiceManager1 [Experimental]
+Object path /org/bluez
+
+Methods RegisterService(object service, dict options)
+
+ Registers remote application service exported under
+ the interface Service1. Characteristic objects must
+ be hierarchical to their service and must use the
+ interface Characteristic1. D-Bus Object Manager is
+ used to fetch the exported objects.
+
+ "service" object path together with the D-Bus system
+ bus connection ID define the identification of the
+ application registering a GATT based service.
+
+ Possible errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.AlreadyExists
+
+ UnregisterService(object service)
+
+ This unregisters the service that has been
+ previously registered. The object path parameter
+ must match the same value that has been used
+ on registration.
+
+ Possible errors: org.bluez.Error.DoesNotExist
--
1.8.3.1


2013-11-27 19:45:05

by Claudio Takahasi

[permalink] [raw]
Subject: Re: [RFC BlueZ v1] doc: Add GATT API

Hi Scott:

On Fri, Nov 15, 2013 at 4:47 PM, Scott James Remnant <[email protected]> wrote:
> On Tue, Nov 12, 2013 at 10:49 AM, Claudio Takahasi
> <[email protected]> wrote:
>
>> On Mon, Nov 11, 2013 at 3:56 PM, Scott James Remnant <[email protected]> wrote:
>>> How will service changed be handled? How will BlueZ track the set of
>>> applications, and the set of services etc. defined by those
>>> applications in a manner that keeps handles consistent? How will it
>>> handle generating the Services Changed notification in the cases where
>>> the set of applications and/or services change, or the handles change?
>>
>> We implemented a hash of declarations. Using the "Id" provided in the
>> options dictionary (see RegisterAgent) we are able to identity if the
>> external service changed its attributes.
>> However, I don' t think we will upstream this approach soon, Marcel
>> wants a simpler approach: always send ServiceChanged.
>>
>
> While this is probably "spec sufficient", and probably sufficient for
> passing qualification, I'm not sure that this is necessarily the best
> approach since this means that BlueZ when acting as a GATT Server
> wouldn't be behaving quite the same as, say, a commodity BTLE device.
>
>>>> +Characteristic hierarchy
>>>> +========================
>>> :
>>>> +Service org.bluez
>>>> +Interface org.bluez.Characteristic1 [Experimental]
>>>> +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
>>>
>>> This would also need a "Permissions" property akin to the one you have
>>> for Descriptors - characteristics can be "not accessible", read-only,
>>> write-only, read/write - and can also require authorization,
>>> authentication, encryption and minimum encryption key sizes - as with
>>> descriptors.
>>
>> It is implemented already, there is an optional "Flags" property :
>> "array{string} Flags [read-only, optional]"
>>
>
> Flags seemed to correspond to the Flags characteristic descriptor and
> not the simple permissions of the characteristic itself.

"Flags" refers to Core SPEC page 1898: "3.3.1.1 Characteristic Properties"
The naming is not helping here. The original suggestion was
"Properties", but it may mislead to D-Bus Properties.

>
>>>> + array{byte} Value [read-write]
>>>> +
>>>> + Cached Value of the characteristic. If present, the
>>>> + value will be cached by bluetoothd and updated when the
>>>> + PropertiesChanged signal is emitted.
>>>> +
>>>> + External services must emit this signal when the
>>>> + characteristic supports notification/indication, so
>>>> + that clients can be notified of the new value.
>>>
>>> The PropertiesChanged signal explains how Notification will be handled
>>> - but how will Indication? How will a service receive the Indication
>>> Confirmation from the remote devices?
>>
>> The bluetoothd core manages the Confirmation. In my opinion clients
>> listening for PropertiesChanged don' t need to know the difference
>> between notification and indication.
>> Allow an external client to manage the Confirmation will insert
>> additional complexity without giving real benefits.
>>
>
> I'm thinking of the opposite way around - not the clients, but the services.
>
> If I implement a service over the D-Bus API, and a characteristic
> supports Indication, then is it not important that the service be
> informed when the clients confirm the Indication that is sent out?

I understand your concerns. However, moving this control to the
servers may require persistence, and access to device and connection
information in the server implementation.
One alternative could be extend the ApplcationAgent1 interface adding
a method to inform timeout (confirmation not received for a given
characteristic).

>
> Otherwise it makes Indications identical to Notifications when
> implementing a service using the BlueZ D-Bus API, which may cause
> issues with implementing certain profiles.

We can assume that Indication has higher priority, and the Properties
( Indication/Notification) can be inferred during the declaration.

>
>
>>>> +Application Agent hierarchy
>>>> +===========================
>>>> +
>>>> +Service unique name
>>>> +Interface org.bluez.ApplicationAgent1 [Experimental]
>>>> +Object path freely definable
>>>> +
>>>
>>> "Agent" seems unnnecessary here - if the object is an Application,
>>> then org.bluez.Application1 would be a decent enough name. Thus an
>>> "Application" consists of multiple Services, each of which consists of
>>> multiple Characteristics, each of which has multiple Descriptors
>>
>> IMO "Agent" gives a better association with its functionality, it
>> reminds me org.bluez.Agent1.
>> Let's wait the opinion of the others developers...
>>
>
> I was more thinking that we have "AgentManager" -> "Agent",
> "ProfileManager" -> "Profile", "ServiceManager" -> "Service" ... all
> of those use the agent-style pattern, but only "Pairing" Agent is
> called Agent.
>
> But honestly, bike shedding ;-) I'm only complaining because calling
> it "ApplicationAgent" would slightly screw up my naming convention
> inside Chromium

My first proposal was ServiceManager1 and Service1.

Maybe renaming the registration method to RegisterService() and moving
Release method to Service1 will make it similar to Profile1, and
easier to understand. Potential errors can be reported through a
method under Service1 interface.

However, this last suggestion will trigger unneeded calls of
GetManagedObjects(), basically one call per service registration.

I will try a new round based on your inputs and wait for feedbacks.

Regards,
Claudio

2013-11-15 19:47:52

by Scott James Remnant

[permalink] [raw]
Subject: Re: [RFC BlueZ v1] doc: Add GATT API

On Tue, Nov 12, 2013 at 10:49 AM, Claudio Takahasi
<[email protected]> wrote:

> On Mon, Nov 11, 2013 at 3:56 PM, Scott James Remnant <[email protected]> wrote:
>> How will service changed be handled? How will BlueZ track the set of
>> applications, and the set of services etc. defined by those
>> applications in a manner that keeps handles consistent? How will it
>> handle generating the Services Changed notification in the cases where
>> the set of applications and/or services change, or the handles change?
>
> We implemented a hash of declarations. Using the "Id" provided in the
> options dictionary (see RegisterAgent) we are able to identity if the
> external service changed its attributes.
> However, I don' t think we will upstream this approach soon, Marcel
> wants a simpler approach: always send ServiceChanged.
>

While this is probably "spec sufficient", and probably sufficient for
passing qualification, I'm not sure that this is necessarily the best
approach since this means that BlueZ when acting as a GATT Server
wouldn't be behaving quite the same as, say, a commodity BTLE device.

>>> +Characteristic hierarchy
>>> +========================
>> :
>>> +Service org.bluez
>>> +Interface org.bluez.Characteristic1 [Experimental]
>>> +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
>>
>> This would also need a "Permissions" property akin to the one you have
>> for Descriptors - characteristics can be "not accessible", read-only,
>> write-only, read/write - and can also require authorization,
>> authentication, encryption and minimum encryption key sizes - as with
>> descriptors.
>
> It is implemented already, there is an optional "Flags" property :
> "array{string} Flags [read-only, optional]"
>

Flags seemed to correspond to the Flags characteristic descriptor and
not the simple permissions of the characteristic itself.

>>> + array{byte} Value [read-write]
>>> +
>>> + Cached Value of the characteristic. If present, the
>>> + value will be cached by bluetoothd and updated when the
>>> + PropertiesChanged signal is emitted.
>>> +
>>> + External services must emit this signal when the
>>> + characteristic supports notification/indication, so
>>> + that clients can be notified of the new value.
>>
>> The PropertiesChanged signal explains how Notification will be handled
>> - but how will Indication? How will a service receive the Indication
>> Confirmation from the remote devices?
>
> The bluetoothd core manages the Confirmation. In my opinion clients
> listening for PropertiesChanged don' t need to know the difference
> between notification and indication.
> Allow an external client to manage the Confirmation will insert
> additional complexity without giving real benefits.
>

I'm thinking of the opposite way around - not the clients, but the services.

If I implement a service over the D-Bus API, and a characteristic
supports Indication, then is it not important that the service be
informed when the clients confirm the Indication that is sent out?

Otherwise it makes Indications identical to Notifications when
implementing a service using the BlueZ D-Bus API, which may cause
issues with implementing certain profiles.


>>> +Application Agent hierarchy
>>> +===========================
>>> +
>>> +Service unique name
>>> +Interface org.bluez.ApplicationAgent1 [Experimental]
>>> +Object path freely definable
>>> +
>>
>> "Agent" seems unnnecessary here - if the object is an Application,
>> then org.bluez.Application1 would be a decent enough name. Thus an
>> "Application" consists of multiple Services, each of which consists of
>> multiple Characteristics, each of which has multiple Descriptors
>
> IMO "Agent" gives a better association with its functionality, it
> reminds me org.bluez.Agent1.
> Let's wait the opinion of the others developers...
>

I was more thinking that we have "AgentManager" -> "Agent",
"ProfileManager" -> "Profile", "ServiceManager" -> "Service" ... all
of those use the agent-style pattern, but only "Pairing" Agent is
called Agent.

But honestly, bike shedding ;-) I'm only complaining because calling
it "ApplicationAgent" would slightly screw up my naming convention
inside Chromium

Scott
--
Scott James Remnant | Chrome OS Systems | [email protected] | Google

2013-11-14 20:13:52

by Caleb Reinhold

[permalink] [raw]
Subject: RE: [RFC BlueZ v1] doc: Add GATT API

Hi Claudio and Scott,

While having minimal familiarity with the workings of BlueZ, I have a fair degree of familiarity with the various health related BTLE specifications.
Because of this, and because of a desire to make use of a more complete GATT API for BlueZ, I thought I might be able to offer some worthwhile insight on useful ways for the API to behave.

I think that while discussing the reading of characteristics, considering the information available to the client side at the time of connection due to advertisements would be useful. Since UUIDs for a given service being included in an advertisement are only at the level of a "should" it may be useful for an application to be able to decide to abort a connection after discovering only the service declarations.

As far as the behavior of enabling Notifications or Indications, while in most circumstances it would be possible to draw appropriate information from the corresponding characteristic declaration's properties, if a situation occurred in which both options were for some reason viable selections it could be quite frustrating for the developer making use of the API. Manual control of the state of the client characteristic configuration descriptors also allows a developer to ensure that data will not be lost due to arriving before the client program is ready to handle it.

Regarding the caching of attributes we were wondering if there is a method for removing the stored data, at least for the purposes of testing.

Regards,

Caleb Reinhold

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Claudio Takahasi
Sent: Tuesday, November 12, 2013 1:49 PM
To: Scott James Remnant
Cc: [email protected]
Subject: Re: [RFC BlueZ v1] doc: Add GATT API

Hi Scott,

On Mon, Nov 11, 2013 at 3:56 PM, Scott James Remnant <[email protected]> wrote:
> On Tue, Oct 15, 2013 at 11:39 AM, Claudio Takahasi
> <[email protected]> wrote:
>
>> +GATT local and remote services share the same high-level D-Bus API.
>> +Local refers to local GATT based service exported by a BlueZ plugin
>> +or an external application. Remote refers to GATT services exported by the peer.
>
> If this object format also be used to describe the services and
> characteristics of a remote device, how will those be handled? I
> assume that we don't want to get the value of every single
> characteristic on connection - that seems wasteful, and would quite
> rapidly drain the batteries of smaller devices.

Declarations are stored/cached. All attributes are discovered only once in the first connection or after bonding.
When re-connecting, value is read on demand when the user calls Properties Get (if value is not cached).
Another point is: Notification or Indication are automatically enabled after the discovery procedure.

>
>
> How will service changed be handled? How will BlueZ track the set of
> applications, and the set of services etc. defined by those
> applications in a manner that keeps handles consistent? How will it
> handle generating the Services Changed notification in the cases where
> the set of applications and/or services change, or the handles change?

We implemented a hash of declarations. Using the "Id" provided in the options dictionary (see RegisterAgent) we are able to identity if the external service changed its attributes.
However, I don' t think we will upstream this approach soon, Marcel wants a simpler approach: always send ServiceChanged.

If you want to understand more details of the implementation see:
https://db.tt/FkWob6jw

>
>
>> +Characteristic hierarchy
>> +========================
> :
>> +Service org.bluez
>> +Interface org.bluez.Characteristic1 [Experimental]
>> +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
>
> This would also need a "Permissions" property akin to the one you have
> for Descriptors - characteristics can be "not accessible", read-only,
> write-only, read/write - and can also require authorization,
> authentication, encryption and minimum encryption key sizes - as with
> descriptors.

It is implemented already, there is an optional "Flags" property :
"array{string} Flags [read-only, optional]"

But this is not enough, there are some cases that the permissions are defined by the external application.

>
>> + array{byte} Value [read-write]
>> +
>> + Cached Value of the characteristic. If present, the
>> + value will be cached by bluetoothd and updated when the
>> + PropertiesChanged signal is emitted.
>> +
>> + External services must emit this signal when the
>> + characteristic supports notification/indication, so
>> + that clients can be notified of the new value.
>
> The PropertiesChanged signal explains how Notification will be handled
> - but how will Indication? How will a service receive the Indication
> Confirmation from the remote devices?

The bluetoothd core manages the Confirmation. In my opinion clients listening for PropertiesChanged don' t need to know the difference between notification and indication.
Allow an external client to manage the Confirmation will insert additional complexity without giving real benefits.

>
>
>> +Application Manager hierarchy
>> +=============================
> :
>> +Service org.bluez
>> +Interface org.bluez.ApplicationManager1 [Experimental]
>> +Object path /org/bluez
>> +
>> +Methods RegisterAgent(object application, dict options)
>
> Shouldn't this be "RegisterApplication" ?
>
> I assume that the object path is the one to which D-Bus Object Manager
> queries are sent, allowing a single process to implement multiple
> "applications"?

The name is still open, but remember that this method might be used to register client and servers.

At the moment "object path" together with DBus BUS id are used for identification only. Multiple GATT services can be registered independently of the application object path.
Application object path can be used to manage *groups* of services exposed by the single process.

>
>> + UnregisterAgent(object application)
>
> Likewise, "UnregisterApplication" ?
>
>> +Application Agent hierarchy
>> +===========================
>> +
>> +Service unique name
>> +Interface org.bluez.ApplicationAgent1 [Experimental]
>> +Object path freely definable
>> +
>
> "Agent" seems unnnecessary here - if the object is an Application,
> then org.bluez.Application1 would be a decent enough name. Thus an
> "Application" consists of multiple Services, each of which consists of
> multiple Characteristics, each of which has multiple Descriptors

IMO "Agent" gives a better association with its functionality, it reminds me org.bluez.Agent1.
Let's wait the opinion of the others developers...

Regards,
Claudio

2013-11-12 18:49:09

by Claudio Takahasi

[permalink] [raw]
Subject: Re: [RFC BlueZ v1] doc: Add GATT API

Hi Scott,

On Mon, Nov 11, 2013 at 3:56 PM, Scott James Remnant <[email protected]> wrote:
> On Tue, Oct 15, 2013 at 11:39 AM, Claudio Takahasi
> <[email protected]> wrote:
>
>> +GATT local and remote services share the same high-level D-Bus API. Local
>> +refers to local GATT based service exported by a BlueZ plugin or an external
>> +application. Remote refers to GATT services exported by the peer.
>
> If this object format also be used to describe the services and
> characteristics of a remote device, how will those be handled? I
> assume that we don't want to get the value of every single
> characteristic on connection - that seems wasteful, and would quite
> rapidly drain the batteries of smaller devices.

Declarations are stored/cached. All attributes are discovered only
once in the first connection or after bonding.
When re-connecting, value is read on demand when the user calls
Properties Get (if value is not cached).
Another point is: Notification or Indication are automatically enabled
after the discovery procedure.

>
>
> How will service changed be handled? How will BlueZ track the set of
> applications, and the set of services etc. defined by those
> applications in a manner that keeps handles consistent? How will it
> handle generating the Services Changed notification in the cases where
> the set of applications and/or services change, or the handles change?

We implemented a hash of declarations. Using the "Id" provided in the
options dictionary (see RegisterAgent) we are able to identity if the
external service changed its attributes.
However, I don' t think we will upstream this approach soon, Marcel
wants a simpler approach: always send ServiceChanged.

If you want to understand more details of the implementation see:
https://db.tt/FkWob6jw

>
>
>> +Characteristic hierarchy
>> +========================
> :
>> +Service org.bluez
>> +Interface org.bluez.Characteristic1 [Experimental]
>> +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
>
> This would also need a "Permissions" property akin to the one you have
> for Descriptors - characteristics can be "not accessible", read-only,
> write-only, read/write - and can also require authorization,
> authentication, encryption and minimum encryption key sizes - as with
> descriptors.

It is implemented already, there is an optional "Flags" property :
"array{string} Flags [read-only, optional]"

But this is not enough, there are some cases that the permissions are
defined by the external application.

>
>> + array{byte} Value [read-write]
>> +
>> + Cached Value of the characteristic. If present, the
>> + value will be cached by bluetoothd and updated when the
>> + PropertiesChanged signal is emitted.
>> +
>> + External services must emit this signal when the
>> + characteristic supports notification/indication, so
>> + that clients can be notified of the new value.
>
> The PropertiesChanged signal explains how Notification will be handled
> - but how will Indication? How will a service receive the Indication
> Confirmation from the remote devices?

The bluetoothd core manages the Confirmation. In my opinion clients
listening for PropertiesChanged don' t need to know the difference
between notification and indication.
Allow an external client to manage the Confirmation will insert
additional complexity without giving real benefits.

>
>
>> +Application Manager hierarchy
>> +=============================
> :
>> +Service org.bluez
>> +Interface org.bluez.ApplicationManager1 [Experimental]
>> +Object path /org/bluez
>> +
>> +Methods RegisterAgent(object application, dict options)
>
> Shouldn't this be "RegisterApplication" ?
>
> I assume that the object path is the one to which D-Bus Object Manager
> queries are sent, allowing a single process to implement multiple
> "applications"?

The name is still open, but remember that this method might be used to
register client and servers.

At the moment "object path" together with DBus BUS id are used for
identification only. Multiple GATT services can be registered
independently of the application object path.
Application object path can be used to manage *groups* of services
exposed by the single process.

>
>> + UnregisterAgent(object application)
>
> Likewise, "UnregisterApplication" ?
>
>> +Application Agent hierarchy
>> +===========================
>> +
>> +Service unique name
>> +Interface org.bluez.ApplicationAgent1 [Experimental]
>> +Object path freely definable
>> +
>
> "Agent" seems unnnecessary here - if the object is an Application,
> then org.bluez.Application1 would be a decent enough name. Thus an
> "Application" consists of multiple Services, each of which consists of
> multiple Characteristics, each of which has multiple Descriptors

IMO "Agent" gives a better association with its functionality, it
reminds me org.bluez.Agent1.
Let's wait the opinion of the others developers...

Regards,
Claudio

2013-11-11 18:56:22

by Scott James Remnant

[permalink] [raw]
Subject: Re: [RFC BlueZ v1] doc: Add GATT API

On Tue, Oct 15, 2013 at 11:39 AM, Claudio Takahasi
<[email protected]> wrote:

> +GATT local and remote services share the same high-level D-Bus API. Local
> +refers to local GATT based service exported by a BlueZ plugin or an external
> +application. Remote refers to GATT services exported by the peer.

If this object format also be used to describe the services and
characteristics of a remote device, how will those be handled? I
assume that we don't want to get the value of every single
characteristic on connection - that seems wasteful, and would quite
rapidly drain the batteries of smaller devices.


How will service changed be handled? How will BlueZ track the set of
applications, and the set of services etc. defined by those
applications in a manner that keeps handles consistent? How will it
handle generating the Services Changed notification in the cases where
the set of applications and/or services change, or the handles change?


> +Characteristic hierarchy
> +========================
:
> +Service org.bluez
> +Interface org.bluez.Characteristic1 [Experimental]
> +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY

This would also need a "Permissions" property akin to the one you have
for Descriptors - characteristics can be "not accessible", read-only,
write-only, read/write - and can also require authorization,
authentication, encryption and minimum encryption key sizes - as with
descriptors.

> + array{byte} Value [read-write]
> +
> + Cached Value of the characteristic. If present, the
> + value will be cached by bluetoothd and updated when the
> + PropertiesChanged signal is emitted.
> +
> + External services must emit this signal when the
> + characteristic supports notification/indication, so
> + that clients can be notified of the new value.

The PropertiesChanged signal explains how Notification will be handled
- but how will Indication? How will a service receive the Indication
Confirmation from the remote devices?


> +Application Manager hierarchy
> +=============================
:
> +Service org.bluez
> +Interface org.bluez.ApplicationManager1 [Experimental]
> +Object path /org/bluez
> +
> +Methods RegisterAgent(object application, dict options)

Shouldn't this be "RegisterApplication" ?

I assume that the object path is the one to which D-Bus Object Manager
queries are sent, allowing a single process to implement multiple
"applications"?

> + UnregisterAgent(object application)

Likewise, "UnregisterApplication" ?

> +Application Agent hierarchy
> +===========================
> +
> +Service unique name
> +Interface org.bluez.ApplicationAgent1 [Experimental]
> +Object path freely definable
> +

"Agent" seems unnnecessary here - if the object is an Application,
then org.bluez.Application1 would be a decent enough name. Thus an
"Application" consists of multiple Services, each of which consists of
multiple Characteristics, each of which has multiple Descriptors

Scott
--
Scott James Remnant | Chrome OS Systems | [email protected] | Google