Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH] android-tester: Add possibility to debug mgmt
From: Johan Hedberg @ 2014-01-13  8:45 UTC (permalink / raw)
  To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1389360214-31932-1-git-send-email-marcin.kraglak@tieto.com>

Hi Marcin,

On Fri, Jan 10, 2014, Marcin Kraglak wrote:
> Print mgmt debug info if debug flag is set in android-tester.
> ---
>  android/android-tester.c | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] btproxy: Fix double close
From: Johan Hedberg @ 2014-01-13  8:42 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1389258082-10847-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Thu, Jan 09, 2014, Andrei Emeltchenko wrote:
> setup_streams() already makes close()
> ---
>  tools/btproxy.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] android/pts: Update PTS results for MAP
From: Johan Hedberg @ 2014-01-13  8:40 UTC (permalink / raw)
  To: Jakub Tyszkowski; +Cc: linux-bluetooth
In-Reply-To: <1389171173-30512-1-git-send-email-jakub.tyszkowski@tieto.com>

Hi Jakub,

On Wed, Jan 08, 2014, Jakub Tyszkowski wrote:
> Update MAP PTS results for BlueZ stack on Nexus4 (Android 4.4.2).
> ---
>  android/pts-map.txt | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH -next] Bluetooth: Convert to use ATTRIBUTE_GROUPS macro
From: Johan Hedberg @ 2014-01-13  8:27 UTC (permalink / raw)
  To: Wei Yongjun; +Cc: marcel, gustavo, yongjun_wei, linux-bluetooth
In-Reply-To: <CAPgLHd9XikeBP3moVKugtsAD83CD1HqE82KeYOyYNdY+=0vctQ@mail.gmail.com>

Hi,

On Tue, Jan 07, 2014, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> 
> Use ATTRIBUTE_GROUPS macro to reduce the number of lines of code.
> 
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
> ---
>  net/bluetooth/hci_sysfs.c | 18 ++----------------
>  1 file changed, 2 insertions(+), 16 deletions(-)

Applied to the bluetooth-next tree. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] android/ipc: Use proper handlers in ipc_handle_msg
From: Szymon Janc @ 2014-01-13  8:11 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1389565338-12618-1-git-send-email-andrzej.kaczmarek@tieto.com>

Hi Andrzej,

On Sunday 12 of January 2014 23:22:18 Andrzej Kaczmarek wrote:
> ipc_handle_msg() should use handlers passed as function parameter
> instead of static one as otherwise Audio IPC will use incorrect
> handlers.
> ---
>  android/ipc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/android/ipc.c b/android/ipc.c
> index a31d315..ed3ef3c 100644
> --- a/android/ipc.c
> +++ b/android/ipc.c
> @@ -82,7 +82,7 @@ int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
>  	}
>  
>  	/* opcode is table offset + 1 */
> -	handler = &services[msg->service_id].handler[msg->opcode - 1];
> +	handler = &handlers[msg->service_id].handler[msg->opcode - 1];
>  
>  	/* if payload size is valid */
>  	if ((handler->var_len && handler->data_len > msg->len) ||
> 

Applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH 2/2] android/pics: Add PICS and PIXIT for A2DP
From: Jakub Tyszkowski @ 2014-01-13  8:11 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389600696-32598-1-git-send-email-jakub.tyszkowski@tieto.com>

Add PICS/PIXIT for A2DP targeting Android 4.4.
---
 android/Makefile.am    |  1 +
 android/pics-a2dp.txt  | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++
 android/pixit-a2dp.txt | 30 ++++++++++++++++++
 3 files changed, 117 insertions(+)
 create mode 100644 android/pics-a2dp.txt
 create mode 100644 android/pixit-a2dp.txt

diff --git a/android/Makefile.am b/android/Makefile.am
index 98d21d8..356f932 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -148,4 +148,5 @@ EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
 		android/pixit-map.txt android/pts-map.txt \
 		android/pics-l2cap.txt android/pixit-l2cap.txt \
 		android/pics-avrcp.txt android/pixit-avrcp.txt \
+		android/pics-a2dp.txt android/pixit-a2dp.txt \
 		android/pts-l2cap.txt
