| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2014 Intel Corporation. All rights reserved.
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <fcntl.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <stdbool.h>
- #include <time.h>
- #include <sys/uio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include "src/log.h"
- #define LOG_TAG "bluetoothd"
- #define LOG_DEBUG 3
- #define LOG_INFO 4
- #define LOG_WARN 5
- #define LOG_ERR 6
- #define LOG_ID_SYSTEM 3
- struct logd_header {
- uint8_t id;
- uint16_t pid; /* Android logd expects only 2 bytes for PID */
- uint32_t sec;
- uint32_t nsec;
- } __attribute__ ((packed));
- static int log_fd = -1;
- static bool legacy_log = false;
- static void android_log(unsigned char level, const char *fmt, va_list ap)
- {
- struct logd_header header;
- struct iovec vec[4];
- int cnt = 0;
- char *msg;
- static pid_t pid = 0;
- if (log_fd < 0)
- return;
- /* no need to call getpid all the time since we don't fork */
- if (!pid)
- pid = getpid();
- if (vasprintf(&msg, fmt, ap) < 0)
- return;
- if (!legacy_log) {
- struct timespec ts;
- clock_gettime(CLOCK_REALTIME, &ts);
- header.id = LOG_ID_SYSTEM;
- header.pid = pid;
- header.sec = ts.tv_sec;
- header.nsec = ts.tv_nsec;
- vec[0].iov_base = &header;
- vec[0].iov_len = sizeof(header);
- cnt += 1;
- }
- vec[cnt + 0].iov_base = &level;
- vec[cnt + 0].iov_len = sizeof(level);
- vec[cnt + 1].iov_base = LOG_TAG;
- vec[cnt + 1].iov_len = sizeof(LOG_TAG);
- vec[cnt + 2].iov_base = msg;
- vec[cnt + 2].iov_len = strlen(msg) + 1;
- cnt += 3;
- writev(log_fd, vec, cnt);
- free(msg);
- }
- void info(const char *format, ...)
- {
- va_list ap;
- va_start(ap, format);
- android_log(LOG_INFO, format, ap);
- va_end(ap);
- }
- void warn(const char *format, ...)
- {
- va_list ap;
- va_start(ap, format);
- android_log(LOG_WARN, format, ap);
- va_end(ap);
- }
- void error(const char *format, ...)
- {
- va_list ap;
- va_start(ap, format);
- android_log(LOG_ERR, format, ap);
- va_end(ap);
- }
- void btd_debug(uint16_t index, const char *format, ...)
- {
- va_list ap;
- va_start(ap, format);
- android_log(LOG_DEBUG, format, ap);
- va_end(ap);
- }
- static bool init_legacy_log(void)
- {
- log_fd = open("/dev/log/system", O_WRONLY);
- if (log_fd < 0)
- return false;
- legacy_log = true;
- return true;
- }
- static bool init_logd(void)
- {
- struct sockaddr_un addr;
- log_fd = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (log_fd < 0)
- return false;
- if (fcntl(log_fd, F_SETFL, O_NONBLOCK) < 0)
- goto failed;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- strcpy(addr.sun_path, "/dev/socket/logdw");
- if (connect(log_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
- goto failed;
- return true;
- failed:
- close(log_fd);
- log_fd = -1;
- return false;
- }
- extern struct btd_debug_desc __start___debug[];
- extern struct btd_debug_desc __stop___debug[];
- void __btd_log_init(const char *debug, int detach)
- {
- if (!init_logd() && !init_legacy_log())
- return;
- if (debug) {
- struct btd_debug_desc *desc;
- for (desc = __start___debug; desc < __stop___debug; desc++)
- desc->flags |= BTD_DEBUG_FLAG_PRINT;
- }
- info("Bluetooth daemon %s", VERSION);
- }
- void __btd_log_cleanup(void)
- {
- if (log_fd < 0)
- return;
- close(log_fd);
- log_fd = -1;
- }
|