From 002e0d0ab1e46a830fa5f06da8122db4e0487e21 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 7 Nov 2015 14:48:10 +0100 Subject: [PATCH] core: Add support for logging output to HCI_CHANNEL_LOGGING --- src/log.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 4 deletions(-) diff --git a/src/log.c b/src/log.c index ca783f367..aa1c822a3 100644 --- a/src/log.c +++ b/src/log.c @@ -28,19 +28,111 @@ #include #include #include +#include +#include +#include +#include +#include #include +#include "lib/bluetooth.h" +#include "lib/hci.h" + +#include "src/shared/util.h" #include "log.h" +struct log_hdr { + uint16_t opcode; + uint16_t index; + uint16_t len; + uint8_t priority; +} __attribute__((packed)); + +static int logging_fd = -1; + +static void logging_open(void) +{ + struct sockaddr_hci addr; + int fd; + + if (logging_fd >= 0) + return; + + fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (fd < 0) + return; + + memset(&addr, 0, sizeof(addr)); + addr.hci_family = AF_BLUETOOTH; + addr.hci_dev = HCI_DEV_NONE; + addr.hci_channel = HCI_CHANNEL_LOGGING; + + if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(fd); + return; + } + + logging_fd = fd; +} + +static void logging_close(void) +{ + if (logging_fd >= 0) { + close(logging_fd); + logging_fd = -1; + } +} + +static void logging_log(int priority, const char *format, va_list ap) +{ + struct log_hdr hdr; + struct msghdr msg; + struct iovec iov[2]; + uint16_t len; + char *str; + + if (vasprintf(&str, format, ap) < 0) + return; + + len = strlen(str) + 1; + + hdr.opcode = cpu_to_le16(0x0000); + hdr.index = cpu_to_le16(0xffff); + hdr.len = cpu_to_le16(len + 1); + hdr.priority = priority; + + iov[0].iov_base = &hdr; + iov[0].iov_len = sizeof(hdr); + + iov[1].iov_base = str; + iov[1].iov_len = len; + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = iov; + msg.msg_iovlen = 2; + + if (sendmsg(logging_fd, &msg, 0) < 0) { + close(logging_fd); + logging_fd = -1; + } + + free(str); +} + void info(const char *format, ...) { va_list ap; va_start(ap, format); - vsyslog(LOG_INFO, format, ap); + va_end(ap); + if (logging_fd < 0) + return; + + va_start(ap, format); + logging_log(LOG_INFO, format, ap); va_end(ap); } @@ -49,9 +141,14 @@ void warn(const char *format, ...) va_list ap; va_start(ap, format); - vsyslog(LOG_WARNING, format, ap); + va_end(ap); + + if (logging_fd < 0) + return; + va_start(ap, format); + logging_log(LOG_WARNING, format, ap); va_end(ap); } @@ -60,9 +157,14 @@ void error(const char *format, ...) va_list ap; va_start(ap, format); - vsyslog(LOG_ERR, format, ap); + va_end(ap); + if (logging_fd < 0) + return; + + va_start(ap, format); + logging_log(LOG_ERR, format, ap); va_end(ap); } @@ -71,9 +173,14 @@ void btd_debug(const char *format, ...) va_list ap; va_start(ap, format); - vsyslog(LOG_DEBUG, format, ap); + va_end(ap); + + if (logging_fd < 0) + return; + va_start(ap, format); + logging_log(LOG_DEBUG, format, ap); va_end(ap); } @@ -128,6 +235,8 @@ void __btd_log_init(const char *debug, int detach) __btd_enable_debug(__start___debug, __stop___debug); + logging_open(); + if (!detach) option |= LOG_PERROR; @@ -140,5 +249,7 @@ void __btd_log_cleanup(void) { closelog(); + logging_close(); + g_strfreev(enabled); } -- 2.47.3