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 #define LOG_TAG "bta_rfcomm_metrics"
17
18 #include "bta_rfcomm_metrics.h"
19
20 #include <bluetooth/log.h>
21 #include <frameworks/proto_logging/stats/enums/bluetooth/rfcomm/enums.pb.h>
22
23 #include "bta_sec_api.h"
24 #include "main/shim/metrics_api.h"
25 #include "stack/include/btm_sec_api_types.h"
26
27 using namespace bluetooth;
28
29 using namespace android::bluetooth;
30 using namespace android::bluetooth::rfcomm;
31
32 static BtaStatus toStatus(tBTA_JV_STATUS status);
33 static SocketConnectionSecurity toSecurity(int security);
34 static PortResult toPortResult(tPORT_RESULT result);
35
36 // logged if SDP result is either FAILED or BUSY
bta_collect_rfc_metrics_after_sdp_fail(tBTA_JV_STATUS sdp_status,RawAddress addr,int app_uid,int security,bool is_server,uint64_t sdp_duration_ms)37 void bta_collect_rfc_metrics_after_sdp_fail(tBTA_JV_STATUS sdp_status, RawAddress addr, int app_uid,
38 int security, bool is_server,
39 uint64_t sdp_duration_ms) {
40 // We only call this function in the case where we started (and failed) sdp
41 bool sdp_initiated = true;
42
43 // We didn't make it to the stage of making a port, so assign default values for these fields
44 PortResult close_reason = PortResult::PORT_RESULT_UNDEFINED;
45 RfcommPortState state_prior = RfcommPortState::PORT_STATE_UNKNOWN;
46 RfcommPortEvent last_event = RfcommPortEvent::PORT_EVENT_UNKNOWN;
47 int open_duration_ms = 0;
48
49 shim::LogMetricRfcommConnectionAtClose(
50 addr, close_reason, toSecurity(security), last_event, state_prior, open_duration_ms,
51 app_uid, toStatus(sdp_status), is_server, sdp_initiated, sdp_duration_ms);
52 }
53
bta_collect_rfc_metrics_after_port_fail(tPORT_RESULT port_result,bool sdp_initiated,tBTA_JV_STATUS sdp_status,RawAddress addr,int app_uid,int security,bool is_server,uint64_t sdp_duration_ms)54 void bta_collect_rfc_metrics_after_port_fail(tPORT_RESULT port_result, bool sdp_initiated,
55 tBTA_JV_STATUS sdp_status, RawAddress addr,
56 int app_uid, int security, bool is_server,
57 uint64_t sdp_duration_ms) {
58 BtaStatus reported_status;
59 if (sdp_status == tBTA_JV_STATUS::SUCCESS && !sdp_initiated) {
60 reported_status = BtaStatus::BTA_STATUS_UNKNOWN;
61 } else {
62 reported_status = toStatus(sdp_status);
63 }
64 RfcommPortState state_prior = RfcommPortState::PORT_STATE_UNKNOWN;
65 RfcommPortEvent last_event = RfcommPortEvent::PORT_EVENT_UNKNOWN;
66 int open_duration_ms = 0;
67
68 shim::LogMetricRfcommConnectionAtClose(
69 addr, toPortResult(port_result), toSecurity(security), last_event, state_prior,
70 open_duration_ms, app_uid, reported_status, is_server, sdp_initiated, sdp_duration_ms);
71 }
72
toStatus(tBTA_JV_STATUS status)73 static BtaStatus toStatus(tBTA_JV_STATUS status) {
74 switch (status) {
75 case tBTA_JV_STATUS::SUCCESS:
76 return BtaStatus::BTA_STATUS_SUCCESS;
77 case tBTA_JV_STATUS::FAILURE:
78 return BtaStatus::BTA_STATUS_FAILURE;
79 case tBTA_JV_STATUS::BUSY:
80 return BtaStatus::BTA_STATUS_BUSY;
81 }
82 return BtaStatus::BTA_STATUS_UNKNOWN;
83 }
84
toSecurity(int security)85 static SocketConnectionSecurity toSecurity(int security) {
86 if ((security == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) ||
87 (security == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) ||
88 (security == (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT))) {
89 return SocketConnectionSecurity::SOCKET_SECURITY_SECURE;
90 } else if (security == BTM_SEC_NONE) {
91 return SocketConnectionSecurity::SOCKET_SECURITY_INSECURE;
92 }
93 return SocketConnectionSecurity::SOCKET_SECURITY_UNKNOWN;
94 }
95
toPortResult(tPORT_RESULT result)96 static PortResult toPortResult(tPORT_RESULT result) {
97 switch (result) {
98 case PORT_SUCCESS:
99 return PortResult::PORT_RESULT_SUCCESS;
100 case PORT_UNKNOWN_ERROR:
101 return PortResult::PORT_RESULT_UNKNOWN_ERROR;
102 case PORT_ALREADY_OPENED:
103 return PortResult::PORT_RESULT_ALREADY_OPENED;
104 case PORT_CMD_PENDING:
105 return PortResult::PORT_RESULT_CMD_PENDING;
106 case PORT_APP_NOT_REGISTERED:
107 return PortResult::PORT_RESULT_APP_NOT_REGISTERED;
108 case PORT_NO_MEM:
109 return PortResult::PORT_RESULT_NO_MEM;
110 case PORT_NO_RESOURCES:
111 return PortResult::PORT_RESULT_NO_RESOURCES;
112 case PORT_BAD_BD_ADDR:
113 return PortResult::PORT_RESULT_BAD_BD_ADDR;
114 case PORT_BAD_HANDLE:
115 return PortResult::PORT_RESULT_BAD_HANDLE;
116 case PORT_NOT_OPENED:
117 return PortResult::PORT_RESULT_NOT_OPENED;
118 case PORT_LINE_ERR:
119 return PortResult::PORT_RESULT_LINE_ERR;
120 case PORT_START_FAILED:
121 return PortResult::PORT_RESULT_START_FAILED;
122 case PORT_PAR_NEG_FAILED:
123 return PortResult::PORT_RESULT_PAR_NEG_FAILED;
124 case PORT_PORT_NEG_FAILED:
125 return PortResult::PORT_RESULT_PORT_NEG_FAILED;
126 case PORT_SEC_FAILED:
127 return PortResult::PORT_RESULT_SEC_FAILED;
128 case PORT_PEER_CONNECTION_FAILED:
129 return PortResult::PORT_RESULT_PEER_CONNECTION_FAILED;
130 case PORT_PEER_FAILED:
131 return PortResult::PORT_RESULT_PEER_FAILED;
132 case PORT_PEER_TIMEOUT:
133 return PortResult::PORT_RESULT_PEER_TIMEOUT;
134 case PORT_CLOSED:
135 return PortResult::PORT_RESULT_CLOSED;
136 case PORT_TX_FULL:
137 return PortResult::PORT_RESULT_TX_FULL;
138 case PORT_LOCAL_CLOSED:
139 return PortResult::PORT_RESULT_LOCAL_CLOSED;
140 case PORT_LOCAL_TIMEOUT:
141 return PortResult::PORT_RESULT_LOCAL_TIMEOUT;
142 case PORT_TX_QUEUE_DISABLED:
143 return PortResult::PORT_RESULT_TX_QUEUE_DISABLED;
144 case PORT_PAGE_TIMEOUT:
145 return PortResult::PORT_RESULT_PAGE_TIMEOUT;
146 case PORT_INVALID_SCN:
147 return PortResult::PORT_RESULT_INVALID_SCN;
148 case PORT_ERR_MAX:
149 return PortResult::PORT_RESULT_ERR_MAX;
150 }
151 return PortResult::PORT_RESULT_UNDEFINED;
152 }
153