2014-05-27 07:52:42

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 0/9] Connection parameters D-Bus API

Hi,

Following patches add possibility for applications to have RSSI and TX
power data for connected device. This uses recently introduced mgmt
command Get Connection Information.

There are 3 new properties for RSSI, current TX power and max TX power.
Polling for RSSI and TX power can be enabled via Start-/Stop- methods
in a manner similar to discovery on adapter. Max TX power is read once
when device is connected and obviously does not change.

As for now polling interval is set to arbitrary chosen value of 2secs,
but perhapts this could be configurable via main.conf entry.

Changes from RFC to v1:
- connection props exist only when someone requested monitoring
- rebased


Andrzej Kaczmarek (8):
core: Add ConnectionRSSI property
core: Add ConnectionTXPower property
core: Add ConnectionTXPowerMax property
core: Make connection properties exist only when connected
core: Read max TX power when device connected
core: Add API to start/stop connection monitoring
core: Store list of monitored devices in adapter
core: Poll for connection info

Lukasz Rymanowski (1):
doc: Introduce connection monitoring API

doc/device-api.txt | 56 +++++++++++
src/adapter.c | 205 ++++++++++++++++++++++++++++++++++++++++
src/adapter.h | 7 ++
src/device.c | 272 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/device.h | 3 +
5 files changed, 543 insertions(+)

--
1.9.3


2014-05-31 05:17:13

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH 1/9] doc: Introduce connection monitoring API

Hi Andrzej,

> This patch introduces API to monitor connection parameters.
>
> New device properties are introduced: ConnectionRSSI, ConnectionTXPower
> and ConnectionTXPowerMax.
>
> Client can request to poll for updates of RSSI and TX power via Start-
> and StopConnectionMonitor methods.

I am not convinced on the naming of the method calls and properties. They feel complicated and long and not really clear with its purpose.

What I am curious if we just expose the calculated pathloss or some value that has a more clear sense and usefulness for proximity. Why not do the job for the application instead of letting the application figure it out by itself.

Regards

Marcel


2014-05-29 20:08:05

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH 1/9] doc: Introduce connection monitoring API

Hi Tim,

On Thu, May 29, 2014 at 8:52 PM, Tim Song <[email protected]> wrote:
> Hi Luiz,
>
> I disagree that these properties are too low level. The inquiry RSSI
> is already exposed to applications, and it makes sense to also expose
> the RSSI during a connection. Additionally, as Andrzej described
> above, the RSSI isn't meaningful without also knowing the TX power.

Then we agree to disagree, btw if you read my initial response I was
saying we should do something meaningful with RSSI and TX power and
not expose to application and expect they will get it right and
apparently you agree that RSSI is not meaningful on its own.

> Proximity for BR/EDR is a bit more complicated than LE due to the
> varying TX power to keep RSSI in a golden range, and calibration on
> the application side may be necessary as well due to hardware
> differences. For this reason, I think it makes sense to expose these
> properties to applications rather than a plugin or a standardized
> profile.

Im afraid you are only looking to one side of the things, BlueZ can be
used for IVI/carkit/IoT type of devices and for those having proximity
and link loss is very interesting specially for things like audio for
example, I was actually looking into incorporate more of that in our
connection policies but then these patches start appearing in the
mailing list so I guess now it is time to start discussing what are
the use cases and what APIs we need to create.

> Regards,
> Tim
>
> On Wed, May 28, 2014 at 3:13 PM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> Hi Lukasz,
>>
>> On Thu, May 29, 2014 at 12:48 AM, Lukasz Rymanowski
>> <[email protected]> wrote:
>>> Hi Luiz
>>>
>>> On Wed, May 28, 2014 at 9:54 PM, Luiz Augusto von Dentz
>>> <[email protected]> wrote:
>>>> Hi Andrzej,
>>>>
>>>> On Wed, May 28, 2014 at 10:24 PM, Andrzej Kaczmarek
>>>> <[email protected]> wrote:
>>>>> Hi Luiz,
>>>>>
>>>>> On 27 May 2014 14:49, Luiz Augusto von Dentz <[email protected]> wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On Tue, May 27, 2014 at 10:52 AM, Andrzej Kaczmarek
>>>>>> <[email protected]> wrote:
>>>>>>> From: Lukasz Rymanowski <[email protected]>
>>>>>>>
>>>>>>> This patch introduces API to monitor connection parameters.
>>>>>>>
>>>>>>> New device properties are introduced: ConnectionRSSI, ConnectionTXPower
>>>>>>> and ConnectionTXPowerMax.
>>>>>>>
>>>>>>> Client can request to poll for updates of RSSI and TX power via Start-
>>>>>>> and StopConnectionMonitor methods.
>>>>>>> ---
>>>>>>> doc/device-api.txt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>> 1 file changed, 56 insertions(+)
>>>>>>>
>>>>>>> diff --git a/doc/device-api.txt b/doc/device-api.txt
>>>>>>> index 577ee60..67f573c 100644
>>>>>>> --- a/doc/device-api.txt
>>>>>>> +++ b/doc/device-api.txt
>>>>>>> @@ -100,6 +100,35 @@ Methods void Connect()
>>>>>>> Possible errors: org.bluez.Error.DoesNotExist
>>>>>>> org.bluez.Error.Failed
>>>>>>>
>>>>>>> +
>>>>>>> + void StartConnectionMonitor()
>>>>>>> +
>>>>>>> + This method starts connection monitor session. This
>>>>>>> + includes link RSSI and TX power.
>>>>>>> + Use StopConnectionMonitor to release the sessions
>>>>>>> + acquired.
>>>>>>> +
>>>>>>> + This process will start updating connection-related
>>>>>>> + properties, e.g. ConnectionRSSI and ConnectionTXPower.
>>>>>>> +
>>>>>>> + Note that all sessions for device are released when
>>>>>>> + device is disconnected and it's required to start
>>>>>>> + sessiong again once reconnected.
>>>>>>> +
>>>>>>> + Possible errors: org.bluez.Error.Busy
>>>>>>> + org.bluez.Error.NotConnected
>>>>>>> +
>>>>>>> + void StopConnectionMonitor()
>>>>>>> +
>>>>>>> + This method stops previous StartConnectionMonitor
>>>>>>> + session.
>>>>>>> +
>>>>>>> + Note that connection monitor is shared between all
>>>>>>> + monitor sessions thus calling StopConnectionMonitor
>>>>>>> + releases a single session.
>>>>>>> +
>>>>>>> + Possible errors: org.bluez.Error.Failed
>>>>>>> +
>>>>>>> Properties string Address [readonly]
>>>>>>>
>>>>>>> The Bluetooth device address of the remote device.
>>>>>>> @@ -193,3 +222,30 @@ Properties string Address [readonly]
>>>>>>>
>>>>>>> Received Signal Strength Indicator of the remote
>>>>>>> device (inquiry or advertising).
>>>>>>> +
>>>>>>> + int16 ConnectionRSSI [readonly, optional]
>>>>>>> +
>>>>>>> + Received Signal Strength Indicator of connected remote
>>>>>>> + device.
>>>>>>> +
>>>>>>> + This property is present only if device is connected
>>>>>>> + and will be updated if at least one monitoring session
>>>>>>> + is active.
>>>>>>> +
>>>>>>> + Note that RSSI has different units for BR/EDR (dB)
>>>>>>> + and LE (dBm) as specified in BT Core ver. 4.1, Vol. 2,
>>>>>>> + Part E, Chapter 7.5.4
>>>>>>> +
>>>>>>> + int16 ConnectionTXPower [readonly, optional]
>>>>>>> +
>>>>>>> + Transmit power level to connected remote device.
>>>>>>> +
>>>>>>> + This property is present only if device is connected
>>>>>>> + and will be updated if at least one monitoring session
>>>>>>> + is active.
>>>>>>> +
>>>>>>> + int16 ConnectionTXPowerMax [readonly, optional]
>>>>>>> +
>>>>>>> + Maximum transmit power level to connected remote device.
>>>>>>> +
>>>>>>> + This property is present only if device is connected.
>>>>>>> --
>>>>>>> 1.9.3
>>>>>>
>>>>>> IMO this API is too low level, if there is a reliable way to calculate
>>>>>> the link quality we should do it and probably expose as a single
>>>>>> property in percentage like we see in WiFi and other technologies,
>>>>>> trying to push this to the application to figure out is probably bad
>>>>>> idea since different applications may come up with different results.
>>>>>>
>>>>>> I would follow connman API design:
>>>>>>
>>>>>> uint8 Strength [readonly]
>>>>>>
>>>>>> Indicates the signal strength of the service. This
>>>>>> is a normalized value between 0 and 100...
>>>>>
>>>>> There's nothing to calculate here since RSSI and TX power are measured
>>>>> in different "directions". Actually you can calculate pathloss once
>>>>> you have RSSI from *local* side and TX power from *remote*. This is
>>>>> what PXP does using TPS, (but it only works over LE). By having these
>>>>> values exposed to application you can make proper PXP application and
>>>>> even do this on BR/EDR.
>>>>
>>>> But why you want to do PXP as an application and not as a plugin? Both
>>>> PXP and TPS should be very simple to be implemented as plugin since we
>>>> have this info over MGMT interface.
>>>>
>>> I think the problem here is that PXP for BR/EDR is not specified so
>>> probably you don't want it as a plugin in BlueZ.
>>> But if we expose those properties to application they can make fun usage of it.
>>
>> We do support non-standard/device specific profiles such as sixaxis
>> and I would always prefer to attract people to contribute directly to
>> BlueZ so we have fun together. Now regarding PXP on BR/EDR, if that is
>> a good idea it is about time someone suggest it as official profile
>> and in case it turn out to be adopted it would kind make these
>> properties useless.
>>
>>
>> --
>> Luiz Augusto von Dentz
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html



