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