Linux bluetooth development
 help / color / mirror / Atom feed
* Re: HDP proposed API
From: José Antonio Santos Cadenas @ 2010-05-05 13:36 UTC (permalink / raw)
  To: Elvis Pfützenreuter; +Cc: Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <E956E54B-C1C5-4FCA-A677-1E549CF3B3D2@signove.com>

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 :)


^ permalink raw reply

* Re: HDP proposed API
From: Elvis Pfützenreuter @ 2010-05-05 13:22 UTC (permalink / raw)
  To: jcaden; +Cc: Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <201005051518.45474.jcaden@libresoft.es>

> 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.

^ permalink raw reply

* Re: HDP proposed API
From: José Antonio Santos Cadenas @ 2010-05-05 13:18 UTC (permalink / raw)
  To: Elvis Pfützenreuter; +Cc: Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <483C27C6-11BB-459F-AD43-F0734EE0F3A9@signove.com>

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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* bluez: lowercase hex digits in BDADDRs
From: Antonio Ospite @ 2010-05-05 13:12 UTC (permalink / raw)
  To: linux-bluetooth


[-- Attachment #1.1: Type: text/plain, Size: 1021 bytes --]

Hi,

when working on Sixaxis pairing plugin I found out a weird behavior, if
I use a BDADDR with lowercase hex digits the association can fail.

The interesting bits in bluetoothd logs are reported in the attached
diff, maybe adapter_create_device() is not robust enough?

You can reproduce this behavior using a lowercase _device_ bdaddr
into these files:
    /var/lib/bluetooth/00:03:C9:XX:XX:XX/did
    /var/lib/bluetooth/00:03:C9:XX:XX:XX/lastused
    /var/lib/bluetooth/00:03:C9:XX:XX:XX/sdp
    /var/lib/bluetooth/00:03:C9:XX:XX:XX/trusts
where 00:03:C9:XX:XX:XX is the _adapter_ bdaddr.

Can anyone else confirm that? bluez-4.64

Not a big deal, but worth reporting IMHO.

Thanks,
   Antonio

-- 
Antonio Ospite
http://ao2.it

PGP public key ID: 0x4553B001

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: bluetoothd-log-lowercase-hex-bdaddr.diff --]
[-- Type: text/x-diff; name="bluetoothd-log-lowercase-hex-bdaddr.diff", Size: 1955 bytes --]

--- bluetoothd.log.bad	2010-05-05 14:02:10.000000000 +0200
+++ bluetoothd.log.good	2010-05-05 14:12:46.000000000 +0200
@@ -134,13 +134,14 @@ bluetoothd[XXXX]: Computer is classified
 bluetoothd[XXXX]: Setting 0x000104 for major/minor device class
 bluetoothd[XXXX]: Agent registered for hci0 at :1.50:/org/bluez/agent/hci0
 bluetoothd[XXXX]: Found Sixaxis device
-bluetoothd[XXXX]: Device Bluetooth address: 00:1b:fb:xx:xx:xx
-bluetoothd[XXXX]: adapter_create_device(00:1b:fb:xx:xx:xx)
+bluetoothd[XXXX]: Device Bluetooth address: 00:1B:FB:XX:XX:XX
+bluetoothd[XXXX]: adapter_create_device(00:1B:FB:XX:XX:XX)
 bluetoothd[XXXX]: Creating device /org/bluez/XXXX/hci0/dev_00_1B_FB_XX_XX_XX
 bluetoothd[XXXX]: btd_device_ref(0x7fdd46a2bb10): ref=1
 bluetoothd[XXXX]: Probe drivers for /org/bluez/XXXX/hci0/dev_00_1B_FB_XX_XX_XX
 bluetoothd[XXXX]: hid_device_probe: path /org/bluez/XXXX/hci0/dev_00_1B_FB_XX_XX_XX
-bluetoothd[XXXX]: probe failed with driver input-hid for device /org/bluez/XXXX/hci0/dev_00_1B_FB_XX_XX_XX
+bluetoothd[XXXX]: btd_device_ref(0x7fdd46a2bb10): ref=2
+bluetoothd[XXXX]: Registered interface org.bluez.Input on path /org/bluez/XXXX/hci0/dev_00_1B_FB_XX_XX_XX
 bluetoothd[XXXX]: Adapter bdaddr 00:03:C9:XX:XX:XX
 bluetoothd[XXXX]: Master Bluetooth address: 00:03:C9:XX:XX:XX
 bluetoothd[XXXX]: New Master Bluetooth address: 00:03:C9:XX:XX:XX
@@ -148,9 +149,3 @@ bluetoothd[XXXX]: adapter_get_device(00:
 bluetoothd[XXXX]: Incoming connection on PSM 17
 bluetoothd[XXXX]: authorize request was sent for /org/bluez/XXXX/hci0/dev_00_1B_FB_XX_XX_XX
 bluetoothd[XXXX]: Incoming connection on PSM 19
-bluetoothd[XXXX]: adapter_get_device(00:1B:FB:XX:XX:XX)
-bluetoothd[XXXX]: Incoming connection on PSM 17
-bluetoothd[XXXX]: Incoming connection on PSM 19
-bluetoothd[XXXX]: adapter_get_device(00:1B:FB:XX:XX:XX)
-bluetoothd[XXXX]: Incoming connection on PSM 17
-bluetoothd[XXXX]: Incoming connection on PSM 19

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: HDP proposed API
From: Elvis Pfützenreuter @ 2010-05-05 13:10 UTC (permalink / raw)
  To: jcaden; +Cc: Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <F4813D96-A6B5-4755-ABB8-4C7D880B05D8@signove.com>


>> 
>> 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)


^ permalink raw reply

* Re: [PATCH] MCAP implementation for BlueZ
From: Santiago Carot-Nemesio @ 2010-05-05 13:01 UTC (permalink / raw)
  To: Elvis Pfützenreuter
  Cc: Gustavo F. Padovan, Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <391F3B56-3BDD-418D-9AE1-8DC00E2989A3@signove.com>

Hi,

El mié, 05-05-2010 a las 09:15 -0300, Elvis Pfützenreuter escribió:
> > 
> > We have some home-made tools and scripts for testing MCAP, if you are
> > interested i'll put them in plubic git too.
> 
> Yes, this is important, because we are about to write some MCAP tools too, and would be nice not to do the same thing again :)--

We have already set up a public git with all code that we have generated
until now. MCAP and tools are included too. There you can find a beta
implementation of HDP, but please don't consider it as definitive
implementation, it's simply for testing purpose.

We expect that thanks to this git we can work together in development
task. If you are interested in having an account, please contact with
us ;)

As we suggested yesterday in IRC, at current moment we believe that fix
HDP API and testing MCAP are the more priority task wich we have to
focus our current effort.

There is the git url:
git://193.147.51.48/git/mcap.git

Please, feel free to get the code and submit bugs and patches.

There you can see next branches:

mcap: This branch has the latest code for MCAP.

mcap_dbus: Here you can find an stupid dbus interface to play with MCAP,
note that MCAP code in this branch is older than mcap branch, it may be
interested update it if you want play with last MCAP code.

If you have some questions, please, you don't hesitate in contact with
us.

Best regards.



^ permalink raw reply

* Re: [PATCH v5] Add support for the Atheros AR300x Bluetooth Chip
From: suraj @ 2010-05-05 12:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, Luis.Rodriguez, Jothikumar.Mothilal, gfpadovan
In-Reply-To: <1272279623.11239.1.camel@atheros013-desktop>

Hi Marcel,

Can you take a look at the patch? Your review has been pending for
sometime.

