1 /*
2 * Copyright 2020 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 #include <cstdint>
18
19 #include "osi/include/log.h"
20 #include "stack/btm/btm_ble_int.h"
21 #include "stack/btm/btm_dev.h"
22 #include "stack/btm/btm_sec.h"
23 #include "stack/gatt/connection_manager.h"
24 #include "stack/include/acl_api.h"
25 #include "stack/include/bt_types.h"
26 #include "stack/include/hcidefs.h"
27 #include "stack/include/l2cap_hci_link_interface.h"
28
29 extern tBTM_CB btm_cb;
30
31 void btm_ble_advertiser_notify_terminated_legacy(uint8_t status,
32 uint16_t connection_handle);
33 void btm_ble_increment_link_topology_mask(uint8_t link_role);
34
35 bool maybe_resolve_address(RawAddress* bda, tBLE_ADDR_TYPE* bda_type);
36
acl_ble_common_connection(const tBLE_BD_ADDR & address_with_type,uint16_t handle,tHCI_ROLE role,bool is_in_security_db,uint16_t conn_interval,uint16_t conn_latency,uint16_t conn_timeout)37 static bool acl_ble_common_connection(const tBLE_BD_ADDR& address_with_type,
38 uint16_t handle, tHCI_ROLE role,
39 bool is_in_security_db,
40 uint16_t conn_interval,
41 uint16_t conn_latency,
42 uint16_t conn_timeout) {
43 if (role == HCI_ROLE_CENTRAL) {
44 btm_cb.ble_ctr_cb.set_connection_state_idle();
45 btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
46 }
47
48 // Inform any applications that a connection has completed.
49 connection_manager::on_connection_complete(address_with_type.bda);
50
51 // Allocate or update the security device record for this device
52 btm_ble_connected(address_with_type.bda, handle, HCI_ENCRYPT_MODE_DISABLED,
53 role, address_with_type.type, is_in_security_db);
54
55 // Update the link topology information for our device
56 btm_ble_increment_link_topology_mask(role);
57
58 // Inform l2cap of a potential connection.
59 if (!l2cble_conn_comp(handle, role, address_with_type.bda,
60 address_with_type.type, conn_interval, conn_latency,
61 conn_timeout)) {
62 btm_sec_disconnect(handle, HCI_ERR_NO_CONNECTION);
63 LOG_WARN("Unable to complete l2cap connection");
64 return false;
65 }
66
67 btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, true);
68
69 /* Tell BTM Acl management about the link */
70 btm_acl_created(address_with_type.bda, handle, role, BT_TRANSPORT_LE);
71
72 return true;
73 }
74
acl_ble_connection_complete(const tBLE_BD_ADDR & address_with_type,uint16_t handle,tHCI_ROLE role,bool match,uint16_t conn_interval,uint16_t conn_latency,uint16_t conn_timeout)75 void acl_ble_connection_complete(const tBLE_BD_ADDR& address_with_type,
76 uint16_t handle, tHCI_ROLE role, bool match,
77 uint16_t conn_interval, uint16_t conn_latency,
78 uint16_t conn_timeout) {
79 if (!acl_ble_common_connection(address_with_type, handle, role, match,
80 conn_interval, conn_latency, conn_timeout)) {
81 LOG_WARN("Unable to create non enhanced ble acl connection");
82 return;
83 }
84
85 btm_ble_update_mode_operation(role, &address_with_type.bda, HCI_SUCCESS);
86
87 if (role == HCI_ROLE_PERIPHERAL)
88 btm_ble_advertiser_notify_terminated_legacy(HCI_SUCCESS, handle);
89 }
90
acl_ble_enhanced_connection_complete(const tBLE_BD_ADDR & address_with_type,uint16_t handle,tHCI_ROLE role,bool match,uint16_t conn_interval,uint16_t conn_latency,uint16_t conn_timeout,const RawAddress & local_rpa,const RawAddress & peer_rpa,uint8_t peer_addr_type)91 void acl_ble_enhanced_connection_complete(
92 const tBLE_BD_ADDR& address_with_type, uint16_t handle, tHCI_ROLE role,
93 bool match, uint16_t conn_interval, uint16_t conn_latency,
94 uint16_t conn_timeout, const RawAddress& local_rpa,
95 const RawAddress& peer_rpa, uint8_t peer_addr_type) {
96 if (!acl_ble_common_connection(address_with_type, handle, role, match,
97 conn_interval, conn_latency, conn_timeout)) {
98 LOG_WARN("Unable to create enhanced ble acl connection");
99 return;
100 }
101
102 btm_ble_refresh_local_resolvable_private_addr(address_with_type.bda,
103 local_rpa);
104
105 if (peer_addr_type & BLE_ADDR_TYPE_ID_BIT)
106 btm_ble_refresh_peer_resolvable_private_addr(
107 address_with_type.bda, peer_rpa, tBTM_SEC_BLE::BTM_BLE_ADDR_RRA);
108 btm_ble_update_mode_operation(role, &address_with_type.bda, HCI_SUCCESS);
109
110 if (role == HCI_ROLE_PERIPHERAL)
111 btm_ble_advertiser_notify_terminated_legacy(HCI_SUCCESS, handle);
112 }
113
maybe_resolve_received_address(const tBLE_BD_ADDR & address_with_type,tBLE_BD_ADDR * resolved_address_with_type)114 static bool maybe_resolve_received_address(
115 const tBLE_BD_ADDR& address_with_type,
116 tBLE_BD_ADDR* resolved_address_with_type) {
117 ASSERT(resolved_address_with_type != nullptr);
118
119 *resolved_address_with_type = address_with_type;
120 return maybe_resolve_address(&resolved_address_with_type->bda,
121 &resolved_address_with_type->type);
122 }
123
acl_ble_enhanced_connection_complete_from_shim(const tBLE_BD_ADDR & address_with_type,uint16_t handle,tHCI_ROLE role,uint16_t conn_interval,uint16_t conn_latency,uint16_t conn_timeout,const RawAddress & local_rpa,const RawAddress & peer_rpa,uint8_t peer_addr_type)124 void acl_ble_enhanced_connection_complete_from_shim(
125 const tBLE_BD_ADDR& address_with_type, uint16_t handle, tHCI_ROLE role,
126 uint16_t conn_interval, uint16_t conn_latency, uint16_t conn_timeout,
127 const RawAddress& local_rpa, const RawAddress& peer_rpa,
128 uint8_t peer_addr_type) {
129 tBLE_BD_ADDR resolved_address_with_type;
130 const bool is_in_security_db = maybe_resolve_received_address(
131 address_with_type, &resolved_address_with_type);
132
133 acl_ble_enhanced_connection_complete(resolved_address_with_type, handle, role,
134 is_in_security_db, conn_interval,
135 conn_latency, conn_timeout, local_rpa,
136 peer_rpa, peer_addr_type);
137
138 // The legacy stack continues the LE connection after the read remote version
139 // complete has been received.
140 l2cble_notify_le_connection(address_with_type.bda);
141 l2cble_use_preferred_conn_params(address_with_type.bda);
142 }
143
acl_ble_connection_fail(const tBLE_BD_ADDR & address_with_type,uint16_t handle,bool enhanced,tHCI_STATUS status)144 void acl_ble_connection_fail(const tBLE_BD_ADDR& address_with_type,
145 uint16_t handle, bool enhanced,
146 tHCI_STATUS status) {
147 if (status != HCI_ERR_ADVERTISING_TIMEOUT) {
148 btm_cb.ble_ctr_cb.set_connection_state_idle();
149 btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
150 btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, true);
151 } else {
152 btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
153 btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true);
154 }
155 btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, &address_with_type.bda,
156 status);
157 }
158
159 void gatt_notify_conn_update(const RawAddress& remote, uint16_t interval,
160 uint16_t latency, uint16_t timeout,
161 tHCI_STATUS status);
acl_ble_update_event_received(tHCI_STATUS status,uint16_t handle,uint16_t interval,uint16_t latency,uint16_t timeout)162 void acl_ble_update_event_received(tHCI_STATUS status, uint16_t handle,
163 uint16_t interval, uint16_t latency,
164 uint16_t timeout) {
165 l2cble_process_conn_update_evt(handle, status, interval, latency, timeout);
166
167 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle);
168
169 if (!p_dev_rec) return;
170
171 gatt_notify_conn_update(p_dev_rec->ble.pseudo_addr, interval, latency,
172 timeout, status);
173 }
174