|
|
# --- SDE-COPYRIGHT-NOTE-BEGIN --- # This copyright note is auto-generated by ./scripts/Create-CopyPatch. # # Filename: package/.../bluez-hcidump/0004-Fix-HCI-LE-advertising-report-dump.patch # Copyright (C) 2011 The OpenSDE Project # # More information can be found in the files COPYING and README. # # This patch file is dual-licensed. It is available under the license the # patched project is licensed under, as long as it is an OpenSource license # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms # of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. # --- SDE-COPYRIGHT-NOTE-END ---
From 70fb86e548eef4d54bb659c76a47c0891ba5f99a Mon Sep 17 00:00:00 2001 From: Andre Dieb Martins <andre.dieb@signove.com> Date: Mon, 28 Feb 2011 00:58:22 -0300 Subject: [PATCH 4/6] Fix HCI LE advertising report dump
LE advertising report event has only one data block for each report. Thus, we can't reuse ext_inquiry_response_dump(), which loops over successive data blocks until reaches a zero-length one.
This commit introduces ext_inquiry_data_dump(), which dumps a frame containing data formatted according to [Vol 3] Part C, Section 8. This function is reused by ext_inquiry_response_dump().
Also adds RSSI parsing to each advertising report. ---
parser/hci.c | 146 +++++++++++++++++++++++++++++++++------------------------ 1 files changed, 84 insertions(+), 62 deletions(-)
diff --git a/parser/hci.c b/parser/hci.c
index fbbebde..4d9a315 100644
--- a/parser/hci.c
+++ b/parser/hci.c
@@ -757,67 +757,83 @@ static char *filterpolicy2str(uint8_t policy)
} } -static inline void ext_inquiry_response_dump(int level, struct frame *frm)
+static inline void ext_inquiry_data_dump(int level, struct frame *frm,
+ uint8_t *data)
{ - void *ptr = frm->ptr;
- uint32_t len = frm->len;
- uint8_t type, length;
+ uint8_t len = data[0];
+ uint8_t type;
char *str; int i; - length = get_u8(frm);
+ if (len == 0)
+ return;
- while (length > 0) {
- type = get_u8(frm);
- length--;
+ type = data[1];
+ data += 2;
+ len -= 1;
- switch (type) {
- case 0x01:
- p_indent(level, frm);
- printf("Flags:");
- for (i = 0; i < length; i++)
- printf(" 0x%2.2x", *((uint8_t *) (frm->ptr + i)));
- printf("\n");
- break;
+ switch (type) {
+ case 0x01:
+ p_indent(level, frm);
+ printf("Flags:");
+ for (i = 0; i < len; i++)
+ printf(" 0x%2.2x", data[i]);
+ printf("\n");
+ break;
- case 0x02:
- case 0x03:
- p_indent(level, frm);
- printf("%s service classes:",
- type == 0x02 ? "Shortened" : "Complete");
- for (i = 0; i < length / 2; i++) {
- uint16_t val = btohs(bt_get_unaligned((uint16_t *) (frm->ptr + (i * 2))));
- printf(" 0x%4.4x", val);
- }
- printf("\n");
- break;
+ case 0x02:
+ case 0x03:
+ p_indent(level, frm);
+ printf("%s service classes:",
+ type == 0x02 ? "Shortened" : "Complete");
- case 0x08:
- case 0x09:
- str = malloc(length + 1);
- if (str) {
- snprintf(str, length + 1, "%s", (char *) frm->ptr);
- for (i = 0; i < length; i++)
- if (!isprint(str[i]))
- str[i] = '.';
- p_indent(level, frm);
- printf("%s local name: \'%s\'\n",
- type == 0x08 ? "Shortened" : "Complete", str);
- free(str);
- }
- break;
+ for (i = 0; i < len / 2; i++) {
+ uint16_t val;
- case 0x0a:
- p_indent(level, frm);
- printf("TX power level: %d\n", *((uint8_t *) frm->ptr));
- break;
+ val = btohs(bt_get_unaligned(((uint16_t *) (data + i * 2))));
+ printf(" 0x%4.4x", val);
+ }
+ printf("\n");
+ break;
- default:
+ case 0x08:
+ case 0x09:
+ str = malloc(len + 1);
+ if (str) {
+ snprintf(str, len + 1, "%s", (char *) data);
+ for (i = 0; i < len; i++)
+ if (!isprint(str[i]))
+ str[i] = '.';
p_indent(level, frm); - printf("Unknown type 0x%02x with %d bytes data\n",
- type, length);
- break;
+ printf("%s local name: \'%s\'\n",
+ type == 0x08 ? "Shortened" : "Complete", str);
+ free(str);
} + break;
+
+ case 0x0a:
+ p_indent(level, frm);
+ printf("TX power level: %d\n", *((uint8_t *) data));
+ break;
+
+ default:
+ p_indent(level, frm);
+ printf("Unknown type 0x%02x with %d bytes data\n",
+ type, len);
+ break;
+ }
+}
+
+static inline void ext_inquiry_response_dump(int level, struct frame *frm)
+{
+ void *ptr = frm->ptr;
+ uint32_t len = frm->len;
+ uint8_t length;
+
+ length = get_u8(frm);
+
+ while (length > 0) {
+ ext_inquiry_data_dump(level, frm, frm->ptr);
frm->ptr += length; frm->len -= length; @@ -825,8 +841,10 @@ static inline void ext_inquiry_response_dump(int level, struct frame *frm)
length = get_u8(frm); } - frm->ptr = ptr + (EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE);
- frm->len = len + (EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE);
+ frm->ptr = ptr +
+ (EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE);
+ frm->len = len +
+ (EXTENDED_INQUIRY_INFO_SIZE - INQUIRY_INFO_WITH_RSSI_SIZE);
} static inline void bdaddr_command_dump(int level, struct frame *frm) @@ -3504,14 +3522,12 @@ static inline void evt_le_conn_complete_dump(int level, struct frame *frm)
static inline void evt_le_advertising_report_dump(int level, struct frame *frm) { - uint8_t num = get_u8(frm);
- char addr[18];
- int i;
+ uint8_t num_reports = get_u8(frm);
+ const uint8_t RSSI_SIZE = 1;
- for (i = 0; i < num; i++) {
+ while (num_reports--) {
+ char addr[18];
le_advertising_info *info = frm->ptr; - void *ptr = frm->ptr;
- uint32_t len = frm->len;
p_ba2str(&info->bdaddr, addr); @@ -3522,13 +3538,19 @@ static inline void evt_le_advertising_report_dump(int level, struct frame *frm)
printf("bdaddr %s (%s)\n", addr, bdaddrtype2str(info->bdaddr_type)); - frm->ptr += LE_ADVERTISING_INFO_SIZE;
- frm->len -= LE_ADVERTISING_INFO_SIZE;
+ if (info->length > 0) {
+ ext_inquiry_data_dump(level, frm,
+ ((uint8_t *) &info->length) + 1);
+ }
- ext_inquiry_response_dump(level, frm);
+ frm->ptr += LE_ADVERTISING_INFO_SIZE + info->length;
+ frm->len -= LE_ADVERTISING_INFO_SIZE + info->length;
+
+ p_indent(level, frm);
+ printf("RSSI: %d\n", ((int8_t *) frm->ptr)[frm->len - 1]);
- frm->ptr = ptr + 1;
- frm->len = len - 1;
+ frm->ptr += RSSI_SIZE;
+ frm->len -= RSSI_SIZE;
} } --
1.7.2.3
|