1 /*
2 * Copyright 2024 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 "stack/rnr/remote_name_request.h"
18
19 #include <bluetooth/log.h>
20 #include <com_android_bluetooth_flags.h>
21
22 #include "btif/include/btif_config.h"
23 #include "main/shim/acl_api.h"
24 #include "stack/btm/btm_dev.h"
25 #include "stack/btm/btm_int_types.h"
26 #include "stack/btm/btm_sec.h"
27 #include "stack/btm/security_device_record.h"
28 #include "stack/include/btm_client_interface.h"
29
30 using namespace bluetooth;
31
32 extern tBTM_CB btm_cb;
33
34 tBTM_STATUS btm_ble_read_remote_name(const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb);
35 bool btm_ble_cancel_remote_name(const RawAddress& remote_bda);
36
BTM_SecAddRmtNameNotifyCallback(tBTM_RMT_NAME_CALLBACK * p_callback)37 bool BTM_SecAddRmtNameNotifyCallback(tBTM_RMT_NAME_CALLBACK* p_callback) {
38 int i;
39
40 for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
41 if (btm_cb.rnr.p_rmt_name_callback[i] == NULL) {
42 btm_cb.rnr.p_rmt_name_callback[i] = p_callback;
43 return true;
44 }
45 }
46
47 return false;
48 }
49
BTM_SecDeleteRmtNameNotifyCallback(tBTM_RMT_NAME_CALLBACK * p_callback)50 bool BTM_SecDeleteRmtNameNotifyCallback(tBTM_RMT_NAME_CALLBACK* p_callback) {
51 int i;
52
53 for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
54 if (btm_cb.rnr.p_rmt_name_callback[i] == p_callback) {
55 btm_cb.rnr.p_rmt_name_callback[i] = NULL;
56 return true;
57 }
58 }
59
60 return false;
61 }
62
BTM_IsRemoteNameKnown(const RawAddress & bd_addr,tBT_TRANSPORT)63 bool BTM_IsRemoteNameKnown(const RawAddress& bd_addr, tBT_TRANSPORT /* transport */) {
64 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
65 return (p_dev_rec == nullptr) ? false : p_dev_rec->sec_rec.is_name_known();
66 }
67
68 /*******************************************************************************
69 *
70 * Function btm_inq_rmt_name_failed_cancelled
71 *
72 * Description This function is if timeout expires or request is cancelled
73 * while getting remote name. This is done for devices that
74 * incorrectly do not report operation failure
75 *
76 * Returns void
77 *
78 ******************************************************************************/
btm_inq_rmt_name_failed_cancelled(void)79 static void btm_inq_rmt_name_failed_cancelled(void) {
80 log::error("remname_active={}", btm_cb.rnr.remname_active);
81
82 if (btm_cb.rnr.remname_active) {
83 btm_process_remote_name(&btm_cb.rnr.remname_bda, NULL, 0, HCI_ERR_UNSPECIFIED);
84 }
85
86 btm_sec_rmt_name_request_complete(NULL, NULL, HCI_ERR_UNSPECIFIED);
87 }
88
btm_inq_remote_name_timer_timeout(void *)89 void btm_inq_remote_name_timer_timeout(void* /* data */) { btm_inq_rmt_name_failed_cancelled(); }
90
91 /*******************************************************************************
92 *
93 * Function btm_initiate_rem_name
94 *
95 * Description This function looks initiates a remote name request. It is
96 * called either by GAP or by the API call
97 * BTM_ReadRemoteDeviceName.
98 *
99 * Input Params: remote_bda: Remote address to execute RNR
100 * timeout_ms: Internal timeout to await response
101 * * p_cb: Callback function called when
102 * tBTM_STATUS::BTM_CMD_STARTED is returned.
103 * A pointer to tBTM_REMOTE_DEV_NAME is
104 * passed to the callback.
105 *
106 * Returns
107 * tBTM_STATUS::BTM_CMD_STARTED is returned if the request was sent to HCI.
108 * and the callback will be called.
109 * BTM_BUSY if already in progress
110 * BTM_NO_RESOURCES if could not allocate resources to start
111 * the command
112 * BTM_WRONG_MODE if the device is not up.
113 *
114 ******************************************************************************/
get_clock_offset_from_storage(const RawAddress & remote_bda)115 static uint16_t get_clock_offset_from_storage(const RawAddress& remote_bda) {
116 int clock_offset_in_cfg = 0;
117 return btif_get_device_clockoffset(remote_bda, &clock_offset_in_cfg)
118 ? static_cast<uint16_t>(clock_offset_in_cfg)
119 : 0;
120 }
121
btm_initiate_rem_name(const RawAddress & remote_bda,uint64_t timeout_ms,tBTM_NAME_CMPL_CB * p_cb)122 static tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint64_t timeout_ms,
123 tBTM_NAME_CMPL_CB* p_cb) {
124 /*** Make sure the device is ready ***/
125 if (!get_btm_client_interface().local.BTM_IsDeviceUp()) {
126 return tBTM_STATUS::BTM_WRONG_MODE;
127 }
128 if (btm_cb.rnr.remname_active) {
129 return tBTM_STATUS::BTM_BUSY;
130 }
131
132 uint16_t clock_offset = get_clock_offset_from_storage(remote_bda);
133 uint8_t page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
134 uint8_t page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
135
136 /* If the database entry exists for the device, use its clock offset */
137 tINQ_DB_ENT* p_i = btm_inq_db_find(remote_bda);
138 if (p_i && (p_i->inq_info.results.inq_result_type & BT_DEVICE_TYPE_BREDR)) {
139 tBTM_INQ_INFO* p_cur = &p_i->inq_info;
140 clock_offset = p_cur->results.clock_offset | BTM_CLOCK_OFFSET_VALID;
141 if (0 == (p_cur->results.clock_offset & BTM_CLOCK_OFFSET_VALID)) {
142 clock_offset = get_clock_offset_from_storage(remote_bda);
143 }
144 page_scan_rep_mode = p_cur->results.page_scan_rep_mode;
145 if (com::android::bluetooth::flags::rnr_validate_page_scan_repetition_mode() &&
146 page_scan_rep_mode >= HCI_PAGE_SCAN_REP_MODE_RESERVED_START) {
147 log::info(
148 "Invalid page scan repetition mode {} from remote_bda:{}, "
149 "fallback to R1",
150 page_scan_rep_mode, remote_bda);
151 page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
152 }
153 page_scan_mode = p_cur->results.page_scan_mode;
154 }
155
156 bluetooth::shim::ACL_RemoteNameRequest(remote_bda, page_scan_rep_mode, page_scan_mode,
157 clock_offset);
158
159 btm_cb.rnr.p_remname_cmpl_cb = p_cb;
160 btm_cb.rnr.remname_bda = remote_bda;
161 btm_cb.rnr.remname_dev_type = BT_DEVICE_TYPE_BREDR;
162 btm_cb.rnr.remname_active = true;
163
164 alarm_set_on_mloop(btm_cb.rnr.remote_name_timer, timeout_ms, btm_inq_remote_name_timer_timeout,
165 NULL);
166
167 return tBTM_STATUS::BTM_CMD_STARTED;
168 }
169
170 /*******************************************************************************
171 *
172 * Function btm_process_remote_name
173 *
174 * Description This function is called when a remote name is received from
175 * the device. If remote names are cached, it updates the
176 * inquiry database.
177 *
178 * Returns void
179 *
180 ******************************************************************************/
btm_process_remote_name(const RawAddress * bda,const BD_NAME bdn,uint16_t,tHCI_STATUS hci_status)181 void btm_process_remote_name(const RawAddress* bda, const BD_NAME bdn, uint16_t /* evt_len */,
182 tHCI_STATUS hci_status) {
183 tBTM_REMOTE_DEV_NAME rem_name = {
184 .bd_addr = bda ? *bda : RawAddress::kEmpty,
185 .remote_bd_name = {},
186 .btm_status = tBTM_STATUS::BTM_BAD_VALUE_RET,
187 .hci_status = hci_status,
188 };
189
190 bool on_le_link;
191 if (com::android::bluetooth::flags::rnr_store_device_type()) {
192 on_le_link = (btm_cb.rnr.remname_dev_type == BT_DEVICE_TYPE_BLE);
193 } else {
194 on_le_link = get_btm_client_interface().ble.BTM_UseLeLink(btm_cb.rnr.remname_bda);
195 }
196
197 /* If the inquire BDA and remote DBA are the same, then stop the timer and set
198 * the active to false */
199 if (btm_cb.rnr.remname_active) {
200 if (rem_name.bd_addr == RawAddress::kEmpty || rem_name.bd_addr == btm_cb.rnr.remname_bda) {
201 log::info("RNR received expected name bd_addr:{} hci_status:{} le_link:{}",
202 rem_name.bd_addr.ToRedactedStringForLogging(), hci_status_code_text(hci_status),
203 on_le_link);
204
205 if (on_le_link && hci_status == HCI_ERR_UNSPECIFIED) {
206 btm_ble_cancel_remote_name(btm_cb.rnr.remname_bda);
207 }
208 alarm_cancel(btm_cb.rnr.remote_name_timer);
209 /* Clean up and return the status if the command was not successful */
210 /* Note: If part of the inquiry, the name is not stored, and the */
211 /* inquiry complete callback is called. */
212
213 if (hci_status == HCI_SUCCESS) {
214 /* Copy the name from the data stream into the return structure */
215 /* Note that even if it is not being returned, it is used as a */
216 /* temporary buffer. */
217 rem_name.btm_status = tBTM_STATUS::BTM_SUCCESS;
218 if (bdn) {
219 bd_name_copy(rem_name.remote_bd_name, bdn);
220 } else {
221 log::warn("Received null name from remote device bd_addr:{}",
222 rem_name.bd_addr.ToRedactedStringForLogging());
223 }
224 }
225 /* Reset the remote BDA and call callback if possible */
226 btm_cb.rnr.remname_active = false;
227 btm_cb.rnr.remname_bda = RawAddress::kEmpty;
228 btm_cb.rnr.remname_dev_type = BT_DEVICE_TYPE_UNKNOWN;
229
230 tBTM_NAME_CMPL_CB* p_cb = btm_cb.rnr.p_remname_cmpl_cb;
231 btm_cb.rnr.p_remname_cmpl_cb = nullptr;
232 if (p_cb) {
233 (p_cb)(&rem_name);
234 }
235 } else {
236 log::warn("RNR received UNKNOWN name bd_addr:{} hci_status:{} le_link:{}",
237 rem_name.bd_addr.ToRedactedStringForLogging(), hci_status_code_text(hci_status),
238 on_le_link);
239 }
240 } else {
241 log::info(
242 "RNR received UNEXPECTED name bd_addr:{} inq_addr:{} hci_status:{} "
243 "le_link:{} rnr_active:{}",
244 rem_name.bd_addr.ToRedactedStringForLogging(),
245 btm_cb.rnr.remname_bda.ToRedactedStringForLogging(), hci_status_code_text(hci_status),
246 on_le_link, btm_cb.rnr.remname_active);
247 }
248 }
249
250 /*******************************************************************************
251 *
252 * Function BTM_ReadRemoteDeviceName
253 *
254 * Description This function initiates a remote device HCI command to the
255 * controller and calls the callback when the process has
256 * completed.
257 *
258 * Input Params: remote_bda - device address of name to retrieve
259 * p_cb - callback function called when
260 * tBTM_STATUS::BTM_CMD_STARTED is returned.
261 * A pointer to tBTM_REMOTE_DEV_NAME is
262 * passed to the callback.
263 *
264 * Returns
265 * tBTM_STATUS::BTM_CMD_STARTED is returned if the request was successfully
266 * sent to HCI.
267 * tBTM_STATUS::BTM_BUSY if already in progress
268 * tBTM_STATUS::BTM_UNKNOWN_ADDR if device address is bad
269 * tBTM_STATUS::BTM_NO_RESOURCES if could not allocate resources to start
270 * the command
271 * tBTM_STATUS::BTM_WRONG_MODE if the device is not up.
272 *
273 ******************************************************************************/
274 #define BTM_EXT_RMT_NAME_TIMEOUT_MS (40 * 1000) /* 40 seconds */
BTM_ReadRemoteDeviceName(const RawAddress & remote_bda,tBTM_NAME_CMPL_CB * p_cb,tBT_TRANSPORT transport)275 tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb,
276 tBT_TRANSPORT transport) {
277 log::verbose("bd addr {}", remote_bda);
278 /* Use LE transport when LE is the only available option */
279 if (transport == BT_TRANSPORT_LE) {
280 return btm_ble_read_remote_name(remote_bda, p_cb);
281 }
282 /* Use classic transport for BR/EDR and Dual Mode devices */
283 return btm_initiate_rem_name(remote_bda, BTM_EXT_RMT_NAME_TIMEOUT_MS, p_cb);
284 }
285
286 /*******************************************************************************
287 *
288 * Function BTM_CancelRemoteDeviceName
289 *
290 * Description This function initiates the cancel request for the specified
291 * remote device.
292 *
293 * Input Params: None
294 *
295 * Returns
296 * tBTM_STATUS::BTM_CMD_STARTED is returned if the request was successfully
297 * sent to HCI.
298 * tBTM_STATUS::BTM_NO_RESOURCES if could not allocate resources to start
299 * the command
300 * tBTM_STATUS::BTM_WRONG_MODE if there is not an active remote name
301 * request.
302 *
303 ******************************************************************************/
BTM_CancelRemoteDeviceName(void)304 tBTM_STATUS BTM_CancelRemoteDeviceName(void) {
305 log::verbose("");
306 bool is_le;
307
308 /* Make sure there is not already one in progress */
309 if (!btm_cb.rnr.remname_active) {
310 return tBTM_STATUS::BTM_WRONG_MODE;
311 }
312
313 if (com::android::bluetooth::flags::rnr_store_device_type()) {
314 is_le = (btm_cb.rnr.remname_dev_type == BT_DEVICE_TYPE_BLE);
315 } else {
316 is_le = get_btm_client_interface().ble.BTM_UseLeLink(btm_cb.rnr.remname_bda);
317 }
318
319 if (is_le) {
320 /* Cancel remote name request for LE device, and process remote name
321 * callback. */
322 btm_inq_rmt_name_failed_cancelled();
323 } else {
324 bluetooth::shim::ACL_CancelRemoteNameRequest(btm_cb.rnr.remname_bda);
325 btm_process_remote_name(&btm_cb.rnr.remname_bda, nullptr, 0, HCI_ERR_UNSPECIFIED);
326 }
327 return tBTM_STATUS::BTM_CMD_STARTED;
328 }
329
BTM_SecAddRmtNameNotifyCallback(tBTM_RMT_NAME_CALLBACK * p_callback)330 bool bluetooth::stack::rnr::Impl::BTM_SecAddRmtNameNotifyCallback(
331 tBTM_RMT_NAME_CALLBACK* p_callback) {
332 return ::BTM_SecAddRmtNameNotifyCallback(p_callback);
333 }
334
BTM_SecDeleteRmtNameNotifyCallback(tBTM_RMT_NAME_CALLBACK * p_callback)335 bool bluetooth::stack::rnr::Impl::BTM_SecDeleteRmtNameNotifyCallback(
336 tBTM_RMT_NAME_CALLBACK* p_callback) {
337 return ::BTM_SecDeleteRmtNameNotifyCallback(p_callback);
338 }
339
BTM_IsRemoteNameKnown(const RawAddress & bd_addr,tBT_TRANSPORT transport)340 bool bluetooth::stack::rnr::Impl::BTM_IsRemoteNameKnown(const RawAddress& bd_addr,
341 tBT_TRANSPORT transport) {
342 return ::BTM_IsRemoteNameKnown(bd_addr, transport);
343 }
344
BTM_ReadRemoteDeviceName(const RawAddress & remote_bda,tBTM_NAME_CMPL_CB * p_cb,tBT_TRANSPORT transport)345 tBTM_STATUS bluetooth::stack::rnr::Impl::BTM_ReadRemoteDeviceName(const RawAddress& remote_bda,
346 tBTM_NAME_CMPL_CB* p_cb,
347 tBT_TRANSPORT transport) {
348 return ::BTM_ReadRemoteDeviceName(remote_bda, p_cb, transport);
349 }
350
BTM_CancelRemoteDeviceName()351 tBTM_STATUS bluetooth::stack::rnr::Impl::BTM_CancelRemoteDeviceName() {
352 return ::BTM_CancelRemoteDeviceName();
353 }
354
btm_process_remote_name(const RawAddress * bda,const BD_NAME bdn,uint16_t evt_len,tHCI_STATUS hci_status)355 void bluetooth::stack::rnr::Impl::btm_process_remote_name(const RawAddress* bda, const BD_NAME bdn,
356 uint16_t evt_len,
357 tHCI_STATUS hci_status) {
358 ::btm_process_remote_name(bda, bdn, evt_len, hci_status);
359 }
360
361 bluetooth::stack::rnr::Impl default_interface;
362
363 bluetooth::stack::rnr::Interface* interface_ = &default_interface;
364
get_stack_rnr_interface()365 bluetooth::stack::rnr::Interface& get_stack_rnr_interface() { return *interface_; }
366