Subject: HDP proposed API (ver 0.3)

This api is a clean up of the previous one the changes.

We've added a new object that uses device path to get the sessions
allocated on this device (as somebody recommended in other thread,
I think Luiz, Elvis or both, but I can't find the exact email). The discovery
of new remote session should be done using device drivers, which is
compliant with the BlueZ style.

Discussions still in progress:

- Fd-passing issue: As Elvis, Santiago and I discussed yesterday on
IRC we think that the best propose is as follows (please Elvis correct
me if I misunderstood something yesterday):
Reconnections should be implicit and the data channel should
be perceived by the application layer as connected all the time.
When the application tries to write in a closed data channel, HDP
will perform the data channel reconnection and if it fails, then the channel
will be present as closed.
The implementation for this this behaviour will use pipes. Each data
channel will use 2 pipes to do fd-passing to the application. The upper
layer will write in this pipes and HDP will redirect it through the l2cap socket,
in this operation, HDP can reconnect if th l2cap socket is closed.

- Sessions issues: We still think that session are necessary because they
are mentioned in the standard and in the whitepaper and we think that
bluez should follow the standards in order to pass PTS for allow Bluetooth SIG
certifications. Any comment in this respect are welcome to improve the API
usability and conformity with Bluez APIs.

- Paths issues: It will be great to find names and paths that are good for
everybody, comments and suggestion on this respect are also welcome.

I hope we can fix this API asap. All comments or ideas are welcome.

Regards.

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

BlueZ D-Bus HDP 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.Hdp
Object path [variable prefix]/{hci0,hci1,...}

Methods object CreateSession(object path, dict config)

Returns the object path for the new HDP session.
The path parameter is the path of the remote object
with the callbacks to notify events (see
org.bluez.HdpAgent at the end of this document)
This petition starts an mcap session and also register
in the SDP is needed
Dict is defined as bellow:
{ "data_spec" : The data_spec is the data exchange
specification (see section 5.2.10 of
the specification document)
possible values:
0x00 = reserved,
0x01 [IEEE 11073-20601],
0x02..0xff reserved,
(optional)
"end_points" : [{ (optional)
"mdepid" : uint8, (optional)
"role" : ("source" or "sink"), (mandatory)
"specs" :[{ (mandatory)
"data_type" : uint16, (mandatory)
"description" : string, (optional)
}]
}]
}

if "data_spec" is not set, no SDP record will be
registered, so all the other data in the dictionary
will be ignored

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

Possible errors: org.bluez.Error.InvalidArguments

void CloseSession(object path)

Closes the HDP session identified by the object path.
Also session will be closed if the process that started
it is removed from the D-Bus.

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

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

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

Methods array GetSessions()

Gets the information of the remote sessions present
in this device and published on its SDP record. The
returned data follows this format.

[{"session_id": "a session identification as string",
"data_spec" : session data spec,
"end_points":
["mdepid": uint8,
"role" : "source" or "sink" ,
"specs" : [{
"dtype" : uint16,
"description" : string, (optional)
}]
]
}]

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

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

object Connect(remote_session_id)

Connects with the remote session and returns its object
path.

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

void Disconnect(object device, boolean delete)

Disconnect from the remote device. If delete is true, any
status will also be deleted. Otherwise, the status will
be kept for allowing future reconnections.

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

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

Service org.bluez
Interface org.bluez.HdpRemoteSession
Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/rem_session_id

boolean Echo(array{byte})

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

uint16 OpenDataChannel(byte mdepid, byte config)

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.
Returns the data channel id.

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

array GetDcFd(uint16 mdlid)

Gets a file descriptor where data can be read or
written for receive or sent by the data channel.
Returns an array of file descriptors one for write
and other for read.

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

void DeleteDataChannel(uint16 mdlid)

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

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

void DeleteAllDataChannels()

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

Possible errors: org.bluez.Error.HdpError

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": [id1, ..., idz],
"best_effort" : [idx, ..., idy]
}

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

HDPAgent hierarchy
==================

(this object is implemented by the HDP client an receives notifications)

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

void DeviceConnected(object path)

This method is called whenever a new device connection
has been established over the control channel of the
current HDP session. The object path contains the object
path of the remote device.

void DeviceDisconnected(object path)

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

void CreatedDataChannel(object path, uint16 mdlid)

This method is called when a new data channel is created
The path contains the object path of the device whith
the new connection is created and the mdlid the data
channel identificator.

void DeletedDataChannel(object path, uint16 mdlid)

This method is called when a data channel is closed.
After this call the data channel will not be valid and
can be reused for future created data channels.


2010-05-14 12:20:19

by Elvis Pfutzenreuter

[permalink] [raw]
Subject: Re: HDP proposed API (ver 0.3)

> - Giving this data to HDP is not only for registering a SDP record but
> also for doing checks when a connection is received, so this data will be
> finally passed to HDP.
> - The HDP client doesn't know all the data that should be published in
> the SDP record, like PSM's where MCAP is waiting for connections or MCAP
> supported features (note that MCAP is not exported by D-BUS).

Also, MCAP uses dynamic PSMs, one more reason to encapsulate the SDP record generation/parsing. If the application had to do this, it would have to find two free PSMs (ugly).


Subject: Re: HDP proposed API (ver 0.3)

Hi all,

El Wednesday 12 May 2010 13:25:26 Jos? Antonio Santos Cadenas escribi?:
> > > HDPAgent hierarchy
> > > ==================
> > >
> > >
> > >
> > > (this object is implemented by the HDP client an receives
> > > notifications)
> > >
> > >
> > >
> > > Service unique name
> > > Interface org.bluez.HdpAgent
> > > Object path freely definable
> > >
> > >
> > > void DeviceConnected(object path)
> > >
> > > This method is called whenever a new device
> > >
> > > connection has been established over the control channel of the current
> > > HDP session. The object path contains the object path of the remote
> > > device.
> > >
> > >
> > > void DeviceDisconnected(object path)
> > >
> > > This method is called when a remote device is
> > > disconnected definitively. Any future
> > >
> > > reconnections will fail. Also all data channels associated to this
> > > device will be closed.
> > >
> > >
> > > void CreatedDataChannel(object path, uint16 mdlid)
> > >
> > > This method is called when a new data channel is
> > >
> > > created The path contains the object path of the device whith the new
> > > connection is created and the mdlid the data channel identificator.
> > >
> > >
> > > void DeletedDataChannel(object path, uint16 mdlid)
> > >
> > > This method is called when a data channel is
> > >
> > > closed. After this call the data channel will not be valid and can be
> > > reused for future created data channels.
> >
> >
> >
> > Question from a user's perspective: why define an agent? Why not
> > define the above as signal callbacks in the relevant object? (same as
> > most APIs in "bluez/docs").
>
> Because the this notifications are only relevant for the process that
> created the session and this process should be the unique that receives
> this events. If you define signals, everybody in the bus can be subscribed
> to them, this is a problem in two ways:
> - Noise in the bus
> - "Privacy" issue because just the owner of the session should be
> notified of the session events.
>
> >
> >
> > The only places I saw where agents are used are: BlueZ pairing (remote
> > device object doesn't necessarily exist yet, so no way to register for
> > its events, so an agent is required), and obexd (callback methods for
> > authroization of transactions return a significant value, i.e. not a
> > simple signal, so an agent is also required).
> >
> >
> >
> > But none of these conditions apply in the HDP agent above. So is there
> > another reason?
>
> I explained above.
>
> If we are wrong and signals can be cached only by one process it is OK for
> us to change this.
>
> >
> >
> > Also, why not add properties for
> > connected/disconnected/opened/closed/etc. states? (And then
> > "GetProperties()" method, and "PropertyChanged(name, value)" signal).
> > For example, see "bluez/docs/network-api.txt"...
>
> Because this notifications concern to objects that are being created and
> destroyed (in the case of devices) and created or closed data channels, so
> new data channels ids are created or destroyed when this method are
> called. I can't see how properties can help here. The channel may exist or
> not I think that properties are not a good option in this case.
>
> Regards.

Any comments about this issue. It will be great to receive a little bit more
of feedback in order to decide one of this two options.


Subject: Re: HDP proposed API (ver 0.3)

Hi Jo?o,

El Friday 14 May 2010 00:35:23 Jo?o Paulo Rechi Vita escribi?:
> Hello Jos?!
>
> Thank you very much for the explanation on the sessions abstraction.
> Now I understood what you're trying to expose and I think the whole
> confusion upraised from the nomenclature 'session', which is usually
> used for defining a well-known slice of time (with known beginning and
> end) in which some events are comprised. Wouldn't it be better to
> change this to something like "Instance", to keep consistency with
> MCAP spec?

We are doing the changes in MCAP and this API will be also changed. I'm happy
we are finally fixing a good API.

>
> For the sake of sanity, I'll keep using the Session nomenclature on
> comments bellow, we can discuss interface names on a further review
> round.

Me too until it is changed :)

>
> On Thu, May 13, 2010 at 05:02, Jos? Antonio Santos Cadenas
>
> <[email protected]> wrote:
> > Hi Jo?o,
> >
> > Thank you very much for you comments :)
> >
> > El Thursday 13 May 2010 00:03:51 Jo?o Paulo Rechi Vita escribi?:
> >> Hello Jose!
> >>
> >> On Wed, May 12, 2010 at 06:26, Jos? Antonio Santos Cadenas
> >>
> >> <[email protected]> wrote:
> >> > This api is a clean up of the previous one the changes.
> >> >
> >> > We've added a new object that uses device path to get the sessions
> >> > allocated on this device (as somebody recommended in other thread,
> >> > I think Luiz, Elvis or both, but I can't find the exact email). The
> >> > discovery of new remote session should be done using device drivers,
> >> > which is compliant with the BlueZ style.
> >> >
> >> > Discussions still in progress:
> >> >
> >> > - Fd-passing issue: As Elvis, Santiago and I discussed yesterday on
> >> > IRC we think that the best propose is as follows (please Elvis correct
> >> > me if I misunderstood something yesterday):
> >> > Reconnections should be implicit and the data channel should
> >> > be perceived by the application layer as connected all the time.
> >> > When the application tries to write in a closed data channel,
> >> > HDP will perform the data channel reconnection and if it fails, then
> >> > the channel will be present as closed.
> >> > The implementation for this this behaviour will use pipes. Each
> >> > data channel will use 2 pipes to do fd-passing to the application. The
> >> > upper layer will write in this pipes and HDP will redirect it through
> >> > the l2cap socket, in this operation, HDP can reconnect if th l2cap
> >> > socket is closed.
> >> >
> >> > - Sessions issues: We still think that session are necessary because
> >> > they are mentioned in the standard and in the whitepaper and we think
> >> > that bluez should follow the standards in order to pass PTS for allow
> >> > Bluetooth SIG certifications. Any comment in this respect are welcome
> >> > to improve the API usability and conformity with Bluez APIs.
> >> >
> >> > - Paths issues: It will be great to find names and paths that are good
> >> > for everybody, comments and suggestion on this respect are also
> >> > welcome.
> >> >
> >> > I hope we can fix this API asap. All comments or ideas are welcome.
> >>
> >> It would be much better if you could bring this API near to other
> >> BlueZ APIs. All comments I'll do right now is regarding this matter.
> >>
> >> > Regards.
> >> >
> >> > --------------------------------------------------
> >> >
> >> > BlueZ D-Bus HDP 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.Hdp
> >>
> >> If you look on other profile interfaces you'll see that we never use
> >> the profile acronym for interface names, but the content type (and
> >> role, where applicable). So this will be better as org.bluez.Health.
> >>
> >> Moreover, I see you're using the same interface name to describe two
> >> different interfaces. This is just wrong. An interface should be a
> >> description of an unique group of methods and signals signatures. You
> >> can refer to [0] for a description on interfaces.
> >>
> >> [0] http://dbus.freedesktop.org/doc/dbus-tutorial.html#interfaces
> >
> > Ok, regarding the above comments, this interface changes to:
> >
> > Interface org.bluez.HealthAdapter
> >
> >> > Object path [variable prefix]/{hci0,hci1,...}
> >> >
> >> > Methods object CreateSession(object path, dict config)
> >> >
> >> > Returns the object path for the new HDP
> >> > session. The path parameter is the path of the remote object with the
> >> > callbacks to notify events (see
> >> > org.bluez.HdpAgent at the end of this document)
> >> > This petition starts an mcap session and also
> >> > register in the SDP is needed
> >> > Dict is defined as bellow:
> >> > { "data_spec" : The data_spec is the data
> >> > exchange specification (see section 5.2.10 of the specification
> >> > document) possible values:
> >> > 0x00 = reserved,
> >> > 0x01 [IEEE
> >> > 11073-20601], 0x02..0xff reserved, (optional)
> >> > "end_points" : [{ (optional)
> >> > "mdepid" : uint8, (optional)
> >> > "role" : ("source" or "sink"),
> >> > (mandatory) "specs" :[{ (mandatory)
> >> > "data_type" : uint16,
> >> > (mandatory) "description" : string, (optional) }]
> >> > }]
> >> > }
> >>
> >> Couldn't this be moved as properties on the session object? So after
> >> creating a session you just go on it's object path and set the desired
> >> properties with SetProperty(). This will be much more aligned with
> >> other BlueZ APIs.
> >
> > We thought about doing something similar to this you propose, but we see
> > some promen, that makes the API more difficult to use:
> > - Session will need another method in order to start it once you
> > have configured it. With this method, configuration and session start
> > are done in just one method call. This implies that the other methods
> > (connect and disconnect to a remote session) could not be called until
> > the session is started, this quite strange.
> > - As you can see, the dictionary has only two members, "data_spec"
> > and "end_points". So, you will have to pass a dictionary to set
> > end_points too.
>
> By "starting the session" I guess you meant publishing the SDP record,
> right?

Start a "session" implies start a MCAP session, optionally you can register a
SDP record (mandatory if you are sink).

> Couldn't this be done using the AddRecord() method on the
> org.bluez.Service interface?

I think this is not a good option:
- Doing this you are rely on the client a possible mandatory (in case of
sinks) protocol requirement.
- Giving this data to HDP is not only for registering a SDP record but
also for doing checks when a connection is received, so this data will be
finally passed to HDP.
- The HDP client doesn't know all the data that should be published in
the SDP record, like PSM's where MCAP is waiting for connections or MCAP
supported features (note that MCAP is not exported by D-BUS).
- The SDP record shouldn't be created until the MCAP "session" is
started and waiting for connections.

> Then you could have a property on the
> session object path that says if it is published or not (calling the
> other methods could also trigger a "session start" or return with an
> error). Then this method would be used only for Agent registration,
> maybe then making RegisterAgent() a more suitable name.

Sorry, but I don't understand this part.

>
> >> > if "data_spec" is not set, no SDP record will
> >> > be registered, so all the other data in the dictionary will be
> >> > ignored
> >> >
> >> > Session will be closed by the call or
> >> > implicitly when the programs leaves the bus.
> >> >
> >> > Possible errors:
> >> > org.bluez.Error.InvalidArguments
> >> >
> >> > void CloseSession(object path)
> >> >
> >> > Closes the HDP session identified by the object
> >> > path. Also session will be closed if the process that started it is
> >> > removed from the D-Bus.
> >>
> >> s/D-Bus/bus. Also, would be good to keep the description consistent
> >> between methods. Previous description says "the programs leaves" and
> >> here "process is removed". IMHO "the process leaves the bus" will be
> >> the more accurate.
> >
> > Ok, I'll try to be more consistent in the next revision, using the text
> > that you suggested.
> >
> >> > Possible errors:
> >> > org.bluez.Error.InvalidArguments org.bluez.Error.NotFound
> >> >
> >> > ----------------------------------------------------------------------
> >> > --- -------
> >> >
> >> > Service org.bluez
> >> > Interface org.bluez.Hdp
> >
> > Chage this to:
> >
> > Interface org.bluez.HdpDevice
> >
> >> > Object path [variable
> >> > prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
> >> >
> >> > Methods array GetSessions()
> >>
> >> It would be better if this method return the session object path, then
> >> you can get this information with GetProperties() on the session
> >> object.
> >
> > Do you mean creating a new object that holds the remote sessions?
> > Right now the org.bluez.HdpSession Objects holds only local sessions.
> > Remote session will be a bit different. See below.
>
> I've actually meant to return a list of object paths for each
> RemoteSession object on the device. But thinking more on this,
> wouldn't this fit better on the Service interface, since it's a SDP
> related function? sdptool has a way to query records for a specific
> service on a device, but it does so accessing libbluetooth sdp.h
> directly. We would need to add a more generic method to query records
> of a device filtering by service, but then we could use this instead
> of defining a new interface only for that. Johan, Luiz, what do you
> think?

For me it's OK but I still see two advantages doing this as I propose:
- The HDP client should know how the SDP record is formed and also filter
the useful information for them.
- HDP needs the remote record too the PSM are variant and the standard
explicitly says in section 3.3 (and again in section 3.4 for data channels):
- Control channels PSM's shall be dynamic PSM's
- In order to avoid assumptions regarding the value of Control
Channel PSMs, PSM values shall be retrieved from the SDP record.
if you rely on HDP for getting the remote SDP record, it can cache it and
not increment the delay when a connection is requested.

>
> >> > Gets the information of the remote sessions
> >> > present in this device and published on its SDP record. The returned
> >> > data follows this format.
> >> >
> >> > [{"session_id": "a session identification as
> >> > string", "data_spec" : session data spec,
> >> > "end_points":
> >> > ["mdepid": uint8,
> >> > "role" : "source" or "sink" ,
> >> > "specs" : [{
> >> > "dtype" : uint16,
> >> > "description" : string,
> >> > (optional) }]
> >> > ]
> >> > }]
> >> >
> >> > ----------------------------------------------------------------------
> >> > --- -------
> >> >
> >> > Service org.bluez
> >> > Interface org.bluez.HdpSession
> >> > Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
> >>
> >> From the previous interface (the one that defines the GetSessions()
> >> method) it seems that sessions are tied to a specific device. If so,
> >> the session objects should be under the device object, not under the
> >> adapter object.
> >
> > See below the Session explanation.
>
> Right. But then, what if you move these two methods to the Remote
> Session object (obviously adapting the parameters to address the local
> session instead of the remote one)? Wouldn't they provide the same
> function? Then we won't need separate interfaces here.

"RemoteSession" (very bad name) refers to a connection between a remote and a
local "session", so the functionality is different. "RemoteSession" manages an
already opened connection and and "HdpDevice" just represents a remote device
(not connected) and provides a way to know the "sessions" on it.

>
> >> > object Connect(remote_session_id)
> >> >
> >> > Connects with the remote session and returns
> >> > its object path.
> >> >
> >> > Possible errors:
> >> > org.bluez.Error.InvalidArguments org.bluez.Error.HdpError
> >> >
> >> > void Disconnect(object device, boolean delete)
> >> >
> >> > Disconnect from the remote device. If delete is
> >> > true, any status will also be deleted. Otherwise, the status will be
> >> > kept for allowing future reconnections.
> >> >
> >> > Possible errors:
> >> > org.bluez.Error.InvalidArguments org.bluez.Error.NotFound
> >> > org.bluez.Error.HdpError
> >> >
> >> > ----------------------------------------------------------------------
> >> > --- -------
> >> >
> >> > Service org.bluez
> >> > Interface org.bluez.HdpRemoteSession
> >> > Object path [variable
> >> > prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/rem_session_id
> >>
> >> Could you please elaborate more on what does HdpSession and
> >> HdpRemoteSessions tries to abstract? It still not clear to me and
> >> depending on this we may find a better name for it.
> >
> > I think that the most estrange part of the protocol is this and I failed
> > with my explanations.
> >
> > HDP uses MCAP that uses what we called "sessions" in the MCAP standard
> > the called them instances (refer to section 2.1.7 of the MCAP
> > specification for more details).
> >
> > A MCAP session/instance is just a tuple of two PSM waiting for
> > connections one for control channels (mcl) and the other for data
> > channels (mdl) this session can connect to a remote MCAP session or be
> > connected by them, this connections is called mcap control link (mcl).
> > Just one connection between two instances can be established.
> >
> > As HDP uses MCAP, HDP inherits this "session" behaviour. Each HDP session
> > starts a MCAP session and also could create a SDP record (mandatory for
> > sinks) to anounce its attributes (mdeps, psms) to other devices.
> >
> > The thing that we called HdpSession is a MCAP session (PSM's waiting for
> > connections) created locally and, optionally a SDP record. HdpSession can
> > connect to other devices' sessions.
> >
> > The thing that we called HdpRemoteSession represents a connection between
> > a local session and a session in other device, in other words is a
> > extension of a MCAP mcl.
> >
> >> > boolean Echo(array{byte})
> >> >
> >> > Sends an echo petition to the remote session.
> >> > Return True if response matches with the buffer sent. If some error is
> >> > detected False value is returned and the associated MCL is closed.
> >> >
> >> > uint16 OpenDataChannel(byte mdepid, byte config)
> >> >
> >> > 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.
> >> > Returns the data channel id.
> >> >
> >> > Possible errors:
> >> > org.bluez.Error.InvalidArguments org.bluez.Error.HdpError
> >> >
> >> > array GetDcFd(uint16 mdlid)
> >> >
> >> > Gets a file descriptor where data can be read
> >> > or written for receive or sent by the data channel. Returns an array
> >> > of file descriptors one for write and other for read.
> >> >
> >> > Possible errors:
> >> > org.bluez.Error.InvalidArguments org.bluez.Error.NotFound
> >> > org.bluez.Error.HdpError
> >> >
> >> > void DeleteDataChannel(uint16 mdlid)
> >> >
> >> > Deletes a data channel so it will not be
> >> > available for use.
> >> >
> >> > Possible errors:
> >> > org.bluez.Error.InvalidArguments org.bluez.Error.NotFound
> >> > org.bluez.Error.HdpError
> >> >
> >> > void DeleteAllDataChannels()
> >> >
> >> > Deletes all data channels so it will not be
> >> > available for use. Typically this function is called when the
> >> > connection with the remote device will be closed permanently
> >> >
> >> > Possible errors: org.bluez.Error.HdpError
> >> >
> >> > 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": [id1, ..., idz],
> >> > "best_effort" : [idx, ..., idy]
> >> > }
> >> >
> >> > The fist reliable data channel will always be
> >> > the first data channel in reliable array.
> >> >
> >> > HDPAgent hierarchy
> >> > ==================
> >> >
> >> > (this object is implemented by the HDP client an receives
> >> > notifications)
> >> >
> >> > Service unique name
> >> > Interface org.bluez.HdpAgent
> >> > Object path freely definable
> >> >
> >> > void DeviceConnected(object path)
> >> >
> >> > This method is called whenever a new device
> >> > connection has been established over the control channel of the
> >> > current HDP session. The object path contains the object path of the
> >> > remote device.
> >> >
> >> > void DeviceDisconnected(object path)
> >> >
> >> > This method is called when a remote device is
> >> > disconnected definitively. Any future
> >> > reconnections will fail. Also all data channels associated to this
> >> > device will be closed.
> >> >
> >> > void CreatedDataChannel(object path, uint16 mdlid)
> >> >
> >> > This method is called when a new data channel
> >> > is created The path contains the object path of the device whith the
> >> > new connection is created and the mdlid the data channel
> >> > identificator.
> >> >
> >> > void DeletedDataChannel(object path, uint16 mdlid)
> >> >
> >> > This method is called when a data channel is
> >> > closed. After this call the data channel will not be valid and can be
> >> > reused for future created data channels.


2010-05-13 22:35:23

by João Paulo Rechi Vita

[permalink] [raw]
Subject: Re: HDP proposed API (ver 0.3)

Hello José!

Thank you very much for the explanation on the sessions abstraction.
Now I understood what you're trying to expose and I think the whole
confusion upraised from the nomenclature 'session', which is usually
used for defining a well-known slice of time (with known beginning and
end) in which some events are comprised. Wouldn't it be better to
change this to something like "Instance", to keep consistency with
MCAP spec?

For the sake of sanity, I'll keep using the Session nomenclature on
comments bellow, we can discuss interface names on a further review
round.

On Thu, May 13, 2010 at 05:02, José Antonio Santos Cadenas
<[email protected]> wrote:
> Hi João,
>
> Thank you very much for you comments :)
>
> El Thursday 13 May 2010 00:03:51 João Paulo Rechi Vita escribió:
>> Hello Jose!
>>
>> On Wed, May 12, 2010 at 06:26, José Antonio Santos Cadenas
>>
>> <[email protected]> wrote:
>> > This api is a clean up of the previous one the changes.
>> >
>> > We've added a new object that uses device path to get the sessions
>> > allocated on this device (as somebody recommended in other thread,
>> > I think Luiz, Elvis or both, but I can't find the exact email). The
>> > discovery of new remote session should be done using device drivers,
>> > which is compliant with the BlueZ style.
>> >
>> > Discussions still in progress:
>> >
>> > - Fd-passing issue: As Elvis, Santiago and I discussed yesterday on
>> > IRC we think that the best propose is as follows (please Elvis correct
>> > me if I misunderstood something yesterday):
>> >        Reconnections should be implicit and the data channel should
>> > be perceived by the application layer as connected all the time.
>> >        When the application tries to write in a closed data channel, HDP
>> > will perform the data channel reconnection and if it fails, then the
>> > channel will be present as closed.
>> >        The implementation for this this behaviour will use pipes. Each
>> > data channel will use 2 pipes to do fd-passing to the application. The
>> > upper layer will write in this pipes and HDP will redirect it through
>> > the l2cap socket, in this operation, HDP can reconnect if th l2cap
>> > socket is closed.
>> >
>> > - Sessions issues: We still think that session are necessary because they
>> > are mentioned in the standard and in the whitepaper and we think that
>> > bluez should follow the standards in order to pass PTS for allow
>> > Bluetooth SIG certifications. Any comment in this respect are welcome to
>> > improve the API usability and conformity with Bluez APIs.
>> >
>> > - Paths issues: It will be great to find names and paths that are good
>> > for everybody, comments and suggestion on this respect are also welcome.
>> >
>> > I hope we can fix this API asap. All comments or ideas are welcome.
>>
>> It would be much better if you could bring this API near to other
>> BlueZ APIs. All comments I'll do right now is regarding this matter.
>>
>> > Regards.
>> >
>> > --------------------------------------------------
>> >
>> > BlueZ D-Bus HDP 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.Hdp
>>
>> If you look on other profile interfaces you'll see that we never use
>> the profile acronym for interface names, but the content type (and
>> role, where applicable). So this will be better as org.bluez.Health.
>>
>> Moreover, I see you're using the same interface name to describe two
>> different interfaces. This is just wrong. An interface should be a
>> description of an unique group of methods and signals signatures. You
>> can refer to [0] for a description on interfaces.
>>
>> [0] http://dbus.freedesktop.org/doc/dbus-tutorial.html#interfaces
>
> Ok, regarding the above comments, this interface changes to:
>
> Interface       org.bluez.HealthAdapter
>
>>
>> > Object path     [variable prefix]/{hci0,hci1,...}
>> >
>> > Methods         object CreateSession(object path, dict config)
>> >
>> >                        Returns the object path for the new HDP session.
>> >                        The path parameter is the path of the remote
>> > object with the callbacks to notify events (see
>> >                        org.bluez.HdpAgent at the end of this document)
>> >                        This petition starts an mcap session and also
>> > register in the SDP is needed
>> >                        Dict is defined as bellow:
>> >                        { "data_spec" : The data_spec is the data exchange
>> >                                        specification (see section 5.2.10
>> > of the specification document) possible values:
>> >                                                0x00 = reserved,
>> >                                                0x01 [IEEE 11073-20601],
>> >                                                0x02..0xff reserved,
>> >                                        (optional)
>> >                          "end_points" : [{ (optional)
>> >                                "mdepid" : uint8, (optional)
>> >                                "role" : ("source" or "sink"), (mandatory)
>> >                                "specs" :[{ (mandatory)
>> >                                        "data_type" : uint16, (mandatory)
>> >                                        "description" : string, (optional)
>> >                                }]
>> >                          }]
>> >                        }
>>
>> Couldn't this be moved as properties on the session object? So after
>> creating a session you just go on it's object path and set the desired
>> properties with SetProperty(). This will be much more aligned with
>> other BlueZ APIs.
>
> We thought about doing something similar to this you propose, but we see some
> promen, that makes the API more difficult to use:
>        - Session will need another method in order to start it once you have
> configured it. With this method, configuration and session start are done in
> just one method call. This implies that the other methods (connect and
> disconnect to a remote session) could not be called until the session is
> started, this quite strange.
>        - As you can see, the dictionary has only two members, "data_spec" and
> "end_points". So, you will have to pass a dictionary to set end_points too.
>

By "starting the session" I guess you meant publishing the SDP record,
right? Couldn't this be done using the AddRecord() method on the
org.bluez.Service interface? Then you could have a property on the
session object path that says if it is published or not (calling the
other methods could also trigger a "session start" or return with an
error). Then this method would be used only for Agent registration,
maybe then making RegisterAgent() a more suitable name.

>>
>> >                        if "data_spec" is not set, no SDP record will be
>> >                        registered, so all the other data in the
>> > dictionary will be ignored
>> >
>> >                        Session will be closed by the call or implicitly
>> > when the programs leaves the bus.
>> >
>> >                        Possible errors: org.bluez.Error.InvalidArguments
>> >
>> >                void CloseSession(object path)
>> >
>> >                        Closes the HDP session identified by the object
>> > path. Also session will be closed if the process that started it is
>> > removed from the D-Bus.
>>
>> s/D-Bus/bus. Also, would be good to keep the description consistent
>> between methods. Previous description says "the programs leaves" and
>> here "process is removed". IMHO "the process leaves the bus" will be
>> the more accurate.
>
> Ok, I'll try to be more consistent in the next revision, using the text that
> you suggested.
>
>>
>> >                        Possible errors: org.bluez.Error.InvalidArguments
>> >                                         org.bluez.Error.NotFound
>> >
>> > -------------------------------------------------------------------------
>> > -------
>> >
>> > Service         org.bluez
>> > Interface       org.bluez.Hdp
>
> Chage this to:
>
> Interface org.bluez.HdpDevice
>
>> > Object path     [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
>> >
>> > Methods array GetSessions()
>>
>> It would be better if this method return the session object path, then
>> you can get this information with GetProperties() on the session
>> object.
>
> Do you mean creating a new object that holds the remote sessions?
> Right now the  org.bluez.HdpSession Objects holds only local sessions. Remote
> session will be a bit different. See below.
>

I've actually meant to return a list of object paths for each
RemoteSession object on the device. But thinking more on this,
wouldn't this fit better on the Service interface, since it's a SDP
related function? sdptool has a way to query records for a specific
service on a device, but it does so accessing libbluetooth sdp.h
directly. We would need to add a more generic method to query records
of a device filtering by service, but then we could use this instead
of defining a new interface only for that. Johan, Luiz, what do you
think?

>>
>> >                        Gets the information of the remote sessions
>> > present in this device and published on its SDP record. The returned
>> > data follows this format.
>> >
>> >                        [{"session_id": "a session identification as
>> > string", "data_spec" : session data spec,
>> >                         "end_points":
>> >                                 ["mdepid": uint8,
>> >                                  "role"  : "source" or "sink" ,
>> >                                  "specs" : [{
>> >                                          "dtype"       : uint16,
>> >                                          "description" : string,
>> > (optional) }]
>> >                                 ]
>> >                        }]
>> >
>> > -------------------------------------------------------------------------
>> > -------
>> >
>> > Service         org.bluez
>> > Interface       org.bluez.HdpSession
>> > Object path     [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
>>
>> From the previous interface (the one that defines the GetSessions()
>> method) it seems that sessions are tied to a specific device. If so,
>> the session objects should be under the device object, not under the
>> adapter object.
>
> See below the Session explanation.

Right. But then, what if you move these two methods to the Remote
Session object (obviously adapting the parameters to address the local
session instead of the remote one)? Wouldn't they provide the same
function? Then we won't need separate interfaces here.

>>
>> >                object Connect(remote_session_id)
>> >
>> >                        Connects with the remote session and returns its
>> > object path.
>> >
>> >                        Possible errors: org.bluez.Error.InvalidArguments
>> >                                         org.bluez.Error.HdpError
>> >
>> >                void Disconnect(object device, boolean delete)
>> >
>> >                        Disconnect from the remote device. If delete is
>> > true, any status will also be deleted. Otherwise, the status will be
>> > kept for allowing future reconnections.
>> >
>> >                        Possible errors: org.bluez.Error.InvalidArguments
>> >                                         org.bluez.Error.NotFound
>> >                                         org.bluez.Error.HdpError
>> >
>> > -------------------------------------------------------------------------
>> > -------
>> >
>> > Service         org.bluez
>> > Interface       org.bluez.HdpRemoteSession
>> > Object path     [variable
>> > prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/rem_session_id
>>
>> Could you please elaborate more on what does HdpSession and
>> HdpRemoteSessions tries to abstract? It still not clear to me and
>> depending on this we may find a better name for it.
>
> I think that the most estrange part of the protocol is this and I failed with
> my explanations.
>
> HDP uses MCAP that uses what we called "sessions" in the MCAP standard the
> called them instances (refer to section 2.1.7 of the MCAP specification for
> more details).
>
> A MCAP session/instance is just a tuple of two PSM waiting for connections one
> for control channels (mcl) and the other for data channels (mdl) this session
> can connect to a remote MCAP session or be connected by them, this connections
> is called mcap control link (mcl). Just one connection between two instances
> can be established.
>
> As HDP uses MCAP, HDP inherits this "session" behaviour. Each HDP session
> starts a MCAP session and also could create a SDP record (mandatory for sinks)
> to anounce its attributes (mdeps, psms) to other devices.
>
> The thing that we called HdpSession is a MCAP session (PSM's waiting for
> connections) created locally and, optionally a SDP record. HdpSession can
> connect to other devices' sessions.
>
> The thing that we called HdpRemoteSession represents a connection between a
> local session and a session in other device, in other words is a extension of
> a MCAP mcl.
>
>>
>> >                boolean Echo(array{byte})
>> >
>> >                        Sends an echo petition to the remote session.
>> > Return True if response matches with the buffer sent. If some error is
>> > detected False value is returned and the associated MCL is closed.
>> >
>> >                uint16 OpenDataChannel(byte mdepid, byte config)
>> >
>> >                        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.
>> >                        Returns the data channel id.
>> >
>> >                        Possible errors: org.bluez.Error.InvalidArguments
>> >                                         org.bluez.Error.HdpError
>> >
>> >                array GetDcFd(uint16 mdlid)
>> >
>> >                        Gets a file descriptor where data can be read or
>> >                        written for receive or sent by the data channel.
>> >                        Returns an array of file descriptors one for write
>> >                        and other for read.
>> >
>> >                        Possible errors: org.bluez.Error.InvalidArguments
>> >                                         org.bluez.Error.NotFound
>> >                                         org.bluez.Error.HdpError
>> >
>> >                void DeleteDataChannel(uint16 mdlid)
>> >
>> >                        Deletes a data channel so it will not be available
>> > for use.
>> >
>> >                        Possible errors: org.bluez.Error.InvalidArguments
>> >                                         org.bluez.Error.NotFound
>> >                                         org.bluez.Error.HdpError
>> >
>> >                void DeleteAllDataChannels()
>> >
>> >                        Deletes all data channels so it will not be
>> > available for use. Typically this function is called when the connection
>> > with the remote device will be closed permanently
>> >
>> >                        Possible errors: org.bluez.Error.HdpError
>> >
>> >                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": [id1, ..., idz],
>> >                                "best_effort" : [idx, ..., idy]
>> >                        }
>> >
>> >                        The fist reliable data channel will always be the
>> > first data channel in reliable array.
>> >
>> > HDPAgent hierarchy
>> > ==================
>> >
>> > (this object is implemented by the HDP client an receives notifications)
>> >
>> > Service         unique name
>> > Interface       org.bluez.HdpAgent
>> > Object path     freely definable
>> >
>> >                void DeviceConnected(object path)
>> >
>> >                        This method is called whenever a new device
>> > connection has been established over the control channel of the current
>> > HDP session. The object path contains the object path of the remote
>> > device.
>> >
>> >                void DeviceDisconnected(object path)
>> >
>> >                        This method is called when a remote device is
>> >                        disconnected definitively. Any future
>> > reconnections will fail. Also all data channels associated to this
>> > device will be closed.
>> >
>> >                void CreatedDataChannel(object path, uint16 mdlid)
>> >
>> >                        This method is called when a new data channel is
>> > created The path contains the object path of the device whith the new
>> > connection is created and the mdlid the data channel identificator.
>> >
>> >                void DeletedDataChannel(object path, uint16 mdlid)
>> >
>> >                        This method is called when a data channel is
>> > closed. After this call the data channel will not be valid and can be
>> > reused for future created data channels.
>
>



--
João Paulo Rechi Vita
http://jprvita.wordpress.com/

Subject: Re: HDP proposed API (ver 0.3)

Hi Jo?o,

Thank you very much for you comments :)

El Thursday 13 May 2010 00:03:51 Jo?o Paulo Rechi Vita escribi?:
> Hello Jose!
>
> On Wed, May 12, 2010 at 06:26, Jos? Antonio Santos Cadenas
>
> <[email protected]> wrote:
> > This api is a clean up of the previous one the changes.
> >
> > We've added a new object that uses device path to get the sessions
> > allocated on this device (as somebody recommended in other thread,
> > I think Luiz, Elvis or both, but I can't find the exact email). The
> > discovery of new remote session should be done using device drivers,
> > which is compliant with the BlueZ style.
> >
> > Discussions still in progress:
> >
> > - Fd-passing issue: As Elvis, Santiago and I discussed yesterday on
> > IRC we think that the best propose is as follows (please Elvis correct
> > me if I misunderstood something yesterday):
> > Reconnections should be implicit and the data channel should
> > be perceived by the application layer as connected all the time.
> > When the application tries to write in a closed data channel, HDP
> > will perform the data channel reconnection and if it fails, then the
> > channel will be present as closed.
> > The implementation for this this behaviour will use pipes. Each
> > data channel will use 2 pipes to do fd-passing to the application. The
> > upper layer will write in this pipes and HDP will redirect it through
> > the l2cap socket, in this operation, HDP can reconnect if th l2cap
> > socket is closed.
> >
> > - Sessions issues: We still think that session are necessary because they
> > are mentioned in the standard and in the whitepaper and we think that
> > bluez should follow the standards in order to pass PTS for allow
> > Bluetooth SIG certifications. Any comment in this respect are welcome to
> > improve the API usability and conformity with Bluez APIs.
> >
> > - Paths issues: It will be great to find names and paths that are good
> > for everybody, comments and suggestion on this respect are also welcome.
> >
> > I hope we can fix this API asap. All comments or ideas are welcome.
>
> It would be much better if you could bring this API near to other
> BlueZ APIs. All comments I'll do right now is regarding this matter.
>
> > Regards.
> >
> > --------------------------------------------------
> >
> > BlueZ D-Bus HDP 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.Hdp
>
> If you look on other profile interfaces you'll see that we never use
> the profile acronym for interface names, but the content type (and
> role, where applicable). So this will be better as org.bluez.Health.
>
> Moreover, I see you're using the same interface name to describe two
> different interfaces. This is just wrong. An interface should be a
> description of an unique group of methods and signals signatures. You
> can refer to [0] for a description on interfaces.
>
> [0] http://dbus.freedesktop.org/doc/dbus-tutorial.html#interfaces

Ok, regarding the above comments, this interface changes to:

Interface org.bluez.HealthAdapter

>
> > Object path [variable prefix]/{hci0,hci1,...}
> >
> > Methods object CreateSession(object path, dict config)
> >
> > Returns the object path for the new HDP session.
> > The path parameter is the path of the remote
> > object with the callbacks to notify events (see
> > org.bluez.HdpAgent at the end of this document)
> > This petition starts an mcap session and also
> > register in the SDP is needed
> > Dict is defined as bellow:
> > { "data_spec" : The data_spec is the data exchange
> > specification (see section 5.2.10
> > of the specification document) possible values:
> > 0x00 = reserved,
> > 0x01 [IEEE 11073-20601],
> > 0x02..0xff reserved,
> > (optional)
> > "end_points" : [{ (optional)
> > "mdepid" : uint8, (optional)
> > "role" : ("source" or "sink"), (mandatory)
> > "specs" :[{ (mandatory)
> > "data_type" : uint16, (mandatory)
> > "description" : string, (optional)
> > }]
> > }]
> > }
>
> Couldn't this be moved as properties on the session object? So after
> creating a session you just go on it's object path and set the desired
> properties with SetProperty(). This will be much more aligned with
> other BlueZ APIs.

We thought about doing something similar to this you propose, but we see some
promen, that makes the API more difficult to use:
- Session will need another method in order to start it once you have
configured it. With this method, configuration and session start are done in
just one method call. This implies that the other methods (connect and
disconnect to a remote session) could not be called until the session is
started, this quite strange.
- As you can see, the dictionary has only two members, "data_spec" and
"end_points". So, you will have to pass a dictionary to set end_points too.

>
> > if "data_spec" is not set, no SDP record will be
> > registered, so all the other data in the
> > dictionary will be ignored
> >
> > Session will be closed by the call or implicitly
> > when the programs leaves the bus.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > void CloseSession(object path)
> >
> > Closes the HDP session identified by the object
> > path. Also session will be closed if the process that started it is
> > removed from the D-Bus.
>
> s/D-Bus/bus. Also, would be good to keep the description consistent
> between methods. Previous description says "the programs leaves" and
> here "process is removed". IMHO "the process leaves the bus" will be
> the more accurate.

Ok, I'll try to be more consistent in the next revision, using the text that
you suggested.

>
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> >
> > -------------------------------------------------------------------------
> > -------
> >
> > Service org.bluez
> > Interface org.bluez.Hdp

Chage this to:

Interface org.bluez.HdpDevice

> > Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
> >
> > Methods array GetSessions()
>
> It would be better if this method return the session object path, then
> you can get this information with GetProperties() on the session
> object.

Do you mean creating a new object that holds the remote sessions?
Right now the org.bluez.HdpSession Objects holds only local sessions. Remote
session will be a bit different. See below.

>
> > Gets the information of the remote sessions
> > present in this device and published on its SDP record. The returned
> > data follows this format.
> >
> > [{"session_id": "a session identification as
> > string", "data_spec" : session data spec,
> > "end_points":
> > ["mdepid": uint8,
> > "role" : "source" or "sink" ,
> > "specs" : [{
> > "dtype" : uint16,
> > "description" : string,
> > (optional) }]
> > ]
> > }]
> >
> > -------------------------------------------------------------------------
> > -------
> >
> > Service org.bluez
> > Interface org.bluez.HdpSession
> > Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
>
> From the previous interface (the one that defines the GetSessions()
> method) it seems that sessions are tied to a specific device. If so,
> the session objects should be under the device object, not under the
> adapter object.

See below the Session explanation.
>
> > object Connect(remote_session_id)
> >
> > Connects with the remote session and returns its
> > object path.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.HdpError
> >
> > void Disconnect(object device, boolean delete)
> >
> > Disconnect from the remote device. If delete is
> > true, any status will also be deleted. Otherwise, the status will be
> > kept for allowing future reconnections.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HdpError
> >
> > -------------------------------------------------------------------------
> > -------
> >
> > Service org.bluez
> > Interface org.bluez.HdpRemoteSession
> > Object path [variable
> > prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/rem_session_id
>
> Could you please elaborate more on what does HdpSession and
> HdpRemoteSessions tries to abstract? It still not clear to me and
> depending on this we may find a better name for it.

I think that the most estrange part of the protocol is this and I failed with
my explanations.

HDP uses MCAP that uses what we called "sessions" in the MCAP standard the
called them instances (refer to section 2.1.7 of the MCAP specification for
more details).

A MCAP session/instance is just a tuple of two PSM waiting for connections one
for control channels (mcl) and the other for data channels (mdl) this session
can connect to a remote MCAP session or be connected by them, this connections
is called mcap control link (mcl). Just one connection between two instances
can be established.

As HDP uses MCAP, HDP inherits this "session" behaviour. Each HDP session
starts a MCAP session and also could create a SDP record (mandatory for sinks)
to anounce its attributes (mdeps, psms) to other devices.

The thing that we called HdpSession is a MCAP session (PSM's waiting for
connections) created locally and, optionally a SDP record. HdpSession can
connect to other devices' sessions.

The thing that we called HdpRemoteSession represents a connection between a
local session and a session in other device, in other words is a extension of
a MCAP mcl.

>
> > boolean Echo(array{byte})
> >
> > Sends an echo petition to the remote session.
> > Return True if response matches with the buffer sent. If some error is
> > detected False value is returned and the associated MCL is closed.
> >
> > uint16 OpenDataChannel(byte mdepid, byte config)
> >
> > 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.
> > Returns the data channel id.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.HdpError
> >
> > array GetDcFd(uint16 mdlid)
> >
> > Gets a file descriptor where data can be read or
> > written for receive or sent by the data channel.
> > Returns an array of file descriptors one for write
> > and other for read.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HdpError
> >
> > void DeleteDataChannel(uint16 mdlid)
> >
> > Deletes a data channel so it will not be available
> > for use.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HdpError
> >
> > void DeleteAllDataChannels()
> >
> > Deletes all data channels so it will not be
> > available for use. Typically this function is called when the connection
> > with the remote device will be closed permanently
> >
> > Possible errors: org.bluez.Error.HdpError
> >
> > 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": [id1, ..., idz],
> > "best_effort" : [idx, ..., idy]
> > }
> >
> > The fist reliable data channel will always be the
> > first data channel in reliable array.
> >
> > HDPAgent hierarchy
> > ==================
> >
> > (this object is implemented by the HDP client an receives notifications)
> >
> > Service unique name
> > Interface org.bluez.HdpAgent
> > Object path freely definable
> >
> > void DeviceConnected(object path)
> >
> > This method is called whenever a new device
> > connection has been established over the control channel of the current
> > HDP session. The object path contains the object path of the remote
> > device.
> >
> > void DeviceDisconnected(object path)
> >
> > This method is called when a remote device is
> > disconnected definitively. Any future
> > reconnections will fail. Also all data channels associated to this
> > device will be closed.
> >
> > void CreatedDataChannel(object path, uint16 mdlid)
> >
> > This method is called when a new data channel is
> > created The path contains the object path of the device whith the new
> > connection is created and the mdlid the data channel identificator.
> >
> > void DeletedDataChannel(object path, uint16 mdlid)
> >
> > This method is called when a data channel is
> > closed. After this call the data channel will not be valid and can be
> > reused for future created data channels.


2010-05-12 22:03:51

by João Paulo Rechi Vita

[permalink] [raw]
Subject: Re: HDP proposed API (ver 0.3)

SGVsbG8gSm9zZSEKCk9uIFdlZCwgTWF5IDEyLCAyMDEwIGF0IDA2OjI2LCBKb3PDqSBBbnRvbmlv
IFNhbnRvcyBDYWRlbmFzCjxqY2FkZW5AbGlicmVzb2Z0LmVzPiB3cm90ZToKPiBUaGlzIGFwaSBp
cyBhIGNsZWFuIHVwIG9mIHRoZSBwcmV2aW91cyBvbmUgdGhlIGNoYW5nZXMuCj4KPiBXZSd2ZSBh
ZGRlZCBhIG5ldyBvYmplY3QgdGhhdCB1c2VzIGRldmljZSBwYXRoIHRvIGdldCB0aGUgc2Vzc2lv
bnMKPiBhbGxvY2F0ZWQgb24gdGhpcyBkZXZpY2UgKGFzIHNvbWVib2R5IHJlY29tbWVuZGVkIGlu
IG90aGVyIHRocmVhZCwKPiBJIHRoaW5rIEx1aXosIEVsdmlzIG9yIGJvdGgsIGJ1dCBJIGNhbid0
IGZpbmQgdGhlIGV4YWN0IGVtYWlsKS4gVGhlIGRpc2NvdmVyeQo+IG9mIG5ldyByZW1vdGUgc2Vz
c2lvbiBzaG91bGQgYmUgZG9uZSB1c2luZyBkZXZpY2UgZHJpdmVycywgd2hpY2ggaXMKPiBjb21w
bGlhbnQgd2l0aCB0aGUgQmx1ZVogc3R5bGUuCj4KPiBEaXNjdXNzaW9ucyBzdGlsbCBpbiBwcm9n
cmVzczoKPgo+IC0gRmQtcGFzc2luZyBpc3N1ZTogQXMgRWx2aXMsIFNhbnRpYWdvIGFuZCBJIGRp
c2N1c3NlZCB5ZXN0ZXJkYXkgb24KPiBJUkMgd2UgdGhpbmsgdGhhdCB0aGUgYmVzdCBwcm9wb3Nl
IGlzIGFzIGZvbGxvd3MgKHBsZWFzZSBFbHZpcyBjb3JyZWN0Cj4gbWUgaWYgSSBtaXN1bmRlcnN0
b29kIHNvbWV0aGluZyB5ZXN0ZXJkYXkpOgo+IMKgIMKgIMKgIMKgUmVjb25uZWN0aW9ucyBzaG91
bGQgYmUgaW1wbGljaXQgYW5kIHRoZSBkYXRhIGNoYW5uZWwgc2hvdWxkCj4gYmUgcGVyY2VpdmVk
IGJ5IHRoZSBhcHBsaWNhdGlvbiBsYXllciBhcyBjb25uZWN0ZWQgYWxsIHRoZSB0aW1lLgo+IMKg
IMKgIMKgIMKgV2hlbiB0aGUgYXBwbGljYXRpb24gdHJpZXMgdG8gd3JpdGUgaW4gYSBjbG9zZWQg
ZGF0YSBjaGFubmVsLCBIRFAKPiB3aWxsIHBlcmZvcm0gdGhlIGRhdGEgY2hhbm5lbCByZWNvbm5l
Y3Rpb24gYW5kIGlmIGl0IGZhaWxzLCB0aGVuIHRoZSBjaGFubmVsCj4gd2lsbCBiZSBwcmVzZW50
IGFzIGNsb3NlZC4KPiDCoCDCoCDCoCDCoFRoZSBpbXBsZW1lbnRhdGlvbiBmb3IgdGhpcyB0aGlz
IGJlaGF2aW91ciB3aWxsIHVzZSBwaXBlcy4gRWFjaCBkYXRhCj4gY2hhbm5lbCB3aWxsIHVzZSAy
IHBpcGVzIHRvIGRvIGZkLXBhc3NpbmcgdG8gdGhlIGFwcGxpY2F0aW9uLiBUaGUgdXBwZXIKPiBs
YXllciB3aWxsIHdyaXRlIGluIHRoaXMgcGlwZXMgYW5kIEhEUCB3aWxsIHJlZGlyZWN0IGl0IHRo
cm91Z2ggdGhlIGwyY2FwIHNvY2tldCwKPiBpbiB0aGlzIG9wZXJhdGlvbiwgSERQIGNhbiByZWNv
bm5lY3QgaWYgdGggbDJjYXAgc29ja2V0IGlzIGNsb3NlZC4KPgo+IC0gU2Vzc2lvbnMgaXNzdWVz
OiBXZSBzdGlsbCB0aGluayB0aGF0IHNlc3Npb24gYXJlIG5lY2Vzc2FyeSBiZWNhdXNlIHRoZXkK
PiBhcmUgbWVudGlvbmVkIGluIHRoZSBzdGFuZGFyZCBhbmQgaW4gdGhlIHdoaXRlcGFwZXIgYW5k
IHdlIHRoaW5rIHRoYXQKPiBibHVleiBzaG91bGQgZm9sbG93IHRoZSBzdGFuZGFyZHMgaW4gb3Jk
ZXIgdG8gcGFzcyBQVFMgZm9yIGFsbG93IEJsdWV0b290aCBTSUcKPiBjZXJ0aWZpY2F0aW9ucy4g
QW55IGNvbW1lbnQgaW4gdGhpcyByZXNwZWN0IGFyZSB3ZWxjb21lIHRvIGltcHJvdmUgdGhlIEFQ
SQo+IHVzYWJpbGl0eSBhbmQgY29uZm9ybWl0eSB3aXRoIEJsdWV6IEFQSXMuCj4KPiAtIFBhdGhz
IGlzc3VlczogSXQgd2lsbCBiZSBncmVhdCB0byBmaW5kIG5hbWVzIGFuZCBwYXRocyB0aGF0IGFy
ZSBnb29kIGZvcgo+IGV2ZXJ5Ym9keSwgY29tbWVudHMgYW5kIHN1Z2dlc3Rpb24gb24gdGhpcyBy
ZXNwZWN0IGFyZSBhbHNvIHdlbGNvbWUuCj4KPiBJIGhvcGUgd2UgY2FuIGZpeCB0aGlzIEFQSSBh
c2FwLiBBbGwgY29tbWVudHMgb3IgaWRlYXMgYXJlIHdlbGNvbWUuCj4KCkl0IHdvdWxkIGJlIG11
Y2ggYmV0dGVyIGlmIHlvdSBjb3VsZCBicmluZyB0aGlzIEFQSSBuZWFyIHRvIG90aGVyCkJsdWVa
IEFQSXMuIEFsbCBjb21tZW50cyBJJ2xsIGRvIHJpZ2h0IG5vdyBpcyByZWdhcmRpbmcgdGhpcyBt
YXR0ZXIuCgo+IFJlZ2FyZHMuCj4KPiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLQo+Cj4gQmx1ZVogRC1CdXMgSERQIEFQSSBkZXNjcmlwdGlvbgo+ICoq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCj4KPiDCoCDCoCDCoCDCoFNhbnRpYWdv
IENhcm90LU5lbWVzaW8gPHNhbmNhbmVAZ21haWwuY29tPgo+IMKgIMKgIMKgIMKgSm9zw6kgQW50
b25pbyBTYW50b3MtQ2FkZW5hcyA8c2FudG9zY2FkZW5hc0BnbWFpbC5jb20+Cj4gwqAgwqAgwqAg
wqBFbHZpcyBQZsO8dHplbnJldXRlciA8ZXB4QHNpZ25vdmUuY29tPgo+Cj4gSGVhbHRoIERldmlj
ZSBQcm9maWxlIGhpZXJhcmNoeQo+ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KPgo+
IFNlcnZpY2UgwqAgwqAgwqAgwqAgb3JnLmJsdWV6Cj4gSW50ZXJmYWNlIMKgIMKgIMKgIG9yZy5i
bHVlei5IZHAKCklmIHlvdSBsb29rIG9uIG90aGVyIHByb2ZpbGUgaW50ZXJmYWNlcyB5b3UnbGwg
c2VlIHRoYXQgd2UgbmV2ZXIgdXNlCnRoZSBwcm9maWxlIGFjcm9ueW0gZm9yIGludGVyZmFjZSBu
YW1lcywgYnV0IHRoZSBjb250ZW50IHR5cGUgKGFuZApyb2xlLCB3aGVyZSBhcHBsaWNhYmxlKS4g
U28gdGhpcyB3aWxsIGJlIGJldHRlciBhcyBvcmcuYmx1ZXouSGVhbHRoLgoKTW9yZW92ZXIsIEkg
c2VlIHlvdSdyZSB1c2luZyB0aGUgc2FtZSBpbnRlcmZhY2UgbmFtZSB0byBkZXNjcmliZSB0d28K
ZGlmZmVyZW50IGludGVyZmFjZXMuIFRoaXMgaXMganVzdCB3cm9uZy4gQW4gaW50ZXJmYWNlIHNo
b3VsZCBiZSBhCmRlc2NyaXB0aW9uIG9mIGFuIHVuaXF1ZSBncm91cCBvZiBtZXRob2RzIGFuZCBz
aWduYWxzIHNpZ25hdHVyZXMuIFlvdQpjYW4gcmVmZXIgdG8gWzBdIGZvciBhIGRlc2NyaXB0aW9u
IG9uIGludGVyZmFjZXMuCgpbMF0gaHR0cDovL2RidXMuZnJlZWRlc2t0b3Aub3JnL2RvYy9kYnVz
LXR1dG9yaWFsLmh0bWwjaW50ZXJmYWNlcwoKPiBPYmplY3QgcGF0aCDCoCDCoCBbdmFyaWFibGUg
cHJlZml4XS97aGNpMCxoY2kxLC4uLn0KPgo+IE1ldGhvZHMgwqAgwqAgwqAgwqAgb2JqZWN0IENy
ZWF0ZVNlc3Npb24ob2JqZWN0IHBhdGgsIGRpY3QgY29uZmlnKQo+Cj4gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBSZXR1cm5zIHRoZSBvYmplY3QgcGF0aCBmb3IgdGhlIG5ldyBI
RFAgc2Vzc2lvbi4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFRoZSBwYXRo
IHBhcmFtZXRlciBpcyB0aGUgcGF0aCBvZiB0aGUgcmVtb3RlIG9iamVjdAo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgd2l0aCB0aGUgY2FsbGJhY2tzIHRvIG5vdGlmeSBldmVu
dHMgKHNlZQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgb3JnLmJsdWV6Lkhk
cEFnZW50IGF0IHRoZSBlbmQgb2YgdGhpcyBkb2N1bWVudCkKPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoFRoaXMgcGV0aXRpb24gc3RhcnRzIGFuIG1jYXAgc2Vzc2lvbiBhbmQg
YWxzbyByZWdpc3Rlcgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaW4gdGhl
IFNEUCBpcyBuZWVkZWQKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoERpY3Qg
aXMgZGVmaW5lZCBhcyBiZWxsb3c6Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqB7ICJkYXRhX3NwZWMiIDogVGhlIGRhdGFfc3BlYyBpcyB0aGUgZGF0YSBleGNoYW5nZQo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
c3BlY2lmaWNhdGlvbiAoc2VlIHNlY3Rpb24gNS4yLjEwIG9mCj4gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0aGUgc3BlY2lmaWNhdGlv
biBkb2N1bWVudCkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoHBvc3NpYmxlIHZhbHVlczoKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoDB4MDAgPSBy
ZXNlcnZlZCwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoDB4MDEgW0lFRUUgMTEwNzMtMjA2MDFdLAo+IMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgMHgwMi4uMHhmZiByZXNlcnZlZCwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChvcHRpb25hbCkKPiDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCJlbmRfcG9pbnRzIiA6IFt7IChvcHRpb25hbCkK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCJtZGVwaWQi
IDogdWludDgsIChvcHRpb25hbCkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCJyb2xlIiA6ICgic291cmNlIiBvciAic2luayIpLCAobWFuZGF0b3J5KQo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgInNwZWNzIiA6
W3sgKG1hbmRhdG9yeSkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCJkYXRhX3R5cGUiIDogdWludDE2LCAobWFuZGF0b3J5KQo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
ImRlc2NyaXB0aW9uIiA6IHN0cmluZywgKG9wdGlvbmFsKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfV0KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoH1dCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB9Cj4K
CkNvdWxkbid0IHRoaXMgYmUgbW92ZWQgYXMgcHJvcGVydGllcyBvbiB0aGUgc2Vzc2lvbiBvYmpl
Y3Q/IFNvIGFmdGVyCmNyZWF0aW5nIGEgc2Vzc2lvbiB5b3UganVzdCBnbyBvbiBpdCdzIG9iamVj
dCBwYXRoIGFuZCBzZXQgdGhlIGRlc2lyZWQKcHJvcGVydGllcyB3aXRoIFNldFByb3BlcnR5KCku
IFRoaXMgd2lsbCBiZSBtdWNoIG1vcmUgYWxpZ25lZCB3aXRoCm90aGVyIEJsdWVaIEFQSXMuCgo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgImRhdGFfc3BlYyIgaXMgbm90
IHNldCwgbm8gU0RQIHJlY29yZCB3aWxsIGJlCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqByZWdpc3RlcmVkLCBzbyBhbGwgdGhlIG90aGVyIGRhdGEgaW4gdGhlIGRpY3Rpb25h
cnkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHdpbGwgYmUgaWdub3JlZAo+
Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBTZXNzaW9uIHdpbGwgYmUgY2xv
c2VkIGJ5IHRoZSBjYWxsIG9yIGltcGxpY2l0bHkgd2hlbgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgdGhlIHByb2dyYW1zIGxlYXZlcyB0aGUgYnVzLgo+Cj4gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBQb3NzaWJsZSBlcnJvcnM6IG9yZy5ibHVlei5FcnJv
ci5JbnZhbGlkQXJndW1lbnRzCj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHZvaWQgQ2xvc2VT
ZXNzaW9uKG9iamVjdCBwYXRoKQo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqBDbG9zZXMgdGhlIEhEUCBzZXNzaW9uIGlkZW50aWZpZWQgYnkgdGhlIG9iamVjdCBwYXRoLgo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgQWxzbyBzZXNzaW9uIHdpbGwgYmUg
Y2xvc2VkIGlmIHRoZSBwcm9jZXNzIHRoYXQgc3RhcnRlZAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgaXQgaXMgcmVtb3ZlZCBmcm9tIHRoZSBELUJ1cy4KCnMvRC1CdXMvYnVz
LiBBbHNvLCB3b3VsZCBiZSBnb29kIHRvIGtlZXAgdGhlIGRlc2NyaXB0aW9uIGNvbnNpc3RlbnQK
YmV0d2VlbiBtZXRob2RzLiBQcmV2aW91cyBkZXNjcmlwdGlvbiBzYXlzICJ0aGUgcHJvZ3JhbXMg
bGVhdmVzIiBhbmQKaGVyZSAicHJvY2VzcyBpcyByZW1vdmVkIi4gSU1ITyAidGhlIHByb2Nlc3Mg
bGVhdmVzIHRoZSBidXMiIHdpbGwgYmUKdGhlIG1vcmUgYWNjdXJhdGUuCgo+Cj4gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBQb3NzaWJsZSBlcnJvcnM6IG9yZy5ibHVlei5FcnJv
ci5JbnZhbGlkQXJndW1lbnRzCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgb3JnLmJsdWV6LkVycm9yLk5vdEZvdW5kCj4KPiAtLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLQo+Cj4gU2VydmljZSDCoCDCoCDCoCDCoCBvcmcuYmx1ZXoKPiBJ
bnRlcmZhY2UgwqAgwqAgwqAgb3JnLmJsdWV6LkhkcAo+IE9iamVjdCBwYXRoIMKgIMKgIFt2YXJp
YWJsZSBwcmVmaXhdL3toY2kwLGhjaTEsLi4ufS9kZXZfWFhfWFhfWFhfWFhfWFhfWFgKPgo+IE1l
dGhvZHMgYXJyYXkgR2V0U2Vzc2lvbnMoKQoKSXQgd291bGQgYmUgYmV0dGVyIGlmIHRoaXMgbWV0
aG9kIHJldHVybiB0aGUgc2Vzc2lvbiBvYmplY3QgcGF0aCwgdGhlbgp5b3UgY2FuIGdldCB0aGlz
IGluZm9ybWF0aW9uIHdpdGggR2V0UHJvcGVydGllcygpIG9uIHRoZSBzZXNzaW9uCm9iamVjdC4K
Cj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoEdldHMgdGhlIGluZm9ybWF0
aW9uIG9mIHRoZSByZW1vdGUgc2Vzc2lvbnMgcHJlc2VudAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgaW4gdGhpcyBkZXZpY2UgYW5kIHB1Ymxpc2hlZCBvbiBpdHMgU0RQIHJl
Y29yZC4gVGhlCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm5lZCBk
YXRhIGZvbGxvd3MgdGhpcyBmb3JtYXQuCj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoFt7InNlc3Npb25faWQiOiAiYSBzZXNzaW9uIGlkZW50aWZpY2F0aW9uIGFzIHN0cmlu
ZyIsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgImRhdGFfc3BlYyIgOiBz
ZXNzaW9uIGRhdGEgc3BlYywKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAi
ZW5kX3BvaW50cyI6Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgWyJtZGVwaWQiOiB1aW50OCwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCJyb2xlIiDCoDogInNvdXJjZSIgb3IgInNpbmsiICwKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCJzcGVjcyIgOiBb
ewo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgImR0eXBlIiDCoCDCoCDCoCA6IHVpbnQxNiwKPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCJkZXNjcmlwdGlvbiIg
OiBzdHJpbmcsIChvcHRpb25hbCkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoH1dCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgXQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgfV0KPgo+
IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4KPiBTZXJ2aWNlIMKgIMKgIMKgIMKgIG9yZy5ibHVl
ego+IEludGVyZmFjZSDCoCDCoCDCoCBvcmcuYmx1ZXouSGRwU2Vzc2lvbgo+IE9iamVjdCBwYXRo
IMKgIMKgIFt2YXJpYWJsZSBwcmVmaXhdL3toY2kwLGhjaTEsLi4ufS97aGRwMCxoZHAxLC4uLn0K
CkZyb20gdGhlIHByZXZpb3VzIGludGVyZmFjZSAodGhlIG9uZSB0aGF0IGRlZmluZXMgdGhlIEdl
dFNlc3Npb25zKCkKbWV0aG9kKSBpdCBzZWVtcyB0aGF0IHNlc3Npb25zIGFyZSB0aWVkIHRvIGEg
c3BlY2lmaWMgZGV2aWNlLiBJZiBzbywKdGhlIHNlc3Npb24gb2JqZWN0cyBzaG91bGQgYmUgdW5k
ZXIgdGhlIGRldmljZSBvYmplY3QsIG5vdCB1bmRlciB0aGUKYWRhcHRlciBvYmplY3QuCgo+Cj4g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBvYmplY3QgQ29ubmVjdChyZW1vdGVfc2Vzc2lvbl9pZCkK
Pgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgQ29ubmVjdHMgd2l0aCB0aGUg
cmVtb3RlIHNlc3Npb24gYW5kIHJldHVybnMgaXRzIG9iamVjdAo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgcGF0aC4KPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgUG9zc2libGUgZXJyb3JzOiBvcmcuYmx1ZXouRXJyb3IuSW52YWxpZEFyZ3VtZW50cwo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIG9yZy5ibHVlei5FcnJvci5IZHBFcnJvcgo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB2
b2lkIERpc2Nvbm5lY3Qob2JqZWN0IGRldmljZSwgYm9vbGVhbiBkZWxldGUpCj4KPiDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoERpc2Nvbm5lY3QgZnJvbSB0aGUgcmVtb3RlIGRl
dmljZS4gSWYgZGVsZXRlIGlzIHRydWUsIGFueQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgc3RhdHVzIHdpbGwgYWxzbyBiZSBkZWxldGVkLiBPdGhlcndpc2UsIHRoZSBzdGF0
dXMgd2lsbAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYmUga2VwdCBmb3Ig
YWxsb3dpbmcgZnV0dXJlIHJlY29ubmVjdGlvbnMuCj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoFBvc3NpYmxlIGVycm9yczogb3JnLmJsdWV6LkVycm9yLkludmFsaWRBcmd1
bWVudHMKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCBvcmcuYmx1ZXouRXJyb3IuTm90Rm91bmQKPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBvcmcuYmx1ZXouRXJyb3Iu
SGRwRXJyb3IKPgo+IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4KPiBTZXJ2aWNlIMKgIMKgIMKg
IMKgIG9yZy5ibHVlego+IEludGVyZmFjZSDCoCDCoCDCoCBvcmcuYmx1ZXouSGRwUmVtb3RlU2Vz
c2lvbgo+IE9iamVjdCBwYXRoIMKgIMKgIFt2YXJpYWJsZSBwcmVmaXhdL3toY2kwLGhjaTEsLi4u
fS97aGRwMCxoZHAxLC4uLn0vcmVtX3Nlc3Npb25faWQKPgoKQ291bGQgeW91IHBsZWFzZSBlbGFi
b3JhdGUgbW9yZSBvbiB3aGF0IGRvZXMgSGRwU2Vzc2lvbiBhbmQKSGRwUmVtb3RlU2Vzc2lvbnMg
dHJpZXMgdG8gYWJzdHJhY3Q/IEl0IHN0aWxsIG5vdCBjbGVhciB0byBtZSBhbmQKZGVwZW5kaW5n
IG9uIHRoaXMgd2UgbWF5IGZpbmQgYSBiZXR0ZXIgbmFtZSBmb3IgaXQuCgo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgYm9vbGVhbiBFY2hvKGFycmF5e2J5dGV9KQo+Cj4gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBTZW5kcyBhbiBlY2hvIHBldGl0aW9uIHRvIHRoZSByZW1vdGUg
c2Vzc2lvbi4gUmV0dXJuIFRydWUKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oGlmIHJlc3BvbnNlIG1hdGNoZXMgd2l0aCB0aGUgYnVmZmVyIHNlbnQuIElmIHNvbWUgZXJyb3IK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlzIGRldGVjdGVkIEZhbHNlIHZh
bHVlIGlzIHJldHVybmVkIGFuZCB0aGUgYXNzb2NpYXRlZAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgTUNMIGlzIGNsb3NlZC4KPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
dWludDE2IE9wZW5EYXRhQ2hhbm5lbChieXRlIG1kZXBpZCwgYnl0ZSBjb25maWcpCj4KPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoENyZWF0ZXMgYSBuZXcgZGF0YSBjaGFubmVs
IHdpdGggdGhlIGluZGljYXRlZCBjb25maWcKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoHRvIHRoZSByZW1vdGUgTUNBUCBEYXRhIEVuZCBQb2ludCAoTURFUCkuCj4gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBUaGUgY29uZmlndXJhdGlvbiBzaG91bGQgaW5k
aWNhdGUgdGhlIGNoYW5uZWwgcXVhbGl0eSBvZgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgc2VydmljZS4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFJl
dHVybnMgdGhlIGRhdGEgY2hhbm5lbCBpZC4KPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgUG9zc2libGUgZXJyb3JzOiBvcmcuYmx1ZXouRXJyb3IuSW52YWxpZEFyZ3VtZW50
cwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIG9yZy5ibHVlei5FcnJvci5IZHBFcnJvcgo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqBhcnJheSBHZXREY0ZkKHVpbnQxNiBtZGxpZCkKPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgR2V0cyBhIGZpbGUgZGVzY3JpcHRvciB3aGVyZSBkYXRhIGNhbiBiZSByZWFk
IG9yCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB3cml0dGVuIGZvciByZWNl
aXZlIG9yIHNlbnQgYnkgdGhlIGRhdGEgY2hhbm5lbC4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoFJldHVybnMgYW4gYXJyYXkgb2YgZmlsZSBkZXNjcmlwdG9ycyBvbmUgZm9y
IHdyaXRlCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhbmQgb3RoZXIgZm9y
IHJlYWQuCj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoFBvc3NpYmxlIGVy
cm9yczogb3JnLmJsdWV6LkVycm9yLkludmFsaWRBcmd1bWVudHMKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBvcmcuYmx1ZXouRXJy
b3IuTm90Rm91bmQKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCBvcmcuYmx1ZXouRXJyb3IuSGRwRXJyb3IKPgo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgdm9pZCBEZWxldGVEYXRhQ2hhbm5lbCh1aW50MTYgbWRsaWQpCj4KPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoERlbGV0ZXMgYSBkYXRhIGNoYW5uZWwgc28g
aXQgd2lsbCBub3QgYmUgYXZhaWxhYmxlIGZvcgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgdXNlLgo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBQb3Nz
aWJsZSBlcnJvcnM6IG9yZy5ibHVlei5FcnJvci5JbnZhbGlkQXJndW1lbnRzCj4gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgb3JnLmJs
dWV6LkVycm9yLk5vdEZvdW5kCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgb3JnLmJsdWV6LkVycm9yLkhkcEVycm9yCj4KPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoHZvaWQgRGVsZXRlQWxsRGF0YUNoYW5uZWxzKCkKPgo+IMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgRGVsZXRlcyBhbGwgZGF0YSBjaGFubmVscyBz
byBpdCB3aWxsIG5vdCBiZSBhdmFpbGFibGUKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoGZvciB1c2UuIFR5cGljYWxseSB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIHRo
ZQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY29ubmVjdGlvbiB3aXRoIHRo
ZSByZW1vdGUgZGV2aWNlIHdpbGwgYmUgY2xvc2VkCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqBwZXJtYW5lbnRseQo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBQb3NzaWJsZSBlcnJvcnM6IG9yZy5ibHVlei5FcnJvci5IZHBFcnJvcgo+Cj4gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqBkaWN0IEdldERhdGFDaGFubmVsU3RhdHVzKCkKPgo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgUmV0dXJuIGEgZGljdGlvbmFyeSB3aXRoIGFsbCB0
aGUgZGF0YSBjaGFubmVscyB0aGF0Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqBjYW4gYmUgdXNlZCB0byBzZW5kIGRhdGEgcmlnaHQgbm93LiBUaGUgZGljdGlvbmFyeQo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaXMgZm9ybWVkIGxpa2UgZm9sbG93czoK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHsKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCJyZWxpYWJsZSI6IFtpZDEsIC4uLiwgaWR6
XSwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCJiZXN0
X2VmZm9ydCIgOiBbaWR4LCAuLi4sIGlkeV0KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoH0KPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgVGhlIGZpc3Qg
cmVsaWFibGUgZGF0YSBjaGFubmVsIHdpbGwgYWx3YXlzIGJlIHRoZSBmaXJzdAo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZGF0YSBjaGFubmVsIGluIHJlbGlhYmxlIGFycmF5
Lgo+Cj4gSERQQWdlbnQgaGllcmFyY2h5Cj4gPT09PT09PT09PT09PT09PT09Cj4KPiAodGhpcyBv
YmplY3QgaXMgaW1wbGVtZW50ZWQgYnkgdGhlIEhEUCBjbGllbnQgYW4gcmVjZWl2ZXMgbm90aWZp
Y2F0aW9ucykKPgo+IFNlcnZpY2UgwqAgwqAgwqAgwqAgdW5pcXVlIG5hbWUKPiBJbnRlcmZhY2Ug
wqAgwqAgwqAgb3JnLmJsdWV6LkhkcEFnZW50Cj4gT2JqZWN0IHBhdGggwqAgwqAgZnJlZWx5IGRl
ZmluYWJsZQo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB2b2lkIERldmljZUNvbm5lY3RlZChv
YmplY3QgcGF0aCkKPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgVGhpcyBt
ZXRob2QgaXMgY2FsbGVkIHdoZW5ldmVyIGEgbmV3IGRldmljZSBjb25uZWN0aW9uCj4gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBoYXMgYmVlbiBlc3RhYmxpc2hlZCBvdmVyIHRo
ZSBjb250cm9sIGNoYW5uZWwgb2YgdGhlCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqBjdXJyZW50IEhEUCBzZXNzaW9uLiBUaGUgb2JqZWN0IHBhdGggY29udGFpbnMgdGhlIG9i
amVjdAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcGF0aCBvZiB0aGUgcmVt
b3RlIGRldmljZS4KPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdm9pZCBEZXZpY2VEaXNjb25u
ZWN0ZWQob2JqZWN0IHBhdGgpCj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIGEgcmVtb3RlIGRldmljZSBpcwo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZGlzY29ubmVjdGVkIGRlZmluaXRpdmVseS4gQW55
IGZ1dHVyZSByZWNvbm5lY3Rpb25zCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqB3aWxsIGZhaWwuIEFsc28gYWxsIGRhdGEgY2hhbm5lbHMgYXNzb2NpYXRlZCB0byB0aGlzCj4g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBkZXZpY2Ugd2lsbCBiZSBjbG9zZWQu
Cj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHZvaWQgQ3JlYXRlZERhdGFDaGFubmVsKG9iamVj
dCBwYXRoLCB1aW50MTYgbWRsaWQpCj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIGEgbmV3IGRhdGEgY2hhbm5lbCBpcyBjcmVh
dGVkCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBUaGUgcGF0aCBjb250YWlu
cyB0aGUgb2JqZWN0IHBhdGggb2YgdGhlIGRldmljZSB3aGl0aAo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgdGhlIG5ldyBjb25uZWN0aW9uIGlzIGNyZWF0ZWQgYW5kIHRoZSBt
ZGxpZCB0aGUgZGF0YQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY2hhbm5l
bCBpZGVudGlmaWNhdG9yLgo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB2b2lkIERlbGV0ZWRE
YXRhQ2hhbm5lbChvYmplY3QgcGF0aCwgdWludDE2IG1kbGlkKQo+Cj4gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiBhIGRhdGEgY2hh
bm5lbCBpcyBjbG9zZWQuCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBBZnRl
ciB0aGlzIGNhbGwgdGhlIGRhdGEgY2hhbm5lbCB3aWxsIG5vdCBiZSB2YWxpZCBhbmQKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGNhbiBiZSByZXVzZWQgZm9yIGZ1dHVyZSBj
cmVhdGVkIGRhdGEgY2hhbm5lbHMuCj4gLS0KPiBUbyB1bnN1YnNjcmliZSBmcm9tIHRoaXMgbGlz
dDogc2VuZCB0aGUgbGluZSAidW5zdWJzY3JpYmUgbGludXgtYmx1ZXRvb3RoIiBpbgo+IHRoZSBi
b2R5IG9mIGEgbWVzc2FnZSB0byBtYWpvcmRvbW9Admdlci5rZXJuZWwub3JnCj4gTW9yZSBtYWpv
cmRvbW8gaW5mbyBhdCDCoGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21vLWluZm8uaHRt
bAo+CgoKCi0tIApKb8OjbyBQYXVsbyBSZWNoaSBWaXRhCmh0dHA6Ly9qcHJ2aXRhLndvcmRwcmVz
cy5jb20vCg==

Subject: Re: HDP proposed API (ver 0.3)

Hi Daniel,

first of all thanks for your comments.

El Wednesday 12 May 2010 12:45:28 Daniel Abraham escribi?:
> On Wed, May 12, 2010 at 12:26 PM, Jos? Antonio Santos Cadenas
>
> <[email protected]> wrote:
> > This api is a clean up of the previous one the changes.
> >
> > We've added a new object that uses device path to get the sessions
> > allocated on this device (as somebody recommended in other thread,
> > I think Luiz, Elvis or both, but I can't find the exact email). The
> > discovery of new remote session should be done using device drivers,
> > which is compliant with the BlueZ style.
> >
> > Discussions still in progress:
> >
> > - Fd-passing issue: As Elvis, Santiago and I discussed yesterday on
> > IRC we think that the best propose is as follows (please Elvis correct
> > me if I misunderstood something yesterday):
> > Reconnections should be implicit and the data channel should
> > be perceived by the application layer as connected all the time.
> > When the application tries to write in a closed data channel, HDP
> > will perform the data channel reconnection and if it fails, then the
> > channel will be present as closed.
> > The implementation for this this behaviour will use pipes. Each
> > data channel will use 2 pipes to do fd-passing to the application. The
> > upper layer will write in this pipes and HDP will redirect it through
> > the l2cap socket, in this operation, HDP can reconnect if th l2cap
> > socket is closed.
> >
> > - Sessions issues: We still think that session are necessary because they
> > are mentioned in the standard and in the whitepaper and we think that
> > bluez should follow the standards in order to pass PTS for allow
> > Bluetooth SIG certifications. Any comment in this respect are welcome to
> > improve the API usability and conformity with Bluez APIs.
> >
> > - Paths issues: It will be great to find names and paths that are good
> > for everybody, comments and suggestion on this respect are also welcome.
> >
> > I hope we can fix this API asap. All comments or ideas are welcome.
> >
> > Regards.
> >
> > --------------------------------------------------
> >
> > BlueZ D-Bus HDP 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.Hdp
> > Object path [variable prefix]/{hci0,hci1,...}
> >
> > Methods object CreateSession(object path, dict config)
> >
> > Returns the object path for the new HDP session.
> > The path parameter is the path of the remote
> > object with the callbacks to notify events (see
> > org.bluez.HdpAgent at the end of this document)
> > This petition starts an mcap session and also
> > register in the SDP is needed
> > Dict is defined as bellow:
> > { "data_spec" : The data_spec is the data exchange
> > specification (see section 5.2.10
> > of the specification document) possible values:
> > 0x00 = reserved,
> > 0x01 [IEEE 11073-20601],
> > 0x02..0xff reserved,
> > (optional)
> > "end_points" : [{ (optional)
> > "mdepid" : uint8, (optional)
> > "role" : ("source" or "sink"), (mandatory)
> > "specs" :[{ (mandatory)
> > "data_type" : uint16, (mandatory)
> > "description" : string, (optional)
> > }]
> > }]
> > }
> >
> > if "data_spec" is not set, no SDP record will be
> > registered, so all the other data in the
> > dictionary will be ignored
> >
> > Session will be closed by the call or implicitly
> > when the programs leaves the bus.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > void CloseSession(object path)
> >
> > Closes the HDP session identified by the object
> > path. Also session will be closed if the process that started it is
> > removed from the D-Bus.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> >
> > -------------------------------------------------------------------------
> > -------
> >
> > Service org.bluez
> > Interface org.bluez.Hdp
> > Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
> >
> > Methods array GetSessions()
> >
> > Gets the information of the remote sessions
> > present in this device and published on its SDP record. The returned
> > data follows this format.
> >
> > [{"session_id": "a session identification as
> > string", "data_spec" : session data spec,
> > "end_points":
> > ["mdepid": uint8,
> > "role" : "source" or "sink" ,
> > "specs" : [{
> > "dtype" : uint16,
> > "description" : string,
> > (optional) }]
> > ]
> > }]
> >
> > -------------------------------------------------------------------------
> > -------
> >
> > Service org.bluez
> > Interface org.bluez.HdpSession
> > Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
> >
> > object Connect(remote_session_id)
> >
> > Connects with the remote session and returns its
> > object path.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.HdpError
> >
> > void Disconnect(object device, boolean delete)
> >
> > Disconnect from the remote device. If delete is
> > true, any status will also be deleted. Otherwise, the status will be
> > kept for allowing future reconnections.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HdpError
> >
> > -------------------------------------------------------------------------
> > -------
> >
> > Service org.bluez
> > Interface org.bluez.HdpRemoteSession
> > Object path [variable
> > prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/rem_session_id
> >
> > boolean Echo(array{byte})
> >
> > Sends an echo petition to the remote session.
> > Return True if response matches with the buffer sent. If some error is
> > detected False value is returned and the associated MCL is closed.
> >
> > uint16 OpenDataChannel(byte mdepid, byte config)
> >
> > 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.
> > Returns the data channel id.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.HdpError
> >
> > array GetDcFd(uint16 mdlid)
>
> "getdcfd" doesn't seem to me as a "friendly" name. Any way to make it
> better, please?

You are right, I forgot to change this name, thank you for the notice. I
suggest:

GetDataChannelFileDescriptor

Which is more compliant with the rest of the API.

>
> > Gets a file descriptor where data can be read or
> > written for receive or sent by the data channel.
> > Returns an array of file descriptors one for write
> > and other for read.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HdpError
> >
> > void DeleteDataChannel(uint16 mdlid)
> >
> > Deletes a data channel so it will not be available
> > for use.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HdpError
> >
> > void DeleteAllDataChannels()
> >
> > Deletes all data channels so it will not be
> > available for use. Typically this function is called when the connection
> > with the remote device will be closed permanently
> >
> > Possible errors: org.bluez.Error.HdpError
> >
> > 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": [id1, ..., idz],
> > "best_effort" : [idx, ..., idy]
> > }
> >
> > The fist reliable data channel will always be the
> > first data channel in reliable array.
> >
> > HDPAgent hierarchy
> > ==================
> >
> > (this object is implemented by the HDP client an receives notifications)
> >
> > Service unique name
> > Interface org.bluez.HdpAgent
> > Object path freely definable
> >
> > void DeviceConnected(object path)
> >
> > This method is called whenever a new device
> > connection has been established over the control channel of the current
> > HDP session. The object path contains the object path of the remote
> > device.
> >
> > void DeviceDisconnected(object path)
> >
> > This method is called when a remote device is
> > disconnected definitively. Any future
> > reconnections will fail. Also all data channels associated to this
> > device will be closed.
> >
> > void CreatedDataChannel(object path, uint16 mdlid)
> >
> > This method is called when a new data channel is
> > created The path contains the object path of the device whith the new
> > connection is created and the mdlid the data channel identificator.
> >
> > void DeletedDataChannel(object path, uint16 mdlid)
> >
> > This method is called when a data channel is
> > closed. After this call the data channel will not be valid and can be
> > reused for future created data channels.
>
> Question from a user's perspective: why define an agent? Why not
> define the above as signal callbacks in the relevant object? (same as
> most APIs in "bluez/docs").

Because the this notifications are only relevant for the process that created
the session and this process should be the unique that receives this events.
If you define signals, everybody in the bus can be subscribed to them, this is
a problem in two ways:
- Noise in the bus
- "Privacy" issue because just the owner of the session should be notified
of the session events.

>
> The only places I saw where agents are used are: BlueZ pairing (remote
> device object doesn't necessarily exist yet, so no way to register for
> its events, so an agent is required), and obexd (callback methods for
> authroization of transactions return a significant value, i.e. not a
> simple signal, so an agent is also required).
>
> But none of these conditions apply in the HDP agent above. So is there
> another reason?

I explained above.

If we are wrong and signals can be cached only by one process it is OK for us
to change this.

>
> Also, why not add properties for
> connected/disconnected/opened/closed/etc. states? (And then
> "GetProperties()" method, and "PropertyChanged(name, value)" signal).
> For example, see "bluez/docs/network-api.txt"...

Because this notifications concern to objects that are being created and
destroyed (in the case of devices) and created or closed data channels, so new
data channels ids are created or destroyed when this method are called. I
can't see how properties can help here. The channel may exist or not I think
that properties are not a good option in this case.

Regards.

> --
> 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-05-12 10:45:28

by Daniel Abraham

[permalink] [raw]
Subject: Re: HDP proposed API (ver 0.3)

On Wed, May 12, 2010 at 12:26 PM, Jos? Antonio Santos Cadenas
<[email protected]> wrote:
> This api is a clean up of the previous one the changes.
>
> We've added a new object that uses device path to get the sessions
> allocated on this device (as somebody recommended in other thread,
> I think Luiz, Elvis or both, but I can't find the exact email). The discovery
> of new remote session should be done using device drivers, which is
> compliant with the BlueZ style.
>
> Discussions still in progress:
>
> - Fd-passing issue: As Elvis, Santiago and I discussed yesterday on
> IRC we think that the best propose is as follows (please Elvis correct
> me if I misunderstood something yesterday):
> ? ? ? ?Reconnections should be implicit and the data channel should
> be perceived by the application layer as connected all the time.
> ? ? ? ?When the application tries to write in a closed data channel, HDP
> will perform the data channel reconnection and if it fails, then the channel
> will be present as closed.
> ? ? ? ?The implementation for this this behaviour will use pipes. Each data
> channel will use 2 pipes to do fd-passing to the application. The upper
> layer will write in this pipes and HDP will redirect it through the l2cap socket,
> in this operation, HDP can reconnect if th l2cap socket is closed.
>
> - Sessions issues: We still think that session are necessary because they
> are mentioned in the standard and in the whitepaper and we think that
> bluez should follow the standards in order to pass PTS for allow Bluetooth SIG
> certifications. Any comment in this respect are welcome to improve the API
> usability and conformity with Bluez APIs.
>
> - Paths issues: It will be great to find names and paths that are good for
> everybody, comments and suggestion on this respect are also welcome.
>
> I hope we can fix this API asap. All comments or ideas are welcome.
>
> Regards.
>
> --------------------------------------------------
>
> BlueZ D-Bus HDP 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.Hdp
> Object path ? ? [variable prefix]/{hci0,hci1,...}
>
> Methods ? ? ? ? object CreateSession(object path, dict config)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Returns the object path for the new HDP session.
> ? ? ? ? ? ? ? ? ? ? ? ?The path parameter is the path of the remote object
> ? ? ? ? ? ? ? ? ? ? ? ?with the callbacks to notify events (see
> ? ? ? ? ? ? ? ? ? ? ? ?org.bluez.HdpAgent at the end of this document)
> ? ? ? ? ? ? ? ? ? ? ? ?This petition starts an mcap session and also register
> ? ? ? ? ? ? ? ? ? ? ? ?in the SDP is needed
> ? ? ? ? ? ? ? ? ? ? ? ?Dict is defined as bellow:
> ? ? ? ? ? ? ? ? ? ? ? ?{ "data_spec" : The data_spec is the data exchange
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?specification (see section 5.2.10 of
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?the specification document)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?possible values:
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x00 = reserved,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x01 [IEEE 11073-20601],
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x02..0xff reserved,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(optional)
> ? ? ? ? ? ? ? ? ? ? ? ? ?"end_points" : [{ (optional)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"mdepid" : uint8, (optional)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"role" : ("source" or "sink"), (mandatory)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"specs" :[{ (mandatory)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"data_type" : uint16, (mandatory)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"description" : string, (optional)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}]
> ? ? ? ? ? ? ? ? ? ? ? ? ?}]
> ? ? ? ? ? ? ? ? ? ? ? ?}
>
> ? ? ? ? ? ? ? ? ? ? ? ?if "data_spec" is not set, no SDP record will be
> ? ? ? ? ? ? ? ? ? ? ? ?registered, so all the other data in the dictionary
> ? ? ? ? ? ? ? ? ? ? ? ?will be ignored
>
> ? ? ? ? ? ? ? ? ? ? ? ?Session will be closed by the call or implicitly when
> ? ? ? ? ? ? ? ? ? ? ? ?the programs leaves the bus.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
>
> ? ? ? ? ? ? ? ?void CloseSession(object path)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Closes the HDP session identified by the object path.
> ? ? ? ? ? ? ? ? ? ? ? ?Also session will be closed if the process that started
> ? ? ? ? ? ? ? ? ? ? ? ?it is removed from the D-Bus.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.NotFound
>
> --------------------------------------------------------------------------------
>
> Service ? ? ? ? org.bluez
> Interface ? ? ? org.bluez.Hdp
> Object path ? ? [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
>
> Methods array GetSessions()
>
> ? ? ? ? ? ? ? ? ? ? ? ?Gets the information of the remote sessions present
> ? ? ? ? ? ? ? ? ? ? ? ?in this device and published on its SDP record. The
> ? ? ? ? ? ? ? ? ? ? ? ?returned data follows this format.
>
> ? ? ? ? ? ? ? ? ? ? ? ?[{"session_id": "a session identification as string",
> ? ? ? ? ? ? ? ? ? ? ? ? "data_spec" : session data spec,
> ? ? ? ? ? ? ? ? ? ? ? ? "end_points":
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ["mdepid": uint8,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"role" ?: "source" or "sink" ,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"specs" : [{
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"dtype" ? ? ? : uint16,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"description" : string, (optional)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}]
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ]
> ? ? ? ? ? ? ? ? ? ? ? ?}]
>
> --------------------------------------------------------------------------------
>
> Service ? ? ? ? org.bluez
> Interface ? ? ? org.bluez.HdpSession
> Object path ? ? [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
>
> ? ? ? ? ? ? ? ?object Connect(remote_session_id)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Connects with the remote session and returns its object
> ? ? ? ? ? ? ? ? ? ? ? ?path.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.HdpError
>
> ? ? ? ? ? ? ? ?void Disconnect(object device, boolean delete)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Disconnect from the remote device. If delete is true, any
> ? ? ? ? ? ? ? ? ? ? ? ?status will also be deleted. Otherwise, the status will
> ? ? ? ? ? ? ? ? ? ? ? ?be kept for allowing future reconnections.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.NotFound
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.HdpError
>
> --------------------------------------------------------------------------------
>
> Service ? ? ? ? org.bluez
> Interface ? ? ? org.bluez.HdpRemoteSession
> Object path ? ? [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/rem_session_id
>
> ? ? ? ? ? ? ? ?boolean Echo(array{byte})
>
> ? ? ? ? ? ? ? ? ? ? ? ?Sends an echo petition to the remote session. Return True
> ? ? ? ? ? ? ? ? ? ? ? ?if response matches with the buffer sent. If some error
> ? ? ? ? ? ? ? ? ? ? ? ?is detected False value is returned and the associated
> ? ? ? ? ? ? ? ? ? ? ? ?MCL is closed.
>
> ? ? ? ? ? ? ? ?uint16 OpenDataChannel(byte mdepid, byte config)
>
> ? ? ? ? ? ? ? ? ? ? ? ?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.
> ? ? ? ? ? ? ? ? ? ? ? ?Returns the data channel id.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.HdpError
>
> ? ? ? ? ? ? ? ?array GetDcFd(uint16 mdlid)

"getdcfd" doesn't seem to me as a "friendly" name. Any way to make it
better, please?

>
> ? ? ? ? ? ? ? ? ? ? ? ?Gets a file descriptor where data can be read or
> ? ? ? ? ? ? ? ? ? ? ? ?written for receive or sent by the data channel.
> ? ? ? ? ? ? ? ? ? ? ? ?Returns an array of file descriptors one for write
> ? ? ? ? ? ? ? ? ? ? ? ?and other for read.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.NotFound
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.HdpError
>
> ? ? ? ? ? ? ? ?void DeleteDataChannel(uint16 mdlid)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Deletes a data channel so it will not be available for
> ? ? ? ? ? ? ? ? ? ? ? ?use.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.NotFound
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.HdpError
>
> ? ? ? ? ? ? ? ?void DeleteAllDataChannels()
>
> ? ? ? ? ? ? ? ? ? ? ? ?Deletes all data channels so it will not be available
> ? ? ? ? ? ? ? ? ? ? ? ?for use. Typically this function is called when the
> ? ? ? ? ? ? ? ? ? ? ? ?connection with the remote device will be closed
> ? ? ? ? ? ? ? ? ? ? ? ?permanently
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.HdpError
>
> ? ? ? ? ? ? ? ?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": [id1, ..., idz],
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"best_effort" : [idx, ..., idy]
> ? ? ? ? ? ? ? ? ? ? ? ?}
>
> ? ? ? ? ? ? ? ? ? ? ? ?The fist reliable data channel will always be the first
> ? ? ? ? ? ? ? ? ? ? ? ?data channel in reliable array.
>
> HDPAgent hierarchy
> ==================
>
> (this object is implemented by the HDP client an receives notifications)
>
> Service ? ? ? ? unique name
> Interface ? ? ? org.bluez.HdpAgent
> Object path ? ? freely definable
>
> ? ? ? ? ? ? ? ?void DeviceConnected(object path)
>
> ? ? ? ? ? ? ? ? ? ? ? ?This method is called whenever a new device connection
> ? ? ? ? ? ? ? ? ? ? ? ?has been established over the control channel of the
> ? ? ? ? ? ? ? ? ? ? ? ?current HDP session. The object path contains the object
> ? ? ? ? ? ? ? ? ? ? ? ?path of the remote device.
>
> ? ? ? ? ? ? ? ?void DeviceDisconnected(object path)
>
> ? ? ? ? ? ? ? ? ? ? ? ?This method is called when a remote device is
> ? ? ? ? ? ? ? ? ? ? ? ?disconnected definitively. Any future reconnections
> ? ? ? ? ? ? ? ? ? ? ? ?will fail. Also all data channels associated to this
> ? ? ? ? ? ? ? ? ? ? ? ?device will be closed.
>
> ? ? ? ? ? ? ? ?void CreatedDataChannel(object path, uint16 mdlid)
>
> ? ? ? ? ? ? ? ? ? ? ? ?This method is called when a new data channel is created
> ? ? ? ? ? ? ? ? ? ? ? ?The path contains the object path of the device whith
> ? ? ? ? ? ? ? ? ? ? ? ?the new connection is created and the mdlid the data
> ? ? ? ? ? ? ? ? ? ? ? ?channel identificator.
>
> ? ? ? ? ? ? ? ?void DeletedDataChannel(object path, uint16 mdlid)
>
> ? ? ? ? ? ? ? ? ? ? ? ?This method is called when a data channel is closed.
> ? ? ? ? ? ? ? ? ? ? ? ?After this call the data channel will not be valid and
> ? ? ? ? ? ? ? ? ? ? ? ?can be reused for future created data channels.

Question from a user's perspective: why define an agent? Why not
define the above as signal callbacks in the relevant object? (same as
most APIs in "bluez/docs").

The only places I saw where agents are used are: BlueZ pairing (remote
device object doesn't necessarily exist yet, so no way to register for
its events, so an agent is required), and obexd (callback methods for
authroization of transactions return a significant value, i.e. not a
simple signal, so an agent is also required).

But none of these conditions apply in the HDP agent above. So is there
another reason?

Also, why not add properties for
connected/disconnected/opened/closed/etc. states? (And then
"GetProperties()" method, and "PropertyChanged(name, value)" signal).
For example, see "bluez/docs/network-api.txt"...

Subject: Re: HDP proposed API (ver 0.3)

El Wednesday 12 May 2010 11:26:12 Jos? Antonio Santos Cadenas escribi?:
> This api is a clean up of the previous one the changes.
>
> We've added a new object that uses device path to get the sessions
> allocated on this device (as somebody recommended in other thread,
> I think Luiz, Elvis or both, but I can't find the exact email). The discovery
> of new remote session should be done using device drivers, which is
> compliant with the BlueZ style.
>
> Discussions still in progress:
>
> - Fd-passing issue: As Elvis, Santiago and I discussed yesterday on
> IRC we think that the best propose is as follows (please Elvis correct
> me if I misunderstood something yesterday):
> Reconnections should be implicit and the data channel should
> be perceived by the application layer as connected all the time.
> When the application tries to write in a closed data channel, HDP
> will perform the data channel reconnection and if it fails, then the channel
> will be present as closed.
> The implementation for this this behaviour will use pipes. Each data
> channel will use 2 pipes to do fd-passing to the application. The upper
> layer will write in this pipes and HDP will redirect it through the l2cap socket,
> in this operation, HDP can reconnect if th l2cap socket is closed.
>
> - Sessions issues: We still think that session are necessary because they
> are mentioned in the standard and in the whitepaper and we think that
> bluez should follow the standards in order to pass PTS for allow Bluetooth SIG
> certifications. Any comment in this respect are welcome to improve the API
> usability and conformity with Bluez APIs.
>
> - Paths issues: It will be great to find names and paths that are good for
> everybody, comments and suggestion on this respect are also welcome.
>
> I hope we can fix this API asap. All comments or ideas are welcome.
>
> Regards.
>
> --------------------------------------------------
>
> BlueZ D-Bus HDP 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.Hdp
> Object path [variable prefix]/{hci0,hci1,...}
>
> Methods object CreateSession(object path, dict config)
>
> Returns the object path for the new HDP session.
> The path parameter is the path of the remote object
> with the callbacks to notify events (see
> org.bluez.HdpAgent at the end of this document)
> This petition starts an mcap session and also register
> in the SDP is needed
> Dict is defined as bellow:
> { "data_spec" : The data_spec is the data exchange
> specification (see section 5.2.10 of
> the specification document)
> possible values:
> 0x00 = reserved,
> 0x01 [IEEE 11073-20601],
> 0x02..0xff reserved,
> (optional)
> "end_points" : [{ (optional)
> "mdepid" : uint8, (optional)

About explicitly set the mdepids, we (Santiago and me) think that HDP should
assign them automatically, this way less protocol issues are exposed to the
application layer as Luiz suggested. The HDP client should only use mdeps when
connecting to a remote data channel. HDP will assign a unique mdepid
to each element of "end_points" array.


> "role" : ("source" or "sink"), (mandatory)
> "specs" :[{ (mandatory)
> "data_type" : uint16, (mandatory)
> "description" : string, (optional)
> }]
> }]
> }
>
> if "data_spec" is not set, no SDP record will be
> registered, so all the other data in the dictionary
> will be ignored
>
> Session will be closed by the call or implicitly when
> the programs leaves the bus.
>
> Possible errors: org.bluez.Error.InvalidArguments
>
> void CloseSession(object path)
>
> Closes the HDP session identified by the object path.
> Also session will be closed if the process that started
> it is removed from the D-Bus.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
>
> --------------------------------------------------------------------------------
>
> Service org.bluez
> Interface org.bluez.Hdp
> Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
>
> Methods array GetSessions()
>
> Gets the information of the remote sessions present
> in this device and published on its SDP record. The
> returned data follows this format.
>
> [{"session_id": "a session identification as string",
> "data_spec" : session data spec,
> "end_points":
> ["mdepid": uint8,
> "role" : "source" or "sink" ,
> "specs" : [{
> "dtype" : uint16,
> "description" : string, (optional)
> }]
> ]
> }]
>
> --------------------------------------------------------------------------------
>
> Service org.bluez
> Interface org.bluez.HdpSession
> Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
>
> object Connect(remote_session_id)
>
> Connects with the remote session and returns its object
> path.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HdpError
>
> void Disconnect(object device, boolean delete)
>
> Disconnect from the remote device. If delete is true, any
> status will also be deleted. Otherwise, the status will
> be kept for allowing future reconnections.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HdpError
>
> --------------------------------------------------------------------------------
>
> Service org.bluez
> Interface org.bluez.HdpRemoteSession
> Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/rem_session_id
>
> boolean Echo(array{byte})
>
> Sends an echo petition to the remote session. Return True
> if response matches with the buffer sent. If some error
> is detected False value is returned and the associated
> MCL is closed.
>
> uint16 OpenDataChannel(byte mdepid, byte config)
>
> 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.
> Returns the data channel id.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.HdpError
>
> array GetDcFd(uint16 mdlid)
>
> Gets a file descriptor where data can be read or
> written for receive or sent by the data channel.
> Returns an array of file descriptors one for write
> and other for read.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HdpError
>
> void DeleteDataChannel(uint16 mdlid)
>
> Deletes a data channel so it will not be available for
> use.
>
> Possible errors: org.bluez.Error.InvalidArguments
> org.bluez.Error.NotFound
> org.bluez.Error.HdpError
>
> void DeleteAllDataChannels()
>
> Deletes all data channels so it will not be available
> for use. Typically this function is called when the
> connection with the remote device will be closed
> permanently
>
> Possible errors: org.bluez.Error.HdpError
>
> 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": [id1, ..., idz],
> "best_effort" : [idx, ..., idy]
> }
>
> The fist reliable data channel will always be the first
> data channel in reliable array.
>
> HDPAgent hierarchy
> ==================
>
> (this object is implemented by the HDP client an receives notifications)
>
> Service unique name
> Interface org.bluez.HdpAgent
> Object path freely definable
>
> void DeviceConnected(object path)
>
> This method is called whenever a new device connection
> has been established over the control channel of the
> current HDP session. The object path contains the object
> path of the remote device.
>
> void DeviceDisconnected(object path)
>
> This method is called when a remote device is
> disconnected definitively. Any future reconnections
> will fail. Also all data channels associated to this
> device will be closed.
>
> void CreatedDataChannel(object path, uint16 mdlid)
>
> This method is called when a new data channel is created
> The path contains the object path of the device whith
> the new connection is created and the mdlid the data
> channel identificator.
>
> void DeletedDataChannel(object path, uint16 mdlid)
>
> This method is called when a data channel is closed.
> After this call the data channel will not be valid and
> can be reused for future created data channels.
> --
> 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
>