diff --git a/android/pics-a2dp.txt b/android/pics-a2dp.txt
new file mode 100644
index 0000000..1579567
--- /dev/null
+++ b/android/pics-a2dp.txt
@@ -0,0 +1,86 @@
+A2DP PICS for the PTS tool.
+
+PTS version: 5.0
+
+* - different than PTS defaults
+# - not yet implemented/supported
+
+M - mandatory if such role selected
+O - optional
+
+		Roles
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_A2DP_1_1	True		Role: Source (C.1)
+TSPC_A2DP_1_2	False (*)	Role: Sink (C.1)
+-------------------------------------------------------------------------------
+C.1: It is mandatory to support at least one of the defined roles.
+-------------------------------------------------------------------------------
+
+
+		A2DP SRC Features
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_A2DP_2_1	True		SRC: Initiate connection establishment (M)
+TSPC_A2DP_2_2	True		SRC: Accept connection establishment (M)
+TSPC_A2DP_2_3	True		SRC: Initiate start streaming (M)
+TSPC_A2DP_2_4	True		SRC: Accept start streaming (M)
+TSPC_A2DP_2_5	True		SRC: Send audio stream (M)
+TSPC_A2DP_2_6	True		SRC: Initiate connection release (M)
+TSPC_A2DP_2_7	True		SRC: Accept connection release (M)
+TSPC_A2DP_2_8	True (*)	SRC: Initiate suspend (O)
+TSPC_A2DP_2_9	True (*)	SRC: Accept suspend (O)
+TSPC_A2DP_2_10	True		SRC: SBC encoder (M)
+TSPC_A2DP_2_10a	False		SRC: Encode Audio Stream (O)
+TSPC_A2DP_2_11	False		SRC: SBC Configurations in 16 KHz sampling (O)
+TSPC_A2DP_2_12	False		SRC: SBC Configurations in 32 KHz sampling (O)
+TSPC_A2DP_2_13	True		SRC: SBC Configurations in 44.1 KHz sampling
+					(C.1)
+TSPC_A2DP_2_14	False		SRC: SBC Configurations in 48 KHz sampling
+					(C.1)
+-------------------------------------------------------------------------------
+C.1: At least one of the values shall be supported.
+-------------------------------------------------------------------------------
+
+
+		Supported Codecs in SRC
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_A2DP_3_1	True		SRC: SBC encoder Codec (M)
+TSPC_A2DP_3_2	False		SRC: Additional encoder Codec (O)
+-------------------------------------------------------------------------------
+
+
+		A2DP Sink Features
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_A2DP_4_1	False		SNK: Initiate connection establishment (O)
+TSPC_A2DP_4_2	False (*)	SNK: Accept connection establishment (M)
+TSPC_A2DP_4_3	False		SNK: Initiate start streaming (O)
+TSPC_A2DP_4_4	False (*)	SNK: Accept start streaming (M)
+TSPC_A2DP_4_5	False (*)	SNK: Receive audio stream (M)
+TSPC_A2DP_4_6	False		SNK: Initiate connection release (O)
+TSPC_A2DP_4_7	False (*)	SNK: Accept connection release (M)
+TSPC_A2DP_4_8	False		SNK: Initiate suspend (O)
+TSPC_A2DP_4_9	False		SNK: Accept suspend (O)
+TSPC_A2DP_4_10	False (*)	SNK: SBC decoder (M)
+TSPC_A2DP_4_10a	False (*)	SNK: Decode Audio Stream (O)
+TSPC_A2DP_4_11	False		SNK: SBC Configurations in 16 KHz sampling (O)
+TSPC_A2DP_4_12	False		SNK: SBC Configurations in 32 KHz sampling (O)
+TSPC_A2DP_4_13	False (*)	SNK: SBC Configurations in 44.1 KHz sampling (M)
+TSPC_A2DP_4_14	False (*)	SNK: SBC Configurations in 48 KHz sampling (M)
+-------------------------------------------------------------------------------
+
+
+		Supported codecs in SNK
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_A2DP_5_1	False		SNK: SBC decoder Codec (M)
+TSPC_A2DP_5_2	False		SNK: Additional decoder Coded (O)
+TSPC_ALL	False		Enable all test cases when set to False.
+-------------------------------------------------------------------------------
diff --git a/android/pixit-a2dp.txt b/android/pixit-a2dp.txt
new file mode 100644
index 0000000..d060045
--- /dev/null
+++ b/android/pixit-a2dp.txt
@@ -0,0 +1,30 @@
+A2DP PIXIT for the PTS tool.
+
+PTS version: 5.0
+
+* - different than PTS defaults
+& - should be set to IUT Bluetooth address
+# - should be set to PTS's bin/audio folder
+
+Required PIXIT settings
+-------------------------------------------------------------------------------
+Parameter Name			Value
+-------------------------------------------------------------------------------
+TSPX_security_enabled		FALSE
+TSPX_bd_addr_iut		112233445566 (*&)
+TSPX_SRC_class_of_device	080418
+TSPX_SNK_class_of_device	04041C
+TSPX_pin_code			0000
+TSPX_delete_link_key		FALSE
+TSPX_time_guard			300000
+TSPX_use_implicit_send		TRUE
+TSPX_media_directory		C:\Program Files\Bluetooth SIG\Bluetooth PTS\
+					bin\audio (#)
+TSPX_no_avrcp			TRUE
+TSPX_auth_password		0000
+TSPX_auth_user_id		PTS
+TSPX_rfcomm_channel		8
+TSPX_l2cap_psm			1011
+TSPX_no_confirmations		FALSE
+TSPX_cover_art_uuid		3EEE
+-------------------------------------------------------------------------------
-- 
1.8.5


^ permalink raw reply related

* [PATCH 1/2] android/pics: Add PICS and PIXIT for AVRCP
From: Jakub Tyszkowski @ 2014-01-13  8:11 UTC (permalink / raw)
  To: linux-bluetooth

Add PICS/PIXIT for AVRCP targeting Android 4.4.
---
 android/Makefile.am     |   1 +
 android/pics-avrcp.txt  | 626 ++++++++++++++++++++++++++++++++++++++++++++++++
 android/pixit-avrcp.txt |  36 +++
 3 files changed, 663 insertions(+)
 create mode 100644 android/pics-avrcp.txt
 create mode 100644 android/pixit-avrcp.txt

diff --git a/android/Makefile.am b/android/Makefile.am
index a3ee148..98d21d8 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -147,4 +147,5 @@ EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
 		android/audio-ipc-api.txt android/pics-map.txt \
 		android/pixit-map.txt android/pts-map.txt \
 		android/pics-l2cap.txt android/pixit-l2cap.txt \
+		android/pics-avrcp.txt android/pixit-avrcp.txt \
 		android/pts-l2cap.txt
diff --git a/android/pics-avrcp.txt b/android/pics-avrcp.txt
new file mode 100644
index 0000000..2be0746
--- /dev/null
+++ b/android/pics-avrcp.txt
@@ -0,0 +1,626 @@
+AVRCP PICS for the PTS tool.
+
+PTS version: 5.0
+
+* - different than PTS defaults
+# - not yet implemented/supported
+
+M - mandatory if such role selected
+O - optional
+
+		Roles
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+SPC_AVRCP_1_1     False (*)	Role: Controller (CT) (C.1)
+TSPC_AVRCP_1_2    True		Role: Target (TG) (C.1)
+-------------------------------------------------------------------------------
+C.1: Mandatory to support at least one of the defined roles.
+-------------------------------------------------------------------------------
+
+
+		Controller Features
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_2_1    False (*)	CT: Initiating connection establishment (M)
+TSPC_AVRCP_2_2    False (*)	CT: Accepting connection establishment (M)
+TSPC_AVRCP_2_3    False (*)	CT: Initiating connection release (M)
+TSPC_AVRCP_2_4    False (*)	CT: Accepting connection release (M)
+TSPC_AVRCP_2_5    False		CT: Sending UNIT INFO (O)
+TSPC_AVRCP_2_6    False		CT: Sending SUBUNIT INFO (O)
+TSPC_AVRCP_2_7    False (*)	CT: Sending PASS THROUGH command category 1
+					(C.1)
+TSPC_AVRCP_2_8    False		CT: Sending PASS THROUGH command category 2
+					(C.1)
+TSPC_AVRCP_2_9    False		CT: Sending PASS THROUGH command category 3
+					(C.1)
+TSPC_AVRCP_2_10   False		CT: Sending PASS THROUGH command category 4
+					(C.1)
+TSPC_AVRCP_2_11   False		CT: Get Capabilities (O)
+TSPC_AVRCP_2_12   False		CT: List Player Application Setting
+					Attributes (C.9)
+TSPC_AVRCP_2_13   False		CT: List Player Application Setting Values (O)
+TSPC_AVRCP_2_14   False		CT: Get Current Player Application Setting
+					(C.10)
+TSPC_AVRCP_2_15   False		CT: Set Player Application Setting Value (C.10)
+TSPC_AVRCP_2_16   False		CT: Get Player Application Setting
+						Attribute (O)
+TSPC_AVRCP_2_17   False		CT: Get Player Application Setting Value (O)
+TSPC_AVRCP_2_18   False		CT: Inform Displayable Character Set (O)
+TSPC_AVRCP_2_19   False		CT: Inform Battery Status of CT (O)
+TSPC_AVRCP_2_20   False		CT: Get Element Attributes (O)
+TSPC_AVRCP_2_21   False		CT: Get Play Status (O)
+TSPC_AVRCP_2_22   False		CT: Register Notification (C.11)
+TSPC_AVRCP_2_23   False		CT: Request Continuing Response (C.2)
+TSPC_AVRCP_2_24   False		CT: Abort Continuing Response (C.2)
+TSPC_AVRCP_2_25   False		CT: Next Group (C.12)
+TSPC_AVRCP_2_26   False		CT: Previous Group (C.12)
+TSPC_AVRCP_2_27   False		CT: Media Player Selection (O)
+TSPC_AVRCP_2_28   False		CT: SetAddressedPlayer (O)
+TSPC_AVRCP_2_29   False		CT: GetFolderItems(MediaPlayerList) (C.5)
+TSPC_AVRCP_2_29b  False		CT: GetTotalNumberOfItems(MediaPlayerList) (C.5)
+TSPC_AVRCP_2_30   False		CT: EVENT_AVAILABLE_PLAYERS_CHANGED (O)
+TSPC_AVRCP_2_31   False		CT: EVENT_ADDRESSED_PLAYER_CHANGED (O)
+TSPC_AVRCP_2_32   False		CT: Browsing (O)
+TSPC_AVRCP_2_33   False		CT: SetBrowsedPlayer (C.4)
+TSPC_AVRCP_2_34   False		CT: ChangePath (C.4)
+TSPC_AVRCP_2_35   False		CT: GetFolderItems(Filesystem) (C.4)
+TSPC_AVRCP_2_35b  False		CT: GetTotalNumberOfItems(Filesystem) (C.4)
+TSPC_AVRCP_2_36   False		CT: GetItemAttributes (O)
+TSPC_AVRCP_2_37   False		CT: PlayItem(Filesystem) (C.4)
+TSPC_AVRCP_2_38   False		CT: EVENT_UIDS_CHANGED (O)
+TSPC_AVRCP_2_39   False		CT: Searching (O)
+TSPC_AVRCP_2_40   False		CT: Search (C.7)
+TSPC_AVRCP_2_41   False		CT: GetFolderItems(Search Results) (C.7)
+TSPC_AVRCP_2_41b  False		CT: GetTotalNumberOfItems(Search Results) (C.7)
+TSPC_AVRCP_2_42   False		CT: PlayItem(SearchResultList) (C.7)
+TSPC_AVRCP_2_43   False		CT: NowPlaying (C.8)
+TSPC_AVRCP_2_44   False		CT: GetFolderItems(NowPlayingList) (C.8)
+TSPC_AVRCP_2_44b  False		CT: GetTotalNumberOfItems(NowPlayingList) (C.8)
+TSPC_AVRCP_2_45   False		CT: PlayItem(NowPlayingList) (C.8)
+TSPC_AVRCP_2_46   False		CT: AddToNowPlaying (O)
+TSPC_AVRCP_2_47   False		CT: EVENT_NOW_PLAYING_CONTENT_CHANGED (O)
+TSPC_AVRCP_2_48   False		CT: Playable Folders (O)
+TSPC_AVRCP_2_49   False		CT: Absolute Volume (C.3)
+TSPC_AVRCP_2_50   False		CT: SetAbsoluteVolume (C.3)
+TSPC_AVRCP_2_51   False		CT: NotifyVolumeChange (C.3)
+TSPC_AVRCP_2_52   False (*)	CT: Discoverable Mode (M)
+TSPC_AVRCP_2_53   False		CT: PASSTHROUGH operation supporting press
+					and hold (O)
+TSPC_AVRCP_2_54   False		CT: Cover Art (O)
+TSPC_AVRCP_2_55   False		CT: GetCapabilities, Cover Art (C.10)
+TSPC_AVRCP_2_56   False		CT: GetImageProperties, Cover Art (C.10)
+TSPC_AVRCP_2_57   False		CT: GetImage, Cover Art (C.9)
+TSPC_AVRCP_2_58   False		CT: GetLinkedThumbnail, CoverArt (C.9)
+-------------------------------------------------------------------------------
+C.1: Mandatory to support at least one of the defined categories
+	(TSPC_AVRCP_2_7 through TSPC_AVRCP_2_10).
+C.2: Mandatory if TSPC_AVRCP_2_20 is supported, otherwise Optional.
+C.3: Mandatory if TSPC_AVRCP_2_8 is supported, otherwise Excluded.
+C.4: Mandatory if TSPC_AVRCP_2_32 is supported, otherwise Excluded.
+C.5: Mandatory if TSPC_AVRCP_2_27 is supported, otherwise Excluded.
+C.7: Mandatory if item TSPC_AVRCP_2_39 is supported, Excluded otherwise.
+C.8: Mandatory if TSPC_AVRCP_2_32 is supported, otherwise Excluded.
+C.9: Mandatory to support if Player Application Settings feature is supported.
+	If any item TSPC_AVRCP_2_13 through TSPC_AVRCP_2_15 is supported it is
+	required to claim support for this feature in accordance with Player
+	Application Settings support requirements, otherwise Optional.
+C.10: Mandatory to support either Get or Set Player Application Settings
+	(TSPC_AVRCP_2_14 or TSPC_AVRCP_2_15) if List Player Application Setting
+	Attributes (TSPC_AVRCP_2_12) is supported. Either TSPC_AVRCP_2_14
+	or TSPC_AVRCP_2_15 must be supported if Player Application Settings
+	feature is supported, in accordance with Player Application Settings
+	support requirements.
+C.11: Mandatory if TSPC_AVRCP_2_7 or (TSPC_AVRCP_2_8 AND TSPC_AVRCP_2_49)
+	or TSPC_AVRCP_2_9 is supported, otherwise Optional.
+C.12: Mandatory if Basic Group Navigation Feature supported. If any item
+	TSPC_AVRCP_2_25 or TSPC_AVRCP_2_26 is supported it is mandatory to
+	support both, in accordance with Basic Group Navigation support
+	requirements, otherwise Excluded.
+-------------------------------------------------------------------------------
+
+
+		Controller Profile Version
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_2b_1   False		CT: AVRCP v1.0 (C.1)
+TSPC_AVRCP_2b_2   False		CT: AVRCP v1.3 (C.1)
+TSPC_AVRCP_2b_3   False		CT: AVRCP v1.4 (C.1)
+TSPC_AVRCP_2b_4   False		CT: AVRCP v1.5 (C.1)
+TSPC_AVRCP_2b_5   False		CT: AVRCP v1.6 (C.1)
+-------------------------------------------------------------------------------
+C.1: It is mandatory to support at least one of the profile versions if
+	Controller role supported (SPC_AVRCP_1_1).
+-------------------------------------------------------------------------------
+
+
+		Operation_id of Category 1 for CT
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_3_1    False		CT: category 1 - Operation id: 0 (C.1)
+TSPC_AVRCP_3_2    False		CT: category 1 - Operation id: 1 (C.1)
+TSPC_AVRCP_3_3    False		CT: category 1 - Operation id: 2 (C.1)
+TSPC_AVRCP_3_4    False		CT: category 1 - Operation id: 3 (C.1)
+TSPC_AVRCP_3_5    False		CT: category 1 - Operation id: 4 (C.1)
+TSPC_AVRCP_3_6    False		CT: category 1 - Operation id: 5 (C.1)
+TSPC_AVRCP_3_7    False		CT: category 1 - Operation id: 6 (C.1)
+TSPC_AVRCP_3_8    False		CT: category 1 - Operation id: 7 (C.1)
+TSPC_AVRCP_3_9    False		CT: category 1 - Operation id: 8 (C.1)
+TSPC_AVRCP_3_10   False		CT: category 1 - Operation id: 9 (C.1)
+TSPC_AVRCP_3_11   False		CT: category 1 - Operation id: dot (C.1)
+TSPC_AVRCP_3_12   False		CT: category 1 - Operation id: enter (C.1)
+TSPC_AVRCP_3_13   False		CT: category 1 - Operation id: clear (C.1)
+TSPC_AVRCP_3_14   False		CT: category 1 - Operation id: sound_select
+					(C.1)
+TSPC_AVRCP_3_15   False		CT: category 1 - Operation id: input_select
+					(C.1)
+TSPC_AVRCP_3_16   False		CT: category 1 - Operation id:
+					display_information (C.1)
+TSPC_AVRCP_3_17   False		CT: category 1 - Operation id: help (C.1)
+TSPC_AVRCP_3_18   False		CT: category 1 - Operation id: power (C.1)
+TSPC_AVRCP_3_19   False (*)	CT: category 1 - Operation id: play (C.1)
+TSPC_AVRCP_3_20   False (*)	CT: category 1 - Operation id: stop (C.1)
+TSPC_AVRCP_3_21   False (*)	CT: category 1 - Operation id: pause (C.1)
+TSPC_AVRCP_3_22   False		CT: category 1 - Operation id: record (C.1)
+TSPC_AVRCP_3_23   False		CT: category 1 - Operation id: rewind (C.1)
+TSPC_AVRCP_3_24   False		CT: category 1 - Operation id: fast_forward
+					(C.1)
+TSPC_AVRCP_3_25   False		CT: category 1 - Operation id: eject (C.1)
+TSPC_AVRCP_3_26   False		CT: category 1 - Operation id: forward (C.1)
+TSPC_AVRCP_3_27   False		CT: category 1 - Operation id: backward (C.1)
+TSPC_AVRCP_3_28   False		CT: category 1 - Operation id: angle (C.1)
+TSPC_AVRCP_3_29   False		CT: category 1 - Operation id: subpicture (C.1)
+TSPC_AVRCP_3_30   False		CT: category 1 - Operation id: F1 (C.1)
+TSPC_AVRCP_3_31   False		CT: category 1 - Operation id: F2 (C.1)
+TSPC_AVRCP_3_32   False		CT: category 1 - Operation id: F3 (C.1)
+TSPC_AVRCP_3_33   False		CT: category 1 - Operation id: F4 (C.1)
+TSPC_AVRCP_3_33a  False		CT: category 1 - Operation id: F5 (C.1)
+TSPC_AVRCP_3_34   False		CT: category 1 - Operation id: vendor_unique
+					(C.1)
+-------------------------------------------------------------------------------
+C.1: Mandatory to support at least one of these operation_ids if the device
+	supports category 1 (TSPC_AVRCP_2_7).
+-------------------------------------------------------------------------------
+
+
+		Operation_id of category 2 for CT
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_4_1    False		CT: category 2 - Operation id: 0 (C.2)
+TSPC_AVRCP_4_2    False		CT: category 2 - Operation id: 1 (C.2)
+TSPC_AVRCP_4_3    False		CT: category 2 - Operation id: 2 (C.2)
+TSPC_AVRCP_4_4    False		CT: category 2 - Operation id: 3 (C.2)
+TSPC_AVRCP_4_5    False		CT: category 2 - Operation id: 4 (C.2)
+TSPC_AVRCP_4_6    False		CT: category 2 - Operation id: 5 (C.2)
+TSPC_AVRCP_4_7    False		CT: category 2 - Operation id: 6 (C.2)
+TSPC_AVRCP_4_8    False		CT: category 2 - Operation id: 7 (C.2)
+TSPC_AVRCP_4_9    False		CT: category 2 - Operation id: 8 (C.2)
+TSPC_AVRCP_4_10   False		CT: category 2 - Operation id: 9 (C.2)
+TSPC_AVRCP_4_11   False		CT: category 2 - Operation id: dot (C.2)
+TSPC_AVRCP_4_12   False		CT: category 2 - Operation id: enter (C.2)
+TSPC_AVRCP_4_13   False		CT: category 2 - Operation id: clear (C.2)
+TSPC_AVRCP_4_14   False		CT: category 2 - Operation id: sound_select
+					(C.2)
+TSPC_AVRCP_4_15   False		CT: category 2 - Operation id: input_select
+					(C.2)
+TSPC_AVRCP_4_16   False		CT: category 2 - Operation id:
+					display_information (C.2)
+TSPC_AVRCP_4_17   False		CT: category 2 - Operation id: help (C.2)
+TSPC_AVRCP_4_18   False		CT: category 2 - Operation id: power (C.2)
+TSPC_AVRCP_4_19   False (*)	CT: category 2 - Operation id: volume_up (C.2)
+TSPC_AVRCP_4_20   False (*)	CT: category 2 - Operation id: volume_down (C.2)
+TSPC_AVRCP_4_21   False		CT: category 2 - Operation id: mute (C.2)
+TSPC_AVRCP_4_22   False		CT: category 2 - Operation id: F1 (C.2)
+TSPC_AVRCP_4_23   False		CT: category 2 - Operation id: F2 (C.2)
+TSPC_AVRCP_4_24   False		CT: category 2 - Operation id: F3 (C.2)
+TSPC_AVRCP_4_25   False		CT: category 2 - Operation id: F4 (C.2)
+TSPC_AVRCP_4_25a  False		CT: category 2 - Operation id: F5 (C.2)
+TSPC_AVRCP_4_26   False		CT: category 2 - Operation id: vendor_unique
+					(C.2)
+-------------------------------------------------------------------------------
+C.2: Mandatory to support at least one of these operation_ids if the device
+	supports category 2 (TSPC_AVRCP_2_8).
+-------------------------------------------------------------------------------
+
+
+		Operation_id of category 3 for CT
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_5_1    False		CT: category 3 - Operation id: 0 (C.3)
+TSPC_AVRCP_5_2    False		CT: category 3 - Operation id: 1 (C.3)
+TSPC_AVRCP_5_3    False		CT: category 3 - Operation id: 2 (C.3)
+TSPC_AVRCP_5_4    False		CT: category 3 - Operation id: 3 (C.3)
+TSPC_AVRCP_5_5    False		CT: category 3 - Operation id: 4 (C.3)
+TSPC_AVRCP_5_6    False		CT: category 3 - Operation id: 5 (C.3)
+TSPC_AVRCP_5_7    False		CT: category 3 - Operation id: 6 (C.3)
+TSPC_AVRCP_5_8    False		CT: category 3 - Operation id: 7 (C.3)
+TSPC_AVRCP_5_9    False		CT: category 3 - Operation id: 8 (C.3)
+TSPC_AVRCP_5_10   False		CT: category 3 - Operation id: 9 (C.3)
+TSPC_AVRCP_5_11   False		CT: category 3 - Operation id: dot (C.3)
+TSPC_AVRCP_5_12   False		CT: category 3 - Operation id: enter (C.3)
+TSPC_AVRCP_5_13   False		CT: category 3 - Operation id: clear (C.3)
+TSPC_AVRCP_5_14   False		CT: category 3 - Operation id: channel up (C.3)
+TSPC_AVRCP_5_15   False		CT: category 3 - Operation id: channel down
+					(C.3)
+TSPC_AVRCP_5_16   False		CT: category 3 - Operation id: previous channel
+					(C.3)
+TSPC_AVRCP_5_17   False		CT: category 3 - Operation id: sound_select
+					(C.3)
+TSPC_AVRCP_5_18   False		CT: category 3 - Operation id: input_select
+					(C.3)
+TSPC_AVRCP_5_19   False		CT: category 3 - Operation id:
+					display_information (C.3)
+TSPC_AVRCP_5_20   False		CT: category 3 - Operation id: help (C.3)
+TSPC_AVRCP_5_21   False		CT: category 3 - Operation id: power (C.3)
+TSPC_AVRCP_5_22   False		CT: category 3 - Operation id: angle (C.3)
+TSPC_AVRCP_5_23   False		CT: category 3 - Operation id: subpicture(C.3)
+TSPC_AVRCP_5_24   False		CT: category 3 - Operation id: F1 (C.3)
+TSPC_AVRCP_5_25   False		CT: category 3 - Operation id: F2 (C.3)
+TSPC_AVRCP_5_26   False		CT: category 3 - Operation id: F3 (C.3)
+TSPC_AVRCP_5_27   False		CT: category 3 - Operation id: F4 (C.3)
+TSPC_AVRCP_5_27a  False		CT: category 3 - Operation id: F5 (C.3)
+TSPC_AVRCP_5_28   False		CT: category 3 - Operation id: vendor_unique
+					(C.3)
+-------------------------------------------------------------------------------
+C.3: Mandatory to support at least one of these operation_ids if the device
+	supports category 3 (TSPC_AVRCP_2_9).
+-------------------------------------------------------------------------------
+
+
+		Operation_id of category 4 for CT
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_6_1    False		CT: category 4 - Operation id: select (C.4)
+TSPC_AVRCP_6_2    False		CT: category 4 - Operation id: up (C.4)
+TSPC_AVRCP_6_3    False		CT: category 4 - Operation id: down (C.4)
+TSPC_AVRCP_6_4    False		CT: category 4 - Operation id: left (C.4)
+TSPC_AVRCP_6_5    False		CT: category 4 - Operation id: right (C.4)
+TSPC_AVRCP_6_6    False		CT: category 4 - Operation id: right up (C.4)
+TSPC_AVRCP_6_7    False		CT: category 4 - Operation id: right down (C.4)
+TSPC_AVRCP_6_8    False		CT: category 4 - Operation id: left up (C.4)
+TSPC_AVRCP_6_9    False		CT: category 4 - Operation id: left down (C.4)
+TSPC_AVRCP_6_10   False		CT: category 4 - Operation id: root menu (C.4)
+TSPC_AVRCP_6_11   False		CT: category 4 - Operation id: setup menu (C.4)
+TSPC_AVRCP_6_12   False		CT: category 4 - Operation id: contents menu
+					(C.4)
+TSPC_AVRCP_6_13   False		CT: category 4 - Operation id: favorite menu
+					(C.4)
+TSPC_AVRCP_6_14   False		CT: category 4 - Operation id: exit (C.4)
+TSPC_AVRCP_6_15   False		CT: category 4 - Operation id: 0 (C.4)
+TSPC_AVRCP_6_16   False		CT: category 4 - Operation id: 1 (C.4)
+TSPC_AVRCP_6_17   False		CT: category 4 - Operation id: 2 (C.4)
+TSPC_AVRCP_6_18   False		CT: category 4 - Operation id: 3 (C.4)
+TSPC_AVRCP_6_19   False		CT: category 4 - Operation id: 4 (C.4)
+TSPC_AVRCP_6_20   False		CT: category 4 - Operation id: 5 (C.4)
+TSPC_AVRCP_6_21   False		CT: category 4 - Operation id: 6 (C.4)
+TSPC_AVRCP_6_22   False		CT: category 4 - Operation id: 7 (C.4)
+TSPC_AVRCP_6_23   False		CT: category 4 - Operation id: 8 (C.4)
+TSPC_AVRCP_6_24   False		CT: category 4 - Operation id: 9 (C.4)
+TSPC_AVRCP_6_25   False		CT: category 4 - Operation id: dot (C.4)
+TSPC_AVRCP_6_26   False		CT: category 4 - Operation id: enter (C.4)
+TSPC_AVRCP_6_27   False		CT: category 4 - Operation id: clear (C.4)
+TSPC_AVRCP_6_28   False		CT: category 4 - Operation id:
+					display_information (C.4)
+TSPC_AVRCP_6_29   False		CT: category 4 - Operation id: help (C.4)
+TSPC_AVRCP_6_30   False		CT: category 4 - Operation id: page up (C.4)
+TSPC_AVRCP_6_31   False		CT: category 4 - Operation id: page down (C.4)
+TSPC_AVRCP_6_32   False		CT: category 4 - Operation id: power (C.4)
+TSPC_AVRCP_6_33   False		CT: category 4 - Operation id: F1 (C.4)
+TSPC_AVRCP_6_34   False		CT: category 4 - Operation id: F2 (C.4)
+TSPC_AVRCP_6_35   False		CT: category 4 - Operation id: F3 (C.4)
+TSPC_AVRCP_6_36   False		CT: category 4 - Operation id: F4 (C.4)
+TSPC_AVRCP_6_36a  False		CT: category 4 - Operation id: F5 (C.4)
+TSPC_AVRCP_6_37   False		CT: category 4 - Operation id: vendor_unique
+					(C.4)
+-------------------------------------------------------------------------------
+C.4: Mandatory to support at least one of these operation_ids if the device
+	supports category 4 (TSPC_AVRCP_2_9).
+-------------------------------------------------------------------------------
+
+
+		Target Features
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_7_1    True (*)	TG: Initiating connection establishment (O)
+TSPC_AVRCP_7_2    True		TG: Accept connection establishment (M)
+TSPC_AVRCP_7_3    True		TG: Initiating connection release (M)
+TSPC_AVRCP_7_4    True		TG: Accepting connection release (M)
+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
+					(C.1)
+TSPC_AVRCP_7_9    False		TG: Receiving PASS THROUGH command category 3
+					(C.1)
+TSPC_AVRCP_7_10   False		TG: Receiving PASS THROUGH command category 4
+					(C.1)
+TSPC_AVRCP_7_11   True (*)	TG: Get Capabilities Response (C.3)
+TSPC_AVRCP_7_12   False		TG: List Player Application Settings (C.14)
+TSPC_AVRCP_7_13   False		TG: List Player Application Setting Values
+					(C.14)
+TSPC_AVRCP_7_14   False		TG: Get Current Player Application Settings
+					(C.14)
+TSPC_AVRCP_7_15   False		TG: Set Player Application Setting Value (C.14)
+TSPC_AVRCP_7_16   False		TG: Get Player Application Setting Attribute
+					(O)
+TSPC_AVRCP_7_17   False		TG: Get Player Application Setting Value (O)
+TSPC_AVRCP_7_18   False		TG: Inform Displayable Character Set (O)
+TSPC_AVRCP_7_19   False		TG: Inform Battery Status Of CT Response (O)
+TSPC_AVRCP_7_20   True (*)	TG: Get Element Attributes Response (C.3)
+TSPC_AVRCP_7_21   True (*)	TG: Get Play Status Response (C.2)
+TSPC_AVRCP_7_22   True (*)	TG: Register Notification Response (C.12)
+TSPC_AVRCP_7_23   True (*)	TG: Notify Event Response:
+					PLAYBACK_STATUS_CHANGED (C.4)
+TSPC_AVRCP_7_24   True (*)	TG: Notify Event Response: TRACK_CHANGED (C.4)
+TSPC_AVRCP_7_25   False		TG: Notify Event Response: TRACK_REACHED_END (O)
+TSPC_AVRCP_7_26   False		TG: Notify Event Response: TRACK_REACHED_START
+					(O)
+TSPC_AVRCP_7_27   False		TG: Notify Event Response: PLAYBACK_POS_CHANGED
+					(O)
+TSPC_AVRCP_7_28   False		TG: Notify Event Response: BATT_STATUS_CHANGED
+					(O)
+TSPC_AVRCP_7_29   False		TG: Notify Event Response: SYSTEM_STATUS_CHANGED
+					(O)
+TSPC_AVRCP_7_30   False		TG: Notify Event Response:
+					PLAYER_APPLICATION_SETTING_CHANGED (O)
+TSPC_AVRCP_7_31   True (*)	TG: Request ContinuingResponse (C.2)
+TSPC_AVRCP_7_32   True (*)	TG: Abort ContinuingResponse Response (C.2)
+TSPC_AVRCP_7_34   False		TG: Next Group (C.15)
+TSPC_AVRCP_7_35   False		TG: Previous Group (C.15)
+TSPC_AVRCP_7_36   False		TG: Media Player Selection (C.8)
+TSPC_AVRCP_7_37   False		TG: SetAddressedPlayer (C.8)
+TSPC_AVRCP_7_38   False		TG: GetFolderItems(MediaPlayerList) (C.8)
+TSPC_AVRCP_7_38b  False		TG: GetTotalNumberOfItems(MediaPlayerList) (C.8)
+TSPC_AVRCP_7_39   False		TG: EVENT_AVAILABLE_PLAYERS_CHANGED (C.8)
+TSPC_AVRCP_7_40   False		TG: EVENT_ADDRESSED_PLAYER_CHANGED (C.8)
+TSPC_AVRCP_7_41   False		TG: Supports Multiple Players (O)
+TSPC_AVRCP_7_42   False		TG: Browsing (O)
+TSPC_AVRCP_7_42a  False		TG: Supports initiation of browsing channel
+					establishment (O)
+TSPC_AVRCP_7_43   False		TG: SetBrowsedPlayer (C.6)
+TSPC_AVRCP_7_44   False		TG: ChangePath (C.6)
+TSPC_AVRCP_7_45   False		TG: GetFolderItems(Filesystem) (C.6)
+TSPC_AVRCP_7_45b  False		TG: GetTotalNumberOfItems(Filesystem) (C.6)
+TSPC_AVRCP_7_46   False		TG: GetItemAttributes (C.6)
+TSPC_AVRCP_7_47   False		TG: PlayItem(Filesystem) (C.6)
+TSPC_AVRCP_7_48   False		TG: EVENT_UIDS_CHANGED (C.9)
+TSPC_AVRCP_7_49   False		TG: Database Aware Players (O)
+TSPC_AVRCP_7_50   False		TG: Searching (O)
+TSPC_AVRCP_7_51   False		TG: Search (C.10)
+TSPC_AVRCP_7_52   False		TG: GetFolderItems(Search Results) (C.10)
+TSPC_AVRCP_7_52b  False		TG: GetTotalNumberOfItems(Search Results) (C.10)
+TSPC_AVRCP_7_53   False		TG: PlayItem(SearchResultList) (C.10)
+TSPC_AVRCP_7_54   False		TG: NowPlaying (C.11)
+TSPC_AVRCP_7_55   False		TG: GetFolderItems(NowPlayingList) (C.11)
+TSPC_AVRCP_7_55b  False		TG: GetTotalNumberOfItems(NowPlayingList) (C.11)
+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_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)
+TSPC_AVRCP_7_66   False		TG: PASSTHROUGH operation supporting press
+					and hold (O)
+TSPC_AVRCP_7_67   False		TG: Cover Art (O)
+TSPC_AVRCP_7_68   False		TG: GetCapabilities, Cover Art (C.12)
+TSPC_AVRCP_7_69   False		TG: GetImageProperties, Cover Art (C.12)
+TSPC_AVRCP_7_70   False		TG: GetImage, Cover Art (C.12)
+TSPC_AVRCP_7_71   False		TG: GetLinkedThumbnail, Cover Art (C.12)
+-------------------------------------------------------------------------------
+C.1: Mandatory to support at least one of the categories. Supported
+	operation_id's are shown in Table 8 to Table 11.
+C.2: Mandatory if 7/20 is supported, otherwise Optional.
+C.3: Mandatory if 7/7 is supported, otherwise Optional.
+C.4: Mandatory if 7/22 and 7/20 is supported, otherwise Optional.
+C.5: Mandatory if 7/8 is supported, otherwise Excluded.
+C.6: Mandatory if 7/42 is supported, otherwise Excluded.
+C.7: Mandatory if 7/36 is supported, otherwise Excluded.
+C.8: Mandatory if (7/7 or 7/9) is supported, otherwise Excluded.
+C.9: Mandatory if 7/49 is supported, otherwise Optional.
+C.10: Mandatory if 7/50 is supported, otherwise Excluded.
+C.11: Mandatory if 7/42 is supported, otherwise Optional.
+C.12: Mandatory if 7/7 or (7/8 AND 7/60) or 7/9 is supported, otherwise Optional
+C.13: Mandatory if 7/7 or 7/9 or 7/42 is supported, otherwise Optional.
+C.14: Mandatory if Player Application Settings Feature supported. If any item
+	7/12 – 7/15 is supported, all items 7/12 – 7/15 shall be supported,
+	in accordance with Player Application Settings Feature support
+	requirements, otherwise Excluded.
+C.15: Mandatory if Basic Group Navigation Feature supported. If any item
+	7/34 or 7/35 is supported it is mandatory to support both,
+	in accordance with Basic Group Navigation support requirements,
+	otherwise Excluded.
+-------------------------------------------------------------------------------
+
+		Target Profile Version
+-------------------------------------------------------------------------------
+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_3   False		TG: AVRCP v1.4 (C.1)
+TSPC_AVRCP_7b_4   False		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.
+-------------------------------------------------------------------------------
+
+
+		operation_id of category 1 for TG
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_8_1    False		TG: category 1 - Operation id: 0 (O)
+TSPC_AVRCP_8_2    False		TG: category 1 - Operation id: 1 (O)
+TSPC_AVRCP_8_3    False		TG: category 1 - Operation id: 2 (O)
+TSPC_AVRCP_8_4    False		TG: category 1 - Operation id: 3 (O)
+TSPC_AVRCP_8_5    False		TG: category 1 - Operation id: 4 (O)
+TSPC_AVRCP_8_6    False		TG: category 1 - Operation id: 5 (O)
+TSPC_AVRCP_8_7    False		TG: category 1 - Operation id: 6 (O)
+TSPC_AVRCP_8_8    False		TG: category 1 - Operation id: 7 (O)
+TSPC_AVRCP_8_9    False		TG: category 1 - Operation id: 8 (O)
+TSPC_AVRCP_8_10   False		TG: category 1 - Operation id: 9 (O)
+TSPC_AVRCP_8_11   False		TG: category 1 - Operation id: dot (O)
+TSPC_AVRCP_8_12   False		TG: category 1 - Operation id: enter (O)
+TSPC_AVRCP_8_13   False		TG: category 1 - Operation id: clear (O)
+TSPC_AVRCP_8_14   False		TG: category 1 - Operation id: sound select (O)
+TSPC_AVRCP_8_15   False		TG: category 1 - Operation id: input select (O)
+TSPC_AVRCP_8_16   False		TG: category 1 - Operation id: display
+					information (O)
+TSPC_AVRCP_8_17   False		TG: category 1 - Operation id: help (O)
+TSPC_AVRCP_8_18   False		TG: category 1 - Operation id: power (O)
+TSPC_AVRCP_8_19   True		TG: category 1 - Operation id: play (M)
+TSPC_AVRCP_8_20   True		TG: category 1 - Operation id: stop (M)
+TSPC_AVRCP_8_21   True		TG: category 1 - Operation id: pause (O)
+TSPC_AVRCP_8_22   False		TG: category 1 - Operation id: record (O)
+TSPC_AVRCP_8_23   True (*)	TG: category 1 - Operation id: rewind (O)
+TSPC_AVRCP_8_24   True (*)	TG: category 1 - Operation id: fast forward (O)
+TSPC_AVRCP_8_25   False		TG: category 1 - Operation id: eject (O)
+TSPC_AVRCP_8_26   True (*)	TG: category 1 - Operation id: forward (O)
+TSPC_AVRCP_8_27   True (*)	TG: category 1 - Operation id: backward (O)
+TSPC_AVRCP_8_28   False		TG: category 1 - Operation id: angle (O)
+TSPC_AVRCP_8_29   False		TG: category 1 - Operation id: subpicture (O)
+TSPC_AVRCP_8_30   False		TG: category 1 - Operation id: F1 (O)
+TSPC_AVRCP_8_31   False		TG: category 1 - Operation id: F2 (O)
+TSPC_AVRCP_8_32   False		TG: category 1 - Operation id: F3 (O)
+TSPC_AVRCP_8_33   False		TG: category 1 - Operation id: F4 (O)
+TSPC_AVRCP_8_33a  False		TG: category 1 - Operation id: F5 (O)
+TSPC_AVRCP_8_34   False		TG: category 1 - Operation id: vendor unique (O)
+-------------------------------------------------------------------------------
+
+
+		operation_id of category 2 for TG
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_9_1    False		TG: category 2 - Operation id: 0 (O)
+TSPC_AVRCP_9_2    False		TG: category 2 - Operation id: 1 (O)
+TSPC_AVRCP_9_3    False		TG: category 2 - Operation id: 2 (O)
+TSPC_AVRCP_9_4    False		TG: category 2 - Operation id: 3 (O)
+TSPC_AVRCP_9_5    False		TG: category 2 - Operation id: 4 (O)
+TSPC_AVRCP_9_6    False		TG: category 2 - Operation id: 5 (O)
+TSPC_AVRCP_9_7    False		TG: category 2 - Operation id: 6 (O)
+TSPC_AVRCP_9_8    False		TG: category 2 - Operation id: 7 (O)
+TSPC_AVRCP_9_9    False		TG: category 2 - Operation id: 8 (O)
+TSPC_AVRCP_9_10   False		TG: category 2 - Operation id: 9 (O)
+TSPC_AVRCP_9_11   False		TG: category 2 - Operation id: dot (O)
+TSPC_AVRCP_9_12   False		TG: category 2 - Operation id: enter (O)
+TSPC_AVRCP_9_13   False		TG: category 2 - Operation id: clear (O)
+TSPC_AVRCP_9_14   False		TG: category 2 - Operation id: sound select (O)
+TSPC_AVRCP_9_15   False		TG: category 2 - Operation id: input select (O)
+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_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)
+TSPC_AVRCP_9_26   False		TG: category 2 - Operation id: F3 (O)
+TSPC_AVRCP_9_27   False		TG: category 2 - Operation id: F4 (O)
+TSPC_AVRCP_9_27a  False		TG: category 2 - Operation id: F5 (O)
+TSPC_AVRCP_9_28   False		TG: category 2 - Operation id: vendor unique (O)
+-------------------------------------------------------------------------------
+C.2: Mandatory to support if the device supports category 2 (TSPC_AVRCP_7_8).
+-------------------------------------------------------------------------------
+
+
+		operation_id of category 3 for TG
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_10_1   False		TG: category 3 - Operation id: 0 (O)
+TSPC_AVRCP_10_2   False		TG: category 3 - Operation id: 1 (O)
+TSPC_AVRCP_10_3   False		TG: category 3 - Operation id: 2 (O)
+TSPC_AVRCP_10_4   False		TG: category 3 - Operation id: 3 (O)
+TSPC_AVRCP_10_5   False		TG: category 3 - Operation id: 4 (O)
+TSPC_AVRCP_10_6   False		TG: category 3 - Operation id: 5 (O)
+TSPC_AVRCP_10_7   False		TG: category 3 - Operation id: 6 (O)
+TSPC_AVRCP_10_8   False		TG: category 3 - Operation id: 7 (O)
+TSPC_AVRCP_10_9   False		TG: category 3 - Operation id: 8 (O)
+TSPC_AVRCP_10_10  False		TG: category 3 - Operation id: 9 (O)
+TSPC_AVRCP_10_11  False		TG: category 3 - Operation id: dot (O)
+TSPC_AVRCP_10_12  False		TG: category 3 - Operation id: enter (O)
+TSPC_AVRCP_10_13  False		TG: category 3 - Operation id: clear (O)
+TSPC_AVRCP_10_14  False		TG: category 3 - Operation id: channel up (C.3)
+TSPC_AVRCP_10_15  False		TG: category 3 - Operation id: channel down
+					(C.3)
+TSPC_AVRCP_10_16  False		TG: category 3 - Operation id: previous channel
+					(O)
+TSPC_AVRCP_10_17  False		TG: category 3 - Operation id: sound select (O)
+TSPC_AVRCP_10_18  False		TG: category 3 - Operation id: input select (O)
+TSPC_AVRCP_10_19  False		TG: category 3 - Operation id: display
+					information (O)
+TSPC_AVRCP_10_20  False		TG: category 3 - Operation id: help (O)
+TSPC_AVRCP_10_21  False		TG: category 3 - Operation id: power (O)
+TSPC_AVRCP_10_21a False		TG: category 3 - Operation id: angle (O)
+TSPC_AVRCP_10_21b False		TG: category 3 - Operation id: subpicture (O)
+TSPC_AVRCP_10_22  False		TG: category 3 - Operation id: F1 (O)
+TSPC_AVRCP_10_23  False		TG: category 3 - Operation id: F2 (O)
+TSPC_AVRCP_10_24  False		TG: category 3 - Operation id: F3 (O)
+TSPC_AVRCP_10_25  False		TG: category 3 - Operation id: F4 (O)
+TSPC_AVRCP_10_25a False		TG: category 3 - Operation id: F5 (O)
+TSPC_AVRCP_10_26  False		TG: category 3 - Operation id: vendor unique (O)
+-------------------------------------------------------------------------------
+C.3: Mandatory to support if the device supports category 3 (TSPC_AVRCP_7_9).
+-------------------------------------------------------------------------------
+
+
+		operation_id of category 4 for TG
+-------------------------------------------------------------------------------
+Parameter Name    Selected	Description
+-------------------------------------------------------------------------------
+TSPC_AVRCP_11_1   False		TG: category 4 - Operation id: select (C.4)
+TSPC_AVRCP_11_2   False		TG: category 4 - Operation id: up (C.4)
+TSPC_AVRCP_11_3   False		TG: category 4 - Operation id: down (C.4)
+TSPC_AVRCP_11_4   False		TG: category 4 - Operation id: left (C.4)
+TSPC_AVRCP_11_5   False		TG: category 4 - Operation id: right (C.4)
+TSPC_AVRCP_11_6   False		TG: category 4 - Operation id: right up (O)
+TSPC_AVRCP_11_7   False		TG: category 4 - Operation id: right down (O)
+TSPC_AVRCP_11_8   False		TG: category 4 - Operation id: left up (O)
+TSPC_AVRCP_11_9   False		TG: category 4 - Operation id: left down (O)
+TSPC_AVRCP_11_10  False		TG: category 4 - Operation id: root menu (C.4)
+TSPC_AVRCP_11_11  False		TG: category 4 - Operation id: setup menu (O)
+TSPC_AVRCP_11_12  False		TG: category 4 - Operation id: contents menu (O)
+TSPC_AVRCP_11_13  False		TG: category 4 - Operation id: favorite menu (O)
+TSPC_AVRCP_11_14  False		TG: category 4 - Operation id: exit (O)
+TSPC_AVRCP_11_15  False		TG: category 4 - Operation id: 0 (O)
+TSPC_AVRCP_11_16  False		TG: category 4 - Operation id: 1 (O)
+TSPC_AVRCP_11_17  False		TG: category 4 - Operation id: 2 (O)
+TSPC_AVRCP_11_18  False		TG: category 4 - Operation id: 3 (O)
+TSPC_AVRCP_11_19  False		TG: category 4 - Operation id: 4 (O)
+TSPC_AVRCP_11_20  False		TG: category 4 - Operation id: 5 (O)
+TSPC_AVRCP_11_21  False		TG: category 4 - Operation id: 6 (O)
+TSPC_AVRCP_11_22  False		TG: category 4 - Operation id: 7 (O)
+TSPC_AVRCP_11_23  False		TG: category 4 - Operation id: 8 (O)
+TSPC_AVRCP_11_24  False		TG: category 4 - Operation id: 9 (O)
+TSPC_AVRCP_11_25  False		TG: category 4 - Operation id: dot (O)
+TSPC_AVRCP_11_26  False		TG: category 4 - Operation id: enter (O)
+TSPC_AVRCP_11_27  False		TG: category 4 - Operation id: clear (O)
+TSPC_AVRCP_11_28  False		TG: category 4 - Operation id: disply (O)
+TSPC_AVRCP_11_29  False		TG: category 4 - Operation id: help (O)
+TSPC_AVRCP_11_30  False		TG: category 4 - Operation id: page up (O)
+TSPC_AVRCP_11_31  False		TG: category 4 - Operation id: page down (O)
+TSPC_AVRCP_11_32  False		TG: category 4 - Operation id: power (O)
+TSPC_AVRCP_11_33  False		TG: category 4 - Operation id: F1 (O)
+TSPC_AVRCP_11_34  False		TG: category 4 - Operation id: F2 (O)
+TSPC_AVRCP_11_35  False		TG: category 4 - Operation id: F3 (O)
+TSPC_AVRCP_11_36  False		TG: category 4 - Operation id: F4 (O)
+TSPC_AVRCP_11_36a False		TG: category 4 - Operation id: F5 (O)
+TSPC_AVRCP_11_37  False		TG: category 4 - Operation id: vendor unique (O)
+TSPC_AVRCP_ALL    False		Enables all test cases when set to TRUE.
+-------------------------------------------------------------------------------
+C.4: Mandatory to support if the device supports category 4 (TSPC_AVRCP_7_10).
+-------------------------------------------------------------------------------
diff --git a/android/pixit-avrcp.txt b/android/pixit-avrcp.txt
new file mode 100644
index 0000000..9b278ad
--- /dev/null
+++ b/android/pixit-avrcp.txt
@@ -0,0 +1,36 @@
+AVRCP PIXIT for the PTS tool.
+
+PTS version: 5.0
+
+* - different than PTS defaults
+& - should be set to IUT Bluetooth address
+# - should be set to PTS's bin/audio folder
+
+Required PIXIT settings
+-------------------------------------------------------------------------------
+Parameter Name			Value
+-------------------------------------------------------------------------------
+TSPX_security_enabled		FALSE
+TSPX_bd_addr_iut		112233445566 (*&)
+TSPX_class_of_device		20050C
+TSPX_player_feature_bitmask	0000000000000007FFF00070000000000
+TSPX_pin_code			0000
+TSPX_delete_link_key		FALSE
+TSPX_time_guard			300000
+TSPX_avrcp_only			FALSE
+TSPX_search_string		tomorrow
+TSPX_max_avc_fragments		10
+TSPX_establish_avdtp_stream	TRUE
+TSPX_use_implicit_send		TRUE
+TSPX_avrcp_version
+TSPX_tester_av_role
+TSPX_media_directory		C:\Program Files\Bluetooth SIG\Bluetooth PTS\
+					bin\audio (#)
+TSPX_auth_password		0000
+TSPX_auth_user_id		PTS
+TSPX_rfcomm_channel		8
+TSPX_l2cap_psm			1011
+TSPX_no_confirmations		FALSE
+TSPX_no_cover_art_folder
+TSPX_cover_art_folder
+-------------------------------------------------------------------------------
-- 
1.8.5


^ permalink raw reply related

* Re: [PATCH] android/ipc: Fix arguments order in DBG
From: Szymon Janc @ 2014-01-13  8:11 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1389563085-9731-1-git-send-email-andrzej.kaczmarek@tieto.com>

Hi Andrzej,

On Sunday 12 of January 2014 22:44:45 Andrzej Kaczmarek wrote:
> ---
>  android/ipc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/android/ipc.c b/android/ipc.c
> index 03bdc35..a31d315 100644
> --- a/android/ipc.c
> +++ b/android/ipc.c
> @@ -88,7 +88,7 @@ int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
>  	if ((handler->var_len && handler->data_len > msg->len) ||
>  			(!handler->var_len && handler->data_len != msg->len)) {
>  		DBG("invalid size for opcode 0x%x service 0x%x",
> -						msg->service_id, msg->opcode);
> +						msg->opcode, msg->service_id);
>  		return -EMSGSIZE;
>  	}
>  
> 

Applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH 2/2] tools: Stop converting file if write failed in seq2bseq
From: Szymon Janc @ 2014-01-13  8:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1389600554-20669-1-git-send-email-szymon.janc@tieto.com>

If write failed converted file would be broken. This make sure that
user is being informed about it.
---
 tools/seq2bseq.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/seq2bseq.c b/tools/seq2bseq.c
index 9797f5f..7657a57 100644
--- a/tools/seq2bseq.c
+++ b/tools/seq2bseq.c
@@ -130,6 +130,7 @@ static void convert_file(const char *input_path, const char *output_path)
 
 	while (1) {
 		char *str;
+		int err;
 
 		str = fgets(line_buffer, line_size - 1, fp);
 		if (!str)
@@ -137,7 +138,12 @@ static void convert_file(const char *input_path, const char *output_path)
 
 		cur += strlen(str);
 
-		convert_line(fd, str);
+		err = convert_line(fd, str);
+		if (err < 0) {
+			fprintf(stderr, "Failed to convert file (%s)\n",
+								strerror(-err));
+			break;
+		}
 	}
 
 	fclose(fp);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/2] tools: Fix build error in seq2bseq
From: Szymon Janc @ 2014-01-13  8:09 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Don't ignore return value of write. This fix following build error on
Ubuntu:

tools/seq2bseq.c: In function ‘convert_line’:
tools/seq2bseq.c:52:8: error: ignoring return value of ‘write’,
     declared with attribute warn_unused_result [-Werror=unused-result]
   write(fd, &val, 1);
---
 tools/seq2bseq.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/seq2bseq.c b/tools/seq2bseq.c
index 6d70777..9797f5f 100644
--- a/tools/seq2bseq.c
+++ b/tools/seq2bseq.c
@@ -31,16 +31,17 @@
 #include <string.h>
 #include <stdlib.h>
 #include <getopt.h>
+#include <errno.h>
 #include <sys/stat.h>
 
-static void convert_line(int fd, const char *line)
+static int convert_line(int fd, const char *line)
 {
 	const char *ptr = line;
 	char str[3];
 	unsigned char val;
 
 	if (line[0] == '*' || line[0] == '\r' || line[0] == '\r')
-		return;
+		return 0;
 
 	while (1) {
 		str[0] = *ptr++;
@@ -49,7 +50,8 @@ static void convert_line(int fd, const char *line)
 
 		val = strtol(str, NULL, 16);
 
-		write(fd, &val, 1);
+		if (write(fd, &val, 1) < 0)
+			return -errno;
 
 		if (*ptr == '\r' || *ptr == '\n')
 			break;
@@ -57,6 +59,8 @@ static void convert_line(int fd, const char *line)
 		while (*ptr == ' ')
 			ptr++;
 	}
+
+	return 0;
 }
 
 static void convert_file(const char *input_path, const char *output_path)
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH BlueZ 3/6] audio/A2DP: Add implemention of audio Open Stream command
From: Luiz Augusto von Dentz @ 2014-01-13  7:55 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CAN_7+YbqjZ7=hRjED10mDJuGnhy8pD45iuf9SWFqGM_3N=hVDg@mail.gmail.com>

