Diff between 7163013a596c66424fb78ac0bc6827dc9fd3f059 and 36927f39b50fa4d70ab71a2446cfd03f1449134c

Changed Files

File Additions Deletions Status
tools/parser/l2cap.c +29 -25 modified
tools/parser/parser.c +50 -2 modified
tools/parser/parser.h +7 -4 modified
tools/parser/sdp.c +1 -0 modified

Full Patch

diff --git a/tools/parser/l2cap.c b/tools/parser/l2cap.c
index 7bb6783..f518baa 100644
--- a/tools/parser/l2cap.c
+++ b/tools/parser/l2cap.c
@@ -38,6 +38,7 @@
 #include <bluetooth/l2cap.h>
 
 #include "parser.h"
+#include "sdp.h"
 
 typedef struct {
 	uint16_t handle;
@@ -51,7 +52,7 @@ typedef struct {
 	uint16_t cid;
 	uint16_t psm;
 } cid_info;
-#define CID_TABLE_SIZE	20
+#define CID_TABLE_SIZE 20
 
 static cid_info cid_table[2][CID_TABLE_SIZE];
 
@@ -110,7 +111,7 @@ static void del_cid(int in, uint16_t dcid, uint16_t scid)
 	}
 
 	for (t = 0; t < 2; t++) {
-		for (i=0; i<CID_TABLE_SIZE; i++)
+		for (i = 0; i < CID_TABLE_SIZE; i++)
 			if (cid_table[t][i].cid == cid[t]) {
 				cid_table[t][i].cid = 0;
 				break;
@@ -122,7 +123,7 @@ static uint16_t get_psm(int in, uint16_t cid)
 {
 	register cid_info *table = cid_table[in];
 	register int i;
-	
+
 	for (i = 0; i < CID_TABLE_SIZE; i++)
 		if (table[i].cid == cid)
 			return table[i].psm;
@@ -183,10 +184,10 @@ static void conf_opt(int level, void *ptr, int len)
 	p_indent(level, 0);
 	while (len > 0) {
 		l2cap_conf_opt *h = ptr;
-	
+
 		ptr += L2CAP_CONF_OPT_SIZE + h->len;
 		len -= L2CAP_CONF_OPT_SIZE + h->len;
-		
+
 		switch (h->type) {
 		case L2CAP_CONF_MTU:
 			printf("MTU %d ", conf_opt_val(h->val, h->len));
@@ -237,7 +238,7 @@ static inline void disconn_req(int level, struct frame *frm)
 	if (p_filter(FILT_L2CAP))
 		return;
 
-	printf("Disconn req: dcid 0x%4.4x scid 0x%4.4x\n", 
+	printf("Disconn req: dcid 0x%4.4x scid 0x%4.4x\n",
 			btohs(h->dcid), btohs(h->scid));
 }
 
@@ -258,8 +259,7 @@ static inline void echo_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
 	if (p_filter(FILT_L2CAP))
 		return;
 
-	printf("Echo req: dlen %d\n", 
-			btohs(cmd->len));
+	printf("Echo req: dlen %d\n", btohs(cmd->len));
 	raw_dump(level, frm);
 }
 
@@ -268,8 +268,7 @@ static inline void echo_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
 	if (p_filter(FILT_L2CAP))
 		return;
 
-	printf("Echo rsp: dlen %d\n", 
-			btohs(cmd->len));
+	printf("Echo rsp: dlen %d\n", btohs(cmd->len));
 	raw_dump(level, frm);
 }
 
@@ -278,8 +277,7 @@ static inline void info_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
 	if (p_filter(FILT_L2CAP))
 		return;
 
-	printf("Info req: dlen %d\n", 
-			btohs(cmd->len));
+	printf("Info req: dlen %d\n", btohs(cmd->len));
 	raw_dump(level, frm);
 }
 
@@ -288,8 +286,7 @@ static inline void info_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
 	if (p_filter(FILT_L2CAP))
 		return;
 
-	printf("Info rsp: dlen %d\n", 
-			btohs(cmd->len));
+	printf("Info rsp: dlen %d\n", btohs(cmd->len));
 	raw_dump(level, frm);
 }
 
@@ -387,12 +384,13 @@ static void l2cap_parse(int level, struct frame *frm)
 	} else {
 		/* Connection oriented channel */
 		uint16_t psm = get_psm(!frm->in, cid);
+		uint32_t proto;
 
 		frm->cid = cid;
 
 		if (!p_filter(FILT_L2CAP)) {
 			p_indent(level, frm);
-			printf("L2CAP(d): cid 0x%x len %d [psm %d]\n", 
+			printf("L2CAP(d): cid 0x%x len %d [psm %d]\n",
 				cid, dlen, psm);
 			level++;
 		}
@@ -427,18 +425,24 @@ static void l2cap_parse(int level, struct frame *frm)
 				raw_dump(level + 1, frm);
 			break;
 
-		case 4099:
-			if (!p_filter(FILT_CMTP))
-				cmtp_dump(level, frm);
-			else
-				raw_dump(level + 1, frm);
-			break;
-
 		default:
-			if (p_filter(FILT_L2CAP))
+			proto = get_proto(frm->handle, psm);
+
+			switch (proto) {
+			case SDP_UUID_CMTP:
+				if (!p_filter(FILT_CMTP))
+					cmtp_dump(level, frm);
+				else
+					raw_dump(level + 1, frm);
 				break;
 
-			raw_dump(level, frm);
+			default:
+				if (p_filter(FILT_L2CAP))
+					break;
+
+				raw_dump(level, frm);
+				break;
+			}
 			break;
 		}
 	}
@@ -492,7 +496,7 @@ void l2cap_dump(int level, struct frame *frm)
 			raw_dump(level, frm);
 			return;
 		}
-		
+
 		if (frm->len > (fr->data_len - fr->len)) {
 			/* Bad fragment */
 			raw_dump(level, frm);
diff --git a/tools/parser/parser.c b/tools/parser/parser.c
index 02fdcac..2ef56a9 100644
--- a/tools/parser/parser.c
+++ b/tools/parser/parser.c
@@ -49,6 +49,54 @@ void init_parser(unsigned long flags, unsigned long filter,
 	parser.state  = 0;
 }
 
+#define PROTO_TABLE_SIZE 20
+
+static struct {
+	uint16_t handle;
+	uint16_t psm;
+	uint32_t proto;
+} proto_table[PROTO_TABLE_SIZE];
+
+void set_proto(uint16_t handle, uint16_t psm, uint32_t proto)
+{
+	int i, pos = -1;
+
+	if (psm < 0x1000)
+		return;
+
+	for (i = 0; i < PROTO_TABLE_SIZE; i++) {
+		if (proto_table[i].handle == handle && proto_table[i].psm == psm) {
+			pos = i;
+			break;
+		}
+
+		if (pos < 0 && !proto_table[i].handle && !proto_table[i].psm)
+			pos = i;
+	}
+
+	if (pos < 0)
+		return;
+
+	proto_table[pos].handle = handle;
+	proto_table[pos].psm    = psm;
+	proto_table[pos].proto  = proto;
+}
+
+uint32_t get_proto(uint16_t handle, uint16_t psm)
+{
+	int i, pos = -1;
+
+	for (i = 0; i < PROTO_TABLE_SIZE; i++) {
+		if (proto_table[i].handle == handle && proto_table[i].psm == psm)
+			return proto_table[i].proto;
+
+		if (!proto_table[i].handle && proto_table[i].psm == psm)
+			pos = i;
+	}
+
+	return (pos < 0) ? 0 : proto_table[pos].proto;
+}
+
 static inline void hex_dump(int level, struct frame *frm, int num)
 {
 	unsigned char *buf = frm->ptr;
@@ -57,7 +105,7 @@ static inline void hex_dump(int level, struct frame *frm, int num)
 	if ((num < 0) || (num > frm->len))
 		num = frm->len;
 
-	for (i=0, n=1; i<num; i++, n++) {
+	for (i = 0, n = 1; i < num; i++, n++) {
 		if (n == 1)
 			p_indent(level, frm);
 		printf("%2.2X ", buf[i]);
@@ -78,7 +126,7 @@ static inline void ascii_dump(int level, struct frame *frm, int num)
 	if ((num < 0) || (num > frm->len))
 		num = frm->len;
 
-	for (i=0, n=1; i<num; i++, n++) {
+	for (i = 0, n = 1; i < num; i++, n++) {
 		if (n == 1)
 			p_indent(level, frm);
 		printf("%1c ", isprint(buf[i]) ? buf[i] : '.');
diff --git a/tools/parser/parser.h b/tools/parser/parser.h
index 05b010b..0c2781e 100644
--- a/tools/parser/parser.h
+++ b/tools/parser/parser.h
@@ -46,10 +46,10 @@ struct frame {
 
 /* Parser filter */
 #define FILT_HCI	0x0001
-#define FILT_L2CAP	0x0002
-#define FILT_RFCOMM	0x0004
-#define FILT_SDP	0x0008
-#define FILT_SCO	0x0010
+#define FILT_SCO	0x0002
+#define FILT_L2CAP	0x0004
+#define FILT_RFCOMM	0x0008
+#define FILT_SDP	0x0010
 #define FILT_BNEP	0x0020
 #define FILT_CMTP	0x0040
 #define FILT_HIDP	0x0080
@@ -145,6 +145,9 @@ static inline void get_u128(struct frame *frm, uint64_t *l, uint64_t *h)
 
 char *get_uuid_name(int uuid);
 
+void set_proto(uint16_t handle, uint16_t psm, uint32_t proto);
+uint32_t get_proto(uint16_t handle, uint16_t psm);
+
 void raw_dump(int level, struct frame *frm);
 void raw_ndump(int level, struct frame *frm, int num);
 void hci_dump(int level, struct frame *frm);
diff --git a/tools/parser/sdp.c b/tools/parser/sdp.c
index d58d70c..c1cb0fe 100644
--- a/tools/parser/sdp.c
+++ b/tools/parser/sdp.c
@@ -256,6 +256,7 @@ static inline void print_uuid(int n, struct frame *frm, uint16_t *psm)
 	}
 
 	if (psm && *psm > 0 && *psm != 0xffff) {
+		set_proto(frm->handle, *psm, uuid);
 		*psm = 0xffff;
 	}