Subject: Proposed API for HDP

Hi all,

This is the new design of the HDP API that we designed using the Marcel's recomendations.

Regards.


BlueZ D-Bus Health API description
**********************************

Santiago Carot-Nemesio <[email protected]>
Jos? Antonio Santos-Cadenas <[email protected]>
Elvis Pf?tzenreuter <[email protected]>

Health Device Profile hierarchy
===============================

Service org.bluez
Interface org.bluez.HealthAdapter
Object path [variable prefix]/{hci0,hci1,...}

Methods:

path CreateApplication(object path, dict config)

Returns the path of the new created application. The path
parameter is the path of the object with the callbacks to
notify events (see org.bluez.HealthAgent at the end of this
document)
This petition starts an mcap instance and also register a proper
record in the SDP if is needed.

Dict is defined as bellow:
{
"end_points" : [{ (optional)
"role" : ("source" or "sink"), (mandatory)
"specs" :[{ (mandatory)
"data_type" : uint16, (mandatory)
"description" : string, (optional)
}]
}]
}

Application will be closed by the call or implicitly when the
programs leaves the bus.

Possible errors: org.bluez.Error.InvalidArguments

void ReleaseApplication(path application)

Closes the HDP application identified by the object path. Also
application will be closed if the process that started it leaves
the bus. If there is a SDP record associated to this application
it will be removed.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound

array GetRemoteApplications(path application)

This method will return an array with the paths of all the
remote instances found in remote devices.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound

--------------------------------------------------------------------------------

Service org.bluez
Interface org.bluez.HealthDevice
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX

Methods:

void Refresh()

This method searches for HDP applications in the remote device
and notifies them to the appropriate agents.

--------------------------------------------------------------------------------

Service org.bluez
Interface org.bluez.HealthDeviceApplication
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY

Methods:

array GetProperties()

Gets the information of the remote application published on its
SDP record. The returned data format is as follows:

{
"end_points": [
"mdepid": uint8,
"role" : "source" or "sink" ,
"specs" : [{
"dtype" : uint16,
"description" : string, (optional)
}]
]
}

object Connect(path local_application_id)

Connects the local application with the remote application.

Only the bus client that created the local session will be able
to create connections using it.

If the Device is already connected with an other application an
org.bluez.Error.AlreadyConnected error will be received.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.AlreadyConnected
org.bluez.Error.HealthError

void Disconnect()

Disconnect from the remote application the state will also be
deleted. And no future reconnections will be possible. For
keeping the state the method Pause of the health link should be
used.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
org.bluez.Error.HealthError

boolean Echo(array{byte})

Sends an echo petition to the remote intance. Returns True if
response matches with the buffer sent. If some error is detected
False value is returned and the associated MCL is closed.

path OpenDataChannel(byte mdepid, string conf)

Creates a new data channel with the indicated config to the
remote MCAP Data End Point (MDEP).
The configuration should indicate the channel quality of
service using one of this values "reliable", "streaming", "any".

Returns the data channel path.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.HealthError

void ReconnectDataChannel(path data_channel)

Reconnects a previously created data channel indicated by its
path.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.HealthError
org.bluez.Error.NotFound

int GetDataChannelFileDescriptor(path data_channel)

Gets a file descriptor where data can be read or written.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
org.bluez.Error.HealthError

void DeleteDataChannel(path data_channel)

Deletes a data channel so it will not be available to use.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
org.bluez.Error.HealthError

void DeleteAllDataChannels()

Deletes all data channels so they will not be available for
future use. Typically this function is called when the
connection with the remote device will be closed permanently.

Possible errors: org.bluez.Error.HealthError

dict GetDataChannelStatus()

Return a dictionary with all the data channels that can be used
to send data right now. The dictionary is formed like follows:

{
"reliable": [channel_path_r1, channel_path_r2, ...],
"streaming" : [channel_path_s1, channel_path_s2, ...]
}

The fist reliable data channel will always be the first data
channel in reliable array.

HealthAgent hierarchy
=====================

(this object is implemented by the HDP user in order to receive notifications)

Service unique name
Interface org.bluez.HealthAgent
Object path freely definable

Methods:

void DeviceApplicationDiscovered(object path)

This method is called when a device containing an hdp
application is connected. The object path is the application
path. The method will be called one time for each
application.

void DeviceConnected(object path)

This method is called whenever a new connection has been
established over the control channel of the current HDP
application. The object path paremeter contains the object path
of the connected HealthDevice.

void DevicePaused(object path)

This method is called when a MCL is closed. Future reconnections
will be notified using the DeviceRestarted callback.
All data channels associated to this device will be closed and
a reconnection will be needed before using them again.

void DeviceResumed(object path)

This method is called whenever a MCL is reconnected. All data
channels associated are still closed but they will be able to be
reconnected skipping the configuration process.

void DeviceDisconnected(object path)

This method is called when a remote device is disconnected or
removed from MCAP cache. Any future reconnections will fail.
Also all data channels associated to this device will be closed.

void CreatedDataChannel(object path, path data_channel, string conf)

This method is called when a new data channel is created.

The path contains the object path of the HealthDeviceApplication
where the new connection is created, the data_channel is the
path for identify the data channel and conf is the quality of
service of the data channel ("reliable" or "streaming").

void DataChannelReconnected(object path, path data_channel, string conf)

This method is called when a closed data channel is reconnected
by the remote device.

Conf will be "reliable" or "streaming".

TThe path contains the object path of the
HealthDeviceApplication where the new connection is reconnected,
the data_channel is the path for identify the data channel and
conf is the quality of service of the data channel ("reliable"
or "streaming").

void DeletedDataChannel(object path, path data_channel)

This method is called when a data channel is deleted.

After this call the data channel path will not be valid and can
be reused for future creation of data channels.

void DeletedAllDataChannels(object path)

This method is called when all data channels are deleted.

The path contains the object path of the HealthDeviceApplication
where the data channels are deleted.


Subject: Re: Proposed API for HDP (v4)


BlueZ D-Bus Health API description
**********************************

Santiago Carot-Nemesio <[email protected]>
Jos? Antonio Santos-Cadenas <[email protected]>
Elvis Pf?tzenreuter <[email protected]>

Health Device Profile hierarchy
===============================

Service org.bluez
Interface org.bluez.HealthManager
Object path [variable prefix]/

Methods:

path RegisterApplication(object agent, dict config)

Returns the path of the new registered application. The agent
parameter is the path of the object with the callbacks to
notify events (see org.bluez.HealthAgent at the end of this
document)
This petition starts an mcap instance on every adapter and also
register a proper record in the SDP if is needed.

Dict is defined as bellow:
{
"end_points" : [{ (optional)
"role" : ("source" or "sink"), (mandatory)
"specs" :[{ (mandatory)
"data_type" : uint16, (mandatory)
"description" : string, (optional)
}]
}]
}

Application will be closed by the call or implicitly when the
programs leaves the bus.

Possible errors: org.bluez.Error.InvalidArguments

void UnregisterApplication(object application)

Closes the HDP application identified by the object path. Also
application will be closed if the process that started it leaves
the bus. If there is a SDP record associated to this application
it will also be removed.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound

void UpdateServices()

This method searches for HDP applications on the all remote
devices and notifies them to the appropriate agents.

Signals:

void ServiceDiscovered(object service)

This signal is sent when a device containing an HDP
application is paired or when the method Update of the
HealthManager is called and new HealthServices are discovered.
The object path is the HealthService path. The signal will be
launched once for each HealthService.

void ServiceRemoved(object service)

This signal is sent if during an Update some HealthServices
have disappeared. The signal is launched once for each removed
HealthService.

--------------------------------------------------------------------------------

Service org.bluez
Interface org.bluez.HealthService
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY

Methods:

array GetProperties()

Returns all properties for the interface. See the properties
section for available properties.

boolean Echo(array{byte})

Sends an echo petition to the remote service. Returns True if
response matches with the buffer sent. If some error is detected
False value is returned and the associated MCL is closed.

string OpenDataChannel(byte mdepid, string conf)

Creates a new data channel with the indicated config to the
remote MCAP Data End Point (MDEP).
The configuration should indicate the channel quality of
service using one of this values "Reliable", "Streaming", "Any".

Returns an string that identifies the data channel.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.HealthError

void ReconnectDataChannel(string data_channel)

Reconnects a previously created data channel.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.HealthError
org.bluez.Error.NotFound

void DeleteDataChannel(string data_channel)

Deletes a data channel so it will not be available.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
org.bluez.Error.HealthError

void DeleteAllDataChannels()

Deletes all data channels so they will not be available for
future use.

Possible errors: org.bluez.Error.HealthError

Properties:

array EndPoints

An array with all the end points in this Service. Each one of
then has this format.

{
"mdepid": uint8,
"role" : "source" or "sink" ,
"specs" : [{
"dtype" : uint16,
"description" : string, (optional)
}]
}

HealthAgent hierarchy
=====================

(this object is implemented by the HDP user in order to receive notifications)

Service unique name
Interface org.bluez.HealthAgent
Object path freely definable

Methods:

void Release()

This method gets called when the service daemon unregisters the
agent. An agent can use it to do cleanup tasks. There is no need
to unregister the agent, because when this method gets called it
has already been unregistered.

void DataChannelCreated(object service, string data_channel,
string conf, fd file_descriptor, boolean reconnection)

This method is called when a new data channel is created.

The service parameter contains the object path of the
HealthService that created the connection, data_channel is
the string that identifies the data channel, conf is the quality
of service of the data channel ("reliable" or "streaming"),
file_descriptor the file descriptor for reading and writing
data and reconnection indicates if it is a reconnection or a
data channel creation.

void DataChannelRemoved(object service, string data_channel)

This method is called when a data channel is deleted.

After this call the data channel path will not be valid and can
be reused for future creation of data channels.

Subject: Re: Proposed API for HDP (v3)

Again a new version with some modifications


BlueZ D-Bus Health API description
**********************************

Santiago Carot-Nemesio <[email protected]>
Jos? Antonio Santos-Cadenas <[email protected]>
Elvis Pf?tzenreuter <[email protected]>

Health Device Profile hierarchy
===============================

Service org.bluez
Interface org.bluez.HealthManager
Object path [variable prefix]/

Methods:

path RegisterApplication(object path, dict config)

Returns the path of the new registered application. The path
parameter is the path of the object with the callbacks to
notify events (see org.bluez.HealthAgent at the end of this
document)
This petition starts an mcap instance on every adapter and also
register a proper record in the SDP if is needed.

Dict is defined as bellow:
{
"end_points" : [{ (optional)
"role" : ("Source" or "Sink"), (mandatory)
"specs" :[{ (mandatory)
"data_type" : uint16, (mandatory)
"description" : string, (optional)
}]
}]
}

Application will be closed by the call or implicitly when the
programs leaves the bus.

Possible errors: org.bluez.Error.InvalidArguments

void UnregisterApplication(path application)

Closes the HDP application identified by the object path. Also
application will be closed if the process that started it leaves
the bus. If there is a SDP record associated to this application
it will also be removed.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound

void UpdateServices()

This method searches for HDP applications on the all remote
devices and notifies them to the appropriate agents.

Signals:

void ServiceDiscovered(object path)

This signal is sent when a device containing an HDP
application is paired or when the method Update of the
HealthManager is called and new HealthServices are discovered.
The object path is the HealthService path. The signal will be
launched once for each HealthService.

void ServiceRemoved(object path)

This signal is sent if during an Update some HealthServices
have disappeared. The signal is launched once for each removed
HealthService.

--------------------------------------------------------------------------------

Service org.bluez
Interface org.bluez.HealthService
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY

Methods:

array GetProperties()

Returns all properties for the interface. See the properties
section for available properties.

boolean Echo(array{byte})

Sends an echo petition to the remote service. Returns True if
response matches with the buffer sent. If some error is detected
False value is returned and the associated MCL is closed.

path OpenDataChannel(byte mdepid, string conf)

Creates a new data channel with the indicated config to the
remote MCAP Data End Point (MDEP).
The configuration should indicate the channel quality of
service using one of this values "Reliable", "Streaming", "Any".

Returns the data channel path.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.HealthError

void ReconnectDataChannel(path data_channel)

Reconnects a previously created data channel indicated by its
path.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.HealthError
org.bluez.Error.NotFound

void DeleteDataChannel(path data_channel)

Deletes a data channel so it will not be available.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
org.bluez.Error.HealthError

void DeleteAllDataChannels()

Deletes all data channels so they will not be available for
future use.

Possible errors: org.bluez.Error.HealthError

Properties:

array EndPoints

An array with all the end points in this Service. Each one of
then has this format.

{
"mdepid": uint8,
"role" : "Source" or "Sink" ,
"specs" : [{
"dtype" : uint16,
"description" : string, (optional)
}]
}

HealthAgent hierarchy
=====================

(this object is implemented by the HDP user in order to receive notifications)

Service unique name
Interface org.bluez.HealthAgent
Object path freely definable

Methods:

void DataChannelCreated(object path, path data_channel, string conf,
fd file_descriptor)

This method is called when a new data channel is created.

The path contains the object path of the HealthService that
created the connection, the data_channel is the path that
identifies the data channel, conf is the quality of service of
the data channel ("reliable" or "streaming") and file_descriptor
the file descriptor for reading and writing data.

void DataChannelReconnected(object path, path data_channel, string conf,
fd file_descriptor))

This method is called when a closed data channel is reconnected
by the remote device.

The path contains the object path of the HealthService that
reconnected the channel. data_channel is the path that
identifies the data channel, conf is the quality of service of
the data channel ("reliable" or "streaming") and file_descriptor
is the file descriptor for reading and writing data.

void DataChannelRemoved(object path, path data_channel)

This method is called when a data channel is deleted.

After this call the data channel path will not be valid and can
be reused for future creation of data channels. The path is the
path of the HealthService that removes the data channel.

2010-07-09 17:36:18

by Gustavo Padovan

[permalink] [raw]
Subject: Re: Proposed API for HDP

* Jos? Antonio Santos Cadenas <[email protected]> [2010-07-09 19:12:44 +0200]:

> El Friday 09 July 2010 18:55:08 Gustavo F. Padovan escribi?:
> > Hi Jos?,
> >
> > * Jos? Antonio Santos Cadenas <[email protected]> [2010-07-09 15:49:42
> +0200]:
> > > I wrote a new API based on the changes suggested in this thread.
> > >
> > > Regards.
> > >
> > > Jose.
> > >
> > >
> > > BlueZ D-Bus Health API description
> > > **********************************
> > >
> > > Santiago Carot-Nemesio <[email protected]>
> > > Jos? Antonio Santos-Cadenas <[email protected]>
> > > Elvis Pf?tzenreuter <[email protected]>
> > >
> > > Health Device Profile hierarchy
> > > ===============================
> > >
> > > Service org.bluez
> > > Interface org.bluez.HealthManager
> > > Object path [variable prefix]/{hci0,hci1,...}
> > >
> > > Methods:
> > > path RegisterApplication(object path, dict config)
> > >
> > > Returns the path of the new registered application. The path
> > > parameter is the path of the object with the callbacks to
> > > notify events (see org.bluez.HealthAgent at the end of this
> > > document)
> > > This petition starts an mcap instance on every adapter and also
> > > register a proper record in the SDP if is needed.
> > >
> > > Dict is defined as bellow:
> > > {
> > >
> > > "end_points" : [{ (optional)
> > >
> > > "role" : ("source" or "sink"), (mandatory)
> > > "specs" :[{ (mandatory)
> > >
> > > "data_type" : uint16, (mandatory)
> > > "description" : string, (optional)
> > >
> > > }]
> > >
> > > }]
> > >
> > > }
> > >
> > > Application will be closed by the call or implicitly when the
> > > programs leaves the bus.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > void UnregisterApplication(path application)
> > >
> > > Closes the HDP application identified by the object path. Also
> > > application will be closed if the process that started it leaves
> > > the bus. If there is a SDP record associated to this application
> > > it will also be removed.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.NotFound
> > >
> > > void UpdateServices()
> > >
> > > This method searches for HDP applications on the all remote
> > > devices and notifies them to the appropriate agents.
> > >
> > > -------------------------------------------------------------------------
> > > -------
> > >
> > > Service org.bluez
> > > Interface org.bluez.HealthService
> > > Object path [variable
> > > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
> > >
> > > Methods:
> > > array GetProperties()
> > >
> > > Gets the information of the remote application published on its
> > > SDP record. The returned data format is as follows:
> > >
> > > {
> > >
> > > "end_points": [
> > >
> > > "mdepid": uint8,
> > > "role" : "source" or "sink" ,
> > > "specs" : [{
> > >
> > > "dtype" : uint16,
> > > "description" : string, (optional)
> > > }]
> > >
> > > ]
> > >
> > > }
> >
> > What's the name of this property? See the others APIs, properties need a
> > name.
>
> I didn't think about properties here (I'm not used to them) But here yes, a
> property fixes better than a method call.


The method should remain, look the the others APIs. They a have a
Properties section and GetProperties() show all of them.


--
Gustavo F. Padovan
http://padovan.org

Subject: Re: Proposed API for HDP

El Friday 09 July 2010 18:55:08 Gustavo F. Padovan escribi?:
> Hi Jos?,
>
> * Jos? Antonio Santos Cadenas <[email protected]> [2010-07-09 15:49:42
+0200]:
> > I wrote a new API based on the changes suggested in this thread.
> >
> > Regards.
> >
> > Jose.
> >
> >
> > BlueZ D-Bus Health API description
> > **********************************
> >
> > Santiago Carot-Nemesio <[email protected]>
> > Jos? Antonio Santos-Cadenas <[email protected]>
> > Elvis Pf?tzenreuter <[email protected]>
> >
> > Health Device Profile hierarchy
> > ===============================
> >
> > Service org.bluez
> > Interface org.bluez.HealthManager
> > Object path [variable prefix]/{hci0,hci1,...}
> >
> > Methods:
> > path RegisterApplication(object path, dict config)
> >
> > Returns the path of the new registered application. The path
> > parameter is the path of the object with the callbacks to
> > notify events (see org.bluez.HealthAgent at the end of this
> > document)
> > This petition starts an mcap instance on every adapter and also
> > register a proper record in the SDP if is needed.
> >
> > Dict is defined as bellow:
> > {
> >
> > "end_points" : [{ (optional)
> >
> > "role" : ("source" or "sink"), (mandatory)
> > "specs" :[{ (mandatory)
> >
> > "data_type" : uint16, (mandatory)
> > "description" : string, (optional)
> >
> > }]
> >
> > }]
> >
> > }
> >
> > Application will be closed by the call or implicitly when the
> > programs leaves the bus.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > void UnregisterApplication(path application)
> >
> > Closes the HDP application identified by the object path. Also
> > application will be closed if the process that started it leaves
> > the bus. If there is a SDP record associated to this application
> > it will also be removed.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > org.bluez.Error.NotFound
> >
> > void UpdateServices()
> >
> > This method searches for HDP applications on the all remote
> > devices and notifies them to the appropriate agents.
> >
> > -------------------------------------------------------------------------
> > -------
> >
> > Service org.bluez
> > Interface org.bluez.HealthService
> > Object path [variable
> > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
> >
> > Methods:
> > array GetProperties()
> >
> > Gets the information of the remote application published on its
> > SDP record. The returned data format is as follows:
> >
> > {
> >
> > "end_points": [
> >
> > "mdepid": uint8,
> > "role" : "source" or "sink" ,
> > "specs" : [{
> >
> > "dtype" : uint16,
> > "description" : string, (optional)
> > }]
> >
> > ]
> >
> > }
>
> What's the name of this property? See the others APIs, properties need a
> name.

I didn't think about properties here (I'm not used to them) But here yes, a
property fixes better than a method call.

>
> > boolean Echo(array{byte})
> >
> > Sends an echo petition to the remote service. Returns True if
> > response matches with the buffer sent. If some error is detected
> > False value is returned and the associated MCL is closed.
> >
> > path OpenDataChannel(byte mdepid, string conf)
>
> Do we really need to expose the mdepid to the application? Isn't there
> any way to abstract this for the application?

In fact I would like to avoid this ugly think (mdep) but we didn't find a way
to avoid it. In fact you should open a connection to an end point and bot the
initiator and the acceptor should be concerned of the end point beeng
connected. Of course find a way to avoid the use of mdep's will be great.

>
> > Creates a new data channel with the indicated config to the
> > remote MCAP Data End Point (MDEP).
> > The configuration should indicate the channel quality of
> > service using one of this values "reliable", "streaming", "any".
>
> What is "any" mean? and make it "Reliable", "Streaming" and "Any", with
> capital letters.

Any means that there is no preference for the quality of service of this data
channel. The remote will decide the Quality of service. This is the correct
way for a sink to create a new data channel, letting the source decide the
QoS.

>
> > Returns the data channel path.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > org.bluez.Error.HealthError
> >
> > void ReconnectDataChannel(path data_channel)
> >
> > Reconnects a previously created data channel indicated by its
> > path.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > org.bluez.Error.HealthError
> > org.bluez.Error.NotFound
> >
> > void DeleteDataChannel(path data_channel)
> >
> > Deletes a data channel so it will not be available.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > org.bluez.Error.NotFound
> > org.bluez.Error.HealthError
> >
> > void DeleteAllDataChannels()
> >
> > Deletes all data channels so they will not be available for
> > future use.
> >
> > Possible errors: org.bluez.Error.HealthError
> >
> > HealthAgent hierarchy
> > =====================
> >
> > (this object is implemented by the HDP user in order to receive
> > notifications)
> >
> > Service unique name
> > Interface org.bluez.HealthAgent
> > Object path freely definable
> >
> > Methods:
> > void ServiceDiscovered(object path)
> >
> > This method is called when a device containing an HDP
> > application is paired or when the method Update of the
> > HealthManager is called and new HealthServices are discovered.
> > The object path is the HealthService path. The method will be
> > called for each HealthService.
>
> This one could be a signal.

Shure, I'll change this.

>
> > (Not shure if this should be added)
> >
> > void ServiceRemoved(object path)
> >
> > This method is called if during an Update some HealthServices
> > have disappeared. The method is called once for each removed
> > HealthService.
>
> That one as well.
>
> > void DataChannelCreated(object path, path data_channel, string conf,
> >
> > fd file_descriptor)
> >
> > This method is called when a new data channel is created.
> >
> > The path contains the object path of the HealthService that
> > created the connection, the data_channel is the path that
> > identifies the data channel, conf is the quality of service of
> > the data channel ("reliable" or "streaming") and file_descriptor
> > the file descriptor for reading and writing data.
> >
> > void DataChannelReconnected(object path, path data_channel, string
conf,
> >
> > fd file_descriptor))
> >
> > This method is called when a closed data channel is reconnected
> > by the remote device.
> >
> > The path contains the object path of the HealthService that
> > reconnected the channel. data_channel is the path that
> > identifies the data channel, conf is the quality of service of
> > the data channel ("reliable" or "streaming") and file_descriptor
> > is the file descriptor for reading and writing data.
>
> Couldn't these two be integrated into one? What they do is just pass the
> fd to the application. The application can keep the information about if
> it is a Created or Reconnected data channel because it knows what is
> being requested.

Yes, as Elvis suggested, they will be fixed in to just one method.

>
> Also, is the conf parameter really needed? The application should know
> the channel type it asked.

Not really, it is receiving a new connection it doesn't request nothing. Is
the remote side the one that initiated the connection. So the configuration
should be notified.

>
> > void DataChannelRemoved(object path, path data_channel)
> >
> > This method is called when a data channel is deleted.
> >
> > After this call the data channel path will not be valid and can
> > be reused for future creation of data channels. The path is the
> > path of the HealthService that removes the data channel.
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe
> > linux-bluetooth" in the body of a message to [email protected]
> > More majordomo info at http://vger.kernel.org/majordomo-info.html

2010-07-09 16:55:08

by Gustavo Padovan

[permalink] [raw]
Subject: Re: Proposed API for HDP

Hi Jos?,

* Jos? Antonio Santos Cadenas <[email protected]> [2010-07-09 15:49:42 +0200]:

> I wrote a new API based on the changes suggested in this thread.
>
> Regards.
>
> Jose.
>
>
> BlueZ D-Bus Health API description
> **********************************
>
> Santiago Carot-Nemesio <[email protected]>
> Jos? Antonio Santos-Cadenas <[email protected]>
> Elvis Pf?tzenreuter <[email protected]>
>
> Health Device Profile hierarchy
> ===============================
>
> Service org.bluez
> Interface org.bluez.HealthManager
> Object path [variable prefix]/{hci0,hci1,...}
>
> Methods:
>
> path RegisterApplication(object path, dict config)
>
> Returns the path of the new registered application. The path
> parameter is the path of the object with the callbacks to
> notify events (see org.bluez.HealthAgent at the end of this
> document)
> This petition starts an mcap instance on every adapter and also
> register a proper record in the SDP if is needed.
>
> Dict is defined as bellow:
> {
> "end_points" : [{ (optional)
> "role" : ("source" or "sink"), (mandatory)
> "specs" :[{ (mandatory)
> "data_type" : uint16, (mandatory)
> "description" : string, (optional)
> }]
> }]
> }
>
> Application will be closed by the call or implicitly when the
> programs leaves the bus.
>
> Possible errors: org.bluez.Error.InvalidArguments
>
> void UnregisterApplication(path application)
>
> Closes the HDP application identified by the object path. Also
> application will be closed if the process that started it leaves
> the bus. If there is a SDP record associated to this application
> it will also be removed.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
>
> void UpdateServices()
>
> This method searches for HDP applications on the all remote
> devices and notifies them to the appropriate agents.
>
> --------------------------------------------------------------------------------
>
> Service org.bluez
> Interface org.bluez.HealthService
> Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
>
> Methods:
>
> array GetProperties()
>
> Gets the information of the remote application published on its
> SDP record. The returned data format is as follows:
>
> {
> "end_points": [
> "mdepid": uint8,
> "role" : "source" or "sink" ,
> "specs" : [{
> "dtype" : uint16,
> "description" : string, (optional)
> }]
> ]
> }

What's the name of this property? See the others APIs, properties need a name.

>
> boolean Echo(array{byte})
>
> Sends an echo petition to the remote service. Returns True if
> response matches with the buffer sent. If some error is detected
> False value is returned and the associated MCL is closed.
>
> path OpenDataChannel(byte mdepid, string conf)

