* [PATCH 0/4] Add parsing of BT 3.0+HS signalling
@ 2011-10-21 23:29 Peter Krystad
2011-10-21 23:29 ` [PATCH 1/4] Add parsing of L2CAP Create/Move Channel signals Peter Krystad
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Peter Krystad @ 2011-10-21 23:29 UTC (permalink / raw)
To: linux-bluetooth; +Cc: andrei.emeltchenko, Peter Krystad
This patchset adds parsing and display of BT 3.0+HS signalling
Peter Krystad (4):
Add parsing of L2CAP Create/Move Channel signals
Add parsing of A2MP signals
Add parsing of L2CAP Fixed Channel list
Minor cleanup of indentation in output
lib/amp.h | 133 +++++++++++++++
lib/l2cap.h | 50 ++++++
parser/hci.c | 15 +-
parser/l2cap.c | 498 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
parser/parser.h | 1 +
src/hcidump.c | 1 +
6 files changed, 693 insertions(+), 5 deletions(-)
create mode 100644 lib/amp.h
--
1.7.7
--
Peter Krystad
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 1/4] Add parsing of L2CAP Create/Move Channel signals 2011-10-21 23:29 [PATCH 0/4] Add parsing of BT 3.0+HS signalling Peter Krystad @ 2011-10-21 23:29 ` Peter Krystad 2011-10-22 7:21 ` Marcel Holtmann 2011-10-21 23:30 ` [PATCH 2/4] Add parsing of A2MP signals Peter Krystad ` (2 subsequent siblings) 3 siblings, 1 reply; 10+ messages in thread From: Peter Krystad @ 2011-10-21 23:29 UTC (permalink / raw) To: linux-bluetooth; +Cc: andrei.emeltchenko, Peter Krystad Add parsing of L2CAP Create/Move Channel signalling. Example output: 2011-10-18 16:09:47.810208 > ACL data: handle 39 flags 0x02 dlen 13 L2CAP(s): Create req: psm 4097 scid 0x4201 id 17 2011-10-18 16:09:47.810269 < ACL data: handle 39 flags 0x00 dlen 16 L2CAP(s): Create rsp: dcid 0x0040 scid 0x4201 result 1 status 0 2011-10-18 16:09:47.898308 < ACL data: handle 39 flags 0x00 dlen 16 L2CAP(s): Create rsp: dcid 0x0040 scid 0x4201 result 0 status 0 .... 2011-10-18 14:25:24.646869 > ACL data: handle 39 flags 0x02 dlen 11 L2CAP(s): Move req: icid 0x4000 id 17 2011-10-18 14:25:24.646987 < ACL data: handle 39 flags 0x00 dlen 12 L2CAP(s): Move rsp: icid 0x4000 result 1 2011-10-18 14:25:24.846873 < ACL data: handle 39 flags 0x00 dlen 12 L2CAP(s): Move rsp: icid 0x4000 result 0 2011-10-18 14:25:25.041844 > ACL data: handle 39 flags 0x02 dlen 12 L2CAP(s): Move cfm: icid 0x4000 result 0 2011-10-18 14:25:25.041945 < ACL data: handle 39 flags 0x00 dlen 10 L2CAP(s): Move cfm rsp: icid 0x4000 --- lib/l2cap.h | 50 +++++++++++++++++++++++++++++ parser/l2cap.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 0 deletions(-) diff --git a/lib/l2cap.h b/lib/l2cap.h index 3880551..b970a6e 100644 --- a/lib/l2cap.h +++ b/lib/l2cap.h @@ -82,6 +82,12 @@ struct l2cap_conninfo { #define L2CAP_ECHO_RSP 0x09 #define L2CAP_INFO_REQ 0x0a #define L2CAP_INFO_RSP 0x0b +#define L2CAP_CREATE_REQ 0x0c +#define L2CAP_CREATE_RSP 0x0d +#define L2CAP_MOVE_REQ 0x0e +#define L2CAP_MOVE_RSP 0x0f +#define L2CAP_MOVE_CFM 0x10 +#define L2CAP_MOVE_CFM_RSP 0x11 /* L2CAP extended feature mask */ #define L2CAP_FEAT_FLOWCTL 0x00000001 @@ -270,6 +276,50 @@ typedef struct { #define L2CAP_IR_SUCCESS 0x0000 #define L2CAP_IR_NOTSUPP 0x0001 +typedef struct { + uint16_t psm; + uint16_t scid; + uint8_t id; +} __attribute__ ((packed)) l2cap_create_req; +#define L2CAP_CREATE_REQ_SIZE 5 + +typedef struct { + uint16_t dcid; + uint16_t scid; + uint16_t result; + uint16_t status; +} __attribute__ ((packed)) l2cap_create_rsp; +#define L2CAP_CREATE_RSP_SIZE 8 + +typedef struct { + uint16_t icid; + uint8_t id; +} __attribute__ ((packed)) l2cap_move_req; +#define L2CAP_MOVE_REQ_SIZE 3 + +typedef struct { + uint16_t icid; + uint16_t result; +} __attribute__ ((packed)) l2cap_move_rsp; +#define L2CAP_MOVE_RSP_SIZE 4 + +typedef struct { + uint16_t icid; + uint16_t result; +} __attribute__ ((packed)) l2cap_move_cfm; +#define L2CAP_MOVE_CFM_SIZE 4 + +typedef struct { + uint16_t icid; +} __attribute__ ((packed)) l2cap_move_cfm_rsp; +#define L2CAP_MOVE_CFM_RSP_SIZE 2 + +/* info type */ +#define L2CAP_IT_CL_MTU 0x0001 +#define L2CAP_IT_FEAT_MASK 0x0002 + +/* info result */ +#define L2CAP_IR_SUCCESS 0x0000 #ifdef __cplusplus } #endif diff --git a/parser/l2cap.c b/parser/l2cap.c index 6a5a4b2..7547e8b 100644 --- a/parser/l2cap.c +++ b/parser/l2cap.c @@ -399,6 +399,7 @@ static char *supervisory2str(uint8_t supervisory) } } + static inline void command_rej(int level, struct frame *frm) { l2cap_cmd_rej *h = frm->ptr; @@ -850,6 +851,78 @@ static void l2cap_ctrl_parse(int level, struct frame *frm, uint32_t ctrl) printf(" F-bit"); } +static inline void create_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_create_req *h = frm->ptr; + uint16_t psm = btohs(h->psm); + uint16_t scid = btohs(h->scid); + + if (p_filter(FILT_L2CAP)) + return; + + printf("Create req: psm %d scid 0x%4.4x id %d\n", psm, scid, h->id); +} + +static inline void create_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_create_rsp *h = frm->ptr; + uint16_t scid = btohs(h->scid); + uint16_t dcid = btohs(h->dcid); + uint16_t result = btohs(h->result); + uint16_t status = btohs(h->status); + + if (p_filter(FILT_L2CAP)) + return; + + printf("Create rsp: dcid 0x%4.4x scid 0x%4.4x result %d status %d\n", dcid, scid, result, status); +} + +static inline void move_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_move_req *h = frm->ptr; + uint16_t icid = btohs(h->icid); + + if (p_filter(FILT_L2CAP)) + return; + + printf("Move req: icid 0x%4.4x id %d\n", icid, h->id); +} + +static inline void move_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_move_rsp *h = frm->ptr; + uint16_t icid = btohs(h->icid); + uint16_t result = btohs(h->result); + + if (p_filter(FILT_L2CAP)) + return; + + printf("Move rsp: icid 0x%4.4x result %d\n", icid, result); +} + +static inline void move_cfm(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_move_cfm *h = frm->ptr; + uint16_t icid = btohs(h->icid); + uint16_t result = btohs(h->result); + + if (p_filter(FILT_L2CAP)) + return; + + printf("Move cfm: icid 0x%4.4x result %d\n", icid, result); +} + +static inline void move_cfm_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm) +{ + l2cap_move_cfm_rsp *h = frm->ptr; + uint16_t icid = btohs(h->icid); + + if (p_filter(FILT_L2CAP)) + return; + + printf("Move cfm rsp: icid 0x%4.4x\n", icid); +} + static void l2cap_parse(int level, struct frame *frm) { l2cap_hdr *hdr = (void *)frm->ptr; @@ -919,6 +992,30 @@ static void l2cap_parse(int level, struct frame *frm) info_rsp(level, hdr, frm); break; + case L2CAP_CREATE_REQ: + create_req(level, hdr, frm); + break; + + case L2CAP_CREATE_RSP: + create_rsp(level, hdr, frm); + break; + + case L2CAP_MOVE_REQ: + move_req(level, hdr, frm); + break; + + case L2CAP_MOVE_RSP: + move_rsp(level, hdr, frm); + break; + + case L2CAP_MOVE_CFM: + move_cfm(level, hdr, frm); + break; + + case L2CAP_MOVE_CFM_RSP: + move_cfm_rsp(level, hdr, frm); + break; + default: if (p_filter(FILT_L2CAP)) break; -- 1.7.7 -- Peter Krystad Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] Add parsing of L2CAP Create/Move Channel signals 2011-10-21 23:29 ` [PATCH 1/4] Add parsing of L2CAP Create/Move Channel signals Peter Krystad @ 2011-10-22 7:21 ` Marcel Holtmann 0 siblings, 0 replies; 10+ messages in thread From: Marcel Holtmann @ 2011-10-22 7:21 UTC (permalink / raw) To: Peter Krystad; +Cc: linux-bluetooth, andrei.emeltchenko Hi Peter, > Add parsing of L2CAP Create/Move Channel signalling. > Example output: > > 2011-10-18 16:09:47.810208 > ACL data: handle 39 flags 0x02 dlen 13 > L2CAP(s): Create req: psm 4097 scid 0x4201 id 17 > 2011-10-18 16:09:47.810269 < ACL data: handle 39 flags 0x00 dlen 16 > L2CAP(s): Create rsp: dcid 0x0040 scid 0x4201 result 1 status 0 > 2011-10-18 16:09:47.898308 < ACL data: handle 39 flags 0x00 dlen 16 > L2CAP(s): Create rsp: dcid 0x0040 scid 0x4201 result 0 status 0 > > .... > > 2011-10-18 14:25:24.646869 > ACL data: handle 39 flags 0x02 dlen 11 > L2CAP(s): Move req: icid 0x4000 id 17 > 2011-10-18 14:25:24.646987 < ACL data: handle 39 flags 0x00 dlen 12 > L2CAP(s): Move rsp: icid 0x4000 result 1 > 2011-10-18 14:25:24.846873 < ACL data: handle 39 flags 0x00 dlen 12 > L2CAP(s): Move rsp: icid 0x4000 result 0 > 2011-10-18 14:25:25.041844 > ACL data: handle 39 flags 0x02 dlen 12 > L2CAP(s): Move cfm: icid 0x4000 result 0 > 2011-10-18 14:25:25.041945 < ACL data: handle 39 flags 0x00 dlen 10 > L2CAP(s): Move cfm rsp: icid 0x4000 > --- > lib/l2cap.h | 50 +++++++++++++++++++++++++++++ > parser/l2cap.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 147 insertions(+), 0 deletions(-) same requirement as with Andrei's patches before. First get them accepted into bluez.git and then we port them over here. Regards Marcel ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/4] Add parsing of A2MP signals 2011-10-21 23:29 [PATCH 0/4] Add parsing of BT 3.0+HS signalling Peter Krystad 2011-10-21 23:29 ` [PATCH 1/4] Add parsing of L2CAP Create/Move Channel signals Peter Krystad @ 2011-10-21 23:30 ` Peter Krystad 2011-10-24 7:34 ` Andrei Emeltchenko 2011-10-26 13:33 ` Andrei Emeltchenko 2011-10-21 23:30 ` [PATCH 3/4] Add parsing of L2CAP Fixed Channel list Peter Krystad 2011-10-21 23:30 ` [PATCH 4/4] Minor cleanup of indentation in output Peter Krystad 3 siblings, 2 replies; 10+ messages in thread From: Peter Krystad @ 2011-10-21 23:30 UTC (permalink / raw) To: linux-bluetooth; +Cc: andrei.emeltchenko, Peter Krystad Add parsing of A2MP signalling. Example output: 2011-10-18 16:09:44.493202 > ACL data: handle 39 flags 0x02 dlen 16 A2MP: Discover req: mtu/mps 670 mask: 0x0000 2011-10-18 16:09:44.493404 < ACL data: handle 39 flags 0x00 dlen 22 A2MP: Discover rsp: mtu/mps 670 mask: 0x0000 Controller list: id 0, type 0, status 0x01 (Bluetooth only) id 17, type 254, status 0x06 (Full capacity) 2011-10-18 16:09:44.697203 > ACL data: handle 39 flags 0x02 dlen 13 A2MP: Get Info req: id 17 2011-10-18 16:09:44.697312 < ACL data: handle 39 flags 0x00 dlen 30 A2MP: Get Info rsp: id 17 status (0) Success total bandwidth 500000 max guaranteed bandwidth 0 min latency 100000 pal capabilities 0x0000 assoc size 8 2011-10-18 16:09:44.893203 > ACL data: handle 39 flags 0x02 dlen 13 A2MP: Get AMP Assoc req: id 17 2011-10-18 16:09:44.893618 < ACL data: handle 39 flags 0x00 dlen 22 A2MP: Get AMP Assoc rsp: id 17 status (0) Success assoc data: 08 01 b1 01 0a 04 6c 42 2011-10-18 16:09:45.598201 > ACL data: handle 39 flags 0x02 dlen 22 A2MP: Create Physical Link req: local id 1 remote id 17 assoc data: 08 01 b1 01 0a 04 6d 38 2011-10-18 16:09:45.598643 < ACL data: handle 39 flags 0x00 dlen 15 A2MP: Create Physical Link rsp: local id 17 remote id 1 status 0 Success --- lib/amp.h | 133 +++++++++++++++++++ parser/l2cap.c | 385 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ parser/parser.h | 1 + src/hcidump.c | 1 + 4 files changed, 520 insertions(+), 0 deletions(-) create mode 100644 lib/amp.h diff --git a/lib/amp.h b/lib/amp.h new file mode 100644 index 0000000..0c6300a --- /dev/null +++ b/lib/amp.h @@ -0,0 +1,133 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2010-2011 Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __AMP_H +#define __AMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define AMP_MGR_CID 0x03 + +/* AMP manager codes */ +#define AMP_COMMAND_REJ 0x01 +#define AMP_DISCOVER_REQ 0x02 +#define AMP_DISCOVER_RSP 0x03 +#define AMP_CHANGE_NOTIFY 0x04 +#define AMP_CHANGE_RSP 0x05 +#define AMP_INFO_REQ 0x06 +#define AMP_INFO_RSP 0x07 +#define AMP_ASSOC_REQ 0x08 +#define AMP_ASSOC_RSP 0x09 +#define AMP_LINK_REQ 0x0a +#define AMP_LINK_RSP 0x0b +#define AMP_DISCONN_REQ 0x0c +#define AMP_DISCONN_RSP 0x0d + +typedef struct { + uint8_t code; + uint8_t ident; + uint16_t len; +} __attribute__ ((packed)) amp_mgr_hdr; +#define AMP_MGR_HDR_SIZE 4 + +/* AMP ASSOC structure */ +typedef struct { + uint8_t type_id; + uint16_t len; + uint8_t data[0]; +} __attribute__ ((packed)) amp_assoc_tlv; + +typedef struct { + uint16_t reason; +} __attribute__ ((packed)) amp_cmd_rej_parms; + +typedef struct { + uint16_t mtu; + uint16_t mask; +} __attribute__ ((packed)) amp_discover_req_parms; + +typedef struct { + uint16_t mtu; + uint16_t mask; + uint8_t controller_list[0]; +} __attribute__ ((packed)) amp_discover_rsp_parms; + +typedef struct { + uint8_t id; +} __attribute__ ((packed)) amp_info_req_parms; + +typedef struct { + uint8_t id; + uint8_t status; + uint32_t total_bandwidth; + uint32_t max_bandwidth; + uint32_t min_latency; + uint16_t pal_caps; + uint16_t assoc_size; +} __attribute__ ((packed)) amp_info_rsp_parms; + +typedef struct { + uint8_t id; + uint8_t status; + amp_assoc_tlv assoc; +} __attribute__ ((packed)) amp_assoc_rsp_parms; + +typedef struct { + uint8_t local_id; + uint8_t remote_id; + amp_assoc_tlv assoc; +} __attribute__ ((packed)) amp_link_req_parms; + +typedef struct { + uint8_t local_id; + uint8_t remote_id; + uint8_t status; +} __attribute__ ((packed)) amp_link_rsp_parms; + +typedef struct { + uint8_t local_id; + uint8_t remote_id; +} __attribute__ ((packed)) amp_disconn_req_parms; + +#define AMP_COMMAND_NOT_RECOGNIZED 0x0000 + +/* AMP controller status */ +#define AMP_CT_POWERED_DOWN 0x00 +#define AMP_CT_BLUETOOTH_ONLY 0x01 +#define AMP_CT_NO_CAPACITY 0x02 +#define AMP_CT_LOW_CAPACITY 0x03 +#define AMP_CT_MEDIUM_CAPACITY 0x04 +#define AMP_CT_HIGH_CAPACITY 0x05 +#define AMP_CT_FULL_CAPACITY 0x06 + +/* AMP response status */ +#define AMP_STATUS_SUCCESS 0x00 +#define AMP_STATUS_INVALID_CTRL_ID 0x01 +#define AMP_STATUS_UNABLE_START_LINK_CREATION 0x02 +#define AMP_STATUS_NO_PHYSICAL_LINK_EXISTS 0x02 +#define AMP_STATUS_COLLISION_OCCURED 0x03 +#define AMP_STATUS_DISCONN_REQ_RECVD 0x04 +#define AMP_STATUS_PHYS_LINK_EXISTS 0x05 +#define AMP_STATUS_SECURITY_VIOLATION 0x06 + +#ifdef __cplusplus +} +#endif + +#endif /* __AMP_H */ diff --git a/parser/l2cap.c b/parser/l2cap.c index 7547e8b..7915788 100644 --- a/parser/l2cap.c +++ b/parser/l2cap.c @@ -36,6 +36,7 @@ #include "parser/sdp.h" #include "lib/hci.h" #include "lib/l2cap.h" +#include "lib/amp.h" typedef struct { uint16_t handle; @@ -259,6 +260,16 @@ static char *reason2str(uint16_t reason) } } +static char *ampreason2str(uint16_t reason) +{ + switch (reason) { + case AMP_COMMAND_NOT_RECOGNIZED: + return "Command not recognized"; + default: + return "Reserved"; + } +} + static char *connresult2str(uint16_t result) { switch (result) { @@ -399,6 +410,76 @@ static char *supervisory2str(uint8_t supervisory) } } +static char *ampctstatus2str(uint8_t status) +{ + switch (status) { + case AMP_CT_POWERED_DOWN: + return "Powered down"; + case AMP_CT_BLUETOOTH_ONLY: + return "Bluetooth only"; + case AMP_CT_NO_CAPACITY: + return "No capacity"; + case AMP_CT_LOW_CAPACITY: + return "Low capacity"; + case AMP_CT_MEDIUM_CAPACITY: + return "Medium capacity"; + case AMP_CT_HIGH_CAPACITY: + return "High capacity"; + case AMP_CT_FULL_CAPACITY: + return "Full capacity"; + default: + return "Reserved"; + + } +} + +static char *ampstatus2str(uint8_t status) +{ + switch (status) { + case AMP_STATUS_SUCCESS: + return "Success"; + case AMP_STATUS_INVALID_CTRL_ID: + return "Invalid Controller ID"; + default: + return "Reserved"; + } +} + +static char *ampcplstatus2str(uint8_t status) +{ + switch (status) { + case AMP_STATUS_SUCCESS: + return "Success"; + case AMP_STATUS_INVALID_CTRL_ID: + return "Invalid Controller ID"; + case AMP_STATUS_UNABLE_START_LINK_CREATION: + return "Failed - Unable to start link creation"; + case AMP_STATUS_COLLISION_OCCURED: + return "Failed - Collision occured"; + case AMP_STATUS_DISCONN_REQ_RECVD: + return "Failed - Disconnect physical link received"; + case AMP_STATUS_PHYS_LINK_EXISTS: + return "Failed - Physical link already exists"; + case AMP_STATUS_SECURITY_VIOLATION: + return "Failed - Security violation"; + default: + return "Reserved"; + } +} + +static char *ampdplstatus2str(uint8_t status) +{ + switch (status) { + case AMP_STATUS_SUCCESS: + return "Success"; + case AMP_STATUS_INVALID_CTRL_ID: + return "Invalid Controller ID"; + case AMP_STATUS_NO_PHYSICAL_LINK_EXISTS: + return "Failed - No Physical Link exists"; + default: + return "Reserved"; + } +} static inline void command_rej(int level, struct frame *frm) { @@ -923,6 +1004,240 @@ static inline void move_cfm_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm printf("Move cfm rsp: icid 0x%4.4x\n", icid); } +static inline void amp_command_rej(int level, struct frame *frm) +{ + amp_cmd_rej_parms *h = frm->ptr; + uint16_t reason = btohs(h->reason); + + if (p_filter(FILT_A2MP)) + return; + + printf("Command Reject: reason (%d)- ", reason); + p_indent(level + 1, frm); + printf("%s\n", ampreason2str(reason)); +} + +static inline void amp_discover_req(int level, struct frame *frm, uint16_t len) +{ + amp_discover_req_parms *h = frm->ptr; + uint16_t mtu = btohs(h->mtu); + uint8_t *octet = (uint8_t *)&(h->mask); + uint16_t mask; + uint8_t extension; + + if (p_filter(FILT_A2MP)) + return; + + printf("Discover req: mtu/mps %d ", mtu); + len -= 2; + + printf("mask:"); + + do { + len -= 2; + mask = btohs(*(uint16_t *)(&octet[0])); + printf(" 0x%4.4x", mask); + + extension = octet[1] & 0x80; + octet += 2; + } while ((extension != 0) && (len >= 2)); + + printf("\n"); +} + +static inline void controller_list_dump (int level, uint8_t *octet, uint16_t len) +{ + if (p_filter(FILT_A2MP)) + return; + + p_indent(level, 0); + printf("Controller list:\n"); + + while (len >= 3) { + p_indent(level + 1, 0); + printf("id %d, type %d, status 0x%2.2x (%s)\n", + octet[0], octet[1], octet[2], ampctstatus2str(octet[2])); + octet += 3; + len -= 3; + } + +} + +static inline void amp_discover_rsp(int level, struct frame *frm, uint16_t len) +{ + amp_discover_rsp_parms *h = frm->ptr; + uint16_t mtu = btohs(h->mtu); + uint8_t *octet = (uint8_t *)&(h->mask); + uint16_t mask; + uint8_t extension; + + if (p_filter(FILT_A2MP)) + return; + + printf("Discover rsp: mtu/mps %d ", mtu); + len -= 2; + + printf("mask:"); + + do { + len -= 2; + mask = btohs(*(uint16_t *)(&octet[0])); + printf(" 0x%4.4x", mask); + + extension = octet[1] & 0x80; + octet += 2; + } while ((extension != 0) && (len >= 2)); + + printf("\n"); + + if (len >= 3) { + controller_list_dump (level + 1, octet, len); + } +} + +static inline void amp_change_notify(int level, struct frame *frm, uint16_t len) +{ + uint8_t *octet = frm->ptr; + + if (p_filter(FILT_A2MP)) + return; + + printf("Change Notify\n"); + + if (len >= 3) { + controller_list_dump (level + 1, octet, len); + } +} + +static inline void amp_change_rsp(int level, struct frame *frm) +{ + if (p_filter(FILT_A2MP)) + return; + + printf("Change Response\n"); +} + +static inline void amp_info_req(int level, struct frame *frm) +{ + amp_info_req_parms *h = frm->ptr; + + if (p_filter(FILT_A2MP)) + return; + + printf("Get Info req: id %d\n", h->id); +} + +static inline void amp_info_rsp(int level, struct frame *frm) +{ + amp_info_rsp_parms *h = frm->ptr; + + if (p_filter(FILT_A2MP)) + return; + + printf("Get Info rsp: id %d status (%d) %s\n", + h->id, h->status, ampstatus2str(h->status)); + + p_indent(level + 1, frm); + printf("total bandwidth %d\n", btohl(h->total_bandwidth)); + p_indent(level + 1, frm); + printf("max guaranteed bandwidth %d\n", btohl(h->max_bandwidth)); + p_indent(level + 1, frm); + printf("min latency %d\n", btohl(h->min_latency)); + p_indent(level + 1, frm); + printf("pal capabilities 0x%4.4x\n", btohs(h->pal_caps)); + p_indent(level + 1, frm); + printf("assoc size %d\n", btohs(h->assoc_size)); +} + +static inline void amp_assoc_req(int level, struct frame *frm) +{ + amp_info_req_parms *h = frm->ptr; + + if (p_filter(FILT_A2MP)) + return; + + printf("Get AMP Assoc req: id %d\n", h->id); +} + +static inline void amp_assoc_dump(int level, uint8_t *assoc, uint16_t len) +{ + int i; + + if (p_filter(FILT_A2MP)) + return; + + p_indent(level, 0); + printf("assoc data:"); + for (i = 0; i < len; i++) { + if (!(i%16)) printf("\n"); + if (!(i%16)) p_indent(level+1, 0); + printf("%2.2x ",*assoc++); + } + printf("\n"); + +} + +static inline void amp_assoc_rsp(int level, struct frame *frm, uint16_t len) +{ + amp_assoc_rsp_parms *h = frm->ptr; + + if (p_filter(FILT_A2MP)) + return; + + printf("Get AMP Assoc rsp: id %d status (%d) %s \n", + h->id, h->status, ampstatus2str(h->status)); + amp_assoc_dump(level + 1, (uint8_t *) &h->assoc, len - 2); +} + +static inline void amp_link_req(int level, struct frame *frm, uint16_t len) +{ + amp_link_req_parms *h = frm->ptr; + + if (p_filter(FILT_A2MP)) + return; + + printf("Create Physical Link req: local id %d remote id %d\n", + h->local_id, h->remote_id); + amp_assoc_dump(level + 1, (uint8_t *) &h->assoc, len - 2); +} + +static inline void amp_link_rsp(int level, struct frame *frm) +{ + amp_link_rsp_parms *h = frm->ptr; + + if (p_filter(FILT_A2MP)) + return; + + printf("Create Physical Link rsp: local id %d remote id %d status %d\n", + h->local_id, h->remote_id, h->status); + p_indent(level+1, 0); + printf("%s\n", ampcplstatus2str(h->status)); +} + +static inline void amp_disconn_req(int level, struct frame *frm) +{ + amp_disconn_req_parms *h = frm->ptr; + + if (p_filter(FILT_A2MP)) + return; + + printf("Disconnect Physical Link req: local id %d remote id %d\n", + h->local_id, h->remote_id); +} + +static inline void amp_disconn_rsp(int level, struct frame *frm) +{ + amp_link_rsp_parms *h = frm->ptr; + + if (p_filter(FILT_A2MP)) + return; + + printf("Disconnect Physical Link rsp: local id %d remote id %d status %d\n", + h->local_id, h->remote_id, h->status); + p_indent(level+1, 0); + printf("%s\n", ampdplstatus2str(h->status)); +} + static void l2cap_parse(int level, struct frame *frm) { l2cap_hdr *hdr = (void *)frm->ptr; @@ -1043,6 +1358,76 @@ static void l2cap_parse(int level, struct frame *frm) p_indent(level, frm); printf("L2CAP(c): len %d psm %d\n", dlen, psm); raw_dump(level, frm); + } else if ((cid == 0x3) && (frm->len > 4)) { + + /* Adjust for extra ERTM control bytes */ + frm->ptr += 2; + frm->len -= 2; + + while (frm->len >= AMP_MGR_HDR_SIZE) { + amp_mgr_hdr *hdr = frm->ptr; + + frm->ptr += AMP_MGR_HDR_SIZE; + frm->len -= AMP_MGR_HDR_SIZE; + + if (!p_filter(FILT_A2MP)) { + p_indent(level, frm); + printf("A2MP: "); + } + switch (hdr->code) { + case AMP_COMMAND_REJ: + amp_command_rej(level, frm); + break; + case AMP_DISCOVER_REQ: + amp_discover_req(level, frm, hdr->len); + break; + case AMP_DISCOVER_RSP: + amp_discover_rsp(level, frm, hdr->len); + break; + case AMP_CHANGE_NOTIFY: + amp_change_notify(level, frm, hdr->len); + break; + case AMP_CHANGE_RSP: + amp_change_rsp(level, frm); + break; + case AMP_INFO_REQ: + amp_info_req(level, frm); + break; + case AMP_INFO_RSP: + amp_info_rsp(level, frm); + break; + case AMP_ASSOC_REQ: + amp_assoc_req(level, frm); + break; + case AMP_ASSOC_RSP: + amp_assoc_rsp(level, frm, hdr->len); + break; + case AMP_LINK_REQ: + amp_link_req(level, frm, hdr->len); + break; + case AMP_LINK_RSP: + amp_link_rsp(level, frm); + break; + case AMP_DISCONN_REQ: + amp_disconn_req(level, frm); + break; + case AMP_DISCONN_RSP: + amp_disconn_rsp(level, frm); + break; + default: + if (p_filter(FILT_A2MP)) + break; + printf("code 0x%2.2x ident %d len %d\n", + hdr->code, hdr->ident, btohs(hdr->len)); + raw_dump(level, frm); + } + + if (frm->len > btohs(hdr->len)) { + frm->len -= btohs(hdr->len); + frm->ptr += btohs(hdr->len); + } else + frm->len = 0; + } } else if (cid == 0x04) { if (!p_filter(FILT_ATT)) att_dump(level, frm); diff --git a/parser/parser.h b/parser/parser.h index e975808..22d18c3 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -80,6 +80,7 @@ struct frame { #define FILT_AVCTP 0x0800 #define FILT_ATT 0x1000 #define FILT_SMP 0x2000 +#define FILT_A2MP 0x4000 #define FILT_OBEX 0x00010000 #define FILT_CAPI 0x00020000 diff --git a/src/hcidump.c b/src/hcidump.c index 0c13360..2513c7c 100644 --- a/src/hcidump.c +++ b/src/hcidump.c @@ -802,6 +802,7 @@ static struct { { "hci", FILT_HCI }, { "sco", FILT_SCO }, { "l2cap", FILT_L2CAP }, + { "a2mp", FILT_A2MP }, { "rfcomm", FILT_RFCOMM }, { "sdp", FILT_SDP }, { "bnep", FILT_BNEP }, -- 1.7.7 -- Peter Krystad Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/4] Add parsing of A2MP signals 2011-10-21 23:30 ` [PATCH 2/4] Add parsing of A2MP signals Peter Krystad @ 2011-10-24 7:34 ` Andrei Emeltchenko 2011-10-26 13:33 ` Andrei Emeltchenko 1 sibling, 0 replies; 10+ messages in thread From: Andrei Emeltchenko @ 2011-10-24 7:34 UTC (permalink / raw) To: Peter Krystad; +Cc: linux-bluetooth Hi Peter, On Fri, Oct 21, 2011 at 04:30:00PM -0700, Peter Krystad wrote: > Add parsing of A2MP signalling. > Example output: > > 2011-10-18 16:09:44.493202 > ACL data: handle 39 flags 0x02 dlen 16 > A2MP: Discover req: mtu/mps 670 mask: 0x0000 > 2011-10-18 16:09:44.493404 < ACL data: handle 39 flags 0x00 dlen 22 > A2MP: Discover rsp: mtu/mps 670 mask: 0x0000 > Controller list: > id 0, type 0, status 0x01 (Bluetooth only) > id 17, type 254, status 0x06 (Full capacity) > 2011-10-18 16:09:44.697203 > ACL data: handle 39 flags 0x02 dlen 13 > A2MP: Get Info req: id 17 > 2011-10-18 16:09:44.697312 < ACL data: handle 39 flags 0x00 dlen 30 > A2MP: Get Info rsp: id 17 status (0) Success > total bandwidth 500000 > max guaranteed bandwidth 0 > min latency 100000 > pal capabilities 0x0000 > assoc size 8 > 2011-10-18 16:09:44.893203 > ACL data: handle 39 flags 0x02 dlen 13 > A2MP: Get AMP Assoc req: id 17 > 2011-10-18 16:09:44.893618 < ACL data: handle 39 flags 0x00 dlen 22 > A2MP: Get AMP Assoc rsp: id 17 status (0) Success > assoc data: > 08 01 b1 01 0a 04 6c 42 > 2011-10-18 16:09:45.598201 > ACL data: handle 39 flags 0x02 dlen 22 > A2MP: Create Physical Link req: local id 1 remote id 17 > assoc data: > 08 01 b1 01 0a 04 6d 38 > 2011-10-18 16:09:45.598643 < ACL data: handle 39 flags 0x00 dlen 15 > A2MP: Create Physical Link rsp: local id 17 remote id 1 status 0 > Success > --- > lib/amp.h | 133 +++++++++++++++++++ > parser/l2cap.c | 385 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > parser/parser.h | 1 + > src/hcidump.c | 1 + > 4 files changed, 520 insertions(+), 0 deletions(-) > create mode 100644 lib/amp.h > > diff --git a/lib/amp.h b/lib/amp.h Minor comments. Would it be better to name it a2mp.h and functions below a2mp_*? Otherwise as Marcel mentioned header patches shall be applied first to bluez. Best regards Andrei Emeltchenko > new file mode 100644 > index 0000000..0c6300a > --- /dev/null > +++ b/lib/amp.h > @@ -0,0 +1,133 @@ > +/* > + * > + * BlueZ - Bluetooth protocol stack for Linux > + * > + * Copyright (C) 2010-2011 Code Aurora Forum. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 and > + * only version 2 as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + */ > + > +#ifndef __AMP_H > +#define __AMP_H > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#define AMP_MGR_CID 0x03 > + > +/* AMP manager codes */ > +#define AMP_COMMAND_REJ 0x01 > +#define AMP_DISCOVER_REQ 0x02 > +#define AMP_DISCOVER_RSP 0x03 > +#define AMP_CHANGE_NOTIFY 0x04 > +#define AMP_CHANGE_RSP 0x05 > +#define AMP_INFO_REQ 0x06 > +#define AMP_INFO_RSP 0x07 > +#define AMP_ASSOC_REQ 0x08 > +#define AMP_ASSOC_RSP 0x09 > +#define AMP_LINK_REQ 0x0a > +#define AMP_LINK_RSP 0x0b > +#define AMP_DISCONN_REQ 0x0c > +#define AMP_DISCONN_RSP 0x0d > + > +typedef struct { > + uint8_t code; > + uint8_t ident; > + uint16_t len; > +} __attribute__ ((packed)) amp_mgr_hdr; > +#define AMP_MGR_HDR_SIZE 4 > + > +/* AMP ASSOC structure */ > +typedef struct { > + uint8_t type_id; > + uint16_t len; > + uint8_t data[0]; > +} __attribute__ ((packed)) amp_assoc_tlv; > + > +typedef struct { > + uint16_t reason; > +} __attribute__ ((packed)) amp_cmd_rej_parms; > + > +typedef struct { > + uint16_t mtu; > + uint16_t mask; > +} __attribute__ ((packed)) amp_discover_req_parms; > + > +typedef struct { > + uint16_t mtu; > + uint16_t mask; > + uint8_t controller_list[0]; > +} __attribute__ ((packed)) amp_discover_rsp_parms; > + > +typedef struct { > + uint8_t id; > +} __attribute__ ((packed)) amp_info_req_parms; > + > +typedef struct { > + uint8_t id; > + uint8_t status; > + uint32_t total_bandwidth; > + uint32_t max_bandwidth; > + uint32_t min_latency; > + uint16_t pal_caps; > + uint16_t assoc_size; > +} __attribute__ ((packed)) amp_info_rsp_parms; > + > +typedef struct { > + uint8_t id; > + uint8_t status; > + amp_assoc_tlv assoc; > +} __attribute__ ((packed)) amp_assoc_rsp_parms; > + > +typedef struct { > + uint8_t local_id; > + uint8_t remote_id; > + amp_assoc_tlv assoc; > +} __attribute__ ((packed)) amp_link_req_parms; > + > +typedef struct { > + uint8_t local_id; > + uint8_t remote_id; > + uint8_t status; > +} __attribute__ ((packed)) amp_link_rsp_parms; > + > +typedef struct { > + uint8_t local_id; > + uint8_t remote_id; > +} __attribute__ ((packed)) amp_disconn_req_parms; > + > +#define AMP_COMMAND_NOT_RECOGNIZED 0x0000 > + > +/* AMP controller status */ > +#define AMP_CT_POWERED_DOWN 0x00 > +#define AMP_CT_BLUETOOTH_ONLY 0x01 > +#define AMP_CT_NO_CAPACITY 0x02 > +#define AMP_CT_LOW_CAPACITY 0x03 > +#define AMP_CT_MEDIUM_CAPACITY 0x04 > +#define AMP_CT_HIGH_CAPACITY 0x05 > +#define AMP_CT_FULL_CAPACITY 0x06 > + > +/* AMP response status */ > +#define AMP_STATUS_SUCCESS 0x00 > +#define AMP_STATUS_INVALID_CTRL_ID 0x01 > +#define AMP_STATUS_UNABLE_START_LINK_CREATION 0x02 > +#define AMP_STATUS_NO_PHYSICAL_LINK_EXISTS 0x02 > +#define AMP_STATUS_COLLISION_OCCURED 0x03 > +#define AMP_STATUS_DISCONN_REQ_RECVD 0x04 > +#define AMP_STATUS_PHYS_LINK_EXISTS 0x05 > +#define AMP_STATUS_SECURITY_VIOLATION 0x06 > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* __AMP_H */ > diff --git a/parser/l2cap.c b/parser/l2cap.c > index 7547e8b..7915788 100644 > --- a/parser/l2cap.c > +++ b/parser/l2cap.c > @@ -36,6 +36,7 @@ > #include "parser/sdp.h" > #include "lib/hci.h" > #include "lib/l2cap.h" > +#include "lib/amp.h" > > typedef struct { > uint16_t handle; > @@ -259,6 +260,16 @@ static char *reason2str(uint16_t reason) > } > } > > +static char *ampreason2str(uint16_t reason) > +{ > + switch (reason) { > + case AMP_COMMAND_NOT_RECOGNIZED: > + return "Command not recognized"; > + default: > + return "Reserved"; > + } > +} > + > static char *connresult2str(uint16_t result) > { > switch (result) { > @@ -399,6 +410,76 @@ static char *supervisory2str(uint8_t supervisory) > } > } > > +static char *ampctstatus2str(uint8_t status) > +{ > + switch (status) { > + case AMP_CT_POWERED_DOWN: > + return "Powered down"; > + case AMP_CT_BLUETOOTH_ONLY: > + return "Bluetooth only"; > + case AMP_CT_NO_CAPACITY: > + return "No capacity"; > + case AMP_CT_LOW_CAPACITY: > + return "Low capacity"; > + case AMP_CT_MEDIUM_CAPACITY: > + return "Medium capacity"; > + case AMP_CT_HIGH_CAPACITY: > + return "High capacity"; > + case AMP_CT_FULL_CAPACITY: > + return "Full capacity"; > + default: > + return "Reserved"; > + > + } > +} > + > +static char *ampstatus2str(uint8_t status) > +{ > + switch (status) { > + case AMP_STATUS_SUCCESS: > + return "Success"; > + case AMP_STATUS_INVALID_CTRL_ID: > + return "Invalid Controller ID"; > + default: > + return "Reserved"; > + } > +} > + > +static char *ampcplstatus2str(uint8_t status) > +{ > + switch (status) { > + case AMP_STATUS_SUCCESS: > + return "Success"; > + case AMP_STATUS_INVALID_CTRL_ID: > + return "Invalid Controller ID"; > + case AMP_STATUS_UNABLE_START_LINK_CREATION: > + return "Failed - Unable to start link creation"; > + case AMP_STATUS_COLLISION_OCCURED: > + return "Failed - Collision occured"; > + case AMP_STATUS_DISCONN_REQ_RECVD: > + return "Failed - Disconnect physical link received"; > + case AMP_STATUS_PHYS_LINK_EXISTS: > + return "Failed - Physical link already exists"; > + case AMP_STATUS_SECURITY_VIOLATION: > + return "Failed - Security violation"; > + default: > + return "Reserved"; > + } > +} > + > +static char *ampdplstatus2str(uint8_t status) > +{ > + switch (status) { > + case AMP_STATUS_SUCCESS: > + return "Success"; > + case AMP_STATUS_INVALID_CTRL_ID: > + return "Invalid Controller ID"; > + case AMP_STATUS_NO_PHYSICAL_LINK_EXISTS: > + return "Failed - No Physical Link exists"; > + default: > + return "Reserved"; > + } > +} > > static inline void command_rej(int level, struct frame *frm) > { > @@ -923,6 +1004,240 @@ static inline void move_cfm_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm > printf("Move cfm rsp: icid 0x%4.4x\n", icid); > } > > +static inline void amp_command_rej(int level, struct frame *frm) > +{ > + amp_cmd_rej_parms *h = frm->ptr; > + uint16_t reason = btohs(h->reason); > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Command Reject: reason (%d)- ", reason); > + p_indent(level + 1, frm); > + printf("%s\n", ampreason2str(reason)); > +} > + > +static inline void amp_discover_req(int level, struct frame *frm, uint16_t len) > +{ > + amp_discover_req_parms *h = frm->ptr; > + uint16_t mtu = btohs(h->mtu); > + uint8_t *octet = (uint8_t *)&(h->mask); > + uint16_t mask; > + uint8_t extension; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Discover req: mtu/mps %d ", mtu); > + len -= 2; > + > + printf("mask:"); > + > + do { > + len -= 2; > + mask = btohs(*(uint16_t *)(&octet[0])); > + printf(" 0x%4.4x", mask); > + > + extension = octet[1] & 0x80; > + octet += 2; > + } while ((extension != 0) && (len >= 2)); > + > + printf("\n"); > +} > + > +static inline void controller_list_dump (int level, uint8_t *octet, uint16_t len) > +{ > + if (p_filter(FILT_A2MP)) > + return; > + > + p_indent(level, 0); > + printf("Controller list:\n"); > + > + while (len >= 3) { > + p_indent(level + 1, 0); > + printf("id %d, type %d, status 0x%2.2x (%s)\n", > + octet[0], octet[1], octet[2], ampctstatus2str(octet[2])); > + octet += 3; > + len -= 3; > + } > + > +} > + > +static inline void amp_discover_rsp(int level, struct frame *frm, uint16_t len) > +{ > + amp_discover_rsp_parms *h = frm->ptr; > + uint16_t mtu = btohs(h->mtu); > + uint8_t *octet = (uint8_t *)&(h->mask); > + uint16_t mask; > + uint8_t extension; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Discover rsp: mtu/mps %d ", mtu); > + len -= 2; > + > + printf("mask:"); > + > + do { > + len -= 2; > + mask = btohs(*(uint16_t *)(&octet[0])); > + printf(" 0x%4.4x", mask); > + > + extension = octet[1] & 0x80; > + octet += 2; > + } while ((extension != 0) && (len >= 2)); > + > + printf("\n"); > + > + if (len >= 3) { > + controller_list_dump (level + 1, octet, len); > + } > +} > + > +static inline void amp_change_notify(int level, struct frame *frm, uint16_t len) > +{ > + uint8_t *octet = frm->ptr; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Change Notify\n"); > + > + if (len >= 3) { > + controller_list_dump (level + 1, octet, len); > + } > +} > + > +static inline void amp_change_rsp(int level, struct frame *frm) > +{ > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Change Response\n"); > +} > + > +static inline void amp_info_req(int level, struct frame *frm) > +{ > + amp_info_req_parms *h = frm->ptr; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Get Info req: id %d\n", h->id); > +} > + > +static inline void amp_info_rsp(int level, struct frame *frm) > +{ > + amp_info_rsp_parms *h = frm->ptr; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Get Info rsp: id %d status (%d) %s\n", > + h->id, h->status, ampstatus2str(h->status)); > + > + p_indent(level + 1, frm); > + printf("total bandwidth %d\n", btohl(h->total_bandwidth)); > + p_indent(level + 1, frm); > + printf("max guaranteed bandwidth %d\n", btohl(h->max_bandwidth)); > + p_indent(level + 1, frm); > + printf("min latency %d\n", btohl(h->min_latency)); > + p_indent(level + 1, frm); > + printf("pal capabilities 0x%4.4x\n", btohs(h->pal_caps)); > + p_indent(level + 1, frm); > + printf("assoc size %d\n", btohs(h->assoc_size)); > +} > + > +static inline void amp_assoc_req(int level, struct frame *frm) > +{ > + amp_info_req_parms *h = frm->ptr; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Get AMP Assoc req: id %d\n", h->id); > +} > + > +static inline void amp_assoc_dump(int level, uint8_t *assoc, uint16_t len) > +{ > + int i; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + p_indent(level, 0); > + printf("assoc data:"); > + for (i = 0; i < len; i++) { > + if (!(i%16)) printf("\n"); > + if (!(i%16)) p_indent(level+1, 0); > + printf("%2.2x ",*assoc++); > + } > + printf("\n"); > + > +} > + > +static inline void amp_assoc_rsp(int level, struct frame *frm, uint16_t len) > +{ > + amp_assoc_rsp_parms *h = frm->ptr; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Get AMP Assoc rsp: id %d status (%d) %s \n", > + h->id, h->status, ampstatus2str(h->status)); > + amp_assoc_dump(level + 1, (uint8_t *) &h->assoc, len - 2); > +} > + > +static inline void amp_link_req(int level, struct frame *frm, uint16_t len) > +{ > + amp_link_req_parms *h = frm->ptr; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Create Physical Link req: local id %d remote id %d\n", > + h->local_id, h->remote_id); > + amp_assoc_dump(level + 1, (uint8_t *) &h->assoc, len - 2); > +} > + > +static inline void amp_link_rsp(int level, struct frame *frm) > +{ > + amp_link_rsp_parms *h = frm->ptr; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Create Physical Link rsp: local id %d remote id %d status %d\n", > + h->local_id, h->remote_id, h->status); > + p_indent(level+1, 0); > + printf("%s\n", ampcplstatus2str(h->status)); > +} > + > +static inline void amp_disconn_req(int level, struct frame *frm) > +{ > + amp_disconn_req_parms *h = frm->ptr; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Disconnect Physical Link req: local id %d remote id %d\n", > + h->local_id, h->remote_id); > +} > + > +static inline void amp_disconn_rsp(int level, struct frame *frm) > +{ > + amp_link_rsp_parms *h = frm->ptr; > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Disconnect Physical Link rsp: local id %d remote id %d status %d\n", > + h->local_id, h->remote_id, h->status); > + p_indent(level+1, 0); > + printf("%s\n", ampdplstatus2str(h->status)); > +} > + > static void l2cap_parse(int level, struct frame *frm) > { > l2cap_hdr *hdr = (void *)frm->ptr; > @@ -1043,6 +1358,76 @@ static void l2cap_parse(int level, struct frame *frm) > p_indent(level, frm); > printf("L2CAP(c): len %d psm %d\n", dlen, psm); > raw_dump(level, frm); > + } else if ((cid == 0x3) && (frm->len > 4)) { > + > + /* Adjust for extra ERTM control bytes */ > + frm->ptr += 2; > + frm->len -= 2; > + > + while (frm->len >= AMP_MGR_HDR_SIZE) { > + amp_mgr_hdr *hdr = frm->ptr; > + > + frm->ptr += AMP_MGR_HDR_SIZE; > + frm->len -= AMP_MGR_HDR_SIZE; > + > + if (!p_filter(FILT_A2MP)) { > + p_indent(level, frm); > + printf("A2MP: "); > + } > + switch (hdr->code) { > + case AMP_COMMAND_REJ: > + amp_command_rej(level, frm); > + break; > + case AMP_DISCOVER_REQ: > + amp_discover_req(level, frm, hdr->len); > + break; > + case AMP_DISCOVER_RSP: > + amp_discover_rsp(level, frm, hdr->len); > + break; > + case AMP_CHANGE_NOTIFY: > + amp_change_notify(level, frm, hdr->len); > + break; > + case AMP_CHANGE_RSP: > + amp_change_rsp(level, frm); > + break; > + case AMP_INFO_REQ: > + amp_info_req(level, frm); > + break; > + case AMP_INFO_RSP: > + amp_info_rsp(level, frm); > + break; > + case AMP_ASSOC_REQ: > + amp_assoc_req(level, frm); > + break; > + case AMP_ASSOC_RSP: > + amp_assoc_rsp(level, frm, hdr->len); > + break; > + case AMP_LINK_REQ: > + amp_link_req(level, frm, hdr->len); > + break; > + case AMP_LINK_RSP: > + amp_link_rsp(level, frm); > + break; > + case AMP_DISCONN_REQ: > + amp_disconn_req(level, frm); > + break; > + case AMP_DISCONN_RSP: > + amp_disconn_rsp(level, frm); > + break; > + default: > + if (p_filter(FILT_A2MP)) > + break; > + printf("code 0x%2.2x ident %d len %d\n", > + hdr->code, hdr->ident, btohs(hdr->len)); > + raw_dump(level, frm); > + } > + > + if (frm->len > btohs(hdr->len)) { > + frm->len -= btohs(hdr->len); > + frm->ptr += btohs(hdr->len); > + } else > + frm->len = 0; > + } > } else if (cid == 0x04) { > if (!p_filter(FILT_ATT)) > att_dump(level, frm); > diff --git a/parser/parser.h b/parser/parser.h > index e975808..22d18c3 100644 > --- a/parser/parser.h > +++ b/parser/parser.h > @@ -80,6 +80,7 @@ struct frame { > #define FILT_AVCTP 0x0800 > #define FILT_ATT 0x1000 > #define FILT_SMP 0x2000 > +#define FILT_A2MP 0x4000 > > #define FILT_OBEX 0x00010000 > #define FILT_CAPI 0x00020000 > diff --git a/src/hcidump.c b/src/hcidump.c > index 0c13360..2513c7c 100644 > --- a/src/hcidump.c > +++ b/src/hcidump.c > @@ -802,6 +802,7 @@ static struct { > { "hci", FILT_HCI }, > { "sco", FILT_SCO }, > { "l2cap", FILT_L2CAP }, > + { "a2mp", FILT_A2MP }, > { "rfcomm", FILT_RFCOMM }, > { "sdp", FILT_SDP }, > { "bnep", FILT_BNEP }, > -- > 1.7.7 > > -- > Peter Krystad > Employee of Qualcomm Innovation Center, Inc. > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum > -- > 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 [flat|nested] 10+ messages in thread
* Re: [PATCH 2/4] Add parsing of A2MP signals 2011-10-21 23:30 ` [PATCH 2/4] Add parsing of A2MP signals Peter Krystad 2011-10-24 7:34 ` Andrei Emeltchenko @ 2011-10-26 13:33 ` Andrei Emeltchenko 2011-10-26 18:49 ` Peter Krystad 1 sibling, 1 reply; 10+ messages in thread From: Andrei Emeltchenko @ 2011-10-26 13:33 UTC (permalink / raw) To: Peter Krystad; +Cc: linux-bluetooth Hi Peter, On Fri, Oct 21, 2011 at 04:30:00PM -0700, Peter Krystad wrote: ... > @@ -923,6 +1004,240 @@ static inline void move_cfm_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm > printf("Move cfm rsp: icid 0x%4.4x\n", icid); > } > > +static inline void amp_command_rej(int level, struct frame *frm) > +{ > + amp_cmd_rej_parms *h = frm->ptr; > + uint16_t reason = btohs(h->reason); > + > + if (p_filter(FILT_A2MP)) > + return; > + > + printf("Command Reject: reason (%d)- ", reason); > + p_indent(level + 1, frm); This doesn't make sense to use p_indent if you print on the same line. Maybe you forgot "\n" ? > + printf("%s\n", ampreason2str(reason)); > +} > + Best regards Andrei Emeltchenko ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [PATCH 2/4] Add parsing of A2MP signals 2011-10-26 13:33 ` Andrei Emeltchenko @ 2011-10-26 18:49 ` Peter Krystad 0 siblings, 0 replies; 10+ messages in thread From: Peter Krystad @ 2011-10-26 18:49 UTC (permalink / raw) To: 'Andrei Emeltchenko'; +Cc: linux-bluetooth Hi Andrei, > > > > +static inline void amp_command_rej(int level, struct frame *frm) > > +{ > > + amp_cmd_rej_parms *h = frm->ptr; > > + uint16_t reason = btohs(h->reason); > > + > > + if (p_filter(FILT_A2MP)) > > + return; > > + > > + printf("Command Reject: reason (%d)- ", reason); > > + p_indent(level + 1, frm); > > This doesn't make sense to use p_indent if you print on the same line. > Maybe you forgot "\n" ? > > > + printf("%s\n", ampreason2str(reason)); > > +} > > + > Will add a '\n'. I'll repost this patch set after the bluez header patchset is approved. Peter. --Peter Krystad Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/4] Add parsing of L2CAP Fixed Channel list 2011-10-21 23:29 [PATCH 0/4] Add parsing of BT 3.0+HS signalling Peter Krystad 2011-10-21 23:29 ` [PATCH 1/4] Add parsing of L2CAP Create/Move Channel signals Peter Krystad 2011-10-21 23:30 ` [PATCH 2/4] Add parsing of A2MP signals Peter Krystad @ 2011-10-21 23:30 ` Peter Krystad 2011-10-24 7:51 ` Andrei Emeltchenko 2011-10-21 23:30 ` [PATCH 4/4] Minor cleanup of indentation in output Peter Krystad 3 siblings, 1 reply; 10+ messages in thread From: Peter Krystad @ 2011-10-21 23:30 UTC (permalink / raw) To: linux-bluetooth; +Cc: andrei.emeltchenko, Peter Krystad Add DUMP_VERBOSE display of L2CAP Fixed Channel list. Example output: 2011-10-21 12:01:50.423246 > ACL data: handle 39 flags 0x02 dlen 20 L2CAP(s): Info rsp: type 3 result 0 Fixed channel list L2CAP CONNLESS A2MP --- parser/l2cap.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/parser/l2cap.c b/parser/l2cap.c index 7915788..ce78d05 100644 --- a/parser/l2cap.c +++ b/parser/l2cap.c @@ -811,6 +811,7 @@ static void info_opt(int level, int type, void *ptr, int len) { uint32_t mask; int i; + uint8_t list; p_indent(level, 0); @@ -830,6 +831,21 @@ static void info_opt(int level, int type, void *ptr, int len) break; case 0x0003: printf("Fixed channel list\n"); + list = get_val(ptr, 1); + if (parser.flags & DUMP_VERBOSE) { + if (list & L2CAP_FC_L2CAP) { + p_indent(level + 1, 0); + printf("L2CAP\n"); + } + if (list & L2CAP_FC_CONNLESS) { + p_indent(level + 1, 0); + printf("CONNLESS\n"); + } + if (list & L2CAP_FC_A2MP) { + p_indent(level + 1, 0); + printf("A2MP\n"); + } + } break; default: printf("Unknown (len %d)\n", len); -- 1.7.7 -- Peter Krystad Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 3/4] Add parsing of L2CAP Fixed Channel list 2011-10-21 23:30 ` [PATCH 3/4] Add parsing of L2CAP Fixed Channel list Peter Krystad @ 2011-10-24 7:51 ` Andrei Emeltchenko 0 siblings, 0 replies; 10+ messages in thread From: Andrei Emeltchenko @ 2011-10-24 7:51 UTC (permalink / raw) To: Peter Krystad; +Cc: linux-bluetooth Hi Peter, On Fri, Oct 21, 2011 at 04:30:01PM -0700, Peter Krystad wrote: > Add DUMP_VERBOSE display of L2CAP Fixed Channel list. > Example output: > > 2011-10-21 12:01:50.423246 > ACL data: handle 39 flags 0x02 dlen 20 > L2CAP(s): Info rsp: type 3 result 0 > Fixed channel list > L2CAP > CONNLESS > A2MP We can be more specific here since each channel is printed on new line > --- > parser/l2cap.c | 16 ++++++++++++++++ > 1 files changed, 16 insertions(+), 0 deletions(-) > > diff --git a/parser/l2cap.c b/parser/l2cap.c > index 7915788..ce78d05 100644 > --- a/parser/l2cap.c > +++ b/parser/l2cap.c > @@ -811,6 +811,7 @@ static void info_opt(int level, int type, void *ptr, int len) > { > uint32_t mask; > int i; > + uint8_t list; > > p_indent(level, 0); > > @@ -830,6 +831,21 @@ static void info_opt(int level, int type, void *ptr, int len) > break; > case 0x0003: > printf("Fixed channel list\n"); > + list = get_val(ptr, 1); We had discussion about this with Mat Martineau and agreed that we read 8 octets (there is one bit in 8th octet - AMP test manager) > + if (parser.flags & DUMP_VERBOSE) { > + if (list & L2CAP_FC_L2CAP) { > + p_indent(level + 1, 0); > + printf("L2CAP\n"); > + } > + if (list & L2CAP_FC_CONNLESS) { > + p_indent(level + 1, 0); > + printf("CONNLESS\n"); > + } > + if (list & L2CAP_FC_A2MP) { > + p_indent(level + 1, 0); > + printf("A2MP\n"); > + } > + } I know that this is common in hcidump but I do not like current approach. I have sent similar patch and the difference (beyond mentioned above) is that I define decode table: +static struct features l2cap_fix_chan[] = { + { "L2CAP Signalling Channel", L2CAP_FC_L2CAP }, + { "L2CAP Connless", L2CAP_FC_CONNLESS }, + { "AMP Manager Protocol", L2CAP_FC_A2MP }, + { 0 } +}; then: + if (parser.flags & DUMP_VERBOSE) + for (i=0; l2cap_fix_chan[i].name; i++) + if (fc_mask & l2cap_fix_chan[i].flag) { + p_indent(level + 1, 0); + printf("%s\n", l2cap_fix_chan[i].name); + } http://www.spinics.net/lists/linux-bluetooth/msg17247.html This is the way how it is done is wireshark network packet analyzer. Then if you want to add one extra feature (like AMP test manager) => you just add new table entry. Otherwise you have to create new "if" branch. Best regards Andrei Emeltchenko ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 4/4] Minor cleanup of indentation in output 2011-10-21 23:29 [PATCH 0/4] Add parsing of BT 3.0+HS signalling Peter Krystad ` (2 preceding siblings ...) 2011-10-21 23:30 ` [PATCH 3/4] Add parsing of L2CAP Fixed Channel list Peter Krystad @ 2011-10-21 23:30 ` Peter Krystad 3 siblings, 0 replies; 10+ messages in thread From: Peter Krystad @ 2011-10-21 23:30 UTC (permalink / raw) To: linux-bluetooth; +Cc: andrei.emeltchenko, Peter Krystad Minor indentation cleanup and fix display of physical link key --- parser/hci.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) diff --git a/parser/hci.c b/parser/hci.c index a0e3034..e459e9e 100644 --- a/parser/hci.c +++ b/parser/hci.c @@ -1124,12 +1124,11 @@ static inline void create_physical_link_dump(int level, struct frame *frm) int i; p_indent(level, frm); - printf("handle %d key length %d key type %d\n", cp->handle, cp->key_length, cp->key_type); + p_indent(level, frm); printf("key "); - - for (i = 0; i < cp->key_length && cp->key_length < 32; i++) + for (i = 0; i < cp->key_length && cp->key_length <= 32; i++) printf("%2.2x", cp->key[i]); printf("\n"); } @@ -1140,12 +1139,16 @@ static inline void create_logical_link_dump(int level, struct frame *frm) int i; p_indent(level, frm); - printf("handle %d\n", cp->handle); + + p_indent(level, frm); printf("tx_flow "); for (i = 0; i < 16; i++) printf("%2.2x", cp->tx_flow[i]); - printf("\nrx_flow "); + printf("\n"); + + p_indent(level, frm); + printf("rx_flow "); for (i = 0; i < 16; i++) printf("%2.2x", cp->rx_flow[i]); printf("\n"); @@ -2605,6 +2608,8 @@ static inline void read_local_amp_assoc_dump(int level, struct frame *frm) p_indent(level, frm); printf("Error: %s\n", status2str(rp->status)); } else { + p_indent(level, frm); + printf("assoc data"); for (i = 0; i < len; i++) { if (!(i % 16)) { printf("\n"); -- 1.7.7 -- Peter Krystad Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-10-26 18:49 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-10-21 23:29 [PATCH 0/4] Add parsing of BT 3.0+HS signalling Peter Krystad 2011-10-21 23:29 ` [PATCH 1/4] Add parsing of L2CAP Create/Move Channel signals Peter Krystad 2011-10-22 7:21 ` Marcel Holtmann 2011-10-21 23:30 ` [PATCH 2/4] Add parsing of A2MP signals Peter Krystad 2011-10-24 7:34 ` Andrei Emeltchenko 2011-10-26 13:33 ` Andrei Emeltchenko 2011-10-26 18:49 ` Peter Krystad 2011-10-21 23:30 ` [PATCH 3/4] Add parsing of L2CAP Fixed Channel list Peter Krystad 2011-10-24 7:51 ` Andrei Emeltchenko 2011-10-21 23:30 ` [PATCH 4/4] Minor cleanup of indentation in output Peter Krystad
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).