2011-08-01 08:42:05

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 00/13] AVRCP 1.3 pdus

From: Luiz Augusto von Dentz <[email protected]>

This adds parsing for remaining pdus defined by AVRCP 1.3 spec, here is
an example of what it would generate using current upstream agains Sony
MW600 headset (note that current upstream has a bug in which it sets an
invalid pdu length for not implemented response):

> AVCTP: Command : pt 0x00 transaction 5 pid 0x110e
AV/C: Status: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: GetCapabilities: pt 0x00 len 0x0001
CapabilityID: 0x02 (CompanyID)
< AVCTP: Response : pt 0x00 transaction 5 pid 0x110e
AV/C: Not Implemented: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: GetCapabilities: pt 0x00 len 0x0001
PDU Malformed
> AVCTP: Command : pt 0x00 transaction 6 pid 0x110e
AV/C: Notify: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: RegisterNotification: pt 0x00 len 0x0005
EventID: 0x02 (EVENT_TRACK_CHANGED)
Interval: 0x0000000a (10 seconds)
< AVCTP: Response : pt 0x00 transaction 6 pid 0x110e
AV/C: Not Implemented: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: RegisterNotification: pt 0x00 len 0x0005
PDU Malformed

Same thing but now using Lucas's tree:

< AVCTP: Response : pt 0x00 transaction 5 pid 0x110e
AV/C: Stable: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: GetCapabilities: pt 0x00 len 0x0005
CapabilityID: 0x02 (CompanyID)
CapabilityCount: 0x01
CompanyID: 0x001958
> AVCTP: Command : pt 0x00 transaction 6 pid 0x110e
AV/C: Status: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: GetCapabilities: pt 0x00 len 0x0001
CapabilityID: 0x03 (EventsID)
< AVCTP: Response : pt 0x00 transaction 6 pid 0x110e
AV/C: Stable: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: GetCapabilities: pt 0x00 len 0x0004
CapabilityID: 0x03 (EventsID)
CapabilityCount: 0x02
EventsID: 0x01 (EVENT_PLAYBACK_STATUS_CHANGED)
EventsID: 0x02 (EVENT_TRACK_CHANGED)
> AVCTP: Command : pt 0x00 transaction 7 pid 0x110e
AV/C: Notify: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: RegisterNotification: pt 0x00 len 0x0005
EventID: 0x02 (EVENT_TRACK_CHANGED)
Interval: 0x0000000a (10 seconds)
< AVCTP: Response : pt 0x00 transaction 7 pid 0x110e
AV/C: Interim: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: RegisterNotification: pt 0x00 len 0x0009
EventID: 0x02 (EVENT_TRACK_CHANGED)
Identifier: 0xffffffffffffffff (Reserved)
> AVCTP: Command : pt 0x00 transaction 8 pid 0x110e
AV/C: Status: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: GetElementAttributes: pt 0x00 len 0x000d
Identifier: 0x0 (PLAYING)
AttributeCount: 0x01
Attribute: 0x00000001 (Title)
< AVCTP: Response : pt 0x00 transaction 8 pid 0x110e
AV/C: Stable: address 0x48 opcode 0x00
Subunit: Panel
Opcode: Vendor Dependent
Company ID: 0x001958
AVRCP: GetElementAttributes: pt 0x00 len 0x0009
AttributeCount: 0x01
Attribute: 0x00000001 (Title)
CharsetID: 0x006a (UTF-8)
AttributeValueLength: 0x0000
AttributeValue:

Luiz Augusto von Dentz (13):
Don't parse response AVRCP pdu if ctype is NOT_IMPLETED
Add parsing for command type rejected AVRCP responses
Add parsing for AVRCP ListPlayerApplicationSettingAttributes pdu
Add parsing for AVRCP ListPlayerApplicationSettingValues pdu
Add parsing for AVRCP GetCurrentPlayerApplicationSettingValue pdu
Add parsing for AVRCP SetPlayerApplicationSettingValue pdu
Add parsing for AVRCP GetPlayerApplicationSettingAttributeText pdu
Add parsing for AVRCP GetPlayerApplicationSettingValueText pdu
Add parsing for AVRCP InformDisplayableCharacterSet pdu
Add parsing for AVRCP InformBatteryStatusOfCT pdu
Add parsing for AVRCP GetElementAttributes pdu
Add parsing for AVRCP GetPlayStatus pdu
Add parsing for AVRCP RegisterNotification pdu

parser/avrcp.c | 863 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 863 insertions(+), 0 deletions(-)

--
1.7.6



2011-08-01 15:44:25

by Lucas De Marchi

[permalink] [raw]
Subject: Re: [PATCH hcidump 01/13] Don't parse response AVRCP pdu if ctype is NOT_IMPLETED

On Mon, Aug 1, 2011 at 12:25 PM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Lucas,
>
> On Mon, Aug 1, 2011 at 5:11 PM, Lucas De Marchi
> <[email protected]> wrote:
>> On Mon, Aug 1, 2011 at 5:42 AM, Luiz Augusto von Dentz
>> <[email protected]> wrote:
>>> From: Luiz Augusto von Dentz <[email protected]>
>>>
>>> ---
>>> ?parser/avrcp.c | ? ?3 +++
>>> ?1 files changed, 3 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/parser/avrcp.c b/parser/avrcp.c
>>> index ff6862d..a1768e3 100644
>>> --- a/parser/avrcp.c
>>> +++ b/parser/avrcp.c
>>> @@ -347,6 +347,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
>>> ? ? ? ? ? ? ? ?return;
>>> ? ? ? ?}
>>>
>>> + ? ? ? if (ctype == AVC_CTYPE_NOT_IMPLEMENTED)
>>> + ? ? ? ? ? ? ? return;
>>> +
>>
>> From my reading of the spec, this check should be in avrcp_dump()
>> function -- like you did for skipping non-panel subunit packets. This
>> is because in the not-implemented case, only the avctp + avrcp headers
>> are sent, with no operands inside.
>> In AVRCP 1.3, section 4.3.4:
>>
>> "All of the operands are optional and are defined based on the values
>> of ctype, subunit_type, and opcode."
>>
>> In case ctype == NOT_IMPLEMENTED, there isn't any operand.
>
> But apparently the avrcp header indicates it length wrong (!= 0), also

