Blob: log.c
Blob id: 8548954b07c8a71e5e35f92958298c5bc474a306
Size: 3.0 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | // SPDX-License-Identifier: LGPL-2.1-or-later /* * * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2018 Intel Corporation. All rights reserved. * * */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #define _GNU_SOURCE #include <stdio.h> #include <errno.h> #include <inttypes.h> #include <unistd.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <signal.h> #include <sys/socket.h> #include "bluetooth/bluetooth.h" #include "bluetooth/hci.h" #include "src/shared/util.h" #include "src/shared/log.h" struct log_hdr { uint16_t opcode; uint16_t index; uint16_t len; uint8_t priority; uint8_t ident_len; } __attribute__((packed)); struct log_l2cap_hdr { uint16_t cid; uint16_t psm; } __attribute__((packed)); static int log_fd = -1; int bt_log_sendmsg(uint16_t index, const char *label, int level, struct iovec *io, size_t io_len) { struct log_hdr hdr; struct msghdr msg; struct iovec iov[5]; size_t i; int err; if (io_len > 3) return -EMSGSIZE; log_fd = bt_log_open(); if (log_fd < 0) return log_fd; hdr.opcode = cpu_to_le16(0x0000); hdr.index = cpu_to_le16(index); hdr.ident_len = strlen(label) + 1; hdr.len = cpu_to_le16(2 + hdr.ident_len); hdr.priority = level; iov[0].iov_base = &hdr; iov[0].iov_len = sizeof(hdr); iov[1].iov_base = (void *) label; iov[1].iov_len = hdr.ident_len; memset(&msg, 0, sizeof(msg)); msg.msg_iov = iov; msg.msg_iovlen = 2; for (i = 0; i < io_len; i++) { iov[i + 2] = io[i]; hdr.len += io[i].iov_len; msg.msg_iovlen++; } err = sendmsg(log_fd, &msg, 0); if (err < 0) { err = -errno; close(log_fd); log_fd = -1; } return err; } int bt_log_open(void) { struct sockaddr_hci addr; int fd; static int err; if (err < 0) return err; if (log_fd >= 0) return log_fd; fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (fd < 0) { err = -errno; return -errno; } memset(&addr, 0, sizeof(addr)); addr.hci_family = AF_BLUETOOTH; addr.hci_dev = HCI_DEV_NONE; addr.hci_channel = HCI_CHANNEL_LOGGING; err = bind(fd, (struct sockaddr *) &addr, sizeof(addr)); if (err < 0) { err = -errno; close(fd); return err; } log_fd = fd; return fd; } int bt_log_vprintf(uint16_t index, const char *label, int level, const char *format, va_list ap) { struct iovec iov; char *str; int len; len = vasprintf(&str, format, ap); if (len < 0 || !str) return errno; len = strlen(str); /* Replace new line since btmon already adds it */ if (len > 1 && str[len - 1] == '\n') { str[len - 1] = '\0'; len--; } iov.iov_base = str; iov.iov_len = len + 1; len = bt_log_sendmsg(index, label, level, &iov, 1); free(str); return len; } int bt_log_printf(uint16_t index, const char *label, int level, const char *format, ...) { va_list ap; int err; va_start(ap, format); err = bt_log_vprintf(index, label, level, format, ap); va_end(ap); return err; } void bt_log_close(void) { if (log_fd < 0) return; close(log_fd); log_fd = -1; } |