OSDN Git Service

Clean up btsnoop code.
authorSharvil Nanavati <sharvil@google.com>
Sun, 15 Jun 2014 06:45:16 +0000 (23:45 -0700)
committerSharvil Nanavati <sharvil@google.com>
Thu, 19 Jun 2014 20:13:14 +0000 (20:13 +0000)
Change-Id: Icb1dacb95453effa6d267c084353608dbdc915a3

hci/Android.mk
hci/include/bt_hci_bdroid.h
hci/include/btsnoop.h [new file with mode: 0644]
hci/src/bt_hci_bdroid.c
hci/src/btsnoop.c
hci/src/btsnoop_net.c
hci/src/hci_h4.c
hci/src/hci_mct.c

index 7f6113a..fac6a42 100644 (file)
@@ -28,6 +28,7 @@ LOCAL_CFLAGS += -std=c99
 
 LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/include \
+       $(LOCAL_PATH)/../osi/include \
        $(LOCAL_PATH)/../utils/include
 
 LOCAL_MODULE := libbt-hci
index 7b23851..a3c2028 100644 (file)
 #define BTHC_USERIAL_READ_MEM_SIZE (1024)
 #endif
 
-#ifndef BTSNOOPDISP_INCLUDED
-#define BTSNOOPDISP_INCLUDED TRUE
-#endif
-
-/* Disable external parser for production */
-#ifndef BTSNOOP_EXT_PARSER_INCLUDED
-#define BTSNOOP_EXT_PARSER_INCLUDED FALSE
-#endif
-
 /* Host/Controller lib internal event ID */
 #define HC_EVENT_PRELOAD               0x0001
 #define HC_EVENT_POSTLOAD              0x0002
diff --git a/hci/include/btsnoop.h b/hci/include/btsnoop.h
new file mode 100644 (file)
index 0000000..4f2d23b
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <stdbool.h>
+
+void btsnoop_open(const char *p_path);
+void btsnoop_close(void);
+
+void btsnoop_capture(const HC_BT_HDR *p_buf, bool is_rcvd);
index 7cd422e..88fc743 100644 (file)
@@ -36,6 +36,7 @@
 #include "hci.h"
 #include "userial.h"
 #include "bt_utils.h"
+#include "btsnoop.h"
 #include <sys/prctl.h>
 
 #ifndef BTHC_DBG
@@ -66,8 +67,6 @@ void lpm_wake_deassert(void);
 void lpm_allow_bt_device_sleep(void);
 void lpm_wake_assert(void);
 void init_vnd_if(unsigned char *local_bdaddr);
-void btsnoop_open(char *p_path);
-void btsnoop_close(void);
 
 /******************************************************************************
 **  Variables
index e4b1376..1d9bcb7 100644 (file)
  *
  ******************************************************************************/
 
-/****************************************************************************
- *
- *  Name:       btsnoopdisp.c
- *
- *  Function:   this file contains functions to generate a BTSNOOP file
- *
- *
- ****************************************************************************/
-#include <stdio.h>
-#include <dlfcn.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <pthread.h>
-#include <sys/prctl.h>
-#include <unistd.h>
+#define LOG_TAG "btsnoop"
+
+#include <arpa/inet.h>
+#include <assert.h>
 #include <ctype.h>
+#include <cutils/log.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netdb.h>
-
-/* for gettimeofday */
-#include <sys/time.h>
-/* for the S_* open parameters */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/stat.h>
-/* for write */
+#include <sys/time.h>
 #include <unistd.h>
-/* for O_* open parameters */
-#include <fcntl.h>
-/* defines the O_* open parameters */
-#include <fcntl.h>
-
-#define LOG_TAG "BTSNOOP-DISP"
-#include <cutils/log.h>
 
 #include "bt_hci_bdroid.h"
-#include "utils.h"
 #include "bt_utils.h"
