Diff between b689aca5d8d1cf09bab7245d5f5053ef1586549c and cde05014b346ce1084029ca42b497321d25bd73b

Changed Files

File Additions Deletions Status
tools/hcidump.c +106 -88 modified

Full Patch

diff --git a/tools/hcidump.c b/tools/hcidump.c
index 701fc88..e324293 100644
--- a/tools/hcidump.c
+++ b/tools/hcidump.c
@@ -41,19 +41,9 @@
 #include <bluetooth/hci.h>
 #include <bluetooth/l2cap.h>
 
-#define HEXDUMP		0
-#define ANALYZE		1
-
 /* Default options */
-int action = ANALYZE;
-
-char * hci_pkt_type[] = {
-	"Unknown",
-	"Command",
-	"ACL Data",
-	"SCO Data",
-	"Event"
-};
+int snap_len  = 1 + HCI_ACL_HDR_SIZE + L2CAP_HDR_SIZE + 40;
+int dump_type = 0;
 
 void usage(void)
 {
@@ -62,62 +52,83 @@ void usage(void)
 	printf("\thcidump <-i hciX> [-h]\n");
 }
 
-void hex_dump(char *pref, unsigned char *buf, int len)
+void raw_dump(char *pref, unsigned char *buf, int len)
 {
 	register char *ptr;
 	register int i;
 	char line[100];
 
+	if (!dump_type)
+		return;
+
 	ptr = line; *ptr = 0; 
-	for(i=0; i<len; i++ ){
+	for (i=0; i<len; i++) {
 		ptr += sprintf(ptr, " %2.2X", buf[i]);
-		if( i && !((i+1)%20) ){
+		if (i && !((i+1)%20)) {
 			printf("%s%s\n", pref, line);
 			ptr = line; *ptr = 0;
 		}
 	}
-	if( line[0] )
+	if (line[0])
 		printf("%s%s\n", pref, line);
 }
 
-void inline command_dump(void *ptr, int len)
+static inline void command_dump(void *ptr, int len)
 {
 	hci_command_hdr *hdr = ptr;
 	__u16 opcode = __le16_to_cpu(hdr->opcode);
-	printf("ogf 0x%x ocf 0x%x plen %d\n", 
+
+	ptr += HCI_COMMAND_HDR_SIZE;
+	len -= HCI_COMMAND_HDR_SIZE;
+
+	printf("Command: ogf 0x%x ocf 0x%x plen %d\n", 
 		cmd_opcode_ogf(opcode), cmd_opcode_ocf(opcode), hdr->plen);
+	raw_dump(" ", ptr, len);
 }
 
-void inline event_dump(void *ptr, int len)
+static inline void event_dump(void *ptr, int len)
 {
 	hci_event_hdr *hdr = ptr;
-	printf("code 0x%2.2x plen %d\n", hdr->evt, hdr->plen);
+	
+	ptr += HCI_EVENT_HDR_SIZE;
+	len -= HCI_EVENT_HDR_SIZE;
+
+	printf("Event: code 0x%2.2x plen %d\n", hdr->evt, hdr->plen);
+	raw_dump(" ", ptr, len);
 }
 
-void inline l2cap_dump(void *ptr, int len)
+static inline void l2cap_dump(void *ptr, int len)
 {
 	l2cap_hdr *hdr = ptr;
 	__u16 dlen = __le16_to_cpu(hdr->len);
 	__u16 cid  = __le16_to_cpu(hdr->cid);
 
-	printf("    L2CAP: cid 0x%x len %d\n", cid, dlen);
-
 	ptr += L2CAP_HDR_SIZE;
+	len -= L2CAP_HDR_SIZE;
+
 	if (cid == 0x1) {
 		l2cap_cmd_hdr *hdr = ptr;
 		__u16 len = __le16_to_cpu(hdr->len);
-		printf("    signaling: code 0x%x ident %d len %d\n", 
+
+		ptr += L2CAP_CMD_HDR_SIZE;
+		len -= L2CAP_CMD_HDR_SIZE;
+
+		printf("  L2CAP signaling: code 0x%2.2x ident %d len %d\n", 
 				hdr->code, hdr->ident, len);
+		raw_dump(" ", ptr, len);
+	} else {
+		printf("  L2CAP data: cid 0x%x len %d\n", cid, dlen);
+		raw_dump(" ", ptr, len);
 	}
 }
 
-void inline acl_dump(void *ptr, int len)
+static inline void acl_dump(void *ptr, int len)
 {
 	hci_acl_hdr *hdr = ptr;
 	__u16 handle = __le16_to_cpu(hdr->handle);
 	__u16 dlen = __le16_to_cpu(hdr->dlen);
 
-	printf("handle 0x%x flags 0x%x dlen %d\n",
+	printf("ACL data: handle 0x%x flags 0x%x dlen %d\n",
 		acl_handle(handle), acl_flags(handle), dlen);
 	
 	ptr += HCI_ACL_HDR_SIZE;
@@ -125,7 +136,7 @@ void inline acl_dump(void *ptr, int len)
 	l2cap_dump(ptr, len);
 }
 
-void analyze(int type, unsigned char *ptr, int len)
+static inline void analyze(int type, unsigned char *ptr, int len)
 {
 	switch( type ){
 		case HCI_COMMAND_PKT:
@@ -141,37 +152,89 @@ void analyze(int type, unsigned char *ptr, int len)
 			break;
 
 		default:
-			printf("\n");
+			printf("Unknown: type 0x%2.2x len %d\n", 
+					(__u8) type, len);
+
+			raw_dump("  ", ptr, len);
 			break;
 	}
 }
 
+void process_frames(int dev, int fd)
+{
+	char data[HCI_MAX_FRAME_SIZE], ctrl[100], *ptr;
+	struct cmsghdr *cmsg;
+	struct msghdr msg;
+	struct iovec  iv;
+	int len, type, in;
+
+	if (snap_len > sizeof(data))
+		snap_len = sizeof(data);
+	else if (snap_len < 20)
+		snap_len = 20;	
+
+	printf("device: hci%d snap_len: %d filter: none\n", dev, snap_len); 
+
+	while (1) {
+		iv.iov_base = data;
+		iv.iov_len  = snap_len;
+
+		msg.msg_iov = &iv;
+		msg.msg_iovlen = 1;
+		msg.msg_control = ctrl;
+		msg.msg_controllen = sizeof(ctrl);
+
+		if( (len = recvmsg(fd, &msg, 0)) < 0 ){
+			perror("Receive failed");
+			exit(1);
+		}
+
+		/* Process control message */
+		in = 0;
+		cmsg = CMSG_FIRSTHDR(&msg);
+		while( cmsg ){
+			switch(cmsg->cmsg_type){
+				case HCI_CMSG_DIR:
+					in = *((int *)CMSG_DATA(cmsg));
+					break;
+			}
+			cmsg = CMSG_NXTHDR(&msg, cmsg);
+		}
+
+		ptr = data;
+		type = *ptr++; len--;
+
+		/* Print data direction */
+		printf("%c ", (in ? '>' : '<')); 
+
+		analyze(type, ptr, len);
+
+		fflush(stdout);
+	}
+}
+
 extern int optind,opterr,optopt;
 extern char *optarg;
 
 int main(int argc, char *argv[])
 {
-	char data[HCI_MAX_FRAME_SIZE], ctrl[100], *ptr;
-	int s, len, type, opt, dev, in;
 	struct sockaddr_hci addr;
 	struct hci_filter flt;
-	struct cmsghdr *cmsg;
-	struct msghdr msg;
-	struct iovec  iv;
+	int s, opt, dev;
 
 	dev = 0;
-	while( (opt=getopt(argc, argv,"i:h")) != EOF ) {
+	while( (opt=getopt(argc, argv,"i:s:h")) != EOF ) {
 		switch(opt) {
 			case 'i':
 				dev = atoi(optarg+3);
 				break;
 
 			case 'h':
-				action = HEXDUMP;
+				dump_type = 1;
 				break;
 
-			case 'a':
-				action = ANALYZE;
+			case 's':
+				snap_len = atoi(optarg);
 				break;
 
 			default:
@@ -205,60 +268,15 @@ int main(int argc, char *argv[])
 	addr.hci_family = AF_BLUETOOTH;
 	addr.hci_dev = dev;
 	if( bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ) {
-		printf("Can't attach to device hci%d. %s(%d)\n", dev, strerror(errno), errno);
+		printf("Can't attach to device hci%d. %s(%d)\n", 
+					dev, strerror(errno), errno);
 		exit(1);
 	}
 
-	printf("HCIDump version %s\n", VERSION);
+	printf("HCIDump - HCI packet analyzer ver %s.\n", VERSION);
 
-	while( 1 ) {
-		iv.iov_base = data;
-		iv.iov_len  = sizeof(data);
+	process_frames(dev, s);	
 
-		msg.msg_iov = &iv;
-		msg.msg_iovlen = 1;
-		msg.msg_control = ctrl;
-		msg.msg_controllen = sizeof(ctrl);
-
-		if( (len = recvmsg(s, &msg, 0)) < 0 ){
-			perror("Receive failed");
-			exit(1);
-		}
-
-		/* Process controll message */
-		in = 0;
-		cmsg = CMSG_FIRSTHDR(&msg);
-		while( cmsg ){
-			switch(cmsg->cmsg_type){
-				case HCI_CMSG_DIR:
-					in = *((int *)CMSG_DATA(cmsg));
-					break;
-			}
-			cmsg = CMSG_NXTHDR(&msg, cmsg);
-		}
-
-		ptr = data;
-		type = *ptr++; len--;
-		if( type < 0 || type > 4 )
-			type = 0;
-
-		switch (action) {
-			case ANALYZE:
-				printf("%c %s: ", (in ? '>' : '<'), 
-					hci_pkt_type[type] );
-
-				analyze(type, ptr, len);
-				break;
-
-			case HEXDUMP:
-				printf("%c type 0x%2.2x len %d\n", 
-					(in ? '>' : '<'), 
-					(__u8) type, len);
-
-				hex_dump("  ", ptr, len);
-				break;
-		}
-
-		fflush(stdout);
-	}
+	close(s);
+	return 0;
 }