2010-08-02 14:51:22

by Davide Pesavento

[permalink] [raw]
Subject: Getting link quality or RSSI

Hello,

I'm writing an application to retrieve the current link quality (or
RSSI) between my laptop's Bluetooth adapter and a specific remote
device (my mobile phone). In order to do that I'm of course using the
latest version of BlueZ, but I've encountered several issues so far.

The dbus API exposed by bluetoothd doesn't have any GetRSSI or
GetLinkQuality methods. Would it be possible to export these methods
in the public API?

Then I looked at the bluetooth HCI library that comes with bluez.
First of all, is there any reasons why it's totally undocumented?
Anyway, I noticed hci_read_link_quality() and hci_read_rssi() in
hci_lib.h and tried using them. Since they seem to require an
established connection, I also used hci_create_connection(). However I
soon discovered that creating a connection requires root privileges,
is that right or did I do something wrong?

Furthermore, even when running the program as root, the connection
gets established only for a few seconds and then it disconnects from
the remote device. Is this behaviour intended? How can I specify to
keep the connection alive indefinitely?

Thanks a lot in advance for any help!

Regards,
Davide


2010-08-02 22:58:42

by Davide Pesavento

[permalink] [raw]
Subject: Re: Getting link quality or RSSI

On Tue, Aug 3, 2010 at 00:09, Marcel Holtmann <[email protected]> wrote:
> Hi Davide,
>
>> >> >> I'm writing an application to retrieve the current link quality (or
>> >> >> RSSI) between my laptop's Bluetooth adapter and a specific remote
>> >> >> device (my mobile phone). In order to do that I'm of course using the
>> >> >> latest version of BlueZ, but I've encountered several issues so far.
>> >> >>
>> >> >> The dbus API exposed by bluetoothd doesn't have any GetRSSI or
>> >> >> GetLinkQuality methods. Would it be possible to export these methods
>> >> >> in the public API?
>> >> >
>> >> > the link quality is vendor specific according to the specification and
>> >> > the RSSI of an existing connection is rather useless. So we don't bother
>> >> > to export those.
>> >> >
>> >>
>> >> Does this mean you're going to reject a patch which adds those methods
>> >> to the dbus API?
>> >
>> > constantly polling them via D-Bus, yes I would reject such a patch. To
>> > make this proper you would need a kernel patch first that polls the RSSI
>> > and/or link quality when a ACL is established and not in power saving
>> > mode. Then you need to use this data to send async signals via D-Bus.
>> >
>> > I have done both, let me assure you that some chips don't provide proper
>> > RSSI values. Then link quality is vendor specific and we can't do
>> > anything real useful with it (except it is a CSR chip). So I have don't
>> > the whole exercise and figured out that it is rather useless feature of
>> > Bluetooth.
>> >
>> >> >> Then I looked at the bluetooth HCI library that comes with bluez.
>> >> >> First of all, is there any reasons why it's totally undocumented?
>> >> >> Anyway, I noticed hci_read_link_quality() and hci_read_rssi() in
>> >> >> hci_lib.h and tried using them. Since they seem to require an
>> >> >> established connection, I also used hci_create_connection(). However I
>> >> >> soon discovered that creating a connection requires root privileges,
>> >> >> is that right or did I do something wrong?
>> >> >>
>> >> >> Furthermore, even when running the program as root, the connection
>> >> >> gets established only for a few seconds and then it disconnects from
>> >> >> the remote device. Is this behaviour intended? How can I specify to
>> >> >> keep the connection alive indefinitely?
>> >> >
>> >> > If you don't have an active connection that is used, the kernel will
>> >> > terminate any idle ones. So using hcitool for this is rather pointless
>> >> > unless you have a profile already using that connection.
>> >> >
>> >>
>> >> "using a connection" means pushing some traffic over it?
>> >> Is there no other way to prevent the kernel from terminating idle connections?
>> >
>> > You don't need to transfer data, but you need a reference count on the
>> > ACL link. And that can only happen by opening a L2CAP socket.
>> >
>> >> By the way, I've read in the Bluetooth specs that there exists an
>> >> extended inquiry mode which allows the host to gather the RSSI of
>> >> available devices too. How can I perform such kind of inquiry from my
>> >> application using bluez?
>> >
>> > Nice idea, but RSSI from inquiry result and RSSI from an ACL are not the
>> > same. You can't compare them properly to make sense out of them. I tried
>> > that as well. Please read the specification again to see their
>> > difference when it comes to power control on the low level baseband.
>> >
>>
>> Well, that's a non-issue. If I decide to go that way, I'll only use
>> RSSI from inquiry results so I don't need to compare RSSI values
>> coming from different sources.
>> How could I trigger an inquiry with RSSI reporting?
>
> that is one by default if the hardware supports it.
>

Very nice! I quickly checked using qdbusviewer and it does seem to
work. Thanks a lot for you help!

Regards,
Davide

2010-08-02 22:09:49

by Marcel Holtmann

[permalink] [raw]
Subject: Re: Getting link quality or RSSI

Hi Davide,

> >> >> I'm writing an application to retrieve the current link quality (or
> >> >> RSSI) between my laptop's Bluetooth adapter and a specific remote
> >> >> device (my mobile phone). In order to do that I'm of course using the
> >> >> latest version of BlueZ, but I've encountered several issues so far.
> >> >>
> >> >> The dbus API exposed by bluetoothd doesn't have any GetRSSI or
> >> >> GetLinkQuality methods. Would it be possible to export these methods
> >> >> in the public API?
> >> >
> >> > the link quality is vendor specific according to the specification and
> >> > the RSSI of an existing connection is rather useless. So we don't bother
> >> > to export those.
> >> >
> >>
> >> Does this mean you're going to reject a patch which adds those methods
> >> to the dbus API?
> >
> > constantly polling them via D-Bus, yes I would reject such a patch. To
> > make this proper you would need a kernel patch first that polls the RSSI
> > and/or link quality when a ACL is established and not in power saving
> > mode. Then you need to use this data to send async signals via D-Bus.
> >
> > I have done both, let me assure you that some chips don't provide proper
> > RSSI values. Then link quality is vendor specific and we can't do
> > anything real useful with it (except it is a CSR chip). So I have don't
> > the whole exercise and figured out that it is rather useless feature of
> > Bluetooth.
> >
> >> >> Then I looked at the bluetooth HCI library that comes with bluez.
> >> >> First of all, is there any reasons why it's totally undocumented?
> >> >> Anyway, I noticed hci_read_link_quality() and hci_read_rssi() in
> >> >> hci_lib.h and tried using them. Since they seem to require an
> >> >> established connection, I also used hci_create_connection(). However I
> >> >> soon discovered that creating a connection requires root privileges,
> >> >> is that right or did I do something wrong?
> >> >>
> >> >> Furthermore, even when running the program as root, the connection
> >> >> gets established only for a few seconds and then it disconnects from
> >> >> the remote device. Is this behaviour intended? How can I specify to
> >> >> keep the connection alive indefinitely?
> >> >
> >> > If you don't have an active connection that is used, the kernel will
> >> > terminate any idle ones. So using hcitool for this is rather pointless
> >> > unless you have a profile already using that connection.
> >> >
> >>
> >> "using a connection" means pushing some traffic over it?
> >> Is there no other way to prevent the kernel from terminating idle connections?
> >
> > You don't need to transfer data, but you need a reference count on the
> > ACL link. And that can only happen by opening a L2CAP socket.
> >
> >> By the way, I've read in the Bluetooth specs that there exists an
> >> extended inquiry mode which allows the host to gather the RSSI of
> >> available devices too. How can I perform such kind of inquiry from my
> >> application using bluez?
> >
> > Nice idea, but RSSI from inquiry result and RSSI from an ACL are not the
> > same. You can't compare them properly to make sense out of them. I tried
> > that as well. Please read the specification again to see their
> > difference when it comes to power control on the low level baseband.
> >
>
> Well, that's a non-issue. If I decide to go that way, I'll only use
> RSSI from inquiry results so I don't need to compare RSSI values
> coming from different sources.
> How could I trigger an inquiry with RSSI reporting?

that is one by default if the hardware supports it.

Regards

Marcel



2010-08-02 22:07:19

by Davide Pesavento

[permalink] [raw]
Subject: Re: Getting link quality or RSSI

On Mon, Aug 2, 2010 at 20:58, Marcel Holtmann <[email protected]> wrote:
> Hi Davide,
>
>> >> I'm writing an application to retrieve the current link quality (or
>> >> RSSI) between my laptop's Bluetooth adapter and a specific remote
>> >> device (my mobile phone). In order to do that I'm of course using the
>> >> latest version of BlueZ, but I've encountered several issues so far.
>> >>
>> >> The dbus API exposed by bluetoothd doesn't have any GetRSSI or
>> >> GetLinkQuality methods. Would it be possible to export these methods
>> >> in the public API?
>> >
>> > the link quality is vendor specific according to the specification and
>> > the RSSI of an existing connection is rather useless. So we don't bother
>> > to export those.
>> >
>>
>> Does this mean you're going to reject a patch which adds those methods
>> to the dbus API?
>
> constantly polling them via D-Bus, yes I would reject such a patch. To
> make this proper you would need a kernel patch first that polls the RSSI
> and/or link quality when a ACL is established and not in power saving
> mode. Then you need to use this data to send async signals via D-Bus.
>
> I have done both, let me assure you that some chips don't provide proper
> RSSI values. Then link quality is vendor specific and we can't do
> anything real useful with it (except it is a CSR chip). So I have don't
> the whole exercise and figured out that it is rather useless feature of
> Bluetooth.
>
>> >> Then I looked at the bluetooth HCI library that comes with bluez.
>> >> First of all, is there any reasons why it's totally undocumented?
>> >> Anyway, I noticed hci_read_link_quality() and hci_read_rssi() in
>> >> hci_lib.h and tried using them. Since they seem to require an
>> >> established connection, I also used hci_create_connection(). However I
>> >> soon discovered that creating a connection requires root privileges,
>> >> is that right or did I do something wrong?
>> >>
>> >> Furthermore, even when running the program as root, the connection
>> >> gets established only for a few seconds and then it disconnects from
>> >> the remote device. Is this behaviour intended? How can I specify to
>> >> keep the connection alive indefinitely?
>> >
>> > If you don't have an active connection that is used, the kernel will
>> > terminate any idle ones. So using hcitool for this is rather pointless
>> > unless you have a profile already using that connection.
>> >
>>
>> "using a connection" means pushing some traffic over it?
>> Is there no other way to prevent the kernel from terminating idle connections?
>
> You don't need to transfer data, but you need a reference count on the
> ACL link. And that can only happen by opening a L2CAP socket.
>
>> By the way, I've read in the Bluetooth specs that there exists an
>> extended inquiry mode which allows the host to gather the RSSI of
>> available devices too. How can I perform such kind of inquiry from my
>> application using bluez?
>
> Nice idea, but RSSI from inquiry result and RSSI from an ACL are not the
> same. You can't compare them properly to make sense out of them. I tried
> that as well. Please read the specification again to see their
> difference when it comes to power control on the low level baseband.
>

Well, that's a non-issue. If I decide to go that way, I'll only use
RSSI from inquiry results so I don't need to compare RSSI values
coming from different sources.
How could I trigger an inquiry with RSSI reporting?

Thanks,
Davide

2010-08-02 21:55:19

by Davide Pesavento

[permalink] [raw]
Subject: Re: Getting link quality or RSSI

On Mon, Aug 2, 2010 at 20:12, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi,
>
> On Mon, Aug 2, 2010 at 7:34 PM, Davide Pesavento <[email protected]> wrote:
>> "using a connection" means pushing some traffic over it?
>> Is there no other way to prevent the kernel from terminating idle connections?
>
> You should really think twice if you are creating a connection just to
> see the link quality, it really doesn't worth.
>