Do we really need to expose the mdepid to the application? Isn't there
any way to abstract this for the application?

>
> Creates a new data channel with the indicated config to the
> remote MCAP Data End Point (MDEP).
> The configuration should indicate the channel quality of
> service using one of this values "reliable", "streaming", "any".

What is "any" mean? and make it "Reliable", "Streaming" and "Any", with
capital letters.

>
> Returns the data channel path.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HealthError
>
> void ReconnectDataChannel(path data_channel)
>
> Reconnects a previously created data channel indicated by its
> path.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HealthError
> org.bluez.Error.NotFound
>
> void DeleteDataChannel(path data_channel)
>
> Deletes a data channel so it will not be available.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HealthError
>
> void DeleteAllDataChannels()
>
> Deletes all data channels so they will not be available for
> future use.
>
> Possible errors: org.bluez.Error.HealthError
>
> HealthAgent hierarchy
> =====================
>
> (this object is implemented by the HDP user in order to receive notifications)
>
> Service unique name
> Interface org.bluez.HealthAgent
> Object path freely definable
>
> Methods:
>
> void ServiceDiscovered(object path)
>
> This method is called when a device containing an HDP
> application is paired or when the method Update of the
> HealthManager is called and new HealthServices are discovered.
> The object path is the HealthService path. The method will be
> called for each HealthService.

This one could be a signal.

>
> (Not shure if this should be added)
> void ServiceRemoved(object path)
>
> This method is called if during an Update some HealthServices
> have disappeared. The method is called once for each removed
> HealthService.

That one as well.

>
> void DataChannelCreated(object path, path data_channel, string conf,
> fd file_descriptor)
>
> This method is called when a new data channel is created.
>
> The path contains the object path of the HealthService that
> created the connection, the data_channel is the path that
> identifies the data channel, conf is the quality of service of
> the data channel ("reliable" or "streaming") and file_descriptor
> the file descriptor for reading and writing data.
>
> void DataChannelReconnected(object path, path data_channel, string conf,
> fd file_descriptor))
>
> This method is called when a closed data channel is reconnected
> by the remote device.
>
> The path contains the object path of the HealthService that
> reconnected the channel. data_channel is the path that
> identifies the data channel, conf is the quality of service of
> the data channel ("reliable" or "streaming") and file_descriptor
> is the file descriptor for reading and writing data.

Couldn't these two be integrated into one? What they do is just pass the
fd to the application. The application can keep the information about if
it is a Created or Reconnected data channel because it knows what is
being requested.

Also, is the conf parameter really needed? The application should know
the channel type it asked.


>
> void DataChannelRemoved(object path, path data_channel)
>
> This method is called when a data channel is deleted.
>
> After this call the data channel path will not be valid and can
> be reused for future creation of data channels. The path is the
> path of the HealthService that removes the data channel.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

--
Gustavo F. Padovan
http://padovan.org

2010-07-09 14:04:52

by Elvis Pfutzenreuter

[permalink] [raw]
Subject: Re: Proposed API for HDP

Hi,

On Jul 9, 2010, at 10:49 AM, Jos? Antonio Santos Cadenas wrote:

> I wrote a new API based on the changes suggested in this thread.
>
> Regards.
>
> Jose.
>
>
> BlueZ D-Bus Health API description
> **********************************
>
> Santiago Carot-Nemesio <[email protected]>
> Jos? Antonio Santos-Cadenas <[email protected]>
> Elvis Pf?tzenreuter <[email protected]>
>
> Health Device Profile hierarchy
> ===============================
>
> Service org.bluez
> Interface org.bluez.HealthManager
> Object path [variable prefix]/{hci0,hci1,...}
>
> Methods:
>
> path RegisterApplication(object path, dict config)
>
> Returns the path of the new registered application. The path
> parameter is the path of the object with the callbacks to
> notify events (see org.bluez.HealthAgent at the end of this
> document)
> This petition starts an mcap instance on every adapter and also
> register a proper record in the SDP if is needed.
>
> Dict is defined as bellow:
> {
> "end_points" : [{ (optional)
> "role" : ("source" or "sink"), (mandatory)
> "specs" :[{ (mandatory)
> "data_type" : uint16, (mandatory)
> "description" : string, (optional)
> }]
> }]
> }
>
> Application will be closed by the call or implicitly when the
> programs leaves the bus.
>
> Possible errors: org.bluez.Error.InvalidArguments
>
> void UnregisterApplication(path application)
>
> Closes the HDP application identified by the object path. Also
> application will be closed if the process that started it leaves
> the bus. If there is a SDP record associated to this application
> it will also be removed.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
>
> void UpdateServices()
>
> This method searches for HDP applications on the all remote
> devices and notifies them to the appropriate agents.
>
> --------------------------------------------------------------------------------
>
> Service org.bluez
> Interface org.bluez.HealthService
> Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
>
> Methods:
>
> array GetProperties()
>
> Gets the information of the remote application published on its
> SDP record. The returned data format is as follows:
>
> {
> "end_points": [
> "mdepid": uint8,
> "role" : "source" or "sink" ,
> "specs" : [{
> "dtype" : uint16,
> "description" : string, (optional)
> }]
> ]
> }
>
> boolean Echo(array{byte})
>
> Sends an echo petition to the remote service. Returns True if
> response matches with the buffer sent. If some error is detected
> False value is returned and the associated MCL is closed.
>
> path OpenDataChannel(byte mdepid, string conf)
>
> Creates a new data channel with the indicated config to the
> remote MCAP Data End Point (MDEP).
> The configuration should indicate the channel quality of
> service using one of this values "reliable", "streaming", "any".
>
> Returns the data channel path.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HealthError
>
> void ReconnectDataChannel(path data_channel)
>
> Reconnects a previously created data channel indicated by its
> path.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HealthError
> org.bluez.Error.NotFound
>
> void DeleteDataChannel(path data_channel)
>
> Deletes a data channel so it will not be available.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HealthError
>
> void DeleteAllDataChannels()
>
> Deletes all data channels so they will not be available for
> future use.
>
> Possible errors: org.bluez.Error.HealthError
>
> HealthAgent hierarchy
> =====================
>
> (this object is implemented by the HDP user in order to receive notifications)
>
> Service unique name
> Interface org.bluez.HealthAgent
> Object path freely definable
>
> Methods:
>
> void ServiceDiscovered(object path)
>
> This method is called when a device containing an HDP
> application is paired or when the method Update of the
> HealthManager is called and new HealthServices are discovered.
> The object path is the HealthService path. The method will be
> called for each HealthService.
>
> (Not shure if this should be added)
> void ServiceRemoved(object path)
>
> This method is called if during an Update some HealthServices
> have disappeared. The method is called once for each removed
> HealthService.
>
> void DataChannelCreated(object path, path data_channel, string conf,
> fd file_descriptor)
>
> This method is called when a new data channel is created.
>
> The path contains the object path of the HealthService that
> created the connection, the data_channel is the path that
> identifies the data channel, conf is the quality of service of
> the data channel ("reliable" or "streaming") and file_descriptor
> the file descriptor for reading and writing data.
>
> void DataChannelReconnected(object path, path data_channel, string conf,
> fd file_descriptor))
>
> This method is called when a closed data channel is reconnected
> by the remote device.
>
> The path contains the object path of the HealthService that
> reconnected the channel. data_channel is the path that
> identifies the data channel, conf is the quality of service of
> the data channel ("reliable" or "streaming") and file_descriptor
> is the file descriptor for reading and writing data.

I think that only one method for receiving both channel and creation and reconnection events is better. An additional boolean parameter like "new" or "reconnection" should suffice.

And we need to know which MDEP ID the remote side connected to. Otherwise, an acceptor would never know which endpoint the remote device actually connected to. (The initiator knows because it passed the MDEP ID in OpenDataChannel()).

How will the application detect a simple disconnection (which does not delete the data channel?) It is easily detectable by file descriptor closure, but this must be explicitly mentioned in API, so nobody keeps looking for a "disconnected" method.

Finally, the initiator call is Open...() and the method here is ...Created(). I guess both should use the same nomenclature.

>
> void DataChannelRemoved(object path, path data_channel)
>
> This method is called when a data channel is deleted.
>
> After this call the data channel path will not be valid and can
> be reused for future creation of data channels. The path is the
> path of the HealthService that removes the data channel.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html


Subject: Re: Proposed API for HDP

I wrote a new API based on the changes suggested in this thread.

Regards.

Jose.


BlueZ D-Bus Health API description
**********************************

Santiago Carot-Nemesio <[email protected]>
Jos? Antonio Santos-Cadenas <[email protected]>
Elvis Pf?tzenreuter <[email protected]>

Health Device Profile hierarchy
===============================

Service org.bluez
Interface org.bluez.HealthManager
Object path [variable prefix]/{hci0,hci1,...}

Methods:

path RegisterApplication(object path, dict config)

Returns the path of the new registered application. The path
parameter is the path of the object with the callbacks to
notify events (see org.bluez.HealthAgent at the end of this
document)
This petition starts an mcap instance on every adapter and also
register a proper record in the SDP if is needed.

Dict is defined as bellow:
{
"end_points" : [{ (optional)
"role" : ("source" or "sink"), (mandatory)
"specs" :[{ (mandatory)
"data_type" : uint16, (mandatory)
"description" : string, (optional)
}]
}]
}

Application will be closed by the call or implicitly when the
programs leaves the bus.

Possible errors: org.bluez.Error.InvalidArguments

void UnregisterApplication(path application)

Closes the HDP application identified by the object path. Also
application will be closed if the process that started it leaves
the bus. If there is a SDP record associated to this application
it will also be removed.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound

void UpdateServices()

This method searches for HDP applications on the all remote
devices and notifies them to the appropriate agents.

--------------------------------------------------------------------------------

Service org.bluez
Interface org.bluez.HealthService
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY

Methods:

array GetProperties()

Gets the information of the remote application published on its
SDP record. The returned data format is as follows:

{
"end_points": [
"mdepid": uint8,
"role" : "source" or "sink" ,
"specs" : [{
"dtype" : uint16,
"description" : string, (optional)
}]
]
}

boolean Echo(array{byte})

Sends an echo petition to the remote service. Returns True if
response matches with the buffer sent. If some error is detected
False value is returned and the associated MCL is closed.

path OpenDataChannel(byte mdepid, string conf)

Creates a new data channel with the indicated config to the
remote MCAP Data End Point (MDEP).
The configuration should indicate the channel quality of
service using one of this values "reliable", "streaming", "any".

Returns the data channel path.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.HealthError

void ReconnectDataChannel(path data_channel)

Reconnects a previously created data channel indicated by its
path.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.HealthError
org.bluez.Error.NotFound

void DeleteDataChannel(path data_channel)

Deletes a data channel so it will not be available.

Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
org.bluez.Error.HealthError

void DeleteAllDataChannels()

Deletes all data channels so they will not be available for
future use.

Possible errors: org.bluez.Error.HealthError

HealthAgent hierarchy
=====================

(this object is implemented by the HDP user in order to receive notifications)

Service unique name
Interface org.bluez.HealthAgent
Object path freely definable

Methods:

void ServiceDiscovered(object path)

This method is called when a device containing an HDP
application is paired or when the method Update of the
HealthManager is called and new HealthServices are discovered.
The object path is the HealthService path. The method will be
called for each HealthService.

(Not shure if this should be added)
void ServiceRemoved(object path)

This method is called if during an Update some HealthServices
have disappeared. The method is called once for each removed
HealthService.

void DataChannelCreated(object path, path data_channel, string conf,
fd file_descriptor)

This method is called when a new data channel is created.

The path contains the object path of the HealthService that
created the connection, the data_channel is the path that
identifies the data channel, conf is the quality of service of
the data channel ("reliable" or "streaming") and file_descriptor
the file descriptor for reading and writing data.

void DataChannelReconnected(object path, path data_channel, string conf,
fd file_descriptor))

This method is called when a closed data channel is reconnected
by the remote device.

The path contains the object path of the HealthService that
reconnected the channel. data_channel is the path that
identifies the data channel, conf is the quality of service of
the data channel ("reliable" or "streaming") and file_descriptor
is the file descriptor for reading and writing data.

void DataChannelRemoved(object path, path data_channel)

This method is called when a data channel is deleted.

After this call the data channel path will not be valid and can
be reused for future creation of data channels. The path is the
path of the HealthService that removes the data channel.

Subject: Re: Proposed API for HDP

