1 /*
2 * Copyright 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "bt_btif_sock"
18
19 #include "btif/include/btif_sock_logging.h"
20
21 #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
22 #include <time.h>
23
24 #include <atomic>
25
26 #include "btif/include/btif_metrics_logging.h"
27 #include "btif/include/btif_sock.h"
28 #include "os/logging/log_adapter.h"
29 #include "types/raw_address.h"
30
31 #define SOCK_LOGGER_SIZE_MAX 16
32
33 using namespace bluetooth;
34
35 struct SockConnectionEvent {
36 bool used;
37 RawAddress addr;
38 int state;
39 int role;
40 int channel;
41 int type;
42 char server_name[64];
43 struct timespec timestamp;
44
45 void dump(const int fd);
46 };
47
48 static std::atomic<uint8_t> logger_index;
49
50 static SockConnectionEvent connection_logger[SOCK_LOGGER_SIZE_MAX];
51
52 static android::bluetooth::SocketConnectionstateEnum toConnectionStateEnum(int state);
53 static android::bluetooth::SocketRoleEnum toSocketRoleEnum(int role);
54
btif_sock_connection_logger(const RawAddress & address,int port,int type,int state,int role,int uid,int server_port,int64_t tx_bytes,int64_t rx_bytes,const char * server_name)55 void btif_sock_connection_logger(const RawAddress& address, int port, int type, int state, int role,
56 int uid, int server_port, int64_t tx_bytes, int64_t rx_bytes,
57 const char* server_name) {
58 log::verbose("bd_addr: {}, port: {}, role: {}, state: {}", address, port, role, state);
59
60 uint8_t index = logger_index++ % SOCK_LOGGER_SIZE_MAX;
61
62 connection_logger[index] = {
63 .used = true,
64 .addr = address,
65 .state = state,
66 .role = role,
67 .channel = server_port,
68 .type = type,
69 .server_name = {'\0'},
70 };
71
72 if (server_name != nullptr) {
73 strncpy(connection_logger[index].server_name, server_name,
74 sizeof(connection_logger[index].server_name) - 1);
75 }
76
77 clock_gettime(CLOCK_REALTIME, &connection_logger[index].timestamp);
78 log_socket_connection_state(address, port, type, toConnectionStateEnum(state), tx_bytes, rx_bytes,
79 uid, server_port, toSocketRoleEnum(role));
80 }
81
btif_sock_dump(int fd)82 void btif_sock_dump(int fd) {
83 dprintf(fd, "\nSocket Events: \n");
84 dprintf(fd,
85 " Time \tAddress \tState \tRole"
86 " \tChannel \tType \tServerName\n");
87
88 const uint8_t head = logger_index.load() % SOCK_LOGGER_SIZE_MAX;
89
90 uint8_t index = head;
91 do {
92 connection_logger[index].dump(fd);
93
94 index++;
95 index %= SOCK_LOGGER_SIZE_MAX;
96 } while (index != head);
97 dprintf(fd, "\n");
98 }
99
dump(const int fd)100 void SockConnectionEvent::dump(const int fd) {
101 if (!used) {
102 return;
103 }
104
105 char eventtime[20];
106 char temptime[20];
107 struct tm* tstamp = localtime(×tamp.tv_sec);
108 strftime(temptime, sizeof(temptime), "%H:%M:%S", tstamp);
109 snprintf(eventtime, sizeof(eventtime), "%s.%03ld", temptime, timestamp.tv_nsec / 1000000);
110
111 const char* str_state;
112 switch (state) {
113 case SOCKET_CONNECTION_STATE_LISTENING:
114 str_state = "STATE_LISTENING";
115 break;
116 case SOCKET_CONNECTION_STATE_CONNECTING:
117 str_state = "STATE_CONNECTING";
118 break;
119 case SOCKET_CONNECTION_STATE_CONNECTED:
120 str_state = "STATE_CONNECTED";
121 break;
122 case SOCKET_CONNECTION_STATE_DISCONNECTING:
123 str_state = "STATE_DISCONNECTING";
124 break;
125 case SOCKET_CONNECTION_STATE_DISCONNECTED:
126 str_state = "STATE_DISCONNECTED";
127 break;
128 default:
129 str_state = "STATE_UNKNOWN";
130 break;
131 }
132
133 const char* str_role;
134 switch (role) {
135 case SOCKET_ROLE_LISTEN:
136 str_role = "ROLE_LISTEN";
137 break;
138 case SOCKET_ROLE_CONNECTION:
139 str_role = "ROLE_CONNECTION";
140 break;
141 default:
142 str_role = "ROLE_UNKNOWN";
143 break;
144 }
145
146 const char* str_type;
147 switch (type) {
148 case BTSOCK_RFCOMM:
149 str_type = "RFCOMM";
150 break;
151 case BTSOCK_L2CAP:
152 str_type = "L2CAP";
153 break;
154 case BTSOCK_L2CAP_LE:
155 str_type = "L2CAP_LE";
156 break;
157 case BTSOCK_SCO:
158 str_type = "SCO";
159 break;
160 default:
161 str_type = "UNKNOWN";
162 break;
163 }
164
165 dprintf(fd, " %s\t%s\t%s \t%s \t%d \t%s\t%s\n", eventtime,
166 ADDRESS_TO_LOGGABLE_CSTR(addr), str_state, str_role, channel, str_type, server_name);
167 }
168
toConnectionStateEnum(int state)169 static android::bluetooth::SocketConnectionstateEnum toConnectionStateEnum(int state) {
170 switch (state) {
171 case SOCKET_CONNECTION_STATE_LISTENING:
172 return android::bluetooth::SocketConnectionstateEnum::SOCKET_CONNECTION_STATE_LISTENING;
173 break;
174 case SOCKET_CONNECTION_STATE_CONNECTING:
175 return android::bluetooth::SocketConnectionstateEnum::SOCKET_CONNECTION_STATE_CONNECTING;
176 case SOCKET_CONNECTION_STATE_CONNECTED:
177 return android::bluetooth::SocketConnectionstateEnum::SOCKET_CONNECTION_STATE_CONNECTED;
178 case SOCKET_CONNECTION_STATE_DISCONNECTING:
179 return android::bluetooth::SocketConnectionstateEnum::SOCKET_CONNECTION_STATE_DISCONNECTING;
180 case SOCKET_CONNECTION_STATE_DISCONNECTED:
181 return android::bluetooth::SocketConnectionstateEnum::SOCKET_CONNECTION_STATE_DISCONNECTED;
182 }
183 return android::bluetooth::SocketConnectionstateEnum::SOCKET_CONNECTION_STATE_UNKNOWN;
184 }
185
toSocketRoleEnum(int role)186 static android::bluetooth::SocketRoleEnum toSocketRoleEnum(int role) {
187 switch (role) {
188 case SOCKET_ROLE_LISTEN:
189 return android::bluetooth::SOCKET_ROLE_LISTEN;
190 case SOCKET_ROLE_CONNECTION:
191 return android::bluetooth::SOCKET_ROLE_CONNECTION;
192 }
193 return android::bluetooth::SOCKET_ROLE_UNKNOWN;
194 }
195