summaryrefslogtreecommitdiff
path: root/src/log.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-11-07 14:48:10 +0100
committerMarcel Holtmann <marcel@holtmann.org>2015-11-07 14:48:10 +0100
commit002e0d0ab1e46a830fa5f06da8122db4e0487e21 (patch)
tree4143402b109fc3d180b77180c1d5ddb413367e97 /src/log.c
parent3b8f3b74066eaa6cde54d71d38c8c3050fdbc084 (diff)
downloadbluez-002e0d0ab1e46a830fa5f06da8122db4e0487e21.tar.gz
core: Add support for logging output to HCI_CHANNEL_LOGGING
Diffstat (limited to 'src/log.c')
-rw-r--r--src/log.c119
1 files 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 <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);
}