On Mon, 2010-04-26 at 16:30 +0530, suraj wrote:
> Hi marcel,
> 
> On Thu, 2010-04-22 at 14:40 +0530, suraj wrote:
> > This implements the Atheros Bluetooth serial protocol to
> > support the AR300x Bluetooth chipsets.
> > The serial protocol implements enhanced power management
> > features for the AR300x chipsets. 
> > 
> > Reviewed-by: Luis R. Rodriguez <lrodriguez@atheros.com>
> > Reviewed-by: Gustavo F. Padovan <gustavo@padovan.org>
> > Signed-off-by: Suraj <suraj@atheros.com>
> > 
> > ---
> >  drivers/bluetooth/Kconfig     |   14 ++
> >  drivers/bluetooth/Makefile    |    1 +
> >  drivers/bluetooth/hci_ath.c   |  378 +++++++++++++++++++++++++++++++++++++++++
> >  drivers/bluetooth/hci_ldisc.c |    6 +
> >  drivers/bluetooth/hci_uart.h  |    8 +-
> >  5 files changed, 406 insertions(+), 1 deletions(-)
> >  create mode 100755 drivers/bluetooth/hci_ath.c
> > 
> Can you verify the patch let me know your comments? 
> 
> Regards
> Suraj
> 

^ permalink raw reply

* Re: [PATCH] MCAP implementation for BlueZ
From: Elvis Pfützenreuter @ 2010-05-05 12:15 UTC (permalink / raw)
  To: Santiago Carot-Nemesio
  Cc: Gustavo F. Padovan, Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <1273045541.2105.27.camel@mosquito>

> 
> We have some home-made tools and scripts for testing MCAP, if you are
> interested i'll put them in plubic git too.

Yes, this is important, because we are about to write some MCAP tools too, and would be nice not to do the same thing again :)

^ permalink raw reply

* Re: HDP proposed API
From: Elvis Pfützenreuter @ 2010-05-05 12:13 UTC (permalink / raw)
  To: jcaden; +Cc: Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <201005051257.20525.jcaden@libresoft.es>

> 
> 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.)


^ permalink raw reply

* Re: [PATCH] Health Device Profile API
From: José Antonio Santos Cadenas @ 2010-05-05 11:14 UTC (permalink / raw)
  To: Elvis Pfützenreuter; +Cc: Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <F76BD3E9-A0AF-434E-AE1A-17E7ED692113@signove.com>

Hello,

El Wednesday 05 May 2010 02:19:37 Elvis Pfützenreuter escribió:
> > 
> > We have provided an abstraction based in HDP sessions becasue there may
> > exist different HDP sessions running in the same host. Your API doesn't
> > seem to take in count that possibility.
> 
> Note that our adapter.RegisterRole() is bound to a client process. You can have any number of processes, each one calling adapter.RegisterRole() and publishing its own HDP profile. When a process exits, the respective profile is killed.

This is a good idea.  Sessions live while the process that creates them 
is conencted to the bus. We have included in the 0.2 version of the api
that we just sent. Please, feel free to comment.

> 
> Our adapter.RegisterRole() has two limitations that you noted.
> 
> First: only one HDP profile per client application. We feel that this is not bad.
> 
> Second: we don't provide an option NOT to publish an HDP profile. This may be a bug indeed (sinks are not required to publish HDP records, as you kindly noted yesterday via IRC;i in our API we intended to force every every HDP service provider to publish a SDP record.

We proposed a mixed API with dictionaries that in just one petition is completly configured
(you were rigth, our API could be a little bit complicated in this aspect) but that allows 
sessions without a SDP register.

> 
> > Above callbacks reflect same ideas that we have, but we propose a
> > session oriented agent (we call HdpAgent in the e-mail) that
> > applications should provide when they connect to a HdpSession. Once
> > applications are connected to a session, HDP will notify them using that
> > d-bus object.
> 
> As said above, there is an (implicit) session per client.

We are not sure if this could be a limitation in the future, may be
good to talk about this before fixing an API. There could be process thad 
needs more than one session. (i.e., a manager than wants to be perceived
by the agents as different sessions). Please, note that HDP specification
does not limit the number of session per peer nor process, so we shouldn't
close the API to this possibility so can limit the application's functionality
using HDP in Linux.

> 
> > You can't rely in remote HDP record for Source devices (it is not
> > mandatory for them to registry it).  we dont understand why you need to
> > provide a local mdep for the connection of the data channel, only the
> > remote mdep is required for do that.
> 
> Point.
> 
> > Reconnections may be transparent for applications, we believe that HDP
> > knows when a data channels is re-connected. (see our API for more
> > details)
> 
> See other email about FD, reconnection semantics. I feel we must either expose both reconnections and FDs for the application, or neither one.
> 
> >> +		array{MDLs}: array of open data channels. Mandatory
> >> +			MDLs attributes are:
> >> +			uint16 MDLId: Data channel identification
> >> +			string path: HealthData object path
> > 
> > I think that above method is not necessary because an HdpAgent always is
> > notified when a new data channel is created or destroyed, but we are
> > open to discuss.
> 
> As an occasional application writer, I'd like to have this list at hand :) Indeed the application can integrate every connection/disconnection and know the current state, but...

Sounds good to be in the API. We added it in the proposal.

Regards.


^ permalink raw reply

* Re: HDP proposed API
From: José Antonio Santos Cadenas @ 2010-05-05 10:57 UTC (permalink / raw)
  To: Elvis Pfützenreuter; +Cc: Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <414EAFF0-4D91-488E-A19B-E0B063487B7D@signove.com>

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

^ permalink raw reply

* HDP proposed api (ver 0.2)
From: José Antonio Santos Cadenas @ 2010-05-05 10:55 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org

Hi all,

Here is a new proposoal that tries to integrate all that have been comented
and proposed in the list, as well as we talked yesterday on the IRC.

There is still one thing that should be discussed, the fd passin issue. 
We think that we must talk about this and find the best way for 
the implementation as Elvis sugested.

Regards.

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

BlueZ D-Bus HDP API description
***********************************

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 nofity 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
					specficication (see section 5.2.10 of
					the specification document),
					(optional)
			  "end_points" : [{ (optional)
				"mdepid" : uint8, (optional)
				"role" : uint8, (mandatory)
				"specs" :[{ (mandatory)
					"dtype" : uint16, (mandatory)
					"description" : string, (optional)
				}]
			  }]
			}

			if "data_spec" is not set, no SDP record will be
			registerd, 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 DeleteSession(object path)

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

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

		array remote_session_properties GetRemotesSessions()

			Returns an array with the remote session_properties
			of all the visible devices.
			remote_session_properties is a dictionary like:
			[{"session_id": a_session_identification (int or string,
					 probably the SDP handler + btaddr)
			 "data_spec" : the remote data spec,
			 "end_points":
				 ["mdepid": uint8,
				  "role"  : uint8,
				  "specs" : [{
					  "dtype"	: uint16,
					  "description"	: string, (optional)
				  }]
				 ]
			}]

			Note that only remotes with a SDP record will be
			notified by this function.

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

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 keeped 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 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 (ERTM) connected for this device.

			Possible errors: org.bluez.Error.HdpError

		uint16 GetBestEfforDc()

			Returns the id of a best effort (streamming) data
			channel if any.

			Possible errors: org.bluez.Error.NotFound

		array getStatus()

			Returns an array with all the data channels available

			returned array:
			[uint16, ...]

			Possible errors: org.bluez.Error.NotFound

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 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

		void RemoteSession(dict remote_session_properties)

			This methos is called when a new session is discorevered
			in a remote device. See Hdp.GetRemotes to know how the
			dictionary is formed.

^ permalink raw reply

* Re: HDP proposed API
From: Santiago Carot-Nemesio @ 2010-05-05 10:53 UTC (permalink / raw)
  Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <p2h2d5a2c101005040750n6c5ea46dk4722b6ca3bea5543@mail.gmail.com>

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
> <jcaden@libresoft.es> 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.


^ permalink raw reply

* Re: Detect invalid (i.e. non-UTF-8) device names and fix them during initialization phase
From: Fabian Greffrath @ 2010-05-05 10:27 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <4BE14458.1020908@greffrath.com>

[-- Attachment #1: Type: text/plain, Size: 356 bytes --]

Dear Bluez list,

I am sorry, I know this is the worst way to start getting in touch 
with a software project, but I accidently attached the wrong patch to 
my previous email. It's configure_device() that must be patched. 
Please find a corrected patch attached (it has been written against 
bluez 4.63 but applies perfectly against 4.64).

Cheers,
Fabian

[-- Attachment #2: fix_invalid_non-utf-8_device_name.patch --]
[-- Type: text/x-diff, Size: 1106 bytes --]

--- bluez-4.63.orig/plugins/hciops.c
+++ bluez-4.63/plugins/hciops.c
@@ -81,6 +81,7 @@ static void configure_device(int index)
 	struct hci_dev_info di;
 	uint16_t policy;
 	int dd, err;
+	char name[249];
 
 	if (hci_devinfo(index, &di) < 0)
 		return;
@@ -96,6 +97,30 @@ static void configure_device(int index)
 		return;
 	}
 
+	if (hci_read_local_name(dd, sizeof(name), name, 1000) < 0) {
+		error("Can't read local name on hci%d: %s (%d)\n",
+						index, strerror(errno), errno);
+		return;
+	}
+
+	name[248] = '\0';
+
+	if (!g_utf8_validate(name, -1, NULL)) {
+		char *utf8_name;
+
+		utf8_name = g_convert(name, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
+		if (utf8_name) {
+			debug("Fix invalid non-UTF-8 device name \"%s\" on hci%d to \"%s\"",
+							name, index, utf8_name);
+			if (hci_write_local_name(dd, utf8_name, 2000) < 0) {
+				error("Can't change local name on hci%d: %s (%d)\n",
+								index, strerror(errno), errno);
+				return;
+			}
+			g_free(utf8_name);
+		}
+	}
+
 	/* Set page timeout */
 	if ((main_opts.flags & (1 << HCID_SET_PAGETO))) {
 		write_page_timeout_cp cp;

^ permalink raw reply

* Re: HDP proposed API
From: Santiago Carot-Nemesio @ 2010-05-05 10:11 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: jcaden, linux-bluetooth@vger.kernel.org
In-Reply-To: <p2h2d5a2c101005040750n6c5ea46dk4722b6ca3bea5543@mail.gmail.com>

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
> <jcaden@libresoft.es> 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.



^ permalink raw reply

* Detect invalid (i.e. non-UTF-8) device names and fix them during initialization phase
From: Fabian Greffrath @ 2010-05-05 10:11 UTC (permalink / raw)
  To: linux-bluetooth

[-- Attachment #1: Type: text/plain, Size: 1822 bytes --]

Dear Bluez developers,

recently I have experienced a problem with one of my USB bluetooth 
dongles: Whenever I plugged it into an USB port, the kernel detected 
the device (i.e. reasonable output in dmesg) and the correct kernel 
module (i.e. btusb) was loaded, but bluez frontends like 
gnome-bluetooth could still not activate the device. The bug that I 
reported against this software can be found at: 
<https://bugzilla.gnome.org/show_bug.cgi?id=617050>.

It turned out that my USB dongle was the culprit, since it had an 
invalid default device name that contained non-UTF-8 characters, as 
reported by 'hciconfig -a'. When I changed the device name to 
something reasonable via e.g. 'hciconfig hci0 name foobar', I had to 
*restart* the bluetoothd daemon afterwards in order to get everything 
working as expected. However, when I unplugged the USB dongle and 
plugged it back in, the device name was reset to the defective default 
again and I had to repeat this procedure.

Since I found it unreasonable to be forced to manually change the 
device name and restart the daemon each and every time I plugged my 
USB dongle in, I wanted a solution that detected a faulty device name 
string during the device initialization phase and instantly fixed it 
by writing a converted string back to the device. The attached patch 
does exact this and makes my USB dongle work out-of-the-box, despite 
its defective default device name.

Please review the patch for integration into Bluez.

Cheers,
Fabian

PS: There is still one open question that I would like to address: 
Since I am going to print both the faulty and the fixed device name 
strings to stderr via debug(), should I make sure the strings do not 
contain any ASCII control characters prior to that? At least this is 
what is done in tools/hciconfig.c:442.


[-- Attachment #2: fix_invalid_non-utf-8_device_name.patch --]
[-- Type: text/x-diff, Size: 1064 bytes --]

--- bluez-4.64.orig/plugins/hciops.c
+++ bluez-4.64/plugins/hciops.c
@@ -119,6 +119,7 @@ static void init_device(int index)
 	struct hci_dev_info di;
 	pid_t pid;
 	int dd, err;
+	char name[249];
 
 	/* Do initialization in the separate process */
 	pid = fork();
@@ -143,6 +144,30 @@ static void init_device(int index)
 		exit(1);
 	}
 
+	if (hci_read_local_name(dd, sizeof(name), name, 1000) < 0) {
+		error("Can't read local name on hci%d: %s (%d)\n",
+						index, strerror(errno), errno);
+		exit(1);
+	}
+
+	name[248] = '\0';
+
+	if (!g_utf8_validate(name, -1, NULL)) {
+		char *utf8_name;
+
+		utf8_name = g_convert(name, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
+		if (utf8_name) {
+			debug("Fix invalid non-UTF-8 device name \"%s\" on hci%d to \"%s\"",
+							name, index, utf8_name);
+			if (hci_write_local_name(dd, utf8_name, 2000) < 0) {
+				error("Can't change local name on hci%d: %s (%d)\n",
+								index, strerror(errno), errno);
+				exit(1);
+			}
+			g_free(utf8_name);
+		}
+	}
+
 	memset(&dr, 0, sizeof(dr));
 	dr.dev_id = index;
 

^ permalink raw reply

* Re: [PATCH] MCAP implementation for BlueZ
From: Santiago Carot-Nemesio @ 2010-05-05  7:45 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <20100504200657.GC26732@vigoh>

Hi,

El mar, 04-05-2010 a las 17:06 -0300, Gustavo F. Padovan escribió:
> Hi Santiago,
> 
> * Santiago Carot-Nemesio <sancane@gmail.com> [2010-05-04 10:43:15 +0200]:
> 
> > This patch enables MCAP in BlueZ.
> > Current implementation provides support for standard op. codes. Clock
> > Synchronization protocol is not yet supported.
> > ---
> >  Makefile.am     |   11 +-
> >  acinclude.m4    |    6 +
> >  mcap/mcap.c     | 2146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  mcap/mcap.h     |  176 +++++
> >  mcap/mcap_lib.h |  162 +++++
> >  5 files changed, 2500 insertions(+), 1 deletions(-)
> >  create mode 100644 mcap/mcap.c
> >  create mode 100644 mcap/mcap.h
> >  create mode 100644 mcap/mcap_lib.h
> 
> 2500+ lines is too big for review. MCAP is way complicated to
> understand completely. I suggest you to split this patch and send
> smaller ones for each feature of MCAP you implement, then we can review
> each piece and not at once.

You are rigth, I know it, but please, remember that it is a new
specification implemented from scratch, there were not any similar
profile in BlueZ wich i could take as reference point. I have done a lot
of changes in the architecture, interfaces, etc. until I found what IMHO
is a presentable implementation.
Sending patches with a non definitive implementation could have full of
noise the mailing list, I think that its better to have a base
implementation to discuss about.

I'm thinking that it may be interesting put my git in public to
everybody can see all development process, commit-by-commit. I have not
problem in doing that.

> 
> Also a MCAP test tool would be interesting to help on the
> review/merge/qualification process. Do you guys have one? Or are you
> planning to do one?

We have some home-made tools and scripts for testing MCAP, if you are
interested i'll put them in plubic git too.

Thanks in advance for your feedback.

Best regards.


^ permalink raw reply

* RE: Modem emulator and DUN server side for oFono and BlueZ
From: Zhang, Zhenhua @ 2010-05-05  0:57 UTC (permalink / raw)
  To: ofono@ofono.org; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <20100430080319.GA11712@vigoh>

Hi Padovan,

Gustavo F. Padovan wrote:
> Hi Zhenhua,
> 
> * Zhang, Zhenhua <zhenhua.zhang@intel.com> [2010-04-27 15:53:54
> +0800]: 
> 
>> Hi,
>> 
>> I am now working on modem emulator and one usage is for DUN
> server role. Since Padovan is working on client role, it's
> good to share my rough thinking for server side
> implementation. Here are the simple steps I have:
>> 
>> 1. Create an oFono emulator atom in oFono. It's the emulator
> manager that could create DUN, HFP AG or SPP type emulators.
> It exposes dbus methods like CreateEmulator, DestroyEmulator,
> GetProperty, etc.
>> 
>> 2. DUN agent server in BlueZ watch oFono and call
> CreateEmulator and pass the file descriptor to oFono. This
> server could further implement HFP AG and SPP connection.
> 
> 
> Shouldn't the emulator register itself on the BlueZ agent server?

It's fine to register the emulator like HFP client. In this way, we might able to share the agent with DUN server as well. Thanks.

> 
> --
> Gustavo F. Padovan
> http://padovan.org
> _______________________________________________
> ofono mailing list
> ofono@ofono.org
> http://lists.ofono.org/listinfo/ofono



Regards,
Zhenhua


^ permalink raw reply

* Re: HDP proposed API
From: Elvis Pfützenreuter @ 2010-05-05  0:32 UTC (permalink / raw)
  To: Santiago Carot-Nemesio; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1272959741.2182.123.camel@mosquito>

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.

^ permalink raw reply

* Re: [PATCH] Health Device Profile API
From: Elvis Pfützenreuter @ 2010-05-05  0:19 UTC (permalink / raw)
  To: Santiago Carot-Nemesio; +Cc: linux-bluetooth
In-Reply-To: <1272959405.2182.117.camel@mosquito>

> 
> We have provided an abstraction based in HDP sessions becasue there may
> exist different HDP sessions running in the same host. Your API doesn't
> seem to take in count that possibility.

Note that our adapter.RegisterRole() is bound to a client process. You can have any number of processes, each one calling adapter.RegisterRole() and publishing its own HDP profile. When a process exits, the respective profile is killed.

Our adapter.RegisterRole() has two limitations that you noted.

First: only one HDP profile per client application. We feel that this is not bad.

Second: we don't provide an option NOT to publish an HDP profile. This may be a bug indeed (sinks are not required to publish HDP records, as you kindly noted yesterday via IRC;i in our API we intended to force every every HDP service provider to publish a SDP record.

> Above callbacks reflect same ideas that we have, but we propose a
> session oriented agent (we call HdpAgent in the e-mail) that
> applications should provide when they connect to a HdpSession. Once
> applications are connected to a session, HDP will notify them using that
> d-bus object.

As said above, there is an (implicit) session per client.

> You can't rely in remote HDP record for Source devices (it is not
> mandatory for them to registry it).  we dont understand why you need to
> provide a local mdep for the connection of the data channel, only the
> remote mdep is required for do that.

Point.

> Reconnections may be transparent for applications, we believe that HDP
> knows when a data channels is re-connected. (see our API for more
> details)

See other email about FD, reconnection semantics. I feel we must either expose both reconnections and FDs for the application, or neither one.

>> +		array{MDLs}: array of open data channels. Mandatory
>> +			MDLs attributes are:
>> +			uint16 MDLId: Data channel identification
>> +			string path: HealthData object path
> 
> I think that above method is not necessary because an HdpAgent always is
> notified when a new data channel is created or destroyed, but we are
> open to discuss.

As an occasional application writer, I'd like to have this list at hand :) Indeed the application can integrate every connection/disconnection and know the current state, but...


^ permalink raw reply

* Re: HDP proposed API
From: Elvis Pfützenreuter @ 2010-05-05  0:07 UTC (permalink / raw)
  To: jcaden; +Cc: Santiago Carot-Nemesio, linux-bluetooth
In-Reply-To: <201005041254.37990.jcaden@libresoft.es>


> 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.

^ permalink raw reply

* Re: [PATCH] MCAP implementation for BlueZ
From: Gustavo F. Padovan @ 2010-05-04 20:06 UTC (permalink / raw)
  To: Santiago Carot-Nemesio; +Cc: linux-bluetooth
In-Reply-To: <1272962595-4108-1-git-send-email-sancane@gmail.com>

Hi Santiago,

* Santiago Carot-Nemesio <sancane@gmail.com> [2010-05-04 10:43:15 +0200]:

> This patch enables MCAP in BlueZ.
> Current implementation provides support for standard op. codes. Clock
> Synchronization protocol is not yet supported.
> ---
>  Makefile.am     |   11 +-
>  acinclude.m4    |    6 +
>  mcap/mcap.c     | 2146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  mcap/mcap.h     |  176 +++++
>  mcap/mcap_lib.h |  162 +++++
>  5 files changed, 2500 insertions(+), 1 deletions(-)
>  create mode 100644 mcap/mcap.c
>  create mode 100644 mcap/mcap.h
>  create mode 100644 mcap/mcap_lib.h

2500+ lines is too big for review. MCAP is way complicated to
understand completely. I suggest you to split this patch and send
smaller ones for each feature of MCAP you implement, then we can review
each piece and not at once.

Also a MCAP test tool would be interesting to help on the
review/merge/qualification process. Do you guys have one? Or are you
planning to do one?


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

^ permalink raw reply

* Re: HDP proposed API
From: Luiz Augusto von Dentz @ 2010-05-04 14:50 UTC (permalink / raw)
  To: jcaden; +Cc: Santiago Carot-Nemesio, linux-bluetooth@vger.kernel.org
In-Reply-To: <201005041254.37990.jcaden@libresoft.es>

Hi,

On Tue, May 4, 2010 at 1:54 PM, José Antonio Santos Cadenas
<jcaden@libresoft.es> 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.

> 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

^ permalink raw reply

* RE: How to use a2dp avrcp controls
From: John Frankish @ 2010-05-04 11:53 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <44EE5C37ADC36343B0625A05DD408C4850DA702DD0@CHEXMB-01.global.atheros.com>



> -----Original Message-----
> From: Vikram Kandukuri [mailto:Vikram.Kandukuri@Atheros.com]
> Sent: Tuesday, 04 May, 2010 15:00
> To: John Frankish
> Subject: RE: How to use a2dp avrcp controls
> 
> Hi John,
> Hi,
> 
> Although I can pair with and play music to a set of a2dp headphones
> without problems, I cannot figure out how to enable the "track skip"
> and similar remote controls on the headphones.
> 
> Is this something that can be done easily - if so, could somebody point
> me to the documentation?
> 
> If not, are there music playing applications (rhythmbox or similar)
> that already enable the remote controls on headphones?
> 
> Note that I see appropriate echoes in dmesg when I press the "track
> skip" button, so the message is getting from the headphones to my
> laptop...
> 
> Thanks
> John
> 
> >>uinput module is responsible for AVRCP ; so do modprobe to uinput. It
> will >>work
> 
> vikram
----

Sorry, I should have mentioned that, but the uinput module is loaded (I don't get the messages in dmesg without that), but the tracks do not skip in rhythmbox or xmms

$ dmesg
...
[press track skip]
input: 00:1B:66:00:31:88 as /devices/virtual/input/input11

John


^ permalink raw reply

* Re: HDP proposed API
From: José Antonio Santos Cadenas @ 2010-05-04 10:54 UTC (permalink / raw)
  To: Luiz Augusto von Dentz
  Cc: Santiago Carot-Nemesio, linux-bluetooth@vger.kernel.org
In-Reply-To: <m2u2d5a2c101005040304ke238595n54b8584dd78b8f37@mail.gmail.com>

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

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox