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