• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2019 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 <frameworks/base/core/proto/android/bluetooth/enums.pb.h>
20 #include <frameworks/base/core/proto/android/bluetooth/hci/enums.pb.h>
21 
22 #include "bt_types.h"
23 #include "btm_int.h"
24 #include "common/metrics.h"
25 #include "device/include/controller.h"
26 #include "l2c_int.h"
27 #include "stack/gatt/connection_manager.h"
28 #include "stack/include/hcimsgs.h"
29 
30 extern void btm_ble_advertiser_notify_terminated_legacy(
31     uint8_t status, uint16_t connection_handle);
32 
33 /** This function get BLE connection state */
btm_ble_get_conn_st(void)34 tBTM_BLE_CONN_ST btm_ble_get_conn_st(void) {
35   return btm_cb.ble_ctr_cb.conn_state;
36 }
37 
38 /** This function set BLE connection state */
btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st)39 void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st) {
40   btm_cb.ble_ctr_cb.conn_state = new_st;
41 
42   if (new_st == BLE_CONNECTING)
43     btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT);
44   else
45     btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
46 }
47 
btm_send_hci_create_connection(uint16_t scan_int,uint16_t scan_win,uint8_t init_filter_policy,uint8_t addr_type_peer,const RawAddress & bda_peer,uint8_t addr_type_own,uint16_t conn_int_min,uint16_t conn_int_max,uint16_t conn_latency,uint16_t conn_timeout,uint16_t min_ce_len,uint16_t max_ce_len,uint8_t initiating_phys)48 void btm_send_hci_create_connection(
49     uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
50     uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
51     uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
52     uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
53     uint8_t initiating_phys) {
54   if (controller_get_interface()->supports_ble_extended_advertising()) {
55     EXT_CONN_PHY_CFG phy_cfg[3];  // maximum three phys
56 
57     int phy_cnt =
58         std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
59             .count();
60 
61     LOG_ASSERT(phy_cnt <= 3) << "More than three phys provided";
62     // TODO(jpawlowski): tune parameters for different transports
63     for (int i = 0; i < phy_cnt; i++) {
64       phy_cfg[i].scan_int = scan_int;
65       phy_cfg[i].scan_win = scan_win;
66       phy_cfg[i].conn_int_min = conn_int_min;
67       phy_cfg[i].conn_int_max = conn_int_max;
68       phy_cfg[i].conn_latency = conn_latency;
69       phy_cfg[i].sup_timeout = conn_timeout;
70       phy_cfg[i].min_ce_len = min_ce_len;
71       phy_cfg[i].max_ce_len = max_ce_len;
72     }
73 
74     addr_type_peer &= ~BLE_ADDR_TYPE_ID_BIT;
75     btsnd_hcic_ble_ext_create_conn(init_filter_policy, addr_type_own,
76                                    addr_type_peer, bda_peer, initiating_phys,
77                                    phy_cfg);
78   } else {
79     btsnd_hcic_ble_create_ll_conn(scan_int, scan_win, init_filter_policy,
80                                   addr_type_peer, bda_peer, addr_type_own,
81                                   conn_int_min, conn_int_max, conn_latency,
82                                   conn_timeout, min_ce_len, max_ce_len);
83   }
84 
85   btm_ble_set_conn_st(BLE_CONNECTING);
86 }
87 
88 /** LE connection complete. */
btm_ble_create_ll_conn_complete(uint8_t status)89 void btm_ble_create_ll_conn_complete(uint8_t status) {
90   if (status == HCI_SUCCESS) return;
91 
92   LOG(WARNING) << "LE Create Connection attempt failed, status="
93                << loghex(status);
94 
95   if (status == HCI_ERR_COMMAND_DISALLOWED) {
96     btm_ble_set_conn_st(BLE_CONNECTING);
97     LOG(ERROR) << "LE Create Connection - command disallowed";
98   } else {
99     btm_ble_set_conn_st(BLE_CONN_IDLE);
100     btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status);
101   }
102 }
103 
104 /** LE connection complete. */
btm_ble_conn_complete(uint8_t * p,UNUSED_ATTR uint16_t evt_len,bool enhanced)105 void btm_ble_conn_complete(uint8_t* p, UNUSED_ATTR uint16_t evt_len,
106                            bool enhanced) {
107 #if (BLE_PRIVACY_SPT == TRUE)
108   uint8_t peer_addr_type;
109 #endif
110   RawAddress local_rpa, peer_rpa;
111   uint8_t role, status, bda_type;
112   uint16_t handle;
113   RawAddress bda;
114   uint16_t conn_interval, conn_latency, conn_timeout;
115   bool match = false;
116 
117   STREAM_TO_UINT8(status, p);
118   STREAM_TO_UINT16(handle, p);
119   STREAM_TO_UINT8(role, p);
120   STREAM_TO_UINT8(bda_type, p);
121   STREAM_TO_BDADDR(bda, p);
122   if (enhanced) {
123     STREAM_TO_BDADDR(local_rpa, p);
124     STREAM_TO_BDADDR(peer_rpa, p);
125   }
126   STREAM_TO_UINT16(conn_interval, p);
127   STREAM_TO_UINT16(conn_latency, p);
128   STREAM_TO_UINT16(conn_timeout, p);
129   handle = HCID_GET_HANDLE(handle);
130 
131   uint32_t hci_ble_event =
132       enhanced ? android::bluetooth::hci::BLE_EVT_ENHANCED_CONN_COMPLETE_EVT
133                : android::bluetooth::hci::BLE_EVT_CONN_COMPLETE_EVT;
134 
135   if (status == HCI_SUCCESS) {
136 #if (BLE_PRIVACY_SPT == TRUE)
137     peer_addr_type = bda_type;
138     bool addr_is_rpa =
139         (peer_addr_type == BLE_ADDR_RANDOM && BTM_BLE_IS_RESOLVE_BDA(bda));
140 
141     /* We must translate whatever address we received into the "pseudo" address.
142      * i.e. if we bonded with device that was using RPA for first connection,
143      * "pseudo" address is equal to this RPA. If it later decides to use Public
144      * address, or Random Static Address, we convert it into the "pseudo"
145      * address here. */
146     if (!addr_is_rpa || peer_addr_type & BLE_ADDR_TYPE_ID_BIT) {
147       match = btm_identity_addr_to_random_pseudo(&bda, &bda_type, true);
148     }
149 
150     /* possiblly receive connection complete with resolvable random while
151        the device has been paired */
152     if (!match && addr_is_rpa) {
153       tBTM_SEC_DEV_REC* match_rec = btm_ble_resolve_random_addr(bda);
154       if (match_rec) {
155         LOG(INFO) << __func__ << ": matched and resolved random address";
156         match = true;
157         match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
158         match_rec->ble.cur_rand_addr = bda;
159         if (!btm_ble_init_pseudo_addr(match_rec, bda)) {
160           /* assign the original address to be the current report address */
161           bda = match_rec->ble.pseudo_addr;
162           bda_type = match_rec->ble.ble_addr_type;
163         } else {
164           bda = match_rec->bd_addr;
165         }
166       } else {
167         LOG(INFO) << __func__ << ": unable to match and resolve random address";
168       }
169     }
170 #endif
171     // Log for the HCI success case after resolving Bluetooth address
172     bluetooth::common::LogLinkLayerConnectionEvent(
173         &bda, handle, android::bluetooth::DIRECTION_UNKNOWN,
174         android::bluetooth::LINK_TYPE_ACL, android::bluetooth::hci::CMD_UNKNOWN,
175         android::bluetooth::hci::EVT_BLE_META, hci_ble_event, status,
176         android::bluetooth::hci::STATUS_UNKNOWN);
177 
178     if (role == HCI_ROLE_MASTER) {
179       btm_ble_set_conn_st(BLE_CONN_IDLE);
180     }
181 
182     connection_manager::on_connection_complete(bda);
183     btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type,
184                       match);
185 
186     l2cble_conn_comp(handle, role, bda, bda_type, conn_interval, conn_latency,
187                      conn_timeout);
188 
189 #if (BLE_PRIVACY_SPT == TRUE)
190     if (enhanced) {
191       btm_ble_refresh_local_resolvable_private_addr(bda, local_rpa);
192 
193       if (peer_addr_type & BLE_ADDR_TYPE_ID_BIT)
194         btm_ble_refresh_peer_resolvable_private_addr(bda, peer_rpa,
195                                                      BLE_ADDR_RANDOM);
196     }
197 #endif
198   } else {
199     // Log for non HCI success case
200     bluetooth::common::LogLinkLayerConnectionEvent(
201         &bda, handle, android::bluetooth::DIRECTION_UNKNOWN,
202         android::bluetooth::LINK_TYPE_ACL, android::bluetooth::hci::CMD_UNKNOWN,
203         android::bluetooth::hci::EVT_BLE_META, hci_ble_event, status,
204         android::bluetooth::hci::STATUS_UNKNOWN);
205 
206     role = HCI_ROLE_UNKNOWN;
207     if (status != HCI_ERR_ADVERTISING_TIMEOUT) {
208       btm_ble_set_conn_st(BLE_CONN_IDLE);
209 #if (BLE_PRIVACY_SPT == TRUE)
210       btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, true);
211 #endif
212     } else {
213 #if (BLE_PRIVACY_SPT == TRUE)
214       btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
215       btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true);
216 #endif
217     }
218   }
219 
220   btm_ble_update_mode_operation(role, &bda, status);
221 
222   if (role == HCI_ROLE_SLAVE)
223     btm_ble_advertiser_notify_terminated_legacy(status, handle);
224 }
225 
btm_ble_create_conn_cancel()226 void btm_ble_create_conn_cancel() {
227   btsnd_hcic_ble_create_conn_cancel();
228   btm_ble_set_conn_st(BLE_CONN_CANCEL);
229 }
230 
btm_ble_create_conn_cancel_complete(uint8_t * p)231 void btm_ble_create_conn_cancel_complete(uint8_t* p) {
232   uint8_t status;
233   STREAM_TO_UINT8(status, p);
234   if (status != HCI_SUCCESS) {
235     // Only log errors to prevent log spam due to whitelist connections
236     bluetooth::common::LogLinkLayerConnectionEvent(
237         nullptr, bluetooth::common::kUnknownConnectionHandle,
238         android::bluetooth::DIRECTION_OUTGOING,
239         android::bluetooth::LINK_TYPE_ACL,
240         android::bluetooth::hci::CMD_BLE_CREATE_CONN_CANCEL,
241         android::bluetooth::hci::EVT_COMMAND_COMPLETE,
242         android::bluetooth::hci::BLE_EVT_UNKNOWN, status,
243         android::bluetooth::hci::STATUS_UNKNOWN);
244   }
245 
246   if (status == HCI_ERR_COMMAND_DISALLOWED) {
247     /* This is a sign that logic around keeping connection state is broken */
248     LOG(ERROR)
249         << "Attempt to cancel LE connection, when no connection is pending.";
250     if (btm_ble_get_conn_st() == BLE_CONN_CANCEL) {
251       btm_ble_set_conn_st(BLE_CONN_IDLE);
252       btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, nullptr, status);
253     }
254   }
255 }
256