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