El Thursday 08 July 2010 21:13:05 Gustavo F. Padovan escribi?:
> Hi Jos?,
>
> * Jos? Antonio Santos Cadenas <[email protected]> [2010-07-08 20:36:00
+0200]:
> > El Thursday 08 July 2010 19:54:30 Gustavo F. Padovan escribi?:
> > > Hi Jos?,
> > >
> > > * Jos? Antonio Santos Cadenas <[email protected]> [2010-07-08
> > > 19:12:31 +0200]:
> > >
> > > <snip>
> > >
> > > > Service org.bluez
> > > > Interface org.bluez.HealthDeviceApplication
> > > > Object path [variable
> > > > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
> > > >
> > > > Methods:
> > > > array GetProperties()
> > > >
> > > > Gets the information of the remote application published on
its
> > > > SDP record. The returned data format is as follows:
> > > >
> > > > {
> > > >
> > > > "end_points": [
> > > >
> > > > "mdepid": uint8,
> > > > "role" : "source" or "sink" ,
> > > > "specs" : [{
> > > >
> > > > "dtype" : uint16,
> > > > "description" : string, (optional)
> > > > }]
> > > >
> > > > ]
> > > >
> > > > }
> > > >
> > > > object Connect(path local_application_id)
> > > >
> > > > Connects the local application with the remote application.
> > > >
> > > > Only the bus client that created the local session will be
able
> > > > to create connections using it.
> > > >
> > > > If the Device is already connected with an other application
an
> > > > org.bluez.Error.AlreadyConnected error will be received.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.AlreadyConnected
> > > > org.bluez.Error.HealthError
> > > >
> > > > void Disconnect()
> > > >
> > > > Disconnect from the remote application the state will also be
> > > > deleted. And no future reconnections will be possible. For
> > > > keeping the state the method Pause of the health link should
be
> > > > used.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.NotFound
> > > > org.bluez.Error.HealthError
> > > >
> > > > boolean Echo(array{byte})
> > > >
> > > > Sends an echo petition to the remote intance. Returns True if
> > > > response matches with the buffer sent. If some error is
detected
> > > > False value is returned and the associated MCL is closed.
> > > >
> > > > path OpenDataChannel(byte mdepid, string conf)
> > > >
> > > > Creates a new data channel with the indicated config to the
> > > > remote MCAP Data End Point (MDEP).
> > > > The configuration should indicate the channel quality of
> > > > service using one of this values "reliable", "streaming",
"any".
> > > >
> > > > Returns the data channel path.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.HealthError
> > > >
> > > > void ReconnectDataChannel(path data_channel)
> > > >
> > > > Reconnects a previously created data channel indicated by its
> > > > path.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.HealthError
> > > > org.bluez.Error.NotFound
> > >
> > > So are we really going to expose the temporally disconnect and
> > > reconnection to the applicantion level? The application should not
> > > care if the data channel is there or not.
> >
> > We changed our mind about this issue because there are cases were an
> > implicit reconnection will not be possible (when the remote do not
> > publish an SDP record) so if the application is concerned about this
> > issues could try to avoid this kind of failure waiting for the remote to
> > reconnect the data channel.
>
> Is this better than simplify the API removing the Reconnection stuff?
> On average how much time takes to reconnect achieve the timeout?
> BTW, failure can occur on OpenDataChannel as well, that just happens.

I think it is better because you can deal with more situations. Imagine that
reconnections are performed implicitly. When you try to send data over a
closed channel, a reconnection will be attempted and fail because the remote
does not publish an SDP record. In this case the application perceives a
failure sending data and the channel will be ignored definitely. In the other
hand, if reconnections are explicit you know that the failure was during the
reconnection and it is up to the application to decide if the channel should
be closed or just wait until the remote device reconnects it.

>
> > > > int GetDataChannelFileDescriptor(path data_channel)
> > > >
> > > > Gets a file descriptor where data can be read or written.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.NotFound
> > > > org.bluez.Error.HealthError
> > >
> > > What about the fd-passing feature of D-Bus here?
> >
> > There is an error here, the return value is not an integer is a file
> > descriptor.
>
> No. The fd should go to the Agent automatically, once you try to
> open a data channel a callback in the Application should be registered.
> The callback is a function in the Agent API with the fd as parameter,
> that will be called once the connection in the lower layer is done.
> See the NewConnection method from the HandsfreeAgent Interface.

Subject: Re: Proposed API for HDP

El Thursday 08 July 2010 21:17:55 Gustavo F. Padovan escribi=F3:
> > > ---------------------------------------------------------------------=
=2D-
> > > ---------
> > >=20
> > > Service org.bluez
> > > Interface org.bluez.HealthDeviceApplication
> > > Object path [variable
> > > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
> >=20
> > That is more like the org.bluez.HealthService as mentioned above. So
> > lets combine them. I don't see a need for splitting these.
> >=20
> > > Methods:
> > > array GetProperties()
> > > =09
> > > Gets the information of the remote application published on its
> > > SDP record. The returned data format is as follows:
> > > =09
> > > {
> > > =09
> > > "end_points": [
> > > =09
> > > "mdepid": uint8,
> > > "role" : "source" or "sink" ,
> > > "specs" : [{
> > > =09
> > > "dtype" : uint16,
> > > "description" : string, (optional)
> > > }]
> > > =09
> > > ]
> > > =09
> > > }
> > > =09
> > > object Connect(path local_application_id)
> > > =09
> > > Connects the local application with the remote application.
> > > =09
> > > Only the bus client that created the local session will be able
> > > to create connections using it.
> > > =09
> > > If the Device is already connected with an other application an
> > > org.bluez.Error.AlreadyConnected error will be received.
> > > =09
> > > Possible errors: org.bluez.Error.InvalidArguments
> > > =09
> > > org.bluez.Error.AlreadyConnected
> > > org.bluez.Error.HealthError
> > > =09
> > > void Disconnect()
> > > =09
> > > Disconnect from the remote application the state will also be
> > > deleted. And no future reconnections will be possible. For
> > > keeping the state the method Pause of the health link should be
> > > used.
> > > =09
> > > Possible errors: org.bluez.Error.InvalidArguments
> > > =09
> > > org.bluez.Error.NotFound
> > > org.bluez.Error.HealthError
> >=20
> > Do we need Connect() and Disconnect() here. Can we just not create these
> > connections in the background based of a reference counting via the
> > channels?
> >=20
> > > boolean Echo(array{byte})
> > > =09
> > > Sends an echo petition to the remote intance. Returns True if
> > > response matches with the buffer sent. If some error is detected
> > > False value is returned and the associated MCL is closed.
> > > =09
> > > path OpenDataChannel(byte mdepid, string conf)
> > > =09
> > > Creates a new data channel with the indicated config to the
> > > remote MCAP Data End Point (MDEP).
> > > The configuration should indicate the channel quality of
> > > service using one of this values "reliable", "streaming", "any".
> > > =09
> > > Returns the data channel path.
> > > =09
> > > Possible errors: org.bluez.Error.InvalidArguments
> > > =09
> > > org.bluez.Error.HealthError
> > > =09
> > > void ReconnectDataChannel(path data_channel)
> > > =09
> > > Reconnects a previously created data channel indicated by its
> > > path.
> > > =09
> > > Possible errors: org.bluez.Error.InvalidArguments
> > > =09
> > > org.bluez.Error.HealthError
> > > org.bluez.Error.NotFound
> > > =09
> > > int GetDataChannelFileDescriptor(path data_channel)
> > > =09
> > > Gets a file descriptor where data can be read or written.
> > > =09
> > > Possible errors: org.bluez.Error.InvalidArguments
> > > =09
> > > org.bluez.Error.NotFound
> > > org.bluez.Error.HealthError
> > > =09
> > > void DeleteDataChannel(path data_channel)
> > > =09
> > > Deletes a data channel so it will not be available to use.
> > > =09
> > > Possible errors: org.bluez.Error.InvalidArguments
> > > =09
> > > org.bluez.Error.NotFound
> > > org.bluez.Error.HealthError
> > > =09
> > > void DeleteAllDataChannels()
> > > =09
> > > Deletes all data channels so they will not be available for
> > > future use. Typically this function is called when the
> > > connection with the remote device will be closed permanently.
> > > =09
> > > Possible errors: org.bluez.Error.HealthError
> >=20
> > This actually means also Disconnect() to me. So clear the extra work of
> > connect and disconnect can be done in the background and invisible for
> > the user.
> >=20
> > > dict GetDataChannelStatus()
> > > =09
> > > Return a dictionary with all the data channels that can be used
> > > to send data right now. The dictionary is formed like follows:
> > > =09
> > > {
> > > =09
> > > "reliable": [channel_path_r1, channel_path_r2, ...],
> > > "streaming" : [channel_path_s1, channel_path_s2, ...]
> > > =09
> > > }
> > > =09
> > > The fist reliable data channel will always be the first data
> > > channel in reliable array.
>=20
> You don't need this method, DataChannel could be a Property and then you
> get this via GetProperties().

The problem is that properties are public and any process could access the=
=20
data channel status of the link even when they did not created the applicat=
ion=20
that is using the data channels. BTW this method can be removed because all=
=20
the data channel creation and deletion are notified to the agent so it alre=
ady=20
has this information.

2010-07-08 19:50:54

by Santiago Carot-Nemesio

[permalink] [raw]
Subject: Re: Proposed API for HDP

Hi,

El jue, 08-07-2010 a las 16:15 -0300, Marcel Holtmann escribió:
> Hi Jose,
>
> > > > Health Device Profile hierarchy
> > > > ===============================
> > > >
> > > > Service org.bluez
> > > > Interface org.bluez.HealthAdapter
> > > > Object path [variable prefix]/{hci0,hci1,...}
> > >
> > > so I changed my mind here. Basing this on the local adapter is rather
> > > pointless.
> > >
> > > Lets just do org.bluez.HealthManager on /org/bluez object path. There is
> > > no need that the calling application knows anything about the specific
> > > adapters in our system. We properly separate them anyway during paring.
> > >
> > > Only the application that does the initial pairing with a remote health
> > > device needs to know which adapter to use. For the actual health
> > > application it is pointless since it will be notified about the paired
> > > health device initially.
> >
> > In case we don't use an adapter how can we know were the connections are
> > waited. ¿In all the adapters? Remember that this is going to create an SDP
> > record and also open l2cap sockets waiting data channels.
>
> so you only need to wait on the adapters that have been paired with a
> remote device. However also it is just okay to listen via all adapters.
> I don't see a direct need to differentiate this.
>
> > > > Methods:
> > > > path CreateApplication(object path, dict config)
> > > >
> > > > Returns the path of the new created application. The path
> > > > parameter is the path of the object with the callbacks to
> > > > notify events (see org.bluez.HealthAgent at the end of this
> > > > document)
> > > > This petition starts an mcap instance and also register a proper
> > > > record in the SDP if is needed.
> > > >
> > > > Dict is defined as bellow:
> > > > {
> > > >
> > > > "end_points" : [{ (optional)
> > > >
> > > > "role" : ("source" or "sink"), (mandatory)
> > > > "specs" :[{ (mandatory)
> > > >
> > > > "data_type" : uint16, (mandatory)
> > > > "description" : string, (optional)
> > > >
> > > > }]
> > > >
> > > > }]
> > > >
> > > > }
> > > >
> > > > Application will be closed by the call or implicitly when the
> > > > programs leaves the bus.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > void ReleaseApplication(path application)
> > > >
> > > > Closes the HDP application identified by the object path. Also
> > > > application will be closed if the process that started it leaves
> > > > the bus. If there is a SDP record associated to this application
> > > > it will be removed.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.NotFound
> > >
> > > Since we now make this as part of a generic manager, the method class
> > > RegisterApplication and UnregisterApplication are a lot better choice.
> > >
> > > > array GetRemoteApplications(path application)
> > > >
> > > > This method will return an array with the paths of all the
> > > > remote instances found in remote devices.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.NotFound
> > >
> > > We don't wanna do that. When you register your application the first
> > > callback via the agent should be telling what remote instances are
> > > available.
> > >
> > > This has the advantage that the code flow for the application is
> > > simpler. It just has to listen to that update. And if you register your
> > > application before pairing with a new device, it will still work. So no
> > > extra work to listen for new devices and bootstrapping an existing list.
> > >
> > > > -------------------------------------------------------------------------
> > > > -------
> > > >
> > > > Service org.bluez
> > > > Interface org.bluez.HealthDevice
> > > > Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
> > >
> > > This is not really a health device. As mentioned yesterday, we can have
> > > multiple health service per remote device. So we should be using here
> > > are org.bluez.HealthService for every SDP record for HDP inside the
> > > remote device.
> > >
> > > So potential object paths are .../hci0/dev_xxxxxxxx/{hdp0,hdp1,...} and
> > > so on. This way we clearly map health service and not bother with remote
> > > device details that might implement multiple functions.
> >
> > This object is created on each adapter for refreshing the SDP records. It is
> > supposed to search again for HDP records on the device and notify them to the
> > proper agents.
>
> That can be done automatically via existing BlueZ D-Bus APIs. I don't
> think there is need to have specific functionality.
>
> > > > Methods:
> > > > void Refresh()
> > > >
> > > > This method searches for HDP applications in the remote device
> > > > and notifies them to the appropriate agents.
> > >
> > > I might have called this Update(), but that is a minor detail.
> >
> > Ok
> >
> > >
> > > > -------------------------------------------------------------------------
> > > > -------
> > > >
> > > > Service org.bluez
> > > > Interface org.bluez.HealthDeviceApplication
> > > > Object path [variable
> > > > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
> > >
> > > That is more like the org.bluez.HealthService as mentioned above. So
> > > lets combine them. I don't see a need for splitting these.
> >
> > As I mentioned above, I think next methods and the previous one are different.
> > Is a little bit ugly but I think that is necessary to have a way for check
> > again the SDP records looking for new remote instances (or applications).
> >
> > >
> > > > Methods:
> > > > array GetProperties()
> > > >
> > > > Gets the information of the remote application published on its
> > > > SDP record. The returned data format is as follows:
> > > >
> > > > {
> > > >
> > > > "end_points": [
> > > >
> > > > "mdepid": uint8,
> > > > "role" : "source" or "sink" ,
> > > > "specs" : [{
> > > >
> > > > "dtype" : uint16,
> > > > "description" : string, (optional)
> > > > }]
> > > >
> > > > ]
> > > >
> > > > }
> > > >
> > > > object Connect(path local_application_id)
> > > >
> > > > Connects the local application with the remote application.
> > > >
> > > > Only the bus client that created the local session will be able
> > > > to create connections using it.
> > > >
> > > > If the Device is already connected with an other application an
> > > > org.bluez.Error.AlreadyConnected error will be received.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.AlreadyConnected
> > > > org.bluez.Error.HealthError
> > > >
> > > > void Disconnect()
> > > >
> > > > Disconnect from the remote application the state will also be
> > > > deleted. And no future reconnections will be possible. For
> > > > keeping the state the method Pause of the health link should be
> > > > used.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.NotFound
> > > > org.bluez.Error.HealthError
> > >
> > > Do we need Connect() and Disconnect() here. Can we just not create these
> > > connections in the background based of a reference counting via the
> > > channels?
> >
> > This functions offer an abstraction to create a mcl and removing it from
> > cache. As status is maintained even when the connection is off. So Connect is
> > something like start keeping state and Disconnect is like stop keeping state.
>
> I don't see a need here. That can be hidden from the application. I
> would make the channel look persistent and not bother with manual
> connect of the MCL entity.
>
> > > > boolean Echo(array{byte})
> > > >
> > > > Sends an echo petition to the remote intance. Returns True if
> > > > response matches with the buffer sent. If some error is detected
> > > > False value is returned and the associated MCL is closed.
> > > >
> > > > path OpenDataChannel(byte mdepid, string conf)
> > > >
> > > > Creates a new data channel with the indicated config to the
> > > > remote MCAP Data End Point (MDEP).
> > > > The configuration should indicate the channel quality of
> > > > service using one of this values "reliable", "streaming", "any".
> > > >
> > > > Returns the data channel path.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.HealthError
> > > >
> > > > void ReconnectDataChannel(path data_channel)
> > > >
> > > > Reconnects a previously created data channel indicated by its
> > > > path.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.HealthError
> > > > org.bluez.Error.NotFound
> > > >
> > > > int GetDataChannelFileDescriptor(path data_channel)
> > > >
> > > > Gets a file descriptor where data can be read or written.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.NotFound
> > > > org.bluez.Error.HealthError
> > > >
> > > > void DeleteDataChannel(path data_channel)
> > > >
> > > > Deletes a data channel so it will not be available to use.
> > > >
> > > > Possible errors: org.bluez.Error.InvalidArguments
> > > >
> > > > org.bluez.Error.NotFound
> > > > org.bluez.Error.HealthError
> > > >
> > > > void DeleteAllDataChannels()
> > > >
> > > > Deletes all data channels so they will not be available for
> > > > future use. Typically this function is called when the
> > > > connection with the remote device will be closed permanently.
> > > >
> > > > Possible errors: org.bluez.Error.HealthError
> > >
> > > This actually means also Disconnect() to me. So clear the extra work of
> > > connect and disconnect can be done in the background and invisible for
> > > the user.
> >
> > It is not just the same. Probably the explanations is not very pointless. This
> > is a way for deleting all data channels but keeping the connection active
> > (waiting for more channel creation)
>
> That is fine, but way? We can use and idle timeout to keep the
> connection around and disconnect it after inactivity. That is a good way
> of handling this anyway. And if disconnect, then the other side just
> needs to reestablish it again. Happens. I don't want the upper layer to
> worry about these details.

Just to clear this point, Why do we want to delete all data channels and
preserve active the MCL connection?, it is because the health device
doesnt want to send any data but it still may want to send
synchronization commands (CSP).

>
> > >
> > > > dict GetDataChannelStatus()
> > > >
> > > > Return a dictionary with all the data channels that can be used
> > > > to send data right now. The dictionary is formed like follows:
> > > >
> > > > {
> > > >
> > > > "reliable": [channel_path_r1, channel_path_r2, ...],
> > > > "streaming" : [channel_path_s1, channel_path_s2, ...]
> > > >
> > > > }
> > > >
> > > > The fist reliable data channel will always be the first data
> > > > channel in reliable array.
> > > >
> > > > HealthAgent hierarchy
> > > > =====================
> > > >
> > > > (this object is implemented by the HDP user in order to receive
> > > > notifications)
> > > >
> > > > Service unique name
> > > > Interface org.bluez.HealthAgent
> > > > Object path freely definable
> > > >
> > > > Methods:
> > > > void DeviceApplicationDiscovered(object path)
> > > >
> > > > This method is called when a device containing an hdp
> > > > application is connected. The object path is the application
> > > > path. The method will be called one time for each
> > > > application.
> > >
> > > I think this should be ServiceDiscovered and map to a HealthService.
> >
> > Ok
> >
> > >
> > > > void DeviceConnected(object path)
> > > >
> > > > This method is called whenever a new connection has been
> > > > established over the control channel of the current HDP
> > > > application. The object path paremeter contains the object path
> > > > of the connected HealthDevice.
> > >
> > > Don't see a useful need for this. I don't want to expose HealthDevice
> > > details anyway.
> >
> > What this tries to mean is that this HealthService has connected with the
> > local Application so the application can open data channels with it now.
>
> And why does it care? It only cares when a channel has been created.
> What is the benefit about telling about a physical link that has no
> users yet.
>
> >
> > >
> > > > void DevicePaused(object path)
> > > >
> > > > This method is called when a MCL is closed. Future reconnections
> > > > will be notified using the DeviceRestarted callback.
> > > > All data channels associated to this device will be closed and
> > > > a reconnection will be needed before using them again.
> > > >
> > > > void DeviceResumed(object path)
> > > >
> > > > This method is called whenever a MCL is reconnected. All data
> > > > channels associated are still closed but they will be able to be
> > > > reconnected skipping the configuration process.
> > > >
> > > > void DeviceDisconnected(object path)
> > > >
> > > > This method is called when a remote device is disconnected or
> > > > removed from MCAP cache. Any future reconnections will fail.
> > > > Also all data channels associated to this device will be closed.
> > >
> > > Why bother with this. We can do this on channel level.
> >
> > The problem is that in some cases (when the remote is not publishing a record)
> > it is not possible to open data channels nor reconnecting the mcl so it is not
> > possible to make this automatically. The application should be concerned about
> > this issues to avoid this kind of operation in this cases.
>
> I can follow the reason. We can figure this out intelligent for the
> application. If we can't then neither will the application.
>
> >
> > >
> > > > void CreatedDataChannel(object path, path data_channel, string conf)
> > > >
> > > > This method is called when a new data channel is created.
> > > >
> > > > The path contains the object path of the HealthDeviceApplication
> > > > where the new connection is created, the data_channel is the
> > > > path for identify the data channel and conf is the quality of
> > > > service of the data channel ("reliable" or "streaming").
> > >
> > > DataChannelCreated please.
> > >
> > > > void DataChannelReconnected(object path, path data_channel, string
> > conf)
> > > >
> > > > This method is called when a closed data channel is reconnected
> > > > by the remote device.
> > > >
> > > > Conf will be "reliable" or "streaming".
> > > >
> > > > TThe path contains the object path of the
> > > > HealthDeviceApplication where the new connection is reconnected,
> > > > the data_channel is the path for identify the data channel and
> > > > conf is the quality of service of the data channel ("reliable"
> > > > or "streaming").
> > > >
> > > > void DeletedDataChannel(object path, path data_channel)
> > > >
> > > > This method is called when a data channel is deleted.
> > > >
> > > > After this call the data channel path will not be valid and can
> > > > be reused for future creation of data channels.
> > >
> > > DataChannelRemoved. We always map create with remove.
> > >
> > > > void DeletedAllDataChannels(object path)
> > > >
> > > > This method is called when all data channels are deleted.
> > > >
> > > > The path contains the object path of the HealthDeviceApplication
> > > > where the data channels are deleted.
> > >
> > > That is pointless. You will get separate callbacks for each channel
> > > anyway.
> >
> > We tried to avoid calling may times to the same callback when a delete all
> > operation is done, but of course it is not necessary.
>
> I would normally agree, but about how many channels are we talking here.
> 5, 10 or 200. Since I assume this is mostly 2-3 channels sending it
> multiple times on cleanup just makes the code flow inside the
> application a lot simpler. That is what we want. The extra payload on
> the D-Bus can be neglected her in favor of a simpler application work
> flow.
>
> Regards
>
> Marcel
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2010-07-08 19:17:55

by Gustavo Padovan

[permalink] [raw]
Subject: Re: Proposed API for HDP

>
> > --------------------------------------------------------------------------------
> >
> > Service org.bluez
> > Interface org.bluez.HealthDeviceApplication
> > Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
> >
>
> That is more like the org.bluez.HealthService as mentioned above. So
> lets combine them. I don't see a need for splitting these.
>
> > Methods:
> >
> > array GetProperties()
> >
> > Gets the information of the remote application published on its
> > SDP record. The returned data format is as follows:
> >
> > {
> > "end_points": [
> > "mdepid": uint8,
> > "role" : "source" or "sink" ,
> > "specs" : [{
> > "dtype" : uint16,
> > "description" : string, (optional)
> > }]
> > ]
> > }
> >
> > object Connect(path local_application_id)
> >
> > Connects the local application with the remote application.
> >
> > Only the bus client that created the local session will be able
> > to create connections using it.
> >
> > If the Device is already connected with an other application an
> > org.bluez.Error.AlreadyConnected error will be received.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.AlreadyConnected
> > org.bluez.Error.HealthError
> >
> > void Disconnect()
> >
> > Disconnect from the remote application the state will also be
> > deleted. And no future reconnections will be possible. For
> > keeping the state the method Pause of the health link should be
> > used.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HealthError
>
> Do we need Connect() and Disconnect() here. Can we just not create these
> connections in the background based of a reference counting via the
> channels?
>
> > boolean Echo(array{byte})
> >
> > Sends an echo petition to the remote intance. Returns True if
> > response matches with the buffer sent. If some error is detected
> > False value is returned and the associated MCL is closed.
> >
> > path OpenDataChannel(byte mdepid, string conf)
> >
> > Creates a new data channel with the indicated config to the
> > remote MCAP Data End Point (MDEP).
> > The configuration should indicate the channel quality of
> > service using one of this values "reliable", "streaming", "any".
> >
> > Returns the data channel path.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.HealthError
> >
> > void ReconnectDataChannel(path data_channel)
> >
> > Reconnects a previously created data channel indicated by its
> > path.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.HealthError
> > org.bluez.Error.NotFound
> >
> > int GetDataChannelFileDescriptor(path data_channel)
> >
> > Gets a file descriptor where data can be read or written.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HealthError
> >
> > void DeleteDataChannel(path data_channel)
> >
> > Deletes a data channel so it will not be available to use.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HealthError
> >
> > void DeleteAllDataChannels()
> >
> > Deletes all data channels so they will not be available for
> > future use. Typically this function is called when the
> > connection with the remote device will be closed permanently.
> >
> > Possible errors: org.bluez.Error.HealthError
>
> This actually means also Disconnect() to me. So clear the extra work of
> connect and disconnect can be done in the background and invisible for
> the user.
>
> > dict GetDataChannelStatus()
> >
> > Return a dictionary with all the data channels that can be used
> > to send data right now. The dictionary is formed like follows:
> >
> > {
> > "reliable": [channel_path_r1, channel_path_r2, ...],
> > "streaming" : [channel_path_s1, channel_path_s2, ...]
> > }
> >
> > The fist reliable data channel will always be the first data
> > channel in reliable array.
> >

You don't need this method, DataChannel could be a Property and then you
get this via GetProperties().

--
Gustavo F. Padovan
http://padovan.org

2010-07-08 19:15:20

by Marcel Holtmann

[permalink] [raw]
Subject: Re: Proposed API for HDP

Hi Jose,

> > > Health Device Profile hierarchy
> > > ===============================
> > >
> > > Service org.bluez
> > > Interface org.bluez.HealthAdapter
> > > Object path [variable prefix]/{hci0,hci1,...}
> >
> > so I changed my mind here. Basing this on the local adapter is rather
> > pointless.
> >
> > Lets just do org.bluez.HealthManager on /org/bluez object path. There is
> > no need that the calling application knows anything about the specific
> > adapters in our system. We properly separate them anyway during paring.
> >
> > Only the application that does the initial pairing with a remote health
> > device needs to know which adapter to use. For the actual health
> > application it is pointless since it will be notified about the paired
> > health device initially.
>
> In case we don't use an adapter how can we know were the connections are
> waited. ¿In all the adapters? Remember that this is going to create an SDP
> record and also open l2cap sockets waiting data channels.

so you only need to wait on the adapters that have been paired with a
remote device. However also it is just okay to listen via all adapters.
I don't see a direct need to differentiate this.

> > > Methods:
> > > path CreateApplication(object path, dict config)
> > >
> > > Returns the path of the new created application. The path
> > > parameter is the path of the object with the callbacks to
> > > notify events (see org.bluez.HealthAgent at the end of this
> > > document)
> > > This petition starts an mcap instance and also register a proper
> > > record in the SDP if is needed.
> > >
> > > Dict is defined as bellow:
> > > {
> > >
> > > "end_points" : [{ (optional)
> > >
> > > "role" : ("source" or "sink"), (mandatory)
> > > "specs" :[{ (mandatory)
> > >
> > > "data_type" : uint16, (mandatory)
> > > "description" : string, (optional)
> > >
> > > }]
> > >
> > > }]
> > >
> > > }
> > >
> > > Application will be closed by the call or implicitly when the
> > > programs leaves the bus.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > void ReleaseApplication(path application)
> > >
> > > Closes the HDP application identified by the object path. Also
> > > application will be closed if the process that started it leaves
> > > the bus. If there is a SDP record associated to this application
> > > it will be removed.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.NotFound
> >
> > Since we now make this as part of a generic manager, the method class
> > RegisterApplication and UnregisterApplication are a lot better choice.
> >
> > > array GetRemoteApplications(path application)
> > >
> > > This method will return an array with the paths of all the
> > > remote instances found in remote devices.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.NotFound
> >
> > We don't wanna do that. When you register your application the first
> > callback via the agent should be telling what remote instances are
> > available.
> >
> > This has the advantage that the code flow for the application is
> > simpler. It just has to listen to that update. And if you register your
> > application before pairing with a new device, it will still work. So no
> > extra work to listen for new devices and bootstrapping an existing list.
> >
> > > -------------------------------------------------------------------------
> > > -------
> > >
> > > Service org.bluez
> > > Interface org.bluez.HealthDevice
> > > Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
> >
> > This is not really a health device. As mentioned yesterday, we can have
> > multiple health service per remote device. So we should be using here
> > are org.bluez.HealthService for every SDP record for HDP inside the
> > remote device.
> >
> > So potential object paths are .../hci0/dev_xxxxxxxx/{hdp0,hdp1,...} and
> > so on. This way we clearly map health service and not bother with remote
> > device details that might implement multiple functions.
>
> This object is created on each adapter for refreshing the SDP records. It is
> supposed to search again for HDP records on the device and notify them to the
> proper agents.

That can be done automatically via existing BlueZ D-Bus APIs. I don't
think there is need to have specific functionality.

> > > Methods:
> > > void Refresh()
> > >
> > > This method searches for HDP applications in the remote device
> > > and notifies them to the appropriate agents.
> >
> > I might have called this Update(), but that is a minor detail.
>
> Ok
>
> >
> > > -------------------------------------------------------------------------
> > > -------
> > >
> > > Service org.bluez
> > > Interface org.bluez.HealthDeviceApplication
> > > Object path [variable
> > > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
> >
> > That is more like the org.bluez.HealthService as mentioned above. So
> > lets combine them. I don't see a need for splitting these.
>
> As I mentioned above, I think next methods and the previous one are different.
> Is a little bit ugly but I think that is necessary to have a way for check
> again the SDP records looking for new remote instances (or applications).
>
> >
> > > Methods:
> > > array GetProperties()
> > >
> > > Gets the information of the remote application published on its
> > > SDP record. The returned data format is as follows:
> > >
> > > {
> > >
> > > "end_points": [
> > >
> > > "mdepid": uint8,
> > > "role" : "source" or "sink" ,
> > > "specs" : [{
> > >
> > > "dtype" : uint16,
> > > "description" : string, (optional)
> > > }]
> > >
> > > ]
> > >
> > > }
> > >
> > > object Connect(path local_application_id)
> > >
> > > Connects the local application with the remote application.
> > >
> > > Only the bus client that created the local session will be able
> > > to create connections using it.
> > >
> > > If the Device is already connected with an other application an
> > > org.bluez.Error.AlreadyConnected error will be received.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.AlreadyConnected
> > > org.bluez.Error.HealthError
> > >
> > > void Disconnect()
> > >
> > > Disconnect from the remote application the state will also be
> > > deleted. And no future reconnections will be possible. For
> > > keeping the state the method Pause of the health link should be
> > > used.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.NotFound
> > > org.bluez.Error.HealthError
> >
> > Do we need Connect() and Disconnect() here. Can we just not create these
> > connections in the background based of a reference counting via the
> > channels?
>
> This functions offer an abstraction to create a mcl and removing it from
> cache. As status is maintained even when the connection is off. So Connect is
> something like start keeping state and Disconnect is like stop keeping state.

I don't see a need here. That can be hidden from the application. I
would make the channel look persistent and not bother with manual
connect of the MCL entity.

> > > boolean Echo(array{byte})
> > >
> > > Sends an echo petition to the remote intance. Returns True if
> > > response matches with the buffer sent. If some error is detected
> > > False value is returned and the associated MCL is closed.
> > >
> > > path OpenDataChannel(byte mdepid, string conf)
> > >
> > > Creates a new data channel with the indicated config to the
> > > remote MCAP Data End Point (MDEP).
> > > The configuration should indicate the channel quality of
> > > service using one of this values "reliable", "streaming", "any".
> > >
> > > Returns the data channel path.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.HealthError
> > >
> > > void ReconnectDataChannel(path data_channel)
> > >
> > > Reconnects a previously created data channel indicated by its
> > > path.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.HealthError
> > > org.bluez.Error.NotFound
> > >
> > > int GetDataChannelFileDescriptor(path data_channel)
> > >
> > > Gets a file descriptor where data can be read or written.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.NotFound
> > > org.bluez.Error.HealthError
> > >
> > > void DeleteDataChannel(path data_channel)
> > >
> > > Deletes a data channel so it will not be available to use.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.NotFound
> > > org.bluez.Error.HealthError
> > >
> > > void DeleteAllDataChannels()
> > >
> > > Deletes all data channels so they will not be available for
> > > future use. Typically this function is called when the
> > > connection with the remote device will be closed permanently.
> > >
> > > Possible errors: org.bluez.Error.HealthError
> >
> > This actually means also Disconnect() to me. So clear the extra work of
> > connect and disconnect can be done in the background and invisible for
> > the user.
>
> It is not just the same. Probably the explanations is not very pointless. This
> is a way for deleting all data channels but keeping the connection active
> (waiting for more channel creation)

That is fine, but way? We can use and idle timeout to keep the
connection around and disconnect it after inactivity. That is a good way
of handling this anyway. And if disconnect, then the other side just
needs to reestablish it again. Happens. I don't want the upper layer to
worry about these details.

> >
> > > dict GetDataChannelStatus()
> > >
> > > Return a dictionary with all the data channels that can be used
> > > to send data right now. The dictionary is formed like follows:
> > >
> > > {
> > >
> > > "reliable": [channel_path_r1, channel_path_r2, ...],
> > > "streaming" : [channel_path_s1, channel_path_s2, ...]
> > >
> > > }
> > >
> > > The fist reliable data channel will always be the first data
> > > channel in reliable array.
> > >
> > > HealthAgent hierarchy
> > > =====================
> > >
> > > (this object is implemented by the HDP user in order to receive
> > > notifications)
> > >
> > > Service unique name
> > > Interface org.bluez.HealthAgent
> > > Object path freely definable
> > >
> > > Methods:
> > > void DeviceApplicationDiscovered(object path)
> > >
> > > This method is called when a device containing an hdp
> > > application is connected. The object path is the application
> > > path. The method will be called one time for each
> > > application.
> >
> > I think this should be ServiceDiscovered and map to a HealthService.
>
> Ok
>
> >
> > > void DeviceConnected(object path)
> > >
> > > This method is called whenever a new connection has been
> > > established over the control channel of the current HDP
> > > application. The object path paremeter contains the object path
> > > of the connected HealthDevice.
> >
> > Don't see a useful need for this. I don't want to expose HealthDevice
> > details anyway.
>
> What this tries to mean is that this HealthService has connected with the
> local Application so the application can open data channels with it now.

And why does it care? It only cares when a channel has been created.
What is the benefit about telling about a physical link that has no
users yet.

>
> >
> > > void DevicePaused(object path)
> > >
> > > This method is called when a MCL is closed. Future reconnections
> > > will be notified using the DeviceRestarted callback.
> > > All data channels associated to this device will be closed and
> > > a reconnection will be needed before using them again.
> > >
> > > void DeviceResumed(object path)
> > >
> > > This method is called whenever a MCL is reconnected. All data
> > > channels associated are still closed but they will be able to be
> > > reconnected skipping the configuration process.
> > >
> > > void DeviceDisconnected(object path)
> > >
> > > This method is called when a remote device is disconnected or
> > > removed from MCAP cache. Any future reconnections will fail.
> > > Also all data channels associated to this device will be closed.
> >
> > Why bother with this. We can do this on channel level.
>
> The problem is that in some cases (when the remote is not publishing a record)
> it is not possible to open data channels nor reconnecting the mcl so it is not
> possible to make this automatically. The application should be concerned about
> this issues to avoid this kind of operation in this cases.

I can follow the reason. We can figure this out intelligent for the
application. If we can't then neither will the application.

>
> >
> > > void CreatedDataChannel(object path, path data_channel, string conf)
> > >
> > > This method is called when a new data channel is created.
> > >
> > > The path contains the object path of the HealthDeviceApplication
> > > where the new connection is created, the data_channel is the
> > > path for identify the data channel and conf is the quality of
> > > service of the data channel ("reliable" or "streaming").
> >
> > DataChannelCreated please.
> >
> > > void DataChannelReconnected(object path, path data_channel, string
> conf)
> > >
> > > This method is called when a closed data channel is reconnected
> > > by the remote device.
> > >
> > > Conf will be "reliable" or "streaming".
> > >
> > > TThe path contains the object path of the
> > > HealthDeviceApplication where the new connection is reconnected,
> > > the data_channel is the path for identify the data channel and
> > > conf is the quality of service of the data channel ("reliable"
> > > or "streaming").
> > >
> > > void DeletedDataChannel(object path, path data_channel)
> > >
> > > This method is called when a data channel is deleted.
> > >
> > > After this call the data channel path will not be valid and can
> > > be reused for future creation of data channels.
> >
> > DataChannelRemoved. We always map create with remove.
> >
> > > void DeletedAllDataChannels(object path)
> > >
> > > This method is called when all data channels are deleted.
> > >
> > > The path contains the object path of the HealthDeviceApplication
> > > where the data channels are deleted.
> >
> > That is pointless. You will get separate callbacks for each channel
> > anyway.
>
> We tried to avoid calling may times to the same callback when a delete all
> operation is done, but of course it is not necessary.

I would normally agree, but about how many channels are we talking here.
5, 10 or 200. Since I assume this is mostly 2-3 channels sending it
multiple times on cleanup just makes the code flow inside the
application a lot simpler. That is what we want. The extra payload on
the D-Bus can be neglected her in favor of a simpler application work
flow.

Regards

Marcel



2010-07-08 19:13:05

by Gustavo Padovan

[permalink] [raw]
Subject: Re: Proposed API for HDP

Hi Jos?,

* Jos? Antonio Santos Cadenas <[email protected]> [2010-07-08 20:36:00 +0200]:

> El Thursday 08 July 2010 19:54:30 Gustavo F. Padovan escribi?:
> > Hi Jos?,
> >
> > * Jos? Antonio Santos Cadenas <[email protected]> [2010-07-08
> > 19:12:31 +0200]:
> >
> > <snip>
> >
> > > Service org.bluez
> > > Interface org.bluez.HealthDeviceApplication
> > > Object path [variable
> > > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
> > >
> > > Methods:
> > > array GetProperties()
> > >
> > > Gets the information of the remote application published on its
> > > SDP record. The returned data format is as follows:
> > >
> > > {
> > >
> > > "end_points": [
> > >
> > > "mdepid": uint8,
> > > "role" : "source" or "sink" ,
> > > "specs" : [{
> > >
> > > "dtype" : uint16,
> > > "description" : string, (optional)
> > > }]
> > >
> > > ]
> > >
> > > }
> > >
> > > object Connect(path local_application_id)
> > >
> > > Connects the local application with the remote application.
> > >
> > > Only the bus client that created the local session will be able
> > > to create connections using it.
> > >
> > > If the Device is already connected with an other application an
> > > org.bluez.Error.AlreadyConnected error will be received.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.AlreadyConnected
> > > org.bluez.Error.HealthError
> > >
> > > void Disconnect()
> > >
> > > Disconnect from the remote application the state will also be
> > > deleted. And no future reconnections will be possible. For
> > > keeping the state the method Pause of the health link should be
> > > used.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.NotFound
> > > org.bluez.Error.HealthError
> > >
> > > boolean Echo(array{byte})
> > >
> > > Sends an echo petition to the remote intance. Returns True if
> > > response matches with the buffer sent. If some error is detected
> > > False value is returned and the associated MCL is closed.
> > >
> > > path OpenDataChannel(byte mdepid, string conf)
> > >
> > > Creates a new data channel with the indicated config to the
> > > remote MCAP Data End Point (MDEP).
> > > The configuration should indicate the channel quality of
> > > service using one of this values "reliable", "streaming", "any".
> > >
> > > Returns the data channel path.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.HealthError
> > >
> > > void ReconnectDataChannel(path data_channel)
> > >
> > > Reconnects a previously created data channel indicated by its
> > > path.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.HealthError
> > > org.bluez.Error.NotFound
> >
> > So are we really going to expose the temporally disconnect and
> > reconnection to the applicantion level? The application should not
> > care if the data channel is there or not.
>
> We changed our mind about this issue because there are cases were an implicit
> reconnection will not be possible (when the remote do not publish an SDP
> record) so if the application is concerned about this issues could try to
> avoid this kind of failure waiting for the remote to reconnect the data
> channel.

Is this better than simplify the API removing the Reconnection stuff?
On average how much time takes to reconnect achieve the timeout?
BTW, failure can occur on OpenDataChannel as well, that just happens.

>
> >
> > > int GetDataChannelFileDescriptor(path data_channel)
> > >
> > > Gets a file descriptor where data can be read or written.
> > >
> > > Possible errors: org.bluez.Error.InvalidArguments
> > >
> > > org.bluez.Error.NotFound
> > > org.bluez.Error.HealthError
> >
> > What about the fd-passing feature of D-Bus here?
>
> There is an error here, the return value is not an integer is a file
> descriptor.

No. The fd should go to the Agent automatically, once you try to
open a data channel a callback in the Application should be registered.
The callback is a function in the Agent API with the fd as parameter,
that will be called once the connection in the lower layer is done.
See the NewConnection method from the HandsfreeAgent Interface.

--
Gustavo F. Padovan
http://padovan.org

Subject: Re: Proposed API for HDP

El Thursday 08 July 2010 19:54:30 Gustavo F. Padovan escribi?:
> Hi Jos?,
>
> * Jos? Antonio Santos Cadenas <[email protected]> [2010-07-08
> 19:12:31 +0200]:
>
> <snip>
>
> > Service org.bluez
> > Interface org.bluez.HealthDeviceApplication
> > Object path [variable
> > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
> >
> > Methods:
> > array GetProperties()
> >
> > Gets the information of the remote application published on its
> > SDP record. The returned data format is as follows:
> >
> > {
> >
> > "end_points": [
> >
> > "mdepid": uint8,
> > "role" : "source" or "sink" ,
> > "specs" : [{
> >
> > "dtype" : uint16,
> > "description" : string, (optional)
> > }]
> >
> > ]
> >
> > }
> >
> > object Connect(path local_application_id)
> >
> > Connects the local application with the remote application.
> >
> > Only the bus client that created the local session will be able
> > to create connections using it.
> >
> > If the Device is already connected with an other application an
> > org.bluez.Error.AlreadyConnected error will be received.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > org.bluez.Error.AlreadyConnected
> > org.bluez.Error.HealthError
> >
> > void Disconnect()
> >
> > Disconnect from the remote application the state will also be
> > deleted. And no future reconnections will be possible. For
> > keeping the state the method Pause of the health link should be
> > used.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > org.bluez.Error.NotFound
> > org.bluez.Error.HealthError
> >
> > boolean Echo(array{byte})
> >
> > Sends an echo petition to the remote intance. Returns True if
> > response matches with the buffer sent. If some error is detected
> > False value is returned and the associated MCL is closed.
> >
> > path OpenDataChannel(byte mdepid, string conf)
> >
> > Creates a new data channel with the indicated config to the
> > remote MCAP Data End Point (MDEP).
> > The configuration should indicate the channel quality of
> > service using one of this values "reliable", "streaming", "any".
> >
> > Returns the data channel path.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > org.bluez.Error.HealthError
> >
> > void ReconnectDataChannel(path data_channel)
> >
> > Reconnects a previously created data channel indicated by its
> > path.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > org.bluez.Error.HealthError
> > org.bluez.Error.NotFound
>
> So are we really going to expose the temporally disconnect and
> reconnection to the applicantion level? The application should not
> care if the data channel is there or not.

We changed our mind about this issue because there are cases were an implicit
reconnection will not be possible (when the remote do not publish an SDP
record) so if the application is concerned about this issues could try to
avoid this kind of failure waiting for the remote to reconnect the data
channel.

>
> > int GetDataChannelFileDescriptor(path data_channel)
> >
> > Gets a file descriptor where data can be read or written.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > org.bluez.Error.NotFound
> > org.bluez.Error.HealthError
>
> What about the fd-passing feature of D-Bus here?

There is an error here, the return value is not an integer is a file
descriptor.

Thanks for the comments.

Regards.

Jose.

Subject: Re: Proposed API for HDP

Hi Marcel,


El Thursday 08 July 2010 19:39:48 Marcel Holtmann escribi=F3:
> Hi Jose,
>=20
> > Health Device Profile hierarchy
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D
> >=20
> > Service org.bluez
> > Interface org.bluez.HealthAdapter
> > Object path [variable prefix]/{hci0,hci1,...}
>=20
> so I changed my mind here. Basing this on the local adapter is rather
> pointless.
>=20
> Lets just do org.bluez.HealthManager on /org/bluez object path. There is
> no need that the calling application knows anything about the specific
> adapters in our system. We properly separate them anyway during paring.
>=20
> Only the application that does the initial pairing with a remote health
> device needs to know which adapter to use. For the actual health
> application it is pointless since it will be notified about the paired
> health device initially.

In case we don't use an adapter how can we know were the connections are=20
waited. =BFIn all the adapters? Remember that this is going to create an SD=
P=20
record and also open l2cap sockets waiting data channels.

>=20
> > Methods:
> > path CreateApplication(object path, dict config)
> > =09
> > Returns the path of the new created application. The path
> > parameter is the path of the object with the callbacks to
> > notify events (see org.bluez.HealthAgent at the end of this
> > document)
> > This petition starts an mcap instance and also register a proper
> > record in the SDP if is needed.
> > =09
> > Dict is defined as bellow:
> > {
> > =09
> > "end_points" : [{ (optional)
> > =09
> > "role" : ("source" or "sink"), (mandatory)
> > "specs" :[{ (mandatory)
> > =09
> > "data_type" : uint16, (mandatory)
> > "description" : string, (optional)
> > =09
> > }]
> > =09
> > }]
> > =09
> > }
> > =09
> > Application will be closed by the call or implicitly when the
> > programs leaves the bus.
> > =09
> > Possible errors: org.bluez.Error.InvalidArguments
> > =09
> > void ReleaseApplication(path application)
> > =09
> > Closes the HDP application identified by the object path. Also
> > application will be closed if the process that started it leaves
> > the bus. If there is a SDP record associated to this application
> > it will be removed.
> > =09
> > Possible errors: org.bluez.Error.InvalidArguments
> > =09
> > org.bluez.Error.NotFound
>=20
> Since we now make this as part of a generic manager, the method class
> RegisterApplication and UnregisterApplication are a lot better choice.
>=20
> > array GetRemoteApplications(path application)
> > =09
> > This method will return an array with the paths of all the
> > remote instances found in remote devices.
> > =09
> > Possible errors: org.bluez.Error.InvalidArguments
> > =09
> > org.bluez.Error.NotFound
>=20
> We don't wanna do that. When you register your application the first
> callback via the agent should be telling what remote instances are
> available.
>=20
> This has the advantage that the code flow for the application is
> simpler. It just has to listen to that update. And if you register your
> application before pairing with a new device, it will still work. So no
> extra work to listen for new devices and bootstrapping an existing list.
>=20
> > -----------------------------------------------------------------------=
=2D-
> > -------
> >=20
> > Service org.bluez
> > Interface org.bluez.HealthDevice
> > Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
>=20
> This is not really a health device. As mentioned yesterday, we can have
> multiple health service per remote device. So we should be using here
> are org.bluez.HealthService for every SDP record for HDP inside the
> remote device.
>=20
> So potential object paths are .../hci0/dev_xxxxxxxx/{hdp0,hdp1,...} and
> so on. This way we clearly map health service and not bother with remote
> device details that might implement multiple functions.

This object is created on each adapter for refreshing the SDP records. It i=
s=20
supposed to search again for HDP records on the device and notify them to t=
he=20
proper agents.

>=20
> > Methods:
> > void Refresh()
> > =09
> > This method searches for HDP applications in the remote device
> > and notifies them to the appropriate agents.
>=20
> I might have called this Update(), but that is a minor detail.

Ok

>=20
> > -----------------------------------------------------------------------=
=2D-
> > -------
> >=20
> > Service org.bluez
> > Interface org.bluez.HealthDeviceApplication
> > Object path [variable
> > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
>=20
> That is more like the org.bluez.HealthService as mentioned above. So
> lets combine them. I don't see a need for splitting these.

As I mentioned above, I think next methods and the previous one are differe=
nt.=20
Is a little bit ugly but I think that is necessary to have a way for check=
=20
again the SDP records looking for new remote instances (or applications).

>=20
> > Methods:
> > array GetProperties()
> > =09
> > Gets the information of the remote application published on its
> > SDP record. The returned data format is as follows:
> > =09
> > {
> > =09
> > "end_points": [
> > =09
> > "mdepid": uint8,
> > "role" : "source" or "sink" ,
> > "specs" : [{
> > =09
> > "dtype" : uint16,
> > "description" : string, (optional)
> > }]
> > =09
> > ]
> > =09
> > }
> > =09
> > object Connect(path local_application_id)
> > =09
> > Connects the local application with the remote application.
> > =09
> > Only the bus client that created the local session will be able
> > to create connections using it.
> > =09
> > If the Device is already connected with an other application an
> > org.bluez.Error.AlreadyConnected error will be received.
> > =09
> > Possible errors: org.bluez.Error.InvalidArguments
> > =09
> > org.bluez.Error.AlreadyConnected
> > org.bluez.Error.HealthError
> > =09
> > void Disconnect()
> > =09
> > Disconnect from the remote application the state will also be
> > deleted. And no future reconnections will be possible. For
> > keeping the state the method Pause of the health link should be
> > used.
> > =09
> > Possible errors: org.bluez.Error.InvalidArguments
> > =09
> > org.bluez.Error.NotFound
> > org.bluez.Error.HealthError
>=20
> Do we need Connect() and Disconnect() here. Can we just not create these
> connections in the background based of a reference counting via the
> channels?

This functions offer an abstraction to create a mcl and removing it from=20
cache. As status is maintained even when the connection is off. So Connect =
is=20
something like start keeping state and Disconnect is like stop keeping stat=
e.

>=20
> > boolean Echo(array{byte})
> > =09
> > Sends an echo petition to the remote intance. Returns True if
> > response matches with the buffer sent. If some error is detected
> > False value is returned and the associated MCL is closed.
> > =09
> > path OpenDataChannel(byte mdepid, string conf)
> > =09
> > Creates a new data channel with the indicated config to the
> > remote MCAP Data End Point (MDEP).
> > The configuration should indicate the channel quality of
> > service using one of this values "reliable", "streaming", "any".
> > =09
> > Returns the data channel path.
> > =09
> > Possible errors: org.bluez.Error.InvalidArguments
> > =09
> > org.bluez.Error.HealthError
> > =09
> > void ReconnectDataChannel(path data_channel)
> > =09
> > Reconnects a previously created data channel indicated by its
> > path.
> > =09
> > Possible errors: org.bluez.Error.InvalidArguments
> > =09
> > org.bluez.Error.HealthError
> > org.bluez.Error.NotFound
> > =09
> > int GetDataChannelFileDescriptor(path data_channel)
> > =09
> > Gets a file descriptor where data can be read or written.
> > =09
> > Possible errors: org.bluez.Error.InvalidArguments
> > =09
> > org.bluez.Error.NotFound
> > org.bluez.Error.HealthError
> > =09
> > void DeleteDataChannel(path data_channel)
> > =09
> > Deletes a data channel so it will not be available to use.
> > =09
> > Possible errors: org.bluez.Error.InvalidArguments
> > =09
> > org.bluez.Error.NotFound
> > org.bluez.Error.HealthError
> > =09
> > void DeleteAllDataChannels()
> > =09
> > Deletes all data channels so they will not be available for
> > future use. Typically this function is called when the
> > connection with the remote device will be closed permanently.
> > =09
> > Possible errors: org.bluez.Error.HealthError
>=20
> This actually means also Disconnect() to me. So clear the extra work of
> connect and disconnect can be done in the background and invisible for
> the user.

It is not just the same. Probably the explanations is not very pointless. T=
his=20
is a way for deleting all data channels but keeping the connection active=20
(waiting for more channel creation)
>=20
> > dict GetDataChannelStatus()
> > =09
> > Return a dictionary with all the data channels that can be used
> > to send data right now. The dictionary is formed like follows:
> > =09
> > {
> > =09
> > "reliable": [channel_path_r1, channel_path_r2, ...],
> > "streaming" : [channel_path_s1, channel_path_s2, ...]
> > =09
> > }
> > =09
> > The fist reliable data channel will always be the first data
> > channel in reliable array.
> >=20
> > HealthAgent hierarchy
> > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> >=20
> > (this object is implemented by the HDP user in order to receive
> > notifications)
> >=20
> > Service unique name
> > Interface org.bluez.HealthAgent
> > Object path freely definable
> >=20
> > Methods:
> > void DeviceApplicationDiscovered(object path)
> > =09
> > This method is called when a device containing an hdp
> > application is connected. The object path is the application
> > path. The method will be called one time for each
> > application.
>=20
> I think this should be ServiceDiscovered and map to a HealthService.

Ok

>=20
> > void DeviceConnected(object path)
> > =09
> > This method is called whenever a new connection has been
> > established over the control channel of the current HDP
> > application. The object path paremeter contains the object path
> > of the connected HealthDevice.
>=20
> Don't see a useful need for this. I don't want to expose HealthDevice
> details anyway.

What this tries to mean is that this HealthService has connected with the=20
local Application so the application can open data channels with it now.

>=20
> > void DevicePaused(object path)
> > =09
> > This method is called when a MCL is closed. Future reconnections
> > will be notified using the DeviceRestarted callback.
> > All data channels associated to this device will be closed and
> > a reconnection will be needed before using them again.
> > =09
> > void DeviceResumed(object path)
> > =09
> > This method is called whenever a MCL is reconnected. All data
> > channels associated are still closed but they will be able to be
> > reconnected skipping the configuration process.
> > =09
> > void DeviceDisconnected(object path)
> > =09
> > This method is called when a remote device is disconnected or
> > removed from MCAP cache. Any future reconnections will fail.
> > Also all data channels associated to this device will be closed.
>=20
> Why bother with this. We can do this on channel level.

The problem is that in some cases (when the remote is not publishing a reco=
rd)=20
it is not possible to open data channels nor reconnecting the mcl so it is =
not=20
possible to make this automatically. The application should be concerned ab=
out=20
this issues to avoid this kind of operation in this cases.

>=20
> > void CreatedDataChannel(object path, path data_channel, string conf)
> > =09
> > This method is called when a new data channel is created.
> > =09
> > The path contains the object path of the HealthDeviceApplication
> > where the new connection is created, the data_channel is the
> > path for identify the data channel and conf is the quality of
> > service of the data channel ("reliable" or "streaming").
>=20
> DataChannelCreated please.
>=20
> > void DataChannelReconnected(object path, path data_channel, string=20
conf)
> > =09
> > This method is called when a closed data channel is reconnected
> > by the remote device.
> > =09
> > Conf will be "reliable" or "streaming".
> > =09
> > TThe path contains the object path of the
> > HealthDeviceApplication where the new connection is reconnected,
> > the data_channel is the path for identify the data channel and
> > conf is the quality of service of the data channel ("reliable"
> > or "streaming").
> > =09
> > void DeletedDataChannel(object path, path data_channel)
> > =09
> > This method is called when a data channel is deleted.
> > =09
> > After this call the data channel path will not be valid and can
> > be reused for future creation of data channels.
>=20
> DataChannelRemoved. We always map create with remove.
>=20
> > void DeletedAllDataChannels(object path)
> > =09
> > This method is called when all data channels are deleted.
> > =09
> > The path contains the object path of the HealthDeviceApplication
> > where the data channels are deleted.
>=20
> That is pointless. You will get separate callbacks for each channel
> anyway.

We tried to avoid calling may times to the same callback when a delete all=
=20
operation is done, but of course it is not necessary.

>=20
> And the agent is missing a Release method for unforseen terminations.
> See other agents for that detail.

I'll have a look.

>=20
> Regards
>=20
> Marcel

Thanks for your comments.

Regards

Jose

2010-07-08 17:54:30

by Gustavo Padovan

[permalink] [raw]
Subject: Re: Proposed API for HDP

Hi Jos?,

* Jos? Antonio Santos Cadenas <[email protected]> [2010-07-08 19:12:31 +0200]:

<snip>

>
> Service org.bluez
> Interface org.bluez.HealthDeviceApplication
> Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
>
> Methods:
>
> array GetProperties()
>
> Gets the information of the remote application published on its
> SDP record. The returned data format is as follows:
>
> {
> "end_points": [
> "mdepid": uint8,
> "role" : "source" or "sink" ,
> "specs" : [{
> "dtype" : uint16,
> "description" : string, (optional)
> }]
> ]
> }
>
> object Connect(path local_application_id)
>
> Connects the local application with the remote application.
>
> Only the bus client that created the local session will be able
> to create connections using it.
>
> If the Device is already connected with an other application an
> org.bluez.Error.AlreadyConnected error will be received.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.AlreadyConnected
> org.bluez.Error.HealthError
>
> void Disconnect()
>
> Disconnect from the remote application the state will also be
> deleted. And no future reconnections will be possible. For
> keeping the state the method Pause of the health link should be
> used.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HealthError
>
> boolean Echo(array{byte})
>
> Sends an echo petition to the remote intance. Returns True if
> response matches with the buffer sent. If some error is detected
> False value is returned and the associated MCL is closed.
>
> path OpenDataChannel(byte mdepid, string conf)
>
> Creates a new data channel with the indicated config to the
> remote MCAP Data End Point (MDEP).
> The configuration should indicate the channel quality of
> service using one of this values "reliable", "streaming", "any".
>
> Returns the data channel path.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HealthError
>
> void ReconnectDataChannel(path data_channel)
>
> Reconnects a previously created data channel indicated by its
> path.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HealthError
> org.bluez.Error.NotFound

So are we really going to expose the temporally disconnect and
reconnection to the applicantion level? The application should not
care if the data channel is there or not.

>
> int GetDataChannelFileDescriptor(path data_channel)
>
> Gets a file descriptor where data can be read or written.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HealthError

What about the fd-passing feature of D-Bus here?


--
Gustavo F. Padovan
http://padovan.org

2010-07-08 17:39:48

by Marcel Holtmann

[permalink] [raw]
Subject: Re: Proposed API for HDP

Hi Jose,

> Health Device Profile hierarchy
> ===============================
>
> Service org.bluez
> Interface org.bluez.HealthAdapter
> Object path [variable prefix]/{hci0,hci1,...}

so I changed my mind here. Basing this on the local adapter is rather
pointless.

Lets just do org.bluez.HealthManager on /org/bluez object path. There is
no need that the calling application knows anything about the specific
adapters in our system. We properly separate them anyway during paring.

Only the application that does the initial pairing with a remote health
device needs to know which adapter to use. For the actual health
application it is pointless since it will be notified about the paired
health device initially.

> Methods:
>
> path CreateApplication(object path, dict config)
>
> Returns the path of the new created application. The path
> parameter is the path of the object with the callbacks to
> notify events (see org.bluez.HealthAgent at the end of this
> document)
> This petition starts an mcap instance and also register a proper
> record in the SDP if is needed.
>
> Dict is defined as bellow:
> {
> "end_points" : [{ (optional)
> "role" : ("source" or "sink"), (mandatory)
> "specs" :[{ (mandatory)
> "data_type" : uint16, (mandatory)
> "description" : string, (optional)
> }]
> }]
> }
>
> Application will be closed by the call or implicitly when the
> programs leaves the bus.
>
> Possible errors: org.bluez.Error.InvalidArguments
>
> void ReleaseApplication(path application)
>
> Closes the HDP application identified by the object path. Also
> application will be closed if the process that started it leaves
> the bus. If there is a SDP record associated to this application
> it will be removed.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound

Since we now make this as part of a generic manager, the method class
RegisterApplication and UnregisterApplication are a lot better choice.

> array GetRemoteApplications(path application)
>
> This method will return an array with the paths of all the
> remote instances found in remote devices.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound

We don't wanna do that. When you register your application the first
callback via the agent should be telling what remote instances are
available.

This has the advantage that the code flow for the application is
simpler. It just has to listen to that update. And if you register your
application before pairing with a new device, it will still work. So no
extra work to listen for new devices and bootstrapping an existing list.

> --------------------------------------------------------------------------------
>
> Service org.bluez
> Interface org.bluez.HealthDevice
> Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX

This is not really a health device. As mentioned yesterday, we can have
multiple health service per remote device. So we should be using here
are org.bluez.HealthService for every SDP record for HDP inside the
remote device.

So potential object paths are .../hci0/dev_xxxxxxxx/{hdp0,hdp1,...} and
so on. This way we clearly map health service and not bother with remote
device details that might implement multiple functions.

> Methods:
>
> void Refresh()
>
> This method searches for HDP applications in the remote device
> and notifies them to the appropriate agents.

I might have called this Update(), but that is a minor detail.

> --------------------------------------------------------------------------------
>
> Service org.bluez
> Interface org.bluez.HealthDeviceApplication
> Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY
>

That is more like the org.bluez.HealthService as mentioned above. So
lets combine them. I don't see a need for splitting these.

> Methods:
>
> array GetProperties()
>
> Gets the information of the remote application published on its
> SDP record. The returned data format is as follows:
>
> {
> "end_points": [
> "mdepid": uint8,
> "role" : "source" or "sink" ,
> "specs" : [{
> "dtype" : uint16,
> "description" : string, (optional)
> }]
> ]
> }
>
> object Connect(path local_application_id)
>
> Connects the local application with the remote application.
>
> Only the bus client that created the local session will be able
> to create connections using it.
>
> If the Device is already connected with an other application an
> org.bluez.Error.AlreadyConnected error will be received.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.AlreadyConnected
> org.bluez.Error.HealthError
>
> void Disconnect()
>
> Disconnect from the remote application the state will also be
> deleted. And no future reconnections will be possible. For
> keeping the state the method Pause of the health link should be
> used.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HealthError

Do we need Connect() and Disconnect() here. Can we just not create these
connections in the background based of a reference counting via the
channels?

> boolean Echo(array{byte})
>
> Sends an echo petition to the remote intance. Returns True if
> response matches with the buffer sent. If some error is detected
> False value is returned and the associated MCL is closed.
>
> path OpenDataChannel(byte mdepid, string conf)
>
> Creates a new data channel with the indicated config to the
> remote MCAP Data End Point (MDEP).
> The configuration should indicate the channel quality of
> service using one of this values "reliable", "streaming", "any".
>
> Returns the data channel path.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HealthError
>
> void ReconnectDataChannel(path data_channel)
>
> Reconnects a previously created data channel indicated by its
> path.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HealthError
> org.bluez.Error.NotFound
>
> int GetDataChannelFileDescriptor(path data_channel)
>
> Gets a file descriptor where data can be read or written.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HealthError
>
> void DeleteDataChannel(path data_channel)
>
> Deletes a data channel so it will not be available to use.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HealthError
>
> void DeleteAllDataChannels()
>
> Deletes all data channels so they will not be available for
> future use. Typically this function is called when the
> connection with the remote device will be closed permanently.
>
> Possible errors: org.bluez.Error.HealthError

This actually means also Disconnect() to me. So clear the extra work of
connect and disconnect can be done in the background and invisible for
the user.

> dict GetDataChannelStatus()
>
> Return a dictionary with all the data channels that can be used
> to send data right now. The dictionary is formed like follows:
>
> {
> "reliable": [channel_path_r1, channel_path_r2, ...],
> "streaming" : [channel_path_s1, channel_path_s2, ...]
> }
>
> The fist reliable data channel will always be the first data
> channel in reliable array.
>
> HealthAgent hierarchy
> =====================
>
> (this object is implemented by the HDP user in order to receive notifications)
>
> Service unique name
> Interface org.bluez.HealthAgent
> Object path freely definable
>
> Methods:
>
> void DeviceApplicationDiscovered(object path)
>
> This method is called when a device containing an hdp
> application is connected. The object path is the application
> path. The method will be called one time for each
> application.

I think this should be ServiceDiscovered and map to a HealthService.

> void DeviceConnected(object path)
>
> This method is called whenever a new connection has been
> established over the control channel of the current HDP
> application. The object path paremeter contains the object path
> of the connected HealthDevice.

Don't see a useful need for this. I don't want to expose HealthDevice
details anyway.

> void DevicePaused(object path)
>
> This method is called when a MCL is closed. Future reconnections
> will be notified using the DeviceRestarted callback.
> All data channels associated to this device will be closed and
> a reconnection will be needed before using them again.
>
> void DeviceResumed(object path)
>
> This method is called whenever a MCL is reconnected. All data
> channels associated are still closed but they will be able to be
> reconnected skipping the configuration process.
>
> void DeviceDisconnected(object path)
>
> This method is called when a remote device is disconnected or
> removed from MCAP cache. Any future reconnections will fail.
> Also all data channels associated to this device will be closed.

Why bother with this. We can do this on channel level.

> void CreatedDataChannel(object path, path data_channel, string conf)
>
> This method is called when a new data channel is created.
>
> The path contains the object path of the HealthDeviceApplication
> where the new connection is created, the data_channel is the
> path for identify the data channel and conf is the quality of
> service of the data channel ("reliable" or "streaming").

DataChannelCreated please.

> void DataChannelReconnected(object path, path data_channel, string conf)
>
> This method is called when a closed data channel is reconnected
> by the remote device.
>
> Conf will be "reliable" or "streaming".
>
> TThe path contains the object path of the
> HealthDeviceApplication where the new connection is reconnected,
> the data_channel is the path for identify the data channel and
> conf is the quality of service of the data channel ("reliable"
> or "streaming").
>
> void DeletedDataChannel(object path, path data_channel)
>
> This method is called when a data channel is deleted.
>
> After this call the data channel path will not be valid and can
> be reused for future creation of data channels.

DataChannelRemoved. We always map create with remove.

> void DeletedAllDataChannels(object path)
>
> This method is called when all data channels are deleted.
>
> The path contains the object path of the HealthDeviceApplication
> where the data channels are deleted.

That is pointless. You will get separate callbacks for each channel
anyway.

And the agent is missing a Release method for unforseen terminations.
See other agents for that detail.

Regards

Marcel