summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2014-02-12 11:54:02 -0800
committerMarcel Holtmann <marcel@holtmann.org>2014-02-12 11:54:02 -0800
commitd7c40c78693aed5d0d351e7981c3c529f0aa483a (patch)
tree81e91aad54b4005c1cd65d79e7837ee41c3e7242
parented1d75bee937970656ef14394a693b09d9d256bb (diff)
downloadbluez-d7c40c78693aed5d0d351e7981c3c529f0aa483a.tar.gz
monitor: Add support for reading Apple Packet Logger traces
-rw-r--r--monitor/analyze.c2
-rw-r--r--monitor/control.c2
-rw-r--r--src/shared/btsnoop.c98
-rw-r--r--src/shared/btsnoop.h4
4 files changed, 95 insertions, 11 deletions
diff --git a/monitor/analyze.c b/monitor/analyze.c
index 2d994e3c1..a747938f9 100644
--- a/monitor/analyze.c
+++ b/monitor/analyze.c
@@ -259,7 +259,7 @@ void analyze_trace(const char *path)
unsigned long num_packets = 0;
uint32_t type;
- btsnoop_file = btsnoop_open(path);
+ btsnoop_file = btsnoop_open(path, BTSNOOP_FLAG_PKLG_SUPPORT);
if (!btsnoop_file)
return;
diff --git a/monitor/control.c b/monitor/control.c
index bf0ee0220..f637a9633 100644
--- a/monitor/control.c
+++ b/monitor/control.c
@@ -825,7 +825,7 @@ void control_reader(const char *path)
uint32_t type;
struct timeval tv;
- btsnoop_file = btsnoop_open(path);
+ btsnoop_file = btsnoop_open(path, BTSNOOP_FLAG_PKLG_SUPPORT);
if (!btsnoop_file)
return;
diff --git a/src/shared/btsnoop.c b/src/shared/btsnoop.c
index a16830631..d2b3b4b3d 100644
--- a/src/shared/btsnoop.c
+++ b/src/shared/btsnoop.c
@@ -56,15 +56,24 @@ static const uint8_t btsnoop_id[] = { 0x62, 0x74, 0x73, 0x6e,
static const uint32_t btsnoop_version = 1;
+struct pklg_pkt {
+ uint32_t len;
+ uint64_t ts;
+ uint8_t type;
+} __attribute__ ((packed));
+#define PKLG_PKT_SIZE (sizeof(struct pklg_pkt))
+
struct btsnoop {
int ref_count;
int fd;
+ unsigned long flags;
uint32_t type;
uint16_t index;
bool aborted;
+ bool pklg_format;
};
-struct btsnoop *btsnoop_open(const char *path)
+struct btsnoop *btsnoop_open(const char *path, unsigned long flags)
{
struct btsnoop *btsnoop;
struct btsnoop_hdr hdr;
@@ -80,18 +89,34 @@ struct btsnoop *btsnoop_open(const char *path)
return NULL;
}
+ btsnoop->flags = flags;
+
len = read(btsnoop->fd, &hdr, BTSNOOP_HDR_SIZE);
if (len < 0 || len != BTSNOOP_HDR_SIZE)
goto failed;
- if (memcmp(hdr.id, btsnoop_id, sizeof(btsnoop_id)))
- goto failed;
+ if (!memcmp(hdr.id, btsnoop_id, sizeof(btsnoop_id))) {
+ /* Check for BTSnoop version 1 format */
+ if (be32toh(hdr.version) != btsnoop_version)
+ goto failed;
- if (be32toh(hdr.version) != btsnoop_version)
- goto failed;
+ btsnoop->type = be32toh(hdr.type);
+ btsnoop->index = 0xffff;
+ } else {
+ if (!(btsnoop->flags & BTSNOOP_FLAG_PKLG_SUPPORT))
+ goto failed;
- btsnoop->type = be32toh(hdr.type);
- btsnoop->index = 0xffff;
+ /* Check for Apple Packet Logger format */
+ if (hdr.id[0] != 0x00 || hdr.id[1] != 0x00)
+ goto failed;
+
+ btsnoop->type = BTSNOOP_TYPE_MONITOR;
+ btsnoop->index = 0xffff;
+ btsnoop->pklg_format = true;
+
+ /* Apple Packet Logger format has no header */
+ lseek(btsnoop->fd, 0, SEEK_SET);
+ }
return btsnoop_ref(btsnoop);
@@ -274,6 +299,60 @@ bool btsnoop_write_phy(struct btsnoop *btsnoop, struct timeval *tv,
return btsnoop_write(btsnoop, tv, flags, data, size);
}
+static uint16_t get_opcode_from_pklg(uint8_t type)
+{
+ switch (type) {
+ case 0x00:
+ return BTSNOOP_OPCODE_COMMAND_PKT;
+ case 0x01:
+ return BTSNOOP_OPCODE_EVENT_PKT;
+ case 0x02:
+ return BTSNOOP_OPCODE_ACL_TX_PKT;
+ case 0x03:
+ return BTSNOOP_OPCODE_ACL_RX_PKT;
+ }
+
+ return 0xffff;
+}
+
+static bool pklg_read_hci(struct btsnoop *btsnoop, struct timeval *tv,
+ uint16_t *index, uint16_t *opcode,
+ void *data, uint16_t *size)
+{
+ struct pklg_pkt pkt;
+ uint32_t toread;
+ uint64_t ts;
+ ssize_t len;
+
+ len = read(btsnoop->fd, &pkt, PKLG_PKT_SIZE);
+ if (len == 0)
+ return false;
+
+ if (len < 0 || len != PKLG_PKT_SIZE) {
+ btsnoop->aborted = true;
+ return false;
+ }
+
+ toread = be32toh(pkt.len) - 9;
+
+ ts = be64toh(pkt.ts);
+ tv->tv_sec = ts >> 32;
+ tv->tv_usec = ts & 0xffffffff;
+
+ *index = 0;
+ *opcode = get_opcode_from_pklg(pkt.type);
+
+ len = read(btsnoop->fd, data, toread);
+ if (len < 0) {
+ btsnoop->aborted = true;
+ return false;
+ }
+
+ *size = toread;
+
+ return true;
+}
+
static uint16_t get_opcode_from_flags(uint8_t type, uint32_t flags)
{
switch (type) {
@@ -306,7 +385,7 @@ static uint16_t get_opcode_from_flags(uint8_t type, uint32_t flags)
break;
}
- return 0xff;
+ return 0xffff;
}
bool btsnoop_read_hci(struct btsnoop *btsnoop, struct timeval *tv,
@@ -322,6 +401,9 @@ bool btsnoop_read_hci(struct btsnoop *btsnoop, struct timeval *tv,
if (!btsnoop || btsnoop->aborted)
return false;
+ if (btsnoop->pklg_format)
+ return pklg_read_hci(btsnoop, tv, index, opcode, data, size);
+
len = read(btsnoop->fd, &pkt, BTSNOOP_PKT_SIZE);
if (len == 0)
return false;
diff --git a/src/shared/btsnoop.h b/src/shared/btsnoop.h
index 7f1481061..2c55d02a2 100644
--- a/src/shared/btsnoop.h
+++ b/src/shared/btsnoop.h
@@ -33,6 +33,8 @@
#define BTSNOOP_TYPE_MONITOR 2001
#define BTSNOOP_TYPE_SIMULATOR 2002
+#define BTSNOOP_FLAG_PKLG_SUPPORT (1 << 0)
+
#define BTSNOOP_OPCODE_NEW_INDEX 0
#define BTSNOOP_OPCODE_DEL_INDEX 1
#define BTSNOOP_OPCODE_COMMAND_PKT 2
@@ -51,7 +53,7 @@ struct btsnoop_opcode_new_index {
struct btsnoop;
-struct btsnoop *btsnoop_open(const char *path);
+struct btsnoop *btsnoop_open(const char *path, unsigned long flags);
struct btsnoop *btsnoop_create(const char *path, uint32_t type);
struct btsnoop *btsnoop_ref(struct btsnoop *btsnoop);