diff --git a/tools/hcidump.c b/tools/hcidump.c
index 8a76556..bad6107 100644
--- a/tools/hcidump.c
+++ b/tools/hcidump.c
{
printf("HCIDump - HCI packet analyzer ver %s\n", VERSION);
printf("Usage:\n");
- printf("\thcidump <-i hciX> [-ah]\n");
+ printf("\thcidump <-i hciX> [-ah] [-w file] [-r file]\n");
}
void process_frames(int dev, int sock, int file)
{
- char *data, *ctrl, *frame;
+ char *buf, *data, *ctrl;
struct cmsghdr *cmsg;
struct msghdr msg;
struct iovec iv;
if (snap_len < SNAP_LEN)
snap_len = SNAP_LEN;
- if (!(data = malloc(snap_len + DUMP_HDR_SIZE))) {
+ if (!(buf = malloc(snap_len + DUMP_HDR_SIZE))) {
perror("Can't allocate data buffer");
exit(1);
}
- dh = (void *) data;
- frame = data + DUMP_HDR_SIZE;
+ dh = (void *) buf;
+ data = buf + DUMP_HDR_SIZE;
if (!(ctrl = malloc(100))) {
perror("Can't allocate control buffer");
printf("device: hci%d snap_len: %d filter: none\n", dev, snap_len);
while (1) {
- iv.iov_base = frame;
+ iv.iov_base = data;
iv.iov_len = snap_len;
msg.msg_iov = &iv;
}
if (file == -1) {
- /* Parse and print */
- parse(in, frame, len);
+ /* Parse and print */
+ struct frame frm;
+
+ frm.data = frm.ptr = data;
+ frm.data_len = frm.len = len;
+ frm.in = in;
+ frm.flags = 0;
+
+ parse(&frm);
} else {
/* Save dump */
dh->len = __cpu_to_le16(len);
}
while (1) {
+ struct frame frm;
int len;
if ((err = read_n(file, (void *) &dh, DUMP_HDR_SIZE)) < 0)
goto failed;
if (!err) return;
- parse(dh.in, data, len);
+ frm.data = frm.ptr = data;
+ frm.data_len = frm.len = len;
+ frm.in = dh.in;
+ frm.flags = 0;
+
+ parse(&frm);
}
failed:
diff --git a/tools/parser/hci.c b/tools/parser/hci.c
index a5bf52b..93b3772 100644
--- a/tools/parser/hci.c
+++ b/tools/parser/hci.c
};
#define CMD_STATUS_NUM 5
-static inline void command_dump(void *ptr, int len)
+static inline void command_dump(struct frame *frm)
{
- hci_command_hdr *hdr = ptr;
+ hci_command_hdr *hdr = frm->ptr;
__u16 opcode = __le16_to_cpu(hdr->opcode);
__u16 ogf = cmd_opcode_ogf(opcode);
__u16 ocf = cmd_opcode_ocf(opcode);
char *cmd;
- ptr += HCI_COMMAND_HDR_SIZE;
- len -= HCI_COMMAND_HDR_SIZE;
+ frm->ptr += HCI_COMMAND_HDR_SIZE;
+ frm->len -= HCI_COMMAND_HDR_SIZE;
switch (ogf) {
case OGF_INFO_PARAM:
}
printf("HCI Command: %s(0x%2.2x|0x%4.4x) plen %d\n", cmd, ogf, ocf, hdr->plen);
- raw_dump(1, ptr, len);
+ raw_dump(1, frm);
}
-static inline void event_dump(void *ptr, int len)
+static inline void event_dump(struct frame *frm)
{
- hci_event_hdr *hdr = ptr;
+ hci_event_hdr *hdr = frm->ptr;
- ptr += HCI_EVENT_HDR_SIZE;
- len -= HCI_EVENT_HDR_SIZE;
+ frm->ptr += HCI_EVENT_HDR_SIZE;
+ frm->len -= HCI_EVENT_HDR_SIZE;
if (hdr->evt <= EVENT_NUM)
printf("HCI Event: %s(0x%2.2x) plen %d\n",
event_map[hdr->evt], hdr->evt, hdr->plen);
else
printf("HCI Event: code 0x%2.2x plen %d\n", hdr->evt, hdr->plen);
- raw_dump(1, ptr, len);
+ raw_dump(1, frm);
}
-static inline void acl_dump(void *ptr, int len)
+static inline void acl_dump(struct frame *frm)
{
- hci_acl_hdr *hdr = ptr;
+ hci_acl_hdr *hdr = (void *) frm->ptr;
__u16 handle = __le16_to_cpu(hdr->handle);
__u16 dlen = __le16_to_cpu(hdr->dlen);
__u8 flags = acl_flags(handle);
printf("ACL data: handle 0x%4.4x flags 0x%2.2x dlen %d\n",
acl_handle(handle), flags, dlen);
- ptr += HCI_ACL_HDR_SIZE;
- len -= HCI_ACL_HDR_SIZE;
-
+ frm->ptr += HCI_ACL_HDR_SIZE;
+ frm->len -= HCI_ACL_HDR_SIZE;
+ frm->flags = flags;
+
if (flags & ACL_START) {
- l2cap_dump(1, ptr, len, flags);
+ l2cap_dump(1, frm);
} else {
- raw_dump(1, ptr, len);
+ raw_dump(1, frm);
}
}
-void hci_dump(int level, __u8 *data, int len)
+void hci_dump(int level, struct frame *frm)
{
- unsigned char *ptr = data;
- __u8 type;
+ __u8 type = *(__u8 *)frm->ptr;
- type = *ptr++; len--;
+ frm->ptr++; frm->len--;
switch (type) {
case HCI_COMMAND_PKT:
- command_dump(ptr, len);
+ command_dump(frm);
break;
case HCI_EVENT_PKT:
- event_dump(ptr, len);
+ event_dump(frm);
break;
case HCI_ACLDATA_PKT:
- acl_dump(ptr, len);
+ acl_dump(frm);
break;
default:
- printf("Unknown: type 0x%2.2x len %d\n", type, len);
- raw_dump(1, ptr, len);
+ printf("Unknown: type 0x%2.2x len %d\n", type, frm->len);
+ raw_dump(1, frm);
break;
}
}
diff --git a/tools/parser/l2cap.c b/tools/parser/l2cap.c
index 468115f..0f725e8 100644
--- a/tools/parser/l2cap.c
+++ b/tools/parser/l2cap.c
#include "parser.h"
-static inline void command_rej(int level, __u8 *ptr, int len)
+static inline void command_rej(int level, struct frame *frm)
{
- l2cap_cmd_rej *h = (void *) ptr;
+ l2cap_cmd_rej *h = frm->ptr;
printf("Command rej: reason %d\n",
btohs(h->reason));
}
-static inline void conn_req(int level, __u8 *ptr, int len)
+static inline void conn_req(int level, struct frame *frm)
{
- l2cap_conn_req *h = (void *) ptr;
+ l2cap_conn_req *h = frm->ptr;
printf("Connect req: psm %d scid 0x%4.4x\n",
btohs(h->psm), btohs(h->scid));
}
-static inline void conn_rsp(int level, __u8 *ptr, int len)
+static inline void conn_rsp(int level, struct frame *frm)
{
- l2cap_conn_rsp *h = (void *) ptr;
+ l2cap_conn_rsp *h = frm->ptr;
printf("Connect rsp: dcid 0x%4.4x scid 0x%4.4x result %d status %d\n",
btohs(h->dcid), btohs(h->scid),
btohs(h->result), btohs(h->status));
return 0;
}
-static void conf_opt(int level, __u8 *ptr, int len)
+static void conf_opt(int level, void *ptr, int len)
{
indent(level);
while (len > 0) {
- l2cap_conf_opt *h = (void *) ptr;
+ l2cap_conf_opt *h = ptr;
ptr += L2CAP_CONF_OPT_SIZE + h->len;
len -= L2CAP_CONF_OPT_SIZE + h->len;
printf("\n");
}
-static inline void conf_req(int level, l2cap_cmd_hdr *cmd, __u8 *ptr, int len)
+static inline void conf_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
- l2cap_conf_req *h = (void *) ptr;
+ l2cap_conf_req *h = frm->ptr;
int clen = btohs(cmd->len) - L2CAP_CONF_REQ_SIZE;
printf("Config req: dcid 0x%4.4x flags 0x%4.4x clen %d\n",
btohs(h->dcid), btohs(h->flags), clen);
conf_opt(level+1, h->data, clen);
}
-static inline void conf_rsp(int level, l2cap_cmd_hdr *cmd, __u8 *ptr, int len)
+static inline void conf_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
- l2cap_conf_rsp *h = (void *) ptr;
+ l2cap_conf_rsp *h = frm->ptr;
int clen = btohs(cmd->len) - L2CAP_CONF_RSP_SIZE;
printf("Config rsp: scid 0x%4.4x flags 0x%4.4x result %d clen %d\n",
btohs(h->scid), btohs(h->flags), btohs(h->result), clen);
conf_opt(level+1, h->data, clen);
}
-static inline void disconn_req(int level, __u8 *ptr, int len)
+static inline void disconn_req(int level, struct frame *frm)
{
- l2cap_disconn_req *h = (void *) ptr;
+ l2cap_disconn_req *h = frm->ptr;
printf("Disconn req: dcid 0x%4.4x scid 0x%4.4x\n",
btohs(h->dcid), btohs(h->scid));
}
-static inline void disconn_rsp(int level, __u8 *ptr, int len)
+static inline void disconn_rsp(int level, struct frame *frm)
{
- l2cap_disconn_rsp *h = (void *) ptr;
+ l2cap_disconn_rsp *h = frm->ptr;
printf("Disconn rsp: dcid 0x%4.4x scid 0x%4.4x\n",
btohs(h->dcid), btohs(h->scid));
}
-static inline void echo_req(int level, l2cap_cmd_hdr *cmd, __u8 *ptr, int len)
+static inline void echo_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
printf("Echo req: dlen %d\n",
btohs(cmd->len));
- raw_dump(level, ptr, len);
+ raw_dump(level, frm);
}
-static inline void echo_rsp(int level, l2cap_cmd_hdr *cmd, __u8 *ptr, int len)
+static inline void echo_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
printf("Echo rsp: dlen %d\n",
btohs(cmd->len));
- raw_dump(level, ptr, len);
+ raw_dump(level, frm);
}
-static inline void info_req(int level, l2cap_cmd_hdr *cmd, __u8 *ptr, int len)
+static inline void info_req(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
printf("Info req: dlen %d\n",
btohs(cmd->len));
- raw_dump(level, ptr, len);
+ raw_dump(level, frm);
}
-static inline void info_rsp(int level, l2cap_cmd_hdr *cmd, __u8 *ptr, int len)
+static inline void info_rsp(int level, l2cap_cmd_hdr *cmd, struct frame *frm)
{
printf("Info rsp: dlen %d\n",
btohs(cmd->len));
- raw_dump(level, ptr, len);
+ raw_dump(level, frm);
}
-void l2cap_dump(int level, __u8 *ptr, int len, __u8 flags)
+void l2cap_dump(int level, struct frame *frm)
{
- l2cap_hdr *hdr = (void *) ptr;
+ l2cap_hdr *hdr = frm->ptr;
__u16 dlen = btohs(hdr->len);
__u16 cid = btohs(hdr->cid);
- ptr += L2CAP_HDR_SIZE;
- len -= L2CAP_HDR_SIZE;
+ frm->ptr += L2CAP_HDR_SIZE;
+ frm->len -= L2CAP_HDR_SIZE;
indent(level);
if (cid == 0x1) {
- l2cap_cmd_hdr *hdr = (void *) ptr;
+ l2cap_cmd_hdr *hdr = frm->ptr;
- ptr += L2CAP_CMD_HDR_SIZE;
- len -= L2CAP_CMD_HDR_SIZE;
+ frm->ptr += L2CAP_CMD_HDR_SIZE;
+ frm->len -= L2CAP_CMD_HDR_SIZE;
printf("L2CAP(s): ");
switch (hdr->code) {
case L2CAP_COMMAND_REJ:
- command_rej(level, ptr, len);
+ command_rej(level, frm);
break;
case L2CAP_CONN_REQ:
- conn_req(level, ptr, len);
+ conn_req(level, frm);
break;
case L2CAP_CONN_RSP:
- conn_rsp(level, ptr, len);
+ conn_rsp(level, frm);
break;
case L2CAP_CONF_REQ:
- conf_req(level, hdr, ptr, len);
+ conf_req(level, hdr, frm);
break;
case L2CAP_CONF_RSP:
- conf_rsp(level, hdr, ptr, len);
+ conf_rsp(level, hdr, frm);
break;
case L2CAP_DISCONN_REQ:
- disconn_req(level, ptr, len);
+ disconn_req(level, frm);
break;
case L2CAP_DISCONN_RSP:
- disconn_rsp(level, ptr, len);
+ disconn_rsp(level, frm);
break;
case L2CAP_ECHO_REQ:
- echo_req(level, hdr, ptr, len);
+ echo_req(level, hdr, frm);
break;
case L2CAP_ECHO_RSP:
- echo_rsp(level, hdr, ptr, len);
+ echo_rsp(level, hdr, frm);
break;
case L2CAP_INFO_REQ:
- info_req(level, hdr, ptr, len);
+ info_req(level, hdr, frm);
break;
case L2CAP_INFO_RSP:
- info_rsp(level, hdr, ptr, len);
+ info_rsp(level, hdr, frm);
break;
default:
printf("code 0x%2.2x ident %d len %d\n",
hdr->code, hdr->ident, btohs(hdr->len));
- raw_dump(level, ptr, len);
+ raw_dump(level, frm);
}
} else {
printf("L2CAP(d): cid 0x%x len %d\n", cid, dlen);
- raw_dump(level, ptr, len);
+ raw_dump(level, frm);
}
}
diff --git a/tools/parser/parser.c b/tools/parser/parser.c
index 6ae5225..0decd04 100644
--- a/tools/parser/parser.c
+++ b/tools/parser/parser.c
printf("\n");
}
-void raw_dump(int level, unsigned char *buf, int len)
+void raw_dump(int level, struct frame *frm)
{
switch (parser_flags & DUMP_TYPE_MASK) {
case DUMP_HEX:
- hex_dump(level, buf, len);
+ hex_dump(level, frm->ptr, frm->len);
break;
case DUMP_ASCII:
- ascii_dump(level, buf, len);
+ ascii_dump(level, frm->ptr, frm->len);
break;
}
}
diff --git a/tools/parser/parser.h b/tools/parser/parser.h
index a2d0b34..401d3ca 100644
--- a/tools/parser/parser.h
+++ b/tools/parser/parser.h
#define DUMP_ASCII 0x02
#define DUMP_TYPE_MASK (DUMP_HEX | DUMP_ASCII)
-#define indent(l) printf("%*c", (l*2), ' ')
+struct frame {
+ void *data;
+ int data_len;
+ void *ptr;
+ int len;
+ int in;
+ long flags;
+};
void init_parser(long flags);
-void raw_dump(int level, __u8 *data, int len);
-void hci_dump(int level, __u8 *data, int len);
-void l2cap_dump(int level, __u8 *data, int len, __u8 flags);
+void raw_dump(int level, struct frame *frm);
+void hci_dump(int level, struct frame *frm);
+void l2cap_dump(int level, struct frame *frm);
-static inline void parse(int in, char *data, int len)
+static inline void indent(int level)
{
- printf("%c ", (in ? '>' : '<'));
- hci_dump(0, data, len);
+ printf("%*c", (level*2), ' ');
+}
+
+static inline void parse(struct frame *frm)
+{
+ printf("%c ", (frm->in ? '>' : '<'));
+ hci_dump(0, frm);
fflush(stdout);
}