Diff between 936842f88055f2c42e99ebe890b5b29b239c5e56 and 56d5fec6a436410bc70a595003fd4df5714e53e1

Changed Files

File Additions Deletions Status
monitor/analyze.c +115 -18 modified

Full Patch

diff --git a/monitor/analyze.c b/monitor/analyze.c
index b617fcb..afe2ce9 100644
--- a/monitor/analyze.c
+++ b/monitor/analyze.c
@@ -48,6 +48,10 @@ struct hci_dev {
 	uint8_t bdaddr[6];
 	struct timeval time_added;
 	struct timeval time_removed;
+	unsigned long num_cmd;
+	unsigned long num_evt;
+	unsigned long num_acl;
+	unsigned long num_sco;
 };
 
 static struct queue *dev_list;
@@ -60,28 +64,28 @@ static void dev_destroy(void *data)
 	printf("  BD_ADDR %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
 			dev->bdaddr[5], dev->bdaddr[4], dev->bdaddr[3],
 			dev->bdaddr[2], dev->bdaddr[1], dev->bdaddr[0]);
+	printf("  %lu commands\n", dev->num_cmd);
+	printf("  %lu events\n", dev->num_evt);
+	printf("  %lu ACL packets\n", dev->num_acl);
+	printf("  %lu SCO packets\n", dev->num_sco);
 	printf("\n");
 
 	free(dev);
 }
 
-static void new_index(struct timeval *tv, uint16_t index,
-					const void *data, uint16_t size)
+static struct hci_dev *dev_alloc(uint16_t index)
 {
-	const struct btsnoop_opcode_new_index *ni = data;
 	struct hci_dev *dev;
 
 	dev = new0(struct hci_dev, 1);
 	if (!dev) {
 		fprintf(stderr, "Failed to allocate new device entry\n");
-		return;
+		return NULL;
 	}
 
 	dev->index = index;
-	dev->type = ni->type;
-	memcpy(dev->bdaddr, ni->bdaddr, 6);
 
-	queue_push_tail(dev_list, dev);
+	return dev;
 }
 
 static bool dev_match_index(const void *a, const void *b)
@@ -92,6 +96,40 @@ static bool dev_match_index(const void *a, const void *b)
 	return dev->index == index;
 }
 
+static struct hci_dev *dev_lookup(uint16_t index)
+{
+	struct hci_dev *dev;
+
+	dev = queue_find(dev_list, dev_match_index, UINT_TO_PTR(index));
+	if (!dev) {
+		fprintf(stderr, "Creating new device for unknown index\n");
+
+		dev = dev_alloc(index);
+		if (!dev)
+			return NULL;
+
+		queue_push_tail(dev_list, dev);
+	}
+
+	return dev;
+}
+
+static void new_index(struct timeval *tv, uint16_t index,
+					const void *data, uint16_t size)
+{
+	const struct btsnoop_opcode_new_index *ni = data;
+	struct hci_dev *dev;
+
+	dev = dev_alloc(index);
+	if (!dev)
+		return;
+
+	dev->type = ni->type;
+	memcpy(dev->bdaddr, ni->bdaddr, 6);
+
+	queue_push_tail(dev_list, dev);
+}
+
 static void del_index(struct timeval *tv, uint16_t index,
 					const void *data, uint16_t size)
 {
@@ -106,27 +144,36 @@ static void del_index(struct timeval *tv, uint16_t index,
 	dev_destroy(dev);
 }
 
-static void rsp_read_bd_addr(struct timeval *tv, uint16_t index,
+static void command_pkt(struct timeval *tv, uint16_t index,
 					const void *data, uint16_t size)
 {
-	const struct bt_hci_rsp_read_bd_addr *rsp = data;
+	const struct bt_hci_cmd_hdr *hdr = data;
 	struct hci_dev *dev;
 
-	printf("Read BD Addr event with status 0x%2.2x\n", rsp->status);
+	data += sizeof(*hdr);
+	size -= sizeof(*hdr);
 
-	if (rsp->status)
+	dev = dev_lookup(index);
+	if (!dev)
 		return;
 
-	dev = queue_find(dev_list, dev_match_index, UINT_TO_PTR(index));
-	if (!dev) {
-		fprintf(stderr, "Address for unknown device\n");
+	dev->num_cmd++;
+}
+
+static void rsp_read_bd_addr(struct hci_dev *dev, struct timeval *tv,
+					const void *data, uint16_t size)
+{
+	const struct bt_hci_rsp_read_bd_addr *rsp = data;
+
+	printf("Read BD Addr event with status 0x%2.2x\n", rsp->status);
+
+	if (rsp->status)
 		return;
-	}
 
 	memcpy(dev->bdaddr, rsp->bdaddr, 6);
 }
 
-static void evt_cmd_complete(struct timeval *tv, uint16_t index,
+static void evt_cmd_complete(struct hci_dev *dev, struct timeval *tv,
 					const void *data, uint16_t size)
 {
 	const struct bt_hci_evt_cmd_complete *evt = data;
@@ -139,7 +186,7 @@ static void evt_cmd_complete(struct timeval *tv, uint16_t index,
 
 	switch (opcode) {
 	case BT_HCI_CMD_READ_BD_ADDR:
-		rsp_read_bd_addr(tv, index, data, size);
+		rsp_read_bd_addr(dev, tv, data, size);
 		break;
 	}
 }
@@ -148,17 +195,56 @@ static void event_pkt(struct timeval *tv, uint16_t index,
 					const void *data, uint16_t size)
 {
 	const struct bt_hci_evt_hdr *hdr = data;
+	struct hci_dev *dev;
 
 	data += sizeof(*hdr);
 	size -= sizeof(*hdr);
 
+	dev = dev_lookup(index);
+	if (!dev)
+		return;
+
+	dev->num_evt++;
+
 	switch (hdr->evt) {
 	case BT_HCI_EVT_CMD_COMPLETE:
-		evt_cmd_complete(tv, index, data, size);
+		evt_cmd_complete(dev, tv, data, size);
 		break;
 	}
 }
 
+static void acl_pkt(struct timeval *tv, uint16_t index,
+					const void *data, uint16_t size)
+{
+	const struct bt_hci_acl_hdr *hdr = data;
+	struct hci_dev *dev;
+
+	data += sizeof(*hdr);
+	size -= sizeof(*hdr);
+
+	dev = dev_lookup(index);
+	if (!dev)
+		return;
+
+	dev->num_acl++;
+}
+
+static void sco_pkt(struct timeval *tv, uint16_t index,
+					const void *data, uint16_t size)
+{
+	const struct bt_hci_sco_hdr *hdr = data;
+	struct hci_dev *dev;
+
+	data += sizeof(*hdr);
+	size -= sizeof(*hdr);
+
+	dev = dev_lookup(index);
+	if (!dev)
+		return;
+
+	dev->num_sco++;
+}
+
 void analyze_trace(const char *path)
 {
 	unsigned long num_packets = 0;
@@ -198,9 +284,20 @@ void analyze_trace(const char *path)
 		case BTSNOOP_OPCODE_DEL_INDEX:
 			del_index(&tv, index, buf, pktlen);
 			break;
+		case BTSNOOP_OPCODE_COMMAND_PKT:
+			command_pkt(&tv, index, buf, pktlen);
+			break;
 		case BTSNOOP_OPCODE_EVENT_PKT:
 			event_pkt(&tv, index, buf, pktlen);
 			break;
+		case BTSNOOP_OPCODE_ACL_TX_PKT:
+		case BTSNOOP_OPCODE_ACL_RX_PKT:
+			acl_pkt(&tv, index, buf, pktlen);
+			break;
+		case BTSNOOP_OPCODE_SCO_TX_PKT:
+		case BTSNOOP_OPCODE_SCO_RX_PKT:
+			sco_pkt(&tv, index, buf, pktlen);
+			break;
 		}
 
 		num_packets++;