diff options
author | Kim Schulz <k.schulz@samsung.com> | 2013-09-23 12:48:47 +0200 |
---|---|---|
committer | Zhihai Xu <zhihaixu@google.com> | 2013-12-16 14:27:34 -0800 |
commit | f1d68e95f34921361dced60b1b53e3fef8401f03 (patch) | |
tree | 9eabcff47ad1adae5f8c6abff999215e3a8ad859 /hci/src/btsnoop.c | |
parent | 9628abf10efe5df159f7ad4c192c3ef89fd7731c (diff) | |
download | android_system_bt-f1d68e95f34921361dced60b1b53e3fef8401f03.tar.gz android_system_bt-f1d68e95f34921361dced60b1b53e3fef8401f03.tar.bz2 android_system_bt-f1d68e95f34921361dced60b1b53e3fef8401f03.zip |
fix for btsnoop log blogging HCI socket
Fix for bug 10887611 - btsnoop logging can block HCI socket for longer times.
- Removed the use of the same mutex as the receive queue.
- optimized the code (combined identical code pieces)
- added new function for writing to the log
- switched from using multiple write() calls to using a single writev() (to get atomicity).
patch-set 2:
- fixed review comments (overruns + warnings)
patch-set 3:
- fixed problem with non-matching flags for H4
Bug: 10887611
Change-Id: I16cc23a850093448309ec34c73d536b8571441e9
Diffstat (limited to 'hci/src/btsnoop.c')
-rwxr-xr-x | hci/src/btsnoop.c | 201 |
1 files changed, 66 insertions, 135 deletions
diff --git a/hci/src/btsnoop.c b/hci/src/btsnoop.c index 4807df839..5b0f26d39 100755 --- a/hci/src/btsnoop.c +++ b/hci/src/btsnoop.c @@ -66,6 +66,11 @@ #define SNOOPDBG(param, ...) {} #endif +#define HCIT_TYPE_COMMAND 1 +#define HCIT_TYPE_ACL_DATA 2 +#define HCIT_TYPE_SCO_DATA 3 +#define HCIT_TYPE_EVENT 4 + /* file descriptor of the BT snoop file (by default, -1 means disabled) */ int hci_btsnoop_fd = -1; @@ -117,6 +122,7 @@ do { #define BTSNOOP_EPOCH_HI 0x00dcddb3U #define BTSNOOP_EPOCH_LO 0x0f2f8000U + /******************************************************************************* ** ** Function tv_to_btsnoop_ts @@ -252,6 +258,46 @@ static int btsnoop_log_close(void) } /******************************************************************************* + ** Function btsnoop_write + ** + ** Description Function used to write the actual data to the log + ** + ** Returns none +*******************************************************************************/ + +void btsnoop_write(uint8_t *p, uint32_t flags, const uint8_t *ptype, uint32_t len) +{ + uint32_t value, value_hi; + struct timeval tv; + struct iovec io[3]; + uint32_t header[6]; + + /* store the length in both original and included fields */ + header[0] = l_to_be(len + 1); + header[1] = header[0]; + /* flags: data can be sent or received */ + header[2] = l_to_be(flags); + /* drops: none */ + header[3] = 0; + /* time */ + gettimeofday(&tv, NULL); + tv_to_btsnoop_ts(&header[5], &header[4], &tv); + header[4] = l_to_be(header[4]); + header[5] = l_to_be(header[5]); + + io[0].iov_base = header; + io[0].iov_len = sizeof(header); + + io[1].iov_base = (void*)ptype; + io[1].iov_len = 1; + + io[2].iov_base = p; + io[2].iov_len = len; + + (void) writev(hci_btsnoop_fd, io, 3); +} + +/******************************************************************************* ** ** Function btsnoop_hci_cmd ** @@ -261,42 +307,14 @@ static int btsnoop_log_close(void) *******************************************************************************/ void btsnoop_hci_cmd(uint8_t *p) { + const uint8_t cmd = HCIT_TYPE_COMMAND; + int plen; SNOOPDBG("btsnoop_hci_cmd: fd = %d", hci_btsnoop_fd); - - if (hci_btsnoop_fd != -1) - { - uint32_t value, value_hi; - struct timeval tv; - - /* since these display functions are called from different contexts */ - utils_lock(); - - /* store the length in both original and included fields */ - value = l_to_be(p[2] + 4); - write(hci_btsnoop_fd, &value, 4); - write(hci_btsnoop_fd, &value, 4); - /* flags: command sent from the host */ - value = l_to_be(2); - write(hci_btsnoop_fd, &value, 4); - /* drops: none */ - value = 0; - write(hci_btsnoop_fd, &value, 4); - /* time */ - gettimeofday(&tv, NULL); - tv_to_btsnoop_ts(&value, &value_hi, &tv); - value_hi = l_to_be(value_hi); - value = l_to_be(value); - write(hci_btsnoop_fd, &value_hi, 4); - write(hci_btsnoop_fd, &value, 4); - /* data */ - write(hci_btsnoop_fd, "\x1", 1); - write(hci_btsnoop_fd, p, p[2] + 3); - - /* since these display functions are called from different contexts */ - utils_unlock(); - } + plen = (int) p[2] + 3; + btsnoop_write(p, 2, &cmd, plen); } + /******************************************************************************* ** ** Function btsnoop_hci_evt @@ -307,40 +325,12 @@ void btsnoop_hci_cmd(uint8_t *p) *******************************************************************************/ void btsnoop_hci_evt(uint8_t *p) { + const uint8_t evt = HCIT_TYPE_EVENT; + int plen; SNOOPDBG("btsnoop_hci_evt: fd = %d", hci_btsnoop_fd); + plen = (int) p[1] + 2; - if (hci_btsnoop_fd != -1) - { - uint32_t value, value_hi; - struct timeval tv; - - /* since these display functions are called from different contexts */ - utils_lock(); - - /* store the length in both original and included fields */ - value = l_to_be(p[1] + 3); - write(hci_btsnoop_fd, &value, 4); - write(hci_btsnoop_fd, &value, 4); - /* flags: event received in the host */ - value = l_to_be(3); - write(hci_btsnoop_fd, &value, 4); - /* drops: none */ - value = 0; - write(hci_btsnoop_fd, &value, 4); - /* time */ - gettimeofday(&tv, NULL); - tv_to_btsnoop_ts(&value, &value_hi, &tv); - value_hi = l_to_be(value_hi); - value = l_to_be(value); - write(hci_btsnoop_fd, &value_hi, 4); - write(hci_btsnoop_fd, &value, 4); - /* data */ - write(hci_btsnoop_fd, "\x4", 1); - write(hci_btsnoop_fd, p, p[1] + 2); - - /* since these display functions are called from different contexts */ - utils_unlock(); - } + btsnoop_write(p, 3, &evt, plen); } /******************************************************************************* @@ -353,40 +343,12 @@ void btsnoop_hci_evt(uint8_t *p) *******************************************************************************/ void btsnoop_sco_data(uint8_t *p, uint8_t is_rcvd) { + const uint8_t sco = HCIT_TYPE_SCO_DATA; + int plen; SNOOPDBG("btsnoop_sco_data: fd = %d", hci_btsnoop_fd); + plen = (int) p[2] + 3; - if (hci_btsnoop_fd != -1) - { - uint32_t value, value_hi; - struct timeval tv; - - /* since these display functions are called from different contexts */ - utils_lock(); - - /* store the length in both original and included fields */ - value = l_to_be(p[2] + 4); - write(hci_btsnoop_fd, &value, 4); - write(hci_btsnoop_fd, &value, 4); - /* flags: data can be sent or received */ - value = l_to_be(is_rcvd?1:0); - write(hci_btsnoop_fd, &value, 4); - /* drops: none */ - value = 0; - write(hci_btsnoop_fd, &value, 4); - /* time */ - gettimeofday(&tv, NULL); - tv_to_btsnoop_ts(&value, &value_hi, &tv); - value_hi = l_to_be(value_hi); - value = l_to_be(value); - write(hci_btsnoop_fd, &value_hi, 4); - write(hci_btsnoop_fd, &value, 4); - /* data */ - write(hci_btsnoop_fd, "\x3", 1); - write(hci_btsnoop_fd, p, p[2] + 3); - - /* since these display functions are called from different contexts */ - utils_unlock(); - } + btsnoop_write(p, is_rcvd, &sco, plen); } /******************************************************************************* @@ -399,41 +361,15 @@ void btsnoop_sco_data(uint8_t *p, uint8_t is_rcvd) *******************************************************************************/ void btsnoop_acl_data(uint8_t *p, uint8_t is_rcvd) { + const uint8_t acl = HCIT_TYPE_ACL_DATA; + int plen; + SNOOPDBG("btsnoop_acl_data: fd = %d", hci_btsnoop_fd); - if (hci_btsnoop_fd != -1) - { - uint32_t value, value_hi; - struct timeval tv; - - /* since these display functions are called from different contexts */ - utils_lock(); - - /* store the length in both original and included fields */ - value = l_to_be((p[3]<<8) + p[2] + 5); - write(hci_btsnoop_fd, &value, 4); - write(hci_btsnoop_fd, &value, 4); - /* flags: data can be sent or received */ - value = l_to_be(is_rcvd?1:0); - write(hci_btsnoop_fd, &value, 4); - /* drops: none */ - value = 0; - write(hci_btsnoop_fd, &value, 4); - /* time */ - gettimeofday(&tv, NULL); - tv_to_btsnoop_ts(&value, &value_hi, &tv); - value_hi = l_to_be(value_hi); - value = l_to_be(value); - write(hci_btsnoop_fd, &value_hi, 4); - write(hci_btsnoop_fd, &value, 4); - /* data */ - write(hci_btsnoop_fd, "\x2", 1); - write(hci_btsnoop_fd, p, (p[3]<<8) + p[2] + 4); - - /* since these display functions are called from different contexts */ - utils_unlock(); - } -} + plen = (((int) p[3]) << 8) + ((int) p[2]) +4; + + btsnoop_write(p, is_rcvd, &acl, plen); +} /******************************************************************************** ** API allow external realtime parsing of output using e.g hcidump @@ -619,11 +555,6 @@ void btsnoop_cleanup (void) } -#define HCIT_TYPE_COMMAND 1 -#define HCIT_TYPE_ACL_DATA 2 -#define HCIT_TYPE_SCO_DATA 3 -#define HCIT_TYPE_EVENT 4 - void btsnoop_capture(HC_BT_HDR *p_buf, uint8_t is_rcvd) { uint8_t *p = (uint8_t *)(p_buf + 1) + p_buf->offset; |