--
Luiz Augusto von Dentz

2014-05-29 17:52:53

by Tim Song

[permalink] [raw]
Subject: Re: [PATCH 1/9] doc: Introduce connection monitoring API

Hi Luiz,

I disagree that these properties are too low level. The inquiry RSSI
is already exposed to applications, and it makes sense to also expose
the RSSI during a connection. Additionally, as Andrzej described
above, the RSSI isn't meaningful without also knowing the TX power.

Proximity for BR/EDR is a bit more complicated than LE due to the
varying TX power to keep RSSI in a golden range, and calibration on
the application side may be necessary as well due to hardware
differences. For this reason, I think it makes sense to expose these
properties to applications rather than a plugin or a standardized
profile.

Regards,
Tim

On Wed, May 28, 2014 at 3:13 PM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Lukasz,
>
> On Thu, May 29, 2014 at 12:48 AM, Lukasz Rymanowski
> <[email protected]> wrote:
>> Hi Luiz
>>
>> On Wed, May 28, 2014 at 9:54 PM, Luiz Augusto von Dentz
>> <[email protected]> wrote:
>>> Hi Andrzej,
>>>
>>> On Wed, May 28, 2014 at 10:24 PM, Andrzej Kaczmarek
>>> <[email protected]> wrote:
>>>> Hi Luiz,
>>>>
>>>> On 27 May 2014 14:49, Luiz Augusto von Dentz <[email protected]> wrote:
>>>>> Hi,
>>>>>
>>>>> On Tue, May 27, 2014 at 10:52 AM, Andrzej Kaczmarek
>>>>> <[email protected]> wrote:
>>>>>> From: Lukasz Rymanowski <[email protected]>
>>>>>>
>>>>>> This patch introduces API to monitor connection parameters.
>>>>>>
>>>>>> New device properties are introduced: ConnectionRSSI, ConnectionTXPower
>>>>>> and ConnectionTXPowerMax.
>>>>>>
>>>>>> Client can request to poll for updates of RSSI and TX power via Start-
>>>>>> and StopConnectionMonitor methods.
>>>>>> ---
>>>>>> doc/device-api.txt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>> 1 file changed, 56 insertions(+)
>>>>>>
>>>>>> diff --git a/doc/device-api.txt b/doc/device-api.txt
>>>>>> index 577ee60..67f573c 100644
>>>>>> --- a/doc/device-api.txt
>>>>>> +++ b/doc/device-api.txt
>>>>>> @@ -100,6 +100,35 @@ Methods void Connect()
>>>>>> Possible errors: org.bluez.Error.DoesNotExist
>>>>>> org.bluez.Error.Failed
>>>>>>
>>>>>> +
>>>>>> + void StartConnectionMonitor()
>>>>>> +
>>>>>> + This method starts connection monitor session. This
>>>>>> + includes link RSSI and TX power.
>>>>>> + Use StopConnectionMonitor to release the sessions
>>>>>> + acquired.
>>>>>> +
>>>>>> + This process will start updating connection-related
>>>>>> + properties, e.g. ConnectionRSSI and ConnectionTXPower.
>>>>>> +
>>>>>> + Note that all sessions for device are released when
>>>>>> + device is disconnected and it's required to start
>>>>>> + sessiong again once reconnected.
>>>>>> +
>>>>>> + Possible errors: org.bluez.Error.Busy
>>>>>> + org.bluez.Error.NotConnected
>>>>>> +
>>>>>> + void StopConnectionMonitor()
>>>>>> +
>>>>>> + This method stops previous StartConnectionMonitor
>>>>>> + session.
>>>>>> +
>>>>>> + Note that connection monitor is shared between all
>>>>>> + monitor sessions thus calling StopConnectionMonitor
>>>>>> + releases a single session.
>>>>>> +
>>>>>> + Possible errors: org.bluez.Error.Failed
>>>>>> +
>>>>>> Properties string Address [readonly]
>>>>>>
>>>>>> The Bluetooth device address of the remote device.
>>>>>> @@ -193,3 +222,30 @@ Properties string Address [readonly]
>>>>>>
>>>>>> Received Signal Strength Indicator of the remote
>>>>>> device (inquiry or advertising).
>>>>>> +
>>>>>> + int16 ConnectionRSSI [readonly, optional]
>>>>>> +
>>>>>> + Received Signal Strength Indicator of connected remote
>>>>>> + device.
>>>>>> +
>>>>>> + This property is present only if device is connected
>>>>>> + and will be updated if at least one monitoring session
>>>>>> + is active.
>>>>>> +
>>>>>> + Note that RSSI has different units for BR/EDR (dB)
>>>>>> + and LE (dBm) as specified in BT Core ver. 4.1, Vol. 2,
>>>>>> + Part E, Chapter 7.5.4
>>>>>> +
>>>>>> + int16 ConnectionTXPower [readonly, optional]
>>>>>> +
>>>>>> + Transmit power level to connected remote device.
>>>>>> +
>>>>>> + This property is present only if device is connected
>>>>>> + and will be updated if at least one monitoring session
>>>>>> + is active.
>>>>>> +
>>>>>> + int16 ConnectionTXPowerMax [readonly, optional]
>>>>>> +
>>>>>> + Maximum transmit power level to connected remote device.
>>>>>> +
>>>>>> + This property is present only if device is connected.
>>>>>> --
>>>>>> 1.9.3
>>>>>
>>>>> IMO this API is too low level, if there is a reliable way to calculate
>>>>> the link quality we should do it and probably expose as a single
>>>>> property in percentage like we see in WiFi and other technologies,
>>>>> trying to push this to the application to figure out is probably bad
>>>>> idea since different applications may come up with different results.
>>>>>
>>>>> I would follow connman API design:
>>>>>
>>>>> uint8 Strength [readonly]
>>>>>
>>>>> Indicates the signal strength of the service. This
>>>>> is a normalized value between 0 and 100...
>>>>
>>>> There's nothing to calculate here since RSSI and TX power are measured
>>>> in different "directions". Actually you can calculate pathloss once
>>>> you have RSSI from *local* side and TX power from *remote*. This is
>>>> what PXP does using TPS, (but it only works over LE). By having these
>>>> values exposed to application you can make proper PXP application and
>>>> even do this on BR/EDR.
>>>
>>> But why you want to do PXP as an application and not as a plugin? Both
>>> PXP and TPS should be very simple to be implemented as plugin since we
>>> have this info over MGMT interface.
>>>
>> I think the problem here is that PXP for BR/EDR is not specified so
>> probably you don't want it as a plugin in BlueZ.
>> But if we expose those properties to application they can make fun usage of it.
>
> We do support non-standard/device specific profiles such as sixaxis
> and I would always prefer to attract people to contribute directly to
> BlueZ so we have fun together. Now regarding PXP on BR/EDR, if that is
> a good idea it is about time someone suggest it as official profile
> and in case it turn out to be adopted it would kind make these
> properties useless.
>
>
> --
> Luiz Augusto von Dentz
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2014-05-28 22:13:36

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH 1/9] doc: Introduce connection monitoring API

Hi Lukasz,

