1 /******************************************************************************
2 *
3 * Copyright 2018 The Android Open Source Project
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 #include "connection_manager.h"
20
21 #include <base/functional/bind.h>
22 #include <base/functional/callback.h>
23 #include <base/location.h>
24 #include <bluetooth/log.h>
25
26 #include <map>
27 #include <memory>
28 #include <set>
29
30 #include "gd/hci/acl_manager.h"
31 #include "gd/hci/controller_interface.h"
32 #include "main/shim/acl_api.h"
33 #include "main/shim/entry.h"
34 #include "main/shim/helpers.h"
35 #include "main/shim/le_scanning_manager.h"
36 #include "main/shim/metrics_api.h"
37 #include "osi/include/alarm.h"
38 #include "stack/btm/btm_dev.h"
39 #include "stack/include/advertise_data_parser.h"
40 #include "stack/include/bt_types.h"
41 #include "stack/include/btm_ble_api.h"
42 #include "stack/include/btm_client_interface.h"
43 #include "stack/include/btm_log_history.h"
44 #include "stack/include/main_thread.h"
45 #include "types/raw_address.h"
46
47 #define DIRECT_CONNECT_TIMEOUT (30 * 1000) /* 30 seconds */
48
49 using namespace bluetooth;
50
51 constexpr char kBtmLogTagACL[] = "ACL";
52 constexpr char kBtmLogTagTA[] = "TA";
53
54 struct closure_data {
55 base::OnceClosure user_task;
56 };
57
58 extern std::string get_client_name(uint8_t gatt_if);
59
alarm_closure_cb(void * p)60 static void alarm_closure_cb(void* p) {
61 closure_data* data = (closure_data*)p;
62 std::move(data->user_task).Run();
63 delete data;
64 }
65
66 // Periodic alarms are not supported, because we clean up data in callback
alarm_set_closure(alarm_t * alarm,uint64_t interval_ms,base::OnceClosure user_task)67 static void alarm_set_closure(alarm_t* alarm, uint64_t interval_ms, base::OnceClosure user_task) {
68 closure_data* data = new closure_data;
69 data->user_task = std::move(user_task);
70 alarm_set_on_mloop(alarm, interval_ms, alarm_closure_cb, data);
71 }
72
73 using unique_alarm_ptr = std::unique_ptr<alarm_t, decltype(&alarm_free)>;
74
75 namespace {
ACL_AcceptLeConnectionFrom(const tBLE_BD_ADDR & legacy_address_with_type,bool is_direct)76 static void ACL_AcceptLeConnectionFrom(const tBLE_BD_ADDR& legacy_address_with_type,
77 bool is_direct) {
78 BTM_LogHistory(kBtmLogTagACL, legacy_address_with_type, "Allow connection from", "Le");
79 bluetooth::shim::GetAclManager()->CreateLeConnection(
80 bluetooth::ToAddressWithTypeFromLegacy(legacy_address_with_type), is_direct);
81 }
82
ACL_IgnoreLeConnectionFrom(const tBLE_BD_ADDR & legacy_address_with_type)83 static void ACL_IgnoreLeConnectionFrom(const tBLE_BD_ADDR& legacy_address_with_type) {
84 BTM_LogHistory(kBtmLogTagACL, legacy_address_with_type, "Ignore connection from", "Le");
85 bluetooth::shim::GetAclManager()->CancelLeConnect(
86 bluetooth::ToAddressWithTypeFromLegacy(legacy_address_with_type));
87 }
88 } // namespace
89
90 namespace connection_manager {
91
92 struct tAPPS_CONNECTING {
93 // ids of clients doing background connection to given device
94 std::set<tAPP_ID> doing_bg_conn;
95 std::set<tAPP_ID> doing_targeted_announcements_conn;
96 bool is_in_accept_list;
97
98 // Apps trying to do direct connection.
99 std::map<tAPP_ID, unique_alarm_ptr> doing_direct_conn;
100 };
101
102 namespace {
103 // Maps address to apps trying to connect to it
104 std::map<RawAddress, tAPPS_CONNECTING> bgconn_dev;
105
num_of_targeted_announcements_users(void)106 int num_of_targeted_announcements_users(void) {
107 return std::count_if(bgconn_dev.begin(), bgconn_dev.end(), [](const auto& pair) {
108 return !pair.second.is_in_accept_list && !pair.second.doing_targeted_announcements_conn.empty();
109 });
110 }
111
is_anyone_interested_to_use_accept_list(const std::map<RawAddress,tAPPS_CONNECTING>::iterator it)112 bool is_anyone_interested_to_use_accept_list(
113 const std::map<RawAddress, tAPPS_CONNECTING>::iterator it) {
114 if (!it->second.doing_targeted_announcements_conn.empty()) {
115 return !it->second.doing_direct_conn.empty();
116 }
117 return !it->second.doing_bg_conn.empty() || !it->second.doing_direct_conn.empty();
118 }
119
is_anyone_connecting(const std::map<RawAddress,tAPPS_CONNECTING>::iterator it)120 bool is_anyone_connecting(const std::map<RawAddress, tAPPS_CONNECTING>::iterator it) {
121 return !it->second.doing_bg_conn.empty() || !it->second.doing_direct_conn.empty() ||
122 !it->second.doing_targeted_announcements_conn.empty();
123 }
124
accept_list_is_full()125 static bool accept_list_is_full() {
126 uint8_t accept_list_size = shim::GetController()->GetLeFilterAcceptListSize();
127
128 int num_entries = 0;
129 for (const auto& entry : bgconn_dev) {
130 if (entry.second.is_in_accept_list) {
131 num_entries++;
132 }
133 }
134
135 if (num_entries >= accept_list_size) {
136 return true;
137 }
138
139 return false;
140 }
141
142 } // namespace
143
144 /** Return all apps interested in device, or empty set if not found. */
get_apps_connecting_to(const RawAddress & address)145 std::set<tAPP_ID> get_apps_connecting_to(const RawAddress& address) {
146 log::debug("address={}", address);
147 auto it = bgconn_dev.find(address);
148 if (it == bgconn_dev.end()) {
149 return std::set<tAPP_ID>();
150 }
151
152 std::set<tAPP_ID> result;
153 result.insert(it->second.doing_bg_conn.begin(), it->second.doing_bg_conn.end());
154 result.insert(it->second.doing_targeted_announcements_conn.begin(),
155 it->second.doing_targeted_announcements_conn.end());
156
157 for (const auto& entry : it->second.doing_direct_conn) {
158 result.insert(entry.first);
159 }
160 return result;
161 }
162
IsTargetedAnnouncement(const uint8_t * p_eir,uint16_t eir_len)163 static bool IsTargetedAnnouncement(const uint8_t* p_eir, uint16_t eir_len) {
164 const uint8_t* p_service_data = p_eir;
165 uint8_t service_data_len = 0;
166
167 while ((p_service_data = AdvertiseDataParser::GetFieldByType(
168 p_service_data + service_data_len,
169 eir_len - (p_service_data - p_eir) - service_data_len,
170 BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE, &service_data_len))) {
171 uint16_t uuid;
172 uint8_t announcement_type;
173 const uint8_t* p_tmp = p_service_data;
174
175 if (service_data_len < 3) {
176 continue;
177 }
178
179 STREAM_TO_UINT16(uuid, p_tmp);
180 log::debug("Found UUID 0x{:04x}", uuid);
181
182 if (uuid != 0x184E && uuid != 0x1853) {
183 continue;
184 }
185
186 STREAM_TO_UINT8(announcement_type, p_tmp);
187 log::debug("Found announcement_type 0x{:02x}", announcement_type);
188 if (announcement_type == 0x01) {
189 return true;
190 }
191 }
192 return false;
193 }
194
195 static void schedule_direct_connect_add(uint8_t app_id, const RawAddress& address);
196
target_announcement_observe_results_cb(tBTM_INQ_RESULTS * p_inq,const uint8_t * p_eir,uint16_t eir_len)197 static void target_announcement_observe_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir,
198 uint16_t eir_len) {
199 auto addr = p_inq->remote_bd_addr;
200 auto it = bgconn_dev.find(addr);
201 if (it == bgconn_dev.end() || it->second.doing_targeted_announcements_conn.empty()) {
202 return;
203 }
204
205 if (!IsTargetedAnnouncement(p_eir, eir_len)) {
206 log::debug("Not a targeted announcement for device {}", addr);
207 return;
208 }
209
210 log::info("Found targeted announcement for device {}", addr);
211
212 if (it->second.is_in_accept_list) {
213 log::info("Device {} is already connecting", addr);
214 return;
215 }
216
217 if (get_btm_client_interface().peer.BTM_GetHCIConnHandle(addr, BT_TRANSPORT_LE) != 0xFFFF) {
218 log::debug("Device {} already connected", addr);
219 return;
220 }
221
222 BTM_LogHistory(kBtmLogTagTA, addr, "Found TA from");
223
224 /* Take fist app_id and use it for direct_connect */
225 auto app_id = *(it->second.doing_targeted_announcements_conn.begin());
226
227 /* If scan is ongoing lets stop it */
228 do_in_main_thread(base::BindOnce(schedule_direct_connect_add, app_id, addr));
229 }
230
target_announcements_filtering_set(bool enable)231 static void target_announcements_filtering_set(bool enable) {
232 log::debug("enable {}", enable);
233 BTM_LogHistory(kBtmLogTagTA, RawAddress::kEmpty, (enable ? "Start filtering" : "Stop filtering"));
234
235 /* Safe to call as if there is no support for filtering, this call will be
236 * ignored. */
237 bluetooth::shim::set_target_announcements_filter(enable);
238 BTM_BleTargetAnnouncementObserve(enable, target_announcement_observe_results_cb);
239 }
240
241 /** Add a device to the background connection list for targeted announcements.
242 * Returns
243 * true if device added to the list, or already in list,
244 * false otherwise
245 */
background_connect_targeted_announcement_add(tAPP_ID app_id,const RawAddress & address)246 bool background_connect_targeted_announcement_add(tAPP_ID app_id, const RawAddress& address) {
247 log::info("app_id={}, address={}", static_cast<int>(app_id), address);
248
249 bool disable_accept_list = false;
250
251 auto it = bgconn_dev.find(address);
252 if (it != bgconn_dev.end()) {
253 // check if filtering already enabled
254 if (it->second.doing_targeted_announcements_conn.count(app_id)) {
255 log::info("app_id={}, already doing targeted announcement filtering to address={}",
256 static_cast<int>(app_id), address);
257 return true;
258 }
259
260 bool targeted_filtering_enabled = !it->second.doing_targeted_announcements_conn.empty();
261
262 // Check if connecting
263 if (!it->second.doing_direct_conn.empty()) {
264 log::info("app_id={}, address={}, already in direct connection", static_cast<int>(app_id),
265 address);
266
267 } else if (!targeted_filtering_enabled && !it->second.doing_bg_conn.empty()) {
268 // device is already in the acceptlist so we would have to remove it
269 log::info("already doing background connection to address={}. Need to disable it.", address);
270 disable_accept_list = true;
271 }
272 }
273
274 if (disable_accept_list) {
275 ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(address));
276 bgconn_dev[address].is_in_accept_list = false;
277 }
278
279 bgconn_dev[address].doing_targeted_announcements_conn.insert(app_id);
280 if (bgconn_dev[address].doing_targeted_announcements_conn.size() == 1) {
281 BTM_LogHistory(kBtmLogTagTA, address, "Allow connection from");
282 }
283
284 if (num_of_targeted_announcements_users() == 1) {
285 target_announcements_filtering_set(true);
286 }
287
288 return true;
289 }
290
291 /** Add a device from the background connection list. Returns true if device
292 * added to the list, or already in list, false otherwise */
background_connect_add(uint8_t app_id,const RawAddress & address)293 bool background_connect_add(uint8_t app_id, const RawAddress& address) {
294 log::debug("app_id={}, address={}", static_cast<int>(app_id), address);
295 auto it = bgconn_dev.find(address);
296 bool in_acceptlist = false;
297 bool is_targeted_announcement_enabled = false;
298 if (it != bgconn_dev.end()) {
299 // device already in the acceptlist, just add interested app to the list
300 if (it->second.doing_bg_conn.count(app_id)) {
301 log::debug("app_id={}, already doing background connection to address={}",
302 static_cast<int>(app_id), address);
303 return true;
304 }
305
306 // Already in acceptlist ?
307 if (it->second.is_in_accept_list) {
308 log::debug("app_id={}, address={}, already in accept list", static_cast<int>(app_id),
309 address);
310 in_acceptlist = true;
311 } else {
312 is_targeted_announcement_enabled = !it->second.doing_targeted_announcements_conn.empty();
313 }
314 }
315
316 if (!in_acceptlist) {
317 // the device is not in the acceptlist
318 if (is_targeted_announcement_enabled) {
319 log::debug("Targeted announcement enabled, do not add to AcceptList");
320 } else {
321 if (accept_list_is_full()) {
322 log::warn("accept list is full ({}), can't add {}",
323 shim::GetController()->GetLeFilterAcceptListSize(), address);
324 return false;
325 }
326
327 ACL_AcceptLeConnectionFrom(BTM_Sec_GetAddressWithType(address), false);
328
329 bgconn_dev[address].is_in_accept_list = true;
330 }
331 }
332
333 // create entry for address, and insert app_id.
334 // new tAPPS_CONNECTING will be default constructed if not exist
335 bgconn_dev[address].doing_bg_conn.insert(app_id);
336 return true;
337 }
338
339 /** Removes all registrations for connection for given device.
340 * Returns true if anything was removed, false otherwise */
remove_unconditional(const RawAddress & address)341 bool remove_unconditional(const RawAddress& address) {
342 log::debug("address={}", address);
343 int count = bgconn_dev.erase(address);
344 if (count == 0) {
345 log::info("address {} is not found", address);
346 }
347
348 ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(address));
349 return count > 0;
350 }
351
352 /** Remove device from the background connection device list or listening to
353 * advertising list. Returns true if device was on the list and was
354 * successfully removed */
background_connect_remove(uint8_t app_id,const RawAddress & address)355 bool background_connect_remove(uint8_t app_id, const RawAddress& address) {
356 log::debug("app_id={}, address={}", static_cast<int>(app_id), address);
357 auto it = bgconn_dev.find(address);
358 if (it == bgconn_dev.end()) {
359 log::warn("address {} is not found", address);
360 return false;
361 }
362
363 bool accept_list_enabled = it->second.is_in_accept_list;
364 auto num_of_targeted_announcements_before_remove =
365 it->second.doing_targeted_announcements_conn.size();
366
367 bool removed_from_bg_conn = (it->second.doing_bg_conn.erase(app_id) > 0);
368 bool removed_from_ta = (it->second.doing_targeted_announcements_conn.erase(app_id) > 0);
369 if (!removed_from_bg_conn && !removed_from_ta) {
370 log::warn("Failed to remove background connection app {} for address {}",
371 static_cast<int>(app_id), address);
372 return false;
373 }
374
375 if (removed_from_ta && it->second.doing_targeted_announcements_conn.size() == 0) {
376 BTM_LogHistory(kBtmLogTagTA, address, "Ignore connection from");
377 }
378
379 if (is_anyone_connecting(it)) {
380 log::debug("some app is still connecting, app_id={}, address={}", static_cast<int>(app_id),
381 address);
382 /* Check which method should be used now.*/
383 if (!accept_list_enabled) {
384 /* Accept list was not used */
385 if (!it->second.doing_targeted_announcements_conn.empty()) {
386 /* Keep using filtering */
387 log::debug("Keep using target announcement filtering");
388 } else if (!it->second.doing_bg_conn.empty()) {
389 ACL_AcceptLeConnectionFrom(BTM_Sec_GetAddressWithType(address), false);
390 bgconn_dev[address].is_in_accept_list = true;
391 }
392 }
393 return true;
394 }
395
396 bgconn_dev.erase(it);
397
398 // no more apps interested - remove from accept list and delete record
399 if (accept_list_enabled) {
400 ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(address));
401 return true;
402 }
403
404 if ((num_of_targeted_announcements_before_remove > 0) &&
405 num_of_targeted_announcements_users() == 0) {
406 target_announcements_filtering_set(true);
407 }
408
409 return true;
410 }
411
is_background_connection(const RawAddress & address)412 bool is_background_connection(const RawAddress& address) {
413 auto it = bgconn_dev.find(address);
414 if (it == bgconn_dev.end()) {
415 return false;
416 }
417 return it->second.is_in_accept_list;
418 }
419
420 /** deregister all related background connetion device. */
on_app_deregistered(uint8_t app_id)421 void on_app_deregistered(uint8_t app_id) {
422 log::debug("app_id={}", static_cast<int>(app_id));
423 auto it = bgconn_dev.begin();
424 auto end = bgconn_dev.end();
425 /* update the BG conn device list */
426 while (it != end) {
427 it->second.doing_bg_conn.erase(app_id);
428
429 it->second.doing_direct_conn.erase(app_id);
430
431 if (is_anyone_connecting(it)) {
432 it++;
433 continue;
434 }
435
436 ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(it->first));
437 it = bgconn_dev.erase(it);
438 }
439 }
440
remove_all_clients_with_pending_connections(const RawAddress & address)441 static void remove_all_clients_with_pending_connections(const RawAddress& address) {
442 log::debug("address={}", address);
443 auto it = bgconn_dev.find(address);
444 while (it != bgconn_dev.end() && !it->second.doing_direct_conn.empty()) {
445 uint8_t app_id = it->second.doing_direct_conn.begin()->first;
446 direct_connect_remove(app_id, address);
447 it = bgconn_dev.find(address);
448 }
449 }
450
on_connection_complete(const RawAddress & address)451 void on_connection_complete(const RawAddress& address) {
452 log::info("Le connection completed to device:{}", address);
453
454 remove_all_clients_with_pending_connections(address);
455 }
456
on_connection_timed_out_from_shim(const RawAddress & address)457 void on_connection_timed_out_from_shim(const RawAddress& address) {
458 log::info("Connection failed {}", address);
459 on_connection_timed_out(0x00, address);
460 }
461
462 /** Reset bg device list. If called after controller reset, set |after_reset|
463 * to true, as there is no need to wipe controller acceptlist in this case. */
reset(bool after_reset)464 void reset(bool after_reset) {
465 bgconn_dev.clear();
466 if (!after_reset) {
467 target_announcements_filtering_set(false);
468 bluetooth::shim::GetAclManager()->ClearFilterAcceptList();
469 }
470 }
471
wl_direct_connect_timeout_cb(uint8_t app_id,const RawAddress & address)472 static void wl_direct_connect_timeout_cb(uint8_t app_id, const RawAddress& address) {
473 log::debug("app_id={}, address={}", static_cast<int>(app_id), address);
474 on_connection_timed_out(app_id, address);
475
476 // TODO: this would free the timer, from within the timer callback, which is
477 // bad.
478 direct_connect_remove(app_id, address, true);
479 }
480
find_in_device_record(const RawAddress & bd_addr,tBLE_BD_ADDR * address_with_type)481 static void find_in_device_record(const RawAddress& bd_addr, tBLE_BD_ADDR* address_with_type) {
482 const tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
483 if (p_dev_rec == nullptr) {
484 return;
485 }
486
487 if (p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) {
488 if (p_dev_rec->ble.identity_address_with_type.bda.IsEmpty()) {
489 *address_with_type = {.type = p_dev_rec->ble.AddressType(), .bda = bd_addr};
490 return;
491 }
492 *address_with_type = p_dev_rec->ble.identity_address_with_type;
493 return;
494 }
495 *address_with_type = {.type = BLE_ADDR_PUBLIC, .bda = bd_addr};
496 return;
497 }
498
direct_connect_add(uint8_t app_id,const RawAddress & address,tBLE_ADDR_TYPE addr_type)499 bool direct_connect_add(uint8_t app_id, const RawAddress& address, tBLE_ADDR_TYPE addr_type) {
500 tBLE_BD_ADDR address_with_type{
501 .type = addr_type,
502 .bda = address,
503 };
504
505 find_in_device_record(address, &address_with_type);
506
507 if (address_with_type.type == BLE_ADDR_ANONYMOUS) {
508 log::warn("Can't use anonymous address for connection: {}", address_with_type);
509 return false;
510 }
511
512 log::debug("app_id=0x{:x}, address={} (initial type: {})", static_cast<int>(app_id),
513 address_with_type, AddressTypeText(addr_type));
514
515 bool in_acceptlist = false;
516 auto it = bgconn_dev.find(address);
517 if (it != bgconn_dev.end()) {
518 const tAPPS_CONNECTING& info = it->second;
519 // app already trying to connect to this particular device
520 if (info.doing_direct_conn.count(app_id)) {
521 log::info("attempt from app_id=0x{:x} to {} already in progress", app_id, address_with_type);
522 bluetooth::shim::LogMetricLeConnectionRejected(bluetooth::ToGdAddress(address));
523 return false;
524 }
525
526 // This is to match existing GD connection manager behavior - if multiple apps try direct
527 // connect at same time, only 1st request is fully processed
528 if (!info.doing_direct_conn.empty()) {
529 log::info("app_id=0x{:x}: attempt from other app already in progress, will merge {}", app_id,
530 address_with_type);
531 return true;
532 }
533
534 // are we already in the acceptlist ?
535 if (info.is_in_accept_list) {
536 log::warn("background connect attempt already in progress app_id=0x{:x} {}", app_id,
537 address_with_type);
538 in_acceptlist = true;
539 }
540 }
541
542 if (!in_acceptlist) {
543 if (accept_list_is_full()) {
544 log::warn("accept list is full ({}), can't add {}",
545 shim::GetController()->GetLeFilterAcceptListSize(), address_with_type);
546 return false;
547 }
548
549 ACL_AcceptLeConnectionFrom(address_with_type, true /* is_direct */);
550 bgconn_dev[address].is_in_accept_list = true;
551 } else {
552 // if already in accept list, we should just bump parameters up for direct
553 // connection. There is no API for that yet, so use API that's adding to accept list.
554 ACL_AcceptLeConnectionFrom(address_with_type, true /* is_direct */);
555 }
556
557 // Setup a timer
558 alarm_t* timeout = alarm_new("wl_conn_params_30s");
559 alarm_set_closure(timeout, DIRECT_CONNECT_TIMEOUT,
560 base::BindOnce(&wl_direct_connect_timeout_cb, app_id, address));
561
562 bgconn_dev[address].doing_direct_conn.emplace(app_id, unique_alarm_ptr(timeout, &alarm_free));
563 return true;
564 }
565
schedule_direct_connect_add(uint8_t app_id,const RawAddress & address)566 static void schedule_direct_connect_add(uint8_t app_id, const RawAddress& address) {
567 direct_connect_add(app_id, address);
568 }
569
direct_connect_remove(uint8_t app_id,const RawAddress & address,bool connection_timeout)570 bool direct_connect_remove(uint8_t app_id, const RawAddress& address, bool connection_timeout) {
571 log::debug("app_id={}, address={}", static_cast<int>(app_id), address);
572 auto it = bgconn_dev.find(address);
573 if (it == bgconn_dev.end()) {
574 log::warn("unable to find entry to remove: {}", address);
575 return false;
576 }
577
578 auto app_it = it->second.doing_direct_conn.find(app_id);
579 if (app_it == it->second.doing_direct_conn.end()) {
580 log::warn("unable to find direct connection to remove: {}", address);
581 return false;
582 }
583
584 /* Let see if the device was connected due to Target Announcements.*/
585 bool is_targeted_announcement_enabled = !it->second.doing_targeted_announcements_conn.empty();
586
587 // this will free the alarm
588 it->second.doing_direct_conn.erase(app_it);
589
590 if (is_anyone_interested_to_use_accept_list(it)) {
591 if (connection_timeout) {
592 /* In such case we need to add device back to allow list because, when connection timeout
593 * out, the lower layer removes device from the allow list.
594 */
595 ACL_AcceptLeConnectionFrom(BTM_Sec_GetAddressWithType(address), false /* is_direct */);
596 }
597 return true;
598 }
599
600 // no more apps interested - remove from acceptlist
601 ACL_IgnoreLeConnectionFrom(BTM_Sec_GetAddressWithType(address));
602
603 if (!is_targeted_announcement_enabled) {
604 bgconn_dev.erase(it);
605 } else {
606 it->second.is_in_accept_list = false;
607 }
608
609 return true;
610 }
611
dump(int fd)612 void dump(int fd) {
613 dprintf(fd, "\nconnection_manager state:\n");
614 if (bgconn_dev.empty()) {
615 dprintf(fd, "\tno Low Energy connection attempts\n");
616 return;
617 }
618
619 dprintf(fd, "\tdevices attempting connection: %d", (int)bgconn_dev.size());
620 for (const auto& entry : bgconn_dev) {
621 // TODO: confirm whether we need to replace this
622 dprintf(fd, "\n\t * %s:\t\tin_accept_list: %s\t cap_targeted_announcements: %s",
623 entry.first.ToRedactedStringForLogging().c_str(),
624 entry.second.is_in_accept_list ? "true" : "false",
625 entry.second.doing_targeted_announcements_conn.empty() ? "false" : "true");
626
627 if (!entry.second.doing_direct_conn.empty()) {
628 dprintf(fd, "\n\t\tapps doing direct connect: ");
629 for (const auto& id : entry.second.doing_direct_conn) {
630 dprintf(fd, "%s (%d), ", get_client_name(id.first).c_str(), id.first);
631 }
632 }
633
634 if (!entry.second.doing_bg_conn.empty()) {
635 dprintf(fd, "\n\t\tapps doing background connect: ");
636 for (const auto& id : entry.second.doing_bg_conn) {
637 dprintf(fd, "%s (%d), ", get_client_name(id).c_str(), id);
638 }
639 }
640 }
641 dprintf(fd, "\n");
642 }
643
644 } // namespace connection_manager
645