diff --git a/tools/hcidump.c b/tools/hcidump.c
index 35e73c0..fe78301 100644
--- a/tools/hcidump.c
+++ b/tools/hcidump.c
static int device;
static int snap_len = SNAP_LEN;
static int mode = PARSE;
-static long flags;
-static long filter;
+static long flags;
+static long filter;
static char *dump_file;
static void process_frames(int dev, int sock, int file)
case HCI_CMSG_DIR:
frm.in = *((int *)CMSG_DATA(cmsg));
break;
+ case HCI_CMSG_TSTAMP:
+ frm.ts = *((struct timeval *)CMSG_DATA(cmsg));
+ break;
}
cmsg = CMSG_NXTHDR(&msg, cmsg);
}
/* Save dump */
dh->len = __cpu_to_le16(frm.data_len);
dh->in = frm.in;
+ dh->ts_sec = __cpu_to_le32(frm.ts.tv_sec);
+ dh->ts_usec = __cpu_to_le32(frm.ts.tv_usec);
if (write_n(file, buf, frm.data_len + DUMP_HDR_SIZE) < 0) {
perror("Write error");
exit(1);
frm.ptr = frm.data;
frm.len = frm.data_len;
frm.in = dh.in;
+ frm.ts.tv_sec = __le32_to_cpu(dh.ts_sec);
+ frm.ts.tv_usec = __le32_to_cpu(dh.ts_usec);
parse(&frm);
}
exit(1);
}
+ opt = 1;
+ if (setsockopt(s, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
+ perror("Can't enable time stamp");
+ exit(1);
+ }
+
/* Setup filter */
flt.type_mask = ~0; // All packet types
flt.event_mask[0] = ~0L; // All events
{"snap-len", 's', "len", 0, "Snap len (in bytes)", 1 },
{"save-dump", 'w', "file", 0, "Save dump to a file", 2 },
{"read-dump", 'r', "file", 0, "Read dump from a file", 2 },
+ {"ts", 't', 0, 0, "Display time stamps", 2 },
{"hex", 'x', 0, 0, "Dump data in hex", 3 },
{"ascii", 'a', 0, 0, "Dump data in ascii", 3 },
{"raw", 'R', 0, 0, "Raw mode", 4 },
snap_len = atoi(arg);
break;
+ case 't':
+ flags |= DUMP_TSTAMP;
+ break;
+
case 'R':
flags |= DUMP_HEX;
mode = RAW;
diff --git a/tools/parser/hci.c b/tools/parser/hci.c
index 996082f..6b24418 100644
--- a/tools/parser/hci.c
+++ b/tools/parser/hci.c
break;
}
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("HCI Command: %s(0x%2.2x|0x%4.4x) plen %d\n",
cmd, ogf, ocf, hdr->plen);
if (p_filter(FILT_HCI))
return;
- p_indent(level, frm->in);
+ p_indent(level, frm);
if (hdr->evt <= EVENT_NUM)
printf("HCI Event: %s(0x%2.2x) plen %d\n",
__u8 flags = acl_flags(handle);
if (!p_filter(FILT_HCI)) {
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("ACL data: handle 0x%4.4x flags 0x%2.2x dlen %d\n",
acl_handle(handle), flags, dlen);
level++;
__u16 handle = __le16_to_cpu(hdr->handle);
if (!p_filter(FILT_SCO)) {
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("SCO data: handle 0x%4.4x dlen %d\n",
acl_handle(handle), hdr->dlen);
level++;
if (p_filter(FILT_HCI))
break;
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("Unknown: type 0x%2.2x len %d\n", type, frm->len);
raw_dump(level, frm);
break;
diff --git a/tools/parser/l2cap.c b/tools/parser/l2cap.c
index a35a6c3..8d73641 100644
--- a/tools/parser/l2cap.c
+++ b/tools/parser/l2cap.c
frm->len -= L2CAP_CMD_HDR_SIZE;
if (!p_filter(FILT_L2CAP)) {
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("L2CAP(s): ");
}
psm = btohs(*(__u16*)frm->ptr);
frm->len -= 2;
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("L2CAP(c): cid 0x%x len %d psm %d\n", cid, dlen, psm);
raw_dump(level, frm);
} else {
__u16 psm = get_psm(!frm->in, cid);
if (!p_filter(FILT_L2CAP)) {
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("L2CAP(d): cid 0x%x len %d [psm %d]\n",
cid, dlen, psm);
level++;
fr->len = frm->len;
fr->ptr = fr->data;
fr->in = frm->in;
+ fr->ts = frm->ts;
} else {
if (!(fr = get_frame(frm->handle))) {
fprintf(stderr, "Not enough connetion handles\n");
diff --git a/tools/parser/parser.h b/tools/parser/parser.h
index b3351cd..dae3a0f 100644
--- a/tools/parser/parser.h
+++ b/tools/parser/parser.h
*/
struct frame {
- void *data;
- int data_len;
- void *ptr;
- int len;
- int in;
- int handle;
- long flags;
+ void *data;
+ int data_len;
+ void *ptr;
+ int len;
+ int in;
+ int handle;
+ long flags;
+ struct timeval ts;
};
/* Parser flags */
#define DUMP_HEX 0x01
#define DUMP_ASCII 0x02
#define DUMP_TYPE_MASK (DUMP_HEX | DUMP_ASCII)
+#define DUMP_TSTAMP 0x04
/* Parser filter */
#define FILT_HCI 0x0001
return !(parser.filter & f);
}
-static inline void p_indent(int level, int in)
+static inline void p_indent(int level, struct frame *f)
{
if (level < 0) {
parser.state = 0;
}
if (!parser.state) {
- printf("%c ", (in ? '>' : '<'));
+ if (parser.flags & DUMP_TSTAMP)
+ printf("%ld.%ld ", f->ts.tv_sec, f->ts.tv_usec);
+
+ printf("%c ", (f->in ? '>' : '<'));
parser.state = 1;
} else
printf(" ");
diff --git a/tools/parser/rfcomm.c b/tools/parser/rfcomm.c
index 1751526..f50e632 100644
--- a/tools/parser/rfcomm.c
+++ b/tools/parser/rfcomm.c
frm->ptr += hdr_size;
frm->len -= hdr_size;
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("RFCOMM(s): ");
switch (mcc_head.type.type) {
if (!head->addr.server_chn) {
mcc_frame(level, frm, head);
} else {
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("RFCOMM(d): UIH: ");
print_rfcomm_hdr(head, frm->ptr, frm->len);
printf("\n");
if (ctr_type == UIH) {
uih_frame(level, frm, &head);
} else {
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("RFCOMM(s): ");
switch (ctr_type) {
diff --git a/tools/parser/sdp.c b/tools/parser/sdp.c
index 5c29ba4..0b04fac 100644
--- a/tools/parser/sdp.c
+++ b/tools/parser/sdp.c
int n1;
int n2;
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("pat");
if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) {
int n2;
int len = frm->len;
- p_indent(level, frm->in);
+ p_indent(level, frm);
printf("aid(s)");
if (parse_de_hdr(frm, &n1) == SDP_DE_SEQ) {
frm->ptr += SDP_PDU_HDR_SIZE;
frm->len -= SDP_PDU_HDR_SIZE;
- p_indent(level, frm->in);
+ p_indent(level, frm);
switch (hdr->pid) {
case SDP_ERROR_RSP:
if (hdr->pid != SDP_ERROR_RSP) {
/* Parse ContinuationState */
if (*(__u8*) frm->ptr) {
- p_indent(++level, frm->in);
+ p_indent(++level, frm);
printf("cont ");
raw_dump(0, frm);
}