You should not be reading this field because:

> avrcp_pdu_dump is called to print the avrcp header but perhaps the
> header itself is already considered an operand and in that should not
> even that should be present in the response.

And it's not in the response as far as I could check.


Lucas De Marchi

2011-08-01 15:25:53

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH hcidump 01/13] Don't parse response AVRCP pdu if ctype is NOT_IMPLETED

Hi Lucas,

On Mon, Aug 1, 2011 at 5:11 PM, Lucas De Marchi
<[email protected]> wrote:
> On Mon, Aug 1, 2011 at 5:42 AM, Luiz Augusto von Dentz
> <[email protected]> wrote:
>> From: Luiz Augusto von Dentz <[email protected]>
>>
>> ---
>> ?parser/avrcp.c | ? ?3 +++
>> ?1 files changed, 3 insertions(+), 0 deletions(-)
>>
>> diff --git a/parser/avrcp.c b/parser/avrcp.c
>> index ff6862d..a1768e3 100644
>> --- a/parser/avrcp.c
>> +++ b/parser/avrcp.c
>> @@ -347,6 +347,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
>> ? ? ? ? ? ? ? ?return;
>> ? ? ? ?}
>>
>> + ? ? ? if (ctype == AVC_CTYPE_NOT_IMPLEMENTED)
>> + ? ? ? ? ? ? ? return;
>> +
>
> From my reading of the spec, this check should be in avrcp_dump()
> function -- like you did for skipping non-panel subunit packets. This
> is because in the not-implemented case, only the avctp + avrcp headers
> are sent, with no operands inside.
> In AVRCP 1.3, section 4.3.4:
>
> "All of the operands are optional and are defined based on the values
> of ctype, subunit_type, and opcode."
>
> In case ctype == NOT_IMPLEMENTED, there isn't any operand.

But apparently the avrcp header indicates it length wrong (!= 0), also
avrcp_pdu_dump is called to print the avrcp header but perhaps the
header itself is already considered an operand and in that should not
even that should be present in the response.


--
Luiz Augusto von Dentz

2011-08-01 14:11:39

by Lucas De Marchi

[permalink] [raw]
Subject: Re: [PATCH hcidump 01/13] Don't parse response AVRCP pdu if ctype is NOT_IMPLETED

On Mon, Aug 1, 2011 at 5:42 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> ---
> ?parser/avrcp.c | ? ?3 +++
> ?1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/parser/avrcp.c b/parser/avrcp.c
> index ff6862d..a1768e3 100644
> --- a/parser/avrcp.c
> +++ b/parser/avrcp.c
> @@ -347,6 +347,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
> ? ? ? ? ? ? ? ?return;
> ? ? ? ?}
>
> + ? ? ? if (ctype == AVC_CTYPE_NOT_IMPLEMENTED)
> + ? ? ? ? ? ? ? return;
> +

>From my reading of the spec, this check should be in avrcp_dump()
function -- like you did for skipping non-panel subunit packets. This
is because in the not-implemented case, only the avctp + avrcp headers
are sent, with no operands inside.

In AVRCP 1.3, section 4.3.4:

"All of the operands are optional and are defined based on the values
of ctype, subunit_type, and opcode."

In case ctype == NOT_IMPLEMENTED, there isn't any operand.



Lucas De Marchi

2011-08-01 13:25:11

by Lucas De Marchi

[permalink] [raw]
Subject: Re: [PATCH hcidump 00/13] AVRCP 1.3 pdus

Hi Luiz

On Mon, Aug 1, 2011 at 5:42 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> This adds parsing for remaining pdus defined by AVRCP 1.3 spec, here is
> an example of what it would generate using current upstream agains Sony
> MW600 headset (note that current upstream has a bug in which it sets an
> invalid pdu length for not implemented response):
>
>> AVCTP: Command : pt 0x00 transaction 5 pid 0x110e
> ? ?AV/C: Status: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: GetCapabilities: pt 0x00 len 0x0001
> ? ? ? ?CapabilityID: 0x02 (CompanyID)
> < AVCTP: Response : pt 0x00 transaction 5 pid 0x110e
> ? ?AV/C: Not Implemented: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: GetCapabilities: pt 0x00 len 0x0001
> ? ? ?PDU Malformed
>> AVCTP: Command : pt 0x00 transaction 6 pid 0x110e
> ? ?AV/C: Notify: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: RegisterNotification: pt 0x00 len 0x0005
> ? ? ? ?EventID: 0x02 (EVENT_TRACK_CHANGED)
> ? ? ? ?Interval: 0x0000000a (10 seconds)
> < AVCTP: Response : pt 0x00 transaction 6 pid 0x110e
> ? ?AV/C: Not Implemented: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: RegisterNotification: pt 0x00 len 0x0005
> ? ? ?PDU Malformed
>
> Same thing but now using Lucas's tree:
>
> < AVCTP: Response : pt 0x00 transaction 5 pid 0x110e
> ? ?AV/C: Stable: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: GetCapabilities: pt 0x00 len 0x0005
> ? ? ? ?CapabilityID: 0x02 (CompanyID)
> ? ? ? ?CapabilityCount: 0x01
> ? ? ? ?CompanyID: 0x001958
>> AVCTP: Command : pt 0x00 transaction 6 pid 0x110e
> ? ?AV/C: Status: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: GetCapabilities: pt 0x00 len 0x0001
> ? ? ? ?CapabilityID: 0x03 (EventsID)
> < AVCTP: Response : pt 0x00 transaction 6 pid 0x110e
> ? ?AV/C: Stable: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: GetCapabilities: pt 0x00 len 0x0004
> ? ? ? ?CapabilityID: 0x03 (EventsID)
> ? ? ? ?CapabilityCount: 0x02
> ? ? ? ?EventsID: 0x01 (EVENT_PLAYBACK_STATUS_CHANGED)
> ? ? ? ?EventsID: 0x02 (EVENT_TRACK_CHANGED)
>> AVCTP: Command : pt 0x00 transaction 7 pid 0x110e
> ? ?AV/C: Notify: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: RegisterNotification: pt 0x00 len 0x0005
> ? ? ? ?EventID: 0x02 (EVENT_TRACK_CHANGED)
> ? ? ? ?Interval: 0x0000000a (10 seconds)
> < AVCTP: Response : pt 0x00 transaction 7 pid 0x110e
> ? ?AV/C: Interim: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: RegisterNotification: pt 0x00 len 0x0009
> ? ? ? ?EventID: 0x02 (EVENT_TRACK_CHANGED)
> ? ? ? ?Identifier: 0xffffffffffffffff (Reserved)
>> AVCTP: Command : pt 0x00 transaction 8 pid 0x110e
> ? ?AV/C: Status: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: GetElementAttributes: pt 0x00 len 0x000d
> ? ? ? ?Identifier: 0x0 (PLAYING)
> ? ? ? ?AttributeCount: 0x01
> ? ? ? ?Attribute: 0x00000001 (Title)
> < AVCTP: Response : pt 0x00 transaction 8 pid 0x110e
> ? ?AV/C: Stable: address 0x48 opcode 0x00
> ? ? ?Subunit: Panel
> ? ? ?Opcode: Vendor Dependent
> ? ? ?Company ID: 0x001958
> ? ? ?AVRCP: GetElementAttributes: pt 0x00 len 0x0009
> ? ? ? ?AttributeCount: 0x01
> ? ? ? ?Attribute: 0x00000001 (Title)
> ? ? ? ?CharsetID: 0x006a (UTF-8)
> ? ? ? ?AttributeValueLength: 0x0000
> ? ? ? ?AttributeValue:
>

Nice, I've been using this with my implementation of AVRCP 1.3 and
it's working fine.

thanks,
Lucas De Marchi

2011-08-01 08:42:16

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 11/13] Add parsing for AVRCP GetElementAttributes pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 114 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index bb7bcbb..49a7145 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -158,6 +158,16 @@
#define AVRCP_ATTRIBUTE_SHUFFLE 0x03
#define AVRCP_ATTRIBUTE_SCAN 0x04

