Hello,
Next is the API wich we have been working last weeks.
Regards.
BlueZ D-Bus HDP API description
***********************************
Authors:
Santiago Carot-Nemesio [email protected]
Jose Antonio Santos-Cadenas [email protected]
Health Device Profile hierarchy
===============================
Service org.bluez
Interface org.bluez.Hdp
Object path [variable prefix]/{hci0,hci1,...}
Methods object CreateSession(object path, byte data_spec)
Returns the object path for the new HDP session.
The path parameter is the path of the remote object
with the callbacks to nofity events (see
org.bluez.HdpAgent at the end of this document)
The data_spec is the data exchange specficication
(see section 5.2.10 of the specification document)
Possible errors: org.bluez.Error.InvalidArguments
void DeleteSession(object path)
Delete the HDP session identified by the object path.
Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
--------------------------------------------------------------------------------
Service org.bluez
Interface org.bluez.HdpSession
Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
uint8 AllocateMdep(uint8 role)
This method allocates a logical end point. Valids values
for MDEP roles are:
* 0x00 For source
* 0x01 For sink
The return value is the allocated MDEP.
void AddFeature(uint8 mdepid, uint16 dtype, string dscr)
Add a new entry in the HDP supported feature list with
the role given in the MDEP id.
If the new feature has the same data type as other
previusly added feature for the same MDEP id, the old
feature will be overwritten.
void Start()
Starts the associated MCAP layer and set up the SDP
registry with all supported features.
Possible errors: org.bluez.Error.HdpError
object Connect(string btaddr)
Connect with the device and returns the object path of
the remote device.
To call this method, the session must be started.
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 keeped for allowing future reconnections.
To call this method, the session must be started.
Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
org.bluez.Error.HdpError
--------------------------------------------------------------------------------
Service org.bluez
Interface org.bluez.HdpDevice
Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/dev_XX_XX_XX_XX_XX_XX
boolean Echo(array{byte})
Sends an echo petition to the remote device. Return True
if response matches with the buffer sended. If some error
is detected False value is returned and the associated
MCL is closed.
uint16 OpenDc(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
file_descriptor GetDcFd(uint16 mdlid)
Gets a file descriptor where data can be readed or
writed for receive or sent by the data channel.
Returns the file descriptor
Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.NotFound
org.bluez.Error.HdpError
void DeleteDc(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 DeleteAllDc()
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
uint16 FirstRelDc()
Returns the identificator of the first reliable data
channel connected for this device.
Possible errors: org.bluez.Error.HdpError
HDPAgent hierarchy
==================
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 objectpath 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 CreatedDc(object path, uint16 mdlid, filedescriptor fd)
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, the mdlid the data
channel identificator and the fd is the file descriptor
where the data can be readed or writed.
void DeletedDc(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.
void DataReady(object path, uint16 mdlid, filedescriptor fd)
This method is called when there is new data that can be
readed in a data channel
El Wednesday 05 May 2010 15:22:16 Elvis Pf?tzenreuter escribi?:
> > So you mean do fd-passing with the pipe file descriptor to the client and then HDP will write the data in the L2CAP socket using splice, am I right?
>
> I guess they meant using splice for the pipe (because as far as I understood, it is for pipes only), so the data exchanged between bluez and application is zero-copy.--
I'm reading splice documentation and I understand that can be used with any type of fd,
but one of the fd should be a pipe. This is ok for that case.
I see one problem. The pipes are unidirectional so for a full duplex data channel
HDP will need two pipes (what means 4 fd and pass 2 to the client, one for read
and other for write). We should find an easy way to solve this. Proposals are
welcome :)
> So you mean do fd-passing with the pipe file descriptor to the client and then HDP will write the data in the L2CAP socket using splice, am I right?
I guess they meant using splice for the pipe (because as far as I understood, it is for pipes only), so the data exchanged between bluez and application is zero-copy.
Hello,
El Wednesday 05 May 2010 15:10:56 Elvis Pf?tzenreuter escribi?:
>
> >>
> >> The d-bus writing option: we thing that is too much load for the dbus and that will be very
> >> slow too. Because the change to xml formtat could be very expensive, and the amount of data
> >> could be very big. Note tha 11073-20601 defines apdus of 65Kb (we think that this is too much for d-bus)
> >
> > That's a good question for us to make in #dbus channel :)
>
> Ok, indeed D-BUS guys said that a fd (e.g. a pipe) is better, and suggested using pipes + http://en.wikipedia.org/wiki/Splice_(system_call)
So you mean do fd-passing with the pipe file descriptor to the client and then HDP will write the data in the L2CAP socket using splice, am I right?
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
>
>>
>> The d-bus writing option: we thing that is too much load for the dbus and that will be very
>> slow too. Because the change to xml formtat could be very expensive, and the amount of data
>> could be very big. Note tha 11073-20601 defines apdus of 65Kb (we think that this is too much for d-bus)
>
> That's a good question for us to make in #dbus channel :)
Ok, indeed D-BUS guys said that a fd (e.g. a pipe) is better, and suggested using pipes + http://en.wikipedia.org/wiki/Splice_(system_call)
>
> The d-bus writing option: we thing that is too much load for the dbus and that will be very
> slow too. Because the change to xml formtat could be very expensive, and the amount of data
> could be very big. Note tha 11073-20601 defines apdus of 65Kb (we think that this is too much for d-bus)
That's a good question for us to make in #dbus channel :)
But we have agreed that either we use D-BUS or a "fake" fd which is not the L2CAP raw channel, that's everything.
(In audio the raw socket is fine because if you lose some miliseconds of sound, it does not make a difference.)
El Wednesday 05 May 2010 02:07:24 Elvis Pf?tzenreuter escribi?:
>
> > while some_condition:
> > try:
> > os.write(fd, "some_data")
> > except:
> > fd = dev.GetDcFd(dcid) # Implicit reconeciton of dc
>
> I'd like to believe that power-saving disconneciton of a L2CAP channel and reconnection would be that simple to handle at application side. But I don't :)
>
> Even if the fd is a L2CAP SOCK_SEQPACKET, which means that write() would be atomic for the message, the message might be still at output buffer when the connection drops. Or it might have been transmitted. The application would never know, and could not act upon.
>
> I think that, talking specifically about this MCAP/HDP data channel reconnection stuff, we have two extremist albeit sensible approaches:
We think that this is an important issue and you are right, we didn't thought about the
buffers and could be a problem because dbus fd passing could be buffering the data.
We based our design in AUDIO plugin that uses fd passing too.
>
> a) let the application handle it, as "my" API proposes. Application is notified about disconnection and chooses what to do, and lingering sessions must be prepared to deal with FD replacement;
Here you have the same problem that you mentioned above, because you don't know
what data was send, you also have the fd passing problem and you don't know the
amount of data that was sent.
>
> b) hide it completely from the application. This includes NOT passing the L2CAP fd, but a UNIX socket fd which HDP plug-in takes care of. Or, perhaps not to use any FD passing at all: just send HDP data messages via D-BUS, and that's it.
We prefer this and we thought about it in the past. There are a little bit more complicated
but probably safer.
The d-bus writing option: we thing that is too much load for the dbus and that will be very
slow too. Because the change to xml formtat could be very expensive, and the amount of data
could be very big. Note tha 11073-20601 defines apdus of 65Kb (we think that this is too much for d-bus)
The option of having a socket sounds a little bit complicated, but we think that it is the best.
We also thought about it in the past but we discarted it because it is harder to implement it
than the fd-passing option (we didn't see the problems that you mentioned). In fact, the
no-bluez-integrated implementation that we did in the past used this method.
I think having an HDP socket is great because reconnections can be implicit for the upper layers
that can see the socket as permantly connected even when it is closed. HDP should
reconenct when receives data from the client to send to the remote device. This way no data
can be lost and reconnections are implicit. An other advantage of this option is that the
upper aplication doesn't have any aditional load with the reconnection issue.
>
> Your API has a mix of "a" and "b": approaches: automatic reconnection but with possible mid-flight FD replacement.--
Regards
Hi,
El mar, 04-05-2010 a las 17:50 +0300, Luiz Augusto von Dentz escribió:
> Hi,
>
> On Tue, May 4, 2010 at 1:54 PM, José Antonio Santos Cadenas
> <[email protected]> wrote:
> > Hi all,
> >
> > Next a simple example program in python using the api that we proposed in this thread.
> >
> > We still use the name Device but maybe a better name can be used.
> >
> > Regards.
> >
> > ----------
> > #!/usr/bin/python
> > # -*- coding: utf-8 -*-
> >
> > import dbus
> > import dbus.service
> > from dbus.mainloop.glib import DBusGMainLoop
> > import gobject
> > import os
> >
> > DBusGMainLoop(set_as_default=True)
> > loop = gobject.MainLoop()
> >
> > obj_path = "/python/tester/hdp"
> >
> > bus = dbus.SystemBus()
> >
> > # This object receives the information from the daemon
> > class HDP(dbus.service.Object):
> > def __init__(self, bus, obj_path):
> > self.bus = bus
> > dbus.service.Object.__init__(self, self.bus, obj_path)
> > @dbus.service.method('org.bluez.HdpAgent',
> > in_signature='o', out_signature='',
> > sender_keyword='sender')
> > def DeviceConnected(self, path, sender=None):
> > print "Connected new device %s: (sender %s)" % (path, sender)
> > @dbus.service.method('org.bluez.HdpAgent',
> > in_signature='o', out_signature='',
> > sender_keyword='sender')
> > def DeviceDisconnected(self, path, sender=None):
> > print "Device %s: disconnected (sender: %s)" % (path, sender)
> > @dbus.service.method('org.bluez.HdpAgent',
> > in_signature='oq', out_signature='',
> > sender_keyword='sender')
> > def DeletedDc(self, dev, mdlid, sender=None):
> > print "Data channel: %d deleted on dev %s (sender %s)" % \
> > (mdlid, dev, sender)
> > @dbus.service.method('org.bluez.HdpAgent',
> > in_signature='oqh', out_signature='',
> > sender_keyword='sender')
> > def CreatedDc(self, dev, mdlid, fd, sender=None):
> > print "Data channel: %d created on dev %s: fd: %d " % \
> > (mdlid, dev, fd, sender)
> >
> > hdp_obj = HDP(bus, obj_path);
> >
> > manager = dbus.Interface(bus.get_object("org.bluez", "/"),
> > "org.bluez.Manager")
> > hdp = dbus.Interface(bus.get_object("org.bluez", manager.DefaultAdapter()),
> > "org.bluez.Hdp")
> >
> > data_spec = 1
> > session_path = hdp.CreateSession(obj_path, data_spec)
> >
> > session = dbus.Interface(bus.get_object("org.bluez", session_path),
> > "org.bluez.HdpSession")
> >
> > # Configuration of the session, adding suported features
> > source_role = 0
> > mdep = session.AllocateMdep(source_role)
> > session.AddFeature(mdep, 4100, "Pulse oximeter")
> >
> > sink_role = 1 # Sink role
> > mdep2 = session.AllocateMdep(sink_role)
> > session.AddFeature(mdep2, 4111, "Scale")
> > session.AddFeature(mdep2, 4100, "Pulse oximeter sink")
> >
> > # Now start the session
> > # Starts a MCAP session and register in the SDP
> > session.Start()
> >
> > # *****************************************************************************
> > # Now, if you start the main loop, the HDP events will be notified in HDP class
> > # *****************************************************************************
> >
> > # Connect to a remote device
> > addr = "XX:XX:XX:XX:XX:XX"
>
> Where do I get this address from, and more importantly how do the
> application associate that this device supports hdp? To me bdaddr is
> meaningless in the API, we have done this mistake before and we
> learned the hard way that the API should be convenient to use and
> bdaddr hardly is.
>
> > dev_path = session.Connect(addr)
> > dev = dbus.Interface(bus.get_object("org.bluez", dev_path),
> > "org.bluez.HDPDevice")
> >
> > dcid = dev.OpenDc(rem_mdep, conf)
> > fd = dev.GetDcFd(dcid)
> >
> > # You can use the fd for write or read data.
> > # If the read/write operation fails, reconnection will be performed getting
> > # the file descriptor again
> >
> > while some_condition:
> > try:
> > os.write(fd, "some_data")
> > except:
> > fd = dev.GetDcFd(dcid) # Implicit reconeciton of dc
> >
> > dev.DeleteDc(dcid) # Close data channel
> > dev.DeleteAllDc() # Close all data channels for this mcl (device+session)
> >
> > if power_save:
> > session.Disconnect(dev_path, False)
> > # Close the connection with the remote devide for power save,
> > # Reconnections will be possible
> > else:
> > session.Disconnect(dev_path, True)
> > # Close the connection with the remote devide forever and clean state
> > # Reconnections will NOT be possible
>
> IMHO leaving the application to decide when to do save power is a bad idea.
>
Sorry, may be that notation that we used in this example is not enough
clear. Please, let me explain you this matter.
The flag provided to disconnect an MCL indicates to MCAP layer if it
should or not save the state of the MCL, what are all negotiated data
channels and their configuration for possible future reconnections.
Please, note that a quick reconnection of data channels is an important
characteristic in MCAP, it will reduce the amount of data required to
take up again a previous connection.
In addition, bluetooth layer doesn't know when it should forget the
state of an MCL because iso/ieee11073-20601 layer is transport agnostic,
it means that only data exchange protocol layer knows when a
disconnection is permanent (not the transport layer).
Please, if you are thinking in alternatives to iso/ieee11073-20601 tell
us so that we can take into count those.
I don't know if you are familiarizated with the 11073-20601 protocol, in
any case I'm going to try to summarize the importance os this issue. The
iso/ieee11073-20601 defines a finite state machine that permits to an
aaplication layer to know when a disconnection is or not permanent. You
read the HDP white paper to see more examples of when a disconnection
should not be permanent to reduce the amount of
configuration-association data traffic exchanged between agents and
manager after a reconnection takes place. A quite of 11073-20601
knowledge may be required to understand the seriousness of this
situation. If you don't permit that applications can close an MCL saving
state for future reconnections, next time that some device connects
again with a manager they should exchange association traffic to restore
tha last state in wich agent and manager were last time that the device
was connected with the manager. Please don't hesitate to ask to me if
you have more doubts, I know that it may be difficult, but I only am
trying to expose the importance of this question, of course, if you have
a better solution it will be pleasure for me to listen it.
And consider again that we are always guiding our design decision by the
iso/ieee11073-20601 requeriments for what HDP was desgined. If you are
considering another platforms, tell us please: it will be easier to
agree on trade-offs.
To conclude, due to above feature, a manager could say to the transport
layer when a MCL should be stored or not in MCAP. If you don't do that,
MCAP wont be able to distinguish when a disconnection is temporal or
permanent and it will cache it for future reconnections. It may not be a
problem if memory resource is not a concern for you and if you are not
aware about that ;)
Sorry if I'm detailing too much but I think that it is an importan
design feature that we have to take into consideration before to fix the
definitiva HDP API. We wouldn't like that it may become an the Achilles'
hell of the entire protocol stack.
> > hdp.DeleteSession(session_path)
> > # Close the session, all connections and data channels will be closed
> >
>
> Sorry but this is way too complicated for my taste, I guess the one
> shared by Elvis sometime ago has more potential because the device
> path design is reused, and so is the device driver code I suppose,
> which is much more convenient if we want to maintain this upstream.
> Instead of trying to figure out alone you 2 should be cooperating.
>
Sorry, but IMHO I think that it isn't question of choosing one or the
other API. This shuldn't become a competition. I agree with you, I think
that we should work together to get the best HDP implementation for
Linux as soon as possible. Of course, we know you have a best knowledge
about how blueZ APIs should be and we are very glad to listen to you and
other members of the community.
We have experience with HDP/MCAP/ieee11073-20601 and we sould like to
share our knowledge with you to integrate it in blueA.
We are working in a new API which takes into count all comments received
by all of you. We will send to the list during the day so all you can
see it and comment it.
Please, let me know if you have some comments / questions.
Thanks for your time and your attention.
Best regards.
Hi,
El mar, 04-05-2010 a las 17:50 +0300, Luiz Augusto von Dentz escribió:
> Hi,
>
> On Tue, May 4, 2010 at 1:54 PM, José Antonio Santos Cadenas
> <[email protected]> wrote:
> > Hi all,
> >
> > Next a simple example program in python using the api that we proposed in this thread.
> >
> > We still use the name Device but maybe a better name can be used.
> >
> > Regards.
> >
> > ----------
> > #!/usr/bin/python
> > # -*- coding: utf-8 -*-
> >
> > import dbus
> > import dbus.service
> > from dbus.mainloop.glib import DBusGMainLoop
> > import gobject
> > import os
> >
> > DBusGMainLoop(set_as_default=True)
> > loop = gobject.MainLoop()
> >
> > obj_path = "/python/tester/hdp"
> >
> > bus = dbus.SystemBus()
> >
> > # This object receives the information from the daemon
> > class HDP(dbus.service.Object):
> > def __init__(self, bus, obj_path):
> > self.bus = bus
> > dbus.service.Object.__init__(self, self.bus, obj_path)
> > @dbus.service.method('org.bluez.HdpAgent',
> > in_signature='o', out_signature='',
> > sender_keyword='sender')
> > def DeviceConnected(self, path, sender=None):
> > print "Connected new device %s: (sender %s)" % (path, sender)
> > @dbus.service.method('org.bluez.HdpAgent',
> > in_signature='o', out_signature='',
> > sender_keyword='sender')
> > def DeviceDisconnected(self, path, sender=None):
> > print "Device %s: disconnected (sender: %s)" % (path, sender)
> > @dbus.service.method('org.bluez.HdpAgent',
> > in_signature='oq', out_signature='',
> > sender_keyword='sender')
> > def DeletedDc(self, dev, mdlid, sender=None):
> > print "Data channel: %d deleted on dev %s (sender %s)" % \
> > (mdlid, dev, sender)
> > @dbus.service.method('org.bluez.HdpAgent',
> > in_signature='oqh', out_signature='',
> > sender_keyword='sender')
> > def CreatedDc(self, dev, mdlid, fd, sender=None):
> > print "Data channel: %d created on dev %s: fd: %d " % \
> > (mdlid, dev, fd, sender)
> >
> > hdp_obj = HDP(bus, obj_path);
> >
> > manager = dbus.Interface(bus.get_object("org.bluez", "/"),
> > "org.bluez.Manager")
> > hdp = dbus.Interface(bus.get_object("org.bluez", manager.DefaultAdapter()),
> > "org.bluez.Hdp")
> >
> > data_spec = 1
> > session_path = hdp.CreateSession(obj_path, data_spec)
> >
> > session = dbus.Interface(bus.get_object("org.bluez", session_path),
> > "org.bluez.HdpSession")
> >
> > # Configuration of the session, adding suported features
> > source_role = 0
> > mdep = session.AllocateMdep(source_role)
> > session.AddFeature(mdep, 4100, "Pulse oximeter")
> >
> > sink_role = 1 # Sink role
> > mdep2 = session.AllocateMdep(sink_role)
> > session.AddFeature(mdep2, 4111, "Scale")
> > session.AddFeature(mdep2, 4100, "Pulse oximeter sink")
> >
> > # Now start the session
> > # Starts a MCAP session and register in the SDP
> > session.Start()
> >
> > # *****************************************************************************
> > # Now, if you start the main loop, the HDP events will be notified in HDP class
> > # *****************************************************************************
> >
> > # Connect to a remote device
> > addr = "XX:XX:XX:XX:XX:XX"
>
> Where do I get this address from, and more importantly how do the
> application associate that this device supports hdp? To me bdaddr is
> meaningless in the API, we have done this mistake before and we
> learned the hard way that the API should be convenient to use and
> bdaddr hardly is.
>
> > dev_path = session.Connect(addr)
> > dev = dbus.Interface(bus.get_object("org.bluez", dev_path),
> > "org.bluez.HDPDevice")
> >
> > dcid = dev.OpenDc(rem_mdep, conf)
> > fd = dev.GetDcFd(dcid)
> >
> > # You can use the fd for write or read data.
> > # If the read/write operation fails, reconnection will be performed getting
> > # the file descriptor again
> >
> > while some_condition:
> > try:
> > os.write(fd, "some_data")
> > except:
> > fd = dev.GetDcFd(dcid) # Implicit reconeciton of dc
> >
> > dev.DeleteDc(dcid) # Close data channel
> > dev.DeleteAllDc() # Close all data channels for this mcl (device+session)
> >
> > if power_save:
> > session.Disconnect(dev_path, False)
> > # Close the connection with the remote devide for power save,
> > # Reconnections will be possible
> > else:
> > session.Disconnect(dev_path, True)
> > # Close the connection with the remote devide forever and clean state
> > # Reconnections will NOT be possible
>
> IMHO leaving the application to decide when to do save power is a bad idea.
Sorry, may be that notation that we used in this example is not enough
clear. Please, let me explain you this matter.
The flag provided to disconnect an MCL indicates to MCAP layer if it
should or not save the state of the MCL, what are all negotiatied data
channels and their configuration for possible future reconnections.
Please, note that a quick reconnection of data channels is an important
characteristic in MCAP, it will reduce the amount of data required to
take up again a previous connection.
In addition, bluetooth layer doesn't know when it should forget the
state of an MCL because iso/ieee11073-20601 layer is transport agnostic,
it means that only data exchange protocol layer knows when a
disconnection is permanent (not the transport layer).
Please, if you are thinking in alternatives to iso/ieee11073-20601
tell us so that we can take into account those.
I don't know if you are familiarizated with the 11073-20601 protocol, in
any case I going to try summarize the importance of this issue. The
iso/ieee 1103-20601 defines a finite state machine that permits to an
application layer to know when a disconnction is or not permament. You
can read the HDP white paper to see more examples of when disconnection
should not be permament to reduce the amount of
configuration-association data exchanged between agents and manager
after a reconnection takes place. A quite of 11073-20601 knowledge may
be required to understand the seriousness of this situation. If you
don't permit that applications can close an MCL saving state for future
reconnections, next time that some device connects again with a manager
they should exchange association traffic to restore the last state in
which agent and manager were last time that the device was connected
with the manager. Please, don't hesitate to ask to me if you have more
doubts, I know that it may be difficult, but I only am trying to expose
the importance of this question, of course, if you have a better
solution it will be pleasure for me to listen it.
And consider again that we are always guiding our design decisions by
the ieee11073- requirements for what HDP was designed. If you are
considering another platforms, tell us please: it will be easier to
agree on trade-offs.
To conclude, due to above feature, a manager could say to the transport
layer when a MCL should be stored or not in MCAP. If you don't do that,
MCAP wont be able to distinguish when a disconnection is temporal or
permanent and it will cache it for future reconnections. It may not be a
problem if memory resource is not a concern for you and if you are not
aware about that ;)
Sorry if I'm detailing too much but I think that it is an important
design feature that we have to take into consideration before to fix the
definitive HDP API. We wouldn't like that it may become an the Achilles'
heel of the entire protocol stack.
>
> > hdp.DeleteSession(session_path)
> > # Close the session, all connections and data channels will be closed
> >
>
> Sorry but this is way too complicated for my taste, I guess the one
> shared by Elvis sometime ago has more potential because the device
> path design is reused, and so is the device driver code I suppose,
> which is much more convenient if we want to maintain this upstream.
> Instead of trying to figure out alone you 2 should be cooperating.
>
Sorry, but IMHO I think that it isn't question of choosing one or the
other API. This shouldn't become a competition. I agree with you, I
think that we should work together to get the best HDP implementation
for Linux as soon as possible. Of course, we know you have a best
knowledge about how blueZ APIs should be and we are very glad to listen
to you and other members of the community.
We have experience with HDP/MCAP/ieee11073-20601 and we would like to
share our knowledge with you to integrate it in BlueZ.
We are working in a new API which takes into account all comments
received by all of you. We will send to the list during the day so all
you can see it and comment it.
Please, let me know if you have some comments / questions.
Thanks for your time and your attention.
Best regards.
Due to damn SCRUM reviews/meetings, I did not have time to make a good comparison between the two APIs, so I chose to reply directly to keep the ball rolling.
> Service org.bluez
> Interface org.bluez.HdpSession
> Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
If we could agree on a "one process application = at most one HDP service record", we would not need this /hdpX suffix at all.
An HDP session path would be interesting if other processes should be able to talk to this object too, but as far as I can see, this is something we definetively *don't* want :)
> uint8 AllocateMdep(uint8 role)
> void AddFeature(uint8 mdepid, uint16 dtype, string dscr)
> void Start()
As I have already said via IRC, I prefer "my" approach: passing a dict once with all these things at once. If the idea was to confine the MDEP handling, the dict can elide mentioning MDEPs at all, and use some application-attributed handle.
> object Connect(string btaddr)
This has been commented by von Dentz.
> Service org.bluez
> Interface org.bluez.HdpDevice
> Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/dev_XX_XX_XX_XX_XX_XX
>
> boolean Echo(array{byte})
This is something our API does not have, we would have to add.
>
> HDPAgent hierarchy
> ==================
>
> Service unique name
> Interface org.bluez.HdpAgent
> Object path freely definable
What I liked in your Agent, that "mine" does not have, is device connected/device disconnected callback. Our proposal relied on listening D-BUS signals to know about new devices (which may not implement HDP). This is very handy for the application, in particular when it wants to take the initiative and connect to the device. The rest, as you said, looks like our Agent.
> while some_condition:
> try:
> os.write(fd, "some_data")
> except:
> fd = dev.GetDcFd(dcid) # Implicit reconeciton of dc
I'd like to believe that power-saving disconneciton of a L2CAP channel and reconnection would be that simple to handle at application side. But I don't :)
Even if the fd is a L2CAP SOCK_SEQPACKET, which means that write() would be atomic for the message, the message might be still at output buffer when the connection drops. Or it might have been transmitted. The application would never know, and could not act upon.
I think that, talking specifically about this MCAP/HDP data channel reconnection stuff, we have two extremist albeit sensible approaches:
a) let the application handle it, as "my" API proposes. Application is notified about disconnection and chooses what to do, and lingering sessions must be prepared to deal with FD replacement;
b) hide it completely from the application. This includes NOT passing the L2CAP fd, but a UNIX socket fd which HDP plug-in takes care of. Or, perhaps not to use any FD passing at all: just send HDP data messages via D-BUS, and that's it.
Your API has a mix of "a" and "b": approaches: automatic reconnection but with possible mid-flight FD replacement.
Hi,
On Tue, May 4, 2010 at 1:54 PM, Jos? Antonio Santos Cadenas
<[email protected]> wrote:
> Hi all,
>
> Next a simple example program in python using the api that we proposed in this thread.
>
> We still use the name Device but maybe a better name can be used.
>
> Regards.
>
> ----------
> #!/usr/bin/python
> # -*- coding: utf-8 -*-
>
> import dbus
> import dbus.service
> from dbus.mainloop.glib import DBusGMainLoop
> import gobject
> import os
>
> DBusGMainLoop(set_as_default=True)
> loop = gobject.MainLoop()
>
> obj_path = "/python/tester/hdp"
>
> bus = dbus.SystemBus()
>
> # This object receives the information from the daemon
> class HDP(dbus.service.Object):
> ? ? ? ?def __init__(self, bus, obj_path):
> ? ? ? ? ? ? ? ?self.bus = bus
> ? ? ? ? ? ? ? ?dbus.service.Object.__init__(self, self.bus, obj_path)
> ? ? ? [email protected]('org.bluez.HdpAgent',
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? in_signature='o', out_signature='',
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? sender_keyword='sender')
> ? ? ? ?def DeviceConnected(self, path, sender=None):
> ? ? ? ? ? ? ? ?print "Connected new device %s: (sender %s)" % (path, sender)
> ? ? ? [email protected]('org.bluez.HdpAgent',
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? in_signature='o', out_signature='',
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? sender_keyword='sender')
> ? ? ? ?def DeviceDisconnected(self, path, sender=None):
> ? ? ? ? ? ? ? ?print "Device %s: disconnected (sender: %s)" % (path, sender)
> ? ? ? [email protected]('org.bluez.HdpAgent',
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? in_signature='oq', out_signature='',
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? sender_keyword='sender')
> ? ? ? ?def DeletedDc(self, dev, mdlid, sender=None):
> ? ? ? ? ? ? ? ?print "Data channel: %d deleted on dev %s (sender %s)" % \
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(mdlid, dev, sender)
> ? ? ? [email protected]('org.bluez.HdpAgent',
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? in_signature='oqh', out_signature='',
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? sender_keyword='sender')
> ? ? ? ?def CreatedDc(self, dev, mdlid, fd, sender=None):
> ? ? ? ? ? ? ? ?print "Data channel: %d created on dev %s: fd: %d " % \
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(mdlid, dev, fd, sender)
>
> hdp_obj = HDP(bus, obj_path);
>
> manager = dbus.Interface(bus.get_object("org.bluez", "/"),
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.bluez.Manager")
> hdp = dbus.Interface(bus.get_object("org.bluez", manager.DefaultAdapter()),
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.bluez.Hdp")
>
> data_spec = 1
> session_path = hdp.CreateSession(obj_path, data_spec)
>
> session = dbus.Interface(bus.get_object("org.bluez", session_path),
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.bluez.HdpSession")
>
> # Configuration of the session, adding suported features
> source_role = 0
> mdep = session.AllocateMdep(source_role)
> session.AddFeature(mdep, 4100, "Pulse oximeter")
>
> sink_role = 1 # Sink role
> mdep2 = session.AllocateMdep(sink_role)
> session.AddFeature(mdep2, 4111, "Scale")
> session.AddFeature(mdep2, 4100, "Pulse oximeter sink")
>
> # Now start the session
> # Starts a MCAP session and register in the SDP
> session.Start()
>
> # *****************************************************************************
> # Now, if you start the main loop, the HDP events will be notified in HDP class
> # *****************************************************************************
>
> # Connect to a remote device
> addr = "XX:XX:XX:XX:XX:XX"
Where do I get this address from, and more importantly how do the
application associate that this device supports hdp? To me bdaddr is
meaningless in the API, we have done this mistake before and we
learned the hard way that the API should be convenient to use and
bdaddr hardly is.
> dev_path = session.Connect(addr)
> dev = dbus.Interface(bus.get_object("org.bluez", dev_path),
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.bluez.HDPDevice")
>
> dcid = dev.OpenDc(rem_mdep, conf)
> fd = dev.GetDcFd(dcid)
>
> # You can use the fd for write or read data.
> # If the read/write operation fails, reconnection will be performed getting
> # the file descriptor again
>
> while some_condition:
> ? ? ? ?try:
> ? ? ? ? ? ? ? ?os.write(fd, "some_data")
> ? ? ? ?except:
> ? ? ? ? ? ? ? ?fd = dev.GetDcFd(dcid) # Implicit reconeciton of dc
>
> dev.DeleteDc(dcid) # Close data channel
> dev.DeleteAllDc() # Close all data channels for this mcl (device+session)
>
> if power_save:
> ? ? ? ?session.Disconnect(dev_path, False)
> ? ? ? ?# Close the connection with the remote devide for power save,
> ? ? ? ?# Reconnections will be possible
> else:
> ? ? ? ?session.Disconnect(dev_path, True)
> ? ? ? ?# Close the connection with the remote devide forever and clean state
> ? ? ? ?# Reconnections will NOT be possible
IMHO leaving the application to decide when to do save power is a bad idea.
> hdp.DeleteSession(session_path)
> # Close the session, all connections and data channels will be closed
>
Sorry but this is way too complicated for my taste, I guess the one
shared by Elvis sometime ago has more potential because the device
path design is reused, and so is the device driver code I suppose,
which is much more convenient if we want to maintain this upstream.
Instead of trying to figure out alone you 2 should be cooperating.
--
Luiz Augusto von Dentz
Computer Engineer
Hi all,
Next a simple example program in python using the api that we proposed in this thread.
We still use the name Device but maybe a better name can be used.
Regards.
----------
#!/usr/bin/python
# -*- coding: utf-8 -*-
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
import gobject
import os
DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
obj_path = "/python/tester/hdp"
bus = dbus.SystemBus()
# This object receives the information from the daemon
class HDP(dbus.service.Object):
def __init__(self, bus, obj_path):
self.bus = bus
dbus.service.Object.__init__(self, self.bus, obj_path)
@dbus.service.method('org.bluez.HdpAgent',
in_signature='o', out_signature='',
sender_keyword='sender')
def DeviceConnected(self, path, sender=None):
print "Connected new device %s: (sender %s)" % (path, sender)
@dbus.service.method('org.bluez.HdpAgent',
in_signature='o', out_signature='',
sender_keyword='sender')
def DeviceDisconnected(self, path, sender=None):
print "Device %s: disconnected (sender: %s)" % (path, sender)
@dbus.service.method('org.bluez.HdpAgent',
in_signature='oq', out_signature='',
sender_keyword='sender')
def DeletedDc(self, dev, mdlid, sender=None):
print "Data channel: %d deleted on dev %s (sender %s)" % \
(mdlid, dev, sender)
@dbus.service.method('org.bluez.HdpAgent',
in_signature='oqh', out_signature='',
sender_keyword='sender')
def CreatedDc(self, dev, mdlid, fd, sender=None):
print "Data channel: %d created on dev %s: fd: %d " % \
(mdlid, dev, fd, sender)
hdp_obj = HDP(bus, obj_path);
manager = dbus.Interface(bus.get_object("org.bluez", "/"),
"org.bluez.Manager")
hdp = dbus.Interface(bus.get_object("org.bluez", manager.DefaultAdapter()),
"org.bluez.Hdp")
data_spec = 1
session_path = hdp.CreateSession(obj_path, data_spec)
session = dbus.Interface(bus.get_object("org.bluez", session_path),
"org.bluez.HdpSession")
# Configuration of the session, adding suported features
source_role = 0
mdep = session.AllocateMdep(source_role)
session.AddFeature(mdep, 4100, "Pulse oximeter")
sink_role = 1 # Sink role
mdep2 = session.AllocateMdep(sink_role)
session.AddFeature(mdep2, 4111, "Scale")
session.AddFeature(mdep2, 4100, "Pulse oximeter sink")
# Now start the session
# Starts a MCAP session and register in the SDP
session.Start()
# *****************************************************************************
# Now, if you start the main loop, the HDP events will be notified in HDP class
# *****************************************************************************
# Connect to a remote device
addr = "XX:XX:XX:XX:XX:XX"
dev_path = session.Connect(addr)
dev = dbus.Interface(bus.get_object("org.bluez", dev_path),
"org.bluez.HDPDevice")
dcid = dev.OpenDc(rem_mdep, conf)
fd = dev.GetDcFd(dcid)
# You can use the fd for write or read data.
# If the read/write operation fails, reconnection will be performed getting
# the file descriptor again
while some_condition:
try:
os.write(fd, "some_data")
except:
fd = dev.GetDcFd(dcid) # Implicit reconeciton of dc
dev.DeleteDc(dcid) # Close data channel
dev.DeleteAllDc() # Close all data channels for this mcl (device+session)
if power_save:
session.Disconnect(dev_path, False)
# Close the connection with the remote devide for power save,
# Reconnections will be possible
else:
session.Disconnect(dev_path, True)
# Close the connection with the remote devide forever and clean state
# Reconnections will NOT be possible
hdp.DeleteSession(session_path)
# Close the session, all connections and data channels will be closed
Hi,
El Tuesday 04 May 2010 12:04:31 Luiz Augusto von Dentz escribi?:
> Hi,
>
> On Tue, May 4, 2010 at 10:55 AM, Santiago Carot-Nemesio
>
> <[email protected]> wrote:
> > Hello,
> > Next is the API wich we have been working last weeks.
> >
> > Regards.
> >
> >
> > BlueZ D-Bus HDP API description
> > ***********************************
> >
> > Authors:
> > Santiago Carot-Nemesio [email protected]
> > Jose Antonio Santos-Cadenas [email protected]
> >
> >
> > Health Device Profile hierarchy
> > ===============================
> >
> > Service org.bluez
> > Interface org.bluez.Hdp
> > Object path [variable prefix]/{hci0,hci1,...}
> >
> > Methods object CreateSession(object path, byte data_spec)
> >
> > Returns the object path for the new HDP session.
> > The path parameter is the path of the remote
> > object with the callbacks to nofity events (see
> > org.bluez.HdpAgent at the end of this document)
> > The data_spec is the data exchange specficication
> > (see section 5.2.10 of the specification document)
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> >
> > void DeleteSession(object path)
> >
> > Delete the HDP session identified by the object
> > path.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> >
> >
> > -------------------------------------------------------------------------
> > -------
> >
> > Service org.bluez
> > Interface org.bluez.HdpSession
> > Object path [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
> >
> > uint8 AllocateMdep(uint8 role)
> >
> > This method allocates a logical end point. Valids
> > values for MDEP roles are:
> > * 0x00 For source
> > * 0x01 For sink
> >
> > The return value is the allocated MDEP.
> >
> > void AddFeature(uint8 mdepid, uint16 dtype, string dscr)
> >
> > Add a new entry in the HDP supported feature list
> > with the role given in the MDEP id.
> >
> > If the new feature has the same data type as other
> > previusly added feature for the same MDEP id, the
> > old feature will be overwritten.
> >
> > void Start()
> >
> > Starts the associated MCAP layer and set up the
> > SDP registry with all supported features.
> >
> > Possible errors: org.bluez.Error.HdpError
> >
> > object Connect(string btaddr)
> >
> > Connect with the device and returns the object
> > path of the remote device.
> > To call this method, the session must be started.
> >
> > 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
> > keeped for allowing future reconnections. To call this method, the
> > session must be started.
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HdpError
> >
> > -------------------------------------------------------------------------
> > -------
> >
> > Service org.bluez
> > Interface org.bluez.HdpDevice
> > Object path [variable
> > prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/dev_XX_XX_XX_XX_XX_XX
> >
> > boolean Echo(array{byte})
> >
> > Sends an echo petition to the remote device.
> > Return True if response matches with the buffer sended. If some error is
> > detected False value is returned and the associated MCL is closed.
> >
> > uint16 OpenDc(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
> >
> > file_descriptor GetDcFd(uint16 mdlid)
> >
> > Gets a file descriptor where data can be readed or
> > writed for receive or sent by the data channel.
> > Returns the file descriptor
> >
> > Possible errors: org.bluez.Error.InvalidArguments
> > org.bluez.Error.NotFound
> > org.bluez.Error.HdpError
> >
> > void DeleteDc(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 DeleteAllDc()
> >
> > 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
> >
> > uint16 FirstRelDc()
> >
> > Returns the identificator of the first reliable
> > data channel connected for this device.
> >
> > Possible errors: org.bluez.Error.HdpError
> >
> > HDPAgent hierarchy
> > ==================
> >
> > 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 objectpath 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 CreatedDc(object path, uint16 mdlid, filedescriptor
> > fd)
> >
> > 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, the mdlid the data channel identificator and the
> > fd is the file descriptor where the data can be readed or writed.
> >
> > void DeletedDc(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.
> >
> > void DataReady(object path, uint16 mdlid, filedescriptor
> > fd)
> >
> > This method is called when there is new data that
> > can be readed in a data channel
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe
> > linux-bluetooth" in the body of a message to [email protected]
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> This sounds a little too complicated for me, my suggestion for you
> guys is to first discuss a python script for the supported use cases
> to figure out what is the best approach here,
We will prepare a program that shows this usage, we are going to send it in a
few hours. It is normal not to understand this the first time because HDP is
quite estrange.
> a tool written in C
> would be nice too, so you will notice how much logic will got
> duplicate if someone has to do the same thing as the script does. Also
> I must say that this API goes against the design of our current 4.x
> API, since it creates its own device representation.
We know, but since HDP devices are associated to a HDP session it is necessary
to create a new type (maybe the name choosed is not a good idea :), we try to
create and object that handles an mcl, a connection between two HDP sessions
in different devices)
Regards.
Hi,
On Tue, May 4, 2010 at 10:55 AM, Santiago Carot-Nemesio
<[email protected]> wrote:
> Hello,
> Next is the API wich we have been working last weeks.
>
> Regards.
>
>
> BlueZ D-Bus HDP API description
> ***********************************
>
> Authors:
> Santiago Carot-Nemesio ? ? ? ? [email protected]
> Jose Antonio Santos-Cadenas ? ? [email protected]
>
>
> Health Device Profile hierarchy
> ===============================
>
> Service ? ? ? ? org.bluez
> Interface ? ? ? org.bluez.Hdp
> Object path ? ? [variable prefix]/{hci0,hci1,...}
>
> Methods ? ? ? ? object CreateSession(object path, byte data_spec)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Returns the object path for the new HDP session.
> ? ? ? ? ? ? ? ? ? ? ? ?The path parameter is the path of the remote object
> ? ? ? ? ? ? ? ? ? ? ? ?with the callbacks to nofity events (see
> ? ? ? ? ? ? ? ? ? ? ? ?org.bluez.HdpAgent at the end of this document)
> ? ? ? ? ? ? ? ? ? ? ? ?The data_spec is the data exchange specficication
> ? ? ? ? ? ? ? ? ? ? ? ?(see section 5.2.10 of the specification document)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
>
> ? ? ? ? ? ? ? ?void DeleteSession(object path)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Delete the HDP session identified by the object path.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.NotFound
>
>
> --------------------------------------------------------------------------------
>
> Service ? ? ? ? org.bluez
> Interface ? ? ? org.bluez.HdpSession
> Object path ? ? [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}
>
> ? ? ? ? ? ? ? ?uint8 AllocateMdep(uint8 role)
>
> ? ? ? ? ? ? ? ? ? ? ? ?This method allocates a logical end point. Valids values
> ? ? ? ? ? ? ? ? ? ? ? ?for MDEP roles are:
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?* 0x00 For source
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?* 0x01 For sink
>
> ? ? ? ? ? ? ? ? ? ? ? ?The return value is the allocated MDEP.
>
> ? ? ? ? ? ? ? ?void AddFeature(uint8 mdepid, uint16 dtype, string dscr)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Add a new entry in the HDP supported feature list with
> ? ? ? ? ? ? ? ? ? ? ? ?the role given in the MDEP id.
>
> ? ? ? ? ? ? ? ? ? ? ? ?If the new feature has the same data type as other
> ? ? ? ? ? ? ? ? ? ? ? ?previusly added feature for the same MDEP id, the old
> ? ? ? ? ? ? ? ? ? ? ? ?feature will be overwritten.
>
> ? ? ? ? ? ? ? ?void Start()
>
> ? ? ? ? ? ? ? ? ? ? ? ?Starts the associated MCAP layer and set up the SDP
> ? ? ? ? ? ? ? ? ? ? ? ?registry with all supported features.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.HdpError
>
> ? ? ? ? ? ? ? ?object Connect(string btaddr)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Connect with the device and returns the object path of
> ? ? ? ? ? ? ? ? ? ? ? ?the remote device.
> ? ? ? ? ? ? ? ? ? ? ? ?To call this method, the session must be started.
>
> ? ? ? ? ? ? ? ? ? ? ? ?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 keeped for allowing future reconnections.
> ? ? ? ? ? ? ? ? ? ? ? ?To call this method, the session must be started.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.NotFound
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.HdpError
>
> --------------------------------------------------------------------------------
>
> Service ? ? ? ? org.bluez
> Interface ? ? ? org.bluez.HdpDevice
> Object path ? ? [variable prefix]/{hci0,hci1,...}/{hdp0,hdp1,...}/dev_XX_XX_XX_XX_XX_XX
>
> ? ? ? ? ? ? ? ?boolean Echo(array{byte})
>
> ? ? ? ? ? ? ? ? ? ? ? ?Sends an echo petition to the remote device. Return True
> ? ? ? ? ? ? ? ? ? ? ? ?if response matches with the buffer sended. If some error
> ? ? ? ? ? ? ? ? ? ? ? ?is detected False value is returned and the associated
> ? ? ? ? ? ? ? ? ? ? ? ?MCL is closed.
>
> ? ? ? ? ? ? ? ?uint16 OpenDc(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
>
> ? ? ? ? ? ? ? ?file_descriptor GetDcFd(uint16 mdlid)
>
> ? ? ? ? ? ? ? ? ? ? ? ?Gets a file descriptor where data can be readed or
> ? ? ? ? ? ? ? ? ? ? ? ?writed for receive or sent by the data channel.
> ? ? ? ? ? ? ? ? ? ? ? ?Returns the file descriptor
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.InvalidArguments
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.NotFound
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.bluez.Error.HdpError
>
> ? ? ? ? ? ? ? ?void DeleteDc(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 DeleteAllDc()
>
> ? ? ? ? ? ? ? ? ? ? ? ?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
>
> ? ? ? ? ? ? ? ?uint16 FirstRelDc()
>
> ? ? ? ? ? ? ? ? ? ? ? ?Returns the identificator of the first reliable data
> ? ? ? ? ? ? ? ? ? ? ? ?channel connected for this device.
>
> ? ? ? ? ? ? ? ? ? ? ? ?Possible errors: org.bluez.Error.HdpError
>
> HDPAgent hierarchy
> ==================
>
> 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 objectpath 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 CreatedDc(object path, uint16 mdlid, filedescriptor fd)
>
> ? ? ? ? ? ? ? ? ? ? ? ?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, the mdlid the data
> ? ? ? ? ? ? ? ? ? ? ? ?channel identificator and the fd is the file descriptor
> ? ? ? ? ? ? ? ? ? ? ? ?where the data can be readed or writed.
>
> ? ? ? ? ? ? ? ?void DeletedDc(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.
>
> ? ? ? ? ? ? ? ?void DataReady(object path, uint16 mdlid, filedescriptor fd)
>
> ? ? ? ? ? ? ? ? ? ? ? ?This method is called when there is new data that can be
> ? ? ? ? ? ? ? ? ? ? ? ?readed in a data channel
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>
This sounds a little too complicated for me, my suggestion for you
guys is to first discuss a python script for the supported use cases
to figure out what is the best approach here, a tool written in C
would be nice too, so you will notice how much logic will got
duplicate if someone has to do the same thing as the script does. Also
I must say that this API goes against the design of our current 4.x
API, since it creates its own device representation.
--
Luiz Augusto von Dentz
Computer Engineer