On Thu, May 29, 2014 at 12:48 AM, Lukasz Rymanowski
<[email protected]> wrote:
> Hi Luiz
>
> On Wed, May 28, 2014 at 9:54 PM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> Hi Andrzej,
>>
>> On Wed, May 28, 2014 at 10:24 PM, Andrzej Kaczmarek
>> <[email protected]> wrote:
>>> Hi Luiz,
>>>
>>> On 27 May 2014 14:49, Luiz Augusto von Dentz <[email protected]> wrote:
>>>> Hi,
>>>>
>>>> On Tue, May 27, 2014 at 10:52 AM, Andrzej Kaczmarek
>>>> <[email protected]> wrote:
>>>>> From: Lukasz Rymanowski <[email protected]>
>>>>>
>>>>> This patch introduces API to monitor connection parameters.
>>>>>
>>>>> New device properties are introduced: ConnectionRSSI, ConnectionTXPower
>>>>> and ConnectionTXPowerMax.
>>>>>
>>>>> Client can request to poll for updates of RSSI and TX power via Start-
>>>>> and StopConnectionMonitor methods.
>>>>> ---
>>>>> doc/device-api.txt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>> 1 file changed, 56 insertions(+)
>>>>>
>>>>> diff --git a/doc/device-api.txt b/doc/device-api.txt
>>>>> index 577ee60..67f573c 100644
>>>>> --- a/doc/device-api.txt
>>>>> +++ b/doc/device-api.txt
>>>>> @@ -100,6 +100,35 @@ Methods void Connect()
>>>>> Possible errors: org.bluez.Error.DoesNotExist
>>>>> org.bluez.Error.Failed
>>>>>
>>>>> +
>>>>> + void StartConnectionMonitor()
>>>>> +
>>>>> + This method starts connection monitor session. This
>>>>> + includes link RSSI and TX power.
>>>>> + Use StopConnectionMonitor to release the sessions
>>>>> + acquired.
>>>>> +
>>>>> + This process will start updating connection-related
>>>>> + properties, e.g. ConnectionRSSI and ConnectionTXPower.
>>>>> +
>>>>> + Note that all sessions for device are released when
>>>>> + device is disconnected and it's required to start
>>>>> + sessiong again once reconnected.
>>>>> +
>>>>> + Possible errors: org.bluez.Error.Busy
>>>>> + org.bluez.Error.NotConnected
>>>>> +
>>>>> + void StopConnectionMonitor()
>>>>> +
>>>>> + This method stops previous StartConnectionMonitor
>>>>> + session.
>>>>> +
>>>>> + Note that connection monitor is shared between all
>>>>> + monitor sessions thus calling StopConnectionMonitor
>>>>> + releases a single session.
>>>>> +
>>>>> + Possible errors: org.bluez.Error.Failed
>>>>> +
>>>>> Properties string Address [readonly]
>>>>>
>>>>> The Bluetooth device address of the remote device.
>>>>> @@ -193,3 +222,30 @@ Properties string Address [readonly]
>>>>>
>>>>> Received Signal Strength Indicator of the remote
>>>>> device (inquiry or advertising).
>>>>> +
>>>>> + int16 ConnectionRSSI [readonly, optional]
>>>>> +
>>>>> + Received Signal Strength Indicator of connected remote
>>>>> + device.
>>>>> +
>>>>> + This property is present only if device is connected
>>>>> + and will be updated if at least one monitoring session
>>>>> + is active.
>>>>> +
>>>>> + Note that RSSI has different units for BR/EDR (dB)
>>>>> + and LE (dBm) as specified in BT Core ver. 4.1, Vol. 2,
>>>>> + Part E, Chapter 7.5.4
>>>>> +
>>>>> + int16 ConnectionTXPower [readonly, optional]
>>>>> +
>>>>> + Transmit power level to connected remote device.
>>>>> +
>>>>> + This property is present only if device is connected
>>>>> + and will be updated if at least one monitoring session
>>>>> + is active.
>>>>> +
>>>>> + int16 ConnectionTXPowerMax [readonly, optional]
>>>>> +
>>>>> + Maximum transmit power level to connected remote device.
>>>>> +
>>>>> + This property is present only if device is connected.
>>>>> --
>>>>> 1.9.3
>>>>
>>>> IMO this API is too low level, if there is a reliable way to calculate
>>>> the link quality we should do it and probably expose as a single
>>>> property in percentage like we see in WiFi and other technologies,
>>>> trying to push this to the application to figure out is probably bad
>>>> idea since different applications may come up with different results.
>>>>
>>>> I would follow connman API design:
>>>>
>>>> uint8 Strength [readonly]
>>>>
>>>> Indicates the signal strength of the service. This
>>>> is a normalized value between 0 and 100...
>>>
>>> There's nothing to calculate here since RSSI and TX power are measured
>>> in different "directions". Actually you can calculate pathloss once
>>> you have RSSI from *local* side and TX power from *remote*. This is
>>> what PXP does using TPS, (but it only works over LE). By having these
>>> values exposed to application you can make proper PXP application and
>>> even do this on BR/EDR.
>>
>> But why you want to do PXP as an application and not as a plugin? Both
>> PXP and TPS should be very simple to be implemented as plugin since we
>> have this info over MGMT interface.
>>
> I think the problem here is that PXP for BR/EDR is not specified so
> probably you don't want it as a plugin in BlueZ.
> But if we expose those properties to application they can make fun usage of it.

We do support non-standard/device specific profiles such as sixaxis
and I would always prefer to attract people to contribute directly to
BlueZ so we have fun together. Now regarding PXP on BR/EDR, if that is
a good idea it is about time someone suggest it as official profile
and in case it turn out to be adopted it would kind make these
properties useless.


--
Luiz Augusto von Dentz

2014-05-28 21:48:04

by Lukasz Rymanowski

[permalink] [raw]
Subject: Re: [PATCH 1/9] doc: Introduce connection monitoring API

Hi Luiz

On Wed, May 28, 2014 at 9:54 PM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Andrzej,
>
> On Wed, May 28, 2014 at 10:24 PM, Andrzej Kaczmarek
> <[email protected]> wrote:
>> Hi Luiz,
>>
>> On 27 May 2014 14:49, Luiz Augusto von Dentz <[email protected]> wrote:
>>> Hi,
>>>
>>> On Tue, May 27, 2014 at 10:52 AM, Andrzej Kaczmarek
>>> <[email protected]> wrote:
>>>> From: Lukasz Rymanowski <[email protected]>
>>>>
>>>> This patch introduces API to monitor connection parameters.
>>>>
>>>> New device properties are introduced: ConnectionRSSI, ConnectionTXPower
>>>> and ConnectionTXPowerMax.
>>>>
>>>> Client can request to poll for updates of RSSI and TX power via Start-
>>>> and StopConnectionMonitor methods.
>>>> ---
>>>> doc/device-api.txt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>> 1 file changed, 56 insertions(+)
>>>>
>>>> diff --git a/doc/device-api.txt b/doc/device-api.txt
>>>> index 577ee60..67f573c 100644
>>>> --- a/doc/device-api.txt
>>>> +++ b/doc/device-api.txt
>>>> @@ -100,6 +100,35 @@ Methods void Connect()
>>>> Possible errors: org.bluez.Error.DoesNotExist
>>>> org.bluez.Error.Failed
>>>>
>>>> +
>>>> + void StartConnectionMonitor()
>>>> +
>>>> + This method starts connection monitor session. This
>>>> + includes link RSSI and TX power.
>>>> + Use StopConnectionMonitor to release the sessions
>>>> + acquired.
>>>> +
>>>> + This process will start updating connection-related
>>>> + properties, e.g. ConnectionRSSI and ConnectionTXPower.
>>>> +
>>>> + Note that all sessions for device are released when
>>>> + device is disconnected and it's required to start
>>>> + sessiong again once reconnected.
>>>> +
>>>> + Possible errors: org.bluez.Error.Busy
>>>> + org.bluez.Error.NotConnected
>>>> +
>>>> + void StopConnectionMonitor()
>>>> +
>>>> + This method stops previous StartConnectionMonitor
>>>> + session.
>>>> +
>>>> + Note that connection monitor is shared between all
>>>> + monitor sessions thus calling StopConnectionMonitor
>>>> + releases a single session.
>>>> +
>>>> + Possible errors: org.bluez.Error.Failed
>>>> +
>>>> Properties string Address [readonly]
>>>>
>>>> The Bluetooth device address of the remote device.
>>>> @@ -193,3 +222,30 @@ Properties string Address [readonly]
>>>>
>>>> Received Signal Strength Indicator of the remote
>>>> device (inquiry or advertising).
>>>> +
>>>> + int16 ConnectionRSSI [readonly, optional]
>>>> +
>>>> + Received Signal Strength Indicator of connected remote
>>>> + device.
>>>> +
>>>> + This property is present only if device is connected
>>>> + and will be updated if at least one monitoring session
>>>> + is active.
>>>> +
>>>> + Note that RSSI has different units for BR/EDR (dB)
>>>> + and LE (dBm) as specified in BT Core ver. 4.1, Vol. 2,
>>>> + Part E, Chapter 7.5.4
>>>> +
>>>> + int16 ConnectionTXPower [readonly, optional]
>>>> +
>>>> + Transmit power level to connected remote device.
>>>> +
>>>> + This property is present only if device is connected
>>>> + and will be updated if at least one monitoring session
>>>> + is active.
>>>> +
>>>> + int16 ConnectionTXPowerMax [readonly, optional]
>>>> +
>>>> + Maximum transmit power level to connected remote device.
>>>> +
>>>> + This property is present only if device is connected.
>>>> --
>>>> 1.9.3
>>>
>>> IMO this API is too low level, if there is a reliable way to calculate
>>> the link quality we should do it and probably expose as a single
>>> property in percentage like we see in WiFi and other technologies,
>>> trying to push this to the application to figure out is probably bad
>>> idea since different applications may come up with different results.
>>>
>>> I would follow connman API design:
>>>
>>> uint8 Strength [readonly]
>>>
>>> Indicates the signal strength of the service. This
>>> is a normalized value between 0 and 100...
>>
>> There's nothing to calculate here since RSSI and TX power are measured
>> in different "directions". Actually you can calculate pathloss once
>> you have RSSI from *local* side and TX power from *remote*. This is
>> what PXP does using TPS, (but it only works over LE). By having these
>> values exposed to application you can make proper PXP application and
>> even do this on BR/EDR.
>
> But why you want to do PXP as an application and not as a plugin? Both
> PXP and TPS should be very simple to be implemented as plugin since we
> have this info over MGMT interface.
>
I think the problem here is that PXP for BR/EDR is not specified so
probably you don't want it as a plugin in BlueZ.
But if we expose those properties to application they can make fun usage of it.

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