OK, thanks for the advice.

>> By the way, I've read in the Bluetooth specs that there exists an
>> extended inquiry mode which allows the host to gather the RSSI of
>> available devices too. How can I perform such kind of inquiry from my
>> application using bluez?
>
> We do expose the RSSI when doing the device discovery, take a look at
> DeviceFound documentation under doc/adapter-api.txt, as for link
> quality maybe it can be made as a Property of device object, but as
> Marcel said this is vendor specific so the use cases are very limited.
> In the other hand it would be very nice if ui could show the link
> quality and we could possible use it to route the audio back to the
> speaker if the connection quality is too low.
>

What I'm trying to accomplish is indeed similar to that: I'd like to
re-route some audio streams based on RSSI or link quality.

>
> --
> Luiz Augusto von Dentz
> Computer Engineer
>

Regards,
Davide

2010-08-02 18:58:02

by Marcel Holtmann

[permalink] [raw]
Subject: Re: Getting link quality or RSSI

Hi Davide,

> >> I'm writing an application to retrieve the current link quality (or
> >> RSSI) between my laptop's Bluetooth adapter and a specific remote
> >> device (my mobile phone). In order to do that I'm of course using the
> >> latest version of BlueZ, but I've encountered several issues so far.
> >>
> >> The dbus API exposed by bluetoothd doesn't have any GetRSSI or
> >> GetLinkQuality methods. Would it be possible to export these methods
> >> in the public API?
> >
> > the link quality is vendor specific according to the specification and
> > the RSSI of an existing connection is rather useless. So we don't bother
> > to export those.
> >
>
> Does this mean you're going to reject a patch which adds those methods
> to the dbus API?

constantly polling them via D-Bus, yes I would reject such a patch. To
make this proper you would need a kernel patch first that polls the RSSI
and/or link quality when a ACL is established and not in power saving
mode. Then you need to use this data to send async signals via D-Bus.

I have done both, let me assure you that some chips don't provide proper
RSSI values. Then link quality is vendor specific and we can't do
anything real useful with it (except it is a CSR chip). So I have don't
the whole exercise and figured out that it is rather useless feature of
Bluetooth.

> >> Then I looked at the bluetooth HCI library that comes with bluez.
> >> First of all, is there any reasons why it's totally undocumented?
> >> Anyway, I noticed hci_read_link_quality() and hci_read_rssi() in
> >> hci_lib.h and tried using them. Since they seem to require an
> >> established connection, I also used hci_create_connection(). However I
> >> soon discovered that creating a connection requires root privileges,
> >> is that right or did I do something wrong?
> >>
> >> Furthermore, even when running the program as root, the connection
> >> gets established only for a few seconds and then it disconnects from
> >> the remote device. Is this behaviour intended? How can I specify to
> >> keep the connection alive indefinitely?
> >
> > If you don't have an active connection that is used, the kernel will
> > terminate any idle ones. So using hcitool for this is rather pointless
> > unless you have a profile already using that connection.
> >
>
> "using a connection" means pushing some traffic over it?
> Is there no other way to prevent the kernel from terminating idle connections?

You don't need to transfer data, but you need a reference count on the
ACL link. And that can only happen by opening a L2CAP socket.

> By the way, I've read in the Bluetooth specs that there exists an
> extended inquiry mode which allows the host to gather the RSSI of
> available devices too. How can I perform such kind of inquiry from my
> application using bluez?

Nice idea, but RSSI from inquiry result and RSSI from an ACL are not the
same. You can't compare them properly to make sense out of them. I tried
that as well. Please read the specification again to see their
difference when it comes to power control on the low level baseband.

Regards

Marcel



2010-08-02 18:12:53

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: Getting link quality or RSSI

Hi,

On Mon, Aug 2, 2010 at 7:34 PM, Davide Pesavento <[email protected]> wrote:
> "using a connection" means pushing some traffic over it?
> Is there no other way to prevent the kernel from terminating idle connections?

You should really think twice if you are creating a connection just to
see the link quality, it really doesn't worth.

