2015-08-10 11:07:40

by Bharat Bhusan Panda

[permalink] [raw]
Subject: [PATCH 1/2] audio/avrcp: Add support for SetAddressedPlayer

Supprot added to handle SetAddressedPlayer(0x60) command PDU
in AVRCP TG.

AVCTP Control: Command: type 0x00 label 12 PID 0x110e
AV/C: Control: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: SetAddressedPlayer pt Single len 0x0002
PlayerID: 0xffff (65535)

AVCTP Control: Response: type 0x00 label 12 PID 0x110e
AV/C: Rejected: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: SetAddressedPlayer pt Single len 0x0001
Error: 0x11 (Invalid Player ID)
---
profiles/audio/avrcp.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index d66f670..003e978 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -103,6 +103,7 @@
#define AVRCP_REQUEST_CONTINUING 0x40
#define AVRCP_ABORT_CONTINUING 0x41
#define AVRCP_SET_ABSOLUTE_VOLUME 0x50
+#define AVRCP_SET_ADDRESSED_PLAYER 0x60
#define AVRCP_SET_BROWSED_PLAYER 0x70
#define AVRCP_GET_FOLDER_ITEMS 0x71
#define AVRCP_CHANGE_PATH 0x72
@@ -204,6 +205,7 @@ struct avrcp_player {
uint64_t uid;
uint16_t uid_counter;
bool browsed;
+ bool addressed;
uint8_t *features;
char *path;

@@ -1617,6 +1619,57 @@ err:
return AVC_CTYPE_REJECTED;
}

+static struct avrcp_player *find_tg_player(struct avrcp *session, uint16_t id)
+{
+ struct avrcp_server *server = session->server;
+ GSList *l;
+
+ for (l = server->players; l; l = l->next) {
+ struct avrcp_player *player = l->data;
+
+ if (player->id == id)
+ return player;
+ }
+
+ return NULL;
+}
+
+static uint8_t avrcp_handle_set_addressed_player(struct avrcp *session,
+ struct avrcp_header *pdu,
+ uint8_t transaction)
+{
+ struct avrcp_player *player;
+ uint16_t len = ntohs(pdu->params_len);
+ uint16_t player_id = 0;
+ uint8_t status;
+
+ if (len < 1) {
+ status = AVRCP_STATUS_INVALID_PARAM;
+ goto err;
+ }
+
+ player_id = ntohs(pdu->params);
+ player = find_tg_player(session, player_id);
+ pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
+
+ if (player) {
+ player->addressed = true;
+ status = AVRCP_STATUS_SUCCESS;
+ pdu->params_len = htons(len);
+ pdu->params[0] = status;
+ } else {
+ status = AVRCP_STATUS_INVALID_PLAYER_ID;
+ goto err;
+ }
+
+ return AVC_CTYPE_ACCEPTED;
+
+err:
+ pdu->params_len = htons(sizeof(status));
+ pdu->params[0] = status;
+ return AVC_CTYPE_REJECTED;
+}
+
static const struct control_pdu_handler control_handlers[] = {
{ AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS,
avrcp_handle_get_capabilities },
@@ -1648,6 +1701,8 @@ static const struct control_pdu_handler control_handlers[] = {
avrcp_handle_request_continuing },
{ AVRCP_ABORT_CONTINUING, AVC_CTYPE_CONTROL,
avrcp_handle_abort_continuing },
+ { AVRCP_SET_ADDRESSED_PLAYER, AVC_CTYPE_CONTROL,
+ avrcp_handle_set_addressed_player },
{ },
};

--
1.9.1



2015-08-11 08:35:06

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH 2/2] audio/avrcp: Handle Addressed Player Changed event

Hi Bharat,

