• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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