> By the way, I've read in the Bluetooth specs that there exists an
> extended inquiry mode which allows the host to gather the RSSI of
> available devices too. How can I perform such kind of inquiry from my
> application using bluez?

We do expose the RSSI when doing the device discovery, take a look at
DeviceFound documentation under doc/adapter-api.txt, as for link
quality maybe it can be made as a Property of device object, but as
Marcel said this is vendor specific so the use cases are very limited.
In the other hand it would be very nice if ui could show the link
quality and we could possible use it to route the audio back to the
speaker if the connection quality is too low.


--
Luiz Augusto von Dentz
Computer Engineer

2010-08-02 16:34:10

by Davide Pesavento

[permalink] [raw]
Subject: Re: Getting link quality or RSSI

On Mon, Aug 2, 2010 at 17:56, Marcel Holtmann <[email protected]> wrote:
> Hi Davide,
>
>> I'm writing an application to retrieve the current link quality (or
>> RSSI) between my laptop's Bluetooth adapter and a specific remote
>> device (my mobile phone). In order to do that I'm of course using the
>> latest version of BlueZ, but I've encountered several issues so far.
>>
>> The dbus API exposed by bluetoothd doesn't have any GetRSSI or
>> GetLinkQuality methods. Would it be possible to export these methods
>> in the public API?
>
> the link quality is vendor specific according to the specification and
> the RSSI of an existing connection is rather useless. So we don't bother
> to export those.
>

Does this mean you're going to reject a patch which adds those methods
to the dbus API?

>> Then I looked at the bluetooth HCI library that comes with bluez.
>> First of all, is there any reasons why it's totally undocumented?
>> Anyway, I noticed hci_read_link_quality() and hci_read_rssi() in
>> hci_lib.h and tried using them. Since they seem to require an
>> established connection, I also used hci_create_connection(). However I
>> soon discovered that creating a connection requires root privileges,
>> is that right or did I do something wrong?
>>
>> Furthermore, even when running the program as root, the connection
>> gets established only for a few seconds and then it disconnects from
>> the remote device. Is this behaviour intended? How can I specify to
>> keep the connection alive indefinitely?
>
> If you don't have an active connection that is used, the kernel will
> terminate any idle ones. So using hcitool for this is rather pointless
> unless you have a profile already using that connection.
>

"using a connection" means pushing some traffic over it?
Is there no other way to prevent the kernel from terminating idle connections?

By the way, I've read in the Bluetooth specs that there exists an
extended inquiry mode which allows the host to gather the RSSI of
available devices too. How can I perform such kind of inquiry from my
application using bluez?

Thanks,
Davide

2010-08-02 15:56:35

by Marcel Holtmann

[permalink] [raw]
Subject: Re: Getting link quality or RSSI

Hi Davide,

> I'm writing an application to retrieve the current link quality (or
> RSSI) between my laptop's Bluetooth adapter and a specific remote
> device (my mobile phone). In order to do that I'm of course using the
> latest version of BlueZ, but I've encountered several issues so far.
>
> The dbus API exposed by bluetoothd doesn't have any GetRSSI or
> GetLinkQuality methods. Would it be possible to export these methods
> in the public API?

the link quality is vendor specific according to the specification and
the RSSI of an existing connection is rather useless. So we don't bother
to export those.

> Then I looked at the bluetooth HCI library that comes with bluez.
> First of all, is there any reasons why it's totally undocumented?
> Anyway, I noticed hci_read_link_quality() and hci_read_rssi() in
> hci_lib.h and tried using them. Since they seem to require an
> established connection, I also used hci_create_connection(). However I
> soon discovered that creating a connection requires root privileges,
> is that right or did I do something wrong?
>
> Furthermore, even when running the program as root, the connection
> gets established only for a few seconds and then it disconnects from
> the remote device. Is this behaviour intended? How can I specify to
> keep the connection alive indefinitely?

If you don't have an active connection that is used, the kernel will
terminate any idle ones. So using hcitool for this is rather pointless
unless you have a profile already using that connection.

Regards

Marcel