#include <sys/stat.h>
#include <arpa/inet.h>
+#include "packet.h"
#include "btsnoop.h"
static inline uint64_t ntoh64(uint64_t n)
0x6f, 0x6f, 0x70, 0x00 };
static const uint32_t btsnoop_version = 1;
-static const uint32_t btsnoop_type = 1001;
+static const uint32_t btsnoop_type = 2001;
static int btsnoop_fd = -1;
static uint16_t btsnoop_index = 0xffff;
void btsnoop_open(const char *path)
{
+ struct btsnoop_hdr hdr;
+ ssize_t written;
+
if (btsnoop_fd >= 0)
return;
btsnoop_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (btsnoop_fd < 0)
+ return;
+
+ memcpy(hdr.id, btsnoop_id, sizeof(btsnoop_id));
+ hdr.version = htonl(btsnoop_version);
+ hdr.type = htonl(btsnoop_type);
+
+ written = write(btsnoop_fd, &hdr, BTSNOOP_HDR_SIZE);
+ if (written < 0)
+ return;
}
-void btsnoop_write(struct timeval *tv, uint16_t index, uint32_t flags,
+void btsnoop_write(struct timeval *tv, uint16_t index, uint16_t opcode,
const void *data, uint16_t size)
{
- struct btsnoop_hdr hdr;
struct btsnoop_pkt pkt;
+ uint32_t flags;
uint64_t ts;
ssize_t written;
if (btsnoop_fd < 0)
return;
- if (btsnoop_index == 0xffff) {
- memcpy(hdr.id, btsnoop_id, sizeof(btsnoop_id));
- hdr.version = htonl(btsnoop_version);
- hdr.type = htonl(btsnoop_type);
+ switch (btsnoop_type) {
+ case 1001:
+ if (btsnoop_index == 0xffff)
+ btsnoop_index = index;
- written = write(btsnoop_fd, &hdr, BTSNOOP_HDR_SIZE);
- if (written < 0)
+ if (index != btsnoop_index)
return;
- btsnoop_index = index;
- }
+ flags = packet_get_flags(opcode);
+ if (flags == 0xff)
+ return;
+ break;
+
+ case 2001:
+ flags = (index << 16) | opcode;
+ break;
- if (index != btsnoop_index)
+ default:
return;
+ }
ts = (tv->tv_sec - 946684800ll) * 1000000ll + tv->tv_usec;
#include <sys/time.h>
void btsnoop_open(const char *path);
-void btsnoop_write(struct timeval *tv, uint16_t index, uint32_t flags,
+void btsnoop_write(struct timeval *tv, uint16_t index, uint16_t opcode,
const void *data, uint16_t size);
void btsnoop_close(void);
#include "mainloop.h"
#include "packet.h"
+#include "btsnoop.h"
#include "control.h"
struct control_data {
break;
case HCI_CHANNEL_MONITOR:
packet_monitor(tv, index, opcode, buf, pktlen);
+ btsnoop_write(tv, index, opcode, buf, pktlen);
break;
}
}
"Usage:\n");
printf("\tbtmon [options]\n");
printf("options:\n"
- "\t-b, --btsnoop <file> Save dump in btsnoop format\n"
- "\t-s, --server <path> Start monitor server socket\n"
- "\t-h, --help Show help options\n");
+ "\t-w, --write <file> Save traces in btsnoop format\n"
+ "\t-s, --server <socket> Start monitor server socket\n"
+ "\t-h, --help Show help options\n");
}
static const struct option main_options[] = {
- { "btsnoop", required_argument, NULL, 'b' },
- { "server", required_argument, NULL, 'r' },
- { "version", no_argument, NULL, 'v' },
- { "help", no_argument, NULL, 'h' },
+ { "write", required_argument, NULL, 'b' },
+ { "server", required_argument, NULL, 'r' },
+ { "version", no_argument, NULL, 'v' },
+ { "help", no_argument, NULL, 'h' },
{ }
};
for (;;) {
int opt;
- opt = getopt_long(argc, argv, "b:s:vh", main_options, NULL);
+ opt = getopt_long(argc, argv, "w:s:vh", main_options, NULL);
if (opt < 0)
break;
switch (opt) {
- case 'b':
+ case 'w':
btsnoop_open(optarg);
break;
case 's':
#include <bluetooth/hci_lib.h>
#include "control.h"
-#include "btsnoop.h"
#include "packet.h"
static unsigned long filter_mask = 0;
static struct monitor_new_index index_list[MAX_INDEX];
+uint32_t packet_get_flags(uint16_t opcode)
+{
+ switch (opcode) {
+ case MONITOR_NEW_INDEX:
+ case MONITOR_DEL_INDEX:
+ break;
+ case MONITOR_COMMAND_PKT:
+ return 0x02;
+ case MONITOR_EVENT_PKT:
+ return 0x03;
+ case MONITOR_ACL_TX_PKT:
+ return 0x00;
+ case MONITOR_ACL_RX_PKT:
+ return 0x01;
+ case MONITOR_SCO_TX_PKT:
+ case MONITOR_SCO_RX_PKT:
+ break;
+ }
+
+ return 0xff;
+}
+
void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode,
const void *data, uint16_t size)
{
uint16_t ogf = cmd_opcode_ogf(opcode);
uint16_t ocf = cmd_opcode_ocf(opcode);
- btsnoop_write(tv, index, 0x02, data, size);
-
print_header(tv, index);
if (size < HCI_COMMAND_HDR_SIZE) {
{
const hci_event_hdr *hdr = data;
- btsnoop_write(tv, index, 0x03, data, size);
-
print_header(tv, index);
if (size < HCI_EVENT_HDR_SIZE) {
uint16_t dlen = btohs(hdr->dlen);
uint8_t flags = acl_flags(handle);
- btsnoop_write(tv, index, in ? 0x01 : 0x00, data, size);
-
print_header(tv, index);
if (size < HCI_ACL_HDR_SIZE) {
void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode,
const void *data, uint16_t size);
+uint32_t packet_get_flags(uint16_t opcode);
+
void packet_new_index(struct timeval *tv, uint16_t index, const char *label,
uint8_t type, uint8_t bus, const char *name);
void packet_del_index(struct timeval *tv, uint16_t index, const char *label);