1 /** @file
2 * @brief Custom monitor protocol logging over UART
3 */
4
5 /*
6 * Copyright (c) 2016 Intel Corporation
7 * Copyright (c) 2025 Silicon Laboratories Inc.
8 *
9 * SPDX-License-Identifier: Apache-2.0
10 */
11 #include <stdint.h>
12
13 #include <zephyr/net_buf.h>
14 #include <zephyr/bluetooth/buf.h>
15 #include <zephyr/bluetooth/hci_types.h>
16
17 #define BT_MONITOR_NEW_INDEX 0
18 #define BT_MONITOR_DEL_INDEX 1
19 #define BT_MONITOR_COMMAND_PKT 2
20 #define BT_MONITOR_EVENT_PKT 3
21 #define BT_MONITOR_ACL_TX_PKT 4
22 #define BT_MONITOR_ACL_RX_PKT 5
23 #define BT_MONITOR_SCO_TX_PKT 6
24 #define BT_MONITOR_SCO_RX_PKT 7
25 #define BT_MONITOR_OPEN_INDEX 8
26 #define BT_MONITOR_CLOSE_INDEX 9
27 #define BT_MONITOR_INDEX_INFO 10
28 #define BT_MONITOR_VENDOR_DIAG 11
29 #define BT_MONITOR_SYSTEM_NOTE 12
30 #define BT_MONITOR_USER_LOGGING 13
31 #define BT_MONITOR_ISO_TX_PKT 18
32 #define BT_MONITOR_ISO_RX_PKT 19
33 #define BT_MONITOR_NOP 255
34
35 #define BT_MONITOR_TYPE_PRIMARY 0
36 #define BT_MONITOR_TYPE_AMP 1
37
38 /* Extended header types */
39 #define BT_MONITOR_COMMAND_DROPS 1
40 #define BT_MONITOR_EVENT_DROPS 2
41 #define BT_MONITOR_ACL_RX_DROPS 3
42 #define BT_MONITOR_ACL_TX_DROPS 4
43 #define BT_MONITOR_SCO_RX_DROPS 5
44 #define BT_MONITOR_SCO_TX_DROPS 6
45 #define BT_MONITOR_OTHER_DROPS 7
46 #define BT_MONITOR_TS32 8
47
48 #define BT_MONITOR_BASE_HDR_LEN 6
49
50 #if defined(CONFIG_BT_CLASSIC)
51 #define BT_MONITOR_EXT_HDR_MAX 19
52 #else
53 #define BT_MONITOR_EXT_HDR_MAX 15
54 #endif
55
56 struct bt_monitor_hdr {
57 uint16_t data_len;
58 uint16_t opcode;
59 uint8_t flags;
60 uint8_t hdr_len;
61
62 uint8_t ext[BT_MONITOR_EXT_HDR_MAX];
63 } __packed;
64
65 struct bt_monitor_ts32 {
66 uint8_t type;
67 uint32_t ts32;
68 } __packed;
69
70 struct bt_monitor_new_index {
71 uint8_t type;
72 uint8_t bus;
73 uint8_t bdaddr[6];
74 char name[8];
75 } __packed;
76
77 struct bt_monitor_user_logging {
78 uint8_t priority;
79 uint8_t ident_len;
80 } __packed;
81
82 enum bt_monitor_dir {
83 BT_MONITOR_TX,
84 BT_MONITOR_RX,
85 };
86
bt_monitor_opcode(uint8_t type,enum bt_monitor_dir dir)87 static inline uint8_t bt_monitor_opcode(uint8_t type, enum bt_monitor_dir dir)
88 {
89 switch (type) {
90 case BT_HCI_H4_CMD:
91 return BT_MONITOR_COMMAND_PKT;
92 case BT_HCI_H4_EVT:
93 return BT_MONITOR_EVENT_PKT;
94 case BT_HCI_H4_ACL:
95 if (dir == BT_MONITOR_TX) {
96 return BT_MONITOR_ACL_TX_PKT;
97 } else {
98 return BT_MONITOR_ACL_RX_PKT;
99 }
100 case BT_HCI_H4_ISO:
101 if (dir == BT_MONITOR_TX) {
102 return BT_MONITOR_ISO_TX_PKT;
103 } else {
104 return BT_MONITOR_ISO_RX_PKT;
105 }
106 default:
107 return BT_MONITOR_NOP;
108 }
109 }
110
111 /* TODO: Remove guard and replace with IS_ENABLED(CONFIG_BT_MONITOR) */
112 #if defined(CONFIG_BT_MONITOR)
113
114 void bt_monitor_send(uint16_t opcode, const void *data, size_t len);
115
116 void bt_monitor_new_index(uint8_t type, uint8_t bus, const bt_addr_t *addr,
117 const char *name);
118
119 #else /* !CONFIG_BT_MONITOR */
120
bt_monitor_send(uint16_t opcode,const void * data,size_t len)121 static inline void bt_monitor_send(uint16_t opcode, const void *data, size_t len)
122 {
123 ARG_UNUSED(opcode);
124 ARG_UNUSED(data);
125 ARG_UNUSED(len);
126 }
127
bt_monitor_new_index(uint8_t type,uint8_t bus,const bt_addr_t * addr,const char * name)128 static inline void bt_monitor_new_index(uint8_t type, uint8_t bus, const bt_addr_t *addr,
129 const char *name)
130 {
131 ARG_UNUSED(type);
132 ARG_UNUSED(bus);
133 ARG_UNUSED(addr);
134 ARG_UNUSED(name);
135 }
136
137 #endif
138