-
-#ifndef BTSNOOP_DBG
-#define BTSNOOP_DBG FALSE
-#endif
-
-#if (BTSNOOP_DBG == TRUE)
-#define SNOOPDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
-#else
-#define SNOOPDBG(param, ...) {}
-#endif
+#include "utils.h"
 
 typedef enum {
   kCommandPacket = 1,
   kAclPacket = 2,
   kScoPacket = 3,
   kEventPacket = 4
-} packet_type;
-
-void btsnoop_net_init();
-void btsnoop_net_cleanup();
-void btsnoop_net_write(const void *data, size_t length);
-
-/* file descriptor of the BT snoop file (by default, -1 means disabled) */
-int hci_btsnoop_fd = -1;
-
-/* Macro to perform a multiplication of 2 unsigned 32bit values and store the result
- * in an unsigned 64 bit value (as two 32 bit variables):
- * u64 = u32In1 * u32In2
- * u32OutLow = u64[31:0]
- * u32OutHi = u64[63:32]
- * basically the algorithm:
- * (hi1*2^16 + lo1)*(hi2*2^16 + lo2) = lo1*lo2 + (hi1*hi2)*2^32 + (hi1*lo2 + hi2*lo1)*2^16
- * and the carry is propagated 16 bit by 16 bit:
- * result[15:0] = lo1*lo2 & 0xFFFF
- * result[31:16] = ((lo1*lo2) >> 16) + (hi1*lo2 + hi2*lo1)
- * and so on
- */
-#define HCIDISP_MULT_64(u32In1, u32In2, u32OutLo, u32OutHi)                             \
-do {                                                                                    \
-    uint32_t u32In1Tmp = u32In1;                                                          \
-    uint32_t u32In2Tmp = u32In2;                                                          \
-    uint32_t u32Tmp, u32Carry;                                                            \
-    u32OutLo = (u32In1Tmp & 0xFFFF) * (u32In2Tmp & 0xFFFF);              /*lo1*lo2*/    \
-    u32OutHi = ((u32In1Tmp >> 16) & 0xFFFF) * ((u32In2Tmp >> 16) & 0xFFFF); /*hi1*hi2*/ \
-    u32Tmp = (u32In1Tmp & 0xFFFF) * ((u32In2Tmp >> 16) & 0xFFFF);  /*lo1*hi2*/          \
-    u32Carry = (uint32_t)((u32OutLo>>16)&0xFFFF);                                         \
-    u32Carry += (u32Tmp&0xFFFF);                                                        \
-    u32OutLo += (u32Tmp << 16) ;                                                        \
-    u32OutHi += (u32Tmp >> 16);                                                         \
-    u32Tmp = ((u32In1Tmp >> 16) & 0xFFFF) * (u32In2Tmp & 0xFFFF);                       \
-    u32Carry += (u32Tmp)&0xFFFF;                                                        \
-    u32Carry>>=16;                                                                      \
-    u32OutLo += (u32Tmp << 16);                                                         \
-    u32OutHi += (u32Tmp >> 16);                                                         \
-    u32OutHi += u32Carry;                                                               \
-} while (0)
-
-/* Macro to make an addition of 2 64 bit values:
- * result = (u32OutHi & u32OutLo) + (u32InHi & u32InLo)
- * u32OutHi = result[63:32]
- * u32OutLo = result[31:0]
- */
-#define HCIDISP_ADD_64(u32InLo, u32InHi, u32OutLo, u32OutHi)                            \
-do {                                                                                    \
-    (u32OutLo) += (u32InLo);                                                            \
-    if ((u32OutLo) < (u32InLo)) (u32OutHi)++;                                           \
-    (u32OutHi) += (u32InHi);                                                            \
-} while (0)
+} packet_type_t;
 
-/* EPOCH in microseconds since 01/01/0000 : 0x00dcddb3.0f2f8000 */
-#define BTSNOOP_EPOCH_HI 0x00dcddb3U
-#define BTSNOOP_EPOCH_LO 0x0f2f8000U
+// Epoch in microseconds since 01/01/0000.
+static const uint64_t BTSNOOP_EPOCH_DELTA = 0x00dcddb30f2f8000ULL;
 
+// File descriptor for btsnoop file.
+static int hci_btsnoop_fd = -1;
 
-/*******************************************************************************
- **
- ** Function         tv_to_btsnoop_ts
- **
- ** Description      This function generate a BT Snoop timestamp.
- **
- ** Returns          void
- **
- ** NOTE
- ** The return value is 64 bit as 2 32 bit variables out_lo and * out_hi.
- ** A BT Snoop timestamp is the number of microseconds since 01/01/0000.
- ** The timeval structure contains the number of microseconds since EPOCH
- ** (01/01/1970) encoded as: tv.tv_sec, number of seconds since EPOCH and
- ** tv_usec, number of microseconds in current second
- **
- ** Therefore the algorithm is:
- **  result = tv.tv_sec * 1000000
- **  result += tv.tv_usec
- **  result += EPOCH_OFFSET
- *******************************************************************************/
-static void tv_to_btsnoop_ts(uint32_t *out_lo, uint32_t *out_hi, struct timeval *tv)
-{
-    /* multiply the seconds by 1000000 */
-    HCIDISP_MULT_64(tv->tv_sec, 0xf4240, *out_lo, *out_hi);
-
-    /* add the microseconds */
-    HCIDISP_ADD_64((uint32_t)tv->tv_usec, 0, *out_lo, *out_hi);
-
-    /* add the epoch */
-    HCIDISP_ADD_64(BTSNOOP_EPOCH_LO, BTSNOOP_EPOCH_HI, *out_lo, *out_hi);
-}
-
-/*******************************************************************************
- **
- ** Function         l_to_be
- **
- ** Description      Function to convert a 32 bit value into big endian format
- **
- ** Returns          32 bit value in big endian format
-*******************************************************************************/
-static uint32_t l_to_be(uint32_t x)
-{
-    #if __BIG_ENDIAN != TRUE
-    x = (x >> 24) |
-        ((x >> 8) & 0xFF00) |
-        ((x << 8) & 0xFF0000) |
-        (x << 24);
-    #endif
-    return x;
-}
-
-/*******************************************************************************
- **
- ** Function         btsnoop_is_open
- **
- ** Description      Function to check if BTSNOOP is open
- **
- ** Returns          1 if open otherwise 0
-*******************************************************************************/
-int btsnoop_is_open(void)
-{
-#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
-    SNOOPDBG("btsnoop_is_open: snoop fd = %d\n", hci_btsnoop_fd);
-
-    if (hci_btsnoop_fd != -1)
-    {
-        return 1;
-    }
-    return 0;
-#else
-    return 2;  /* Snoop not available  */
-#endif
-}
-
-/*******************************************************************************
- **
- ** Function         btsnoop_log_open
- **
- ** Description      Function to open the BTSNOOP file
- **
- ** Returns          None
-*******************************************************************************/
-static int btsnoop_log_open(char *btsnoop_logfile)
-{
-#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
-    hci_btsnoop_fd = -1;
-
-    SNOOPDBG("btsnoop_log_open: snoop log file = %s\n", btsnoop_logfile);
+void btsnoop_net_open();
+void btsnoop_net_close();
+void btsnoop_net_write(const void *data, size_t length);
 
-    /* write the BT snoop header */
-    if ((btsnoop_logfile != NULL) && (strlen(btsnoop_logfile) != 0))
-    {
-        hci_btsnoop_fd = open(btsnoop_logfile, \
-                              O_WRONLY|O_CREAT|O_TRUNC, \
-                              S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
-        if (hci_btsnoop_fd == -1)
-        {
-            perror("open");
-            SNOOPDBG("btsnoop_log_open: Unable to open snoop log file\n");
-            hci_btsnoop_fd = -1;
-            return 0;
-        }
-        write(hci_btsnoop_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16);
-        return 1;
-    }
-#endif
-    return 2;  /* Snoop not available  */
-}
+static uint64_t btsnoop_timestamp(void) {
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
 
-/*******************************************************************************
- **
- ** Function         btsnoop_log_close
- **
- ** Description      Function to close the BTSNOOP file
- **
- ** Returns          None
-*******************************************************************************/
-static int btsnoop_log_close(void)
-{
-#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
-    /* write the BT snoop header */
-    if (hci_btsnoop_fd != -1)
-    {
-        SNOOPDBG("btsnoop_log_close: Closing snoop log file\n");
-        close(hci_btsnoop_fd);
-        hci_btsnoop_fd = -1;
-        return 1;
-    }
-    return 0;
-#else
-    return 2;  /* Snoop not available  */
-#endif
+  // Timestamp is in microseconds.
+  uint64_t timestamp = tv.tv_sec * 1000 * 1000LL;
+  timestamp += tv.tv_usec;
+  timestamp += BTSNOOP_EPOCH_DELTA;
+  return timestamp;
 }
 
-/*******************************************************************************
- **
- ** Function         btsnoop_write
- **
- ** Description      Writes raw bytes to the BTSNOOP sinks.
- **
- ** Returns          None
-*******************************************************************************/
 static void btsnoop_write(const void *data, size_t length) {
-    if (hci_btsnoop_fd != -1) {
-        write(hci_btsnoop_fd, data, length);
-    }
-    btsnoop_net_write(data, length);
-}
-
-/*******************************************************************************
- **
- ** Function         btsnoop_write_packet
- **
- ** Description      Writes a single HCI packet to BTSNOOP sinks.
- **
- ** Returns          None
-*******************************************************************************/
-static void btsnoop_write_packet(packet_type type,
-                                 const uint8_t *packet,
-                                 bool is_received) {
-    int length_he;
-    int length;
-    int flags;
-    int drops = 0;
-    switch (type) {
-        case kCommandPacket:
-            length_he = packet[2] + 4;
-            flags = 2;
-            break;
-        case kAclPacket:
-            length_he = (packet[3] << 8) + packet[2] + 5;
-            flags = is_received;
-            break;
-        case kScoPacket:
-            length_he = packet[2] + 4;
-            flags = is_received;
-            break;
-        case kEventPacket:
-            length_he = packet[1] + 3;
-            flags = 3;
-            break;
-    }
-
-    uint32_t time_hi, time_lo;
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    tv_to_btsnoop_ts(&time_lo, &time_hi, &tv);
-
-    length = l_to_be(length_he);
-    flags = l_to_be(flags);
-    drops = l_to_be(drops);
-    time_hi = l_to_be(time_hi);
-    time_lo = l_to_be(time_lo);
-
-    /* since these display functions are called from different contexts */
-    utils_lock();
-
-    btsnoop_write(&length, 4);
-    btsnoop_write(&length, 4);
-    btsnoop_write(&flags, 4);
-    btsnoop_write(&drops, 4);
-    btsnoop_write(&time_hi, 4);
-    btsnoop_write(&time_lo, 4);
-    btsnoop_write(&type, 1);
-    btsnoop_write(packet, length_he - 1);
-
-    utils_unlock();
-}
-
-/********************************************************************************
- ** API allow external realtime parsing of output using e.g hcidump
- *********************************************************************************/
-
-#define EXT_PARSER_PORT 4330
-
-static pthread_t thread_id;
-static int s_listen = -1;
-static int ext_parser_fd = -1;
-
-static void ext_parser_detached(void);
-
-static int ext_parser_accept(int port)
-{
-    socklen_t           clilen;
-    struct sockaddr_in  cliaddr, servaddr;
-    int s, srvlen;
-    int n = 1;
-    int size_n;
-    int result = 0;
-
-    ALOGD("waiting for connection on port %d", port);
-
-    s_listen = socket(AF_INET, SOCK_STREAM, 0);
-
-    if (s_listen < 0)
-    {
-        ALOGE("listener not created: listen fd %d", s_listen);
-        return -1;
-    }
-
-    bzero(&servaddr, sizeof(servaddr));
-    servaddr.sin_family      = AF_INET;
-    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-    servaddr.sin_port        = htons(port);
-
-    srvlen = sizeof(servaddr);
-
-    /* allow reuse of sock addr upon bind */
-    result = setsockopt(s_listen, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
-
-    if (result<0)
-    {
-        perror("setsockopt");
-    }
-
-    result = bind(s_listen, (struct sockaddr *) &servaddr, srvlen);
-
-    if (result < 0)
-        perror("bind");
-
-    result = listen(s_listen, 1);
-
-    if (result < 0)
-        perror("listen");
-
-    clilen = sizeof(struct sockaddr_in);
-
-    s = accept(s_listen, (struct sockaddr *) &cliaddr, &clilen);
-
-    if (s < 0)
-    {
-        perror("accept");
-        return -1;
-    }
-
-    ALOGD("connected (%d)", s);
-
-    return s;
-}
-
-static int send_ext_parser(char *p, int len)
-{
-    int n;
-
-    /* check if io socket is connected */
-    if (ext_parser_fd == -1)
-        return 0;
-
-    SNOOPDBG("write %d to snoop socket\n", len);
-
-    n = write(ext_parser_fd, p, len);
-
-    if (n<=0)
-    {
-        ext_parser_detached();
-    }
-
-    return n;
-}
-
-static void ext_parser_detached(void)
-{
-    ALOGD("ext parser detached");
-
-    if (ext_parser_fd>0)
-        close(ext_parser_fd);
-
-    if (s_listen > 0)
-        close(s_listen);
-
-    ext_parser_fd = -1;
-    s_listen = -1;
-}
-
-static void interruptFn (int sig)
-{
-    UNUSED(sig);
-    ALOGD("interruptFn");
-    pthread_exit(0);
-}
-
-static void ext_parser_thread(void* param)
-{
-    int fd;
-    int sig = SIGUSR2;
-    sigset_t sigSet;
-    sigemptyset (&sigSet);
-    sigaddset (&sigSet, sig);
-    UNUSED(param);
-
-    ALOGD("ext_parser_thread");
-
-    prctl(PR_SET_NAME, (unsigned long)"BtsnoopExtParser", 0, 0, 0);
-
-    pthread_sigmask (SIG_UNBLOCK, &sigSet, NULL);
-
-    struct sigaction act;
-    act.sa_handler = interruptFn;
-    sigaction (sig, &act, NULL );
-
-    do
-    {
-        fd = ext_parser_accept(EXT_PARSER_PORT);
-
-        ext_parser_fd = fd;
-
-        ALOGD("ext parser attached on fd %d\n", ext_parser_fd);
-    } while (1);
-}
-
-void btsnoop_stop_listener(void)
-{
-    ALOGD("btsnoop_init");
-    ext_parser_detached();
-}
-
-void btsnoop_init(void)
-{
-#if defined(BTSNOOP_EXT_PARSER_INCLUDED) && (BTSNOOP_EXT_PARSER_INCLUDED == TRUE)
-    ALOGD("btsnoop_init");
-
-    /* always setup ext listener port */
-    if (pthread_create(&thread_id, NULL,
-                       (void*)ext_parser_thread,NULL)!=0)
-      perror("pthread_create");
-
-#endif
-    btsnoop_net_init();
-}
-
-void btsnoop_open(char *p_path)
-{
-#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
-    ALOGD("btsnoop_open");
-    btsnoop_log_open(p_path);
-#endif // BTSNOOPDISP_INCLUDED
-}
-
-void btsnoop_close(void)
-{
-#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
-    ALOGD("btsnoop_close");
-    btsnoop_log_close();
-#endif
-}
-
-void btsnoop_cleanup (void)
-{
-    btsnoop_net_cleanup();
-#if defined(BTSNOOP_EXT_PARSER_INCLUDED) && (BTSNOOP_EXT_PARSER_INCLUDED == TRUE)
-    ALOGD("btsnoop_cleanup");
-    pthread_kill(thread_id, SIGUSR2);
-    pthread_join(thread_id, NULL);
-    ext_parser_detached();
-#endif
-}
-
-
-void btsnoop_capture(HC_BT_HDR *p_buf, uint8_t is_rcvd)
-{
-    uint8_t *p = (uint8_t *)(p_buf + 1) + p_buf->offset;
-
-    SNOOPDBG("btsnoop_capture: fd = %d, type %x, rcvd %d, ext %d", \
-             hci_btsnoop_fd, p_buf->event, is_rcvd, ext_parser_fd);
-
-#if defined(BTSNOOP_EXT_PARSER_INCLUDED) && (BTSNOOP_EXT_PARSER_INCLUDED == TRUE)
-    if (ext_parser_fd > 0)
-    {
-        uint8_t tmp = *p;
-
-        /* borrow one byte for H4 packet type indicator */
-        p--;
-
-        switch (p_buf->event & MSG_EVT_MASK)
-        {
-              case MSG_HC_TO_STACK_HCI_EVT:
-                  *p = HCIT_TYPE_EVENT;
-                  break;
-              case MSG_HC_TO_STACK_HCI_ACL:
-              case MSG_STACK_TO_HC_HCI_ACL:
-                  *p = HCIT_TYPE_ACL_DATA;
-                  break;
-              case MSG_HC_TO_STACK_HCI_SCO:
-              case MSG_STACK_TO_HC_HCI_SCO:
-                  *p = HCIT_TYPE_SCO_DATA;
-                  break;
-              case MSG_STACK_TO_HC_HCI_CMD:
-                  *p = HCIT_TYPE_COMMAND;
-                  break;
-        }
-
-        send_ext_parser((char*)p, p_buf->len+1);
-        *(++p) = tmp;
-        return;
-    }
-#endif
-
-#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
-    if (hci_btsnoop_fd == -1)
-        return;
-
-    switch (p_buf->event & MSG_EVT_MASK)
-    {
-        case MSG_HC_TO_STACK_HCI_EVT:
-            SNOOPDBG("TYPE : EVT");
-            btsnoop_write_packet(kEventPacket, p, false);
-            break;
-        case MSG_HC_TO_STACK_HCI_ACL:
-        case MSG_STACK_TO_HC_HCI_ACL:
-            SNOOPDBG("TYPE : ACL");
-            btsnoop_write_packet(kAclPacket, p, is_rcvd);
-            break;
-        case MSG_HC_TO_STACK_HCI_SCO:
-        case MSG_STACK_TO_HC_HCI_SCO:
-            SNOOPDBG("TYPE : SCO");
-            btsnoop_write_packet(kScoPacket, p, is_rcvd);
-            break;
-        case MSG_STACK_TO_HC_HCI_CMD:
-            SNOOPDBG("TYPE : CMD");
-            btsnoop_write_packet(kCommandPacket, p, true);
-            break;
-    }
-#endif // BTSNOOPDISP_INCLUDED
+  if (hci_btsnoop_fd != -1)
+    write(hci_btsnoop_fd, data, length);
+
+  btsnoop_net_write(data, length);
+}
+
+static void btsnoop_write_packet(packet_type_t type, const uint8_t *packet, bool is_received) {
+  int length_he;
+  int length;
+  int flags;
+  int drops = 0;
+  switch (type) {
+    case kCommandPacket:
+      length_he = packet[2] + 4;
+      flags = 2;
+      break;
+    case kAclPacket:
+      length_he = (packet[3] << 8) + packet[2] + 5;
+      flags = is_received;
+      break;
+    case kScoPacket:
+      length_he = packet[2] + 4;
+      flags = is_received;
+      break;
+    case kEventPacket:
+      length_he = packet[1] + 3;
+      flags = 3;
+      break;
+  }
+
+  uint64_t timestamp = btsnoop_timestamp();
+  uint32_t time_hi = timestamp >> 32;
+  uint32_t time_lo = timestamp & 0xFFFFFFFF;
+
+  length = htonl(length_he);
+  flags = htonl(flags);
+  drops = htonl(drops);
+  time_hi = htonl(time_hi);
+  time_lo = htonl(time_lo);
+
+  // This function is called from different contexts.
+  utils_lock();
+
+  btsnoop_write(&length, 4);
+  btsnoop_write(&length, 4);
+  btsnoop_write(&flags, 4);
+  btsnoop_write(&drops, 4);
+  btsnoop_write(&time_hi, 4);
+  btsnoop_write(&time_lo, 4);
+  btsnoop_write(&type, 1);
+  btsnoop_write(packet, length_he - 1);
+
+  utils_unlock();
+}
+
+void btsnoop_open(const char *p_path) {
+  assert(p_path != NULL);
+  assert(*p_path != '\0');
+
+  btsnoop_net_open();
+
+  if (hci_btsnoop_fd != -1) {
+    ALOGE("%s btsnoop log file is already open.", __func__);
+    return;
+  }
+
+  hci_btsnoop_fd = open(p_path,
+                        O_WRONLY | O_CREAT | O_TRUNC,
+                        S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
+
+  if (hci_btsnoop_fd == -1) {
+    ALOGE("%s unable to open '%s': %s", __func__, p_path, strerror(errno));
+    return;
+  }
+
+  write(hci_btsnoop_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16);
+}
+
+void btsnoop_close(void) {
+  if (hci_btsnoop_fd != -1)
+    close(hci_btsnoop_fd);
+  hci_btsnoop_fd = -1;
+
+  btsnoop_net_close();
+}
+
+void btsnoop_capture(const HC_BT_HDR *p_buf, bool is_rcvd) {
+  const uint8_t *p = (const uint8_t *)(p_buf + 1) + p_buf->offset;
+
+  if (hci_btsnoop_fd == -1)
+    return;
+
+  switch (p_buf->event & MSG_EVT_MASK) {
+    case MSG_HC_TO_STACK_HCI_EVT:
+      btsnoop_write_packet(kEventPacket, p, false);
+      break;
+    case MSG_HC_TO_STACK_HCI_ACL:
+    case MSG_STACK_TO_HC_HCI_ACL:
+      btsnoop_write_packet(kAclPacket, p, is_rcvd);
+      break;
+    case MSG_HC_TO_STACK_HCI_SCO:
+    case MSG_STACK_TO_HC_HCI_SCO:
+      btsnoop_write_packet(kScoPacket, p, is_rcvd);
+      break;
+    case MSG_STACK_TO_HC_HCI_CMD:
+      btsnoop_write_packet(kCommandPacket, p, true);
+      break;
+  }
 }
index 06cc01a..adaddcd 100644 (file)
  *
  ******************************************************************************/
 
+#define LOG_TAG "btsnoop_net"
+
 #include <assert.h>
+#include <cutils/log.h>
 #include <errno.h>
 #include <netinet/in.h>
 #include <pthread.h>
@@ -26,8 +29,7 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 
-#define LOG_TAG "btsnoop_net"
-#include <cutils/log.h>
+#include "osi.h"
 
 static void safe_close_(int *fd);
 static void *listen_fn_(void *context);
@@ -42,7 +44,7 @@ static pthread_mutex_t client_socket_lock_ = PTHREAD_MUTEX_INITIALIZER;
 static int listen_socket_ = -1;
 static int client_socket_ = -1;
 
-void btsnoop_net_init() {
+void btsnoop_net_open() {
   listen_thread_valid_ = (pthread_create(&listen_thread_, NULL, listen_fn_, NULL) == 0);
   if (!listen_thread_valid_) {
     ALOGE("%s pthread_create failed: %s", __func__, strerror(errno));
@@ -51,7 +53,7 @@ void btsnoop_net_init() {
   }
 }
 
-void btsnoop_net_cleanup() {
+void btsnoop_net_close() {
   if (listen_thread_valid_) {
     shutdown(listen_socket_, SHUT_RDWR);
     pthread_join(listen_thread_, NULL);
@@ -70,7 +72,8 @@ void btsnoop_net_write(const void *data, size_t length) {
   pthread_mutex_unlock(&client_socket_lock_);
 }
 
-static void *listen_fn_(void *context) {
+static void *listen_fn_(UNUSED_ATTR void *context) {
+
   prctl(PR_SET_NAME, (unsigned long)LISTEN_THREAD_NAME_, 0, 0, 0);
 
   listen_socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
index ba15426..bc9f350 100644 (file)
@@ -29,7 +29,9 @@
 #include <utils/Log.h>
 #include <stdlib.h>
 #include <fcntl.h>
+
 #include "bt_hci_bdroid.h"
+#include "btsnoop.h"
 #include "hci.h"
 #include "userial.h"
 #include "utils.h"
@@ -152,10 +154,6 @@ typedef struct
 
 extern BUFFER_Q tx_q;
 
-void btsnoop_init(void);
-void btsnoop_close(void);
-void btsnoop_cleanup (void);
-void btsnoop_capture(HC_BT_HDR *p_buf, uint8_t is_rcvd);
 uint8_t hci_h4_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \
                                   tINT_CMD_CBACK p_cback);
 void lpm_wake_assert(void);
@@ -509,7 +507,7 @@ static uint8_t acl_rx_frame_end_chk (void)
         p_buf->offset = p_buf->offset - HCI_ACL_PREAMBLE_SIZE;
         p_buf->len = p_buf->len - p_buf->offset;
 
-        btsnoop_capture(p_buf, TRUE);
+        btsnoop_capture(p_buf, true);
 
         /* restore contents */
         memcpy(p, p_cb->preload_buffer, HCI_ACL_PREAMBLE_SIZE);
@@ -520,7 +518,7 @@ static uint8_t acl_rx_frame_end_chk (void)
     else
     {
         /* START PACKET */
-        btsnoop_capture(p_buf, TRUE);
+        btsnoop_capture(p_buf, true);
     }
 
     if (frame_end == TRUE)
@@ -559,8 +557,6 @@ void hci_h4_init(void)
      */
     h4_cb.hc_acl_data_size = 1021;
     h4_cb.hc_ble_acl_data_size = 27;
-
-    btsnoop_init();
 }
 
 /*******************************************************************************
@@ -575,9 +571,6 @@ void hci_h4_init(void)
 void hci_h4_cleanup(void)
 {
     HCIDBG("hci_h4_cleanup");
-
-    btsnoop_close();
-    btsnoop_cleanup();
 }
 
 /*******************************************************************************
@@ -645,7 +638,7 @@ void hci_h4_send_msg(HC_BT_HDR *p_msg)
             bytes_sent = userial_write(event,(uint8_t *) p,bytes_to_send);
 
             /* generate snoop trace message */
-            btsnoop_capture(p_msg, FALSE);
+            btsnoop_capture(p_msg, false);
 
             p_msg->layer_specific = lay_spec;
             /* Adjust offset and length for what we just sent */
@@ -713,7 +706,7 @@ void hci_h4_send_msg(HC_BT_HDR *p_msg)
     }
 
     /* generate snoop trace message */
-    btsnoop_capture(p_msg, FALSE);
+    btsnoop_capture(p_msg, false);
 
     if (bt_hc_cbacks)
     {
@@ -955,7 +948,7 @@ uint16_t hci_h4_receive_msg(void)
             /* generate snoop trace message */
             /* ACL packet tracing had done in acl_rx_frame_end_chk() */
             if (p_cb->p_rcv_msg->event != MSG_HC_TO_STACK_HCI_ACL)
-                btsnoop_capture(p_cb->p_rcv_msg, TRUE);
+                btsnoop_capture(p_cb->p_rcv_msg, true);
 
             if (p_cb->p_rcv_msg->event == MSG_HC_TO_STACK_HCI_EVT)
                 intercepted = internal_event_intercept();
index 4e70063..6a5c242 100644 (file)
@@ -30,7 +30,9 @@
 #include <utils/Log.h>
 #include <stdlib.h>
 #include <fcntl.h>
+
 #include "bt_hci_bdroid.h"
+#include "btsnoop.h"
 #include "hci.h"
 #include "userial.h"
 #include "utils.h"
@@ -135,10 +137,6 @@ typedef struct
 
 extern BUFFER_Q tx_q;
 
-void btsnoop_init(void);
-void btsnoop_close(void);
-void btsnoop_cleanup (void);
-void btsnoop_capture(HC_BT_HDR *p_buf, uint8_t is_rcvd);
 uint8_t hci_mct_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \
                                   tINT_CMD_CBACK p_cback);
 void lpm_wake_assert(void);
@@ -504,7 +502,7 @@ static uint8_t acl_rx_frame_end_chk (void)
         p_buf->offset = p_buf->offset - HCI_ACL_PREAMBLE_SIZE;
         p_buf->len = p_buf->len - p_buf->offset;
 
-        btsnoop_capture(p_buf, TRUE);
+        btsnoop_capture(p_buf, true);
 
         /* restore contents */
         memcpy(p, p_cb->rcv_acl.preload_buffer, HCI_ACL_PREAMBLE_SIZE);
@@ -515,7 +513,7 @@ static uint8_t acl_rx_frame_end_chk (void)
     else
     {
         /* START PACKET */
-        btsnoop_capture(p_buf, TRUE);
+        btsnoop_capture(p_buf, true);
     }
 
     if (frame_end == TRUE)
@@ -570,9 +568,6 @@ void hci_mct_init(void)
 void hci_mct_cleanup(void)
 {
     HCIDBG("hci_mct_cleanup");
-
-    btsnoop_close();
-    btsnoop_cleanup();
 }
 
 /*******************************************************************************
@@ -625,7 +620,7 @@ void hci_mct_send_msg(HC_BT_HDR *p_msg)
             userial_write(event, (uint8_t *) p, acl_pkt_size);
 
             /* generate snoop trace message */
-            btsnoop_capture(p_msg, FALSE);
+            btsnoop_capture(p_msg, false);
 
             /* Adjust offset and length for what we just sent */
             p_msg->offset += acl_data_size;
@@ -687,7 +682,7 @@ void hci_mct_send_msg(HC_BT_HDR *p_msg)
 
 
     /* generate snoop trace message */
-    btsnoop_capture(p_msg, FALSE);
+    btsnoop_capture(p_msg, false);
 
     if (bt_hc_cbacks)
     {
@@ -873,7 +868,7 @@ uint16_t hci_mct_receive_evt_msg(void)
             uint8_t intercepted = FALSE;
 
             /* generate snoop trace message */
-            btsnoop_capture(p_cb->p_rcv_msg, TRUE);
+            btsnoop_capture(p_cb->p_rcv_msg, true);
 
             intercepted = internal_event_intercept();