BR
Lukasz

2014-05-28 19:54:47

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH 1/9] doc: Introduce connection monitoring API

Hi Andrzej,

On Wed, May 28, 2014 at 10:24 PM, Andrzej Kaczmarek
<[email protected]> wrote:
> Hi Luiz,
>
> On 27 May 2014 14:49, Luiz Augusto von Dentz <[email protected]> wrote:
>> Hi,
>>
>> On Tue, May 27, 2014 at 10:52 AM, Andrzej Kaczmarek
>> <[email protected]> wrote:
>>> From: Lukasz Rymanowski <[email protected]>
>>>
>>> This patch introduces API to monitor connection parameters.
>>>
>>> New device properties are introduced: ConnectionRSSI, ConnectionTXPower
>>> and ConnectionTXPowerMax.
>>>
>>> Client can request to poll for updates of RSSI and TX power via Start-
>>> and StopConnectionMonitor methods.
>>> ---
>>> doc/device-api.txt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 56 insertions(+)
>>>
>>> diff --git a/doc/device-api.txt b/doc/device-api.txt
>>> index 577ee60..67f573c 100644
>>> --- a/doc/device-api.txt
>>> +++ b/doc/device-api.txt
>>> @@ -100,6 +100,35 @@ Methods void Connect()
>>> Possible errors: org.bluez.Error.DoesNotExist
>>> org.bluez.Error.Failed
>>>
>>> +
>>> + void StartConnectionMonitor()
>>> +
>>> + This method starts connection monitor session. This
>>> + includes link RSSI and TX power.
>>> + Use StopConnectionMonitor to release the sessions
>>> + acquired.
>>> +
>>> + This process will start updating connection-related
>>> + properties, e.g. ConnectionRSSI and ConnectionTXPower.
>>> +
>>> + Note that all sessions for device are released when
>>> + device is disconnected and it's required to start
>>> + sessiong again once reconnected.
>>> +
>>> + Possible errors: org.bluez.Error.Busy
>>> + org.bluez.Error.NotConnected
>>> +
>>> + void StopConnectionMonitor()
>>> +
>>> + This method stops previous StartConnectionMonitor
>>> + session.
>>> +
>>> + Note that connection monitor is shared between all
>>> + monitor sessions thus calling StopConnectionMonitor
>>> + releases a single session.
>>> +
>>> + Possible errors: org.bluez.Error.Failed
>>> +
>>> Properties string Address [readonly]
>>>
>>> The Bluetooth device address of the remote device.
>>> @@ -193,3 +222,30 @@ Properties string Address [readonly]
>>>
>>> Received Signal Strength Indicator of the remote
>>> device (inquiry or advertising).
>>> +
>>> + int16 ConnectionRSSI [readonly, optional]
>>> +
>>> + Received Signal Strength Indicator of connected remote
>>> + device.
>>> +
>>> + This property is present only if device is connected
>>> + and will be updated if at least one monitoring session
>>> + is active.
>>> +
>>> + Note that RSSI has different units for BR/EDR (dB)
>>> + and LE (dBm) as specified in BT Core ver. 4.1, Vol. 2,
>>> + Part E, Chapter 7.5.4
>>> +
>>> + int16 ConnectionTXPower [readonly, optional]
>>> +
>>> + Transmit power level to connected remote device.
>>> +
>>> + This property is present only if device is connected
>>> + and will be updated if at least one monitoring session
>>> + is active.
>>> +
>>> + int16 ConnectionTXPowerMax [readonly, optional]
>>> +
>>> + Maximum transmit power level to connected remote device.
>>> +
>>> + This property is present only if device is connected.
>>> --
>>> 1.9.3
>>
>> IMO this API is too low level, if there is a reliable way to calculate
>> the link quality we should do it and probably expose as a single
>> property in percentage like we see in WiFi and other technologies,
>> trying to push this to the application to figure out is probably bad
>> idea since different applications may come up with different results.
>>
>> I would follow connman API design:
>>
>> uint8 Strength [readonly]
>>
>> Indicates the signal strength of the service. This
>> is a normalized value between 0 and 100...
>
> There's nothing to calculate here since RSSI and TX power are measured
> in different "directions". Actually you can calculate pathloss once
> you have RSSI from *local* side and TX power from *remote*. This is
> what PXP does using TPS, (but it only works over LE). By having these
> values exposed to application you can make proper PXP application and
> even do this on BR/EDR.

But why you want to do PXP as an application and not as a plugin? Both
PXP and TPS should be very simple to be implemented as plugin since we
have this info over MGMT interface.

--
Luiz Augusto von Dentz

2014-05-28 19:24:11

by Andrzej Kaczmarek

[permalink] [raw]
Subject: Re: [PATCH 1/9] doc: Introduce connection monitoring API

Hi Luiz,

On 27 May 2014 14:49, Luiz Augusto von Dentz <[email protected]> wrote:
> Hi,
>
> On Tue, May 27, 2014 at 10:52 AM, Andrzej Kaczmarek
> <[email protected]> wrote:
>> From: Lukasz Rymanowski <[email protected]>
>>
>> This patch introduces API to monitor connection parameters.
>>
>> New device properties are introduced: ConnectionRSSI, ConnectionTXPower
>> and ConnectionTXPowerMax.
>>
>> Client can request to poll for updates of RSSI and TX power via Start-
>> and StopConnectionMonitor methods.
>> ---
>> doc/device-api.txt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 56 insertions(+)
>>
>> diff --git a/doc/device-api.txt b/doc/device-api.txt
>> index 577ee60..67f573c 100644
>> --- a/doc/device-api.txt
>> +++ b/doc/device-api.txt
>> @@ -100,6 +100,35 @@ Methods void Connect()
>> Possible errors: org.bluez.Error.DoesNotExist
>> org.bluez.Error.Failed
>>
>> +
>> + void StartConnectionMonitor()
>> +
>> + This method starts connection monitor session. This
>> + includes link RSSI and TX power.
>> + Use StopConnectionMonitor to release the sessions
>> + acquired.
>> +
>> + This process will start updating connection-related
>> + properties, e.g. ConnectionRSSI and ConnectionTXPower.
>> +
>> + Note that all sessions for device are released when
>> + device is disconnected and it's required to start
>> + sessiong again once reconnected.
>> +
>> + Possible errors: org.bluez.Error.Busy
>> + org.bluez.Error.NotConnected
>> +
>> + void StopConnectionMonitor()
>> +
>> + This method stops previous StartConnectionMonitor
>> + session.
>> +
>> + Note that connection monitor is shared between all
>> + monitor sessions thus calling StopConnectionMonitor
>> + releases a single session.
>> +
>> + Possible errors: org.bluez.Error.Failed
>> +
>> Properties string Address [readonly]
>>
>> The Bluetooth device address of the remote device.
>> @@ -193,3 +222,30 @@ Properties string Address [readonly]
>>
>> Received Signal Strength Indicator of the remote
>> device (inquiry or advertising).
>> +
>> + int16 ConnectionRSSI [readonly, optional]
>> +
>> + Received Signal Strength Indicator of connected remote
>> + device.
>> +
>> + This property is present only if device is connected
>> + and will be updated if at least one monitoring session
>> + is active.
>> +
>> + Note that RSSI has different units for BR/EDR (dB)
>> + and LE (dBm) as specified in BT Core ver. 4.1, Vol. 2,
>> + Part E, Chapter 7.5.4
>> +
>> + int16 ConnectionTXPower [readonly, optional]
>> +
>> + Transmit power level to connected remote device.
>> +
>> + This property is present only if device is connected
>> + and will be updated if at least one monitoring session
>> + is active.
>> +
>> + int16 ConnectionTXPowerMax [readonly, optional]
>> +
>> + Maximum transmit power level to connected remote device.
>> +
>> + This property is present only if device is connected.
>> --
>> 1.9.3
>
> IMO this API is too low level, if there is a reliable way to calculate
> the link quality we should do it and probably expose as a single
> property in percentage like we see in WiFi and other technologies,
> trying to push this to the application to figure out is probably bad
> idea since different applications may come up with different results.
>
> I would follow connman API design:
>
> uint8 Strength [readonly]
>
> Indicates the signal strength of the service. This
> is a normalized value between 0 and 100...

There's nothing to calculate here since RSSI and TX power are measured
in different "directions". Actually you can calculate pathloss once
you have RSSI from *local* side and TX power from *remote*. This is
what PXP does using TPS, (but it only works over LE). By having these
values exposed to application you can make proper PXP application and
even do this on BR/EDR.

BR,
Andrzej

2014-05-27 12:49:28

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH 1/9] doc: Introduce connection monitoring API

Hi,

On Tue, May 27, 2014 at 10:52 AM, Andrzej Kaczmarek
<[email protected]> wrote:
> From: Lukasz Rymanowski <[email protected]>
>
> This patch introduces API to monitor connection parameters.
>
> New device properties are introduced: ConnectionRSSI, ConnectionTXPower
> and ConnectionTXPowerMax.
>
> Client can request to poll for updates of RSSI and TX power via Start-
> and StopConnectionMonitor methods.
> ---
> doc/device-api.txt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 56 insertions(+)
>
> diff --git a/doc/device-api.txt b/doc/device-api.txt
> index 577ee60..67f573c 100644
> --- a/doc/device-api.txt
> +++ b/doc/device-api.txt
> @@ -100,6 +100,35 @@ Methods void Connect()
> Possible errors: org.bluez.Error.DoesNotExist
> org.bluez.Error.Failed
>
> +
> + void StartConnectionMonitor()
> +
> + This method starts connection monitor session. This
> + includes link RSSI and TX power.
> + Use StopConnectionMonitor to release the sessions
> + acquired.
> +
> + This process will start updating connection-related
> + properties, e.g. ConnectionRSSI and ConnectionTXPower.
> +
> + Note that all sessions for device are released when
> + device is disconnected and it's required to start
> + sessiong again once reconnected.
> +
> + Possible errors: org.bluez.Error.Busy
> + org.bluez.Error.NotConnected
> +
> + void StopConnectionMonitor()
> +
> + This method stops previous StartConnectionMonitor
> + session.
> +
> + Note that connection monitor is shared between all
> + monitor sessions thus calling StopConnectionMonitor
> + releases a single session.
> +
> + Possible errors: org.bluez.Error.Failed
> +
> Properties string Address [readonly]
>
> The Bluetooth device address of the remote device.
> @@ -193,3 +222,30 @@ Properties string Address [readonly]
>
> Received Signal Strength Indicator of the remote
> device (inquiry or advertising).
> +
> + int16 ConnectionRSSI [readonly, optional]
> +
> + Received Signal Strength Indicator of connected remote
> + device.
> +
> + This property is present only if device is connected
> + and will be updated if at least one monitoring session
> + is active.
> +
> + Note that RSSI has different units for BR/EDR (dB)
> + and LE (dBm) as specified in BT Core ver. 4.1, Vol. 2,
> + Part E, Chapter 7.5.4
> +
> + int16 ConnectionTXPower [readonly, optional]
> +
> + Transmit power level to connected remote device.
> +
> + This property is present only if device is connected
> + and will be updated if at least one monitoring session
> + is active.
> +
> + int16 ConnectionTXPowerMax [readonly, optional]
> +
> + Maximum transmit power level to connected remote device.
> +
> + This property is present only if device is connected.
> --
> 1.9.3

IMO this API is too low level, if there is a reliable way to calculate
the link quality we should do it and probably expose as a single
property in percentage like we see in WiFi and other technologies,
trying to push this to the application to figure out is probably bad
idea since different applications may come up with different results.

I would follow connman API design:

uint8 Strength [readonly]

Indicates the signal strength of the service. This
is a normalized value between 0 and 100...

--
Luiz Augusto von Dentz

2014-05-27 07:52:51

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 9/9] core: Poll for connection info

This patch adds actual polling mechanism for devices which are stored
on list for each adapter.
---
src/adapter.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index 045ce30..c0ebfab 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -183,6 +183,7 @@ struct btd_adapter {
guint discovery_idle_timeout; /* timeout between discovery runs */
guint passive_scan_timeout; /* timeout between passive scans */
guint temp_devices_timeout; /* timeout for temporary devices */
+ guint mon_devices_timeout;

guint pairable_timeout_id; /* pairable timeout id */
guint auth_idle_id; /* Pending authorization dequeue */
@@ -4189,6 +4190,11 @@ static void adapter_remove(struct btd_adapter *adapter)
adapter->temp_devices_timeout = 0;
}

+ if (adapter->mon_devices_timeout > 0) {
+ g_source_remove(adapter->mon_devices_timeout);
+ adapter->mon_devices_timeout = 0;
+ }
+
discovery_cleanup(adapter);

g_slist_free(adapter->connect_list);
@@ -5467,6 +5473,73 @@ static void disconnect_complete(uint8_t status, uint16_t length,
dev_disconnected(adapter, &rp->addr, MGMT_DEV_DISCONN_LOCAL_HOST);
}

+static void monitor_conn_info_destroy(void *data)
+{
+ struct btd_device *device = data;
+
+ btd_device_unref(device);
+}
+
+static void monitor_conn_info_rsp(uint8_t status, uint16_t len,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_get_conn_info *rp = param;
+ struct btd_device *device = user_data;
+
+ DBG("status %d", status);
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Get Connection Information failed: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ if (len < sizeof(*rp)) {
+ error("Too small Get Connection Information response");
+ return;
+ }
+
+ device_set_conn_rssi(device, rp->rssi);
+ device_set_conn_tx_power(device, rp->tx_power);
+}
+
+static void monitor_conn_info(void *data, void *user_data)
+{
+ struct mgmt_addr_info *addr = data;
+ struct btd_adapter *adapter = user_data;
+ struct mgmt_cp_get_conn_info cp;
+ char addrstr[18];
+ struct btd_device *device;
+
+ ba2str(&addr->bdaddr, addrstr);
+ DBG("bdaddr %s type %d", addrstr, addr->type);
+
+ device = btd_adapter_find_device(adapter, &addr->bdaddr, addr->type);
+ if (!device)
+ return;
+
+ btd_device_ref(device);
+
+ memset(&cp, 0, sizeof(cp));
+ bacpy(&cp.addr.bdaddr, &addr->bdaddr);
+ cp.addr.type = addr->type;
+
+ mgmt_send(adapter->mgmt, MGMT_OP_GET_CONN_INFO, adapter->dev_id,
+ sizeof(cp), &cp, monitor_conn_info_rsp,
+ device, monitor_conn_info_destroy);
+}
+
+static gboolean trigger_conn_monitor(gpointer user_data)
+{
+ struct btd_adapter *adapter = user_data;
+
+ DBG("");
+
+ queue_foreach(adapter->monitored_devices, monitor_conn_info, adapter);
+
+ return TRUE;
+}
+
struct monitored_device {
struct mgmt_addr_info addr;
};
@@ -5500,6 +5573,10 @@ int btd_adapter_add_monitored_device(struct btd_adapter *adapter,
return 0;
}

+ if (!queue_length(adapter->monitored_devices))
+ adapter->mon_devices_timeout =
+ g_timeout_add(2000, trigger_conn_monitor, adapter);
+
queue_push_tail(adapter->monitored_devices, mdev);

return 0;
@@ -5529,6 +5606,12 @@ int btd_adapter_remove_monitored_device(struct btd_adapter *adapter,

free(mdev);

+ if (!queue_length(adapter->monitored_devices))
+ if (adapter->mon_devices_timeout > 0) {
+ g_source_remove(adapter->mon_devices_timeout);
+ adapter->mon_devices_timeout = 0;
+ }
+
return 0;
}

--
1.9.3

2014-05-27 07:52:49

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 7/9] core: Add API to start/stop connection monitoring

This patch adds Start-/StopConnectionMonitor methods to
org.bluez.Device1 which can be used to request polling of connection
properties, i.e. ConnectionRSSI and ConnectionTXPower.
---
src/adapter.c | 24 +++++++++
src/adapter.h | 7 +++
src/device.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 191 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index 585f2e2..a3204d0 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -5460,6 +5460,30 @@ static void disconnect_complete(uint8_t status, uint16_t length,
dev_disconnected(adapter, &rp->addr, MGMT_DEV_DISCONN_LOCAL_HOST);
}

+int btd_adapter_add_monitored_device(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr,
+ uint8_t bdaddr_type)
+{
+ char addrstr[18];
+
+ ba2str(bdaddr, addrstr);
+ DBG("addr %s type %d", addrstr, bdaddr_type);
+
+ return 0;
+}
+
+int btd_adapter_remove_monitored_device(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr,
+ uint8_t bdaddr_type)
+{
+ char addrstr[18];
+
+ ba2str(bdaddr, addrstr);
+ DBG("addr %s type %d", addrstr, bdaddr_type);
+
+ return 0;
+}
+
int btd_adapter_disconnect_device(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,
uint8_t bdaddr_type)
diff --git a/src/adapter.h b/src/adapter.h
index f88c339..713c3ec 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -207,3 +207,10 @@ gboolean btd_adapter_check_oob_handler(struct btd_adapter *adapter);
void btd_adapter_for_each_device(struct btd_adapter *adapter,
void (*cb)(struct btd_device *device, void *data),
void *data);
+
+int btd_adapter_add_monitored_device(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr,
+ uint8_t bdaddr_type);
+int btd_adapter_remove_monitored_device(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr,
+ uint8_t bdaddr_type);
diff --git a/src/device.c b/src/device.c
index a66f397..6a2dc0a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -48,6 +48,8 @@
#include "btio/btio.h"
#include "lib/uuid.h"
#include "lib/mgmt.h"
+#include "src/shared/queue.h"
+#include "src/shared/util.h"
#include "attrib/att.h"
#include "hcid.h"
#include "adapter.h"
@@ -159,6 +161,13 @@ struct bearer_state {
bool bonded;
bool connected;
bool svc_resolved;
+ bool monitored;
+};
+
+struct monitor_client {
+ struct btd_device *device;
+ char *owner;
+ guint watch;
};

struct btd_device {
@@ -219,6 +228,7 @@ struct btd_device {
bool legacy;
int8_t rssi;

+ struct queue *monitor_list;
int8_t conn_rssi;
int8_t conn_tx_power;
int8_t conn_max_tx_power;
@@ -515,6 +525,13 @@ static void svc_dev_remove(gpointer user_data)
g_free(cb);
}

+static void monitor_client_remove(void *data, void *user_data)
+{
+ struct monitor_client *client = data;
+
+ g_dbus_remove_watch(dbus_conn, client->watch);
+}
+
static void device_free(gpointer user_data)
{
struct btd_device *device = user_data;
@@ -555,6 +572,9 @@ static void device_free(gpointer user_data)
if (device->eir_uuids)
g_slist_free_full(device->eir_uuids, g_free);

+ queue_foreach(device->monitor_list, monitor_client_remove, NULL);
+ queue_destroy(device->monitor_list, NULL);
+
g_free(device->path);
g_free(device->alias);
free(device->modalias);
@@ -1941,6 +1961,134 @@ static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
return dbus_message_new_method_return(msg);
}

+static bool compare_sender(const void *a, const void *b)
+{
+ const struct monitor_client *client = a;
+ const char *sender = b;
+
+ return !strcmp(client->owner, sender);
+}
+
+static void monitor_start(struct btd_device *device)
+{
+ DBG("");
+
+ if (device->bredr_state.connected && !device->bredr_state.monitored) {
+ btd_adapter_add_monitored_device(device->adapter,
+ &device->bdaddr,
+ BDADDR_BREDR);
+ device->bredr_state.monitored = true;
+ }
+
+ if (device->le_state.connected && !device->le_state.monitored) {
+ btd_adapter_add_monitored_device(device->adapter,
+ &device->bdaddr,
+ device->bdaddr_type);
+ device->le_state.monitored = true;
+ }
+}
+
+static void monitor_stop(struct btd_device *device, bool stop_all)
+{
+ DBG("");
+
+ if (device->bredr_state.monitored &&
+ (stop_all || !device->bredr_state.connected)) {
+ btd_adapter_remove_monitored_device(device->adapter,
+ &device->bdaddr,
+ BDADDR_BREDR);
+ device->bredr_state.monitored = false;
+ }
+
+ if (device->le_state.monitored &&
+ (stop_all || !device->le_state.connected)) {
+ btd_adapter_remove_monitored_device(device->adapter,
+ &device->bdaddr,
+ device->bdaddr_type);
+ device->le_state.monitored = false;
+ }
+}
+
+static void monitor_destroy(void *user_data)
+{
+ struct monitor_client *client = user_data;
+ struct btd_device *device = client->device;
+
+ DBG("owner %s", client->owner);
+
+ queue_remove(device->monitor_list, client);
+
+ g_free(client->owner);
+ free(client);
+}
+
+static void monitor_disconnect(DBusConnection *conn, void *user_data)
+{
+ struct monitor_client *client = user_data;
+ struct btd_device *device = client->device;
+
+ DBG("owner %s", client->owner);
+
+ queue_remove(device->monitor_list, client);
+
+ if (queue_length(device->monitor_list))
+ return;
+
+ monitor_stop(device, true);
+}
+
+static DBusMessage *start_conn_monitoring(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ struct btd_device *device = user_data;
+ const char *sender = dbus_message_get_sender(msg);
+ struct monitor_client *client;
+
+ DBG("sender %s", sender);
+
+ if (!btd_device_is_connected(device))
+ return btd_error_not_connected(msg);
+
+ if (queue_find(device->monitor_list, compare_sender, sender))
+ return btd_error_busy(msg);
+
+ client = new0(struct monitor_client, 1);
+ client->device = device;
+ client->owner = g_strdup(sender);
+ client->watch = g_dbus_add_disconnect_watch(dbus_conn, sender,
+ monitor_disconnect,
+ client,
+ monitor_destroy);
+
+ if (!queue_length(device->monitor_list))
+ monitor_start(device);
+
+ queue_push_head(device->monitor_list, client);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *stop_conn_monitoring(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ struct btd_device *device = user_data;
+ const char *sender = dbus_message_get_sender(msg);
+ struct monitor_client *client;
+
+ DBG("sender %s", sender);
+
+ client = queue_find(device->monitor_list, compare_sender, sender);
+ if (!client)
+ return btd_error_failed(msg, "No monitor started");
+
+ g_dbus_remove_watch(dbus_conn, client->watch);
+
+ if (!queue_length(device->monitor_list))
+ monitor_stop(device, true);
+
+ return dbus_message_new_method_return(msg);
+}
+
static const GDBusMethodTable device_methods[] = {
{ GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, dev_disconnect) },
{ GDBUS_ASYNC_METHOD("Connect", NULL, NULL, dev_connect) },
@@ -1950,6 +2098,10 @@ static const GDBusMethodTable device_methods[] = {
NULL, disconnect_profile) },
{ GDBUS_ASYNC_METHOD("Pair", NULL, NULL, pair_device) },
{ GDBUS_METHOD("CancelPairing", NULL, NULL, cancel_pairing) },
+ { GDBUS_METHOD("StartConnectionMonitor", NULL, NULL,
+ start_conn_monitoring) },
+ { GDBUS_METHOD("StopConnectionMonitor", NULL, NULL,
+ stop_conn_monitoring) },
{ }
};

@@ -2005,6 +2157,8 @@ void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
return;
}

+ monitor_start(dev);
+
/* If this is the first connection over this bearer */
if (bdaddr_type == BDADDR_BREDR)
device_set_bredr_support(dev);
@@ -2031,6 +2185,8 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
device->svc_refreshed = false;
device->general_connect = FALSE;

+ monitor_stop(device, false);
+
if (device->disconn_timer > 0) {
g_source_remove(device->disconn_timer);
device->disconn_timer = 0;
@@ -2051,6 +2207,8 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
if (device->bredr_state.connected || device->le_state.connected)
return;

+ queue_foreach(device->monitor_list, monitor_client_remove, NULL);
+
g_dbus_emit_property_changed(dbus_conn, device->path,
DEVICE_INTERFACE, "Connected");
}
@@ -2374,6 +2532,8 @@ static struct btd_device *device_new(struct btd_adapter *adapter,
str2ba(address, &device->bdaddr);
device->adapter = adapter;

+ device->monitor_list = queue_new();
+
device->conn_tx_power = 127; /* invalid */
device->conn_max_tx_power = 127; /* invalid */

--
1.9.3

2014-05-27 07:52:45

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 3/9] core: Add ConnectionTXPower property

This patch adds ConnectionTXPower property on org.bluez.Device1
interface which provides local TX power on currently connected link.

Property value will be refreshed once connection monitoring code is in
place.
---
src/device.c | 32 ++++++++++++++++++++++++++++++++
src/device.h | 1 +
2 files changed, 33 insertions(+)

diff --git a/src/device.c b/src/device.c
index fd4e120..ac42a75 100644
--- a/src/device.c
+++ b/src/device.c
@@ -220,6 +220,7 @@ struct btd_device {
int8_t rssi;

int8_t conn_rssi;
+ int8_t conn_tx_power;

GIOChannel *att_io;
guint cleanup_id;
@@ -838,6 +839,18 @@ static gboolean dev_property_get_conn_rssi(const GDBusPropertyTable *property,
return TRUE;
}

+static gboolean dev_property_get_conn_txpower(
+ const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *device = data;
+ dbus_int16_t val = device->conn_tx_power;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
+
+ return TRUE;
+}
+
static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
{
struct btd_device *device = data;
@@ -1932,6 +1945,7 @@ static const GDBusPropertyTable device_properties[] = {
dev_property_exists_modalias },
{ "Adapter", "o", dev_property_get_adapter },
{ "ConnectionRSSI", "n", dev_property_get_conn_rssi },
+ { "ConnectionTXPower", "n", dev_property_get_conn_txpower },
{ }
};

@@ -2327,6 +2341,8 @@ static struct btd_device *device_new(struct btd_adapter *adapter,
str2ba(address, &device->bdaddr);
device->adapter = adapter;

+ device->conn_tx_power = 127; /* invalid */
+
return btd_device_ref(device);
}

@@ -4073,6 +4089,22 @@ void device_set_conn_rssi(struct btd_device *device, int8_t rssi)
"ConnectionRSSI");
}

+void device_set_conn_tx_power(struct btd_device *device, int8_t tx_power)
+{
+ if (!device)
+ return;
+
+ if (device->conn_tx_power == tx_power)
+ return;
+
+ DBG("conn_tx_power %d", tx_power);
+
+ device->conn_tx_power = tx_power;
+
+ g_dbus_emit_property_changed(dbus_conn, device->path, DEVICE_INTERFACE,
+ "ConnectionTXPower");
+}
+
static void device_set_auto_connect(struct btd_device *device, gboolean enable)
{
char addr[18];
diff --git a/src/device.h b/src/device.h
index 79d5132..e0e44cc 100644
--- a/src/device.h
+++ b/src/device.h
@@ -89,6 +89,7 @@ void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type);
void device_set_legacy(struct btd_device *device, bool legacy);
void device_set_rssi(struct btd_device *device, int8_t rssi);
void device_set_conn_rssi(struct btd_device *device, int8_t rssi);
+void device_set_conn_tx_power(struct btd_device *device, int8_t tx_power);
bool btd_device_is_connected(struct btd_device *dev);
uint8_t btd_device_get_bdaddr_type(struct btd_device *dev);
bool device_is_retrying(struct btd_device *device);
--
1.9.3

2014-05-27 07:52:43

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 1/9] doc: Introduce connection monitoring API

From: Lukasz Rymanowski <[email protected]>

This patch introduces API to monitor connection parameters.

New device properties are introduced: ConnectionRSSI, ConnectionTXPower
and ConnectionTXPowerMax.

Client can request to poll for updates of RSSI and TX power via Start-
and StopConnectionMonitor methods.
---
doc/device-api.txt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)

diff --git a/doc/device-api.txt b/doc/device-api.txt
index 577ee60..67f573c 100644
--- a/doc/device-api.txt
+++ b/doc/device-api.txt
@@ -100,6 +100,35 @@ Methods void Connect()
Possible errors: org.bluez.Error.DoesNotExist
org.bluez.Error.Failed

+
+ void StartConnectionMonitor()
+
+ This method starts connection monitor session. This
+ includes link RSSI and TX power.
+ Use StopConnectionMonitor to release the sessions
+ acquired.
+
+ This process will start updating connection-related
+ properties, e.g. ConnectionRSSI and ConnectionTXPower.
+
+ Note that all sessions for device are released when
+ device is disconnected and it's required to start
+ sessiong again once reconnected.
+
+ Possible errors: org.bluez.Error.Busy
+ org.bluez.Error.NotConnected
+
+ void StopConnectionMonitor()
+
+ This method stops previous StartConnectionMonitor
+ session.
+
+ Note that connection monitor is shared between all
+ monitor sessions thus calling StopConnectionMonitor
+ releases a single session.
+
+ Possible errors: org.bluez.Error.Failed
+
Properties string Address [readonly]

The Bluetooth device address of the remote device.
@@ -193,3 +222,30 @@ Properties string Address [readonly]

Received Signal Strength Indicator of the remote
device (inquiry or advertising).
+
+ int16 ConnectionRSSI [readonly, optional]
+
+ Received Signal Strength Indicator of connected remote
+ device.
+
+ This property is present only if device is connected
+ and will be updated if at least one monitoring session
+ is active.
+
+ Note that RSSI has different units for BR/EDR (dB)
+ and LE (dBm) as specified in BT Core ver. 4.1, Vol. 2,
+ Part E, Chapter 7.5.4
+
+ int16 ConnectionTXPower [readonly, optional]
+
+ Transmit power level to connected remote device.
+
+ This property is present only if device is connected
+ and will be updated if at least one monitoring session
+ is active.
+
+ int16 ConnectionTXPowerMax [readonly, optional]
+
+ Maximum transmit power level to connected remote device.
+
+ This property is present only if device is connected.
--
1.9.3

2014-05-27 07:52:47

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 5/9] core: Make connection properties exist only when connected

This patch adds common 'exists' function for Connection* properties
on org.bluez.Device1 interface. It will make properties to exist only
when device is connected since they do not make sense otherwise.
---
src/device.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/src/device.c b/src/device.c
index 8661386..a66f397 100644
--- a/src/device.c
+++ b/src/device.c
@@ -864,6 +864,22 @@ static gboolean dev_property_get_conn_max_txpower(
return TRUE;
}

+static gboolean dev_property_exists_conn(const GDBusPropertyTable *property,
+ void *data)
+{
+ struct btd_device *device = data;
+
+ /* Properties do not exist on disconnected device */
+ if (!btd_device_is_connected(device))
+ return FALSE;
+
+ /* Properties do not exist if no one requested monitoring */
+ if (!queue_length(device->monitor_list))
+ return FALSE;
+
+ return TRUE;
+}
+
static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
{
struct btd_device *device = data;
@@ -1957,9 +1973,12 @@ static const GDBusPropertyTable device_properties[] = {
{ "Modalias", "s", dev_property_get_modalias, NULL,
dev_property_exists_modalias },
{ "Adapter", "o", dev_property_get_adapter },
- { "ConnectionRSSI", "n", dev_property_get_conn_rssi },
- { "ConnectionTXPower", "n", dev_property_get_conn_txpower },
- { "ConnectionTXPowerMax", "n", dev_property_get_conn_max_txpower },
+ { "ConnectionRSSI", "n", dev_property_get_conn_rssi, NULL,
+ dev_property_exists_conn },
+ { "ConnectionTXPower", "n", dev_property_get_conn_txpower, NULL,
+ dev_property_exists_conn },
+ { "ConnectionTXPowerMax", "n", dev_property_get_conn_max_txpower, NULL,
+ dev_property_exists_conn },
{ }
};

--
1.9.3

2014-05-27 07:52:50

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 8/9] core: Store list of monitored devices in adapter

This patch adds list of devices which should be polled for connection
information to adapter.
---
src/adapter.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index a3204d0..045ce30 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -53,6 +53,7 @@
#include "lib/mgmt.h"
#include "src/shared/mgmt.h"
#include "src/shared/util.h"
+#include "src/shared/queue.h"

#include "hcid.h"
#include "sdpd.h"
@@ -178,6 +179,7 @@ struct btd_adapter {
bool discovery_suspended; /* discovery has been suspended */
GSList *discovery_list; /* list of discovery clients */
GSList *discovery_found; /* list of found devices */
+ struct queue *monitored_devices;
guint discovery_idle_timeout; /* timeout between discovery runs */
guint passive_scan_timeout; /* timeout between passive scans */
guint temp_devices_timeout; /* timeout for temporary devices */
@@ -4166,6 +4168,8 @@ static struct btd_adapter *btd_adapter_new(uint16_t index)

adapter->auths = g_queue_new();

+ adapter->monitored_devices = queue_new();
+
return btd_adapter_ref(adapter);
}

@@ -4190,6 +4194,9 @@ static void adapter_remove(struct btd_adapter *adapter)
g_slist_free(adapter->connect_list);
adapter->connect_list = NULL;

+ queue_destroy(adapter->monitored_devices, free);
+ adapter->monitored_devices = NULL;
+
for (l = adapter->devices; l; l = l->next)
device_remove(l->data, FALSE);

@@ -5460,15 +5467,41 @@ static void disconnect_complete(uint8_t status, uint16_t length,
dev_disconnected(adapter, &rp->addr, MGMT_DEV_DISCONN_LOCAL_HOST);
}

+struct monitored_device {
+ struct mgmt_addr_info addr;
+};
+
+static bool compare_monitored_device(const void *a, const void *b)
+{
+ const struct monitored_device *a1 = a;
+ const struct monitored_device *b1 = b;
+
+ return !memcmp(&a1->addr.bdaddr, &b1->addr.bdaddr, sizeof(bdaddr_t)) &&
+ a1->addr.type == b1->addr.type;
+}
+
int btd_adapter_add_monitored_device(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,
uint8_t bdaddr_type)
{
+ struct monitored_device *mdev;
char addrstr[18];

ba2str(bdaddr, addrstr);
DBG("addr %s type %d", addrstr, bdaddr_type);

+ mdev = new0(struct monitored_device, 1);
+ bacpy(&mdev->addr.bdaddr, bdaddr);
+ mdev->addr.type = bdaddr_type;
+
+ if (queue_find(adapter->monitored_devices, compare_monitored_device,
+ mdev)) {
+ free(mdev);
+ return 0;
+ }
+
+ queue_push_tail(adapter->monitored_devices, mdev);
+
return 0;
}

@@ -5476,11 +5509,26 @@ int btd_adapter_remove_monitored_device(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,
uint8_t bdaddr_type)
{
+ struct monitored_device match;
+ struct monitored_device *mdev;
char addrstr[18];

ba2str(bdaddr, addrstr);
DBG("addr %s type %d", addrstr, bdaddr_type);

+ memset(&match, 0, sizeof(match));
+ bacpy(&match.addr.bdaddr, bdaddr);
+ match.addr.type = bdaddr_type;
+
+ mdev = queue_find(adapter->monitored_devices, compare_monitored_device,
+ &match);
+ if (!mdev)
+ return 0;
+
+ queue_remove(adapter->monitored_devices, mdev);
+
+ free(mdev);
+
return 0;
}

--
1.9.3

2014-05-27 07:52:48

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 6/9] core: Read max TX power when device connected

This patch adds proper support for max TX power, i.e. this property
is refreshed once device is connected.
---
src/adapter.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index f5f8c8c..585f2e2 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -6174,6 +6174,54 @@ static void disconnected_callback(uint16_t index, uint16_t length,
dev_disconnected(adapter, &ev->addr, reason);
}

+static void read_max_tx_power_destroy(void *data)
+{
+ struct btd_device *device = data;
+
+ btd_device_unref(device);
+}
+
+static void read_max_tx_power_rsp(uint8_t status, uint16_t len,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_get_conn_info *rp = param;
+ struct btd_device *device = user_data;
+
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Get Connection Information failed: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ if (len < sizeof(*rp)) {
+ error("Too small Get Connection Information response");
+ return;
+ }
+
+ device_set_conn_max_tx_power(device, rp->max_tx_power);
+}
+
+static void read_max_tx_power(struct btd_adapter *adapter,
+ struct btd_device *device,
+ const bdaddr_t *addr, uint8_t addr_type)
+{
+ struct mgmt_cp_get_conn_info cp;
+ char addrstr[18];
+
+ ba2str(addr, addrstr);
+ DBG("bdaddr %s type %d", addrstr, addr_type);
+
+ btd_device_ref(device);
+
+ memset(&cp, 0, sizeof(cp));
+ bacpy(&cp.addr.bdaddr, addr);
+ cp.addr.type = addr_type;
+
+ mgmt_send(adapter->mgmt, MGMT_OP_GET_CONN_INFO, adapter->dev_id,
+ sizeof(cp), &cp, read_max_tx_power_rsp,
+ device, read_max_tx_power_destroy);
+}
+
static void connected_callback(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
@@ -6220,6 +6268,8 @@ static void connected_callback(uint16_t index, uint16_t length,
btd_device_device_set_name(device, eir_data.name);
}

+ read_max_tx_power(adapter, device, &ev->addr.bdaddr, ev->addr.type);
+
eir_data_free(&eir_data);
}

--
1.9.3

2014-05-27 07:52:46

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 4/9] core: Add ConnectionTXPowerMax property

This patch adds ConnectionTXPowerMax property on org.bluez.Device1
interface which provides maximum local TX power on currently connected
link.

Property value will be read after connection and won't change during
connection lifetime.
---
src/device.c | 31 +++++++++++++++++++++++++++++++
src/device.h | 1 +
2 files changed, 32 insertions(+)

diff --git a/src/device.c b/src/device.c
index ac42a75..8661386 100644
--- a/src/device.c
+++ b/src/device.c
@@ -221,6 +221,7 @@ struct btd_device {

int8_t conn_rssi;
int8_t conn_tx_power;
+ int8_t conn_max_tx_power;

GIOChannel *att_io;
guint cleanup_id;
@@ -851,6 +852,18 @@ static gboolean dev_property_get_conn_txpower(
return TRUE;
}

+static gboolean dev_property_get_conn_max_txpower(
+ const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *device = data;
+ dbus_int16_t val = device->conn_max_tx_power;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
+
+ return TRUE;
+}
+
static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
{
struct btd_device *device = data;
@@ -1946,6 +1959,7 @@ static const GDBusPropertyTable device_properties[] = {
{ "Adapter", "o", dev_property_get_adapter },
{ "ConnectionRSSI", "n", dev_property_get_conn_rssi },
{ "ConnectionTXPower", "n", dev_property_get_conn_txpower },
+ { "ConnectionTXPowerMax", "n", dev_property_get_conn_max_txpower },
{ }
};

@@ -2342,6 +2356,7 @@ static struct btd_device *device_new(struct btd_adapter *adapter,
device->adapter = adapter;

device->conn_tx_power = 127; /* invalid */
+ device->conn_max_tx_power = 127; /* invalid */

return btd_device_ref(device);
}
@@ -4105,6 +4120,22 @@ void device_set_conn_tx_power(struct btd_device *device, int8_t tx_power)
"ConnectionTXPower");
}

+void device_set_conn_max_tx_power(struct btd_device *device, int8_t tx_power)
+{
+ if (!device)
+ return;
+
+ if (device->conn_max_tx_power == tx_power)
+ return;
+
+ DBG("conn_max_tx_power %d", tx_power);
+
+ device->conn_max_tx_power = tx_power;
+
+ g_dbus_emit_property_changed(dbus_conn, device->path, DEVICE_INTERFACE,
+ "ConnectionTXPowerMax");
+}
+
static void device_set_auto_connect(struct btd_device *device, gboolean enable)
{
char addr[18];
diff --git a/src/device.h b/src/device.h
index e0e44cc..b59fa19 100644
--- a/src/device.h
+++ b/src/device.h
@@ -90,6 +90,7 @@ void device_set_legacy(struct btd_device *device, bool legacy);
void device_set_rssi(struct btd_device *device, int8_t rssi);
void device_set_conn_rssi(struct btd_device *device, int8_t rssi);
void device_set_conn_tx_power(struct btd_device *device, int8_t tx_power);
+void device_set_conn_max_tx_power(struct btd_device *device, int8_t tx_power);
bool btd_device_is_connected(struct btd_device *dev);
uint8_t btd_device_get_bdaddr_type(struct btd_device *dev);
bool device_is_retrying(struct btd_device *device);
--
1.9.3

2014-05-27 07:52:44

by Andrzej Kaczmarek

[permalink] [raw]
Subject: [PATCH 2/9] core: Add ConnectionRSSI property

This patch adds ConnectionRSSI property on org.bluez.Device1 interface
which provides RSSI on currently connected link (unlike RSSI which
provides RSSI for inquiry/advertising packets).

Property value will be refreshed once connection monitoring code is in
place.
---
src/device.c | 30 ++++++++++++++++++++++++++++++
src/device.h | 1 +
2 files changed, 31 insertions(+)

diff --git a/src/device.c b/src/device.c
index 8222610..fd4e120 100644
--- a/src/device.c
+++ b/src/device.c
@@ -219,6 +219,8 @@ struct btd_device {
bool legacy;
int8_t rssi;

+ int8_t conn_rssi;
+
GIOChannel *att_io;
guint cleanup_id;
guint store_id;
@@ -825,6 +827,17 @@ static gboolean dev_property_get_trusted(const GDBusPropertyTable *property,
return TRUE;
}

+static gboolean dev_property_get_conn_rssi(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *device = data;
+ dbus_int16_t val = device->conn_rssi;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
+
+ return TRUE;
+}
+
static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
{
struct btd_device *device = data;
@@ -1918,6 +1931,7 @@ static const GDBusPropertyTable device_properties[] = {
{ "Modalias", "s", dev_property_get_modalias, NULL,
dev_property_exists_modalias },
{ "Adapter", "o", dev_property_get_adapter },
+ { "ConnectionRSSI", "n", dev_property_get_conn_rssi },
{ }
};

@@ -4043,6 +4057,22 @@ void device_set_rssi(struct btd_device *device, int8_t rssi)
DEVICE_INTERFACE, "RSSI");
}

+void device_set_conn_rssi(struct btd_device *device, int8_t rssi)
+{
+ if (!device)
+ return;
+
+ if (device->conn_rssi == rssi)
+ return;
+
+ DBG("conn_rssi %d", rssi);
+
+ device->conn_rssi = rssi;
+
+ g_dbus_emit_property_changed(dbus_conn, device->path, DEVICE_INTERFACE,
+ "ConnectionRSSI");
+}
+
static void device_set_auto_connect(struct btd_device *device, gboolean enable)
{
char addr[18];
diff --git a/src/device.h b/src/device.h
index 2e0473e..79d5132 100644
--- a/src/device.h
+++ b/src/device.h
@@ -88,6 +88,7 @@ void btd_device_set_trusted(struct btd_device *device, gboolean trusted);
void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type);
void device_set_legacy(struct btd_device *device, bool legacy);
void device_set_rssi(struct btd_device *device, int8_t rssi);
+void device_set_conn_rssi(struct btd_device *device, int8_t rssi);
bool btd_device_is_connected(struct btd_device *dev);
uint8_t btd_device_get_bdaddr_type(struct btd_device *dev);
bool device_is_retrying(struct btd_device *device);
--
1.9.3

2014-06-02 11:00:00

by Andrzej Kaczmarek

[permalink] [raw]
Subject: Re: [PATCH 1/9] doc: Introduce connection monitoring API

Hi Marcel,

On 31 May 2014 07:17, Marcel Holtmann <[email protected]> wrote:
> Hi Andrzej,
>
>> This patch introduces API to monitor connection parameters.
>>
>> New device properties are introduced: ConnectionRSSI, ConnectionTXPower
>> and ConnectionTXPowerMax.
>>
>> Client can request to poll for updates of RSSI and TX power via Start-
>> and StopConnectionMonitor methods.
>
> I am not convinced on the naming of the method calls and properties. They feel complicated and long and not really clear with its purpose.
>
> What I am curious if we just expose the calculated pathloss or some value that has a more clear sense and usefulness for proximity. Why not do the job for the application instead of letting the application figure it out by itself.

For pathloss you'll need remote TX power so it could be done from PXP
which has (or can have) this value. But still, on BR/EDR pathloss is
kind of useless due to how RSSI is defined.

What if we move these properties to new interface (and perhaps
implement in plugin), something like let's say org.bluez.Connection1?
And mark it as experimental for now, let's see how it works.

BR,
Andrzej