Hi Lukasz,

On Mon, Jan 13, 2014 at 2:10 AM, Lukasz Rymanowski
<lukasz.rymanowski@gmail.com> wrote:
> Hi Luiz,
>
> On Sat, Jan 11, 2014 at 11:13 AM, Luiz Augusto von Dentz
> <luiz.dentz@gmail.com> wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> ---
>>  android/a2dp.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 197 insertions(+), 2 deletions(-)
>>
>> diff --git a/android/a2dp.c b/android/a2dp.c
>> index 8649cf3..479cb71 100644
>> --- a/android/a2dp.c
>> +++ b/android/a2dp.c
>> @@ -37,6 +37,7 @@
>>  #include "lib/bluetooth.h"
>>  #include "lib/sdp.h"
>>  #include "lib/sdp_lib.h"
>> +#include "profiles/audio/a2dp-codecs.h"
>
> We need to discuss how we gonna use structs from this file in
> hal-audio (eg. a2dp_sbc_t). Maybe we should have some special file
> with audio structs/defines for IPC only? Then you could copy data to
> structs you need.

Not sure what you mean about this header, its LGPL already so I see no
problem of including it in hal-audio.

^ permalink raw reply

* [BlueZ v2 6/6] audio/A2DP: Add implemention of audio Suspend Stream command
From: Luiz Augusto von Dentz @ 2014-01-13  7:52 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389599525-6353-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 0598d4d..9061984 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -807,8 +807,29 @@ failed:
 
 static void bt_stream_suspend(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct audio_cmd_suspend_stream *cmd = buf;
+	struct a2dp_setup *setup;
+	int err;
+
+	DBG("");
+
+	setup = find_setup(cmd->id);
+	if (!setup) {
+		error("Unable to find stream for endpoint %u", cmd->id);
+		goto failed;
+	}
+
+	err = avdtp_suspend(setup->dev->session, setup->stream);
+	if (err < 0) {
+		error("avdtp_suspend: %s", strerror(-err));
+		goto failed;
+	}
 
+	audio_ipc_send_rsp(AUDIO_OP_SUSPEND_STREAM, AUDIO_STATUS_SUCCESS);
+
+	return;
+
+failed:
 	audio_ipc_send_rsp(AUDIO_OP_SUSPEND_STREAM, AUDIO_STATUS_FAILED);
 }
 
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 5/6] audio/A2DP: Add implemention of audio Resume Stream command
From: Luiz Augusto von Dentz @ 2014-01-13  7:52 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389599525-6353-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 48ca00b..0598d4d 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -779,8 +779,29 @@ failed:
 
 static void bt_stream_resume(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct audio_cmd_resume_stream *cmd = buf;
+	struct a2dp_setup *setup;
+	int err;
+
+	DBG("");
 
+	setup = find_setup(cmd->id);
+	if (!setup) {
+		error("Unable to find stream for endpoint %u", cmd->id);
+		goto failed;
+	}
+
+	err = avdtp_start(setup->dev->session, setup->stream);
+	if (err < 0) {
+		error("avdtp_start: %s", strerror(-err));
+		goto failed;
+	}
+
+	audio_ipc_send_rsp(AUDIO_OP_RESUME_STREAM, AUDIO_STATUS_SUCCESS);
+
+	return;
+
+failed:
 	audio_ipc_send_rsp(AUDIO_OP_RESUME_STREAM, AUDIO_STATUS_FAILED);
 }
 
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 4/6] audio/A2DP: Add implemention of audio Close Stream command
From: Luiz Augusto von Dentz @ 2014-01-13  7:52 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389599525-6353-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index af7a131..48ca00b 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -751,8 +751,29 @@ static void bt_stream_open(const void *buf, uint16_t len)
 
 static void bt_stream_close(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct audio_cmd_close_stream *cmd = buf;
+	struct a2dp_setup *setup;
+	int err;
 
+	DBG("");
+
+	setup = find_setup(cmd->id);
+	if (!setup) {
+		error("Unable to find stream for endpoint %u", cmd->id);
+		goto failed;
+	}
+
+	err = avdtp_close(setup->dev->session, setup->stream, FALSE);
+	if (err < 0) {
+		error("avdtp_close: %s", strerror(-err));
+		goto failed;
+	}
+
+	audio_ipc_send_rsp(AUDIO_OP_CLOSE_STREAM, AUDIO_STATUS_SUCCESS);
+
+	return;
+
+failed:
 	audio_ipc_send_rsp(AUDIO_OP_CLOSE_STREAM, AUDIO_STATUS_FAILED);
 }
 
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 3/6] audio/A2DP: Add implemention of audio Open Stream command
From: Luiz Augusto von Dentz @ 2014-01-13  7:52 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389599525-6353-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 200 insertions(+), 3 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 82f9b4f..af7a131 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -37,6 +37,7 @@
 #include "lib/bluetooth.h"
 #include "lib/sdp.h"
 #include "lib/sdp_lib.h"
+#include "profiles/audio/a2dp-codecs.h"
 #include "log.h"
 #include "a2dp.h"
 #include "hal-msg.h"
@@ -53,6 +54,7 @@
 static GIOChannel *server = NULL;
 static GSList *devices = NULL;
 static GSList *endpoints = NULL;
+static GSList *setups = NULL;
 static bdaddr_t adapter_addr;
 static uint32_t record_id = 0;
 