+/* media attributes */
+#define AVRCP_MEDIA_ATTRIBUTE_ILLEGAL 0x0
+#define AVRCP_MEDIA_ATTRIBUTE_TITLE 0x1
+#define AVRCP_MEDIA_ATTRIBUTE_ARTIST 0x2
+#define AVRCP_MEDIA_ATTRIBUTE_ALBUM 0x3
+#define AVRCP_MEDIA_ATTRIBUTE_TRACK 0x4
+#define AVRCP_MEDIA_ATTRIBUTE_TOTAL 0x5
+#define AVRCP_MEDIA_ATTRIBUTE_GENRE 0x6
+#define AVRCP_MEDIA_ATTRIBUTE_PROGRESS 0x7
+
static const char *ctype2str(uint8_t ctype)
{
switch (ctype & 0x0f) {
@@ -879,6 +889,107 @@ static void avrcp_ct_battery_status_dump(int level, struct frame *frm,
printf("BatteryStatus: 0x%02x (%s)\n", status, status2str(status));
}

+static const char *mediattr2str(uint32_t attr)
+{
+ switch (attr) {
+ case AVRCP_MEDIA_ATTRIBUTE_ILLEGAL:
+ return "Illegal";
+ case AVRCP_MEDIA_ATTRIBUTE_TITLE:
+ return "Title";
+ case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
+ return "Artist";
+ case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
+ return "Album";
+ case AVRCP_MEDIA_ATTRIBUTE_TRACK:
+ return "Track";
+ case AVRCP_MEDIA_ATTRIBUTE_TOTAL:
+ return "Track Total";
+ case AVRCP_MEDIA_ATTRIBUTE_GENRE:
+ return "Genre";
+ case AVRCP_MEDIA_ATTRIBUTE_PROGRESS:
+ return "Progress";
+ default:
+ return "Reserved";
+ }
+}
+
+static void avrcp_get_element_attributes_dump(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ uint64_t id;
+ uint8_t num;
+
+ p_indent(level, frm);
+
+ if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
+ goto response;
+
+ if (len < 9) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ id = get_u64(frm);
+ printf("Identifier: 0x%jx (%s)\n", id, id ? "Reserved" : "PLAYING");
+
+ p_indent(level, frm);
+
+ num = get_u8(frm);
+ printf("AttributeCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint32_t attr;
+
+ p_indent(level, frm);
+
+ attr = get_u32(frm);
+ printf("Attribute: 0x%08x (%s)\n", attr, mediattr2str(attr));
+ }
+
+ return;
+
+response:
+ if (len < 1) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ num = get_u8(frm);
+ printf("AttributeCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint32_t attr;
+ uint16_t charset, len;
+
+ p_indent(level, frm);
+
+ attr = get_u32(frm);
+ printf("Attribute: 0x%08x (%s)\n", attr, mediattr2str(attr));
+
+ p_indent(level, frm);
+
+ charset = get_u16(frm);
+ printf("CharsetID: 0x%04x (%s)\n", charset,
+ charset2str(charset));
+
+ p_indent(level, frm);
+
+ len = get_u16(frm);
+ printf("AttributeValueLength: 0x%04x\n", len);
+
+ p_indent(level, frm);
+
+ printf("AttributeValue: ");
+ for (; len > 0; len--) {
+ uint8_t c = get_u8(frm);
+ printf("%1c", isprint(c) ? c : '.');
+ }
+ printf("\n");
+ }
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -937,6 +1048,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
case AVRCP_CT_BATTERY_STATUS:
avrcp_ct_battery_status_dump(level + 1, frm, ctype, len);
break;
+ case AVRCP_GET_ELEMENT_ATTRIBUTES:
+ avrcp_get_element_attributes_dump(level + 1, frm, ctype, len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:18

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 13/13] Add parsing for AVRCP RegisterNotification pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 101 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index 07a93ad..8412ccf 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -1049,6 +1049,104 @@ static void avrcp_get_play_status_dump(int level, struct frame *frm,
printf("PlayStatus: 0x%02x (%s)\n", status, playstatus2str(status));
}

+static void avrcp_register_notification_dump(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ uint8_t event, status;
+ uint32_t interval;
+ uint64_t id;
+
+ p_indent(level, frm);
+
+ if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
+ goto response;
+
+ if (len < 5) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ event = get_u8(frm);
+ printf("EventID: 0x%02x (%s)\n", event, event2str(event));
+
+ p_indent(level, frm);
+
+ interval = get_u32(frm);
+ printf("Interval: 0x%08x (%u seconds)\n", interval, interval);
+
+ return;
+
+response:
+ if (len < 1) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ event = get_u8(frm);
+ printf("EventID: 0x%02x (%s)\n", event, event2str(event));
+
+ p_indent(level, frm);
+
+ switch (event) {
+ case AVRCP_EVENT_PLAYBACK_STATUS_CHANGED:
+ status = get_u8(frm);
+ printf("PlayStatus: 0x%02x (%s)\n", status,
+ playstatus2str(status));
+ break;
+ case AVRCP_EVENT_TRACK_CHANGED:
+ id = get_u64(frm);
+ printf("Identifier: 0x%jx (%s)\n", id,
+ id ? "Reserved" : "PLAYING");
+ break;
+ case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
+ interval = get_u32(frm);
+ printf("Position: 0x%08x (%u miliseconds)\n", interval,
+ interval);
+ break;
+ case AVRCP_EVENT_BATT_STATUS_CHANGED:
+ status = get_u8(frm);
+ printf("BatteryStatus: 0x%02x (%s)\n", status,
+ status2str(status));
+ break;
+ case AVRCP_EVENT_SYSTEM_STATUS_CHANGED:
+ status = get_u8(frm);
+ printf("SystemStatus: 0x%02x ", status);
+ switch (status) {
+ case 0x00:
+ printf("(POWER_ON)\n");
+ case 0x01:
+ printf("(POWER_OFF)\n");
+ case 0x02:
+ printf("(UNPLUGGED)\n");
+ default:
+ printf("(UNKOWN)\n");
+ }
+ break;
+ case AVRCP_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
+ status = get_u8(frm);
+ printf("AttributeCount: 0x%02x\n", status);
+
+ for (; status > 0; status--) {
+ uint8_t attr, value;
+
+ p_indent(level, frm);
+
+ attr = get_u8(frm);
+ printf("AttributeID: 0x%02x (%s)\n", attr,
+ attr2str(attr));
+
+ p_indent(level, frm);
+
+ value = get_u8(frm);
+ printf("ValueID: 0x%02x (%s)\n", value,
+ value2str(attr, value));
+ }
+ break;
+ }
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -1113,6 +1211,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
case AVRCP_GET_PLAY_STATUS:
avrcp_get_play_status_dump(level + 1, frm, ctype, len);
break;
+ case AVRCP_REGISTER_NOTIFICATION:
+ avrcp_register_notification_dump(level + 1, frm, ctype, len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:17

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 12/13] Add parsing for AVRCP GetPlayStatus pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index 49a7145..07a93ad 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -168,6 +168,14 @@
#define AVRCP_MEDIA_ATTRIBUTE_GENRE 0x6
#define AVRCP_MEDIA_ATTRIBUTE_PROGRESS 0x7

+/* play status */
+#define AVRCP_PLAY_STATUS_STOPPED 0x00
+#define AVRCP_PLAY_STATUS_PLAYING 0x01
+#define AVRCP_PLAY_STATUS_PAUSED 0x02
+#define AVRCP_PLAY_STATUS_FWD_SEEK 0x03
+#define AVRCP_PLAY_STATUS_REV_SEEK 0x04
+#define AVRCP_PLAY_STATUS_ERROR 0xFF
+
static const char *ctype2str(uint8_t ctype)
{
switch (ctype & 0x0f) {
@@ -990,6 +998,57 @@ response:
}
}

+static const char *playstatus2str(uint8_t status)
+{
+ switch (status) {
+ case AVRCP_PLAY_STATUS_STOPPED:
+ return "STOPPED";
+ case AVRCP_PLAY_STATUS_PLAYING:
+ return "PLAYING";
+ case AVRCP_PLAY_STATUS_PAUSED:
+ return "PAUSED";
+ case AVRCP_PLAY_STATUS_FWD_SEEK:
+ return "FWD_SEEK";
+ case AVRCP_PLAY_STATUS_REV_SEEK:
+ return "REV_SEEK";
+ case AVRCP_PLAY_STATUS_ERROR:
+ return "ERROR";
+ default:
+ return "Unknown";
+ }
+}
+
+static void avrcp_get_play_status_dump(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ uint32_t interval;
+ uint8_t status;
+
+ if (ctype <= AVC_CTYPE_GENERAL_INQUIRY)
+ return;
+
+ p_indent(level, frm);
+
+ if (len < 9) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ interval = get_u32(frm);
+ printf("SongLength: 0x%08x (%u miliseconds)\n", interval, interval);
+
+ p_indent(level, frm);
+
+ interval = get_u32(frm);
+ printf("SongPosition: 0x%08x (%u miliconds)\n", interval, interval);
+
+ p_indent(level, frm);
+
+ status = get_u8(frm);
+ printf("PlayStatus: 0x%02x (%s)\n", status, playstatus2str(status));
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -1051,6 +1110,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
case AVRCP_GET_ELEMENT_ATTRIBUTES:
avrcp_get_element_attributes_dump(level + 1, frm, ctype, len);
break;
+ case AVRCP_GET_PLAY_STATUS:
+ avrcp_get_play_status_dump(level + 1, frm, ctype, len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:14

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 09/13] Add parsing for AVRCP InformDisplayableCharacterSet pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 33 +++++++++++++++++++++++++++++++++
1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index 5fb5cbe..ababe03 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -817,6 +817,36 @@ response:
}
}

+static void avrcp_displayable_charset(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ uint8_t num;
+
+ if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
+ return;
+
+ p_indent(level, frm);
+
+ if (len < 2) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ num = get_u8(frm);
+ printf("CharsetCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint16_t charset;
+
+ p_indent(level, frm);
+
+ charset = get_u16(frm);
+ printf("CharsetID: 0x%04x (%s)\n", charset,
+ charset2str(charset));
+ }
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -869,6 +899,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
case AVRCP_GET_PLAYER_VALUE_TEXT:
avrcp_get_player_value_text_dump(level + 1, frm, ctype, len);
break;
+ case AVRCP_DISPLAYABLE_CHARSET:
+ avrcp_displayable_charset(level + 1, frm, ctype, len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:15

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 10/13] Add parsing for AVRCP InformBatteryStatusOfCT pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index ababe03..bb7bcbb 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -847,6 +847,38 @@ static void avrcp_displayable_charset(int level, struct frame *frm,
}
}

+static const char *status2str(uint8_t status)
+{
+ switch (status) {
+ case 0x0:
+ return "NORMAL";
+ case 0x1:
+ return "WARNING";
+ case 0x2:
+ return "CRITICAL";
+ case 0x3:
+ return "EXTERNAL";
+ case 0x4:
+ return "FULL_CHARGE";
+ default:
+ return "Reserved";
+ }
+}
+
+static void avrcp_ct_battery_status_dump(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ uint8_t status;
+
+ if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
+ return;
+
+ p_indent(level, frm);
+
+ status = get_u8(frm);
+ printf("BatteryStatus: 0x%02x (%s)\n", status, status2str(status));
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -902,6 +934,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
case AVRCP_DISPLAYABLE_CHARSET:
avrcp_displayable_charset(level + 1, frm, ctype, len);
break;
+ case AVRCP_CT_BATTERY_STATUS:
+ avrcp_ct_battery_status_dump(level + 1, frm, ctype, len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:13

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 08/13] Add parsing for AVRCP GetPlayerApplicationSettingValueText pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index 5915cc4..5fb5cbe 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -744,6 +744,79 @@ response:
}
}

+static void avrcp_get_player_value_text_dump(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ static uint8_t attr = 0; /* Remember attribute */
+ uint8_t num;
+
+ p_indent(level, frm);
+
+ if (len < 1) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
+ goto response;
+
+ attr = get_u8(frm);
+ printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
+
+ p_indent(level, frm);
+
+ num = get_u8(frm);
+ printf("ValueCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint8_t value;
+
+ p_indent(level, frm);
+
+ value = get_u8(frm);
+ printf("ValueID: 0x%02x (%s)\n", value,
+ value2str(attr, value));
+ }
+
+ return;
+
+response:
+ num = get_u8(frm);
+ printf("ValueCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint8_t value, len;
+ uint16_t charset;
+
+ p_indent(level, frm);
+
+ value = get_u8(frm);
+ printf("ValueID: 0x%02x (%s)\n", value,
+ value2str(attr, value));
+
+ p_indent(level, frm);
+
+ charset = get_u16(frm);
+ printf("CharsetID: 0x%04x (%s)\n", charset,
+ charset2str(charset));
+
+ p_indent(level, frm);
+
+ len = get_u8(frm);
+ printf("StringLength: 0x%02x\n", len);
+
+ p_indent(level, frm);
+
+ printf("String: ");
+ for (; len > 0; len--) {
+ uint8_t c = get_u8(frm);
+ printf("%1c", isprint(c) ? c : '.');
+ }
+ printf("\n");
+ }
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -793,6 +866,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
avrcp_get_player_attribute_text_dump(level + 1, frm, ctype,
len);
break;
+ case AVRCP_GET_PLAYER_VALUE_TEXT:
+ avrcp_get_player_value_text_dump(level + 1, frm, ctype, len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:11

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 06/13] Add parsing for AVRCP SetPlayerApplicationSettingValue pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index bb0dd1d..e07e77b 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -613,6 +613,41 @@ response:
}
}

+static void avrcp_set_player_value_dump(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ uint8_t num;
+
+ p_indent(level, frm);
+
+ if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
+ return;
+
+ if (len < 1) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ num = get_u8(frm);
+ printf("AttributeCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint8_t attr, value;
+
+ p_indent(level, frm);
+
+ attr = get_u8(frm);
+ printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
+
+ p_indent(level, frm);
+
+ value = get_u8(frm);
+ printf("ValueID: 0x%02x (%s)\n", value,
+ value2str(attr, value));
+ }
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -655,6 +690,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
avrcp_get_current_player_value_dump(level + 1, frm, ctype,
len);
break;
+ case AVRCP_SET_PLAYER_VALUE:
+ avrcp_set_player_value_dump(level + 1, frm, ctype, len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:12

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 07/13] Add parsing for AVRCP GetPlayerApplicationSettingAttributeText pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 100 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index e07e77b..5915cc4 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -30,6 +30,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>

#include <sys/types.h>
#include <netinet/in.h>
@@ -648,6 +649,101 @@ static void avrcp_set_player_value_dump(int level, struct frame *frm,
}
}

+static const char *charset2str(uint16_t charset)
+{
+ switch (charset) {
+ case 1:
+ case 2:
+ return "Reserved";
+ case 3:
+ return "ASCII";
+ case 4:
+ return "ISO_8859-1";
+ case 5:
+ return "ISO_8859-2";
+ case 6:
+ return "ISO_8859-3";
+ case 7:
+ return "ISO_8859-4";
+ case 8:
+ return "ISO_8859-5";
+ case 9:
+ return "ISO_8859-6";
+ case 10:
+ return "ISO_8859-7";
+ case 11:
+ return "ISO_8859-8";
+ case 12:
+ return "ISO_8859-9";
+ case 106:
+ return "UTF-8";
+ default:
+ return "Unknown";
+ }
+}
+
+static void avrcp_get_player_attribute_text_dump(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ uint8_t num;
+
+ p_indent(level, frm);
+
+ if (len < 1) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ num = get_u8(frm);
+ printf("AttributeCount: 0x%02x\n", num);
+
+ if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
+ goto response;
+
+ for (; num > 0; num--) {
+ uint8_t attr;
+
+ p_indent(level, frm);
+
+ attr = get_u8(frm);
+ printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
+ }
+
+ return;
+
+response:
+ for (; num > 0; num--) {
+ uint8_t attr, len;
+ uint16_t charset;
+
+ p_indent(level, frm);
+
+ attr = get_u8(frm);
+ printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
+
+ p_indent(level, frm);
+
+ charset = get_u16(frm);
+ printf("CharsetID: 0x%04x (%s)\n", charset,
+ charset2str(charset));
+
+ p_indent(level, frm);
+
+ len = get_u8(frm);
+ printf("StringLength: 0x%02x\n", len);
+
+ p_indent(level, frm);
+
+ printf("String: ");
+ for (; len > 0; len--) {
+ uint8_t c = get_u8(frm);
+ printf("%1c", isprint(c) ? c : '.');
+ }
+ printf("\n");
+ }
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -693,6 +789,10 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
case AVRCP_SET_PLAYER_VALUE:
avrcp_set_player_value_dump(level + 1, frm, ctype, len);
break;
+ case AVRCP_GET_PLAYER_ATTRIBUTE_TEXT:
+ avrcp_get_player_attribute_text_dump(level + 1, frm, ctype,
+ len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:10

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 05/13] Add parsing for AVRCP GetCurrentPlayerApplicationSettingValue pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index e6f8755..bb0dd1d 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -558,6 +558,61 @@ response:
}
}

+static void avrcp_get_current_player_value_dump(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ uint8_t num;
+
+ p_indent(level, frm);
+
+ if (len < 2) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
+ goto response;
+
+ num = get_u8(frm);
+ printf("AttributeCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint8_t attr;
+
+ p_indent(level, frm);
+
+ attr = get_u8(frm);
+ printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
+ }
+
+ return;
+
+response:
+ num = get_u8(frm);
+ printf("ValueCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint8_t attr, player, value;
+
+ p_indent(level, frm);
+
+ attr = get_u8(frm);
+ printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
+
+ p_indent(level, frm);
+
+ player = get_u8(frm);
+ printf("Player: 0x%02x\n", player);
+
+ p_indent(level, frm);
+
+ value = get_u8(frm);
+ printf("ValueID: 0x%02x (%s)\n", value,
+ value2str(attr, value));
+ }
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -596,6 +651,10 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
case AVRCP_LIST_PLAYER_VALUES:
avrcp_list_player_values_dump(level + 1, frm, ctype, len);
break;
+ case AVRCP_GET_CURRENT_PLAYER_VALUE:
+ avrcp_get_current_player_value_dump(level + 1, frm, ctype,
+ len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:09

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 04/13] Add parsing for AVRCP ListPlayerApplicationSettingValues pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index 7daba13..e6f8755 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -467,6 +467,97 @@ static void avrcp_list_player_attributes_dump(int level, struct frame *frm,
}
}

+static const char *value2str(uint8_t attr, uint8_t value)
+{
+ switch (attr) {
+ case AVRCP_ATTRIBUTE_ILEGAL:
+ return "Illegal";
+ case AVRCP_ATTRIBUTE_EQUALIZER:
+ switch (value) {
+ case 0x01:
+ return "OFF";
+ case 0x02:
+ return "ON";
+ default:
+ return "Reserved";
+ }
+ case AVRCP_ATTRIBUTE_REPEAT_MODE:
+ switch (value) {
+ case 0x01:
+ return "OFF";
+ case 0x02:
+ return "Single Track Repeat";
+ case 0x03:
+ return "All Track Repeat";
+ case 0x04:
+ return "Group Repeat";
+ default:
+ return "Reserved";
+ }
+ case AVRCP_ATTRIBUTE_SHUFFLE:
+ switch (value) {
+ case 0x01:
+ return "OFF";
+ case 0x02:
+ return "All Track Suffle";
+ case 0x03:
+ return "Group Suffle";
+ default:
+ return "Reserved";
+ }
+ case AVRCP_ATTRIBUTE_SCAN:
+ switch (value) {
+ case 0x01:
+ return "OFF";
+ case 0x02:
+ return "All Track Scan";
+ case 0x03:
+ return "Group Scan";
+ default:
+ return "Reserved";
+ }
+ default:
+ return "Unknown";
+ }
+}
+
+static void avrcp_list_player_values_dump(int level, struct frame *frm,
+ uint8_t ctype, uint16_t len)
+{
+ static uint8_t attr = 0; /* Remember attribute */
+ uint8_t num;
+
+ p_indent(level, frm);
+
+ if (len < 1) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ if (ctype > AVC_CTYPE_GENERAL_INQUIRY)
+ goto response;
+
+ attr = get_u8(frm);
+ printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
+
+ return;
+
+response:
+ num = get_u8(frm);
+ printf("ValueCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint8_t value;
+
+ p_indent(level, frm);
+
+ value = get_u8(frm);
+ printf("ValueID: 0x%02x (%s)\n", value,
+ value2str(attr, value));
+ }
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -502,6 +593,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
case AVRCP_LIST_PLAYER_ATTRIBUTES:
avrcp_list_player_attributes_dump(level + 1, frm, len);
break;
+ case AVRCP_LIST_PLAYER_VALUES:
+ avrcp_list_player_values_dump(level + 1, frm, ctype, len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:08

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 03/13] Add parsing for AVRCP ListPlayerApplicationSettingAttributes pdu

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index 025805e..7daba13 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -150,6 +150,13 @@
#define AVRCP_STATUS_NO_AVAILABLE_PLAYERS 0x15
#define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED 0x16

+/* player attributes */
+#define AVRCP_ATTRIBUTE_ILEGAL 0x00
+#define AVRCP_ATTRIBUTE_EQUALIZER 0x01
+#define AVRCP_ATTRIBUTE_REPEAT_MODE 0x02
+#define AVRCP_ATTRIBUTE_SHUFFLE 0x03
+#define AVRCP_ATTRIBUTE_SCAN 0x04
+
static const char *ctype2str(uint8_t ctype)
{
switch (ctype & 0x0f) {
@@ -419,6 +426,47 @@ static void avrcp_get_capabilities_dump(int level, struct frame *frm, uint16_t l
}
}

+static const char *attr2str(uint8_t attr)
+{
+ switch (attr) {
+ case AVRCP_ATTRIBUTE_ILEGAL:
+ return "Illegal";
+ case AVRCP_ATTRIBUTE_EQUALIZER:
+ return "Equalizer ON/OFF Status";
+ case AVRCP_ATTRIBUTE_REPEAT_MODE:
+ return "Repeat Mode Status";
+ case AVRCP_ATTRIBUTE_SHUFFLE:
+ return "Shuffle ON/OFF Status";
+ case AVRCP_ATTRIBUTE_SCAN:
+ return "Scan ON/OFF Status";
+ default:
+ return "Unknown";
+ }
+}
+
+static void avrcp_list_player_attributes_dump(int level, struct frame *frm,
+ uint16_t len)
+{
+ uint8_t num;
+
+ if (len == 0)
+ return;
+
+ p_indent(level, frm);
+
+ num = get_u8(frm);
+ printf("AttributeCount: 0x%02x\n", num);
+
+ for (; num > 0; num--) {
+ uint8_t attr;
+
+ p_indent(level, frm);
+
+ attr = get_u8(frm);
+ printf("AttributeID: 0x%02x (%s)\n", attr, attr2str(attr));
+ }
+}
+
static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
{
uint8_t pduid, pt;
@@ -451,6 +499,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
case AVRCP_GET_CAPABILITIES:
avrcp_get_capabilities_dump(level + 1, frm, len);
break;
+ case AVRCP_LIST_PLAYER_ATTRIBUTES:
+ avrcp_list_player_attributes_dump(level + 1, frm, len);
+ break;
default:
raw_dump(level, frm);
}
--
1.7.6


2011-08-01 08:42:07

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 02/13] Add parsing for command type rejected AVRCP responses

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index a1768e3..025805e 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -126,6 +126,30 @@
#define AVRCP_EVENT_UIDS_CHANGED 0x0c
#define AVRCP_EVENT_VOLUME_CHANGED 0x0d

+/* error statuses */
+#define AVRCP_STATUS_INVALID_COMMAND 0x00
+#define AVRCP_STATUS_INVALID_PARAMETER 0x01
+#define AVRCP_STATUS_NOT_FOUND 0x02
+#define AVRCP_STATUS_INTERNAL_ERROR 0x03
+#define AVRCP_STATUS_SUCCESS 0x04
+#define AVRCP_STATUS_UID_CHANGED 0x05
+#define AVRCP_STATUS_INVALID_DIRECTION 0x07
+#define AVRCP_STATUS_NOT_DIRECTORY 0x08
+#define AVRCP_STATUS_DOES_NOT_EXIST 0x09
+#define AVRCP_STATUS_INVALID_SCOPE 0x0a
+#define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b
+#define AVRCP_STATUS_IS_DIRECTORY 0x0c
+#define AVRCP_STATUS_MEDIA_IN_USE 0x0d
+#define AVRCP_STATUS_NOW_PLAYING_LIST_FULL 0x0e
+#define AVRCP_STATUS_SEARCH_NOT_SUPPORTED 0x0f
+#define AVRCP_STATUS_SEARCH_IN_PROGRESS 0x10
+#define AVRCP_STATUS_INVALID_PLAYER_ID 0x11
+#define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12
+#define AVRCP_STATUS_PLAYER_NOT_ADDRESSED 0x13
+#define AVRCP_STATUS_NO_VALID_SEARCH_RESULTS 0x14
+#define AVRCP_STATUS_NO_AVAILABLE_PLAYERS 0x15
+#define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED 0x16
+
static const char *ctype2str(uint8_t ctype)
{
switch (ctype & 0x0f) {
@@ -274,6 +298,74 @@ static char *event2str(uint8_t event)
}
}

+static const char *error2str(uint8_t status)
+{
+ switch (status) {
+ case AVRCP_STATUS_INVALID_COMMAND:
+ return "Invalid Command";
+ case AVRCP_STATUS_INVALID_PARAMETER:
+ return "Invalid Parameter";
+ case AVRCP_STATUS_NOT_FOUND:
+ return "Not Found";
+ case AVRCP_STATUS_INTERNAL_ERROR:
+ return "Internal Error";
+ case AVRCP_STATUS_SUCCESS:
+ return "Success";
+ case AVRCP_STATUS_UID_CHANGED:
+ return "UID Changed";
+ case AVRCP_STATUS_INVALID_DIRECTION:
+ return "Invalid Direction";
+ case AVRCP_STATUS_NOT_DIRECTORY:
+ return "Not a Directory";
+ case AVRCP_STATUS_DOES_NOT_EXIST:
+ return "Does Not Exist";
+ case AVRCP_STATUS_INVALID_SCOPE:
+ return "Invalid Scope";
+ case AVRCP_STATUS_OUT_OF_BOUNDS:
+ return "Range Out of Bonds";
+ case AVRCP_STATUS_MEDIA_IN_USE:
+ return "Media in Use";
+ case AVRCP_STATUS_IS_DIRECTORY:
+ return "UID is a Directory";
+ case AVRCP_STATUS_NOW_PLAYING_LIST_FULL:
+ return "Now Playing List Full";
+ case AVRCP_STATUS_SEARCH_NOT_SUPPORTED:
+ return "Seach Not Supported";
+ case AVRCP_STATUS_SEARCH_IN_PROGRESS:
+ return "Search in Progress";
+ case AVRCP_STATUS_INVALID_PLAYER_ID:
+ return "Invalid Player ID";
+ case AVRCP_STATUS_PLAYER_NOT_BROWSABLE:
+ return "Player Not Browsable";
+ case AVRCP_STATUS_PLAYER_NOT_ADDRESSED:
+ return "Player Not Addressed";
+ case AVRCP_STATUS_NO_VALID_SEARCH_RESULTS:
+ return "No Valid Search Result";
+ case AVRCP_STATUS_NO_AVAILABLE_PLAYERS:
+ return "No Available Players";
+ case AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED:
+ return "Addressed Player Changed";
+ default:
+ return "Unknown";
+ }
+}
+
+static void avrcp_rejected_dump(int level, struct frame *frm, uint16_t len)
+{
+ uint8_t status;
+
+ p_indent(level, frm);
+
+ if (len < 1) {
+ printf("PDU Malformed\n");
+ raw_dump(level, frm);
+ return;
+ }
+
+ status = get_u8(frm);
+ printf("Error: 0x%02x (%s)\n", status, error2str(status));
+}
+
static void avrcp_get_capabilities_dump(int level, struct frame *frm, uint16_t len)
{
uint8_t cap;
@@ -350,6 +442,11 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
if (ctype == AVC_CTYPE_NOT_IMPLEMENTED)
return;

+ if (ctype == AVC_CTYPE_REJECTED) {
+ avrcp_rejected_dump(level + 1, frm, len);
+ return;
+ }
+
switch (pduid) {
case AVRCP_GET_CAPABILITIES:
avrcp_get_capabilities_dump(level + 1, frm, len);
--
1.7.6


2011-08-01 08:42:06

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH hcidump 01/13] Don't parse response AVRCP pdu if ctype is NOT_IMPLETED

From: Luiz Augusto von Dentz <[email protected]>

---
parser/avrcp.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/parser/avrcp.c b/parser/avrcp.c
index ff6862d..a1768e3 100644
--- a/parser/avrcp.c
+++ b/parser/avrcp.c
@@ -347,6 +347,9 @@ static void avrcp_pdu_dump(int level, struct frame *frm, uint8_t ctype)
return;
}

+ if (ctype == AVC_CTYPE_NOT_IMPLEMENTED)
+ return;
+
switch (pduid) {
case AVRCP_GET_CAPABILITIES:
avrcp_get_capabilities_dump(level + 1, frm, len);
--
1.7.6