Linux bluetooth development
 help / color / mirror / Atom feed
* Re: Background scanning and white list usage
From: Andre Guedes @ 2014-03-06 21:15 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <B2E73B9C-3787-4B4B-802B-0C76302BF8F9@holtmann.org>

Hi Johan/Marcel,

On 02/28/2014 03:51 AM, Marcel Holtmann wrote:
> Hi Johan,
>
>>> The complicated part comes into play when we have devices with
>>> LE Privacy enabled and when they are using resolvable private
>>> addresses. Meaning when our IRK list is populated with identity
>>> addresses and their IRKs. The only way to make this work with the
>>> current available controller features is if we program the RPA
>>> into the white list. Since that RPA is going to change over time,
>>> we need to stop scanning with the white list filter every now and
>>> then, scan for all devices and resolve the RPA. If we see a new
>>> RPA for a know IRK, we have to replace the old RPA in the white
>>> list with the new RPA. And then we go back to scanning with the
>>> white list filter policy.
>>>
>>> Now the important question is what are good enough intervals to
>>> make this work smoothly. Devices using LE Privacy will take a hit
>>> in their re-connection time, but that is what we have to trade in
>>> for compared to waking up the host for every single advertising
>>> packet.
>>>
>>> My initial idea is to scan 5 minutes using the white list, then
>>> scan 10 seconds without the white list, then back to 5 minutes
>>> using the white list and so on.
>>>
>>> The default value for the PRA lifetime according to the
>>> specification is 15 minutes. I timed recent iOS devices which
>>> seem to be using 9 minutes intervals. So we have to play a little
>>> bit with this and see what are good values.
>>>
>>> Maybe 3 minutes white list scan and 5 seconds without white list
>>> is better. Things to try out.
>>
>> I don't think this is a good idea at all. With LE starting
>> advertising is typically seen as the initiating action of
>> connection creation (unlike with BR/EDR where HCI_Create_Connection
>> is the initiating action). Typically peripherals mean "connect to
>> me now!" when they start connectable advertising.
>>
>> Let's stay you switch on your peripheral device, or it comes into
>> range you haven't used it for some time (hours or even days). If
>> it's using RPAs it's pretty much guaranteed to have a different one
>> than what we know of and even if we're using 3 minutes white list
>> scanning the user is on average going to have to wait for 1.5
>> minutes for the device to get connected which is not acceptable
>> behavior (the extreme example would be if this is a keyboard or a
>> mouse which you start using for the first time in the morning -
>> moving the mouse or pressing a key on the keyboard should certainly
>> get you a connection in less than 1 second).
>
> HID devices would suffer the most here. Fully agree here.
>
> However since neither Microsoft Windows nor OS X can deal with RPAs
> at the moment, I do not think we are entering a dangerous zone here
> from an interoperability point of view. Actually Windows 8.1 is not
> able to connect to any random address for that matter.
>
> My point is that we certainly not make it worse.

HoG is not the only problem. I'm afraid delaying re-connection 3-5
minutes we might become others profiles impractical (e.g. Fob keeps
beeping even if it is beside the cellphone).

>> I fully understand the desire to use the white list as it's a very
>> nice power saving feature, but I don't think we can win here as
>> long as we don't have a way to have the controller do the resolving
>> for us.
>>
>> One thing we could potentially try to do (but which I doubt is
>> really worth it in the end) is to track the age of resolved RPAs.
>> If we have an RPA which was resolved say less than 5 minutes ago we
>> consider it appropriate to place into the white list. Otherwise we
>> skip using the white list.
>
> I was thinking about this as well. Over time we could learn the age
> of a RPA and thus schedule the scanning without white list times most
> efficient. Frankly, I want to get the white list usage going first.
> As long as you only have public or static addresses, it is the way to
> go. And then we optimize it when we have to deal with RPAs.

I agree with Johan about this aging approach, I seems not worthy. 
Honestly, I don't see how we would properly deal with white list and LE 
Privacy issue by now.

> We can not close our eyes to iOS devices using RPAs and I am not
> willing to take the power hit of getting flooded with advertising
> reports.

To fix this other issue (advertising flooding), filtering duplicates is 
just fine.

The problem with enabling filter duplicates in background scan happens 
in the following scenario:
   * Background scan is running.
   * A device disconnects and starts advertising.
   * Before host gets the disconnect event, the advertising is reported
     to host. Since there is no pending LE connection at that time,
     nothing happens.
   * Host gets the disconnection event and adds a pending connection.
   * No advertising is reported (since controller is filtering) and the
     connection is never established.

To address this scenario, all we have to do is: always restart 
background scan when a new LE pending connection is added. This way, we 
unsure that we don't miss the advertising report.

If you guys agree with this approach I can write the patches.

Regards,

Andre

^ permalink raw reply

* Re: [PATCH net-next 0/2] 6lowpan: header cleanup
From: David Miller @ 2014-03-06 22:22 UTC (permalink / raw)
  To: alex.aring
  Cc: marcel, gustavo, johan.hedberg, alex.bluesman.smirnov, dbaryshkov,
	linux-bluetooth, netdev
In-Reply-To: <1394026145-18981-1-git-send-email-alex.aring@gmail.com>

From: Alexander Aring <alex.aring@gmail.com>
Date: Wed,  5 Mar 2014 14:29:03 +0100

> this patch series fix a missing include of 6LoWPAN header and move it
> into the include/net directory. Since we did some code sharing with
> bluetooth 6LoWPAN the header turns into a generic header for 6LoWPAN.
> Instead to use a relative path in bluetooth 6LoWPAN we can now use
> include <net/6lowpan.h>.

Series applied, thanks Alex.

^ permalink raw reply

* [PATCH 1/3] input: Remove input_device.name
From: Petri Gynther @ 2014-03-06 23:00 UTC (permalink / raw)
  To: linux-bluetooth

Remove input_device.name and use input_device.device to get the device name.
---
 profiles/input/device.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index d6e97c7..5235dfd 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -78,7 +78,6 @@ struct input_device {
 	struct hidp_connadd_req *req;
 	guint			dc_id;
 	bool			disable_sdp;
-	char			*name;
 	enum reconnect_mode_t	reconnect_mode;
 	guint			reconnect_timer;
 	uint32_t		reconnect_attempt;
@@ -100,7 +99,6 @@ static void input_device_free(struct input_device *idev)
 
 	btd_service_unref(idev->service);
 	btd_device_unref(idev->device);
-	g_free(idev->name);
 	g_free(idev->path);
 
 	if (idev->ctrl_watch > 0)
@@ -420,8 +418,8 @@ static int hidp_add_connection(struct input_device *idev)
 	req->product = btd_device_get_product(idev->device);
 	req->version = btd_device_get_version(idev->device);
 
-	if (idev->name)
-		strncpy(req->name, idev->name, sizeof(req->name) - 1);
+	if (device_name_known(idev->device))
+		device_get_name(idev->device, req->name, sizeof(req->name));
 
 	/* Encryption is mandatory for keyboards */
 	if (req->subclass & 0x40) {
@@ -808,7 +806,6 @@ static struct input_device *input_device_new(struct btd_service *service)
 	const sdp_record_t *rec = btd_device_get_record(device, p->remote_uuid);
 	struct btd_adapter *adapter = device_get_adapter(device);
 	struct input_device *idev;
-	char name[HCI_MAX_NAME_LENGTH + 1];
 
 	if (!rec)
 		return NULL;
@@ -822,10 +819,6 @@ static struct input_device *input_device_new(struct btd_service *service)
 	idev->handle = rec->handle;
 	idev->disable_sdp = is_device_sdp_disable(rec);
 
-	device_get_name(device, name, sizeof(name));
-	if (strlen(name) > 0)
-		idev->name = g_strdup(name);
-
 	/* Initialize device properties */
 	extract_hid_props(idev, rec);
 
-- 
1.9.0.279.gdc9e3eb


^ permalink raw reply related

* [PATCH 2/3] hog: Remove hog_device.name
From: Petri Gynther @ 2014-03-06 23:00 UTC (permalink / raw)
  To: linux-bluetooth

Remove hog_device.name and use hog_device.device to get the device name.
---
 profiles/input/hog.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index b9a14b9..a9830aa 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -91,7 +91,6 @@ struct hog_device {
 	uint16_t		proto_mode_handle;
 	uint16_t		ctrlpt_handle;
 	uint8_t			flags;
-	char			*name;
 };
 
 struct report {
@@ -393,9 +392,11 @@ static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
 	/* create uHID device */
 	memset(&ev, 0, sizeof(ev));
 	ev.type = UHID_CREATE;
-	strncpy((char *) ev.u.create.name, hogdev->name ?
-					hogdev->name : "bluez-hog-device",
-					sizeof(ev.u.create.name) - 1);
+	if (device_name_known(hogdev->device))
+		device_get_name(hogdev->device, (char *) ev.u.create.name,
+						sizeof(ev.u.create.name));
+	else
+		strcpy((char *) ev.u.create.name, "bluez-hog-device");
 	ev.u.create.vendor = vendor;
 	ev.u.create.product = product;
 	ev.u.create.version = version;
@@ -725,7 +726,6 @@ static struct hog_device *hog_new_device(struct btd_device *device,
 								uint16_t id)
 {
 	struct hog_device *hogdev;
-	char name[HCI_MAX_NAME_LENGTH + 1];
 
 	hogdev = g_try_new0(struct hog_device, 1);
 	if (!hogdev)
@@ -733,9 +733,6 @@ static struct hog_device *hog_new_device(struct btd_device *device,
 
 	hogdev->id = id;
 	hogdev->device = btd_device_ref(device);
-	device_get_name(device, name, sizeof(name));
-	if (strlen(name) > 0)
-		hogdev->name = g_strdup(name);
 
 	return hogdev;
 }
@@ -758,7 +755,6 @@ static void hog_free_device(struct hog_device *hogdev)
 	g_slist_free_full(hogdev->reports, report_free);
 	g_attrib_unref(hogdev->attrib);
 	g_free(hogdev->hog_primary);
-	g_free(hogdev->name);
 	g_free(hogdev);
 }
 
-- 
1.9.0.279.gdc9e3eb


^ permalink raw reply related

* [PATCH 3/3] hog: Fill ev.u.create.{phys,uniq} for UHID_CREATE
From: Petri Gynther @ 2014-03-06 23:00 UTC (permalink / raw)
  To: linux-bluetooth

Fill ev.u.create.{phys,uniq} fields when uHID device is created.
These values are copied to kernel hid_device structure.

linux/include/linux/hid.h:
struct hid_device {
  ...
  char name[128];  /* Device name */
  char phys[64];   /* Device physical location */
  char uniq[64];   /* Device unique identifier (serial #) */
---
 profiles/input/hog.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index a9830aa..fd72e36 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -348,6 +348,7 @@ static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
 							gpointer user_data)
 {
 	struct hog_device *hogdev = user_data;
+	struct btd_adapter *adapter = device_get_adapter(hogdev->device);
 	uint8_t value[HOG_REPORT_MAP_MAX_SIZE];
 	struct uhid_event ev;
 	uint16_t vendor_src, vendor, product, version;
@@ -397,6 +398,8 @@ static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
 						sizeof(ev.u.create.name));
 	else
 		strcpy((char *) ev.u.create.name, "bluez-hog-device");
+	ba2str(btd_adapter_get_address(adapter), (char *) ev.u.create.phys);
+	ba2str(device_get_address(hogdev->device), (char *) ev.u.create.uniq);
 	ev.u.create.vendor = vendor;
 	ev.u.create.product = product;
 	ev.u.create.version = version;
-- 
1.9.0.279.gdc9e3eb


^ permalink raw reply related

* Re: [PATCH 1/3] input: Remove input_device.name
From: Johan Hedberg @ 2014-03-07  7:02 UTC (permalink / raw)
  To: Petri Gynther; +Cc: linux-bluetooth
In-Reply-To: <20140306230023.022CD100A0D@puck.mtv.corp.google.com>

Hi Petri,

On Thu, Mar 06, 2014, Petri Gynther wrote:
> Remove input_device.name and use input_device.device to get the device name.
> ---
>  profiles/input/device.c | 11 ++---------
>  1 file changed, 2 insertions(+), 9 deletions(-)

All three patches in this set have been applied. Thanks.

Johan

^ permalink raw reply

* Re: Background scanning and white list usage
From: Johan Hedberg @ 2014-03-07  7:04 UTC (permalink / raw)
  To: Andre Guedes; +Cc: Marcel Holtmann, linux-bluetooth
In-Reply-To: <5318E560.6050200@openbossa.org>

Hi Andre,

On Thu, Mar 06, 2014, Andre Guedes wrote:
> The problem with enabling filter duplicates in background scan
> happens in the following scenario:
>   * Background scan is running.
>   * A device disconnects and starts advertising.
>   * Before host gets the disconnect event, the advertising is reported
>     to host. Since there is no pending LE connection at that time,
>     nothing happens.
>   * Host gets the disconnection event and adds a pending connection.
>   * No advertising is reported (since controller is filtering) and the
>     connection is never established.
> 
> To address this scenario, all we have to do is: always restart
> background scan when a new LE pending connection is added. This way,
> we unsure that we don't miss the advertising report.
> 
> If you guys agree with this approach I can write the patches.

Sounds fairly reasonable to me, if it actually end up working ok.

Johan

^ permalink raw reply

* Re: Background scanning and white list usage
From: Marcel Holtmann @ 2014-03-07  7:30 UTC (permalink / raw)
  To: Andre Guedes; +Cc: Johan Hedberg, linux-bluetooth
In-Reply-To: <5318E560.6050200@openbossa.org>

Hi Andre,

>>>> The complicated part comes into play when we have devices with
>>>> LE Privacy enabled and when they are using resolvable private
>>>> addresses. Meaning when our IRK list is populated with identity
>>>> addresses and their IRKs. The only way to make this work with the
>>>> current available controller features is if we program the RPA
>>>> into the white list. Since that RPA is going to change over time,
>>>> we need to stop scanning with the white list filter every now and
>>>> then, scan for all devices and resolve the RPA. If we see a new
>>>> RPA for a know IRK, we have to replace the old RPA in the white
>>>> list with the new RPA. And then we go back to scanning with the
>>>> white list filter policy.
>>>> 
>>>> Now the important question is what are good enough intervals to
>>>> make this work smoothly. Devices using LE Privacy will take a hit
>>>> in their re-connection time, but that is what we have to trade in
>>>> for compared to waking up the host for every single advertising
>>>> packet.
>>>> 
>>>> My initial idea is to scan 5 minutes using the white list, then
>>>> scan 10 seconds without the white list, then back to 5 minutes
>>>> using the white list and so on.
>>>> 
>>>> The default value for the PRA lifetime according to the
>>>> specification is 15 minutes. I timed recent iOS devices which
>>>> seem to be using 9 minutes intervals. So we have to play a little
>>>> bit with this and see what are good values.
>>>> 
>>>> Maybe 3 minutes white list scan and 5 seconds without white list
>>>> is better. Things to try out.
>>> 
>>> I don't think this is a good idea at all. With LE starting
>>> advertising is typically seen as the initiating action of
>>> connection creation (unlike with BR/EDR where HCI_Create_Connection
>>> is the initiating action). Typically peripherals mean "connect to
>>> me now!" when they start connectable advertising.
>>> 
>>> Let's stay you switch on your peripheral device, or it comes into
>>> range you haven't used it for some time (hours or even days). If
>>> it's using RPAs it's pretty much guaranteed to have a different one
>>> than what we know of and even if we're using 3 minutes white list
>>> scanning the user is on average going to have to wait for 1.5
>>> minutes for the device to get connected which is not acceptable
>>> behavior (the extreme example would be if this is a keyboard or a
>>> mouse which you start using for the first time in the morning -
>>> moving the mouse or pressing a key on the keyboard should certainly
>>> get you a connection in less than 1 second).
>> 
>> HID devices would suffer the most here. Fully agree here.
>> 
>> However since neither Microsoft Windows nor OS X can deal with RPAs
>> at the moment, I do not think we are entering a dangerous zone here
>> from an interoperability point of view. Actually Windows 8.1 is not
>> able to connect to any random address for that matter.
>> 
>> My point is that we certainly not make it worse.
> 
> HoG is not the only problem. I'm afraid delaying re-connection 3-5
> minutes we might become others profiles impractical (e.g. Fob keeps
> beeping even if it is beside the cellphone).

to be honest not every bonded device needs to auto-reconnect. So this might all work out and when resolution in the controller becomes available, it can be nicely switched over.

>>> I fully understand the desire to use the white list as it's a very
>>> nice power saving feature, but I don't think we can win here as
>>> long as we don't have a way to have the controller do the resolving
>>> for us.
>>> 
>>> One thing we could potentially try to do (but which I doubt is
>>> really worth it in the end) is to track the age of resolved RPAs.
>>> If we have an RPA which was resolved say less than 5 minutes ago we
>>> consider it appropriate to place into the white list. Otherwise we
>>> skip using the white list.
>> 
>> I was thinking about this as well. Over time we could learn the age
>> of a RPA and thus schedule the scanning without white list times most
>> efficient. Frankly, I want to get the white list usage going first.
>> As long as you only have public or static addresses, it is the way to
>> go. And then we optimize it when we have to deal with RPAs.
> 
> I agree with Johan about this aging approach, I seems not worthy. Honestly, I don't see how we would properly deal with white list and LE Privacy issue by now.

As I said, we try out best and see how it works out. The interval can be tweaked of course.

>> We can not close our eyes to iOS devices using RPAs and I am not
>> willing to take the power hit of getting flooded with advertising
>> reports.
> 
> To fix this other issue (advertising flooding), filtering duplicates is just fine.
> 
> The problem with enabling filter duplicates in background scan happens in the following scenario:
>  * Background scan is running.
>  * A device disconnects and starts advertising.
>  * Before host gets the disconnect event, the advertising is reported
>    to host. Since there is no pending LE connection at that time,
>    nothing happens.
>  * Host gets the disconnection event and adds a pending connection.
>  * No advertising is reported (since controller is filtering) and the
>    connection is never established.

that is why we have to disable and re-enable scanning from time to time.

> To address this scenario, all we have to do is: always restart background scan when a new LE pending connection is added. This way, we unsure that we don't miss the advertising report.
> 
> If you guys agree with this approach I can write the patches.

I want to start using the white list for scanning. That is our next step.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH BlueZ] emulator/btdev: Add dummy support for clearing the LE white list
From: Johan Hedberg @ 2014-03-07  9:25 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1393683925-1216-1-git-send-email-anderson.lizardo@openbossa.org>

Hi Lizardo,

On Sat, Mar 01, 2014, Anderson Lizardo wrote:
> Add just enough support for being able to bring up LE capable virtual
> controllers using "btvirt".
> 
> Fixes this error on "btvirt -l2":
> 
> Unsupported command 0x2010
> 
> And on "hciconfig hci0 up":
> 
> Can't init device hci0: Invalid request code (56)
> ---
>  emulator/btdev.c | 7 +++++++
>  1 file changed, 7 insertions(+)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCHv2] android/pics: Change AVRCP to 1.5
From: Szymon Janc @ 2014-03-07  9:51 UTC (permalink / raw)
  To: Sebastian Chlad; +Cc: linux-bluetooth
In-Reply-To: <1394096561-18911-1-git-send-email-sebastian.chlad@tieto.com>

Hi Sebastian,

On Thursday 06 of March 2014 10:02:41 Sebastian Chlad wrote:
> Simple PICS switch from AVRCP 1.3 to 1.5
> ---
>  android/pics-avrcp.txt | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/android/pics-avrcp.txt b/android/pics-avrcp.txt
> index 2be0746..845ba33 100644
> --- a/android/pics-avrcp.txt
> +++ b/android/pics-avrcp.txt
> @@ -336,7 +336,7 @@ TSPC_AVRCP_7_5    True		TG: Receiving UNIT INFO (M)
>  TSPC_AVRCP_7_6    True		TG: Receiving SUBUNIT INFO (M)
>  TSPC_AVRCP_7_7    True		TG: Receiving PASS THROUGH command category 1
>  					(C.1)
> -TSPC_AVRCP_7_8    False		TG: Receiving PASS THROUGH command category 2
> +TSPC_AVRCP_7_8    True (*)	TG: Receiving PASS THROUGH command category 2
>  					(C.1)
>  TSPC_AVRCP_7_9    False		TG: Receiving PASS THROUGH command category 3
>  					(C.1)
> @@ -405,9 +405,9 @@ TSPC_AVRCP_7_56   False		TG: PlayItem(NowPlayingList) (C.11)
>  TSPC_AVRCP_7_57   False		TG: AddToNowPlaying (O)
>  TSPC_AVRCP_7_58   False		TG: EVENT_NOW_PLAYING_CONTENT_CHANGED (C.11)
>  TSPC_AVRCP_7_59   False		TG: Playable Folders (O)
> -TSPC_AVRCP_7_60   False		TG: Absolute Volume (C.5)
> -TSPC_AVRCP_7_61   False		TG: SetAbsoluteVolume (C.5)
> -TSPC_AVRCP_7_62   False		TG: NotifyVolumeChange (C.5)
> +TSPC_AVRCP_7_60   True (*)	TG: Absolute Volume (C.5)
> +TSPC_AVRCP_7_61   True (*)	TG: SetAbsoluteVolume (C.5)
> +TSPC_AVRCP_7_62   True (*)	TG: NotifyVolumeChange (C.5)
>  TSPC_AVRCP_7_63   False		TG: Error Response (O)
>  TSPC_AVRCP_7_64   False		TG: General Reject (C.13)
>  TSPC_AVRCP_7_65   True		TG: Discoverable Mode (M)
> @@ -448,9 +448,9 @@ C.15: Mandatory if Basic Group Navigation Feature supported. If any item
>  Parameter Name    Selected	Description
>  -------------------------------------------------------------------------------
>  TSPC_AVRCP_7b_1   False		TG: AVRCP v1.0 (C.1)
> -TSPC_AVRCP_7b_2   True (*)	TG: AVRCP v1.3 (C.1)
> +TSPC_AVRCP_7b_2   False		TG: AVRCP v1.3 (C.1)
>  TSPC_AVRCP_7b_3   False		TG: AVRCP v1.4 (C.1)
> -TSPC_AVRCP_7b_4   False		TG: AVRCP v1.5 (C.1)
> +TSPC_AVRCP_7b_4   True (*)	TG: AVRCP v1.5 (C.1)
>  TSPC_AVRCP_7b_5   False		TG: AVRCP v1.6 (C.1)
>  -------------------------------------------------------------------------------
>  C.1: It is mandatory to support at least one of the profile versions.
> @@ -523,8 +523,8 @@ TSPC_AVRCP_9_16   False		TG: category 2 - Operation id: display
>  					information (O)
>  TSPC_AVRCP_9_17	  False		TG: category 2 - Operation id: help (O)
>  TSPC_AVRCP_9_18	  False		TG: category 2 - Operation id: power (O)
> -TSPC_AVRCP_9_19   False (*)	TG: category 2 - Operation id: volume up (C.2)
> -TSPC_AVRCP_9_20   False (*)	TG: category 2 - Operation id: volume down (C.2)
> +TSPC_AVRCP_9_19   True		TG: category 2 - Operation id: volume up (C.2)
> +TSPC_AVRCP_9_20   True		TG: category 2 - Operation id: volume down (C.2)
>  TSPC_AVRCP_9_21   False		TG: category 2 - Operation id: mute (O)
>  TSPC_AVRCP_9_24   False		TG: category 2 - Operation id: F1 (O)
>  TSPC_AVRCP_9_25   False		TG: category 2 - Operation id: F2 (O)
> 

Applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH 0/4] android: GATT HAL Implementation
From: Szymon Janc @ 2014-03-07  9:52 UTC (permalink / raw)
  To: Jakub Tyszkowski; +Cc: linux-bluetooth
In-Reply-To: <1394105279-9165-1-git-send-email-jakub.tyszkowski@tieto.com>

Hi Jakub,

On Thursday 06 of March 2014 12:27:55 Jakub Tyszkowski wrote:
> Patchset adds the initial implementation of Android GATT HAL. This will allow
> to start the actual GATT Service development inside the Android daemon.
> 
> Jakub Tyszkowski (4):
>   android/hal-gatt: Add Client Event handlers
>   android/hal-gatt: Add Client API calls
>   android/hal-gatt: Add Server Event handlers
>   android/hal-gatt: Add Server API calls
> 
>  android/hal-gatt.c | 689 ++++++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 655 insertions(+), 34 deletions(-)

All patches applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH 1/2] android: Fix type of discovery on start/stop discovery
From: Lukasz Rymanowski @ 2014-03-07 10:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

Discovering type was confused with adapter settings. With this patch it
is fixed
---
 android/bluetooth.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 1101b64..6d08a50 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2408,14 +2408,13 @@ static void get_adapter_properties(void)
 static bool start_discovery(void)
 {
 	struct mgmt_cp_start_discovery cp;
-	uint8_t type = 1 << BDADDR_BREDR;
 
-	if (adapter.current_settings & type)
-		cp.type = type;
+	if (adapter.current_settings & MGMT_SETTING_BREDR)
+		cp.type = 1 << BDADDR_BREDR;
 	else
 		cp.type = 0;
 
-	DBG("type=0x%x", type);
+	DBG("type=0x%x", cp.type);
 
 	if (mgmt_send(mgmt_if, MGMT_OP_START_DISCOVERY, adapter.index,
 					sizeof(cp), &cp, NULL, NULL, NULL) > 0)
@@ -2428,14 +2427,13 @@ static bool start_discovery(void)
 static bool stop_discovery(void)
 {
 	struct mgmt_cp_stop_discovery cp;
-	uint8_t type = 1 << BDADDR_BREDR;
 
-	if (adapter.current_settings & type)
-		cp.type = type;
+	if (adapter.current_settings & MGMT_SETTING_BREDR)
+		cp.type = 1 << BDADDR_BREDR;
 	else
 		cp.type = 0;
 
-	DBG("type=0x%x", type);
+	DBG("type=0x%x", cp.type);
 
 	if (mgmt_send(mgmt_if, MGMT_OP_STOP_DISCOVERY, adapter.index,
 					sizeof(cp), &cp, NULL, NULL, NULL) > 0)
-- 
1.8.4


^ permalink raw reply related

* [PATCH 2/2] android: Support LE discovery if adapter supports LE
From: Lukasz Rymanowski @ 2014-03-07 10:28 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski
In-Reply-To: <1394188110-16336-1-git-send-email-lukasz.rymanowski@tieto.com>

---
 android/bluetooth.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 6d08a50..c6e40ca 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2414,6 +2414,9 @@ static bool start_discovery(void)
 	else
 		cp.type = 0;
 
+	if (adapter.current_settings & MGMT_SETTING_LE)
+		cp.type |= (1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM);
+
 	DBG("type=0x%x", cp.type);
 
 	if (mgmt_send(mgmt_if, MGMT_OP_START_DISCOVERY, adapter.index,
@@ -2433,6 +2436,9 @@ static bool stop_discovery(void)
 	else
 		cp.type = 0;
 
+	if (adapter.current_settings & MGMT_SETTING_LE)
+		cp.type |= (1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM);
+
 	DBG("type=0x%x", cp.type);
 
 	if (mgmt_send(mgmt_if, MGMT_OP_STOP_DISCOVERY, adapter.index,
-- 
1.8.4


^ permalink raw reply related

* [PATCH 1/9] unit/avrcp: Add /TP/MDI/BV-01-C test
From: Andrei Emeltchenko @ 2014-03-07 11:51 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Test verifies Get play status.
---
 unit/test-avrcp.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index db1a67e..4f81954 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -459,6 +459,23 @@ static ssize_t avrcp_handle_set_player_value(struct avrcp *session,
 	return 1;
 }
 
+static ssize_t avrcp_handle_get_play_status(struct avrcp *session,
+						uint8_t transaction,
+						uint16_t params_len,
+						uint8_t *params,
+						void *user_data)
+{
+	DBG("");
+
+	if (params_len)
+		return -EINVAL;
+
+	avrcp_get_play_status_rsp(session, transaction, 0xaaaaaaaa, 0xbbbbbbbb,
+									0x00);
+
+	return -EAGAIN;
+}
+
 static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_CAPABILITIES,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -481,6 +498,9 @@ static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_SET_PLAYER_VALUE,
 					AVC_CTYPE_CONTROL, AVC_CTYPE_STABLE,
 					avrcp_handle_set_player_value },
+		{ AVRCP_GET_PLAY_STATUS,
+					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+					avrcp_handle_get_play_status },
 		{ },
 };
 
@@ -782,5 +802,16 @@ int main(int argc, char *argv[])
 				0x00, 0x19, 0x58, AVRCP_GET_PLAY_STATUS,
 				0x00, 0x00, 0x00));
 
+	/* Get play status - TG */
+	define_test("/TP/MDI/BV-02-C", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_GET_PLAY_STATUS,
+				0x00, 0x00, 0x00),
+			raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_GET_PLAY_STATUS,
+				0x00, 0x00, 0x09, 0xaa, 0xaa, 0xaa,
+				0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0x00));
+
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 2/9] android/avrcp: Add avrcp_get_element_attributes() function
From: Andrei Emeltchenko @ 2014-03-07 11:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394193113-32347-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 android/avrcp-lib.c | 13 +++++++++++++
 android/avrcp-lib.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index cd39071..fbaa48d 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -403,6 +403,19 @@ int avrcp_get_play_status(struct avrcp *session, avctp_rsp_cb func,
 				user_data);
 }
 
+int avrcp_get_element_attributes(struct avrcp *session, avctp_rsp_cb func,
+								void *user_data)
+{
+	uint8_t buf[9];
+
+	/* This returns all attributes */
+	memset(buf, 0, sizeof(buf));
+
+	return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
+				AVRCP_GET_ELEMENT_ATTRIBUTES, buf, sizeof(buf),
+				func, user_data);
+}
+
 int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction,
 				uint32_t position, uint32_t duration,
 				uint8_t status)
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index ba1d84a..5e90ea1 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -145,6 +145,8 @@ int avrcp_get_current_player_value(struct avrcp *session, uint8_t *attrs,
 					void *user_data);
 int avrcp_get_play_status(struct avrcp *session, avctp_rsp_cb func,
 							void *user_data);
+int avrcp_get_element_attributes(struct avrcp *session, avctp_rsp_cb func,
+							void *user_data);
 
 int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction,
 				uint32_t position, uint32_t duration,
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 3/9] unit/avrcp: Add /TP/MDI/BV-03-C test
From: Andrei Emeltchenko @ 2014-03-07 11:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394193113-32347-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Test verifies that Get element attributes issued correctly.
---
 unit/test-avrcp.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 4f81954..9b334e6 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -553,6 +553,9 @@ static void test_client(gconstpointer data)
 	if (g_str_equal(context->data->test_name, "/TP/MDI/BV-01-C"))
 		avrcp_get_play_status(context->session, NULL, NULL);
 
+	if (g_str_equal(context->data->test_name, "/TP/MDI/BV-03-C"))
+		avrcp_get_element_attributes(context->session, NULL, NULL);
+
 	execute_context(context);
 }
 
@@ -812,6 +815,12 @@ int main(int argc, char *argv[])
 				0x00, 0x00, 0x09, 0xaa, 0xaa, 0xaa,
 				0xaa, 0xbb, 0xbb, 0xbb, 0xbb, 0x00));
 
+	/* Get element attributes - CT */
+	define_test("/TP/MDI/BV-03-C", test_client,
+			raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_GET_ELEMENT_ATTRIBUTES,
+				0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
 
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 4/9] unit/avrcp: Add /TP/MDI/BV-04-C test
From: Andrei Emeltchenko @ 2014-03-07 11:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394193113-32347-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Test verifies Get element attributes responded by Target.
---
 unit/test-avrcp.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 9b334e6..393afee 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -476,6 +476,22 @@ static ssize_t avrcp_handle_get_play_status(struct avrcp *session,
 	return -EAGAIN;
 }
 
+static ssize_t avrcp_handle_get_element_attrs(struct avrcp *session,
+						uint8_t transaction,
+						uint16_t params_len,
+						uint8_t *params,
+						void *user_data)
+{
+	DBG("");
+
+	if (params_len < 9)
+		return -EINVAL;
+
+	avrcp_get_element_attrs_rsp(session, transaction, NULL, 0);
+
+	return -EAGAIN;
+}
+
 static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_CAPABILITIES,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -501,6 +517,9 @@ static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_PLAY_STATUS,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
 					avrcp_handle_get_play_status },
+		{ AVRCP_GET_ELEMENT_ATTRIBUTES,
+					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+					avrcp_handle_get_element_attrs },
 		{ },
 };
 
@@ -822,5 +841,14 @@ int main(int argc, char *argv[])
 				0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
 
+	/* Get element attributes - TG */
+	define_test("/TP/MDI/BV-04-C", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_GET_ELEMENT_ATTRIBUTES,
+				0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+			raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_GET_ELEMENT_ATTRIBUTES,
+				0x00, 0x00, 0x00));
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 5/9] unit/avrcp: Add /TP/MDI/BV-05-C test
From: Andrei Emeltchenko @ 2014-03-07 11:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394193113-32347-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Test verifies that Target responds to Get element attributes cmd.
---
 unit/test-avrcp.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 393afee..496dd1b 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -482,11 +482,14 @@ static ssize_t avrcp_handle_get_element_attrs(struct avrcp *session,
 						uint8_t *params,
 						void *user_data)
 {
-	DBG("");
+	DBG("params_len %d params[8] %d", params_len, params[8]);
 
 	if (params_len < 9)
 		return -EINVAL;
 
+	if (params_len != 9 + params[8] * 4)
+		return -EINVAL;
+
 	avrcp_get_element_attrs_rsp(session, transaction, NULL, 0);
 
 	return -EAGAIN;
@@ -850,5 +853,17 @@ int main(int argc, char *argv[])
 			raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
 				0x00, 0x19, 0x58, AVRCP_GET_ELEMENT_ATTRIBUTES,
 				0x00, 0x00, 0x00));
+
+	/* Get element attributes - TG */
+	define_test("/TP/MDI/BV-05-C", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_GET_ELEMENT_ATTRIBUTES,
+				0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+				0x00, 0x00, 0x00, 0x01),
+			raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_GET_ELEMENT_ATTRIBUTES,
+				0x00, 0x00, 0x00));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 6/9] android/avrcp: Add avrcp_register_notification() function
From: Andrei Emeltchenko @ 2014-03-07 11:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394193113-32347-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 android/avrcp-lib.c | 14 ++++++++++++++
 android/avrcp-lib.h |  6 ++++++
 2 files changed, 20 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index fbaa48d..1663218 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -416,6 +416,20 @@ int avrcp_get_element_attributes(struct avrcp *session, avctp_rsp_cb func,
 				func, user_data);
 }
 
+int avrcp_register_notification(struct avrcp *session, uint8_t event,
+				uint32_t interval, avctp_rsp_cb func,
+				void *user_data)
+{
+	uint8_t pdu[AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH];
+
+	pdu[0] = event;
+	bt_put_be32(interval, &pdu[1]);
+
+	return avrcp_send_req(session, AVC_CTYPE_NOTIFY, AVC_SUBUNIT_PANEL,
+				AVRCP_REGISTER_NOTIFICATION, pdu, sizeof(pdu),
+				func, user_data);
+}
+
 int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction,
 				uint32_t position, uint32_t duration,
 				uint8_t status)
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 5e90ea1..b0a1025 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -86,6 +86,9 @@
 /* Company IDs for vendor dependent commands */
 #define IEEEID_BTSIG		0x001958
 
+/* Parameters legths */
+#define AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH	5
+
 struct avrcp;
 
 struct avrcp_control_handler {
@@ -147,6 +150,9 @@ int avrcp_get_play_status(struct avrcp *session, avctp_rsp_cb func,
 							void *user_data);
 int avrcp_get_element_attributes(struct avrcp *session, avctp_rsp_cb func,
 							void *user_data);
+int avrcp_register_notification(struct avrcp *session, uint8_t event,
+				uint32_t interval, avctp_rsp_cb func,
+				void *user_data);
 
 int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction,
 				uint32_t position, uint32_t duration,
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 7/9] unit/avrcp: Add /TP/NFY/BV-01-C test
From: Andrei Emeltchenko @ 2014-03-07 11:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394193113-32347-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Test verifies that Register notification command is issued by
Controller.
---
 unit/test-avrcp.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 496dd1b..fa4870d 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -578,6 +578,11 @@ static void test_client(gconstpointer data)
 	if (g_str_equal(context->data->test_name, "/TP/MDI/BV-03-C"))
 		avrcp_get_element_attributes(context->session, NULL, NULL);
 
+	if (g_str_equal(context->data->test_name, "/TP/NFY/BV-01-C"))
+		avrcp_register_notification(context->session,
+						AVRCP_EVENT_STATUS_CHANGED, 0,
+						NULL, NULL);
+
 	execute_context(context);
 }
 
@@ -865,5 +870,14 @@ int main(int argc, char *argv[])
 				0x00, 0x19, 0x58, AVRCP_GET_ELEMENT_ATTRIBUTES,
 				0x00, 0x00, 0x00));
 
+	/* Notification Commands */
+
+	/* Register notification - CT */
+	define_test("/TP/NFY/BV-01-C", test_client,
+			raw_pdu(0x00, 0x11, 0x0e, 0x03, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x05, AVRCP_EVENT_STATUS_CHANGED,
+				0x00, 0x00, 0x00, 0x00));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 8/9] unit/avrcp: Add /TP/NFY/BV-02-C test
From: Andrei Emeltchenko @ 2014-03-07 11:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394193113-32347-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Test verifies that Target responds to Register notification command.
---
 unit/test-avrcp.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index fa4870d..20445ff 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -162,7 +162,7 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
 	ssize_t len;
 	int fd;
 
-	pdu = &context->data->pdu_list[context->pdu_offset++];
+	DBG("");
 
 	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
 		context->source = 0;
@@ -172,6 +172,9 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
 
 	fd = g_io_channel_unix_get_fd(channel);
 
+again:
+	pdu = &context->data->pdu_list[context->pdu_offset++];
+
 	len = read(fd, buf, sizeof(buf));
 
 	g_assert(len > 0);
@@ -183,6 +186,10 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
 
 	g_assert(memcmp(buf, pdu->data, pdu->size) == 0);
 
+	if (g_str_equal(context->data->test_name, "/TP/NFY/BV-02-C") &&
+						context->pdu_offset == 2)
+		goto again;
+
 	if (!pdu->fragmented)
 		context_process(context);
 
@@ -495,6 +502,43 @@ static ssize_t avrcp_handle_get_element_attrs(struct avrcp *session,
 	return -EAGAIN;
 }
 
+static ssize_t avrcp_handle_register_notification(struct avrcp *session,
+							uint8_t transaction,
+							uint16_t params_len,
+							uint8_t *params,
+							void *user_data)
+{
+	uint8_t event;
+	uint8_t pdu[1024];
+	size_t pdu_len;
+
+	DBG("");
+
+	if (params_len != AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH)
+		return -EINVAL;
+
+	event = params[0];
+	pdu[0] = event;
+	pdu_len = 1;
+
+	switch (event) {
+	case AVRCP_EVENT_TRACK_CHANGED:
+		memset(&pdu[1], 0xff, 8);
+		pdu_len += 8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	avrcp_register_notification_rsp(session, transaction, AVC_CTYPE_INTERIM,
+						pdu, pdu_len);
+
+	avrcp_register_notification_rsp(session, transaction, AVC_CTYPE_CHANGED,
+						pdu, pdu_len);
+
+	return -EAGAIN;
+}
+
 static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_CAPABILITIES,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -523,6 +567,9 @@ static const struct avrcp_control_handler control_handlers[] = {
 		{ AVRCP_GET_ELEMENT_ATTRIBUTES,
 					AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
 					avrcp_handle_get_element_attrs },
+		{ AVRCP_REGISTER_NOTIFICATION,
+					AVC_CTYPE_NOTIFY, AVC_CTYPE_INTERIM,
+					avrcp_handle_register_notification },
 		{ },
 };
 
@@ -879,5 +926,22 @@ int main(int argc, char *argv[])
 				0x00, 0x00, 0x05, AVRCP_EVENT_STATUS_CHANGED,
 				0x00, 0x00, 0x00, 0x00));
 
+	/* Register notification - TG */
+	define_test("/TP/NFY/BV-02-C", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x03, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x05, AVRCP_EVENT_TRACK_CHANGED,
+				0x00, 0x00, 0x00, 0x00),
+			raw_pdu(0x02, 0x11, 0x0e, AVC_CTYPE_INTERIM, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x09, AVRCP_EVENT_TRACK_CHANGED,
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				0xff, 0xff),
+			raw_pdu(0x02, 0x11, 0x0e, AVC_CTYPE_CHANGED, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x09, AVRCP_EVENT_TRACK_CHANGED,
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				0xff, 0xff));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 9/9] doc: Update test coverage document
From: Andrei Emeltchenko @ 2014-03-07 11:51 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394193113-32347-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 doc/test-coverage.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/test-coverage.txt b/doc/test-coverage.txt
index 244e0c6..1bac0f8 100644
--- a/doc/test-coverage.txt
+++ b/doc/test-coverage.txt
@@ -19,7 +19,7 @@ test-queue		   1	Queue handling functionality
 test-hfp		   9	HFP Audio Gateway functionality
 test-avdtp		  60	AVDTP qualification test cases
 test-avctp		   9	AVCTP qualification test cases
-test-avrcp		  24	AVRCP qualification test cases
+test-avrcp		  32	AVRCP qualification test cases
 test-gobex		  31	Generic OBEX functionality
 test-gobex-packet	   9	OBEX packet handling
 test-gobex-header	  28	OBEX header handling
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH BlueZ 1/4] android/avrcp-lib: Add avrcp_register_notification function
From: Luiz Augusto von Dentz @ 2014-03-07 12:15 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds avrcp_register_notification which can be used to send
RegisterNotification PDUs.
---
 android/avrcp-lib.c | 15 +++++++++++++++
 android/avrcp-lib.h |  3 +++
 2 files changed, 18 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index d66560b..a5530ec 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -334,6 +334,21 @@ int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
 				func, user_data);
 }
 
+int avrcp_register_notification(struct avrcp *session, uint8_t event,
+					uint32_t interval, avctp_rsp_cb func,
+					void *user_data)
+{
+	uint8_t params[5];
+
+	params[0] = event;
+	bt_put_be32(interval, &params[1]);
+
+	return avrcp_send_req(session, AVC_CTYPE_NOTIFY, AVC_SUBUNIT_PANEL,
+					AVRCP_REGISTER_NOTIFICATION,
+					params, sizeof(params),
+					func, user_data);
+}
+
 int avrcp_list_player_attributes(struct avrcp *session, avctp_rsp_cb func,
 								void *user_data)
 {
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index ba1d84a..4a49fe7 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -132,6 +132,9 @@ int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code,
 					uint8_t *params, size_t params_len);
 int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
 					avctp_rsp_cb func, void *user_data);
+int avrcp_register_notification(struct avrcp *session, uint8_t event,
+					uint32_t interval, avctp_rsp_cb func,
+					void *user_data);
 int avrcp_list_player_attributes(struct avrcp *session, avctp_rsp_cb func,
 							void *user_data);
 int avrcp_get_player_attribute_text(struct avrcp *session, uint8_t *attributes,
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH BlueZ 2/4] android/avrcp: Add support to receive volume changed notifications
From: Luiz Augusto von Dentz @ 2014-03-07 12:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394194543-3095-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This checks if remote stack supports volume changed notification and
in case it does register to receive notification when volume changes.
---
 android/avrcp.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/android/avrcp.c b/android/avrcp.c
index 1d211ad..978e6c0 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -700,6 +700,83 @@ static const struct avrcp_control_handler control_handlers[] = {
 		{ },
 };
 
+static gboolean register_notification_rsp(struct avctp *conn,
+					uint8_t code, uint8_t subunit,
+					uint8_t *operands, size_t operand_count,
+					void *user_data)
+{
+	struct avrcp_device *dev = user_data;
+	struct hal_ev_avrcp_volume_changed ev;
+	uint8_t *params;
+
+	if (code != AVC_CTYPE_INTERIM && code != AVC_CTYPE_CHANGED)
+		return FALSE;
+
+	if (operands == NULL || operand_count < 7)
+		return FALSE;
+
+	params = &operands[7];
+
+	if (params == NULL || params[0] != AVRCP_EVENT_VOLUME_CHANGED)
+		return FALSE;
+
+	switch (code) {
+	case AVC_CTYPE_INTERIM:
+		ev.type = HAL_AVRCP_EVENT_TYPE_INTERIM;
+		break;
+	case AVC_CTYPE_CHANGED:
+		ev.type = HAL_AVRCP_EVENT_TYPE_CHANGED;
+		break;
+	default:
+		return FALSE;
+	}
+
+	ev.volume = params[1] & 0x7F;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
+					HAL_EV_AVRCP_VOLUME_CHANGED,
+					sizeof(ev), &ev);
+
+	if (code == AVC_CTYPE_INTERIM)
+		return TRUE;
+
+	avrcp_register_notification(dev->session, params[0], 0,
+					register_notification_rsp, dev);
+	return FALSE;
+}
+
+static gboolean get_capabilities_rsp(struct avctp *conn,
+					uint8_t code, uint8_t subunit,
+					uint8_t *operands, size_t operand_count,
+					void *user_data)
+{
+	struct avrcp_device *dev = user_data;
+	uint8_t *params;
+	uint8_t count;
+
+	if (operands == NULL || operand_count < 7)
+		return FALSE;
+
+	params = &operands[7];
+
+	if (params == NULL || params[0] != CAP_EVENTS_SUPPORTED)
+		return FALSE;
+
+	for (count = params[1]; count > 0; count--) {
+		uint8_t event = params[1 + count];
+
+		if (event != AVRCP_EVENT_VOLUME_CHANGED)
+			continue;
+
+		avrcp_register_notification(dev->session, event, 0,
+						register_notification_rsp,
+						dev);
+		return FALSE;
+	}
+
+	return FALSE;
+}
+
 static int avrcp_device_add_session(struct avrcp_device *dev, int fd,
 						uint16_t imtu, uint16_t omtu)
 {
@@ -732,6 +809,14 @@ static int avrcp_device_add_session(struct avrcp_device *dev, int fd,
 
 	ev.features |= HAL_AVRCP_FEATURE_METADATA;
 
+	if (dev->version < 0x0104)
+		goto done;
+
+	ev.features |= HAL_AVRCP_FEATURE_ABSOLUTE_VOLUME;
+
+	avrcp_get_capabilities(dev->session, CAP_EVENTS_SUPPORTED,
+						get_capabilities_rsp, dev);
+
 done:
 	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP,
 					HAL_EV_AVRCP_REMOTE_FEATURES,
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH BlueZ 3/4] android/avrcp-lib: Add avrcp_set_volume function
From: Luiz Augusto von Dentz @ 2014-03-07 12:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394194543-3095-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds avrcp_set_volume function which can be used to send
SetAbsoluteVolume PDUs.
---
 android/avrcp-lib.c | 9 +++++++++
 android/avrcp-lib.h | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index a5530ec..bd1e7da 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -416,6 +416,15 @@ int avrcp_get_play_status(struct avrcp *session, avctp_rsp_cb func,
 				user_data);
 }
 
+int avrcp_set_volume(struct avrcp *session, uint8_t volume, avctp_rsp_cb func,
+							void *user_data)
+{
+	return avrcp_send_req(session, AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL,
+						AVRCP_SET_ABSOLUTE_VOLUME,
+						&volume, sizeof(volume),
+						func, user_data);
+}
+
 int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction,
 				uint32_t position, uint32_t duration,
 				uint8_t status)
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 4a49fe7..30d220e 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -148,6 +148,8 @@ int avrcp_get_current_player_value(struct avrcp *session, uint8_t *attrs,
 					void *user_data);
 int avrcp_get_play_status(struct avrcp *session, avctp_rsp_cb func,
 							void *user_data);
+int avrcp_set_volume(struct avrcp *session, uint8_t volume, avctp_rsp_cb func,
+							void *user_data);
 
 int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction,
 				uint32_t position, uint32_t duration,
-- 
1.8.5.3


^ permalink raw reply related


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