1 /******************************************************************************
2 *
3 * Copyright 1999-2014 Broadcom Corporation
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 /******************************************************************************
20 *
21 * This file contains functions that handle inquiries. These include
22 * setting discoverable mode, controlling the mode of the Baseband, and
23 * maintaining a small database of inquiry responses, with API for people
24 * to browse it.
25 *
26 ******************************************************************************/
27
28 #define LOG_TAG "bluetooth"
29
30 #include <base/logging.h>
31 #include <stddef.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "advertise_data_parser.h"
37 #include "common/time_util.h"
38 #include "device/include/controller.h"
39 #include "main/shim/btm_api.h"
40 #include "main/shim/shim.h"
41 #include "osi/include/allocator.h"
42 #include "osi/include/log.h"
43 #include "osi/include/osi.h"
44 #include "stack/btm/btm_ble_int.h"
45 #include "stack/btm/btm_dev.h"
46 #include "stack/btm/btm_int_types.h"
47 #include "stack/include/acl_api.h"
48 #include "stack/include/bt_hdr.h"
49 #include "stack/include/btm_api.h"
50 #include "stack/include/btm_ble_api.h"
51 #include "stack/include/inq_hci_link_interface.h"
52 #include "types/bluetooth/uuid.h"
53 #include "types/raw_address.h"
54
55 namespace {
56 constexpr char kBtmLogTag[] = "SCAN";
57 }
58
59 extern tBTM_CB btm_cb;
60
61 extern void btm_inq_remote_name_timer_timeout(void* data);
62 extern tBTM_STATUS btm_ble_read_remote_name(const RawAddress& remote_bda,
63 tBTM_CMPL_CB* p_cb);
64 extern bool btm_ble_cancel_remote_name(const RawAddress& remote_bda);
65 extern tBTM_STATUS btm_ble_set_discoverability(uint16_t combined_mode);
66 extern tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode);
67
68 extern tBTM_STATUS btm_ble_start_inquiry(uint8_t duration);
69 extern void btm_ble_stop_inquiry(void);
70
71 using bluetooth::Uuid;
72
73 /* 3 second timeout waiting for responses */
74 #define BTM_INQ_REPLY_TIMEOUT_MS (3 * 1000)
75
76 /* TRUE to enable DEBUG traces for btm_inq */
77 #ifndef BTM_INQ_DEBUG
78 #define BTM_INQ_DEBUG FALSE
79 #endif
80
81 #define BTIF_DM_DEFAULT_INQ_MAX_DURATION 10
82
83 /******************************************************************************/
84 /* L O C A L D A T A D E F I N I T I O N S */
85 /******************************************************************************/
86 static const LAP general_inq_lap = {0x9e, 0x8b, 0x33};
87 static const LAP limited_inq_lap = {0x9e, 0x8b, 0x00};
88
89 const uint16_t BTM_EIR_UUID_LKUP_TBL[BTM_EIR_MAX_SERVICES] = {
90 UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER,
91 /* UUID_SERVCLASS_BROWSE_GROUP_DESCRIPTOR, */
92 /* UUID_SERVCLASS_PUBLIC_BROWSE_GROUP, */
93 UUID_SERVCLASS_SERIAL_PORT, UUID_SERVCLASS_LAN_ACCESS_USING_PPP,
94 UUID_SERVCLASS_DIALUP_NETWORKING, UUID_SERVCLASS_IRMC_SYNC,
95 UUID_SERVCLASS_OBEX_OBJECT_PUSH, UUID_SERVCLASS_OBEX_FILE_TRANSFER,
96 UUID_SERVCLASS_IRMC_SYNC_COMMAND, UUID_SERVCLASS_HEADSET,
97 UUID_SERVCLASS_CORDLESS_TELEPHONY, UUID_SERVCLASS_AUDIO_SOURCE,
98 UUID_SERVCLASS_AUDIO_SINK, UUID_SERVCLASS_AV_REM_CTRL_TARGET,
99 /* UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION, */
100 UUID_SERVCLASS_AV_REMOTE_CONTROL,
101 /* UUID_SERVCLASS_VIDEO_CONFERENCING, */
102 UUID_SERVCLASS_INTERCOM, UUID_SERVCLASS_FAX,
103 UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY,
104 /* UUID_SERVCLASS_WAP, */
105 /* UUID_SERVCLASS_WAP_CLIENT, */
106 UUID_SERVCLASS_PANU, UUID_SERVCLASS_NAP, UUID_SERVCLASS_GN,
107 UUID_SERVCLASS_DIRECT_PRINTING,
108 /* UUID_SERVCLASS_REFERENCE_PRINTING, */
109 UUID_SERVCLASS_IMAGING, UUID_SERVCLASS_IMAGING_RESPONDER,
110 UUID_SERVCLASS_IMAGING_AUTO_ARCHIVE, UUID_SERVCLASS_IMAGING_REF_OBJECTS,
111 UUID_SERVCLASS_HF_HANDSFREE, UUID_SERVCLASS_AG_HANDSFREE,
112 UUID_SERVCLASS_DIR_PRT_REF_OBJ_SERVICE,
113 /* UUID_SERVCLASS_REFLECTED_UI, */
114 UUID_SERVCLASS_BASIC_PRINTING, UUID_SERVCLASS_PRINTING_STATUS,
115 UUID_SERVCLASS_HUMAN_INTERFACE, UUID_SERVCLASS_CABLE_REPLACEMENT,
116 UUID_SERVCLASS_HCRP_PRINT, UUID_SERVCLASS_HCRP_SCAN,
117 /* UUID_SERVCLASS_COMMON_ISDN_ACCESS, */
118 /* UUID_SERVCLASS_VIDEO_CONFERENCING_GW, */
119 /* UUID_SERVCLASS_UDI_MT, */
120 /* UUID_SERVCLASS_UDI_TA, */
121 /* UUID_SERVCLASS_VCP, */
122 UUID_SERVCLASS_SAP, UUID_SERVCLASS_PBAP_PCE, UUID_SERVCLASS_PBAP_PSE,
123 UUID_SERVCLASS_PHONE_ACCESS, UUID_SERVCLASS_HEADSET_HS,
124 UUID_SERVCLASS_PNP_INFORMATION,
125 /* UUID_SERVCLASS_GENERIC_NETWORKING, */
126 /* UUID_SERVCLASS_GENERIC_FILETRANSFER, */
127 /* UUID_SERVCLASS_GENERIC_AUDIO, */
128 /* UUID_SERVCLASS_GENERIC_TELEPHONY, */
129 /* UUID_SERVCLASS_UPNP_SERVICE, */
130 /* UUID_SERVCLASS_UPNP_IP_SERVICE, */
131 /* UUID_SERVCLASS_ESDP_UPNP_IP_PAN, */
132 /* UUID_SERVCLASS_ESDP_UPNP_IP_LAP, */
133 /* UUID_SERVCLASS_ESDP_UPNP_IP_L2CAP, */
134 UUID_SERVCLASS_VIDEO_SOURCE, UUID_SERVCLASS_VIDEO_SINK,
135 /* UUID_SERVCLASS_VIDEO_DISTRIBUTION */
136 UUID_SERVCLASS_MESSAGE_ACCESS, UUID_SERVCLASS_MESSAGE_NOTIFICATION,
137 UUID_SERVCLASS_HDP_SOURCE, UUID_SERVCLASS_HDP_SINK};
138
139 /******************************************************************************/
140 /* L O C A L F U N C T I O N P R O T O T Y P E S */
141 /******************************************************************************/
142 static void btm_clr_inq_db(const RawAddress* p_bda);
143 void btm_clr_inq_result_flt(void);
144 static void btm_inq_rmt_name_failed_cancelled(void);
145 static tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda,
146 uint8_t origin, uint64_t timeout_ms,
147 tBTM_CMPL_CB* p_cb);
148
149 static uint8_t btm_convert_uuid_to_eir_service(uint16_t uuid16);
150 void btm_set_eir_uuid(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results);
151 static const uint8_t* btm_eir_get_uuid_list(const uint8_t* p_eir,
152 size_t eir_len, uint8_t uuid_size,
153 uint8_t* p_num_uuid,
154 uint8_t* p_uuid_list_type);
155
SendRemoteNameRequest(const RawAddress & raw_address)156 void SendRemoteNameRequest(const RawAddress& raw_address) {
157 if (bluetooth::shim::is_gd_shim_enabled()) {
158 return bluetooth::shim::SendRemoteNameRequest(raw_address);
159 } else {
160 btsnd_hcic_rmt_name_req(raw_address, HCI_PAGE_SCAN_REP_MODE_R1,
161 HCI_MANDATARY_PAGE_SCAN_MODE, 0);
162 }
163 }
164 /*******************************************************************************
165 *
166 * Function BTM_SetDiscoverability
167 *
168 * Description This function is called to set the device into or out of
169 * discoverable mode. Discoverable mode means inquiry
170 * scans are enabled. If a value of '0' is entered for window
171 * or interval, the default values are used.
172 *
173 * Returns BTM_SUCCESS if successful
174 * BTM_BUSY if a setting of the filter is already in progress
175 * BTM_NO_RESOURCES if couldn't get a memory pool buffer
176 * BTM_ILLEGAL_VALUE if a bad parameter was detected
177 * BTM_WRONG_MODE if the device is not up.
178 *
179 ******************************************************************************/
BTM_SetDiscoverability(uint16_t inq_mode)180 tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode) {
181 if (bluetooth::shim::is_gd_shim_enabled()) {
182 return bluetooth::shim::BTM_SetDiscoverability(inq_mode, 0, 0);
183 }
184
185 uint8_t scan_mode = 0;
186 uint16_t service_class;
187 uint8_t* p_cod;
188 uint8_t major, minor;
189 DEV_CLASS cod;
190 LAP temp_lap[2];
191 bool is_limited;
192 bool cod_limited;
193 uint16_t window = BTM_DEFAULT_DISC_WINDOW;
194 uint16_t interval = BTM_DEFAULT_DISC_INTERVAL;
195
196 BTM_TRACE_API("BTM_SetDiscoverability");
197 if (controller_get_interface()->supports_ble()) {
198 if (btm_ble_set_discoverability((uint16_t)(inq_mode)) == BTM_SUCCESS) {
199 btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_BLE_DISCOVERABLE_MASK);
200 btm_cb.btm_inq_vars.discoverable_mode |=
201 (inq_mode & BTM_BLE_DISCOVERABLE_MASK);
202 }
203 }
204 inq_mode &= ~BTM_BLE_DISCOVERABLE_MASK;
205
206 /*** Check mode parameter ***/
207 if (inq_mode > BTM_MAX_DISCOVERABLE) return (BTM_ILLEGAL_VALUE);
208
209 /* Make sure the controller is active */
210 if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET);
211
212 /* If the window and/or interval is '0', set to default values */
213 BTM_TRACE_API("BTM_SetDiscoverability: mode %d [NonDisc-0, Lim-1, Gen-2]",
214 inq_mode);
215
216 /* Set the IAC if needed */
217 if (inq_mode != BTM_NON_DISCOVERABLE) {
218 if (inq_mode & BTM_LIMITED_DISCOVERABLE) {
219 /* Use the GIAC and LIAC codes for limited discoverable mode */
220 memcpy(temp_lap[0], limited_inq_lap, LAP_LEN);
221 memcpy(temp_lap[1], general_inq_lap, LAP_LEN);
222
223 btsnd_hcic_write_cur_iac_lap(2, (LAP * const)temp_lap);
224 } else {
225 btsnd_hcic_write_cur_iac_lap(1, (LAP * const) & general_inq_lap);
226 }
227
228 scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
229 }
230
231 /* Send down the inquiry scan window and period if changed */
232 if ((window != btm_cb.btm_inq_vars.inq_scan_window) ||
233 (interval != btm_cb.btm_inq_vars.inq_scan_period)) {
234 btsnd_hcic_write_inqscan_cfg(interval, window);
235 btm_cb.btm_inq_vars.inq_scan_window = window;
236 btm_cb.btm_inq_vars.inq_scan_period = interval;
237 }
238
239 if (btm_cb.btm_inq_vars.connectable_mode & BTM_CONNECTABLE_MASK)
240 scan_mode |= HCI_PAGE_SCAN_ENABLED;
241
242 btsnd_hcic_write_scan_enable(scan_mode);
243 btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_DISCOVERABLE_MASK);
244 btm_cb.btm_inq_vars.discoverable_mode |= inq_mode;
245
246 /* Change the service class bit if mode has changed */
247 p_cod = BTM_ReadDeviceClass();
248 BTM_COD_SERVICE_CLASS(service_class, p_cod);
249 is_limited = (inq_mode & BTM_LIMITED_DISCOVERABLE) ? true : false;
250 cod_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false;
251 if (is_limited ^ cod_limited) {
252 BTM_COD_MINOR_CLASS(minor, p_cod);
253 BTM_COD_MAJOR_CLASS(major, p_cod);
254 if (is_limited)
255 service_class |= BTM_COD_SERVICE_LMTD_DISCOVER;
256 else
257 service_class &= ~BTM_COD_SERVICE_LMTD_DISCOVER;
258
259 FIELDS_TO_COD(cod, minor, major, service_class);
260 (void)BTM_SetDeviceClass(cod);
261 }
262
263 return (BTM_SUCCESS);
264 }
265
BTM_EnableInterlacedInquiryScan()266 void BTM_EnableInterlacedInquiryScan() {
267 if (bluetooth::shim::is_gd_shim_enabled()) {
268 bluetooth::shim::BTM_EnableInterlacedInquiryScan();
269 }
270
271 BTM_TRACE_API("BTM_EnableInterlacedInquiryScan");
272 if (!controller_get_interface()->supports_interlaced_inquiry_scan() ||
273 btm_cb.btm_inq_vars.inq_scan_type == BTM_SCAN_TYPE_INTERLACED) {
274 return;
275 }
276
277 btsnd_hcic_write_inqscan_type(BTM_SCAN_TYPE_INTERLACED);
278 btm_cb.btm_inq_vars.inq_scan_type = BTM_SCAN_TYPE_INTERLACED;
279 }
280
BTM_EnableInterlacedPageScan()281 void BTM_EnableInterlacedPageScan() {
282 if (bluetooth::shim::is_gd_shim_enabled()) {
283 bluetooth::shim::BTM_EnableInterlacedPageScan();
284 return;
285 }
286
287 BTM_TRACE_API("BTM_EnableInterlacedPageScan");
288 if (!controller_get_interface()->supports_interlaced_inquiry_scan() ||
289 btm_cb.btm_inq_vars.page_scan_type == BTM_SCAN_TYPE_INTERLACED) {
290 return;
291 }
292
293 btsnd_hcic_write_pagescan_type(BTM_SCAN_TYPE_INTERLACED);
294 btm_cb.btm_inq_vars.page_scan_type = BTM_SCAN_TYPE_INTERLACED;
295 }
296
297 /*******************************************************************************
298 *
299 * Function BTM_SetInquiryMode
300 *
301 * Description This function is called to set standard or with RSSI
302 * mode of the inquiry for local device.
303 *
304 * Output Params: mode - standard, with RSSI, extended
305 *
306 * Returns BTM_SUCCESS if successful
307 * BTM_NO_RESOURCES if couldn't get a memory pool buffer
308 * BTM_ILLEGAL_VALUE if a bad parameter was detected
309 * BTM_WRONG_MODE if the device is not up.
310 *
311 ******************************************************************************/
BTM_SetInquiryMode(uint8_t mode)312 tBTM_STATUS BTM_SetInquiryMode(uint8_t mode) {
313 if (bluetooth::shim::is_gd_shim_enabled()) {
314 return bluetooth::shim::BTM_SetInquiryMode(mode);
315 }
316
317 const controller_t* controller = controller_get_interface();
318 BTM_TRACE_API("BTM_SetInquiryMode");
319 if (mode == BTM_INQ_RESULT_STANDARD) {
320 /* mandatory mode */
321 } else if (mode == BTM_INQ_RESULT_WITH_RSSI) {
322 if (!controller->supports_rssi_with_inquiry_results())
323 return (BTM_MODE_UNSUPPORTED);
324 } else if (mode == BTM_INQ_RESULT_EXTENDED) {
325 if (!controller->supports_extended_inquiry_response())
326 return (BTM_MODE_UNSUPPORTED);
327 } else
328 return (BTM_ILLEGAL_VALUE);
329
330 if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
331
332 btsnd_hcic_write_inquiry_mode(mode);
333
334 return (BTM_SUCCESS);
335 }
336
337 /*******************************************************************************
338 *
339 * Function BTM_SetConnectability
340 *
341 * Description This function is called to set the device into or out of
342 * connectable mode. Discoverable mode means page scans are
343 * enabled.
344 *
345 * Returns BTM_SUCCESS if successful
346 * BTM_ILLEGAL_VALUE if a bad parameter is detected
347 * BTM_NO_RESOURCES if could not allocate a message buffer
348 * BTM_WRONG_MODE if the device is not up.
349 *
350 ******************************************************************************/
BTM_SetConnectability(uint16_t page_mode)351 tBTM_STATUS BTM_SetConnectability(uint16_t page_mode) {
352 if (bluetooth::shim::is_gd_shim_enabled()) {
353 return bluetooth::shim::BTM_SetConnectability(page_mode, 0, 0);
354 }
355
356 uint8_t scan_mode = 0;
357 uint16_t window = BTM_DEFAULT_CONN_WINDOW;
358 uint16_t interval = BTM_DEFAULT_CONN_INTERVAL;
359 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
360
361 BTM_TRACE_API("BTM_SetConnectability");
362
363 if (controller_get_interface()->supports_ble()) {
364 if (btm_ble_set_connectability(page_mode) != BTM_SUCCESS) {
365 return BTM_NO_RESOURCES;
366 }
367 p_inq->connectable_mode &= (~BTM_BLE_CONNECTABLE_MASK);
368 p_inq->connectable_mode |= (page_mode & BTM_BLE_CONNECTABLE_MASK);
369 }
370 page_mode &= ~BTM_BLE_CONNECTABLE_MASK;
371
372 /*** Check mode parameter ***/
373 if (page_mode != BTM_NON_CONNECTABLE && page_mode != BTM_CONNECTABLE)
374 return (BTM_ILLEGAL_VALUE);
375
376 /* Make sure the controller is active */
377 if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET);
378
379 BTM_TRACE_API("BTM_SetConnectability: mode %d [NonConn-0, Conn-1]",
380 page_mode);
381
382 /*** Only check window and duration if mode is connectable ***/
383 if (page_mode == BTM_CONNECTABLE) {
384 scan_mode |= HCI_PAGE_SCAN_ENABLED;
385 }
386
387 if ((window != p_inq->page_scan_window) ||
388 (interval != p_inq->page_scan_period)) {
389 p_inq->page_scan_window = window;
390 p_inq->page_scan_period = interval;
391 btsnd_hcic_write_pagescan_cfg(interval, window);
392 }
393
394 /* Keep the inquiry scan as previouosly set */
395 if (p_inq->discoverable_mode & BTM_DISCOVERABLE_MASK)
396 scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
397
398 btsnd_hcic_write_scan_enable(scan_mode);
399 p_inq->connectable_mode &= (~BTM_CONNECTABLE_MASK);
400 p_inq->connectable_mode |= page_mode;
401 return (BTM_SUCCESS);
402 }
403
404 /*******************************************************************************
405 *
406 * Function BTM_IsInquiryActive
407 *
408 * Description This function returns a bit mask of the current inquiry
409 * state
410 *
411 * Returns BTM_INQUIRY_INACTIVE if inactive (0)
412 * BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active
413 *
414 ******************************************************************************/
BTM_IsInquiryActive(void)415 uint16_t BTM_IsInquiryActive(void) {
416 if (bluetooth::shim::is_gd_shim_enabled()) {
417 return bluetooth::shim::BTM_IsInquiryActive();
418 }
419
420 BTM_TRACE_API("BTM_IsInquiryActive");
421
422 return (btm_cb.btm_inq_vars.inq_active);
423 }
424
425 /*******************************************************************************
426 *
427 * Function BTM_CancelInquiry
428 *
429 * Description This function cancels an inquiry if active
430 *
431 ******************************************************************************/
BTM_CancelInquiry(void)432 void BTM_CancelInquiry(void) {
433 if (bluetooth::shim::is_gd_shim_enabled()) {
434 bluetooth::shim::BTM_CancelInquiry();
435 return;
436 }
437
438 BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Classic inquiry stopped");
439
440 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
441 BTM_TRACE_API("BTM_CancelInquiry called");
442
443 CHECK(BTM_IsDeviceUp());
444
445 /* Only cancel if not in periodic mode, otherwise the caller should call
446 * BTM_CancelPeriodicMode */
447 if ((p_inq->inq_active & BTM_INQUIRY_ACTIVE_MASK) != 0) {
448 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
449 p_inq->state = BTM_INQ_INACTIVE_STATE;
450 p_inq->p_inq_results_cb = NULL; /* Do not notify caller anymore */
451 p_inq->p_inq_cmpl_cb = NULL; /* Do not notify caller anymore */
452
453 if ((p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK) != 0) {
454 bluetooth::legacy::hci::GetInterface().InquiryCancel();
455 }
456 if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
457 btm_ble_stop_inquiry();
458
459 p_inq->inq_counter++;
460 btm_clr_inq_result_flt();
461 }
462 }
463
464 /*******************************************************************************
465 *
466 * Function BTM_StartInquiry
467 *
468 * Description This function is called to start an inquiry.
469 *
470 * Parameters: p_inqparms - pointer to the inquiry information
471 * mode - GENERAL or LIMITED inquiry, BR/LE bit mask
472 * seperately
473 * duration - length in 1.28 sec intervals (If '0', the
474 * inquiry is CANCELLED)
475 * filter_cond_type - BTM_CLR_INQUIRY_FILTER,
476 * BTM_FILTER_COND_DEVICE_CLASS, or
477 * BTM_FILTER_COND_BD_ADDR
478 * filter_cond - value for the filter (based on
479 * filter_cond_type)
480 *
481 * p_results_cb - Pointer to the callback routine which gets
482 * called upon receipt of an inquiry result. If
483 * this field is NULL, the application is not
484 * notified.
485 *
486 * p_cmpl_cb - Pointer to the callback routine which gets
487 * called upon completion. If this field is
488 * NULL, the application is not notified when
489 * completed.
490 * Returns tBTM_STATUS
491 * BTM_CMD_STARTED if successfully initiated
492 * BTM_BUSY if already in progress
493 * BTM_ILLEGAL_VALUE if parameter(s) are out of range
494 * BTM_NO_RESOURCES if could not allocate resources to start
495 * the command
496 * BTM_WRONG_MODE if the device is not up.
497 *
498 ******************************************************************************/
BTM_StartInquiry(tBTM_INQ_RESULTS_CB * p_results_cb,tBTM_CMPL_CB * p_cmpl_cb)499 tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb,
500 tBTM_CMPL_CB* p_cmpl_cb) {
501 if (bluetooth::shim::is_gd_shim_enabled()) {
502 return bluetooth::shim::BTM_StartInquiry(p_results_cb, p_cmpl_cb);
503 }
504
505 /* Only one active inquiry is allowed in this implementation.
506 Also do not allow an inquiry if the inquiry filter is being updated */
507 if (btm_cb.btm_inq_vars.inq_active) {
508 LOG_WARN(
509 "Active device discovery already in progress inq_active:0x%02x"
510 " state:%hhu counter:%u",
511 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
512 btm_cb.btm_inq_vars.inq_counter);
513 return BTM_BUSY;
514 }
515
516 /*** Make sure the device is ready ***/
517 if (!BTM_IsDeviceUp()) {
518 LOG(ERROR) << __func__ << ": adapter is not up";
519 return BTM_WRONG_MODE;
520 }
521
522 BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Classic inquiry started");
523
524 /* Save the inquiry parameters to be used upon the completion of
525 * setting/clearing the inquiry filter */
526 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
527
528 p_inq->inqparms = {};
529 p_inq->inqparms.mode = BTM_GENERAL_INQUIRY | BTM_BLE_GENERAL_INQUIRY;
530 p_inq->inqparms.duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION;
531
532 /* Initialize the inquiry variables */
533 p_inq->state = BTM_INQ_ACTIVE_STATE;
534 p_inq->p_inq_cmpl_cb = p_cmpl_cb;
535 p_inq->p_inq_results_cb = p_results_cb;
536 p_inq->inq_cmpl_info.num_resp = 0; /* Clear the results counter */
537 p_inq->inq_active = p_inq->inqparms.mode;
538
539 LOG_DEBUG("Starting device discovery inq_active:0x%02x",
540 btm_cb.btm_inq_vars.inq_active);
541
542 if (controller_get_interface()->supports_ble()) {
543 btm_ble_start_inquiry(p_inq->inqparms.duration);
544 } else {
545 LOG_WARN("Trying to do LE scan on a non-LE adapter");
546 p_inq->inqparms.mode &= ~BTM_BLE_INQUIRY_MASK;
547 }
548
549 btm_acl_update_inquiry_status(BTM_INQUIRY_STARTED);
550
551 if (p_inq->inq_active & BTM_SSP_INQUIRY_ACTIVE) {
552 btm_process_inq_complete(HCI_ERR_MAX_NUM_OF_CONNECTIONS,
553 BTM_GENERAL_INQUIRY);
554 return BTM_CMD_STARTED;
555 }
556
557 btm_clr_inq_result_flt();
558
559 /* Allocate memory to hold bd_addrs responding */
560 p_inq->p_bd_db = (tINQ_BDADDR*)osi_calloc(BT_DEFAULT_BUFFER_SIZE);
561 p_inq->max_bd_entries =
562 (uint16_t)(BT_DEFAULT_BUFFER_SIZE / sizeof(tINQ_BDADDR));
563
564 bluetooth::legacy::hci::GetInterface().StartInquiry(
565 general_inq_lap, p_inq->inqparms.duration, 0);
566 return BTM_CMD_STARTED;
567 }
568
569 /*******************************************************************************
570 *
571 * Function BTM_ReadRemoteDeviceName
572 *
573 * Description This function initiates a remote device HCI command to the
574 * controller and calls the callback when the process has
575 * completed.
576 *
577 * Input Params: remote_bda - device address of name to retrieve
578 * p_cb - callback function called when
579 * BTM_CMD_STARTED is returned.
580 * A pointer to tBTM_REMOTE_DEV_NAME is
581 * passed to the callback.
582 *
583 * Returns
584 * BTM_CMD_STARTED is returned if the request was successfully
585 * sent to HCI.
586 * BTM_BUSY if already in progress
587 * BTM_UNKNOWN_ADDR if device address is bad
588 * BTM_NO_RESOURCES if could not allocate resources to start
589 * the command
590 * BTM_WRONG_MODE if the device is not up.
591 *
592 ******************************************************************************/
BTM_ReadRemoteDeviceName(const RawAddress & remote_bda,tBTM_CMPL_CB * p_cb,tBT_TRANSPORT transport)593 tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda,
594 tBTM_CMPL_CB* p_cb,
595 tBT_TRANSPORT transport) {
596 if (bluetooth::shim::is_gd_shim_enabled()) {
597 return bluetooth::shim::BTM_ReadRemoteDeviceName(remote_bda, p_cb,
598 transport);
599 }
600
601 VLOG(1) << __func__ << ": bd addr " << remote_bda;
602 /* Use LE transport when LE is the only available option */
603 if (transport == BT_TRANSPORT_LE) {
604 return btm_ble_read_remote_name(remote_bda, p_cb);
605 }
606 /* Use classic transport for BR/EDR and Dual Mode devices */
607 return btm_initiate_rem_name(remote_bda, BTM_RMT_NAME_EXT,
608 BTM_EXT_RMT_NAME_TIMEOUT_MS, p_cb);
609 }
610
611 /*******************************************************************************
612 *
613 * Function BTM_CancelRemoteDeviceName
614 *
615 * Description This function initiates the cancel request for the specified
616 * remote device.
617 *
618 * Input Params: None
619 *
620 * Returns
621 * BTM_CMD_STARTED is returned if the request was successfully
622 * sent to HCI.
623 * BTM_NO_RESOURCES if could not allocate resources to start
624 * the command
625 * BTM_WRONG_MODE if there is not an active remote name
626 * request.
627 *
628 ******************************************************************************/
BTM_CancelRemoteDeviceName(void)629 tBTM_STATUS BTM_CancelRemoteDeviceName(void) {
630 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
631
632 BTM_TRACE_API("BTM_CancelRemoteDeviceName()");
633
634 /* Make sure there is not already one in progress */
635 if (p_inq->remname_active) {
636 if (BTM_UseLeLink(p_inq->remname_bda)) {
637 /* Cancel remote name request for LE device, and process remote name
638 * callback. */
639 btm_inq_rmt_name_failed_cancelled();
640 } else
641 btsnd_hcic_rmt_name_req_cancel(p_inq->remname_bda);
642 return (BTM_CMD_STARTED);
643 } else
644 return (BTM_WRONG_MODE);
645 }
646
BTM_IsRemoteNameKnown(const RawAddress & bd_addr,tBT_TRANSPORT transport)647 bool BTM_IsRemoteNameKnown(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
648 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
649 return (p_dev_rec == nullptr) ? false : p_dev_rec->is_name_known();
650 }
651
652 /*******************************************************************************
653 *
654 * Function BTM_InqDbRead
655 *
656 * Description This function looks through the inquiry database for a match
657 * based on Bluetooth Device Address. This is the application's
658 * interface to get the inquiry details of a specific BD
659 * address.
660 *
661 * Returns pointer to entry, or NULL if not found
662 *
663 ******************************************************************************/
BTM_InqDbRead(const RawAddress & p_bda)664 tBTM_INQ_INFO* BTM_InqDbRead(const RawAddress& p_bda) {
665 tINQ_DB_ENT* p_ent = btm_inq_db_find(p_bda);
666 return (p_ent == nullptr) ? nullptr : &p_ent->inq_info;
667 }
668
669 /*******************************************************************************
670 *
671 * Function BTM_InqDbFirst
672 *
673 * Description This function looks through the inquiry database for the
674 * first used entry, and returns that. This is used in
675 * conjunction with
676 * BTM_InqDbNext by applications as a way to walk through the
677 * inquiry database.
678 *
679 * Returns pointer to first in-use entry, or NULL if DB is empty
680 *
681 ******************************************************************************/
BTM_InqDbFirst(void)682 tBTM_INQ_INFO* BTM_InqDbFirst(void) {
683 uint16_t xx;
684 tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
685
686 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
687 if (p_ent->in_use) return (&p_ent->inq_info);
688 }
689
690 /* If here, no used entry found */
691 return ((tBTM_INQ_INFO*)NULL);
692 }
693
694 /*******************************************************************************
695 *
696 * Function BTM_InqDbNext
697 *
698 * Description This function looks through the inquiry database for the
699 * next used entry, and returns that. If the input parameter
700 * is NULL, the first entry is returned.
701 *
702 * Returns pointer to next in-use entry, or NULL if no more found.
703 *
704 ******************************************************************************/
BTM_InqDbNext(tBTM_INQ_INFO * p_cur)705 tBTM_INQ_INFO* BTM_InqDbNext(tBTM_INQ_INFO* p_cur) {
706 tINQ_DB_ENT* p_ent;
707 uint16_t inx;
708
709 if (p_cur) {
710 p_ent = (tINQ_DB_ENT*)((uint8_t*)p_cur - offsetof(tINQ_DB_ENT, inq_info));
711 inx = (uint16_t)((p_ent - btm_cb.btm_inq_vars.inq_db) + 1);
712
713 for (p_ent = &btm_cb.btm_inq_vars.inq_db[inx]; inx < BTM_INQ_DB_SIZE;
714 inx++, p_ent++) {
715 if (p_ent->in_use) return (&p_ent->inq_info);
716 }
717
718 /* If here, more entries found */
719 return ((tBTM_INQ_INFO*)NULL);
720 } else
721 return (BTM_InqDbFirst());
722 }
723
724 /*******************************************************************************
725 *
726 * Function BTM_ClearInqDb
727 *
728 * Description This function is called to clear out a device or all devices
729 * from the inquiry database.
730 *
731 * Parameter p_bda - (input) BD_ADDR -> Address of device to clear
732 * (NULL clears all entries)
733 *
734 * Returns BTM_BUSY if an inquiry, get remote name, or event filter
735 * is active, otherwise BTM_SUCCESS
736 *
737 ******************************************************************************/
BTM_ClearInqDb(const RawAddress * p_bda)738 tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda) {
739 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
740
741 /* If an inquiry or remote name is in progress return busy */
742 if (p_inq->inq_active != BTM_INQUIRY_INACTIVE) return (BTM_BUSY);
743
744 btm_clr_inq_db(p_bda);
745
746 return (BTM_SUCCESS);
747 }
748
749 /*******************************************************************************
750 *******************************************************************************
751 * **
752 * BTM Internal Inquiry Functions **
753 * **
754 *******************************************************************************
755 ******************************************************************************/
756 /*******************************************************************************
757 *
758 * Function btm_inq_db_reset
759 *
760 * Description This function is called at at reset to clear the inquiry
761 * database & pending callback.
762 *
763 * Returns void
764 *
765 ******************************************************************************/
btm_inq_db_reset(void)766 void btm_inq_db_reset(void) {
767 tBTM_REMOTE_DEV_NAME rem_name = {};
768 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
769 uint8_t num_responses;
770 uint8_t temp_inq_active;
771
772 /* If an inquiry or periodic inquiry is active, reset the mode to inactive */
773 if (p_inq->inq_active != BTM_INQUIRY_INACTIVE) {
774 temp_inq_active = p_inq->inq_active; /* Save so state can change BEFORE
775 callback is called */
776 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
777
778 /* If not a periodic inquiry, the complete callback must be called to notify
779 * caller */
780 if (temp_inq_active == BTM_GENERAL_INQUIRY_ACTIVE) {
781 if (p_inq->p_inq_cmpl_cb) {
782 num_responses = 0;
783 (*p_inq->p_inq_cmpl_cb)(&num_responses);
784 }
785 }
786 }
787
788 /* Cancel a remote name request if active, and notify the caller (if waiting)
789 */
790 if (p_inq->remname_active) {
791 alarm_cancel(p_inq->remote_name_timer);
792 p_inq->remname_active = false;
793 p_inq->remname_bda = RawAddress::kEmpty;
794
795 if (p_inq->p_remname_cmpl_cb) {
796 rem_name.status = BTM_DEV_RESET;
797 rem_name.hci_status = HCI_SUCCESS;
798
799 (*p_inq->p_remname_cmpl_cb)(&rem_name);
800 p_inq->p_remname_cmpl_cb = NULL;
801 }
802 }
803
804 p_inq->state = BTM_INQ_INACTIVE_STATE;
805 p_inq->p_inq_results_cb = NULL;
806 btm_clr_inq_db(NULL); /* Clear out all the entries in the database */
807 btm_clr_inq_result_flt();
808
809 p_inq->discoverable_mode = BTM_NON_DISCOVERABLE;
810 p_inq->connectable_mode = BTM_NON_CONNECTABLE;
811 p_inq->page_scan_type = BTM_SCAN_TYPE_STANDARD;
812 p_inq->inq_scan_type = BTM_SCAN_TYPE_STANDARD;
813
814 p_inq->discoverable_mode |= BTM_BLE_NON_DISCOVERABLE;
815 p_inq->connectable_mode |= BTM_BLE_NON_CONNECTABLE;
816 return;
817 }
818
819 /*******************************************************************************
820 *
821 * Function btm_inq_db_init
822 *
823 * Description This function is called at startup to initialize the inquiry
824 * database.
825 *
826 * Returns void
827 *
828 ******************************************************************************/
btm_inq_db_init(void)829 void btm_inq_db_init(void) {
830 alarm_free(btm_cb.btm_inq_vars.remote_name_timer);
831 btm_cb.btm_inq_vars.remote_name_timer =
832 alarm_new("btm_inq.remote_name_timer");
833 btm_cb.btm_inq_vars.no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;
834 }
835
btm_inq_db_free(void)836 void btm_inq_db_free(void) {
837 alarm_free(btm_cb.btm_inq_vars.remote_name_timer);
838 }
839
840 /*******************************************************************************
841 *
842 * Function btm_inq_stop_on_ssp
843 *
844 * Description This function is called on incoming SSP
845 *
846 * Returns void
847 *
848 ******************************************************************************/
btm_inq_stop_on_ssp(void)849 void btm_inq_stop_on_ssp(void) {
850 uint8_t normal_active = (BTM_GENERAL_INQUIRY_ACTIVE);
851
852 #if (BTM_INQ_DEBUG == TRUE)
853 BTM_TRACE_DEBUG(
854 "btm_inq_stop_on_ssp: no_inc_ssp=%d inq_active:0x%x state:%d ",
855 btm_cb.btm_inq_vars.no_inc_ssp, btm_cb.btm_inq_vars.inq_active,
856 btm_cb.btm_inq_vars.state);
857 #endif
858 if (btm_cb.btm_inq_vars.no_inc_ssp) {
859 if (btm_cb.btm_inq_vars.state == BTM_INQ_ACTIVE_STATE) {
860 if (btm_cb.btm_inq_vars.inq_active & normal_active) {
861 /* can not call BTM_CancelInquiry() here. We need to report inquiry
862 * complete evt */
863 bluetooth::legacy::hci::GetInterface().InquiryCancel();
864 }
865 }
866 /* do not allow inquiry to start */
867 btm_cb.btm_inq_vars.inq_active |= BTM_SSP_INQUIRY_ACTIVE;
868 }
869 }
870
871 /*******************************************************************************
872 *
873 * Function btm_inq_clear_ssp
874 *
875 * Description This function is called when pairing_state becomes idle
876 *
877 * Returns void
878 *
879 ******************************************************************************/
btm_inq_clear_ssp(void)880 void btm_inq_clear_ssp(void) {
881 btm_cb.btm_inq_vars.inq_active &= ~BTM_SSP_INQUIRY_ACTIVE;
882 }
883
884 /*******************************************************************************
885 *
886 * Function btm_clr_inq_db
887 *
888 * Description This function is called to clear out a device or all devices
889 * from the inquiry database.
890 *
891 * Parameter p_bda - (input) BD_ADDR -> Address of device to clear
892 * (NULL clears all entries)
893 *
894 * Returns void
895 *
896 ******************************************************************************/
btm_clr_inq_db(const RawAddress * p_bda)897 void btm_clr_inq_db(const RawAddress* p_bda) {
898 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
899 tINQ_DB_ENT* p_ent = p_inq->inq_db;
900 uint16_t xx;
901
902 #if (BTM_INQ_DEBUG == TRUE)
903 BTM_TRACE_DEBUG("btm_clr_inq_db: inq_active:0x%x state:%d",
904 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
905 #endif
906 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
907 if (p_ent->in_use) {
908 /* If this is the specified BD_ADDR or clearing all devices */
909 if (p_bda == NULL || (p_ent->inq_info.results.remote_bd_addr == *p_bda)) {
910 p_ent->in_use = false;
911 }
912 }
913 }
914 #if (BTM_INQ_DEBUG == TRUE)
915 BTM_TRACE_DEBUG("inq_active:0x%x state:%d", btm_cb.btm_inq_vars.inq_active,
916 btm_cb.btm_inq_vars.state);
917 #endif
918 }
919
920 /*******************************************************************************
921 *
922 * Function btm_clr_inq_result_flt
923 *
924 * Description This function looks through the bdaddr database for a match
925 * based on Bluetooth Device Address
926 *
927 * Returns true if found, else false (new entry)
928 *
929 ******************************************************************************/
btm_clr_inq_result_flt(void)930 void btm_clr_inq_result_flt(void) {
931 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
932
933 osi_free_and_reset((void**)&p_inq->p_bd_db);
934 p_inq->num_bd_entries = 0;
935 p_inq->max_bd_entries = 0;
936 }
937
938 /*******************************************************************************
939 *
940 * Function btm_inq_find_bdaddr
941 *
942 * Description This function looks through the bdaddr database for a match
943 * based on Bluetooth Device Address
944 *
945 * Returns true if found, else false (new entry)
946 *
947 ******************************************************************************/
btm_inq_find_bdaddr(const RawAddress & p_bda)948 bool btm_inq_find_bdaddr(const RawAddress& p_bda) {
949 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
950 tINQ_BDADDR* p_db = &p_inq->p_bd_db[0];
951 uint16_t xx;
952
953 /* Don't bother searching, database doesn't exist or periodic mode */
954 if (!p_db) return (false);
955
956 for (xx = 0; xx < p_inq->num_bd_entries; xx++, p_db++) {
957 if (p_db->bd_addr == p_bda && p_db->inq_count == p_inq->inq_counter)
958 return (true);
959 }
960
961 if (xx < p_inq->max_bd_entries) {
962 p_db->inq_count = p_inq->inq_counter;
963 p_db->bd_addr = p_bda;
964 p_inq->num_bd_entries++;
965 }
966
967 /* If here, New Entry */
968 return (false);
969 }
970
971 /*******************************************************************************
972 *
973 * Function btm_inq_db_find
974 *
975 * Description This function looks through the inquiry database for a match
976 * based on Bluetooth Device Address
977 *
978 * Returns pointer to entry, or NULL if not found
979 *
980 ******************************************************************************/
btm_inq_db_find(const RawAddress & p_bda)981 tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda) {
982 uint16_t xx;
983 tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
984
985 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
986 if (p_ent->in_use && p_ent->inq_info.results.remote_bd_addr == p_bda)
987 return (p_ent);
988 }
989
990 /* If here, not found */
991 return (NULL);
992 }
993
994 /*******************************************************************************
995 *
996 * Function btm_inq_db_new
997 *
998 * Description This function looks through the inquiry database for an
999 * unused entry. If no entry is free, it allocates the oldest
1000 * entry.
1001 *
1002 * Returns pointer to entry
1003 *
1004 ******************************************************************************/
btm_inq_db_new(const RawAddress & p_bda)1005 tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda) {
1006 uint16_t xx;
1007 tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
1008 tINQ_DB_ENT* p_old = btm_cb.btm_inq_vars.inq_db;
1009 uint64_t ot = UINT64_MAX;
1010
1011 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
1012 if (!p_ent->in_use) {
1013 memset(p_ent, 0, sizeof(tINQ_DB_ENT));
1014 p_ent->inq_info.results.remote_bd_addr = p_bda;
1015 p_ent->in_use = true;
1016
1017 return (p_ent);
1018 }
1019
1020 if (p_ent->time_of_resp < ot) {
1021 p_old = p_ent;
1022 ot = p_ent->time_of_resp;
1023 }
1024 }
1025
1026 /* If here, no free entry found. Return the oldest. */
1027
1028 memset(p_old, 0, sizeof(tINQ_DB_ENT));
1029 p_old->inq_info.results.remote_bd_addr = p_bda;
1030 p_old->in_use = true;
1031
1032 return (p_old);
1033 }
1034
1035 /*******************************************************************************
1036 *
1037 * Function btm_process_inq_results
1038 *
1039 * Description This function is called when inquiry results are received
1040 * from the device. It updates the inquiry database. If the
1041 * inquiry database is full, the oldest entry is discarded.
1042 *
1043 * Parameters inq_res_mode - BTM_INQ_RESULT_STANDARD
1044 * BTM_INQ_RESULT_WITH_RSSI
1045 * BTM_INQ_RESULT_EXTENDED
1046 *
1047 * Returns void
1048 *
1049 ******************************************************************************/
btm_process_inq_results(const uint8_t * p,uint8_t hci_evt_len,uint8_t inq_res_mode)1050 void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len,
1051 uint8_t inq_res_mode) {
1052 uint8_t num_resp, xx;
1053 RawAddress bda;
1054 tINQ_DB_ENT* p_i;
1055 tBTM_INQ_RESULTS* p_cur = NULL;
1056 bool is_new = true;
1057 bool update = false;
1058 int8_t i_rssi;
1059 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1060 tBTM_INQ_RESULTS_CB* p_inq_results_cb = p_inq->p_inq_results_cb;
1061 uint8_t page_scan_rep_mode = 0;
1062 uint8_t page_scan_per_mode = 0;
1063 uint8_t page_scan_mode = 0;
1064 uint8_t rssi = 0;
1065 DEV_CLASS dc;
1066 uint16_t clock_offset;
1067 const uint8_t* p_eir_data = NULL;
1068
1069 #if (BTM_INQ_DEBUG == TRUE)
1070 BTM_TRACE_DEBUG("btm_process_inq_results inq_active:0x%x state:%d",
1071 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1072 #endif
1073 /* Only process the results if the BR inquiry is still active */
1074 if (!(p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK)) return;
1075
1076 STREAM_TO_UINT8(num_resp, p);
1077
1078 if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
1079 if (num_resp > 1) {
1080 BTM_TRACE_ERROR("btm_process_inq_results() extended results (%d) > 1",
1081 num_resp);
1082 return;
1083 }
1084
1085 constexpr uint16_t extended_inquiry_result_size = 254;
1086 if (hci_evt_len - 1 != extended_inquiry_result_size) {
1087 BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
1088 num_resp, hci_evt_len);
1089 return;
1090 }
1091 } else if (inq_res_mode == BTM_INQ_RESULT_STANDARD ||
1092 inq_res_mode == BTM_INQ_RESULT_WITH_RSSI) {
1093 constexpr uint16_t inquiry_result_size = 14;
1094 if (hci_evt_len < num_resp * inquiry_result_size) {
1095 BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
1096 num_resp, hci_evt_len);
1097 return;
1098 }
1099 }
1100
1101 for (xx = 0; xx < num_resp; xx++) {
1102 update = false;
1103 /* Extract inquiry results */
1104 STREAM_TO_BDADDR(bda, p);
1105 STREAM_TO_UINT8(page_scan_rep_mode, p);
1106 STREAM_TO_UINT8(page_scan_per_mode, p);
1107
1108 if (inq_res_mode == BTM_INQ_RESULT_STANDARD) {
1109 STREAM_TO_UINT8(page_scan_mode, p);
1110 }
1111
1112 STREAM_TO_DEVCLASS(dc, p);
1113 STREAM_TO_UINT16(clock_offset, p);
1114 if (inq_res_mode != BTM_INQ_RESULT_STANDARD) {
1115 STREAM_TO_UINT8(rssi, p);
1116 }
1117
1118 p_i = btm_inq_db_find(bda);
1119
1120 /* Check if this address has already been processed for this inquiry */
1121 if (btm_inq_find_bdaddr(bda)) {
1122 /* BTM_TRACE_DEBUG("BDA seen before %s", bda.ToString().c_str()); */
1123
1124 /* By default suppose no update needed */
1125 i_rssi = (int8_t)rssi;
1126
1127 /* If this new RSSI is higher than the last one */
1128 if ((rssi != 0) && p_i &&
1129 (i_rssi > p_i->inq_info.results.rssi ||
1130 p_i->inq_info.results.rssi == 0
1131 /* BR/EDR inquiry information update */
1132 ||
1133 (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)) {
1134 p_cur = &p_i->inq_info.results;
1135 BTM_TRACE_DEBUG("update RSSI new:%d, old:%d", i_rssi, p_cur->rssi);
1136 p_cur->rssi = i_rssi;
1137 update = true;
1138 }
1139 /* If we received a second Extended Inq Event for an already */
1140 /* discovered device, this is because for the first one EIR was not
1141 received */
1142 else if ((inq_res_mode == BTM_INQ_RESULT_EXTENDED) && (p_i)) {
1143 p_cur = &p_i->inq_info.results;
1144 update = true;
1145 }
1146 /* If no update needed continue with next response (if any) */
1147 else
1148 continue;
1149 }
1150
1151 /* If existing entry, use that, else get a new one (possibly reusing the
1152 * oldest) */
1153 if (p_i == NULL) {
1154 p_i = btm_inq_db_new(bda);
1155 is_new = true;
1156 }
1157
1158 /* If an entry for the device already exists, overwrite it ONLY if it is
1159 from
1160 a previous inquiry. (Ignore it if it is a duplicate response from the
1161 same
1162 inquiry.
1163 */
1164 else if (p_i->inq_count == p_inq->inq_counter &&
1165 (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BREDR))
1166 is_new = false;
1167
1168 /* keep updating RSSI to have latest value */
1169 if (inq_res_mode != BTM_INQ_RESULT_STANDARD)
1170 p_i->inq_info.results.rssi = (int8_t)rssi;
1171 else
1172 p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI;
1173
1174 if (is_new) {
1175 /* Save the info */
1176 p_cur = &p_i->inq_info.results;
1177 p_cur->page_scan_rep_mode = page_scan_rep_mode;
1178 p_cur->page_scan_per_mode = page_scan_per_mode;
1179 p_cur->page_scan_mode = page_scan_mode;
1180 p_cur->dev_class[0] = dc[0];
1181 p_cur->dev_class[1] = dc[1];
1182 p_cur->dev_class[2] = dc[2];
1183 p_cur->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
1184
1185 p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms();
1186
1187 if (p_i->inq_count != p_inq->inq_counter)
1188 p_inq->inq_cmpl_info.num_resp++; /* A new response was found */
1189
1190 p_cur->inq_result_type |= BTM_INQ_RESULT_BR;
1191 if (p_i->inq_count != p_inq->inq_counter) {
1192 p_cur->device_type = BT_DEVICE_TYPE_BREDR;
1193 p_i->scan_rsp = false;
1194 } else
1195 p_cur->device_type |= BT_DEVICE_TYPE_BREDR;
1196 p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */
1197
1198 /* Initialize flag to false. This flag is set/used by application */
1199 p_i->inq_info.appl_knows_rem_name = false;
1200 }
1201
1202 if (is_new || update) {
1203 if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
1204 memset(p_cur->eir_uuid, 0,
1205 BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS / 8));
1206 /* set bit map of UUID list from received EIR */
1207 btm_set_eir_uuid(p, p_cur);
1208 p_eir_data = p;
1209 } else
1210 p_eir_data = NULL;
1211
1212 /* If a callback is registered, call it with the results */
1213 if (p_inq_results_cb) {
1214 (p_inq_results_cb)((tBTM_INQ_RESULTS*)p_cur, p_eir_data,
1215 HCI_EXT_INQ_RESPONSE_LEN);
1216 } else {
1217 BTM_TRACE_DEBUG("No callback is registered");
1218 }
1219 }
1220 }
1221 }
1222
1223 /*******************************************************************************
1224 *
1225 * Function btm_sort_inq_result
1226 *
1227 * Description This function is called when inquiry complete is received
1228 * from the device to sort inquiry results based on rssi.
1229 *
1230 * Returns void
1231 *
1232 ******************************************************************************/
btm_sort_inq_result(void)1233 void btm_sort_inq_result(void) {
1234 uint8_t xx, yy, num_resp;
1235 tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
1236 tINQ_DB_ENT* p_next = btm_cb.btm_inq_vars.inq_db + 1;
1237 int size;
1238 tINQ_DB_ENT* p_tmp = (tINQ_DB_ENT*)osi_malloc(sizeof(tINQ_DB_ENT));
1239
1240 num_resp = (btm_cb.btm_inq_vars.inq_cmpl_info.num_resp < BTM_INQ_DB_SIZE)
1241 ? btm_cb.btm_inq_vars.inq_cmpl_info.num_resp
1242 : BTM_INQ_DB_SIZE;
1243
1244 size = sizeof(tINQ_DB_ENT);
1245 for (xx = 0; xx < num_resp - 1; xx++, p_ent++) {
1246 for (yy = xx + 1, p_next = p_ent + 1; yy < num_resp; yy++, p_next++) {
1247 if (p_ent->inq_info.results.rssi < p_next->inq_info.results.rssi) {
1248 memcpy(p_tmp, p_next, size);
1249 memcpy(p_next, p_ent, size);
1250 memcpy(p_ent, p_tmp, size);
1251 }
1252 }
1253 }
1254
1255 osi_free(p_tmp);
1256 }
1257
1258 /*******************************************************************************
1259 *
1260 * Function btm_process_inq_complete
1261 *
1262 * Description This function is called when inquiry complete is received
1263 * from the device. Call the callback if not in periodic
1264 * inquiry mode AND it is not NULL
1265 * (The caller wants the event).
1266 *
1267 * The callback pass back the status and the number of
1268 * responses
1269 *
1270 * Returns void
1271 *
1272 ******************************************************************************/
btm_process_inq_complete(tHCI_STATUS status,uint8_t mode)1273 void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) {
1274 tBTM_CMPL_CB* p_inq_cb = btm_cb.btm_inq_vars.p_inq_cmpl_cb;
1275 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1276
1277 p_inq->inqparms.mode &= ~(mode);
1278
1279 #if (BTM_INQ_DEBUG == TRUE)
1280 BTM_TRACE_DEBUG("btm_process_inq_complete inq_active:0x%x state:%d",
1281 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1282 #endif
1283 btm_acl_update_inquiry_status(BTM_INQUIRY_COMPLETE);
1284 /* Ignore any stray or late complete messages if the inquiry is not active */
1285 if (p_inq->inq_active) {
1286 p_inq->inq_cmpl_info.status = (tBTM_STATUS)(
1287 (status == HCI_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING);
1288
1289 /* Notify caller that the inquiry has completed; (periodic inquiries do not
1290 * send completion events */
1291 if (p_inq->inqparms.mode == 0) {
1292 btm_clear_all_pending_le_entry();
1293 p_inq->state = BTM_INQ_INACTIVE_STATE;
1294
1295 /* Increment so the start of a next inquiry has a new count */
1296 p_inq->inq_counter++;
1297
1298 btm_clr_inq_result_flt();
1299
1300 if ((p_inq->inq_cmpl_info.status == BTM_SUCCESS) &&
1301 controller_get_interface()->supports_rssi_with_inquiry_results()) {
1302 btm_sort_inq_result();
1303 }
1304
1305 /* Clear the results callback if set */
1306 p_inq->p_inq_results_cb = NULL;
1307 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1308 p_inq->p_inq_cmpl_cb = NULL;
1309
1310 /* If we have a callback registered for inquiry complete, call it */
1311 BTM_TRACE_DEBUG("BTM Inq Compl Callback: status 0x%02x, num results %d",
1312 p_inq->inq_cmpl_info.status,
1313 p_inq->inq_cmpl_info.num_resp);
1314
1315 if (p_inq_cb) (p_inq_cb)((tBTM_INQUIRY_CMPL*)&p_inq->inq_cmpl_info);
1316 }
1317 }
1318 #if (BTM_INQ_DEBUG == TRUE)
1319 BTM_TRACE_DEBUG("inq_active:0x%x state:%d", btm_cb.btm_inq_vars.inq_active,
1320 btm_cb.btm_inq_vars.state);
1321 #endif
1322 }
1323
1324 /*******************************************************************************
1325 *
1326 * Function btm_process_cancel_complete
1327 *
1328 * Description This function is called when inquiry cancel complete is
1329 * received from the device. This function will also call the
1330 * btm_process_inq_complete. This function is needed to
1331 * differentiate a cancel_cmpl_evt from the inq_cmpl_evt.
1332 *
1333 * Returns void
1334 *
1335 ******************************************************************************/
btm_process_cancel_complete(tHCI_STATUS status,uint8_t mode)1336 void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode) {
1337 btm_acl_update_inquiry_status(BTM_INQUIRY_CANCELLED);
1338 btm_process_inq_complete(status, mode);
1339 }
1340 /*******************************************************************************
1341 *
1342 * Function btm_initiate_rem_name
1343 *
1344 * Description This function looks initiates a remote name request. It is
1345 * called either by GAP or by the API call
1346 * BTM_ReadRemoteDeviceName.
1347 *
1348 * Input Params: p_cb - callback function called when
1349 * BTM_CMD_STARTED is returned.
1350 * A pointer to tBTM_REMOTE_DEV_NAME is
1351 * passed to the callback.
1352 *
1353 * Returns
1354 * BTM_CMD_STARTED is returned if the request was sent to HCI.
1355 * BTM_BUSY if already in progress
1356 * BTM_NO_RESOURCES if could not allocate resources to start
1357 * the command
1358 * BTM_WRONG_MODE if the device is not up.
1359 *
1360 ******************************************************************************/
btm_initiate_rem_name(const RawAddress & remote_bda,uint8_t origin,uint64_t timeout_ms,tBTM_CMPL_CB * p_cb)1361 tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin,
1362 uint64_t timeout_ms, tBTM_CMPL_CB* p_cb) {
1363 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1364
1365 /*** Make sure the device is ready ***/
1366 if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
1367 if (origin == BTM_RMT_NAME_EXT) {
1368 if (p_inq->remname_active) {
1369 return (BTM_BUSY);
1370 } else {
1371 /* If there is no remote name request running,call the callback function
1372 * and start timer */
1373 p_inq->p_remname_cmpl_cb = p_cb;
1374 p_inq->remname_bda = remote_bda;
1375
1376 alarm_set_on_mloop(p_inq->remote_name_timer, timeout_ms,
1377 btm_inq_remote_name_timer_timeout, NULL);
1378
1379 /* If the database entry exists for the device, use its clock offset */
1380 tINQ_DB_ENT* p_i = btm_inq_db_find(remote_bda);
1381 if (p_i && (p_i->inq_info.results.inq_result_type & BTM_INQ_RESULT_BR)) {
1382 tBTM_INQ_INFO* p_cur = &p_i->inq_info;
1383 btsnd_hcic_rmt_name_req(
1384 remote_bda, p_cur->results.page_scan_rep_mode,
1385 p_cur->results.page_scan_mode,
1386 (uint16_t)(p_cur->results.clock_offset | BTM_CLOCK_OFFSET_VALID));
1387 } else {
1388 /* Otherwise use defaults and mark the clock offset as invalid */
1389 btsnd_hcic_rmt_name_req(remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
1390 HCI_MANDATARY_PAGE_SCAN_MODE, 0);
1391 }
1392
1393 p_inq->remname_active = true;
1394 return BTM_CMD_STARTED;
1395 }
1396 } else {
1397 return BTM_ILLEGAL_VALUE;
1398 }
1399 }
1400
1401 /*******************************************************************************
1402 *
1403 * Function btm_process_remote_name
1404 *
1405 * Description This function is called when a remote name is received from
1406 * the device. If remote names are cached, it updates the
1407 * inquiry database.
1408 *
1409 * Returns void
1410 *
1411 ******************************************************************************/
btm_process_remote_name(const RawAddress * bda,const BD_NAME bdn,uint16_t evt_len,tHCI_STATUS hci_status)1412 void btm_process_remote_name(const RawAddress* bda, const BD_NAME bdn,
1413 uint16_t evt_len, tHCI_STATUS hci_status) {
1414 tBTM_REMOTE_DEV_NAME rem_name;
1415 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1416 tBTM_CMPL_CB* p_cb = p_inq->p_remname_cmpl_cb;
1417 uint8_t* p_n1;
1418
1419 uint16_t temp_evt_len;
1420
1421 if (bda) {
1422 rem_name.bd_addr = *bda;
1423 VLOG(2) << "BDA " << *bda;
1424 } else {
1425 rem_name.bd_addr = RawAddress::kEmpty;
1426 }
1427
1428 VLOG(2) << "Inquire BDA " << p_inq->remname_bda;
1429
1430 /* If the inquire BDA and remote DBA are the same, then stop the timer and set
1431 * the active to false */
1432 if ((p_inq->remname_active) && (!bda || (*bda == p_inq->remname_bda))) {
1433 if (BTM_UseLeLink(p_inq->remname_bda)) {
1434 if (hci_status == HCI_ERR_UNSPECIFIED)
1435 btm_ble_cancel_remote_name(p_inq->remname_bda);
1436 }
1437 alarm_cancel(p_inq->remote_name_timer);
1438 p_inq->remname_active = false;
1439 /* Clean up and return the status if the command was not successful */
1440 /* Note: If part of the inquiry, the name is not stored, and the */
1441 /* inquiry complete callback is called. */
1442
1443 if (hci_status == HCI_SUCCESS) {
1444 /* Copy the name from the data stream into the return structure */
1445 /* Note that even if it is not being returned, it is used as a */
1446 /* temporary buffer. */
1447 p_n1 = (uint8_t*)rem_name.remote_bd_name;
1448 rem_name.length = (evt_len < BD_NAME_LEN) ? evt_len : BD_NAME_LEN;
1449 rem_name.remote_bd_name[rem_name.length] = 0;
1450 rem_name.status = BTM_SUCCESS;
1451 rem_name.hci_status = hci_status;
1452 temp_evt_len = rem_name.length;
1453
1454 while (temp_evt_len > 0) {
1455 *p_n1++ = *bdn++;
1456 temp_evt_len--;
1457 }
1458 rem_name.remote_bd_name[rem_name.length] = 0;
1459 } else {
1460 /* If processing a stand alone remote name then report the error in the
1461 callback */
1462 rem_name.status = BTM_BAD_VALUE_RET;
1463 rem_name.hci_status = hci_status;
1464 rem_name.length = 0;
1465 rem_name.remote_bd_name[0] = 0;
1466 }
1467 /* Reset the remote BAD to zero and call callback if possible */
1468 p_inq->remname_bda = RawAddress::kEmpty;
1469
1470 p_inq->p_remname_cmpl_cb = NULL;
1471 if (p_cb) (p_cb)(&rem_name);
1472 }
1473 }
1474
btm_inq_remote_name_timer_timeout(UNUSED_ATTR void * data)1475 void btm_inq_remote_name_timer_timeout(UNUSED_ATTR void* data) {
1476 btm_inq_rmt_name_failed_cancelled();
1477 }
1478
1479 /*******************************************************************************
1480 *
1481 * Function btm_inq_rmt_name_failed_cancelled
1482 *
1483 * Description This function is if timeout expires or request is cancelled
1484 * while getting remote name. This is done for devices that
1485 * incorrectly do not report operation failure
1486 *
1487 * Returns void
1488 *
1489 ******************************************************************************/
btm_inq_rmt_name_failed_cancelled(void)1490 void btm_inq_rmt_name_failed_cancelled(void) {
1491 BTM_TRACE_ERROR("btm_inq_rmt_name_failed_cancelled() remname_active=%d",
1492 btm_cb.btm_inq_vars.remname_active);
1493
1494 if (btm_cb.btm_inq_vars.remname_active) {
1495 btm_process_remote_name(&btm_cb.btm_inq_vars.remname_bda, NULL, 0,
1496 HCI_ERR_UNSPECIFIED);
1497 }
1498
1499 btm_sec_rmt_name_request_complete(NULL, NULL, HCI_ERR_UNSPECIFIED);
1500 }
1501
1502 /*******************************************************************************
1503 *
1504 * Function BTM_WriteEIR
1505 *
1506 * Description This function is called to write EIR data to controller.
1507 *
1508 * Parameters p_buff - allocated HCI command buffer including extended
1509 * inquriry response
1510 *
1511 * Returns BTM_SUCCESS - if successful
1512 * BTM_MODE_UNSUPPORTED - if local device cannot support it
1513 *
1514 ******************************************************************************/
BTM_WriteEIR(BT_HDR * p_buff)1515 tBTM_STATUS BTM_WriteEIR(BT_HDR* p_buff) {
1516 if (controller_get_interface()->supports_extended_inquiry_response()) {
1517 BTM_TRACE_API("Write Extended Inquiry Response to controller");
1518 btsnd_hcic_write_ext_inquiry_response(p_buff, BTM_EIR_DEFAULT_FEC_REQUIRED);
1519 return BTM_SUCCESS;
1520 } else {
1521 osi_free(p_buff);
1522 return BTM_MODE_UNSUPPORTED;
1523 }
1524 }
1525
1526 /*******************************************************************************
1527 *
1528 * Function btm_convert_uuid_to_eir_service
1529 *
1530 * Description This function is called to get the bit position of UUID.
1531 *
1532 * Parameters uuid16 - UUID 16-bit
1533 *
1534 * Returns BTM EIR service ID if found
1535 * BTM_EIR_MAX_SERVICES - if not found
1536 *
1537 ******************************************************************************/
btm_convert_uuid_to_eir_service(uint16_t uuid16)1538 static uint8_t btm_convert_uuid_to_eir_service(uint16_t uuid16) {
1539 uint8_t xx;
1540
1541 for (xx = 0; xx < BTM_EIR_MAX_SERVICES; xx++) {
1542 if (uuid16 == BTM_EIR_UUID_LKUP_TBL[xx]) {
1543 return xx;
1544 }
1545 }
1546 return BTM_EIR_MAX_SERVICES;
1547 }
1548
1549 /*******************************************************************************
1550 *
1551 * Function BTM_HasEirService
1552 *
1553 * Description This function is called to know if UUID in bit map of UUID.
1554 *
1555 * Parameters p_eir_uuid - bit map of UUID list
1556 * uuid16 - UUID 16-bit
1557 *
1558 * Returns true - if found
1559 * false - if not found
1560 *
1561 ******************************************************************************/
BTM_HasEirService(const uint32_t * p_eir_uuid,uint16_t uuid16)1562 bool BTM_HasEirService(const uint32_t* p_eir_uuid, uint16_t uuid16) {
1563 uint8_t service_id;
1564
1565 service_id = btm_convert_uuid_to_eir_service(uuid16);
1566 if (service_id < BTM_EIR_MAX_SERVICES)
1567 return (BTM_EIR_HAS_SERVICE(p_eir_uuid, service_id));
1568 else
1569 return (false);
1570 }
1571
1572 /*******************************************************************************
1573 *
1574 * Function BTM_HasInquiryEirService
1575 *
1576 * Description This function is called to know if UUID in bit map of UUID
1577 * list.
1578 *
1579 * Parameters p_results - inquiry results
1580 * uuid16 - UUID 16-bit
1581 *
1582 * Returns BTM_EIR_FOUND - if found
1583 * BTM_EIR_NOT_FOUND - if not found and it is complete list
1584 * BTM_EIR_UNKNOWN - if not found and it is not complete list
1585 *
1586 ******************************************************************************/
BTM_HasInquiryEirService(tBTM_INQ_RESULTS * p_results,uint16_t uuid16)1587 tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService(tBTM_INQ_RESULTS* p_results,
1588 uint16_t uuid16) {
1589 if (BTM_HasEirService(p_results->eir_uuid, uuid16)) {
1590 return BTM_EIR_FOUND;
1591 } else if (p_results->eir_complete_list) {
1592 return BTM_EIR_NOT_FOUND;
1593 } else
1594 return BTM_EIR_UNKNOWN;
1595 }
1596
1597 /*******************************************************************************
1598 *
1599 * Function BTM_AddEirService
1600 *
1601 * Description This function is called to add a service in bit map of UUID
1602 * list.
1603 *
1604 * Parameters p_eir_uuid - bit mask of UUID list for EIR
1605 * uuid16 - UUID 16-bit
1606 *
1607 * Returns None
1608 *
1609 ******************************************************************************/
BTM_AddEirService(uint32_t * p_eir_uuid,uint16_t uuid16)1610 void BTM_AddEirService(uint32_t* p_eir_uuid, uint16_t uuid16) {
1611 uint8_t service_id;
1612
1613 service_id = btm_convert_uuid_to_eir_service(uuid16);
1614 if (service_id < BTM_EIR_MAX_SERVICES)
1615 BTM_EIR_SET_SERVICE(p_eir_uuid, service_id);
1616 }
1617
1618 /*******************************************************************************
1619 *
1620 * Function BTM_RemoveEirService
1621 *
1622 * Description This function is called to remove a service in bit map of
1623 * UUID list.
1624 *
1625 * Parameters p_eir_uuid - bit mask of UUID list for EIR
1626 * uuid16 - UUID 16-bit
1627 *
1628 * Returns None
1629 *
1630 ******************************************************************************/
BTM_RemoveEirService(uint32_t * p_eir_uuid,uint16_t uuid16)1631 void BTM_RemoveEirService(uint32_t* p_eir_uuid, uint16_t uuid16) {
1632 uint8_t service_id;
1633
1634 service_id = btm_convert_uuid_to_eir_service(uuid16);
1635 if (service_id < BTM_EIR_MAX_SERVICES)
1636 BTM_EIR_CLR_SERVICE(p_eir_uuid, service_id);
1637 }
1638
1639 /*******************************************************************************
1640 *
1641 * Function BTM_GetEirSupportedServices
1642 *
1643 * Description This function is called to get UUID list from bit map of
1644 * UUID list.
1645 *
1646 * Parameters p_eir_uuid - bit mask of UUID list for EIR
1647 * p - reference of current pointer of EIR
1648 * max_num_uuid16 - max number of UUID can be written in EIR
1649 * num_uuid16 - number of UUID have been written in EIR
1650 *
1651 * Returns HCI_EIR_MORE_16BITS_UUID_TYPE, if it has more than max
1652 * HCI_EIR_COMPLETE_16BITS_UUID_TYPE, otherwise
1653 *
1654 ******************************************************************************/
BTM_GetEirSupportedServices(uint32_t * p_eir_uuid,uint8_t ** p,uint8_t max_num_uuid16,uint8_t * p_num_uuid16)1655 uint8_t BTM_GetEirSupportedServices(uint32_t* p_eir_uuid, uint8_t** p,
1656 uint8_t max_num_uuid16,
1657 uint8_t* p_num_uuid16) {
1658 uint8_t service_index;
1659
1660 *p_num_uuid16 = 0;
1661
1662 for (service_index = 0; service_index < BTM_EIR_MAX_SERVICES;
1663 service_index++) {
1664 if (BTM_EIR_HAS_SERVICE(p_eir_uuid, service_index)) {
1665 if (*p_num_uuid16 < max_num_uuid16) {
1666 UINT16_TO_STREAM(*p, BTM_EIR_UUID_LKUP_TBL[service_index]);
1667 (*p_num_uuid16)++;
1668 }
1669 /* if max number of UUIDs are stored and found one more */
1670 else {
1671 return HCI_EIR_MORE_16BITS_UUID_TYPE;
1672 }
1673 }
1674 }
1675 return HCI_EIR_COMPLETE_16BITS_UUID_TYPE;
1676 }
1677
1678 /*******************************************************************************
1679 *
1680 * Function BTM_GetEirUuidList
1681 *
1682 * Description This function parses EIR and returns UUID list.
1683 *
1684 * Parameters p_eir - EIR
1685 * eir_len - EIR len
1686 * uuid_size - Uuid::kNumBytes16, Uuid::kNumBytes32,
1687 * Uuid::kNumBytes128
1688 * p_num_uuid - return number of UUID in found list
1689 * p_uuid_list - return UUID list
1690 * max_num_uuid - maximum number of UUID to be returned
1691 *
1692 * Returns 0 - if not found
1693 * HCI_EIR_COMPLETE_16BITS_UUID_TYPE
1694 * HCI_EIR_MORE_16BITS_UUID_TYPE
1695 * HCI_EIR_COMPLETE_32BITS_UUID_TYPE
1696 * HCI_EIR_MORE_32BITS_UUID_TYPE
1697 * HCI_EIR_COMPLETE_128BITS_UUID_TYPE
1698 * HCI_EIR_MORE_128BITS_UUID_TYPE
1699 *
1700 ******************************************************************************/
BTM_GetEirUuidList(const uint8_t * p_eir,size_t eir_len,uint8_t uuid_size,uint8_t * p_num_uuid,uint8_t * p_uuid_list,uint8_t max_num_uuid)1701 uint8_t BTM_GetEirUuidList(const uint8_t* p_eir, size_t eir_len,
1702 uint8_t uuid_size, uint8_t* p_num_uuid,
1703 uint8_t* p_uuid_list, uint8_t max_num_uuid) {
1704 const uint8_t* p_uuid_data;
1705 uint8_t type;
1706 uint8_t yy, xx;
1707 uint16_t* p_uuid16 = (uint16_t*)p_uuid_list;
1708 uint32_t* p_uuid32 = (uint32_t*)p_uuid_list;
1709 char buff[Uuid::kNumBytes128 * 2 + 1];
1710
1711 p_uuid_data =
1712 btm_eir_get_uuid_list(p_eir, eir_len, uuid_size, p_num_uuid, &type);
1713 if (p_uuid_data == NULL) {
1714 return 0x00;
1715 }
1716
1717 if (*p_num_uuid > max_num_uuid) {
1718 BTM_TRACE_WARNING("%s: number of uuid in EIR = %d, size of uuid list = %d",
1719 __func__, *p_num_uuid, max_num_uuid);
1720 *p_num_uuid = max_num_uuid;
1721 }
1722
1723 BTM_TRACE_DEBUG("%s: type = %02X, number of uuid = %d", __func__, type,
1724 *p_num_uuid);
1725
1726 if (uuid_size == Uuid::kNumBytes16) {
1727 for (yy = 0; yy < *p_num_uuid; yy++) {
1728 STREAM_TO_UINT16(*(p_uuid16 + yy), p_uuid_data);
1729 BTM_TRACE_DEBUG(" 0x%04X", *(p_uuid16 + yy));
1730 }
1731 } else if (uuid_size == Uuid::kNumBytes32) {
1732 for (yy = 0; yy < *p_num_uuid; yy++) {
1733 STREAM_TO_UINT32(*(p_uuid32 + yy), p_uuid_data);
1734 BTM_TRACE_DEBUG(" 0x%08X", *(p_uuid32 + yy));
1735 }
1736 } else if (uuid_size == Uuid::kNumBytes128) {
1737 for (yy = 0; yy < *p_num_uuid; yy++) {
1738 STREAM_TO_ARRAY16(p_uuid_list + yy * Uuid::kNumBytes128, p_uuid_data);
1739 for (xx = 0; xx < Uuid::kNumBytes128; xx++)
1740 snprintf(buff + xx * 2, sizeof(buff) - xx * 2, "%02X",
1741 *(p_uuid_list + yy * Uuid::kNumBytes128 + xx));
1742 BTM_TRACE_DEBUG(" 0x%s", buff);
1743 }
1744 }
1745
1746 return type;
1747 }
1748
1749 /*******************************************************************************
1750 *
1751 * Function btm_eir_get_uuid_list
1752 *
1753 * Description This function searches UUID list in EIR.
1754 *
1755 * Parameters p_eir - address of EIR
1756 * eir_len - EIR length
1757 * uuid_size - size of UUID to find
1758 * p_num_uuid - number of UUIDs found
1759 * p_uuid_list_type - EIR data type
1760 *
1761 * Returns NULL - if UUID list with uuid_size is not found
1762 * beginning of UUID list in EIR - otherwise
1763 *
1764 ******************************************************************************/
btm_eir_get_uuid_list(const uint8_t * p_eir,size_t eir_len,uint8_t uuid_size,uint8_t * p_num_uuid,uint8_t * p_uuid_list_type)1765 static const uint8_t* btm_eir_get_uuid_list(const uint8_t* p_eir,
1766 size_t eir_len, uint8_t uuid_size,
1767 uint8_t* p_num_uuid,
1768 uint8_t* p_uuid_list_type) {
1769 const uint8_t* p_uuid_data;
1770 uint8_t complete_type, more_type;
1771 uint8_t uuid_len;
1772
1773 switch (uuid_size) {
1774 case Uuid::kNumBytes16:
1775 complete_type = HCI_EIR_COMPLETE_16BITS_UUID_TYPE;
1776 more_type = HCI_EIR_MORE_16BITS_UUID_TYPE;
1777 break;
1778 case Uuid::kNumBytes32:
1779 complete_type = HCI_EIR_COMPLETE_32BITS_UUID_TYPE;
1780 more_type = HCI_EIR_MORE_32BITS_UUID_TYPE;
1781 break;
1782 case Uuid::kNumBytes128:
1783 complete_type = HCI_EIR_COMPLETE_128BITS_UUID_TYPE;
1784 more_type = HCI_EIR_MORE_128BITS_UUID_TYPE;
1785 break;
1786 default:
1787 *p_num_uuid = 0;
1788 return NULL;
1789 break;
1790 }
1791
1792 p_uuid_data = AdvertiseDataParser::GetFieldByType(p_eir, eir_len,
1793 complete_type, &uuid_len);
1794 if (p_uuid_data == NULL) {
1795 p_uuid_data = AdvertiseDataParser::GetFieldByType(p_eir, eir_len, more_type,
1796 &uuid_len);
1797 *p_uuid_list_type = more_type;
1798 } else {
1799 *p_uuid_list_type = complete_type;
1800 }
1801
1802 *p_num_uuid = uuid_len / uuid_size;
1803 return p_uuid_data;
1804 }
1805
1806 /*******************************************************************************
1807 *
1808 * Function btm_convert_uuid_to_uuid16
1809 *
1810 * Description This function converts UUID to UUID 16-bit.
1811 *
1812 * Parameters p_uuid - address of UUID
1813 * uuid_size - size of UUID
1814 *
1815 * Returns 0 - if UUID cannot be converted to UUID 16-bit
1816 * UUID 16-bit - otherwise
1817 *
1818 ******************************************************************************/
btm_convert_uuid_to_uuid16(const uint8_t * p_uuid,uint8_t uuid_size)1819 static uint16_t btm_convert_uuid_to_uuid16(const uint8_t* p_uuid,
1820 uint8_t uuid_size) {
1821 static const uint8_t base_uuid[Uuid::kNumBytes128] = {
1822 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
1823 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1824 uint16_t uuid16 = 0;
1825 uint32_t uuid32;
1826 bool is_base_uuid;
1827 uint8_t xx;
1828
1829 switch (uuid_size) {
1830 case Uuid::kNumBytes16:
1831 STREAM_TO_UINT16(uuid16, p_uuid);
1832 break;
1833 case Uuid::kNumBytes32:
1834 STREAM_TO_UINT32(uuid32, p_uuid);
1835 if (uuid32 < 0x10000) uuid16 = (uint16_t)uuid32;
1836 break;
1837 case Uuid::kNumBytes128:
1838 /* See if we can compress the UUID down to 16 or 32bit UUIDs */
1839 is_base_uuid = true;
1840 for (xx = 0; xx < Uuid::kNumBytes128 - 4; xx++) {
1841 if (p_uuid[xx] != base_uuid[xx]) {
1842 is_base_uuid = false;
1843 break;
1844 }
1845 }
1846 if (is_base_uuid) {
1847 if ((p_uuid[Uuid::kNumBytes128 - 1] == 0) &&
1848 (p_uuid[Uuid::kNumBytes128 - 2] == 0)) {
1849 p_uuid += (Uuid::kNumBytes128 - 4);
1850 STREAM_TO_UINT16(uuid16, p_uuid);
1851 }
1852 }
1853 break;
1854 default:
1855 BTM_TRACE_WARNING("btm_convert_uuid_to_uuid16 invalid uuid size");
1856 break;
1857 }
1858
1859 return (uuid16);
1860 }
1861
1862 /*******************************************************************************
1863 *
1864 * Function btm_set_eir_uuid
1865 *
1866 * Description This function is called to store received UUID into inquiry
1867 * result.
1868 *
1869 * Parameters p_eir - pointer of EIR significant part
1870 * p_results - pointer of inquiry result
1871 *
1872 * Returns None
1873 *
1874 ******************************************************************************/
btm_set_eir_uuid(const uint8_t * p_eir,tBTM_INQ_RESULTS * p_results)1875 void btm_set_eir_uuid(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results) {
1876 const uint8_t* p_uuid_data;
1877 uint8_t num_uuid;
1878 uint16_t uuid16;
1879 uint8_t yy;
1880 uint8_t type = HCI_EIR_MORE_16BITS_UUID_TYPE;
1881
1882 p_uuid_data = btm_eir_get_uuid_list(p_eir, HCI_EXT_INQ_RESPONSE_LEN,
1883 Uuid::kNumBytes16, &num_uuid, &type);
1884
1885 if (type == HCI_EIR_COMPLETE_16BITS_UUID_TYPE) {
1886 p_results->eir_complete_list = true;
1887 } else {
1888 p_results->eir_complete_list = false;
1889 }
1890
1891 BTM_TRACE_API("btm_set_eir_uuid eir_complete_list=0x%02X",
1892 p_results->eir_complete_list);
1893
1894 if (p_uuid_data) {
1895 for (yy = 0; yy < num_uuid; yy++) {
1896 STREAM_TO_UINT16(uuid16, p_uuid_data);
1897 BTM_AddEirService(p_results->eir_uuid, uuid16);
1898 }
1899 }
1900
1901 p_uuid_data = btm_eir_get_uuid_list(p_eir, HCI_EXT_INQ_RESPONSE_LEN,
1902 Uuid::kNumBytes32, &num_uuid, &type);
1903 if (p_uuid_data) {
1904 for (yy = 0; yy < num_uuid; yy++) {
1905 uuid16 = btm_convert_uuid_to_uuid16(p_uuid_data, Uuid::kNumBytes32);
1906 p_uuid_data += Uuid::kNumBytes32;
1907 if (uuid16) BTM_AddEirService(p_results->eir_uuid, uuid16);
1908 }
1909 }
1910
1911 p_uuid_data = btm_eir_get_uuid_list(p_eir, HCI_EXT_INQ_RESPONSE_LEN,
1912 Uuid::kNumBytes128, &num_uuid, &type);
1913 if (p_uuid_data) {
1914 for (yy = 0; yy < num_uuid; yy++) {
1915 uuid16 = btm_convert_uuid_to_uuid16(p_uuid_data, Uuid::kNumBytes128);
1916 p_uuid_data += Uuid::kNumBytes128;
1917 if (uuid16) BTM_AddEirService(p_results->eir_uuid, uuid16);
1918 }
1919 }
1920 }
1921