From 21e951b6b15827f356ffb0269ea22d0ec3c0a572 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Sep 2003 16:21:48 +0000 Subject: [PATCH] hcidump: HIDP support --- tools/hcidump.c | 1 + tools/parser/hidp.c | 180 ++++++++++++++++++++++++++++++++++++++++++ tools/parser/l2cap.c | 8 ++ tools/parser/parser.h | 2 + 4 files changed, 191 insertions(+) create mode 100644 tools/parser/hidp.c diff --git a/tools/hcidump.c b/tools/hcidump.c index eb44b6467..fdb0b9a84 100644 --- a/tools/hcidump.c +++ b/tools/hcidump.c @@ -246,6 +246,7 @@ static struct { { "sdp", FILT_SDP }, { "bnep", FILT_BNEP }, { "cmtp", FILT_CMTP }, + { "hidp", FILT_HIDP }, { 0 } }; diff --git a/tools/parser/hidp.c b/tools/parser/hidp.c new file mode 100644 index 000000000..e4aaded8a --- /dev/null +++ b/tools/parser/hidp.c @@ -0,0 +1,180 @@ +/* + HCIDump - HCI packet analyzer + Copyright (C) 2000-2001 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + HIDP parser. + Copyright (C) 2003 Marcel Holtmann +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "parser.h" + +char *type2str(uint8_t head) +{ + switch (head & 0xf0) { + case 0x00: + return "Handshake"; + case 0x10: + return "Control"; + case 0x40: + return "Get report"; + case 0x50: + return "Set report"; + case 0x60: + return "Get protocol"; + case 0x70: + return "Set protocol"; + case 0x80: + return "Get idle"; + case 0x90: + return "Set idle"; + case 0xa0: + return "Data"; + case 0xb0: + return "Data continuation"; + default: + return "Reserved"; + } +} + +char *result2str(uint8_t head) +{ + switch (head & 0x0f) { + case 0x00: + return "Successful"; + case 0x01: + return "Not ready"; + case 0x02: + return "Invalid report ID"; + case 0x03: + return "Unsupported request"; + case 0x04: + return "Invalid parameter"; + case 0x0e: + return "Unknown"; + case 0x0f: + return "Fatal"; + default: + return "Reserved"; + } +} + +char *operation2str(uint8_t head) +{ + switch (head & 0x0f) { + case 0x00: + return "No operation"; + case 0x01: + return "Hard reset"; + case 0x02: + return "Soft reset"; + case 0x03: + return "Suspend"; + case 0x04: + return "Exit suspend"; + case 0x05: + return "Virtual cable unplug"; + default: + return "Reserved"; + } +} + +char *report2str(uint8_t head) +{ + switch (head & 0x03) { + case 0x00: + return "Other report"; + case 0x01: + return "Input report"; + case 0x02: + return "Output report"; + case 0x03: + return "Feature report"; + default: + return "Reserved"; + } +} + +char *protocol2str(uint8_t head) +{ + switch (head & 0x01) { + case 0x00: + return "Report protocol"; + case 0x01: + return "Boot protocol"; + default: + return "Reserved"; + } +} + +void hidp_dump(int level, struct frame *frm) +{ + uint8_t head; + char *param; + + head = *(uint8_t *)frm->ptr; + + switch (head & 0xf0) { + case 0x00: + param = result2str(head); + break; + case 0x10: + param = operation2str(head); + break; + case 0x60: + case 0x70: + param = protocol2str(head); + break; + case 0x40: + case 0x50: + case 0xa0: + case 0xb0: + param = report2str(head); + break; + default: + param = ""; + break; + } + + p_indent(level, frm); + + printf("HIDP: %s: %s\n", type2str(head), param); + + frm->ptr++; + frm->len++; + + raw_dump(level, frm); +} diff --git a/tools/parser/l2cap.c b/tools/parser/l2cap.c index 6362ae39a..ac712e611 100644 --- a/tools/parser/l2cap.c +++ b/tools/parser/l2cap.c @@ -420,6 +420,14 @@ static void l2cap_parse(int level, struct frame *frm) raw_dump(level+1, frm); break; + case 0x11: + case 0x13: + if (!p_filter(FILT_HIDP)) + hidp_dump(level, frm); + else + raw_dump(level+1, frm); + break; + case 4099: if (!p_filter(FILT_CMTP)) cmtp_dump(level, frm); diff --git a/tools/parser/parser.h b/tools/parser/parser.h index 4f5282cf7..6dfb220b0 100644 --- a/tools/parser/parser.h +++ b/tools/parser/parser.h @@ -51,6 +51,7 @@ struct frame { #define FILT_SCO 0x0010 #define FILT_BNEP 0x0020 #define FILT_CMTP 0x0040 +#define FILT_HIDP 0x0080 #define STRUCT_OFFSET(type, member) ((uint8_t *)&(((type *)NULL)->member) - \ (uint8_t *)((type *)NULL)) @@ -151,6 +152,7 @@ void rfcomm_dump(int level, struct frame *frm); void sdp_dump(int level, struct frame *frm); void bnep_dump(int level, struct frame *frm); void cmtp_dump(int level, struct frame *frm); +void hidp_dump(int level, struct frame *frm); static inline void parse(struct frame *frm) { -- 2.47.3