* 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
* [PATCH] Bluetooth: BCSP fails to ACK re-transmitted frames from the peer
From: Dean_Jenkins @ 2014-01-12 16:27 UTC (permalink / raw)
To: linux-bluetooth, marcel, gustavo; +Cc: Dean_Jenkins
From: Dean Jenkins <djenkins@mentor.com>
Send an ACK frame with the current txack value in response to
every received reliable frame unless a TX reliable frame is being
sent. This modification allows re-transmitted frames from the remote
peer to be acknowledged rather than ignored. It means that the remote
peer knows which frame number to start re-transmitting from.
Without this modification, the recovery time to a missing frame
from the remote peer was unnecessarily being extended because the
headers of the out of order reliable frames were being discarded rather
than being processed. The frame headers of received frames will
indicate whether the local peer's transmissions have been
acknowledged by the remote peer. Therefore, the local peer may
unnecessarily re-transmit despite the remote peer already indicating
that the frame had been acknowledged in out of order reliable frame.
Signed-off-by: Dean Jenkins <djenkins@mentor.com>
---
drivers/bluetooth/hci_bcsp.c | 94 ++++++++++++++++++++++++++++----------------
1 file changed, 60 insertions(+), 34 deletions(-)
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 0bc87f7..449de29 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -473,13 +473,30 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char
static void bcsp_complete_rx_pkt(struct hci_uart *hu)
{
struct bcsp_struct *bcsp = hu->priv;
- int pass_up;
+ int pass_up = 0;
if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
- bcsp->rxseq_txack++;
- bcsp->rxseq_txack %= 0x8;
- bcsp->txack_req = 1;
+
+ /* check the rx sequence number is as expected */
+ if ((bcsp->rx_skb->data[0] & 0x07) == bcsp->rxseq_txack) {
+ bcsp->rxseq_txack++;
+ bcsp->rxseq_txack %= 0x8;
+ } else {
+ /*
+ * handle re-transmitted packet or
+ * when packet was missed
+ */
+ BT_ERR("Out-of-order packet arrived, got %u expected %u",
+ bcsp->rx_skb->data[0] & 0x07,
+ bcsp->rxseq_txack);
+
+ /* do not process out-of-order packet payload */
+ pass_up = 2;
+ }
+
+ /* send current txack value to all recieved reliable packets */
+ bcsp->txack_req = 1;
/* If needed, transmit an ack pkt */
hci_uart_tx_wakeup(hu);
@@ -488,26 +505,35 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
BT_DBG("Request for pkt %u from card", bcsp->rxack);
+ /*
+ * handle recieved ACK indications,
+ * including those from out-of-order packets
+ */
bcsp_pkt_cull(bcsp);
- if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
- bcsp->rx_skb->data[0] & 0x80) {
- bt_cb(bcsp->rx_skb)->pkt_type = HCI_ACLDATA_PKT;
- pass_up = 1;
- } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
- bcsp->rx_skb->data[0] & 0x80) {
- bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
- pass_up = 1;
- } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
- bt_cb(bcsp->rx_skb)->pkt_type = HCI_SCODATA_PKT;
- pass_up = 1;
- } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
- !(bcsp->rx_skb->data[0] & 0x80)) {
- bcsp_handle_le_pkt(hu);
- pass_up = 0;
- } else
- pass_up = 0;
-
- if (!pass_up) {
+
+ if (pass_up != 2) {
+ if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
+ bcsp->rx_skb->data[0] & 0x80) {
+ bt_cb(bcsp->rx_skb)->pkt_type = HCI_ACLDATA_PKT;
+ pass_up = 1;
+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
+ bcsp->rx_skb->data[0] & 0x80) {
+ bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
+ pass_up = 1;
+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
+ bt_cb(bcsp->rx_skb)->pkt_type = HCI_SCODATA_PKT;
+ pass_up = 1;
+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
+ !(bcsp->rx_skb->data[0] & 0x80)) {
+ bcsp_handle_le_pkt(hu);
+ pass_up = 0;
+ } else
+ pass_up = 0;
+ }
+
+ switch (pass_up) {
+ case 0:
+ {
struct hci_event_hdr hdr;
u8 desc = (bcsp->rx_skb->data[1] & 0x0f);
@@ -532,11 +558,21 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
}
} else
kfree_skb(bcsp->rx_skb);
- } else {
+ break;
+ }
+ case 1:
/* Pull out BCSP hdr */
skb_pull(bcsp->rx_skb, 4);
hci_recv_frame(hu->hdev, bcsp->rx_skb);
+ break;
+ default:
+ /*
+ * ignore packet payload of already ACKed re-transmitted
+ * packets or when a packet was missed in the BCSP window
+ */
+ kfree_skb(bcsp->rx_skb);
+ break;
}
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
@@ -582,16 +618,6 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
bcsp->rx_count = 0;
continue;
}
- if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
- && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
- BT_ERR ("Out-of-order packet arrived, got %u expected %u",
- bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
-
- kfree_skb(bcsp->rx_skb);
- bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
- bcsp->rx_count = 0;
- continue;
- }
bcsp->rx_state = BCSP_W4_DATA;
bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
(bcsp->rx_skb->data[2] << 4); /* May be 0 */
--
1.8.1.5
^ permalink raw reply related
* [PATCH] Bluetooth: Avoid use of session socket after the session gets freed
From: Dean_Jenkins @ 2014-01-12 13:20 UTC (permalink / raw)
To: linux-bluetooth, marcel, gustavo; +Cc: Dean_Jenkins, vitaly_kuzmichev
From: Vitaly Kuzmichev <vitaly_kuzmichev@mentor.com>
The commits 08c30aca9e698faddebd34f81e1196295f9dc063 "Bluetooth: Remove
RFCOMM session refcnt" and 8ff52f7d04d9cc31f1e81dcf9a2ba6335ed34905
"Bluetooth: Return RFCOMM session ptrs to avoid freed session"
allow rfcomm_recv_ua and rfcomm_session_close to delete the session
(and free the corresponding socket) and propagate NULL session pointer
to the upper callers.
Additional fix is required to terminate the loop in rfcomm_process_rx
function to avoid use of freed 'sk' memory.
The issue is only reproducible with kernel option CONFIG_PAGE_POISONING
enabled making freed memory being changed and filled up with fixed char
value used to unmask use-after-free issues.
Signed-off-by: Vitaly Kuzmichev <Vitaly_Kuzmichev@mentor.com>
Acked-by: Dean Jenkins <Dean_Jenkins@mentor.com>
---
net/bluetooth/rfcomm/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index facd8a7..5632146 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1857,7 +1857,7 @@ static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s)
BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->sk_receive_queue));
/* Get data directly from socket receive queue without copying it. */
- while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
+ while (s && (skb = skb_dequeue(&sk->sk_receive_queue))) {
skb_orphan(skb);
if (!skb_linearize(skb))
s = rfcomm_recv_frame(s, skb);
--
1.8.1.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox