Linux bluetooth development
 help / color / mirror / Atom feed
From: Andre Dieb Martins <andre.dieb@signove.com>
To: linux-bluetooth@vger.kernel.org
Cc: Andre Dieb Martins <andre.dieb@signove.com>
Subject: [PATCH v1] Fix HCI LE advertising report dump
Date: Mon, 28 Feb 2011 00:58:22 -0300	[thread overview]
Message-ID: <1298865502-12676-1-git-send-email-andre.dieb@signove.com> (raw)

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 183fa66..e4a3633 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.1


             reply	other threads:[~2011-02-28  3:58 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-28  3:58 Andre Dieb Martins [this message]
2011-03-01 18:59 ` [PATCH v1] Fix HCI LE advertising report dump Johan Hedberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1298865502-12676-1-git-send-email-andre.dieb@signove.com \
    --to=andre.dieb@signove.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox