1 /******************************************************************************
2 *
3 * Copyright 2003-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This is the main implementation file for the BTA device manager.
22 *
23 ******************************************************************************/
24 #include <base/strings/stringprintf.h>
25 #include <stddef.h>
26
27 #include "bt_trace.h"
28 #include "bta/dm/bta_dm_int.h"
29 #include "gd/common/circular_buffer.h"
30 #include "gd/common/strings.h"
31 #include "stack/include/bt_hdr.h"
32 #include "stack/include/bt_types.h"
33
34 /*****************************************************************************
35 * Constants and types
36 ****************************************************************************/
37
38 namespace {
39 constexpr size_t kSearchStateHistorySize = 50;
40 constexpr char kTimeFormatString[] = "%Y-%m-%d %H:%M:%S";
41
42 constexpr unsigned MillisPerSecond = 1000;
EpochMillisToString(long long time_ms)43 std::string EpochMillisToString(long long time_ms) {
44 time_t time_sec = time_ms / MillisPerSecond;
45 struct tm tm;
46 localtime_r(&time_sec, &tm);
47 std::string s = bluetooth::common::StringFormatTime(kTimeFormatString, tm);
48 return base::StringPrintf(
49 "%s.%03u", s.c_str(),
50 static_cast<unsigned int>(time_ms % MillisPerSecond));
51 }
52 } // namespace
53
54 tBTA_DM_CB bta_dm_cb;
55 tBTA_DM_SEARCH_CB bta_dm_search_cb;
56 tBTA_DM_DI_CB bta_dm_di_cb;
57
58 struct tSEARCH_STATE_HISTORY {
59 const tBTA_DM_STATE state;
60 const tBTA_DM_EVT event;
ToStringtSEARCH_STATE_HISTORY61 std::string ToString() const {
62 return base::StringPrintf("state:%25s event:%s",
63 bta_dm_state_text(state).c_str(),
64 bta_dm_event_text(event).c_str());
65 }
66 };
67 bluetooth::common::TimestampedCircularBuffer<tSEARCH_STATE_HISTORY>
68 search_state_history_(kSearchStateHistorySize);
69
70 /*******************************************************************************
71 *
72 * Function bta_dm_sm_search_disable
73 *
74 * Description unregister BTA SEARCH DM
75 *
76 *
77 * Returns void
78 *
79 ******************************************************************************/
bta_dm_search_sm_disable()80 void bta_dm_search_sm_disable() { bta_sys_deregister(BTA_ID_DM_SEARCH); }
81
82 /*******************************************************************************
83 *
84 * Function bta_dm_search_sm_execute
85 *
86 * Description State machine event handling function for DM
87 *
88 *
89 * Returns void
90 *
91 ******************************************************************************/
bta_dm_search_sm_execute(BT_HDR_RIGID * p_msg)92 bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) {
93 const tBTA_DM_EVT event = static_cast<tBTA_DM_EVT>(p_msg->event);
94 LOG_INFO("state:%s, event:%s[0x%x]",
95 bta_dm_state_text(bta_dm_search_get_state()).c_str(),
96 bta_dm_event_text(event).c_str(), event);
97 search_state_history_.Push({
98 .state = bta_dm_search_get_state(),
99 .event = event,
100 });
101 tBTA_DM_MSG* message = (tBTA_DM_MSG*)p_msg;
102 switch (bta_dm_search_get_state()) {
103 case BTA_DM_SEARCH_IDLE:
104 switch (p_msg->event) {
105 case BTA_DM_API_SEARCH_EVT:
106 bta_dm_search_set_state(BTA_DM_SEARCH_ACTIVE);
107 bta_dm_search_start(message);
108 break;
109 case BTA_DM_API_DISCOVER_EVT:
110 bta_dm_search_set_state(BTA_DM_DISCOVER_ACTIVE);
111 bta_dm_discover(message);
112 break;
113 case BTA_DM_API_SEARCH_CANCEL_EVT:
114 bta_dm_search_clear_queue();
115 bta_dm_search_cancel_notify();
116 break;
117 case BTA_DM_SDP_RESULT_EVT:
118 bta_dm_free_sdp_db();
119 break;
120 case BTA_DM_DISC_CLOSE_TOUT_EVT:
121 bta_dm_close_gatt_conn(message);
122 break;
123 default:
124 LOG_INFO("Received unexpected event %s[0x%x] in state %s",
125 bta_dm_event_text(event).c_str(), event,
126 bta_dm_state_text(bta_dm_search_get_state()).c_str());
127 }
128 break;
129 case BTA_DM_SEARCH_ACTIVE:
130 switch (p_msg->event) {
131 case BTA_DM_REMT_NAME_EVT:
132 bta_dm_rmt_name(message);
133 break;
134 case BTA_DM_SEARCH_CMPL_EVT:
135 bta_dm_search_cmpl();
136 break;
137 case BTA_DM_DISCOVERY_RESULT_EVT:
138 bta_dm_search_result(message);
139 break;
140 case BTA_DM_DISC_CLOSE_TOUT_EVT:
141 bta_dm_close_gatt_conn(message);
142 break;
143 case BTA_DM_API_DISCOVER_EVT:
144 bta_dm_queue_disc(message);
145 break;
146 case BTA_DM_API_SEARCH_CANCEL_EVT:
147 bta_dm_search_clear_queue();
148 bta_dm_search_set_state(BTA_DM_SEARCH_CANCELLING);
149 bta_dm_search_cancel();
150 break;
151 default:
152 LOG_INFO("Received unexpected event %s[0x%x] in state %s",
153 bta_dm_event_text(event).c_str(), event,
154 bta_dm_state_text(bta_dm_search_get_state()).c_str());
155 }
156 break;
157 case BTA_DM_SEARCH_CANCELLING:
158 switch (p_msg->event) {
159 case BTA_DM_API_SEARCH_EVT:
160 bta_dm_queue_search(message);
161 break;
162 case BTA_DM_API_DISCOVER_EVT:
163 bta_dm_queue_disc(message);
164 break;
165 case BTA_DM_API_SEARCH_CANCEL_EVT:
166 bta_dm_search_clear_queue();
167 bta_dm_search_cancel_notify();
168 break;
169 case BTA_DM_SDP_RESULT_EVT:
170 case BTA_DM_REMT_NAME_EVT:
171 case BTA_DM_SEARCH_CMPL_EVT:
172 case BTA_DM_DISCOVERY_RESULT_EVT:
173 bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
174 bta_dm_free_sdp_db();
175 bta_dm_search_cancel_notify();
176 bta_dm_execute_queued_request();
177 break;
178 case BTA_DM_DISC_CLOSE_TOUT_EVT:
179 if (bluetooth::common::init_flags::
180 bta_dm_clear_conn_id_on_client_close_is_enabled()) {
181 bta_dm_close_gatt_conn(message);
182 break;
183 }
184 [[fallthrough]];
185 default:
186 LOG_INFO("Received unexpected event %s[0x%x] in state %s",
187 bta_dm_event_text(event).c_str(), event,
188 bta_dm_state_text(bta_dm_search_get_state()).c_str());
189 }
190 break;
191 case BTA_DM_DISCOVER_ACTIVE:
192 switch (p_msg->event) {
193 case BTA_DM_REMT_NAME_EVT:
194 bta_dm_disc_rmt_name(message);
195 break;
196 case BTA_DM_SDP_RESULT_EVT:
197 bta_dm_sdp_result(message);
198 break;
199 case BTA_DM_SEARCH_CMPL_EVT:
200 bta_dm_search_cmpl();
201 break;
202 case BTA_DM_DISCOVERY_RESULT_EVT:
203 bta_dm_disc_result(message);
204 break;
205 case BTA_DM_API_SEARCH_EVT:
206 bta_dm_queue_search(message);
207 break;
208 case BTA_DM_API_DISCOVER_EVT:
209 bta_dm_queue_disc(message);
210 break;
211 case BTA_DM_API_SEARCH_CANCEL_EVT:
212 bta_dm_search_clear_queue();
213 bta_dm_search_set_state(BTA_DM_SEARCH_CANCELLING);
214 bta_dm_search_cancel_notify();
215 break;
216 case BTA_DM_DISC_CLOSE_TOUT_EVT:
217 if (bluetooth::common::init_flags::
218 bta_dm_clear_conn_id_on_client_close_is_enabled()) {
219 bta_dm_close_gatt_conn(message);
220 break;
221 }
222 [[fallthrough]];
223 default:
224 LOG_INFO("Received unexpected event %s[0x%x] in state %s",
225 bta_dm_event_text(event).c_str(), event,
226 bta_dm_state_text(bta_dm_search_get_state()).c_str());
227 }
228 break;
229 }
230 return true;
231 }
232
233 #define DUMPSYS_TAG "shim::legacy::bta::dm"
DumpsysBtaDm(int fd)234 void DumpsysBtaDm(int fd) {
235 LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
236 auto copy = search_state_history_.Pull();
237 LOG_DUMPSYS(fd, " last %zu search state transitions", copy.size());
238 for (const auto& it : copy) {
239 LOG_DUMPSYS(fd, " %s %s", EpochMillisToString(it.timestamp).c_str(),
240 it.entry.ToString().c_str());
241 }
242 LOG_DUMPSYS(fd, " current bta_dm_search_state:%s",
243 bta_dm_state_text(bta_dm_search_get_state()).c_str());
244 }
245 #undef DUMPSYS_TAG
246