@@ -67,6 +69,7 @@ struct a2dp_endpoint {
 	struct avdtp_local_sep *sep;
 	struct a2dp_preset *caps;
 	GSList *presets;
+	struct a2dp_config *config;
 };
 
 struct a2dp_device {
@@ -76,6 +79,13 @@ struct a2dp_device {
 	struct avdtp	*session;
 };
 
+struct a2dp_setup {
+	struct a2dp_device *dev;
+	struct a2dp_endpoint *endpoint;
+	struct a2dp_preset *preset;
+	struct avdtp_stream *stream;
+};
+
 static int device_cmp(gconstpointer s, gconstpointer user_data)
 {
 	const struct a2dp_device *dev = s;
@@ -397,7 +407,7 @@ static gboolean sep_getcap_ind(struct avdtp *session,
 					void *user_data)
 {
 	struct a2dp_endpoint *endpoint = user_data;
-	struct a2dp_preset *cap = endpoint->presets->data;
+	struct a2dp_preset *cap = endpoint->caps;
 	struct avdtp_service_capability *service;
 	struct avdtp_media_codec_capability *codec;
 
@@ -419,8 +429,162 @@ static gboolean sep_getcap_ind(struct avdtp *session,
 	return TRUE;
 }
 
+static int sbc_check_config(struct a2dp_endpoint *endpoint,
+						struct a2dp_preset *conf)
+{
+	a2dp_sbc_t *caps, *config;
+
+	if (conf->len != sizeof(a2dp_sbc_t)) {
+		error("SBC: Invalid configuration size (%u)", conf->len);
+		return -EINVAL;
+	}
+
+	caps = endpoint->caps->data;
+	config = conf->data;
+
+	if (!(caps->frequency & config->frequency)) {
+		error("SBC: Unsupported frequency (%u) by endpoint",
+							config->frequency);
+		return -EINVAL;
+	}
+
+	if (!(caps->channel_mode & config->channel_mode)) {
+		error("SBC: Unsupported channel mode (%u) by endpoint",
+							config->channel_mode);
+		return -EINVAL;
+	}
+
+	if (!(caps->block_length & config->block_length)) {
+		error("SBC: Unsupported block length (%u) by endpoint",
+							config->block_length);
+		return -EINVAL;
+	}
+
+	if (!(caps->allocation_method & config->allocation_method)) {
+		error("SBC: Unsupported allocation method (%u) by endpoint",
+							config->block_length);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int check_config(struct a2dp_endpoint *endpoint,
+						struct a2dp_preset *config)
+{
+	GSList *l;
+
+	for (l = endpoint->presets; l; l = g_slist_next(l)) {
+		struct a2dp_preset *preset = l->data;
+
+		if (preset->len != config->len)
+			continue;
+
+		if (memcmp(preset->data, config->data, preset->len) == 0)
+			return 0;
+	}
+
+	/* Codec specific */
+	switch (endpoint->codec) {
+	case A2DP_CODEC_SBC:
+		return sbc_check_config(endpoint, config);
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct a2dp_device *find_device_by_session(struct avdtp *session)
+{
+	GSList *l;
+
+	for (l = devices; l; l = g_slist_next(l)) {
+		struct a2dp_device *dev = l->data;
+
+		if (dev->session == session)
+			return dev;
+	}
+
+	return NULL;
+}
+
+static void setup_free(void *data)
+{
+	struct a2dp_setup *setup = data;
+
+	preset_free(setup->preset);
+	g_free(setup);
+}
+
+static void setup_add(struct a2dp_device *dev, struct a2dp_endpoint *endpoint,
+			struct a2dp_preset *preset, struct avdtp_stream *stream)
+{
+	struct a2dp_setup *setup;
+
+	setup = g_new0(struct a2dp_setup, 1);
+	setup->dev = dev;
+	setup->endpoint = endpoint;
+	setup->preset = preset;
+	setup->stream = stream;
+	setups = g_slist_append(setups, setup);
+}
+
+static gboolean sep_setconf_ind(struct avdtp *session,
+						struct avdtp_local_sep *sep,
+						struct avdtp_stream *stream,
+						GSList *caps,
+						avdtp_set_configuration_cb cb,
+						void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+	struct a2dp_device *dev;
+	struct a2dp_preset *preset = NULL;
+
+	DBG("");
+
+	dev = find_device_by_session(session);
+	if (!dev) {
+		error("Unable to find device for session %p", session);
+		return FALSE;
+	}
+
+	for (; caps != NULL; caps = g_slist_next(caps)) {
+		struct avdtp_service_capability *cap = caps->data;
+		struct avdtp_media_codec_capability *codec;
+
+		if (cap->category == AVDTP_DELAY_REPORTING)
+			return FALSE;
+
+		if (cap->category != AVDTP_MEDIA_CODEC)
+			continue;
+
+		codec = (struct avdtp_media_codec_capability *) cap->data;
+
+		if (codec->media_codec_type != endpoint->codec)
+			return FALSE;
+
+		preset = g_new0(struct a2dp_preset, 1);
+		preset->len = cap->length - sizeof(*codec);
+		preset->data = g_memdup(codec->data, preset->len);
+
+		if (check_config(endpoint, preset) < 0) {
+			preset_free(preset);
+			return FALSE;
+		}
+	}
+
+	if (!preset)
+		return FALSE;
+
+	setup_add(dev, endpoint, preset, stream);
+
+	cb(session, stream, NULL);
+
+	return TRUE;
+}
+
 static struct avdtp_sep_ind sep_ind = {
 	.get_capability		= sep_getcap_ind,
+	.set_configuration	= sep_setconf_ind,
 };
 
 static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
@@ -548,11 +712,41 @@ static void bt_audio_close(const void *buf, uint16_t len)
 	audio_ipc_send_rsp(AUDIO_OP_CLOSE, AUDIO_STATUS_SUCCESS);
 }
 
+static struct a2dp_setup *find_setup(uint8_t id)
+{
+	GSList *l;
+
+	for (l = setups; l; l = g_slist_next(l)) {
+		struct a2dp_setup *setup = l->data;
+
+		if (setup->endpoint->id == id)
+			return setup;
+	}
+
+	return NULL;
+}
+
 static void bt_stream_open(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct audio_cmd_open_stream *cmd = buf;
+	struct audio_rsp_open_stream *rsp;
+	struct a2dp_setup *setup;
+
+	DBG("");
 
-	audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED);
+	setup = find_setup(cmd->id);
+	if (!setup) {
+		error("Unable to find stream for endpoint %u", cmd->id);
+		audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED);
+		return;
+	}
+
+	len = sizeof(*rsp) + setup->preset->len;
+	rsp = g_malloc0(sizeof(*rsp) + setup->preset->len);
+	rsp->preset->len = setup->preset->len;
+	memcpy(rsp->preset->data, setup->preset->data, setup->preset->len);
+
+	audio_ipc_send_rsp_full(AUDIO_OP_OPEN_STREAM, len, rsp, -1);
 }
 
 static void bt_stream_close(const void *buf, uint16_t len)
@@ -651,6 +845,9 @@ void bt_a2dp_unregister(void)
 {
 	DBG("");
 
+	g_slist_free_full(setups, setup_free);
+	setups = NULL;
+
 	g_slist_free_full(endpoints, unregister_endpoint);
 	endpoints = NULL;
 
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 2/6] audio/A2DP: Add implemention of audio Close command
From: Luiz Augusto von Dentz @ 2014-01-13  7:52 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389599525-6353-1-git-send-email-luiz.dentz@gmail.com>

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

---
 android/a2dp.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 970e2dc..82f9b4f 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -515,11 +515,37 @@ failed:
 	audio_ipc_send_rsp(AUDIO_OP_OPEN, AUDIO_STATUS_FAILED);
 }
 
+static struct a2dp_endpoint *find_endpoint(uint8_t id)
+{
+	GSList *l;
+
+	for (l = endpoints; l; l = g_slist_next(l)) {
+		struct a2dp_endpoint *endpoint = l->data;
+
+		if (endpoint->id == id)
+			return endpoint;
+	}
+
+	return NULL;
+}
+
 static void bt_audio_close(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct audio_cmd_close *cmd = buf;
+	struct a2dp_endpoint *endpoint;
+
+	DBG("");
+
+	endpoint = find_endpoint(cmd->id);
+	if (!endpoint) {
+		error("Unable to find endpoint %u", cmd->id);
+		audio_ipc_send_rsp(AUDIO_OP_CLOSE, AUDIO_STATUS_FAILED);
+		return;
+	}
+
+	unregister_endpoint(endpoint);
 
-	audio_ipc_send_rsp(AUDIO_OP_CLOSE, HAL_STATUS_FAILED);
+	audio_ipc_send_rsp(AUDIO_OP_CLOSE, AUDIO_STATUS_SUCCESS);
 }
 
 static void bt_stream_open(const void *buf, uint16_t len)
-- 
1.8.4.2


^ permalink raw reply related

* [BlueZ v2 1/6] audio/A2DP: Add implemention of audio Open command
From: Luiz Augusto von Dentz @ 2014-01-13  7:52 UTC (permalink / raw)
  To: linux-bluetooth

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

---
 android/a2dp.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 158 insertions(+), 1 deletion(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index b59c53d..970e2dc 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -52,9 +52,23 @@
 
 static GIOChannel *server = NULL;
 static GSList *devices = NULL;
+static GSList *endpoints = NULL;
 static bdaddr_t adapter_addr;
 static uint32_t record_id = 0;
 
+struct a2dp_preset {
+	void *data;
+	int8_t len;
+};
+
+struct a2dp_endpoint {
+	uint8_t id;
+	uint8_t codec;
+	struct avdtp_local_sep *sep;
+	struct a2dp_preset *caps;
+	GSList *presets;
+};
+
 struct a2dp_device {
 	bdaddr_t	dst;
 	uint8_t		state;
@@ -70,6 +84,29 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
 	return bacmp(&dev->dst, dst);
 }
 
+static void preset_free(void *data)
+{
+	struct a2dp_preset *preset = data;
+
+	g_free(preset->data);
+	g_free(preset);
+}
+
+static void unregister_endpoint(void *data)
+{
+	struct a2dp_endpoint *endpoint = data;
+
+	if (endpoint->sep)
+		avdtp_unregister_sep(endpoint->sep);
+
+	if (endpoint->caps)
+		preset_free(endpoint->caps);
+
+	g_slist_free_full(endpoint->presets, preset_free);
+
+	g_free(endpoint);
+}
+
 static void a2dp_device_free(struct a2dp_device *dev)
 {
 	if (dev->session)
@@ -354,10 +391,127 @@ static sdp_record_t *a2dp_record(void)
 	return record;
 }
 
+static gboolean sep_getcap_ind(struct avdtp *session,
+					struct avdtp_local_sep *sep,
+					GSList **caps, uint8_t *err,
+					void *user_data)
+{
+	struct a2dp_endpoint *endpoint = user_data;
+	struct a2dp_preset *cap = endpoint->presets->data;
+	struct avdtp_service_capability *service;
+	struct avdtp_media_codec_capability *codec;
+
+	*caps = NULL;
+
+	service = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, NULL, 0);
+	*caps = g_slist_append(*caps, service);
+
+	codec = g_malloc0(sizeof(*codec) + sizeof(cap->len));
+	codec->media_type = AVDTP_MEDIA_TYPE_AUDIO;
+	codec->media_codec_type = endpoint->codec;
+	memcpy(codec->data, cap->data, cap->len);
+
+	service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec,
+						sizeof(*codec) + cap->len);
+	*caps = g_slist_append(*caps, service);
+	g_free(codec);
+
+	return TRUE;
+}
+
+static struct avdtp_sep_ind sep_ind = {
+	.get_capability		= sep_getcap_ind,
+};
+
+static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
+							GSList *presets)
+{
+	struct a2dp_endpoint *endpoint;
+
+	/* FIXME: Add proper check for uuid */
+
+	endpoint = g_new0(struct a2dp_endpoint, 1);
+	endpoint->id = g_slist_length(endpoints) + 1;
+	endpoint->codec = codec;
+	endpoint->sep = avdtp_register_sep(AVDTP_SEP_TYPE_SOURCE,
+						AVDTP_MEDIA_TYPE_AUDIO,
+						codec, FALSE, &sep_ind, NULL,
+						endpoint);
+	endpoint->caps = g_slist_nth_data(presets->data, 0);
+	endpoint->presets = g_slist_copy(g_slist_nth(presets, 1));
+
+	endpoints = g_slist_append(endpoints, endpoint);
+
+	return endpoint->id;
+}
+
+static GSList *parse_presets(const struct audio_preset *p, uint8_t count,
+								uint16_t len)
+{
+	GSList *l = NULL;
+	uint8_t i;
+
+	for (i = 0; count > i; i++) {
+		struct a2dp_preset *preset;
+
+		if (len < sizeof(struct audio_preset)) {
+			DBG("Invalid preset index %u", i);
+			g_slist_free_full(l, preset_free);
+			return NULL;
+		}
+
+		len -= sizeof(struct audio_preset);
+		if (len == 0 || len < p->len) {
+			DBG("Invalid preset size of %u for index %u", len, i);
+			g_slist_free_full(l, preset_free);
+			return NULL;
+		}
+
+		preset = g_new0(struct a2dp_preset, 1);
+		preset->len = p->len;
+		preset->data = g_memdup(p->data, preset->len);
+		l = g_slist_append(l, preset);
+
+		len -= preset->len;
+		p += sizeof(struct audio_preset) + preset->len;
+	}
+
+	return l;
+}
+
 static void bt_audio_open(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct audio_cmd_open *cmd = buf;
+	struct audio_rsp_open rsp;
+	GSList *presets;
 
+	DBG("");
+
+	if (cmd->presets == 0) {
+		error("No audio presets found");
+		goto failed;
+	}
+
+	presets = parse_presets(cmd->preset, cmd->presets, len - sizeof(*cmd));
+	if (!presets) {
+		error("No audio presets found");
+		goto failed;
+	}
+
+	rsp.id = register_endpoint(cmd->uuid, cmd->codec, presets);
+	if (rsp.id == 0) {
+		g_slist_free_full(presets, preset_free);
+		error("Unable to register endpoint");
+		goto failed;
+	}
+
+	g_slist_free(presets);
+
+	audio_ipc_send_rsp_full(AUDIO_OP_OPEN, sizeof(rsp), &rsp, -1);
+
+	return;
+
+failed:
 	audio_ipc_send_rsp(AUDIO_OP_OPEN, AUDIO_STATUS_FAILED);
 }
 
@@ -471,6 +625,9 @@ void bt_a2dp_unregister(void)
 {
 	DBG("");
 
+	g_slist_free_full(endpoints, unregister_endpoint);
+	endpoints = NULL;
+
 	g_slist_foreach(devices, a2dp_device_disconnected, NULL);
 	devices = NULL;
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ] tools: Add missing check of write() return value
From: Anderson Lizardo @ 2014-01-13  1:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo

Fix clang error:

tools/seq2bseq.c: In function ‘convert_line’:
tools/seq2bseq.c:52:8: error: ignoring return value of ‘write’, declared
with attribute warn_unused_result [-Werror=unused-result]
---
 tools/seq2bseq.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/tools/seq2bseq.c b/tools/seq2bseq.c
index 6d70777..191e623 100644
--- a/tools/seq2bseq.c
+++ b/tools/seq2bseq.c
@@ -31,16 +31,17 @@
 #include <string.h>
 #include <stdlib.h>
 #include <getopt.h>
+#include <errno.h>
 #include <sys/stat.h>
 
-static void convert_line(int fd, const char *line)
+static int convert_line(int fd, const char *line)
 {
 	const char *ptr = line;
 	char str[3];
 	unsigned char val;
 
 	if (line[0] == '*' || line[0] == '\r' || line[0] == '\r')
-		return;
+		return 0;
 
 	while (1) {
 		str[0] = *ptr++;
@@ -49,7 +50,11 @@ static void convert_line(int fd, const char *line)
 
 		val = strtol(str, NULL, 16);
 
-		write(fd, &val, 1);
+		if (write(fd, &val, 1) < 0) {
+			int err = -errno;
+			perror("Failed to write to output file");
+			return err;
+		}
 
 		if (*ptr == '\r' || *ptr == '\n')
 			break;
@@ -57,6 +62,8 @@ static void convert_line(int fd, const char *line)
 		while (*ptr == ' ')
 			ptr++;
 	}
+
+	return 0;
 }
 
 static void convert_file(const char *input_path, const char *output_path)
@@ -133,7 +140,8 @@ static void convert_file(const char *input_path, const char *output_path)
 
 		cur += strlen(str);
 
-		convert_line(fd, str);
+		if (convert_line(fd, str) < 0)
+			break;
 	}
 
 	fclose(fp);
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH BlueZ 3/6] audio/A2DP: Add implemention of audio Open Stream command
From: Lukasz Rymanowski @ 2014-01-13  0:10 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1389435216-29040-3-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Sat, Jan 11, 2014 at 11:13 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> ---
>  android/a2dp.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 197 insertions(+), 2 deletions(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 8649cf3..479cb71 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -37,6 +37,7 @@
>  #include "lib/bluetooth.h"
>  #include "lib/sdp.h"
>  #include "lib/sdp_lib.h"
> +#include "profiles/audio/a2dp-codecs.h"

We need to discuss how we gonna use structs from this file in
hal-audio (eg. a2dp_sbc_t). Maybe we should have some special file
with audio structs/defines for IPC only? Then you could copy data to
structs you need.

>  #include "log.h"
>  #include "a2dp.h"
>  #include "hal-msg.h"
> @@ -53,6 +54,7 @@
>  static GIOChannel *server = NULL;
>  static GSList *devices = NULL;
>  static GSList *endpoints = NULL;
> +static GSList *setups = NULL;
>  static bdaddr_t adapter_addr;
>  static uint32_t record_id = 0;
>
> @@ -67,6 +69,7 @@ struct a2dp_endpoint {
>         struct avdtp_local_sep *sep;
>         struct a2dp_preset *caps;
>         GSList *presets;
> +       struct a2dp_config *config;
>  };
>
>  struct a2dp_device {
> @@ -76,6 +79,13 @@ struct a2dp_device {
>         struct avdtp    *session;
>  };
>
> +struct a2dp_setup {
> +       struct a2dp_device *dev;
> +       struct a2dp_endpoint *endpoint;
> +       struct a2dp_preset *preset;
> +       struct avdtp_stream *stream;
> +};
> +
>  static int device_cmp(gconstpointer s, gconstpointer user_data)
>  {
>         const struct a2dp_device *dev = s;
> @@ -422,8 +432,160 @@ static gboolean sep_getcap_ind(struct avdtp *session,
>         return TRUE;
>  }
>
> +static int sbc_check_config(struct a2dp_endpoint *endpoint,
> +                                               struct a2dp_preset *conf)
> +{
> +       a2dp_sbc_t *caps, *config;
> +
> +       if (conf->len != sizeof(a2dp_sbc_t)) {
> +               error("SBC: Invalid configuration size (%u)", conf->len);
> +               return -EINVAL;
> +       }
> +
> +       caps = endpoint->caps->data;
> +       config = conf->data;
> +
> +       if (!(caps->frequency & config->frequency)) {
> +               error("SBC: Unsupported frequency (%u) by endpoint",
> +                                                       config->frequency);
> +               return -EINVAL;
> +       }
> +
> +       if (!(caps->channel_mode & config->channel_mode)) {
> +               error("SBC: Unsupported channel mode (%u) by endpoint",
> +                                                       config->channel_mode);
> +               return -EINVAL;
> +       }
> +
> +       if (!(caps->block_length & config->block_length)) {
> +               error("SBC: Unsupported block length (%u) by endpoint",
> +                                                       config->block_length);
> +               return -EINVAL;
> +       }
> +
> +       if (!(caps->allocation_method & config->allocation_method)) {
> +               error("SBC: Unsupported allocation method (%u) by endpoint",
> +                                                       config->block_length);
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int check_config(struct a2dp_endpoint *endpoint,
> +                                               struct a2dp_preset *config)
> +{
> +       GSList *l;
> +
> +       for (l = endpoint->presets; l; l = g_slist_next(l)) {
> +               struct a2dp_preset *preset = l->data;
> +
> +               if (preset->len != config->len)
> +                       continue;
> +
> +               if (memcmp(preset->data, config->data, preset->len) == 0)
> +                       return 0;
> +       }
> +
> +       /* Codec specific */
> +       switch (endpoint->codec) {
> +       case A2DP_CODEC_SBC:
> +               return sbc_check_config(endpoint, config);
> +       default:
> +               return -EINVAL;
> +       }
> +}
> +
> +static struct a2dp_device *find_device_by_session(struct avdtp *session)
> +{
> +       GSList *l;
> +
> +       for (l = devices; l; l = g_slist_next(l)) {
> +               struct a2dp_device *dev = l->data;
> +
> +               if (dev->session == session)
> +                       return dev;
> +       }
> +
> +       return NULL;
> +}
> +
> +static void setup_free(void *data)
> +{
> +       struct a2dp_setup *setup = data;
> +
> +       preset_free(setup->preset);
> +       g_free(setup);
> +}
> +
> +static void setup_add(struct a2dp_device *dev, struct a2dp_endpoint *endpoint,
> +                       struct a2dp_preset *preset, struct avdtp_stream *stream)
> +{
> +       struct a2dp_setup *setup;
> +
> +       setup = g_new0(struct a2dp_setup, 1);
> +       setup->dev = dev;
> +       setup->endpoint = endpoint;
> +       setup->preset = preset;
> +       setup->stream = stream;
> +       setups = g_slist_append(setups, setup);
> +}
> +
> +static gboolean sep_setconf_ind(struct avdtp *session,
> +                                               struct avdtp_local_sep *sep,
> +                                               struct avdtp_stream *stream,
> +                                               GSList *caps,
> +                                               avdtp_set_configuration_cb cb,
> +                                               void *user_data)
> +{
> +       struct a2dp_endpoint *endpoint = user_data;
> +       struct a2dp_device *dev;
> +       struct a2dp_preset *preset = NULL;
> +
> +       DBG("");
> +
> +       dev = find_device_by_session(session);
> +       if (!dev) {
> +               error("Unable to find device for session %p", session);
> +               return FALSE;
> +       }
> +
> +       for (; caps != NULL; caps = g_slist_next(caps)) {
> +               struct avdtp_service_capability *cap = caps->data;
> +               struct avdtp_media_codec_capability *codec;
> +
> +               if (cap->category == AVDTP_DELAY_REPORTING)
> +                       return FALSE;
> +
> +               if (cap->category != AVDTP_MEDIA_CODEC)
> +                       continue;
> +
> +               codec = (struct avdtp_media_codec_capability *) cap->data;
> +
> +               if (codec->media_codec_type != endpoint->codec)
> +                       return FALSE;
> +
> +               preset = g_new0(struct a2dp_preset, 1);
> +               preset->len = cap->length - sizeof(*codec);
> +               preset->data = g_memdup(codec->data, preset->len);
> +
> +               if (check_config(endpoint, preset) < 0) {
> +                       preset_free(preset);
> +                       return FALSE;
> +               }
> +       }
> +
> +       if (!preset)
> +               return FALSE;
> +
> +       setup_add(dev, endpoint, preset, stream);
> +
> +       return TRUE;
> +}
> +
>  static struct avdtp_sep_ind sep_ind = {
>         .get_capability         = sep_getcap_ind,
> +       .set_configuration      = sep_setconf_ind,
>  };
>
>  static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
> @@ -548,11 +710,41 @@ static void bt_audio_close(const void *buf, uint16_t len)
>         audio_ipc_send_rsp(AUDIO_OP_CLOSE, HAL_STATUS_SUCCESS);
>  }
>
> +static struct a2dp_setup *find_setup(uint8_t id)
> +{
> +       GSList *l;
> +
> +       for (l = setups; l; l = g_slist_next(l)) {
> +               struct a2dp_setup *setup = l->data;
> +
> +               if (setup->endpoint->id == id)
> +                       return setup;
> +       }
> +
> +       return NULL;
> +}
> +
>  static void bt_stream_open(const void *buf, uint16_t len)
>  {
> -       DBG("Not Implemented");
> +       const struct audio_cmd_open_stream *cmd = buf;
> +       struct audio_rsp_open_stream *rsp;
> +       struct a2dp_setup *setup;
> +
> +       DBG("");
>
> -       audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED);
> +       setup = find_setup(cmd->id);
> +       if (!setup) {
> +               error("Unable to find stream for endpoint %u", cmd->id);
> +               audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, HAL_STATUS_FAILED);

Use AUDIO_STATUS_FAILED

> +               return;
> +       }
> +
> +       len = sizeof(*rsp) + setup->preset->len;
> +       rsp = g_malloc0(sizeof(*rsp) + setup->preset->len);
> +       rsp->preset->len = setup->preset->len;
> +       memcpy(rsp->preset->data, setup->preset->data, setup->preset->len);
> +
> +       audio_ipc_send_rsp_full(AUDIO_OP_OPEN_STREAM, len, rsp, -1);
>  }
>
>  static void bt_stream_close(const void *buf, uint16_t len)
> @@ -651,6 +843,9 @@ void bt_a2dp_unregister(void)
>  {
>         DBG("");
>
> +       g_slist_free_full(setups, setup_free);
> +       setups = NULL;
> +
>         g_slist_free_full(endpoints, unregister_endpoint);
>         endpoints = NULL;
>
> --
> 1.8.4.2
>

BR
Lukasz

> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH BlueZ 3/6] audio/A2DP: Add implemention of audio Open Stream command
From: Andrzej Kaczmarek @ 2014-01-13  0:02 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1389435216-29040-3-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On 11 January 2014 11:13, Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> ---
>  android/a2dp.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 197 insertions(+), 2 deletions(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 8649cf3..479cb71 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -37,6 +37,7 @@
>  #include "lib/bluetooth.h"
>  #include "lib/sdp.h"
>  #include "lib/sdp_lib.h"
> +#include "profiles/audio/a2dp-codecs.h"
>  #include "log.h"
>  #include "a2dp.h"
>  #include "hal-msg.h"
> @@ -53,6 +54,7 @@
>  static GIOChannel *server = NULL;
>  static GSList *devices = NULL;
>  static GSList *endpoints = NULL;
> +static GSList *setups = NULL;
>  static bdaddr_t adapter_addr;
>  static uint32_t record_id = 0;
>
> @@ -67,6 +69,7 @@ struct a2dp_endpoint {
>         struct avdtp_local_sep *sep;
>         struct a2dp_preset *caps;
>         GSList *presets;
> +       struct a2dp_config *config;
>  };
>
>  struct a2dp_device {
> @@ -76,6 +79,13 @@ struct a2dp_device {
>         struct avdtp    *session;
>  };
>
> +struct a2dp_setup {
> +       struct a2dp_device *dev;
> +       struct a2dp_endpoint *endpoint;
> +       struct a2dp_preset *preset;
> +       struct avdtp_stream *stream;
> +};
> +
>  static int device_cmp(gconstpointer s, gconstpointer user_data)
>  {
>         const struct a2dp_device *dev = s;
> @@ -422,8 +432,160 @@ static gboolean sep_getcap_ind(struct avdtp *session,
>         return TRUE;
>  }
>
> +static int sbc_check_config(struct a2dp_endpoint *endpoint,
> +                                               struct a2dp_preset *conf)
> +{
> +       a2dp_sbc_t *caps, *config;
> +
> +       if (conf->len != sizeof(a2dp_sbc_t)) {
> +               error("SBC: Invalid configuration size (%u)", conf->len);
> +               return -EINVAL;
> +       }
> +
> +       caps = endpoint->caps->data;
> +       config = conf->data;
> +
> +       if (!(caps->frequency & config->frequency)) {
> +               error("SBC: Unsupported frequency (%u) by endpoint",
> +                                                       config->frequency);
> +               return -EINVAL;
> +       }
> +
> +       if (!(caps->channel_mode & config->channel_mode)) {
> +               error("SBC: Unsupported channel mode (%u) by endpoint",
> +                                                       config->channel_mode);
> +               return -EINVAL;
> +       }
> +
> +       if (!(caps->block_length & config->block_length)) {
> +               error("SBC: Unsupported block length (%u) by endpoint",
> +                                                       config->block_length);
> +               return -EINVAL;
> +       }
> +
> +       if (!(caps->allocation_method & config->allocation_method)) {
> +               error("SBC: Unsupported allocation method (%u) by endpoint",
> +                                                       config->block_length);
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int check_config(struct a2dp_endpoint *endpoint,
> +                                               struct a2dp_preset *config)
> +{
> +       GSList *l;
> +
> +       for (l = endpoint->presets; l; l = g_slist_next(l)) {
> +               struct a2dp_preset *preset = l->data;
> +
> +               if (preset->len != config->len)
> +                       continue;
> +
> +               if (memcmp(preset->data, config->data, preset->len) == 0)
> +                       return 0;
> +       }
> +
> +       /* Codec specific */
> +       switch (endpoint->codec) {
> +       case A2DP_CODEC_SBC:
> +               return sbc_check_config(endpoint, config);
> +       default:
> +               return -EINVAL;
> +       }
> +}
> +
> +static struct a2dp_device *find_device_by_session(struct avdtp *session)
> +{
> +       GSList *l;
> +
> +       for (l = devices; l; l = g_slist_next(l)) {
> +               struct a2dp_device *dev = l->data;
> +
> +               if (dev->session == session)
> +                       return dev;
> +       }
> +
> +       return NULL;
> +}
> +
> +static void setup_free(void *data)
> +{
> +       struct a2dp_setup *setup = data;
> +
> +       preset_free(setup->preset);
> +       g_free(setup);
> +}
> +
> +static void setup_add(struct a2dp_device *dev, struct a2dp_endpoint *endpoint,
> +                       struct a2dp_preset *preset, struct avdtp_stream *stream)
> +{
> +       struct a2dp_setup *setup;
> +
> +       setup = g_new0(struct a2dp_setup, 1);
> +       setup->dev = dev;
> +       setup->endpoint = endpoint;
> +       setup->preset = preset;
> +       setup->stream = stream;
> +       setups = g_slist_append(setups, setup);
> +}
> +
> +static gboolean sep_setconf_ind(struct avdtp *session,
> +                                               struct avdtp_local_sep *sep,
> +                                               struct avdtp_stream *stream,
> +                                               GSList *caps,
> +                                               avdtp_set_configuration_cb cb,
> +                                               void *user_data)
> +{
> +       struct a2dp_endpoint *endpoint = user_data;
> +       struct a2dp_device *dev;
> +       struct a2dp_preset *preset = NULL;
> +
> +       DBG("");
> +
> +       dev = find_device_by_session(session);
> +       if (!dev) {
> +               error("Unable to find device for session %p", session);
> +               return FALSE;
> +       }
> +
> +       for (; caps != NULL; caps = g_slist_next(caps)) {
> +               struct avdtp_service_capability *cap = caps->data;
> +               struct avdtp_media_codec_capability *codec;
> +
> +               if (cap->category == AVDTP_DELAY_REPORTING)
> +                       return FALSE;
> +
> +               if (cap->category != AVDTP_MEDIA_CODEC)
> +                       continue;
> +
> +               codec = (struct avdtp_media_codec_capability *) cap->data;
> +
> +               if (codec->media_codec_type != endpoint->codec)
> +                       return FALSE;
> +
> +               preset = g_new0(struct a2dp_preset, 1);
> +               preset->len = cap->length - sizeof(*codec);
> +               preset->data = g_memdup(codec->data, preset->len);
> +
> +               if (check_config(endpoint, preset) < 0) {
> +                       preset_free(preset);
> +                       return FALSE;
> +               }
> +       }
> +
> +       if (!preset)
> +               return FALSE;
> +
> +       setup_add(dev, endpoint, preset, stream);
> +
> +       return TRUE;

I guess there should be call to avdtp_set_configuration_cb somewhere
in this function?


BR,
Andrzej

^ permalink raw reply

* Re: [PATCH BlueZ 1/6] audio/A2DP: Add implemention of audio Open command
From: Andrzej Kaczmarek @ 2014-01-12 23:58 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1389435216-29040-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On 11 January 2014 11:13, Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> ---
>  android/a2dp.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 158 insertions(+), 1 deletion(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index b59c53d..28b7406 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -52,9 +52,23 @@
>
>  static GIOChannel *server = NULL;
>  static GSList *devices = NULL;
> +static GSList *endpoints = NULL;
>  static bdaddr_t adapter_addr;
>  static uint32_t record_id = 0;
>
> +struct a2dp_preset {
> +       void *data;
> +       int8_t len;
> +};
> +
> +struct a2dp_endpoint {
> +       uint8_t id;
> +       uint8_t codec;
> +       struct avdtp_local_sep *sep;
> +       struct a2dp_preset *caps;
> +       GSList *presets;
> +};
> +
>  struct a2dp_device {
>         bdaddr_t        dst;
>         uint8_t         state;
> @@ -70,6 +84,29 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
>         return bacmp(&dev->dst, dst);
>  }
>
> +static void preset_free(void *data)
> +{
> +       struct a2dp_preset *preset = data;
> +
> +       g_free(preset->data);
> +       g_free(preset);
> +}
> +
> +static void unregister_endpoint(void *data)
> +{
> +       struct a2dp_endpoint *endpoint = data;
> +
> +       if (endpoint->sep)
> +               avdtp_unregister_sep(endpoint->sep);
> +
> +       if (endpoint->caps)
> +               preset_free(endpoint->caps);
> +
> +       g_slist_free_full(endpoint->presets, preset_free);
> +
> +       g_free(endpoint);
> +}
> +
>  static void a2dp_device_free(struct a2dp_device *dev)
>  {
>         if (dev->session)
> @@ -354,10 +391,127 @@ static sdp_record_t *a2dp_record(void)
>         return record;
>  }
>
> +static gboolean sep_getcap_ind(struct avdtp *session,
> +                                       struct avdtp_local_sep *sep,
> +                                       GSList **caps, uint8_t *err,
> +                                       void *user_data)
> +{
> +       struct a2dp_endpoint *endpoint = user_data;
> +       struct a2dp_preset *cap = endpoint->presets->data;

endpoint->caps

> +       struct avdtp_service_capability *media_transport, *media_codec;
> +       struct avdtp_media_codec_capability *codec_caps;
> +
> +       *caps = NULL;
> +
> +       media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
> +                                                               NULL, 0);
> +
> +       *caps = g_slist_append(*caps, media_transport);
> +
> +       codec_caps = g_malloc0(sizeof(*codec_caps) + sizeof(cap));
> +       codec_caps->media_type = AVDTP_MEDIA_TYPE_AUDIO;
> +       codec_caps->media_codec_type = endpoint->codec;
> +       memcpy(codec_caps->data, cap->data, cap->len);
> +
> +       media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec_caps,
> +                                       sizeof(*codec_caps) + sizeof(cap));
> +
> +       *caps = g_slist_append(*caps, media_codec);
> +       g_free(codec_caps);
> +
> +       return TRUE;
> +}
> +
> +static struct avdtp_sep_ind sep_ind = {
> +       .get_capability         = sep_getcap_ind,
> +};
> +
> +static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
> +                                                       GSList *presets)
> +{
> +       struct a2dp_endpoint *endpoint;
> +
> +       /* FIXME: Add proper check for uuid */
> +
> +       endpoint = g_new0(struct a2dp_endpoint, 1);
> +       endpoint->id = g_slist_length(endpoints) + 1;
> +       endpoint->codec = codec;
> +       endpoint->sep = avdtp_register_sep(AVDTP_SEP_TYPE_SOURCE,
> +                                               AVDTP_MEDIA_TYPE_AUDIO,
> +                                               codec, FALSE, &sep_ind, NULL,
> +                                               endpoint);
> +       endpoint->caps = g_slist_nth_data(presets->data, 0);

g_slist_nth_data(presets, 0)


BR,
Andrzej

^ permalink raw reply

* Re: [PATCH BlueZ 2/6] audio/A2DP: Add implemention of audio Close command
From: Lukasz Rymanowski @ 2014-01-12 22:36 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1389435216-29040-2-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Sat, Jan 11, 2014 at 11:13 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> ---
>  android/a2dp.c | 30 ++++++++++++++++++++++++++++--
>  1 file changed, 28 insertions(+), 2 deletions(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 28b7406..8649cf3 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -515,11 +515,37 @@ failed:
>         audio_ipc_send_rsp(AUDIO_OP_OPEN, AUDIO_STATUS_FAILED);
>  }
>
> +static struct a2dp_endpoint *find_endpoint(uint8_t id)
> +{
> +       GSList *l;
> +
> +       for (l = endpoints; l; l = g_slist_next(l)) {
> +               struct a2dp_endpoint *endpoint = l->data;
> +
> +               if (endpoint->id == id)
> +                       return endpoint;
> +       }
> +
> +       return NULL;
> +}
> +
>  static void bt_audio_close(const void *buf, uint16_t len)
>  {
> -       DBG("Not Implemented");
> +       const struct audio_cmd_close *cmd = buf;
> +       struct a2dp_endpoint *endpoint;
> +
> +       DBG("");
> +
> +       endpoint = find_endpoint(cmd->id);
> +       if (!endpoint) {
> +               error("Unable to find endpoint %u", cmd->id);
> +               audio_ipc_send_rsp(AUDIO_OP_CLOSE, HAL_STATUS_FAILED);

I think we should use AUDIO_STATUS_FAILED instead of HAL_STATUS_FAILED

> +               return;
> +       }
> +
> +       unregister_endpoint(endpoint);
>
> -       audio_ipc_send_rsp(AUDIO_OP_CLOSE, HAL_STATUS_FAILED);
> +       audio_ipc_send_rsp(AUDIO_OP_CLOSE, HAL_STATUS_SUCCESS);

Similar here.
>  }
>
>  static void bt_stream_open(const void *buf, uint16_t len)
> --
> 1.8.4.2
>
> --

\Lukasz

> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] android/ipc: Use proper handlers in ipc_handle_msg
From: Andrzej Kaczmarek @ 2014-01-12 22:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

ipc_handle_msg() should use handlers passed as function parameter
instead of static one as otherwise Audio IPC will use incorrect
handlers.
---
 android/ipc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/ipc.c b/android/ipc.c
index a31d315..ed3ef3c 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -82,7 +82,7 @@ int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
 	}
 
 	/* opcode is table offset + 1 */
-	handler = &services[msg->service_id].handler[msg->opcode - 1];
+	handler = &handlers[msg->service_id].handler[msg->opcode - 1];
 
 	/* if payload size is valid */
 	if ((handler->var_len && handler->data_len > msg->len) ||
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH] android/ipc: Fix arguments order in DBG
From: Andrzej Kaczmarek @ 2014-01-12 21:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

---
 android/ipc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/ipc.c b/android/ipc.c
index 03bdc35..a31d315 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -88,7 +88,7 @@ int ipc_handle_msg(struct service_handler *handlers, size_t max_index,
 	if ((handler->var_len && handler->data_len > msg->len) ||
 			(!handler->var_len && handler->data_len != msg->len)) {
 		DBG("invalid size for opcode 0x%x service 0x%x",
-						msg->service_id, msg->opcode);
+						msg->opcode, msg->service_id);
 		return -EMSGSIZE;
 	}
 
-- 
1.8.5.2


^ permalink raw reply related

* Re: [PATCH BlueZ 1/6] audio/A2DP: Add implemention of audio Open command
From: Andrzej Kaczmarek @ 2014-01-12 21:21 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1389435216-29040-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On 11 January 2014 11:13, Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> ---
>  android/a2dp.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 158 insertions(+), 1 deletion(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index b59c53d..28b7406 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -52,9 +52,23 @@
>
>  static GIOChannel *server = NULL;
>  static GSList *devices = NULL;
> +static GSList *endpoints = NULL;
>  static bdaddr_t adapter_addr;
>  static uint32_t record_id = 0;
>
> +struct a2dp_preset {
> +       void *data;
> +       int8_t len;
> +};
> +
> +struct a2dp_endpoint {
> +       uint8_t id;
> +       uint8_t codec;
> +       struct avdtp_local_sep *sep;
> +       struct a2dp_preset *caps;
> +       GSList *presets;
> +};
> +
>  struct a2dp_device {
>         bdaddr_t        dst;
>         uint8_t         state;
> @@ -70,6 +84,29 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
>         return bacmp(&dev->dst, dst);
>  }
>
> +static void preset_free(void *data)
> +{
> +       struct a2dp_preset *preset = data;
> +
> +       g_free(preset->data);
> +       g_free(preset);
> +}
> +
> +static void unregister_endpoint(void *data)
> +{
> +       struct a2dp_endpoint *endpoint = data;
> +
> +       if (endpoint->sep)
> +               avdtp_unregister_sep(endpoint->sep);
> +
> +       if (endpoint->caps)
> +               preset_free(endpoint->caps);
> +
> +       g_slist_free_full(endpoint->presets, preset_free);
> +
> +       g_free(endpoint);
> +}
> +
>  static void a2dp_device_free(struct a2dp_device *dev)
>  {
>         if (dev->session)
> @@ -354,10 +391,127 @@ static sdp_record_t *a2dp_record(void)
>         return record;
>  }
>
> +static gboolean sep_getcap_ind(struct avdtp *session,
> +                                       struct avdtp_local_sep *sep,
> +                                       GSList **caps, uint8_t *err,
> +                                       void *user_data)
> +{
> +       struct a2dp_endpoint *endpoint = user_data;
> +       struct a2dp_preset *cap = endpoint->presets->data;
> +       struct avdtp_service_capability *media_transport, *media_codec;
> +       struct avdtp_media_codec_capability *codec_caps;
> +
> +       *caps = NULL;
> +
> +       media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
> +                                                               NULL, 0);
> +
> +       *caps = g_slist_append(*caps, media_transport);
> +
> +       codec_caps = g_malloc0(sizeof(*codec_caps) + sizeof(cap));
> +       codec_caps->media_type = AVDTP_MEDIA_TYPE_AUDIO;
> +       codec_caps->media_codec_type = endpoint->codec;
> +       memcpy(codec_caps->data, cap->data, cap->len);
> +
> +       media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec_caps,
> +                                       sizeof(*codec_caps) + sizeof(cap));
> +
> +       *caps = g_slist_append(*caps, media_codec);
> +       g_free(codec_caps);
> +
> +       return TRUE;
> +}
> +
> +static struct avdtp_sep_ind sep_ind = {
> +       .get_capability         = sep_getcap_ind,
> +};
> +
> +static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec,
> +                                                       GSList *presets)
> +{
> +       struct a2dp_endpoint *endpoint;
> +
> +       /* FIXME: Add proper check for uuid */
> +
> +       endpoint = g_new0(struct a2dp_endpoint, 1);
> +       endpoint->id = g_slist_length(endpoints) + 1;
> +       endpoint->codec = codec;
> +       endpoint->sep = avdtp_register_sep(AVDTP_SEP_TYPE_SOURCE,
> +                                               AVDTP_MEDIA_TYPE_AUDIO,
> +                                               codec, FALSE, &sep_ind, NULL,
> +                                               endpoint);
> +       endpoint->caps = g_slist_nth_data(presets->data, 0);
> +       endpoint->presets = g_slist_copy(g_slist_nth(presets, 1));
> +
> +       endpoints = g_slist_append(endpoints, endpoint);
> +
> +       return endpoint->id;
> +}
> +
> +static GSList *parse_presets(const struct audio_preset *p, uint8_t count,
> +                                                               uint16_t len)
> +{
> +       GSList *l = NULL;
> +       uint8_t i;
> +
> +       for (i = 0; count > i; i++) {
> +               struct a2dp_preset *preset;
> +
> +               if (len < sizeof(struct audio_preset)) {
> +                       DBG("Invalid preset index %u", i);
> +                       break;
> +               }
> +
> +               len -= sizeof(struct audio_preset);
> +               if (len == 0 || len < p->len) {
> +                       DBG("Invalid preset size of %u for index %u", len, i);
> +                       break;
> +               }
> +
> +               preset = g_new0(struct a2dp_preset, 1);
> +               preset->len = p->len;
> +               preset->data = g_memdup(p->data, preset->len);
> +               l = g_slist_append(l, preset);
> +
> +               len -= preset->len;
> +               p += sizeof(struct audio_preset) + preset->len;

It would be better to explicitly use uint8_t pointer for presets
buffer since this will work only as long as sizeof(struct
audio_preset) is 1.


Andrzej

^ permalink raw reply


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