On Mon, Aug 10, 2015 at 2:07 PM, Bharat Panda <[email protected]> wrote:
> Added AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED to TG supported events.
> Send response and notify on change in addressed player.
>
> AVCTP Control: Response: type 0x00 label 12 PID 0x110e
> AV/C: Interim: address 0x48 opcode 0x00
> Subunit: Panel
> Opcode: Vendor Dependent
> Company ID: 0x001958
> AVRCP: RegisterNotification pt Single len 0x0005
> EventID: 0x0b (EVENT_ADDRESSED_PLAYER_CHANGED)
> PlayerID: 0x0000 (0)
> UIDCounter: 0x0000 (0)
>
> AVCTP Control: Response: type 0x00 label 3 PID 0x110e
> AV/C: Interim: address 0x48 opcode 0x00
> Subunit: Panel
> Opcode: Vendor Dependent
> Company ID: 0x001958
> AVRCP: RegisterNotification pt Single len 0x0005
> EventID: 0x0b (EVENT_ADDRESSED_PLAYER_CHANGED)
> PlayerID: 0x0002 (2)
> UIDCounter: 0x0a8a (2698)
> ---
> profiles/audio/avrcp.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
> index 003e978..596a866 100644
> --- a/profiles/audio/avrcp.c
> +++ b/profiles/audio/avrcp.c
> @@ -676,6 +676,11 @@ void avrcp_player_event(struct avrcp_player *player, uint8_t id,
> pdu->params[size++] = attr;
> pdu->params[size++] = val;
> break;
> + case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
> + size = 5;
> + memcpy(&pdu->params[1], &player->id, sizeof(uint16_t));
> + memcpy(&pdu->params[3], &player->uid_counter, sizeof(uint16_t));
> + break;

As a TG we should complete the player specific events with reject and
error code set to addressed player changed as the spec states.

> case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
> size = 1;
> break;
> @@ -1496,6 +1501,11 @@ static uint8_t avrcp_handle_register_notification(struct avrcp *session,
> }
>
> break;
> + case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
> + len = 5;
> + memcpy(&pdu->params[1], &player->id, sizeof(uint16_t));
> + memcpy(&pdu->params[3], &player->uid_counter, sizeof(uint16_t));
> + break;
> case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
> len = 1;
> break;
> @@ -3576,6 +3586,7 @@ static void target_init(struct avrcp *session)
> return;
>
> session->supported_events |=
> + (1 << AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED) |
> (1 << AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED);
>
> /* Only check capabilities if controller is not supported */
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html



--
Luiz Augusto von Dentz

2015-08-10 11:07:41

by Bharat Bhusan Panda

[permalink] [raw]
Subject: [PATCH 2/2] audio/avrcp: Handle Addressed Player Changed event

Added AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED to TG supported events.
Send response and notify on change in addressed player.

AVCTP Control: Response: type 0x00 label 12 PID 0x110e
AV/C: Interim: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: RegisterNotification pt Single len 0x0005
EventID: 0x0b (EVENT_ADDRESSED_PLAYER_CHANGED)
PlayerID: 0x0000 (0)
UIDCounter: 0x0000 (0)

AVCTP Control: Response: type 0x00 label 3 PID 0x110e
AV/C: Interim: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: RegisterNotification pt Single len 0x0005
EventID: 0x0b (EVENT_ADDRESSED_PLAYER_CHANGED)
PlayerID: 0x0002 (2)
UIDCounter: 0x0a8a (2698)
---
profiles/audio/avrcp.c | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 003e978..596a866 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -676,6 +676,11 @@ void avrcp_player_event(struct avrcp_player *player, uint8_t id,
pdu->params[size++] = attr;
pdu->params[size++] = val;
break;
+ case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
+ size = 5;
+ memcpy(&pdu->params[1], &player->id, sizeof(uint16_t));
+ memcpy(&pdu->params[3], &player->uid_counter, sizeof(uint16_t));
+ break;
case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
size = 1;
break;
@@ -1496,6 +1501,11 @@ static uint8_t avrcp_handle_register_notification(struct avrcp *session,
}

break;
+ case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
+ len = 5;
+ memcpy(&pdu->params[1], &player->id, sizeof(uint16_t));
+ memcpy(&pdu->params[3], &player->uid_counter, sizeof(uint16_t));
+ break;
case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
len = 1;
break;
@@ -3576,6 +3586,7 @@ static void target_init(struct avrcp *session)
return;

session->supported_events |=
+ (1 << AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED) |
(1 << AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED);

/* Only check capabilities if controller is not supported */
--
1.9.1