diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2015-11-07 14:48:10 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-11-07 14:48:10 +0100 |
commit | 002e0d0ab1e46a830fa5f06da8122db4e0487e21 (patch) | |
tree | 4143402b109fc3d180b77180c1d5ddb413367e97 /src/log.c | |
parent | 3b8f3b74066eaa6cde54d71d38c8c3050fdbc084 (diff) | |
download | bluez-002e0d0ab1e46a830fa5f06da8122db4e0487e21.tar.gz |
core: Add support for logging output to HCI_CHANNEL_LOGGING
Diffstat (limited to 'src/log.c')
-rw-r--r-- | src/log.c | 119 |
1 files changed, 115 insertions, 4 deletions
@@ -28,19 +28,111 @@ #include <stdio.h> #include <stdarg.h> #include <syslog.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/socket.h> #include <glib.h> +#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); } |