1 /******************************************************************************
2 *
3 * Copyright (C) 1999-2012 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 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <stddef.h>
32
33 #include "bt_types.h"
34 #include "gki.h"
35 #include "hcimsgs.h"
36 #include "btu.h"
37 #include "btm_api.h"
38 #include "btm_int.h"
39 #include "hcidefs.h"
40
41 #define BTM_INQ_REPLY_TIMEOUT 3 /* 3 second timeout waiting for responses */
42
43 /* TRUE to enable DEBUG traces for btm_inq */
44 #ifndef BTM_INQ_DEBUG
45 #define BTM_INQ_DEBUG FALSE
46 #endif
47 /********************************************************************************/
48 /* L O C A L D A T A D E F I N I T I O N S */
49 /********************************************************************************/
50 static const LAP general_inq_lap = {0x9e,0x8b,0x33};
51 static const LAP limited_inq_lap = {0x9e,0x8b,0x00};
52
53 #if (( BTM_EIR_CLIENT_INCLUDED == TRUE )||( BTM_EIR_SERVER_INCLUDED == TRUE ))
54 #ifndef BTM_EIR_UUID_LKUP_TBL
55 const UINT16 BTM_EIR_UUID_LKUP_TBL[BTM_EIR_MAX_SERVICES] =
56 {
57 UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER,
58 /* UUID_SERVCLASS_BROWSE_GROUP_DESCRIPTOR, */
59 /* UUID_SERVCLASS_PUBLIC_BROWSE_GROUP, */
60 UUID_SERVCLASS_SERIAL_PORT,
61 UUID_SERVCLASS_LAN_ACCESS_USING_PPP,
62 UUID_SERVCLASS_DIALUP_NETWORKING,
63 UUID_SERVCLASS_IRMC_SYNC,
64 UUID_SERVCLASS_OBEX_OBJECT_PUSH,
65 UUID_SERVCLASS_OBEX_FILE_TRANSFER,
66 UUID_SERVCLASS_IRMC_SYNC_COMMAND,
67 UUID_SERVCLASS_HEADSET,
68 UUID_SERVCLASS_CORDLESS_TELEPHONY,
69 UUID_SERVCLASS_AUDIO_SOURCE,
70 UUID_SERVCLASS_AUDIO_SINK,
71 UUID_SERVCLASS_AV_REM_CTRL_TARGET,
72 /* UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION, */
73 UUID_SERVCLASS_AV_REMOTE_CONTROL,
74 /* UUID_SERVCLASS_VIDEO_CONFERENCING, */
75 UUID_SERVCLASS_INTERCOM,
76 UUID_SERVCLASS_FAX,
77 UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY,
78 /* UUID_SERVCLASS_WAP, */
79 /* UUID_SERVCLASS_WAP_CLIENT, */
80 UUID_SERVCLASS_PANU,
81 UUID_SERVCLASS_NAP,
82 UUID_SERVCLASS_GN,
83 UUID_SERVCLASS_DIRECT_PRINTING,
84 /* UUID_SERVCLASS_REFERENCE_PRINTING, */
85 UUID_SERVCLASS_IMAGING,
86 UUID_SERVCLASS_IMAGING_RESPONDER,
87 UUID_SERVCLASS_IMAGING_AUTO_ARCHIVE,
88 UUID_SERVCLASS_IMAGING_REF_OBJECTS,
89 UUID_SERVCLASS_HF_HANDSFREE,
90 UUID_SERVCLASS_AG_HANDSFREE,
91 UUID_SERVCLASS_DIR_PRT_REF_OBJ_SERVICE,
92 /* UUID_SERVCLASS_REFLECTED_UI, */
93 UUID_SERVCLASS_BASIC_PRINTING,
94 UUID_SERVCLASS_PRINTING_STATUS,
95 UUID_SERVCLASS_HUMAN_INTERFACE,
96 UUID_SERVCLASS_CABLE_REPLACEMENT,
97 UUID_SERVCLASS_HCRP_PRINT,
98 UUID_SERVCLASS_HCRP_SCAN,
99 /* UUID_SERVCLASS_COMMON_ISDN_ACCESS, */
100 /* UUID_SERVCLASS_VIDEO_CONFERENCING_GW, */
101 /* UUID_SERVCLASS_UDI_MT, */
102 /* UUID_SERVCLASS_UDI_TA, */
103 /* UUID_SERVCLASS_VCP, */
104 UUID_SERVCLASS_SAP,
105 UUID_SERVCLASS_PBAP_PCE,
106 UUID_SERVCLASS_PBAP_PSE,
107 UUID_SERVCLASS_PHONE_ACCESS,
108 UUID_SERVCLASS_HEADSET_HS,
109 UUID_SERVCLASS_PNP_INFORMATION,
110 /* UUID_SERVCLASS_GENERIC_NETWORKING, */
111 /* UUID_SERVCLASS_GENERIC_FILETRANSFER, */
112 /* UUID_SERVCLASS_GENERIC_AUDIO, */
113 /* UUID_SERVCLASS_GENERIC_TELEPHONY, */
114 /* UUID_SERVCLASS_UPNP_SERVICE, */
115 /* UUID_SERVCLASS_UPNP_IP_SERVICE, */
116 /* UUID_SERVCLASS_ESDP_UPNP_IP_PAN, */
117 /* UUID_SERVCLASS_ESDP_UPNP_IP_LAP, */
118 /* UUID_SERVCLASS_ESDP_UPNP_IP_L2CAP, */
119 UUID_SERVCLASS_VIDEO_SOURCE,
120 UUID_SERVCLASS_VIDEO_SINK,
121 /* UUID_SERVCLASS_VIDEO_DISTRIBUTION */
122 UUID_SERVCLASS_MESSAGE_ACCESS,
123 UUID_SERVCLASS_MESSAGE_NOTIFICATION,
124 UUID_SERVCLASS_HDP_SOURCE,
125 UUID_SERVCLASS_HDP_SINK
126 };
127 #else
128 /*
129 If customized UUID look-up table needs to be used,
130 the followings should be defined in bdroid_buildcfg.h.
131 BTM_EIR_UUID_LKUP_TBL = <customized UUID list>
132 BTM_EIR_MAX_SERVICES = <number of UUID in list>
133 */
134 #if (BTM_EIR_MAX_SERVICES == 0)
135 const UINT16 BTM_EIR_UUID_LKUP_TBL[];
136 #else
137 extern UINT16 BTM_EIR_UUID_LKUP_TBL[BTM_EIR_MAX_SERVICES];
138 #endif
139 #endif
140 #endif /* BTM_EIR_UUID_LKUP_TBL*/
141
142 /********************************************************************************/
143 /* L O C A L F U N C T I O N P R O T O T Y P E S */
144 /********************************************************************************/
145 static void btm_initiate_inquiry (tBTM_INQUIRY_VAR_ST *p_inq);
146 static tBTM_STATUS btm_set_inq_event_filter (UINT8 filter_cond_type, tBTM_INQ_FILT_COND *p_filt_cond);
147 static void btm_clr_inq_result_flt (void);
148
149 #if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
150 static UINT8 btm_convert_uuid_to_eir_service( UINT16 uuid16 );
151 #endif
152 #if (BTM_EIR_CLIENT_INCLUDED == TRUE)
153 static void btm_set_eir_uuid( UINT8 *p_eir, tBTM_INQ_RESULTS *p_results );
154 static UINT8 *btm_eir_get_uuid_list( UINT8 *p_eir, UINT8 uuid_size,
155 UINT8 *p_num_uuid, UINT8 *p_uuid_list_type );
156 static UINT16 btm_convert_uuid_to_uuid16( UINT8 *p_uuid, UINT8 uuid_size );
157 #endif
158
159 /*******************************************************************************
160 **
161 ** Function BTM_SetDiscoverability
162 **
163 ** Description This function is called to set the device into or out of
164 ** discoverable mode. Discoverable mode means inquiry
165 ** scans are enabled. If a value of '0' is entered for window or
166 ** interval, the default values are used.
167 **
168 ** Returns BTM_SUCCESS if successful
169 ** BTM_BUSY if a setting of the filter is already in progress
170 ** BTM_NO_RESOURCES if couldn't get a memory pool buffer
171 ** BTM_ILLEGAL_VALUE if a bad parameter was detected
172 ** BTM_WRONG_MODE if the device is not up.
173 **
174 *******************************************************************************/
BTM_SetDiscoverability(UINT16 inq_mode,UINT16 window,UINT16 interval)175 tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 interval)
176 {
177 UINT8 scan_mode = 0;
178 UINT16 service_class;
179 UINT8 *p_cod;
180 UINT8 major, minor;
181 DEV_CLASS cod;
182 LAP temp_lap[2];
183 BOOLEAN is_limited;
184 BOOLEAN cod_limited;
185
186 BTM_TRACE_API0 ("BTM_SetDiscoverability");
187 #if (BLE_INCLUDED == TRUE && BLE_INCLUDED == TRUE)
188 if (HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
189 {
190 if (btm_ble_set_discoverability((UINT16)(inq_mode))
191 == BTM_SUCCESS)
192 {
193 btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_BLE_DISCOVERABLE_MASK);
194 btm_cb.btm_inq_vars.discoverable_mode |= (inq_mode & BTM_BLE_CONNECTABLE_MASK);
195 }
196 }
197 inq_mode &= ~BTM_BLE_DISCOVERABLE_MASK;
198 #endif
199
200 /*** Check mode parameter ***/
201 if (inq_mode > BTM_MAX_DISCOVERABLE)
202 return (BTM_ILLEGAL_VALUE);
203
204 /* Make sure the controller is active */
205 if (btm_cb.devcb.state < BTM_DEV_STATE_READY)
206 return (BTM_DEV_RESET);
207
208 /* If the window and/or interval is '0', set to default values */
209 if (!window)
210 window = BTM_DEFAULT_DISC_WINDOW;
211
212 if (!interval)
213 interval = BTM_DEFAULT_DISC_INTERVAL;
214
215 BTM_TRACE_API3 ("BTM_SetDiscoverability: mode %d [NonDisc-0, Lim-1, Gen-2], window 0x%04x, interval 0x%04x",
216 inq_mode, window, interval);
217
218 /*** Check for valid window and interval parameters ***/
219 /*** Only check window and duration if mode is connectable ***/
220 if (inq_mode != BTM_NON_DISCOVERABLE)
221 {
222 /* window must be less than or equal to interval */
223 if (window < HCI_MIN_INQUIRYSCAN_WINDOW ||
224 window > HCI_MAX_INQUIRYSCAN_WINDOW ||
225 interval < HCI_MIN_INQUIRYSCAN_INTERVAL ||
226 interval > HCI_MAX_INQUIRYSCAN_INTERVAL ||
227 window > interval)
228 {
229 return (BTM_ILLEGAL_VALUE);
230 }
231 }
232
233 /* Set the IAC if needed */
234 if (inq_mode != BTM_NON_DISCOVERABLE)
235 {
236 if (inq_mode & BTM_LIMITED_DISCOVERABLE)
237 {
238 /* Use the GIAC and LIAC codes for limited discoverable mode */
239 memcpy (temp_lap[0], limited_inq_lap, LAP_LEN);
240 memcpy (temp_lap[1], general_inq_lap, LAP_LEN);
241
242 if (!btsnd_hcic_write_cur_iac_lap (2, (LAP * const) temp_lap))
243 return (BTM_NO_RESOURCES); /* Cannot continue */
244 }
245 else
246 {
247 if (!btsnd_hcic_write_cur_iac_lap (1, (LAP * const) &general_inq_lap))
248 return (BTM_NO_RESOURCES); /* Cannot continue */
249 }
250
251 scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
252 }
253
254 /* Send down the inquiry scan window and period if changed */
255 if ((window != btm_cb.btm_inq_vars.inq_scan_window) ||
256 (interval != btm_cb.btm_inq_vars.inq_scan_period))
257 {
258 if (btsnd_hcic_write_inqscan_cfg (interval, window))
259 {
260 btm_cb.btm_inq_vars.inq_scan_window = window;
261 btm_cb.btm_inq_vars.inq_scan_period = interval;
262 }
263 else
264 return (BTM_NO_RESOURCES);
265 }
266
267 if (btm_cb.btm_inq_vars.connectable_mode & BTM_CONNECTABLE_MASK)
268 scan_mode |= HCI_PAGE_SCAN_ENABLED;
269
270 if (btsnd_hcic_write_scan_enable (scan_mode))
271 {
272 btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_DISCOVERABLE_MASK);
273 btm_cb.btm_inq_vars.discoverable_mode |= inq_mode;
274 }
275 else
276 return (BTM_NO_RESOURCES);
277
278 /* Change the service class bit if mode has changed */
279 p_cod = BTM_ReadDeviceClass();
280 BTM_COD_SERVICE_CLASS(service_class, p_cod);
281 is_limited = (inq_mode & BTM_LIMITED_DISCOVERABLE) ? TRUE : FALSE;
282 cod_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? TRUE : FALSE;
283 if (is_limited ^ cod_limited)
284 {
285 BTM_COD_MINOR_CLASS(minor, p_cod );
286 BTM_COD_MAJOR_CLASS(major, p_cod );
287 if (is_limited)
288 service_class |= BTM_COD_SERVICE_LMTD_DISCOVER;
289 else
290 service_class &= ~BTM_COD_SERVICE_LMTD_DISCOVER;
291
292 FIELDS_TO_COD(cod, minor, major, service_class);
293 (void) BTM_SetDeviceClass (cod);
294 }
295
296 return (BTM_SUCCESS);
297 }
298
299 /*******************************************************************************
300 **
301 ** Function BTM_SetInquiryScanType
302 **
303 ** Description This function is called to set the iquiry scan-type to
304 ** standard or interlaced.
305 **
306 ** Returns BTM_SUCCESS if successful
307 ** BTM_MODE_UNSUPPORTED if not a 1.2 device
308 ** BTM_WRONG_MODE if the device is not up.
309 **
310 *******************************************************************************/
BTM_SetInquiryScanType(UINT16 scan_type)311 tBTM_STATUS BTM_SetInquiryScanType (UINT16 scan_type)
312 {
313
314 BTM_TRACE_API0 ("BTM_SetInquiryScanType");
315 if (scan_type != BTM_SCAN_TYPE_STANDARD && scan_type != BTM_SCAN_TYPE_INTERLACED)
316 return (BTM_ILLEGAL_VALUE);
317
318 /* whatever app wants if device is not 1.2 scan type should be STANDARD */
319 if (!HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
320 return (BTM_MODE_UNSUPPORTED);
321
322 /* Check for scan type if configuration has been changed */
323 if (scan_type != btm_cb.btm_inq_vars.inq_scan_type)
324 {
325 if (BTM_IsDeviceUp())
326 {
327 if (btsnd_hcic_write_inqscan_type ((UINT8)scan_type))
328 btm_cb.btm_inq_vars.inq_scan_type = scan_type;
329 else
330 return (BTM_NO_RESOURCES);
331 }
332 else return (BTM_WRONG_MODE);
333 }
334 return (BTM_SUCCESS);
335 }
336
337 /*******************************************************************************
338 **
339 ** Function BTM_SetPageScanType
340 **
341 ** Description This function is called to set the page scan-type to
342 ** standard or interlaced.
343 **
344 ** Returns BTM_SUCCESS if successful
345 ** BTM_MODE_UNSUPPORTED if not a 1.2 device
346 ** BTM_WRONG_MODE if the device is not up.
347 **
348 *******************************************************************************/
BTM_SetPageScanType(UINT16 scan_type)349 tBTM_STATUS BTM_SetPageScanType (UINT16 scan_type)
350 {
351 BTM_TRACE_API0 ("BTM_SetPageScanType");
352 if (scan_type != BTM_SCAN_TYPE_STANDARD && scan_type != BTM_SCAN_TYPE_INTERLACED)
353 return (BTM_ILLEGAL_VALUE);
354
355 /* whatever app wants if device is not 1.2 scan type should be STANDARD */
356 if (!HCI_LMP_INTERLACED_PAGE_SCAN_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
357 return (BTM_MODE_UNSUPPORTED);
358
359 /* Check for scan type if configuration has been changed */
360 if (scan_type != btm_cb.btm_inq_vars.page_scan_type)
361 {
362 if (BTM_IsDeviceUp())
363 {
364 if (btsnd_hcic_write_pagescan_type ((UINT8)scan_type))
365 btm_cb.btm_inq_vars.page_scan_type = scan_type;
366 else
367 return (BTM_NO_RESOURCES);
368 }
369 else return (BTM_WRONG_MODE);
370 }
371 return (BTM_SUCCESS);
372 }
373
374
375 /*******************************************************************************
376 **
377 ** Function BTM_SetInquiryMode
378 **
379 ** Description This function is called to set standard or with RSSI
380 ** mode of the inquiry for local device.
381 **
382 ** Output Params: mode - standard, with RSSI, extended
383 **
384 ** Returns BTM_SUCCESS if successful
385 ** BTM_NO_RESOURCES if couldn't get a memory pool buffer
386 ** BTM_ILLEGAL_VALUE if a bad parameter was detected
387 ** BTM_WRONG_MODE if the device is not up.
388 **
389 *******************************************************************************/
BTM_SetInquiryMode(UINT8 mode)390 tBTM_STATUS BTM_SetInquiryMode (UINT8 mode)
391 {
392 BTM_TRACE_API0 ("BTM_SetInquiryMode");
393 if (mode == BTM_INQ_RESULT_STANDARD)
394 {
395 /* mandatory mode */
396 }
397 else if (mode == BTM_INQ_RESULT_WITH_RSSI)
398 {
399 if (!HCI_LMP_INQ_RSSI_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
400 return (BTM_MODE_UNSUPPORTED);
401 }
402 #if (( BTM_EIR_CLIENT_INCLUDED == TRUE )||( BTM_EIR_SERVER_INCLUDED == TRUE ))
403 else if (mode == BTM_INQ_RESULT_EXTENDED)
404 {
405 if (!HCI_EXT_INQ_RSP_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
406 return (BTM_MODE_UNSUPPORTED);
407 }
408 #endif
409 else
410 return (BTM_ILLEGAL_VALUE);
411
412 if (!BTM_IsDeviceUp())
413 return (BTM_WRONG_MODE);
414
415 if (!btsnd_hcic_write_inquiry_mode (mode))
416 return (BTM_NO_RESOURCES);
417
418 return (BTM_SUCCESS);
419 }
420
421 /*******************************************************************************
422 **
423 ** Function BTM_ReadDiscoverability
424 **
425 ** Description This function is called to read the current discoverability
426 ** mode of the device.
427 **
428 ** Output Params: p_window - current inquiry scan duration
429 ** p_interval - current inquiry scan interval
430 **
431 ** Returns BTM_NON_DISCOVERABLE, BTM_LIMITED_DISCOVERABLE, or
432 ** BTM_GENERAL_DISCOVERABLE
433 **
434 *******************************************************************************/
BTM_ReadDiscoverability(UINT16 * p_window,UINT16 * p_interval)435 UINT16 BTM_ReadDiscoverability (UINT16 *p_window, UINT16 *p_interval)
436 {
437 BTM_TRACE_API0 ("BTM_ReadDiscoverability");
438 if (p_window)
439 *p_window = btm_cb.btm_inq_vars.inq_scan_window;
440
441 if (p_interval)
442 *p_interval = btm_cb.btm_inq_vars.inq_scan_period;
443
444 return (btm_cb.btm_inq_vars.discoverable_mode);
445 }
446
447
448 /*******************************************************************************
449 **
450 ** Function BTM_SetPeriodicInquiryMode
451 **
452 ** Description This function is called to set the device periodic inquiry mode.
453 ** If the duration is zero, the periodic inquiry mode is cancelled.
454 **
455 ** Note: We currently do not allow concurrent inquiry and periodic inquiry.
456 **
457 ** Parameters: p_inqparms - pointer to the inquiry information
458 ** mode - GENERAL or LIMITED inquiry
459 ** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED)
460 ** max_resps - maximum amount of devices to search for before ending the inquiry
461 ** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or
462 ** BTM_FILTER_COND_BD_ADDR
463 ** filter_cond - value for the filter (based on filter_cond_type)
464 **
465 ** max_delay - maximum amount of time between successive inquiries
466 ** min_delay - minimum amount of time between successive inquiries
467 ** p_results_cb - callback returning pointer to results (tBTM_INQ_RESULTS)
468 **
469 ** Returns BTM_CMD_STARTED if successfully started
470 ** BTM_ILLEGAL_VALUE if a bad parameter is detected
471 ** BTM_NO_RESOURCES if could not allocate a message buffer
472 ** BTM_SUCCESS - if cancelling the periodic inquiry
473 ** BTM_BUSY - if an inquiry is already active
474 ** BTM_WRONG_MODE if the device is not up.
475 **
476 *******************************************************************************/
BTM_SetPeriodicInquiryMode(tBTM_INQ_PARMS * p_inqparms,UINT16 max_delay,UINT16 min_delay,tBTM_INQ_RESULTS_CB * p_results_cb)477 tBTM_STATUS BTM_SetPeriodicInquiryMode (tBTM_INQ_PARMS *p_inqparms, UINT16 max_delay,
478 UINT16 min_delay, tBTM_INQ_RESULTS_CB *p_results_cb)
479 {
480 tBTM_STATUS status;
481 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
482
483 BTM_TRACE_API6 ("BTM_SetPeriodicInquiryMode: mode: %d, dur: %d, rsps: %d, flt: %d, min: %d, max: %d",
484 p_inqparms->mode, p_inqparms->duration, p_inqparms->max_resps,
485 p_inqparms->filter_cond_type, min_delay, max_delay);
486
487 /*** Make sure the device is ready ***/
488 if (!BTM_IsDeviceUp())
489 return (BTM_WRONG_MODE);
490
491 /* Only one active inquiry is allowed in this implementation.
492 Also do not allow an inquiry if the inquiry filter is being updated */
493 if (p_inq->inq_active || p_inq->inqfilt_active)
494 return (BTM_BUSY);
495
496 /* If illegal parameters return FALSE */
497 if (p_inqparms->mode != BTM_GENERAL_INQUIRY &&
498 p_inqparms->mode != BTM_LIMITED_INQUIRY)
499 return (BTM_ILLEGAL_VALUE);
500
501 /* Verify the parameters for this command */
502 if (p_inqparms->duration < BTM_MIN_INQUIRY_LEN ||
503 p_inqparms->duration > BTM_MAX_INQUIRY_LENGTH ||
504 min_delay <= p_inqparms->duration ||
505 min_delay < BTM_PER_INQ_MIN_MIN_PERIOD ||
506 min_delay > BTM_PER_INQ_MAX_MIN_PERIOD ||
507 max_delay <= min_delay ||
508 max_delay < BTM_PER_INQ_MIN_MAX_PERIOD)
509 /* max_delay > BTM_PER_INQ_MAX_MAX_PERIOD)*/
510 /* BTM_PER_INQ_MAX_MAX_PERIOD set to 1's in all bits. Condition resulting in false always*/
511 {
512 return (BTM_ILLEGAL_VALUE);
513 }
514
515 /* Save the inquiry parameters to be used upon the completion of setting/clearing the inquiry filter */
516 p_inq->inqparms = *p_inqparms;
517 p_inq->per_min_delay = min_delay;
518 p_inq->per_max_delay = max_delay;
519 p_inq->inq_cmpl_info.num_resp = 0; /* Clear the results counter */
520 p_inq->p_inq_results_cb = p_results_cb;
521
522 p_inq->inq_active = (UINT8)((p_inqparms->mode == BTM_LIMITED_INQUIRY) ?
523 (BTM_LIMITED_INQUIRY_ACTIVE | BTM_PERIODIC_INQUIRY_ACTIVE) :
524 (BTM_GENERAL_INQUIRY_ACTIVE | BTM_PERIODIC_INQUIRY_ACTIVE));
525
526 #if (defined(BTM_BYPASS_EVENT_FILTERING) && BTM_BYPASS_EVENT_FILTERING == TRUE)
527 BTM_TRACE_WARNING0("BTM: Bypassing event filtering...");
528
529 p_inq->state = BTM_INQ_ACTIVE_STATE;
530 p_inq->inqfilt_active = FALSE;
531 btm_initiate_inquiry (p_inq);
532 status = BTM_CMD_STARTED;
533 #else
534 /* If a filter is specified, then save it for later and clear the current filter.
535 The setting of the filter is done upon completion of clearing of the previous
536 filter.
537 */
538 if (p_inqparms->filter_cond_type != BTM_CLR_INQUIRY_FILTER)
539 {
540 p_inq->state = BTM_INQ_CLR_FILT_STATE;
541 p_inqparms->filter_cond_type = BTM_CLR_INQUIRY_FILTER;
542 }
543 else /* The filter is not being used so simply clear it; the inquiry can start after this operation */
544 p_inq->state = BTM_INQ_SET_FILT_STATE;
545
546 /* Before beginning the inquiry the current filter must be cleared, so initiate the command */
547 if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type, &p_inqparms->filter_cond)) != BTM_CMD_STARTED)
548 {
549 /* If set filter command is not succesful reset the state */
550 p_inq->p_inq_results_cb = NULL;
551 p_inq->state = BTM_INQ_INACTIVE_STATE;
552
553 }
554
555 #endif
556 return (status);
557 }
558
559
560 /*******************************************************************************
561 **
562 ** Function BTM_CancelPeriodicInquiry
563 **
564 ** Description This function cancels a periodic inquiry
565 **
566 ** Returns
567 ** BTM_NO_RESOURCES if could not allocate a message buffer
568 ** BTM_SUCCESS - if cancelling the periodic inquiry
569 ** BTM_WRONG_MODE if the device is not up.
570 **
571 *******************************************************************************/
BTM_CancelPeriodicInquiry(void)572 tBTM_STATUS BTM_CancelPeriodicInquiry(void)
573 {
574 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
575 tBTM_STATUS status = BTM_SUCCESS;
576 BTM_TRACE_API0 ("BTM_CancelPeriodicInquiry called");
577
578 /*** Make sure the device is ready ***/
579 if (!BTM_IsDeviceUp())
580 return (BTM_WRONG_MODE);
581
582 /* Only cancel if one is active */
583 if (btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)
584 {
585 btm_cb.btm_inq_vars.inq_active = BTM_INQUIRY_INACTIVE;
586 btm_cb.btm_inq_vars.p_inq_results_cb = (tBTM_INQ_RESULTS_CB *) NULL;
587
588 if (!btsnd_hcic_exit_per_inq ())
589 status = BTM_NO_RESOURCES;
590
591 /* If the event filter is in progress, mark it so that the processing of the return
592 event will be ignored */
593 if(p_inq->inqfilt_active)
594 p_inq->pending_filt_complete_event++;
595
596 p_inq->inqfilt_active = FALSE;
597 p_inq->inq_counter++;
598 }
599
600 return (status);
601 }
602
603
604 /*******************************************************************************
605 **
606 ** Function BTM_SetConnectability
607 **
608 ** Description This function is called to set the device into or out of
609 ** connectable mode. Discoverable mode means page scans enabled.
610 **
611 ** Returns BTM_SUCCESS if successful
612 ** BTM_ILLEGAL_VALUE if a bad parameter is detected
613 ** BTM_NO_RESOURCES if could not allocate a message buffer
614 ** BTM_WRONG_MODE if the device is not up.
615 **
616 *******************************************************************************/
BTM_SetConnectability(UINT16 page_mode,UINT16 window,UINT16 interval)617 tBTM_STATUS BTM_SetConnectability (UINT16 page_mode, UINT16 window, UINT16 interval)
618 {
619 UINT8 scan_mode = 0;
620 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
621
622 BTM_TRACE_API0 ("BTM_SetConnectability");
623
624 #if (BLE_INCLUDED == TRUE && BLE_INCLUDED == TRUE)
625 if (HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
626 {
627 if (btm_ble_set_connectability(page_mode) != BTM_SUCCESS)
628 {
629 return BTM_NO_RESOURCES;
630 }
631 p_inq->connectable_mode &= (~BTM_BLE_CONNECTABLE_MASK);
632 p_inq->connectable_mode |= (page_mode & BTM_BLE_CONNECTABLE_MASK);
633 }
634 page_mode &= ~BTM_BLE_CONNECTABLE_MASK;
635 #endif
636
637 /*** Check mode parameter ***/
638 if (page_mode != BTM_NON_CONNECTABLE && page_mode != BTM_CONNECTABLE)
639 return (BTM_ILLEGAL_VALUE);
640
641 /* Make sure the controller is active */
642 if (btm_cb.devcb.state < BTM_DEV_STATE_READY)
643 return (BTM_DEV_RESET);
644
645 /* If the window and/or interval is '0', set to default values */
646 if (!window)
647 window = BTM_DEFAULT_CONN_WINDOW;
648
649 if (!interval)
650 interval = BTM_DEFAULT_CONN_INTERVAL;
651
652 BTM_TRACE_API3 ("BTM_SetConnectability: mode %d [NonConn-0, Conn-1], window 0x%04x, interval 0x%04x",
653 page_mode, window, interval);
654
655 /*** Check for valid window and interval parameters ***/
656 /*** Only check window and duration if mode is connectable ***/
657 if (page_mode == BTM_CONNECTABLE)
658 {
659 /* window must be less than or equal to interval */
660 if (window < HCI_MIN_PAGESCAN_WINDOW ||
661 window > HCI_MAX_PAGESCAN_WINDOW ||
662 interval < HCI_MIN_PAGESCAN_INTERVAL ||
663 interval > HCI_MAX_PAGESCAN_INTERVAL ||
664 window > interval)
665 {
666 return (BTM_ILLEGAL_VALUE);
667 }
668
669 scan_mode |= HCI_PAGE_SCAN_ENABLED;
670 }
671
672 if ((window != p_inq->page_scan_window) ||
673 (interval != p_inq->page_scan_period))
674 {
675 p_inq->page_scan_window = window;
676 p_inq->page_scan_period = interval;
677 if (!btsnd_hcic_write_pagescan_cfg (interval, window))
678 return (BTM_NO_RESOURCES);
679 }
680
681 /* Keep the inquiry scan as previouosly set */
682 if (p_inq->discoverable_mode & BTM_DISCOVERABLE_MASK)
683 scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
684
685 if (btsnd_hcic_write_scan_enable (scan_mode))
686 {
687 p_inq->connectable_mode &= (~BTM_CONNECTABLE_MASK);
688 p_inq->connectable_mode |= page_mode;
689
690 return (BTM_SUCCESS);
691 }
692
693 return (BTM_NO_RESOURCES);
694 }
695
696
697 /*******************************************************************************
698 **
699 ** Function BTM_ReadConnectability
700 **
701 ** Description This function is called to read the current discoverability
702 ** mode of the device.
703 ** Output Params p_window - current page scan duration
704 ** p_interval - current time between page scans
705 **
706 ** Returns BTM_NON_CONNECTABLE or BTM_CONNECTABLE
707 **
708 *******************************************************************************/
BTM_ReadConnectability(UINT16 * p_window,UINT16 * p_interval)709 UINT16 BTM_ReadConnectability (UINT16 *p_window, UINT16 *p_interval)
710 {
711 BTM_TRACE_API0 ("BTM_ReadConnectability");
712 if (p_window)
713 *p_window = btm_cb.btm_inq_vars.page_scan_window;
714
715 if (p_interval)
716 *p_interval = btm_cb.btm_inq_vars.page_scan_period;
717
718 return (btm_cb.btm_inq_vars.connectable_mode);
719 }
720
721
722
723 /*******************************************************************************
724 **
725 ** Function BTM_IsInquiryActive
726 **
727 ** Description This function returns a bit mask of the current inquiry state
728 **
729 ** Returns BTM_INQUIRY_INACTIVE if inactive (0)
730 ** BTM_LIMITED_INQUIRY_ACTIVE if a limted inquiry is active
731 ** BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active
732 ** BTM_PERIODIC_INQUIRY_ACTIVE if a periodic inquiry is active
733 **
734 *******************************************************************************/
BTM_IsInquiryActive(void)735 UINT16 BTM_IsInquiryActive (void)
736 {
737 BTM_TRACE_API0 ("BTM_IsInquiryActive");
738
739 return(btm_cb.btm_inq_vars.inq_active);
740 }
741
742
743
744 /*******************************************************************************
745 **
746 ** Function BTM_CancelInquiry
747 **
748 ** Description This function cancels an inquiry if active
749 **
750 ** Returns BTM_SUCCESS if successful
751 ** BTM_NO_RESOURCES if could not allocate a message buffer
752 ** BTM_WRONG_MODE if the device is not up.
753 **
754 *******************************************************************************/
BTM_CancelInquiry(void)755 tBTM_STATUS BTM_CancelInquiry(void)
756 {
757 tBTM_STATUS status = BTM_SUCCESS;
758 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
759
760 BTM_TRACE_API0 ("BTM_CancelInquiry called");
761
762 /*** Make sure the device is ready ***/
763 if (!BTM_IsDeviceUp())
764 return (BTM_WRONG_MODE);
765
766 /* Only cancel if not in periodic mode, otherwise the caller should call BTM_CancelPeriodicMode */
767 if ((p_inq->inq_active &BTM_INQUIRY_ACTIVE_MASK) != 0 &&
768 (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)))
769 {
770 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
771 p_inq->state = BTM_INQ_INACTIVE_STATE;
772 p_inq->p_inq_results_cb = (tBTM_INQ_RESULTS_CB *) NULL; /* Do not notify caller anymore */
773 p_inq->p_inq_cmpl_cb = (tBTM_CMPL_CB *) NULL; /* Do not notify caller anymore */
774
775 /* If the event filter is in progress, mark it so that the processing of the return
776 event will be ignored */
777 if (p_inq->inqfilt_active)
778 {
779 p_inq->inqfilt_active = FALSE;
780 p_inq->pending_filt_complete_event++;
781 }
782 /* Initiate the cancel inquiry */
783 else
784 {
785 if ((p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK) != 0)
786 {
787 if (!btsnd_hcic_inq_cancel())
788 status = BTM_NO_RESOURCES;
789 }
790 #if BLE_INCLUDED == TRUE
791 if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
792 btm_ble_stop_scan();
793 #endif
794 }
795
796 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
797 /* Do not send the BUSY_LEVEL event yet. Wait for the cancel_complete event
798 * and then send the BUSY_LEVEL event
799 * btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
800 */
801 #endif
802
803 p_inq->inq_counter++;
804 btm_clr_inq_result_flt();
805 }
806
807 return (status);
808 }
809
810
811 /*******************************************************************************
812 **
813 ** Function BTM_StartInquiry
814 **
815 ** Description This function is called to start an inquiry.
816 **
817 ** Parameters: p_inqparms - pointer to the inquiry information
818 ** mode - GENERAL or LIMITED inquiry, BR/LE bit mask seperately
819 ** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED)
820 ** max_resps - maximum amount of devices to search for before ending the inquiry
821 ** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or
822 ** BTM_FILTER_COND_BD_ADDR
823 ** filter_cond - value for the filter (based on filter_cond_type)
824 **
825 ** p_results_cb - Pointer to the callback routine which gets called
826 ** upon receipt of an inquiry result. If this field is
827 ** NULL, the application is not notified.
828 **
829 ** p_cmpl_cb - Pointer to the callback routine which gets called
830 ** upon completion. If this field is NULL, the
831 ** application is not notified when completed.
832 ** Returns tBTM_STATUS
833 ** BTM_CMD_STARTED if successfully initiated
834 ** BTM_BUSY if already in progress
835 ** BTM_ILLEGAL_VALUE if parameter(s) are out of range
836 ** BTM_NO_RESOURCES if could not allocate resources to start the command
837 ** BTM_WRONG_MODE if the device is not up.
838 **
839 *******************************************************************************/
BTM_StartInquiry(tBTM_INQ_PARMS * p_inqparms,tBTM_INQ_RESULTS_CB * p_results_cb,tBTM_CMPL_CB * p_cmpl_cb)840 tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p_results_cb,
841 tBTM_CMPL_CB *p_cmpl_cb)
842 {
843 tBTM_STATUS status = BTM_CMD_STARTED;
844 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
845
846 BTM_TRACE_API4 ("BTM_StartInquiry: mode: %d, dur: %d, rsps: %d, flt: %d",
847 p_inqparms->mode, p_inqparms->duration, p_inqparms->max_resps,
848 p_inqparms->filter_cond_type);
849
850 /* Only one active inquiry is allowed in this implementation.
851 Also do not allow an inquiry if the inquiry filter is being updated */
852 if (p_inq->inq_active || p_inq->inqfilt_active)
853 return (BTM_BUSY);
854
855 /*** Make sure the device is ready ***/
856 if (!BTM_IsDeviceUp())
857 return (BTM_WRONG_MODE);
858
859 if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_GENERAL_INQUIRY &&
860 (p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_LIMITED_INQUIRY
861 #if (BLE_INCLUDED == TRUE)
862 && (p_inqparms->mode & BTM_BLE_INQUIRY_MASK)!= BTM_BLE_GENERAL_INQUIRY
863 && (p_inqparms->mode & BTM_BLE_INQUIRY_MASK)!= BTM_BLE_LIMITED_INQUIRY
864 #endif
865 )
866 return (BTM_ILLEGAL_VALUE);
867
868 /* Save the inquiry parameters to be used upon the completion of setting/clearing the inquiry filter */
869 p_inq->inqparms = *p_inqparms;
870
871 /* Initialize the inquiry variables */
872 p_inq->state = BTM_INQ_ACTIVE_STATE;
873 p_inq->p_inq_cmpl_cb = p_cmpl_cb;
874 p_inq->p_inq_results_cb = p_results_cb;
875 p_inq->inq_cmpl_info.num_resp = 0; /* Clear the results counter */
876 p_inq->inq_active = p_inqparms->mode;
877
878 BTM_TRACE_DEBUG1("BTM_StartInquiry: p_inq->inq_active = 0x%02x", p_inq->inq_active);
879
880 /* start LE inquiry here if requested */
881 #if BLE_INCLUDED == TRUE
882 if (p_inqparms->mode & BTM_BLE_INQUIRY_MASK)
883 {
884 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
885 {
886 p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK;
887 status = BTM_ILLEGAL_VALUE;
888 }
889 /* BLE for now does not support filter condition for inquiry */
890 else if ((status = btm_ble_start_inquiry((UINT8)(p_inqparms->mode & BTM_BLE_INQUIRY_MASK),
891 p_inqparms->duration)) != BTM_CMD_STARTED)
892 {
893 BTM_TRACE_ERROR0("Err Starting LE Inquiry.");
894 p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK;
895 }
896
897 p_inqparms->mode &= ~BTM_BLE_INQUIRY_MASK;
898
899 BTM_TRACE_DEBUG1("BTM_StartInquiry: mode = %02x", p_inqparms->mode);
900 }
901 #endif /* end of BLE_INCLUDED */
902
903 /* we're done with this routine if BR/EDR inquiry is not desired. */
904 if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK) == BTM_INQUIRY_NONE)
905 return status;
906
907 #if (defined(BTM_BYPASS_EVENT_FILTERING) && BTM_BYPASS_EVENT_FILTERING == TRUE)
908 BTM_TRACE_WARNING0("BTM: Bypassing event filtering...");
909 p_inq->inqfilt_active = FALSE;
910 btm_initiate_inquiry (p_inq);
911 status = BTM_CMD_STARTED;
912 #else
913 /* If a filter is specified, then save it for later and clear the current filter.
914 The setting of the filter is done upon completion of clearing of the previous
915 filter.
916 */
917 switch (p_inqparms->filter_cond_type)
918 {
919 case BTM_CLR_INQUIRY_FILTER:
920 p_inq->state = BTM_INQ_SET_FILT_STATE;
921 break;
922
923 case BTM_FILTER_COND_DEVICE_CLASS:
924 case BTM_FILTER_COND_BD_ADDR:
925 /* The filter is not being used so simply clear it;
926 the inquiry can start after this operation */
927 p_inq->state = BTM_INQ_CLR_FILT_STATE;
928 p_inqparms->filter_cond_type = BTM_CLR_INQUIRY_FILTER;
929 /* =============>>>> adding LE filtering here ????? */
930 break;
931
932 default:
933 return (BTM_ILLEGAL_VALUE);
934 }
935
936 /* Before beginning the inquiry the current filter must be cleared, so initiate the command */
937 if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type, &p_inqparms->filter_cond)) != BTM_CMD_STARTED)
938 p_inq->state = BTM_INQ_INACTIVE_STATE;
939 #endif
940 return (status);
941 }
942
943
944 /*******************************************************************************
945 **
946 ** Function BTM_ReadRemoteDeviceName
947 **
948 ** Description This function initiates a remote device HCI command to the
949 ** controller and calls the callback when the process has completed.
950 **
951 ** Input Params: remote_bda - device address of name to retrieve
952 ** p_cb - callback function called when BTM_CMD_STARTED
953 ** is returned.
954 ** A pointer to tBTM_REMOTE_DEV_NAME is passed to the
955 ** callback.
956 **
957 ** Returns
958 ** BTM_CMD_STARTED is returned if the request was successfully sent
959 ** to HCI.
960 ** BTM_BUSY if already in progress
961 ** BTM_UNKNOWN_ADDR if device address is bad
962 ** BTM_NO_RESOURCES if could not allocate resources to start the command
963 ** BTM_WRONG_MODE if the device is not up.
964 **
965 *******************************************************************************/
BTM_ReadRemoteDeviceName(BD_ADDR remote_bda,tBTM_CMPL_CB * p_cb)966 tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
967 {
968 tBTM_INQ_INFO *p_cur = NULL;
969 tINQ_DB_ENT *p_i;
970
971 #if BLE_INCLUDED == TRUE
972 tBT_DEVICE_TYPE dev_type;
973 tBLE_ADDR_TYPE addr_type;
974 #endif
975
976 BTM_TRACE_API6 ("BTM_ReadRemoteDeviceName: bd addr [%02x%02x%02x%02x%02x%02x]",
977 remote_bda[0], remote_bda[1], remote_bda[2],
978 remote_bda[3], remote_bda[4], remote_bda[5]);
979
980 /* Use the remote device's clock offset if it is in the local inquiry database */
981 if ((p_i = btm_inq_db_find (remote_bda)) != NULL)
982 {
983 p_cur = &p_i->inq_info;
984
985 #if (BTM_INQ_GET_REMOTE_NAME == TRUE)
986 p_cur->remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
987 #endif
988 }
989 BTM_TRACE_API0 ("no device found in inquiry db");
990
991 #if (BLE_INCLUDED == TRUE)
992 BTM_ReadDevInfo(remote_bda, &dev_type, &addr_type);
993 if (dev_type == BT_DEVICE_TYPE_BLE)
994 {
995 return btm_ble_read_remote_name(remote_bda, p_cur, p_cb);
996 }
997 else
998 #endif
999
1000 return (btm_initiate_rem_name (remote_bda, p_cur, BTM_RMT_NAME_EXT,
1001 BTM_EXT_RMT_NAME_TIMEOUT, p_cb));
1002 }
1003
1004 /*******************************************************************************
1005 **
1006 ** Function BTM_CancelRemoteDeviceName
1007 **
1008 ** Description This function initiates the cancel request for the specified
1009 ** remote device.
1010 **
1011 ** Input Params: None
1012 **
1013 ** Returns
1014 ** BTM_CMD_STARTED is returned if the request was successfully sent
1015 ** to HCI.
1016 ** BTM_NO_RESOURCES if could not allocate resources to start the command
1017 ** BTM_WRONG_MODE if there is not an active remote name request.
1018 **
1019 *******************************************************************************/
BTM_CancelRemoteDeviceName(void)1020 tBTM_STATUS BTM_CancelRemoteDeviceName (void)
1021 {
1022 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1023
1024 #if BLE_INCLUDED == TRUE
1025 tBT_DEVICE_TYPE dev_type;
1026 tBLE_ADDR_TYPE addr_type;
1027 #endif
1028
1029 BTM_TRACE_API0 ("BTM_CancelRemoteDeviceName()");
1030
1031 /* Make sure there is not already one in progress */
1032 if (p_inq->remname_active)
1033 {
1034 #if BLE_INCLUDED == TRUE
1035 BTM_ReadDevInfo(p_inq->remname_bda, &dev_type, &addr_type);
1036 if (dev_type == BT_DEVICE_TYPE_BLE)
1037 {
1038 if (btm_ble_cancel_remote_name(p_inq->remname_bda))
1039 return (BTM_CMD_STARTED);
1040 else
1041 return (BTM_UNKNOWN_ADDR);
1042 }
1043 else
1044 #endif
1045 if (btsnd_hcic_rmt_name_req_cancel (p_inq->remname_bda))
1046 return (BTM_CMD_STARTED);
1047 else
1048 return (BTM_NO_RESOURCES);
1049 }
1050 else
1051 return (BTM_WRONG_MODE);
1052 }
1053
1054 /*******************************************************************************
1055 **
1056 ** Function BTM_InqFirstResult
1057 **
1058 ** Description This function looks through the inquiry database for the first
1059 ** used entrysince the LAST inquiry. This is used in conjunction
1060 ** with BTM_InqNext by applications as a way to walk through the
1061 ** inquiry results database.
1062 **
1063 ** Returns pointer to first in-use entry, or NULL if DB is empty
1064 **
1065 *******************************************************************************/
BTM_InqFirstResult(void)1066 tBTM_INQ_INFO *BTM_InqFirstResult (void)
1067 {
1068 UINT16 xx;
1069 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1070 UINT32 cur_inq_count = btm_cb.btm_inq_vars.inq_counter - 1;
1071
1072 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1073 {
1074 if (p_ent->in_use && p_ent->inq_count == cur_inq_count)
1075 return (&p_ent->inq_info);
1076 }
1077
1078 /* If here, no used entry found */
1079 return ((tBTM_INQ_INFO *)NULL);
1080 }
1081
1082
1083 /*******************************************************************************
1084 **
1085 ** Function BTM_InqNextResult
1086 **
1087 ** Description This function looks through the inquiry database for the next
1088 ** used entrysince the LAST inquiry. If the input parameter is NULL,
1089 ** the first entry is returned.
1090 **
1091 ** Returns pointer to next in-use entry, or NULL if no more found.
1092 **
1093 *******************************************************************************/
BTM_InqNextResult(tBTM_INQ_INFO * p_cur)1094 tBTM_INQ_INFO *BTM_InqNextResult (tBTM_INQ_INFO *p_cur)
1095 {
1096 tINQ_DB_ENT *p_ent;
1097 UINT16 inx;
1098 UINT32 cur_inq_count = btm_cb.btm_inq_vars.inq_counter - 1;
1099
1100 if (p_cur)
1101 {
1102 p_ent = (tINQ_DB_ENT *) ((UINT8 *)p_cur - offsetof (tINQ_DB_ENT, inq_info));
1103 inx = (UINT16)((p_ent - btm_cb.btm_inq_vars.inq_db) + 1);
1104
1105 for (p_ent = &btm_cb.btm_inq_vars.inq_db[inx]; inx < BTM_INQ_DB_SIZE; inx++, p_ent++)
1106 {
1107 if (p_ent->in_use && p_ent->inq_count == cur_inq_count)
1108 return (&p_ent->inq_info);
1109 }
1110
1111 /* If here, more entries found */
1112 return ((tBTM_INQ_INFO *)NULL);
1113 }
1114 else
1115 return (BTM_InqDbFirst());
1116 }
1117
1118
1119 /*******************************************************************************
1120 **
1121 ** Function BTM_InqDbRead
1122 **
1123 ** Description This function looks through the inquiry database for a match
1124 ** based on Bluetooth Device Address. This is the application's
1125 ** interface to get the inquiry details of a specific BD address.
1126 **
1127 ** Returns pointer to entry, or NULL if not found
1128 **
1129 *******************************************************************************/
BTM_InqDbRead(BD_ADDR p_bda)1130 tBTM_INQ_INFO *BTM_InqDbRead (BD_ADDR p_bda)
1131 {
1132 UINT16 xx;
1133 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1134
1135 BTM_TRACE_API6 ("BTM_InqDbRead: bd addr [%02x%02x%02x%02x%02x%02x]",
1136 p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
1137
1138 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1139 {
1140 if ((p_ent->in_use) && (!memcmp (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
1141 return (&p_ent->inq_info);
1142 }
1143
1144 /* If here, not found */
1145 return ((tBTM_INQ_INFO *)NULL);
1146 }
1147
1148
1149 /*******************************************************************************
1150 **
1151 ** Function BTM_InqDbFirst
1152 **
1153 ** Description This function looks through the inquiry database for the first
1154 ** used entry, and returns that. This is used in conjunction with
1155 ** BTM_InqDbNext by applications as a way to walk through the
1156 ** inquiry database.
1157 **
1158 ** Returns pointer to first in-use entry, or NULL if DB is empty
1159 **
1160 *******************************************************************************/
BTM_InqDbFirst(void)1161 tBTM_INQ_INFO *BTM_InqDbFirst (void)
1162 {
1163 UINT16 xx;
1164 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1165
1166 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1167 {
1168 if (p_ent->in_use)
1169 return (&p_ent->inq_info);
1170 }
1171
1172 /* If here, no used entry found */
1173 return ((tBTM_INQ_INFO *)NULL);
1174 }
1175
1176
1177 /*******************************************************************************
1178 **
1179 ** Function BTM_InqDbNext
1180 **
1181 ** Description This function looks through the inquiry database for the next
1182 ** used entry, and returns that. If the input parameter is NULL,
1183 ** the first entry is returned.
1184 **
1185 ** Returns pointer to next in-use entry, or NULL if no more found.
1186 **
1187 *******************************************************************************/
BTM_InqDbNext(tBTM_INQ_INFO * p_cur)1188 tBTM_INQ_INFO *BTM_InqDbNext (tBTM_INQ_INFO *p_cur)
1189 {
1190 tINQ_DB_ENT *p_ent;
1191 UINT16 inx;
1192
1193 if (p_cur)
1194 {
1195 p_ent = (tINQ_DB_ENT *) ((UINT8 *)p_cur - offsetof (tINQ_DB_ENT, inq_info));
1196 inx = (UINT16)((p_ent - btm_cb.btm_inq_vars.inq_db) + 1);
1197
1198 for (p_ent = &btm_cb.btm_inq_vars.inq_db[inx]; inx < BTM_INQ_DB_SIZE; inx++, p_ent++)
1199 {
1200 if (p_ent->in_use)
1201 return (&p_ent->inq_info);
1202 }
1203
1204 /* If here, more entries found */
1205 return ((tBTM_INQ_INFO *)NULL);
1206 }
1207 else
1208 return (BTM_InqDbFirst());
1209 }
1210
1211
1212 /*******************************************************************************
1213 **
1214 ** Function BTM_ClearInqDb
1215 **
1216 ** Description This function is called to clear out a device or all devices
1217 ** from the inquiry database.
1218 **
1219 ** Parameter p_bda - (input) BD_ADDR -> Address of device to clear
1220 ** (NULL clears all entries)
1221 **
1222 ** Returns BTM_BUSY if an inquiry, get remote name, or event filter
1223 ** is active, otherwise BTM_SUCCESS
1224 **
1225 *******************************************************************************/
BTM_ClearInqDb(BD_ADDR p_bda)1226 tBTM_STATUS BTM_ClearInqDb (BD_ADDR p_bda)
1227 {
1228 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1229
1230 /* If an inquiry or remote name is in progress return busy */
1231 if (p_inq->inq_active != BTM_INQUIRY_INACTIVE ||
1232 p_inq->inqfilt_active)
1233 return (BTM_BUSY);
1234
1235 btm_clr_inq_db(p_bda);
1236
1237 return (BTM_SUCCESS);
1238 }
1239
1240
1241 /*******************************************************************************
1242 **
1243 ** Function BTM_ReadNumInqDbEntries
1244 **
1245 ** Returns This function returns the number of entries in the inquiry database.
1246 **
1247 *******************************************************************************/
BTM_ReadNumInqDbEntries(void)1248 UINT8 BTM_ReadNumInqDbEntries (void)
1249 {
1250 UINT8 num_entries;
1251 UINT8 num_results;
1252 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1253
1254 for (num_entries = 0, num_results = 0; num_entries < BTM_INQ_DB_SIZE; num_entries++, p_ent++)
1255 {
1256 if (p_ent->in_use)
1257 num_results++;
1258 }
1259
1260 return (num_results);
1261 }
1262
1263
1264 /*******************************************************************************
1265 **
1266 ** Function BTM_InquiryRegisterForChanges
1267 **
1268 ** Returns This function is called to register a callback for when the
1269 ** inquiry database changes, i.e. new entry or entry deleted.
1270 **
1271 *******************************************************************************/
BTM_InquiryRegisterForChanges(tBTM_INQ_DB_CHANGE_CB * p_cb)1272 tBTM_STATUS BTM_InquiryRegisterForChanges (tBTM_INQ_DB_CHANGE_CB *p_cb)
1273 {
1274 if (!p_cb)
1275 btm_cb.btm_inq_vars.p_inq_change_cb = NULL;
1276 else if (btm_cb.btm_inq_vars.p_inq_change_cb)
1277 return (BTM_BUSY);
1278 else
1279 btm_cb.btm_inq_vars.p_inq_change_cb = p_cb;
1280
1281 return (BTM_SUCCESS);
1282 }
1283
1284
1285 /*******************************************************************************
1286 **
1287 ** Function BTM_SetInquiryFilterCallback
1288 **
1289 ** Description Host can register to be asked whenever an inquiry result
1290 ** is received. If host does not like the device no name
1291 ** request is issued for the device
1292 **
1293 ** Returns void
1294 **
1295 *******************************************************************************/
BTM_SetInquiryFilterCallback(tBTM_FILTER_CB * p_callback)1296 void BTM_SetInquiryFilterCallback (tBTM_FILTER_CB *p_callback)
1297 {
1298 btm_cb.p_inq_filter_cb = p_callback;
1299 }
1300
1301 /*******************************************************************************
1302 **
1303 ** Function BTM_ReadInquiryRspTxPower
1304 **
1305 ** Description This command will read the inquiry Transmit Power level used
1306 ** to transmit the FHS and EIR data packets.
1307 ** This can be used directly in the Tx Power Level EIR data type.
1308 **
1309 ** Returns BTM_SUCCESS if successful
1310 **
1311 *******************************************************************************/
BTM_ReadInquiryRspTxPower(tBTM_CMPL_CB * p_cb)1312 tBTM_STATUS BTM_ReadInquiryRspTxPower (tBTM_CMPL_CB *p_cb)
1313 {
1314 if (btm_cb.devcb.p_txpwer_cmpl_cb)
1315 return (BTM_BUSY);
1316
1317 btu_start_timer (&btm_cb.devcb.txpwer_timer, BTU_TTYPE_BTM_ACL, BTM_INQ_REPLY_TIMEOUT );
1318
1319
1320 btm_cb.devcb.p_txpwer_cmpl_cb = p_cb;
1321
1322 if (!btsnd_hcic_read_inq_tx_power ())
1323 {
1324 btm_cb.devcb.p_txpwer_cmpl_cb = NULL;
1325 btu_stop_timer (&btm_cb.devcb.txpwer_timer);
1326 return (BTM_NO_RESOURCES);
1327 }
1328 else
1329 return (BTM_CMD_STARTED);
1330 }
1331 /*******************************************************************************
1332 **
1333 ** Function BTM_WriteInquiryTxPower
1334 **
1335 ** Description This command is used to write the inquiry transmit power level
1336 ** used to transmit the inquiry (ID) data packets. The Controller
1337 ** should use the supported TX power level closest to the Tx_Power
1338 ** parameter.
1339 **
1340 ** Returns BTM_SUCCESS if successful
1341 **
1342 *******************************************************************************/
BTM_WriteInquiryTxPower(INT8 tx_power)1343 tBTM_STATUS BTM_WriteInquiryTxPower (INT8 tx_power)
1344 {
1345 tBTM_STATUS status = BTM_SUCCESS;
1346
1347 if (tx_power < BTM_MIN_INQ_TX_POWER || tx_power > BTM_MAX_INQ_TX_POWER)
1348 {
1349 status = BTM_ILLEGAL_VALUE;
1350 }
1351 else if (!btsnd_hcic_write_inq_tx_power(tx_power))
1352 status = BTM_NO_RESOURCES;
1353
1354 return status;
1355 }
1356 /*********************************************************************************
1357 **********************************************************************************
1358 ** **
1359 ** BTM Internal Inquiry Functions **
1360 ** **
1361 **********************************************************************************
1362 *********************************************************************************/
1363 /*******************************************************************************
1364 **
1365 ** Function btm_inq_db_reset
1366 **
1367 ** Description This function is called at at reset to clear the inquiry
1368 ** database & pending callback.
1369 **
1370 ** Returns void
1371 **
1372 *******************************************************************************/
btm_inq_db_reset(void)1373 void btm_inq_db_reset (void)
1374 {
1375 tBTM_REMOTE_DEV_NAME rem_name;
1376 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1377 UINT8 num_responses;
1378 UINT8 temp_inq_active;
1379 tBTM_STATUS status;
1380
1381 btu_stop_timer (&p_inq->inq_timer_ent);
1382
1383 /* If an inquiry or periodic inquiry is active, reset the mode to inactive */
1384 if (p_inq->inq_active != BTM_INQUIRY_INACTIVE)
1385 {
1386 temp_inq_active = p_inq->inq_active; /* Save so state can change BEFORE
1387 callback is called */
1388 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1389
1390 /* If not a periodic inquiry, the complete callback must be called to notify caller */
1391 if (temp_inq_active == BTM_LIMITED_INQUIRY_ACTIVE ||
1392 temp_inq_active == BTM_GENERAL_INQUIRY_ACTIVE)
1393 {
1394 if (p_inq->p_inq_cmpl_cb)
1395 {
1396 num_responses = 0;
1397 (*p_inq->p_inq_cmpl_cb)(&num_responses);
1398 }
1399 }
1400 }
1401
1402 /* Cancel a remote name request if active, and notify the caller (if waiting) */
1403 if (p_inq->remname_active )
1404 {
1405 btu_stop_timer (&p_inq->rmt_name_timer_ent);
1406 p_inq->remname_active = FALSE;
1407 memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
1408
1409 if (p_inq->p_remname_cmpl_cb)
1410 {
1411 rem_name.status = BTM_DEV_RESET;
1412
1413 (*p_inq->p_remname_cmpl_cb)(&rem_name);
1414 p_inq->p_remname_cmpl_cb = NULL;
1415 }
1416 }
1417
1418 /* Cancel an inquiry filter request if active, and notify the caller (if waiting) */
1419 if (p_inq->inqfilt_active)
1420 {
1421 p_inq->inqfilt_active = FALSE;
1422
1423 if (p_inq->p_inqfilter_cmpl_cb)
1424 {
1425 status = BTM_DEV_RESET;
1426 (*p_inq->p_inqfilter_cmpl_cb)(&status);
1427 }
1428 }
1429
1430 p_inq->state = BTM_INQ_INACTIVE_STATE;
1431 p_inq->pending_filt_complete_event = 0;
1432 p_inq->p_inq_results_cb = NULL;
1433 btm_clr_inq_db(NULL); /* Clear out all the entries in the database */
1434 btm_clr_inq_result_flt();
1435
1436 p_inq->discoverable_mode = BTM_NON_DISCOVERABLE;
1437 p_inq->connectable_mode = BTM_NON_CONNECTABLE;
1438 p_inq->page_scan_type = BTM_SCAN_TYPE_STANDARD;
1439 p_inq->inq_scan_type = BTM_SCAN_TYPE_STANDARD;
1440
1441 #if BLE_INCLUDED == TRUE
1442 p_inq->discoverable_mode |= BTM_BLE_NON_DISCOVERABLE;
1443 p_inq->connectable_mode |= BTM_BLE_NON_CONNECTABLE;
1444 #endif
1445 return;
1446 }
1447
1448
1449 /*********************************************************************************
1450 **
1451 ** Function btm_inq_db_init
1452 **
1453 ** Description This function is called at startup to initialize the inquiry
1454 ** database.
1455 **
1456 ** Returns void
1457 **
1458 *******************************************************************************/
btm_inq_db_init(void)1459 void btm_inq_db_init (void)
1460 {
1461 #if 0 /* cleared in btm_init; put back in if called from anywhere else! */
1462 memset (&btm_cb.btm_inq_vars, 0, sizeof (tBTM_INQUIRY_VAR_ST));
1463 #endif
1464 btm_cb.btm_inq_vars.no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;
1465 }
1466
1467 /*********************************************************************************
1468 **
1469 ** Function btm_inq_stop_on_ssp
1470 **
1471 ** Description This function is called on incoming SSP
1472 **
1473 ** Returns void
1474 **
1475 *******************************************************************************/
btm_inq_stop_on_ssp(void)1476 void btm_inq_stop_on_ssp(void)
1477 {
1478 UINT8 normal_active = (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE);
1479
1480 #if (BTM_INQ_DEBUG == TRUE)
1481 BTM_TRACE_DEBUG4 ("btm_inq_stop_on_ssp: no_inc_ssp=%d inq_active:0x%x state:%d inqfilt_active:%d",
1482 btm_cb.btm_inq_vars.no_inc_ssp, btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
1483 #endif
1484 if (btm_cb.btm_inq_vars.no_inc_ssp)
1485 {
1486 if (btm_cb.btm_inq_vars.state == BTM_INQ_ACTIVE_STATE)
1487 {
1488 if (btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)
1489 {
1490 BTM_CancelPeriodicInquiry();
1491 }
1492 else if (btm_cb.btm_inq_vars.inq_active & normal_active)
1493 {
1494 /* can not call BTM_CancelInquiry() here. We need to report inquiry complete evt */
1495 btsnd_hcic_inq_cancel();
1496 }
1497 }
1498 /* do not allow inquiry to start */
1499 btm_cb.btm_inq_vars.inq_active |= BTM_SSP_INQUIRY_ACTIVE;
1500 }
1501 }
1502
1503 /*********************************************************************************
1504 **
1505 ** Function btm_inq_clear_ssp
1506 **
1507 ** Description This function is called when pairing_state becomes idle
1508 **
1509 ** Returns void
1510 **
1511 *******************************************************************************/
btm_inq_clear_ssp(void)1512 void btm_inq_clear_ssp(void)
1513 {
1514 btm_cb.btm_inq_vars.inq_active &= ~BTM_SSP_INQUIRY_ACTIVE;
1515 }
1516
1517 /*********************************************************************************
1518 **
1519 ** Function btm_clr_inq_db
1520 **
1521 ** Description This function is called to clear out a device or all devices
1522 ** from the inquiry database.
1523 **
1524 ** Parameter p_bda - (input) BD_ADDR -> Address of device to clear
1525 ** (NULL clears all entries)
1526 **
1527 ** Returns void
1528 **
1529 *******************************************************************************/
btm_clr_inq_db(BD_ADDR p_bda)1530 void btm_clr_inq_db (BD_ADDR p_bda)
1531 {
1532 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1533 tINQ_DB_ENT *p_ent = p_inq->inq_db;
1534 UINT16 xx;
1535
1536 #if (BTM_INQ_DEBUG == TRUE)
1537 BTM_TRACE_DEBUG2 ("btm_clr_inq_db: inq_active:0x%x state:%d",
1538 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1539 #endif
1540 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1541 {
1542 if (p_ent->in_use)
1543 {
1544 /* If this is the specified BD_ADDR or clearing all devices */
1545 if (p_bda == NULL ||
1546 (!memcmp (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
1547 {
1548 p_ent->in_use = FALSE;
1549 #if (BTM_INQ_GET_REMOTE_NAME == TRUE)
1550 p_ent->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
1551 #endif
1552
1553 if (btm_cb.btm_inq_vars.p_inq_change_cb)
1554 (*btm_cb.btm_inq_vars.p_inq_change_cb) (&p_ent->inq_info, FALSE);
1555 }
1556 }
1557 }
1558 #if (BTM_INQ_DEBUG == TRUE)
1559 BTM_TRACE_DEBUG2 ("inq_active:0x%x state:%d",
1560 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1561 #endif
1562 }
1563
1564
1565 /*******************************************************************************
1566 **
1567 ** Function btm_clr_inq_result_flt
1568 **
1569 ** Description This function looks through the bdaddr database for a match
1570 ** based on Bluetooth Device Address
1571 **
1572 ** Returns TRUE if found, else FALSE (new entry)
1573 **
1574 *******************************************************************************/
btm_clr_inq_result_flt(void)1575 static void btm_clr_inq_result_flt (void)
1576 {
1577 #if BTM_USE_INQ_RESULTS_FILTER == TRUE
1578 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1579
1580 if (p_inq->p_bd_db)
1581 {
1582 GKI_freebuf(p_inq->p_bd_db);
1583 p_inq->p_bd_db = NULL;
1584 }
1585 p_inq->num_bd_entries = 0;
1586 p_inq->max_bd_entries = 0;
1587 #endif
1588 }
1589
1590 /*******************************************************************************
1591 **
1592 ** Function btm_inq_find_bdaddr
1593 **
1594 ** Description This function looks through the bdaddr database for a match
1595 ** based on Bluetooth Device Address
1596 **
1597 ** Returns TRUE if found, else FALSE (new entry)
1598 **
1599 *******************************************************************************/
btm_inq_find_bdaddr(BD_ADDR p_bda)1600 BOOLEAN btm_inq_find_bdaddr (BD_ADDR p_bda)
1601 {
1602 #if BTM_USE_INQ_RESULTS_FILTER == TRUE
1603 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1604 tINQ_BDADDR *p_db = &p_inq->p_bd_db[0];
1605 UINT16 xx;
1606
1607 /* Don't bother searching, database doesn't exist or periodic mode */
1608 if ((p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) || !p_db)
1609 return (FALSE);
1610
1611 for (xx = 0; xx < p_inq->num_bd_entries; xx++, p_db++)
1612 {
1613 if (!memcmp(p_db->bd_addr, p_bda, BD_ADDR_LEN)
1614 && p_db->inq_count == p_inq->inq_counter)
1615 return (TRUE);
1616 }
1617
1618 if (xx < p_inq->max_bd_entries)
1619 {
1620 p_db->inq_count = p_inq->inq_counter;
1621 memcpy(p_db->bd_addr, p_bda, BD_ADDR_LEN);
1622 p_inq->num_bd_entries++;
1623 }
1624
1625 #endif
1626 /* If here, New Entry */
1627 return (FALSE);
1628 }
1629
1630 /*******************************************************************************
1631 **
1632 ** Function btm_inq_db_find
1633 **
1634 ** Description This function looks through the inquiry database for a match
1635 ** based on Bluetooth Device Address
1636 **
1637 ** Returns pointer to entry, or NULL if not found
1638 **
1639 *******************************************************************************/
btm_inq_db_find(BD_ADDR p_bda)1640 tINQ_DB_ENT *btm_inq_db_find (BD_ADDR p_bda)
1641 {
1642 UINT16 xx;
1643 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1644
1645 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1646 {
1647 if ((p_ent->in_use) && (!memcmp (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
1648 return (p_ent);
1649 }
1650
1651 /* If here, not found */
1652 return (NULL);
1653 }
1654
1655
1656 /*******************************************************************************
1657 **
1658 ** Function btm_inq_db_new
1659 **
1660 ** Description This function looks through the inquiry database for an unused
1661 ** entry. If no entry is free, it allocates the oldest entry.
1662 **
1663 ** Returns pointer to entry
1664 **
1665 *******************************************************************************/
btm_inq_db_new(BD_ADDR p_bda)1666 tINQ_DB_ENT *btm_inq_db_new (BD_ADDR p_bda)
1667 {
1668 UINT16 xx;
1669 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1670 tINQ_DB_ENT *p_old = btm_cb.btm_inq_vars.inq_db;
1671 UINT32 ot = 0xFFFFFFFF;
1672
1673 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1674 {
1675 if (!p_ent->in_use)
1676 {
1677 memset (p_ent, 0, sizeof (tINQ_DB_ENT));
1678 memcpy (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN);
1679 p_ent->in_use = TRUE;
1680
1681 #if (BTM_INQ_GET_REMOTE_NAME==TRUE)
1682 p_ent->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
1683 #endif
1684
1685 return (p_ent);
1686 }
1687
1688 if (p_ent->time_of_resp < ot)
1689 {
1690 p_old = p_ent;
1691 ot = p_ent->time_of_resp;
1692 }
1693 }
1694
1695 /* If here, no free entry found. Return the oldest. */
1696
1697 /* Before deleting the oldest, if anyone is registered for change */
1698 /* notifications, then tell him we are deleting an entry. */
1699 if (btm_cb.btm_inq_vars.p_inq_change_cb)
1700 (*btm_cb.btm_inq_vars.p_inq_change_cb) (&p_old->inq_info, FALSE);
1701
1702 memset (p_old, 0, sizeof (tINQ_DB_ENT));
1703 memcpy (p_old->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN);
1704 p_old->in_use = TRUE;
1705
1706 #if (BTM_INQ_GET_REMOTE_NAME==TRUE)
1707 p_old->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
1708 #endif
1709
1710 return (p_old);
1711 }
1712
1713
1714 /*******************************************************************************
1715 **
1716 ** Function btm_set_inq_event_filter
1717 **
1718 ** Description This function is called to set the inquiry event filter.
1719 ** It is called by either internally, or by the external API function
1720 ** (BTM_SetInqEventFilter). It is used internally as part of the
1721 ** inquiry processing.
1722 **
1723 ** Input Params:
1724 ** filter_cond_type - this is the type of inquiry filter to apply:
1725 ** BTM_FILTER_COND_DEVICE_CLASS,
1726 ** BTM_FILTER_COND_BD_ADDR, or
1727 ** BTM_CLR_INQUIRY_FILTER
1728 **
1729 ** p_filt_cond - this is either a BD_ADDR or DEV_CLASS depending on the
1730 ** filter_cond_type (See section 4.7.3 of Core Spec 1.0b).
1731 **
1732 ** Returns BTM_CMD_STARTED if successfully initiated
1733 ** BTM_NO_RESOURCES if couldn't get a memory pool buffer
1734 ** BTM_ILLEGAL_VALUE if a bad parameter was detected
1735 **
1736 *******************************************************************************/
btm_set_inq_event_filter(UINT8 filter_cond_type,tBTM_INQ_FILT_COND * p_filt_cond)1737 static tBTM_STATUS btm_set_inq_event_filter (UINT8 filter_cond_type,
1738 tBTM_INQ_FILT_COND *p_filt_cond)
1739 {
1740 UINT8 condition_length = DEV_CLASS_LEN * 2;
1741 UINT8 condition_buf[DEV_CLASS_LEN * 2];
1742 UINT8 *p_cond = condition_buf; /* points to the condition to pass to HCI */
1743
1744 #if (BTM_INQ_DEBUG == TRUE)
1745 BTM_TRACE_DEBUG1 ("btm_set_inq_event_filter: filter type %d [Clear-0, COD-1, BDADDR-2]",
1746 filter_cond_type);
1747 BTM_TRACE_DEBUG6 (" condition [%02x%02x%02x %02x%02x%02x]",
1748 p_filt_cond->bdaddr_cond[0], p_filt_cond->bdaddr_cond[1], p_filt_cond->bdaddr_cond[2],
1749 p_filt_cond->bdaddr_cond[3], p_filt_cond->bdaddr_cond[4], p_filt_cond->bdaddr_cond[5]);
1750 #endif
1751
1752 /* Load the correct filter condition to pass to the lower layer */
1753 switch (filter_cond_type)
1754 {
1755 case BTM_FILTER_COND_DEVICE_CLASS:
1756 /* copy the device class and device class fields into contiguous memory to send to HCI */
1757 memcpy (condition_buf, p_filt_cond->cod_cond.dev_class, DEV_CLASS_LEN);
1758 memcpy (&condition_buf[DEV_CLASS_LEN],
1759 p_filt_cond->cod_cond.dev_class_mask, DEV_CLASS_LEN);
1760
1761 /* condition length should already be set as the default */
1762 break;
1763
1764 case BTM_FILTER_COND_BD_ADDR:
1765 p_cond = p_filt_cond->bdaddr_cond;
1766
1767 /* condition length should already be set as the default */
1768 break;
1769
1770 case BTM_CLR_INQUIRY_FILTER:
1771 condition_length = 0;
1772 break;
1773
1774 default:
1775 return (BTM_ILLEGAL_VALUE); /* Bad parameter was passed in */
1776 }
1777
1778 btm_cb.btm_inq_vars.inqfilt_active = TRUE;
1779
1780 /* Filter the inquiry results for the specified condition type and value */
1781 if (btsnd_hcic_set_event_filter(HCI_FILTER_INQUIRY_RESULT, filter_cond_type,
1782 p_cond, condition_length))
1783
1784 return (BTM_CMD_STARTED);
1785 else
1786 return (BTM_NO_RESOURCES);
1787 }
1788
1789
1790 /*******************************************************************************
1791 **
1792 ** Function btm_event_filter_complete
1793 **
1794 ** Description This function is called when a set event filter has completed.
1795 ** Note: This routine currently only handles inquiry filters.
1796 ** Connection filters are ignored for now.
1797 **
1798 ** Returns void
1799 **
1800 *******************************************************************************/
btm_event_filter_complete(UINT8 * p)1801 void btm_event_filter_complete (UINT8 *p)
1802 {
1803 UINT8 hci_status;
1804 tBTM_STATUS status;
1805 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1806 tBTM_CMPL_CB *p_cb = p_inq->p_inqfilter_cmpl_cb;
1807
1808 #if (BTM_INQ_DEBUG == TRUE)
1809 BTM_TRACE_DEBUG3 ("btm_event_filter_complete: inq_active:0x%x state:%d inqfilt_active:%d",
1810 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
1811 #endif
1812 /* If the filter complete event is from an old or cancelled request, ignore it */
1813 if(p_inq->pending_filt_complete_event)
1814 {
1815 p_inq->pending_filt_complete_event--;
1816 return;
1817 }
1818
1819 /* Only process the inquiry filter; Ignore the connection filter until it
1820 is used by the upper layers */
1821 if (p_inq->inqfilt_active == TRUE )
1822 {
1823 /* Extract the returned status from the buffer */
1824 STREAM_TO_UINT8 (hci_status, p);
1825 if (hci_status != HCI_SUCCESS)
1826 {
1827 /* If standalone operation, return the error status; if embedded in the inquiry, continue the inquiry */
1828 BTM_TRACE_WARNING1 ("BTM Warning: Set Event Filter Failed (HCI returned 0x%x)", hci_status);
1829 status = BTM_ERR_PROCESSING;
1830 }
1831 else
1832 status = BTM_SUCCESS;
1833
1834 /* If the set filter was initiated externally (via BTM_SetInqEventFilter), call the
1835 callback function to notify the initiator that it has completed */
1836 if (p_inq->state == BTM_INQ_INACTIVE_STATE)
1837 {
1838 p_inq->inqfilt_active = FALSE;
1839 if (p_cb)
1840 (*p_cb) (&status);
1841 }
1842 else /* An inquiry is active (the set filter command was internally generated),
1843 process the next state of the process (Set a new filter or start the inquiry). */
1844 {
1845 if(status != BTM_SUCCESS)
1846 {
1847 /* Process the inquiry complete (Error Status) */
1848 btm_process_inq_complete (BTM_ERR_PROCESSING, (UINT8)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
1849
1850 /* btm_process_inq_complete() does not restore the following settings on periodic inquiry */
1851 p_inq->inqfilt_active = FALSE;
1852 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1853 p_inq->state = BTM_INQ_INACTIVE_STATE;
1854
1855 return;
1856 }
1857
1858 /* Check to see if a new filter needs to be set up */
1859 if (p_inq->state == BTM_INQ_CLR_FILT_STATE)
1860 {
1861 if ((status = btm_set_inq_event_filter (p_inq->inqparms.filter_cond_type, &p_inq->inqparms.filter_cond)) == BTM_CMD_STARTED)
1862 {
1863 p_inq->state = BTM_INQ_SET_FILT_STATE;
1864 }
1865 else /* Error setting the filter: Call the initiator's callback function to indicate a failure */
1866 {
1867 p_inq->inqfilt_active = FALSE;
1868
1869 /* Process the inquiry complete (Error Status) */
1870 btm_process_inq_complete (BTM_ERR_PROCESSING, (UINT8)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
1871 }
1872 }
1873 else /* Initiate the Inquiry or Periodic Inquiry */
1874 {
1875 p_inq->state = BTM_INQ_ACTIVE_STATE;
1876 p_inq->inqfilt_active = FALSE;
1877 btm_initiate_inquiry (p_inq);
1878 }
1879 }
1880 }
1881 }
1882
1883
1884 /*******************************************************************************
1885 **
1886 ** Function btm_initiate_inquiry
1887 **
1888 ** Description This function is called to start an inquiry or periodic inquiry
1889 ** upon completion of the setting and/or clearing of the inquiry filter.
1890 **
1891 ** Inputs: p_inq (btm_cb.btm_inq_vars) - pointer to saved inquiry information
1892 ** mode - GENERAL or LIMITED inquiry
1893 ** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED)
1894 ** max_resps - maximum amount of devices to search for before ending the inquiry
1895 ** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or
1896 ** BTM_FILTER_COND_BD_ADDR
1897 ** filter_cond - value for the filter (based on filter_cond_type)
1898 **
1899 ** Returns If an error occurs the initiator's callback is called with the error status.
1900 **
1901 *******************************************************************************/
btm_initiate_inquiry(tBTM_INQUIRY_VAR_ST * p_inq)1902 static void btm_initiate_inquiry (tBTM_INQUIRY_VAR_ST *p_inq)
1903 {
1904 const LAP *lap;
1905 tBTM_INQ_PARMS *p_inqparms = &p_inq->inqparms;
1906
1907 #if (BTM_INQ_DEBUG == TRUE)
1908 BTM_TRACE_DEBUG3 ("btm_initiate_inquiry: inq_active:0x%x state:%d inqfilt_active:%d",
1909 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
1910 #endif
1911 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
1912 btm_acl_update_busy_level (BTM_BLI_INQ_EVT);
1913 #endif
1914
1915 if (p_inq->inq_active & BTM_SSP_INQUIRY_ACTIVE)
1916 {
1917 btm_process_inq_complete (BTM_NO_RESOURCES, (UINT8)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
1918 return;
1919 }
1920
1921 /* Make sure the number of responses doesn't overflow the database configuration */
1922 p_inqparms->max_resps = (UINT8)((p_inqparms->max_resps <= BTM_INQ_DB_SIZE) ? p_inqparms->max_resps : BTM_INQ_DB_SIZE);
1923
1924 lap = (p_inq->inq_active & BTM_LIMITED_INQUIRY_ACTIVE) ? &limited_inq_lap : &general_inq_lap;
1925
1926 if (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)
1927 {
1928 if (!btsnd_hcic_per_inq_mode (p_inq->per_max_delay,
1929 p_inq->per_min_delay,
1930 *lap, p_inqparms->duration,
1931 p_inqparms->max_resps))
1932 btm_process_inq_complete (BTM_NO_RESOURCES, (UINT8)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
1933 }
1934 else
1935 {
1936 #if BTM_USE_INQ_RESULTS_FILTER == TRUE
1937 btm_clr_inq_result_flt();
1938
1939 /* Allocate memory to hold bd_addrs responding */
1940 if ((p_inq->p_bd_db = (tINQ_BDADDR *)GKI_getbuf(GKI_MAX_BUF_SIZE)) != NULL)
1941 {
1942 p_inq->max_bd_entries = (UINT16)(GKI_MAX_BUF_SIZE / sizeof(tINQ_BDADDR));
1943 memset(p_inq->p_bd_db, 0, GKI_MAX_BUF_SIZE);
1944 /* BTM_TRACE_DEBUG1("btm_initiate_inquiry: memory allocated for %d bdaddrs",
1945 p_inq->max_bd_entries); */
1946 }
1947
1948 if (!btsnd_hcic_inquiry(*lap, p_inqparms->duration, 0))
1949 #else
1950 if (!btsnd_hcic_inquiry(*lap, p_inqparms->duration, p_inqparms->max_resps))
1951 #endif /* BTM_USE_INQ_RESULTS_FILTER */
1952 btm_process_inq_complete (BTM_NO_RESOURCES, (UINT8)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
1953 }
1954 }
1955
1956 /*******************************************************************************
1957 **
1958 ** Function btm_process_inq_results
1959 **
1960 ** Description This function is called when inquiry results are received from
1961 ** the device. It updates the inquiry database. If the inquiry
1962 ** database is full, the oldest entry is discarded.
1963 **
1964 ** Parameters inq_res_mode - BTM_INQ_RESULT_STANDARD
1965 ** BTM_INQ_RESULT_WITH_RSSI
1966 ** BTM_INQ_RESULT_EXTENDED
1967 **
1968 ** Returns void
1969 **
1970 *******************************************************************************/
btm_process_inq_results(UINT8 * p,UINT8 inq_res_mode)1971 void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
1972 {
1973 UINT8 num_resp, xx;
1974 BD_ADDR bda;
1975 tINQ_DB_ENT *p_i;
1976 tBTM_INQ_RESULTS *p_cur=NULL;
1977 BOOLEAN is_new = TRUE;
1978 BOOLEAN update = FALSE;
1979 INT8 i_rssi;
1980 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1981 tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb;
1982 UINT8 page_scan_rep_mode = 0;
1983 UINT8 page_scan_per_mode = 0;
1984 UINT8 page_scan_mode = 0;
1985 UINT8 rssi = 0;
1986 DEV_CLASS dc;
1987 UINT16 clock_offset;
1988 #if (BTM_EIR_CLIENT_INCLUDED == TRUE)
1989 UINT8 *p_eir_data = NULL;
1990 #if (BTM_INQ_GET_REMOTE_NAME==TRUE)
1991 UINT8 remote_name_len;
1992 #endif
1993 #endif
1994
1995 #if (BTM_INQ_DEBUG == TRUE)
1996 BTM_TRACE_DEBUG3 ("btm_process_inq_results inq_active:0x%x state:%d inqfilt_active:%d",
1997 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
1998 #endif
1999 /* Only process the results if the BR inquiry is still active */
2000 if (!(p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK))
2001 return;
2002
2003 STREAM_TO_UINT8 (num_resp, p);
2004
2005 for (xx = 0; xx < num_resp; xx++)
2006 {
2007 update = FALSE;
2008 /* Extract inquiry results */
2009 STREAM_TO_BDADDR (bda, p);
2010 STREAM_TO_UINT8 (page_scan_rep_mode, p);
2011 STREAM_TO_UINT8 (page_scan_per_mode, p);
2012
2013 if (inq_res_mode == BTM_INQ_RESULT_STANDARD)
2014 {
2015 STREAM_TO_UINT8(page_scan_mode, p);
2016 }
2017
2018 STREAM_TO_DEVCLASS (dc, p);
2019 STREAM_TO_UINT16 (clock_offset, p);
2020 if (inq_res_mode != BTM_INQ_RESULT_STANDARD)
2021 {
2022 STREAM_TO_UINT8(rssi, p);
2023 }
2024
2025 p_i = btm_inq_db_find (bda);
2026
2027 #if BTM_USE_INQ_RESULTS_FILTER == TRUE
2028 /* Only process the num_resp is smaller than max_resps.
2029 If results are queued to BTU task while canceling inquiry,
2030 or when more than one result is in this response, > max_resp
2031 responses could be processed which can confuse some apps
2032 */
2033 if (p_inq->inqparms.max_resps &&
2034 p_inq->inq_cmpl_info.num_resp >= p_inq->inqparms.max_resps
2035 #if BLE_INCLUDED == TRUE
2036 /* new device response */
2037 && ( p_i == NULL ||
2038 /* exisiting device with BR/EDR info */
2039 (p_i && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)
2040 )
2041 #endif
2042
2043 )
2044 {
2045 /* BTM_TRACE_WARNING0("INQ RES: Extra Response Received...ignoring"); */
2046 return;
2047 }
2048 #endif
2049
2050 /* Check if this address has already been processed for this inquiry */
2051 if (btm_inq_find_bdaddr(bda))
2052 {
2053 /* BTM_TRACE_DEBUG6("BDA seen before [%02x%02x %02x%02x %02x%02x]",
2054 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);*/
2055 /* By default suppose no update needed */
2056 i_rssi = (INT8)rssi;
2057
2058 /* If this new RSSI is higher than the last one */
2059 if(p_inq->inqparms.report_dup && (rssi != 0) &&
2060 p_i && (i_rssi > p_i->inq_info.results.rssi || p_i->inq_info.results.rssi == 0
2061 #if BLE_INCLUDED == TRUE
2062 /* BR/EDR inquiry information update */
2063 || (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0
2064 #endif
2065 ))
2066 {
2067 p_cur = &p_i->inq_info.results;
2068 BTM_TRACE_DEBUG2("update RSSI new:%d, old:%d", i_rssi, p_cur->rssi);
2069 p_cur->rssi = i_rssi;
2070 update = TRUE;
2071 }
2072 /* If we received a second Extended Inq Event for an already */
2073 /* discovered device, this is because for the first one EIR was not received */
2074 else if ((inq_res_mode == BTM_INQ_RESULT_EXTENDED) && (p_i))
2075 {
2076 p_cur = &p_i->inq_info.results;
2077 update = TRUE;
2078 }
2079 /* If no update needed continue with next response (if any) */
2080 else
2081 continue;
2082 }
2083
2084 /* Host can be registered to verify comming BDA or DC */
2085 if (btm_cb.p_inq_filter_cb)
2086 {
2087 if (!(* btm_cb.p_inq_filter_cb) (bda, dc))
2088 {
2089 continue;
2090 }
2091 }
2092
2093 /* If existing entry, use that, else get a new one (possibly reusing the oldest) */
2094 if (p_i == NULL)
2095 {
2096 p_i = btm_inq_db_new (bda);
2097 is_new = TRUE;
2098 }
2099
2100 /* If an entry for the device already exists, overwrite it ONLY if it is from
2101 a previous inquiry. (Ignore it if it is a duplicate response from the same
2102 inquiry.
2103 */
2104 else if (p_i->inq_count == p_inq->inq_counter
2105 #if (BLE_INCLUDED == TRUE )
2106 && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR)
2107 #endif
2108 )
2109 is_new = FALSE;
2110
2111 /* keep updating RSSI to have latest value */
2112 if( inq_res_mode != BTM_INQ_RESULT_STANDARD )
2113 p_i->inq_info.results.rssi = (INT8)rssi;
2114 else
2115 p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI;
2116
2117 if (is_new == TRUE)
2118 {
2119 /* Save the info */
2120 p_cur = &p_i->inq_info.results;
2121 p_cur->page_scan_rep_mode = page_scan_rep_mode;
2122 p_cur->page_scan_per_mode = page_scan_per_mode;
2123 p_cur->page_scan_mode = page_scan_mode;
2124 p_cur->dev_class[0] = dc[0];
2125 p_cur->dev_class[1] = dc[1];
2126 p_cur->dev_class[2] = dc[2];
2127 p_cur->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
2128
2129 p_i->time_of_resp = GKI_get_tick_count ();
2130
2131 if (p_i->inq_count != p_inq->inq_counter)
2132 p_inq->inq_cmpl_info.num_resp++; /* A new response was found */
2133
2134 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
2135 p_cur->inq_result_type = BTM_INQ_RESULT_BR;
2136 if (p_i->inq_count != p_inq->inq_counter)
2137 {
2138 p_cur->device_type = BT_DEVICE_TYPE_BREDR;
2139 p_i->scan_rsp = FALSE;
2140 }
2141 else
2142 p_cur->device_type |= BT_DEVICE_TYPE_BREDR;
2143 #endif
2144 p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */
2145
2146 #if BTM_USE_INQ_RESULTS_FILTER == TRUE
2147 /* If the number of responses found and not unlimited, issue a cancel inquiry */
2148 if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) &&
2149 p_inq->inqparms.max_resps &&
2150 p_inq->inq_cmpl_info.num_resp == p_inq->inqparms.max_resps
2151 #if BLE_INCLUDED == TRUE
2152 /* BLE scanning is active and received adv */
2153 && ((((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) &&
2154 p_cur->device_type == BT_DEVICE_TYPE_DUMO && p_i->scan_rsp) ||
2155 (p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) == 0)
2156 #endif
2157 )
2158 {
2159 /* BTM_TRACE_DEBUG0("BTMINQ: Found devices, cancelling inquiry..."); */
2160 btsnd_hcic_inq_cancel();
2161
2162 #if BLE_INCLUDED == TRUE
2163 if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
2164 btm_ble_stop_scan();
2165 #endif
2166
2167
2168 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2169 btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
2170 #endif
2171 }
2172 #endif
2173 /* Initialize flag to FALSE. This flag is set/used by application */
2174 p_i->inq_info.appl_knows_rem_name = FALSE;
2175 }
2176
2177 if (is_new || update)
2178 {
2179 #if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2180 #if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2181 if( inq_res_mode == BTM_INQ_RESULT_EXTENDED )
2182 {
2183 if((p_eir_data = BTM_CheckEirData( p, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE,
2184 &remote_name_len )) == NULL)
2185 {
2186 p_eir_data = BTM_CheckEirData( p, BTM_EIR_SHORTENED_LOCAL_NAME_TYPE,
2187 &remote_name_len );
2188 }
2189
2190 if( p_eir_data )
2191 {
2192 if( remote_name_len > BTM_MAX_REM_BD_NAME_LEN )
2193 remote_name_len = BTM_MAX_REM_BD_NAME_LEN;
2194
2195 p_i->inq_info.remote_name_len = remote_name_len;
2196 memcpy( p_i->inq_info.remote_name, p_eir_data, p_i->inq_info.remote_name_len );
2197 p_i->inq_info.remote_name[p_i->inq_info.remote_name_len] = 0;
2198 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_DONE;
2199 }
2200 else
2201 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
2202 }
2203 else
2204 #endif
2205 {
2206 /* Clear out the device name so that it can be re-read */
2207 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
2208 }
2209 #endif /*(BTM_INQ_GET_REMOTE_NAME==TRUE)*/
2210
2211 #if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2212 if( inq_res_mode == BTM_INQ_RESULT_EXTENDED )
2213 {
2214 memset( p_cur->eir_uuid, 0,
2215 BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS/8));
2216 /* set bit map of UUID list from received EIR */
2217 btm_set_eir_uuid( p, p_cur );
2218 p_eir_data = p;
2219 }
2220 else
2221 p_eir_data = NULL;
2222 #endif
2223
2224 /* If a callback is registered, call it with the results */
2225 if (p_inq_results_cb)
2226 #if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2227 (p_inq_results_cb)((tBTM_INQ_RESULTS *) p_cur, p_eir_data);
2228 #else
2229 (p_inq_results_cb)((tBTM_INQ_RESULTS *) p_cur, NULL);
2230 #endif
2231
2232 /* If anyone is registered for change notifications, then tell him we added an entry. */
2233 if (p_inq->p_inq_change_cb)
2234 (*p_inq->p_inq_change_cb) (&p_i->inq_info, TRUE);
2235 }
2236 }
2237 }
2238
2239 /*******************************************************************************
2240 **
2241 ** Function btm_sort_inq_result
2242 **
2243 ** Description This function is called when inquiry complete is received
2244 ** from the device to sort inquiry results based on rssi.
2245 **
2246 ** Returns void
2247 **
2248 *******************************************************************************/
btm_sort_inq_result(void)2249 void btm_sort_inq_result(void)
2250 {
2251 UINT8 xx, yy, num_resp;
2252 tINQ_DB_ENT *p_tmp = NULL;
2253 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
2254 tINQ_DB_ENT *p_next = btm_cb.btm_inq_vars.inq_db+1;
2255 int size;
2256
2257 num_resp = (btm_cb.btm_inq_vars.inq_cmpl_info.num_resp<BTM_INQ_DB_SIZE)?
2258 btm_cb.btm_inq_vars.inq_cmpl_info.num_resp: BTM_INQ_DB_SIZE;
2259
2260 if((p_tmp = (tINQ_DB_ENT *)GKI_getbuf(sizeof(tINQ_DB_ENT))) != NULL)
2261 {
2262 size = sizeof(tINQ_DB_ENT);
2263 for(xx = 0; xx < num_resp-1; xx++, p_ent++)
2264 {
2265 for(yy = xx+1, p_next = p_ent+1; yy < num_resp; yy++, p_next++)
2266 {
2267 if(p_ent->inq_info.results.rssi < p_next->inq_info.results.rssi)
2268 {
2269 memcpy (p_tmp, p_next, size);
2270 memcpy (p_next, p_ent, size);
2271 memcpy (p_ent, p_tmp, size);
2272 }
2273 }
2274 }
2275
2276 GKI_freebuf(p_tmp);
2277 }
2278 }
2279
2280 /*******************************************************************************
2281 **
2282 ** Function btm_process_inq_complete
2283 **
2284 ** Description This function is called when inquiry complete is received
2285 ** from the device. Call the callback if not in periodic inquiry
2286 ** mode AND it is not NULL (The caller wants the event).
2287 **
2288 ** The callback pass back the status and the number of responses
2289 **
2290 ** Returns void
2291 **
2292 *******************************************************************************/
btm_process_inq_complete(UINT8 status,UINT8 mode)2293 void btm_process_inq_complete (UINT8 status, UINT8 mode)
2294 {
2295 tBTM_CMPL_CB *p_inq_cb = btm_cb.btm_inq_vars.p_inq_cmpl_cb;
2296 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2297
2298 #if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2299 tBTM_INQ_INFO *p_cur;
2300 UINT8 tempstate;
2301 #endif
2302
2303 p_inq->inqparms.mode &= ~(mode);
2304
2305 #if (BTM_INQ_DEBUG == TRUE)
2306 BTM_TRACE_DEBUG3 ("btm_process_inq_complete inq_active:0x%x state:%d inqfilt_active:%d",
2307 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
2308 #endif
2309 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2310 btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
2311 #endif
2312 /* Ignore any stray or late complete messages if the inquiry is not active */
2313 if (p_inq->inq_active)
2314 {
2315 p_inq->inq_cmpl_info.status = (tBTM_STATUS)((status == HCI_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING);
2316
2317 #if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2318 if (p_inq->inq_cmpl_info.status == BTM_SUCCESS)
2319 {
2320 for (p_cur = BTM_InqDbFirst(); p_cur; p_cur = BTM_InqDbNext (p_cur))
2321 {
2322 if (p_cur->remote_name_state == BTM_INQ_RMT_NAME_EMPTY)
2323 {
2324 tempstate = p_cur->remote_name_state;
2325 p_cur->remote_name_state = BTM_INQ_RMT_NAME_PENDING;
2326
2327 if (btm_initiate_rem_name (p_cur->results.remote_bd_addr,
2328 p_cur, BTM_RMT_NAME_INQ,
2329 BTM_INQ_RMT_NAME_TIMEOUT, NULL) != BTM_CMD_STARTED)
2330 p_cur->remote_name_state = tempstate;
2331 else
2332 return;
2333 }
2334 }
2335 }
2336 #endif
2337
2338 /* Notify caller that the inquiry has completed; (periodic inquiries do not send completion events */
2339 if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) && p_inq->inqparms.mode == 0)
2340 {
2341 p_inq->state = BTM_INQ_INACTIVE_STATE;
2342
2343 /* Increment so the start of a next inquiry has a new count */
2344 p_inq->inq_counter++;
2345
2346 btm_clr_inq_result_flt();
2347
2348 if((p_inq->inq_cmpl_info.status == BTM_SUCCESS) &&
2349 HCI_LMP_INQ_RSSI_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
2350 {
2351 btm_sort_inq_result();
2352 }
2353
2354 /* Clear the results callback if set */
2355 p_inq->p_inq_results_cb = (tBTM_INQ_RESULTS_CB *) NULL;
2356 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
2357 p_inq->p_inq_cmpl_cb = (tBTM_CMPL_CB *) NULL;
2358
2359 /* If we have a callback registered for inquiry complete, call it */
2360 BTM_TRACE_DEBUG2 ("BTM Inq Compl Callback: status 0x%02x, num results %d",
2361 p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp);
2362
2363 if (p_inq_cb)
2364 (p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info);
2365 }
2366
2367 }
2368 #if (BTM_INQ_DEBUG == TRUE)
2369 BTM_TRACE_DEBUG3 ("inq_active:0x%x state:%d inqfilt_active:%d",
2370 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
2371 #endif
2372 }
2373
2374 /*******************************************************************************
2375 **
2376 ** Function btm_process_cancel_complete
2377 **
2378 ** Description This function is called when inquiry cancel complete is received
2379 ** from the device.This function will also call the btm_process_inq_complete
2380 ** This function is needed to differentiate a cancel_cmpl_evt from the
2381 ** inq_cmpl_evt
2382 **
2383 ** Returns void
2384 **
2385 *******************************************************************************/
btm_process_cancel_complete(UINT8 status,UINT8 mode)2386 void btm_process_cancel_complete(UINT8 status, UINT8 mode)
2387 {
2388 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2389 btm_acl_update_busy_level (BTM_BLI_INQ_CANCEL_EVT);
2390 #endif
2391 btm_process_inq_complete(status, mode);
2392 }
2393 /*******************************************************************************
2394 **
2395 ** Function btm_initiate_rem_name
2396 **
2397 ** Description This function looks initiates a remote name request. It is called
2398 ** either by GAP or by the API call BTM_ReadRemoteDeviceName.
2399 **
2400 ** Input Params: p_cur - pointer to an inquiry result structure (NULL if nonexistent)
2401 ** p_cb - callback function called when BTM_CMD_STARTED
2402 ** is returned.
2403 ** A pointer to tBTM_REMOTE_DEV_NAME is passed to the
2404 ** callback.
2405 **
2406 ** Returns
2407 ** BTM_CMD_STARTED is returned if the request was sent to HCI.
2408 ** BTM_BUSY if already in progress
2409 ** BTM_NO_RESOURCES if could not allocate resources to start the command
2410 ** BTM_WRONG_MODE if the device is not up.
2411 **
2412 *******************************************************************************/
btm_initiate_rem_name(BD_ADDR remote_bda,tBTM_INQ_INFO * p_cur,UINT8 origin,UINT32 timeout,tBTM_CMPL_CB * p_cb)2413 tBTM_STATUS btm_initiate_rem_name (BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur,
2414 UINT8 origin, UINT32 timeout, tBTM_CMPL_CB *p_cb)
2415 {
2416 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2417 BOOLEAN cmd_ok;
2418
2419
2420 /*** Make sure the device is ready ***/
2421 if (!BTM_IsDeviceUp())
2422 return (BTM_WRONG_MODE);
2423
2424
2425 if (origin == BTM_RMT_NAME_SEC)
2426 {
2427 cmd_ok = btsnd_hcic_rmt_name_req (remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
2428 HCI_MANDATARY_PAGE_SCAN_MODE, 0);
2429 if (cmd_ok)
2430 return BTM_CMD_STARTED;
2431 else
2432 return BTM_NO_RESOURCES;
2433 }
2434 /* Make sure there are no two remote name requests from external API in progress */
2435 else if (origin == BTM_RMT_NAME_EXT)
2436 {
2437 if (p_inq->remname_active)
2438 {
2439 return (BTM_BUSY);
2440 }
2441 else
2442 {
2443 /* If there is no remote name request running,call the callback function and start timer */
2444 p_inq->p_remname_cmpl_cb = p_cb;
2445 memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
2446 btu_start_timer (&p_inq->rmt_name_timer_ent,
2447 BTU_TTYPE_BTM_RMT_NAME,
2448 timeout);
2449
2450 /* If the database entry exists for the device, use its clock offset */
2451 if (p_cur)
2452 {
2453 cmd_ok = btsnd_hcic_rmt_name_req (remote_bda,
2454 p_cur->results.page_scan_rep_mode,
2455 p_cur->results.page_scan_mode,
2456 (UINT16)(p_cur->results.clock_offset |
2457 BTM_CLOCK_OFFSET_VALID));
2458 }
2459 else /* Otherwise use defaults and mark the clock offset as invalid */
2460 {
2461 cmd_ok = btsnd_hcic_rmt_name_req (remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
2462 HCI_MANDATARY_PAGE_SCAN_MODE, 0);
2463 }
2464 if (cmd_ok)
2465 {
2466 p_inq->remname_active = TRUE;
2467 return BTM_CMD_STARTED;
2468 }
2469 else
2470 return BTM_NO_RESOURCES;
2471 }
2472 }
2473 /* If the inquire feature is on */
2474 #if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2475
2476 else if (origin == BTM_RMT_NAME_INQ)
2477 {
2478 /* If the database entry exists for the device, use its clock offset */
2479 if (p_cur)
2480 {
2481 cmd_ok = btsnd_hcic_rmt_name_req (remote_bda,
2482 p_cur->results.page_scan_rep_mode,
2483 p_cur->results.page_scan_mode,
2484 (UINT16)(p_cur->results.clock_offset |
2485 BTM_CLOCK_OFFSET_VALID));
2486 }
2487 else
2488 {
2489 cmd_ok = FALSE
2490 }
2491
2492 if (cmd_ok)
2493 return BTM_CMD_STARTED;
2494 else
2495 return BTM_NO_RESOURCES;
2496 }
2497 #endif
2498 else
2499 {
2500
2501 return BTM_ILLEGAL_VALUE;
2502
2503
2504 }
2505
2506
2507 }
2508
2509 /*******************************************************************************
2510 **
2511 ** Function btm_process_remote_name
2512 **
2513 ** Description This function is called when a remote name is received from
2514 ** the device. If remote names are cached, it updates the inquiry
2515 ** database.
2516 **
2517 ** Returns void
2518 **
2519 *******************************************************************************/
btm_process_remote_name(BD_ADDR bda,BD_NAME bdn,UINT16 evt_len,UINT8 hci_status)2520 void btm_process_remote_name (BD_ADDR bda, BD_NAME bdn, UINT16 evt_len, UINT8 hci_status)
2521 {
2522 tBTM_REMOTE_DEV_NAME rem_name;
2523 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2524 tBTM_CMPL_CB *p_cb = p_inq->p_remname_cmpl_cb;
2525 UINT8 *p_n1;
2526
2527 UINT16 temp_evt_len;
2528
2529 #if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2530 /*** These are only used if part of the Inquiry Process ***/
2531 tBTM_CMPL_CB *p_inq_cb;
2532 tINQ_DB_ENT *p_i = NULL;
2533 UINT8 *p_n;
2534 tBTM_INQ_INFO *p_cur;
2535 #endif
2536 #if BLE_INCLUDED == TRUE
2537 tBT_DEVICE_TYPE dev_type;
2538 tBLE_ADDR_TYPE addr_type;
2539 #endif
2540
2541
2542 if (bda != NULL)
2543 {
2544 BTM_TRACE_EVENT6("BDA %02x:%02x:%02x:%02x:%02x:%02x",bda[0], bda[1],
2545 bda[2], bda[3],
2546 bda[4], bda[5]);
2547 }
2548
2549 BTM_TRACE_EVENT6("Inquire BDA %02x:%02x:%02x:%02x:%02x:%02x",p_inq->remname_bda[0], p_inq->remname_bda[1],
2550 p_inq->remname_bda[2], p_inq->remname_bda[3],
2551 p_inq->remname_bda[4], p_inq->remname_bda[5]);
2552
2553
2554
2555 /* If the inquire BDA and remote DBA are the same, then stop the timer and set the active to false */
2556 if ((p_inq->remname_active ==TRUE)&&
2557 (((bda != NULL) &&
2558 (memcmp(bda, p_inq->remname_bda,BD_ADDR_LEN)==0)) || bda == NULL))
2559
2560 {
2561 #if BLE_INCLUDED == TRUE
2562 BTM_ReadDevInfo(p_inq->remname_bda, &dev_type, &addr_type);
2563 if (dev_type == BT_DEVICE_TYPE_BLE)
2564 {
2565 if (hci_status == HCI_ERR_UNSPECIFIED)
2566 btm_ble_cancel_remote_name(p_inq->remname_bda);
2567 }
2568 #endif
2569 btu_stop_timer (&p_inq->rmt_name_timer_ent);
2570 p_inq->remname_active = FALSE;
2571 /* Clean up and return the status if the command was not successful */
2572 /* Note: If part of the inquiry, the name is not stored, and the */
2573 /* inquiry complete callback is called. */
2574
2575 if ((hci_status == HCI_SUCCESS))
2576 {
2577 /* Copy the name from the data stream into the return structure */
2578 /* Note that even if it is not being returned, it is used as a */
2579 /* temporary buffer. */
2580 p_n1 = (UINT8 *)rem_name.remote_bd_name;
2581 rem_name.length = (evt_len < BD_NAME_LEN) ? evt_len : BD_NAME_LEN;
2582 rem_name.remote_bd_name[rem_name.length] = 0;
2583 rem_name.status = BTM_SUCCESS;
2584 temp_evt_len = rem_name.length;
2585
2586 while (temp_evt_len > 0)
2587 {
2588 *p_n1++ = *bdn++;
2589 temp_evt_len--;
2590 }
2591 rem_name.remote_bd_name[rem_name.length] = 0;
2592 }
2593
2594
2595 /* If processing a stand alone remote name then report the error in the callback */
2596 else
2597 {
2598 rem_name.status = BTM_BAD_VALUE_RET;
2599 rem_name.length = 0;
2600 rem_name.remote_bd_name[0] = 0;
2601 }
2602 /* Reset the remote BAD to zero and call callback if possible */
2603 memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
2604
2605 p_inq->p_remname_cmpl_cb = NULL;
2606 if (p_cb)
2607 (p_cb)((tBTM_REMOTE_DEV_NAME *)&rem_name);
2608 }
2609
2610
2611 #if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2612 /* If existing entry, update the name */
2613 if ((bda != NULL) && ((p_i = btm_inq_db_find (bda)) != NULL)
2614 && (hci_status == HCI_SUCCESS))
2615 {
2616 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_DONE;
2617 p_n = p_i->inq_info.remote_name;
2618 memset(p_n, 0, BTM_MAX_REM_BD_NAME_LEN + 1);
2619 p_i->inq_info.remote_name_len = (rem_name.length < BTM_MAX_REM_BD_NAME_LEN) ?
2620 rem_name.length : BTM_MAX_REM_BD_NAME_LEN;
2621 evt_len = p_i->inq_info.remote_name_len;
2622 p_n1 = (UINT8 *)rem_name.remote_bd_name;
2623 while (evt_len > 0)
2624 {
2625 *p_n++ = *p_n1++;
2626 evt_len--;
2627 }
2628
2629 if (btm_cb.btm_inq_vars.p_inq_change_cb)
2630 (*btm_cb.btm_inq_vars.p_inq_change_cb) (&p_i->inq_info, TRUE);
2631 }
2632 else
2633 {
2634 if (p_i)
2635 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_FAILED;
2636 else
2637 {
2638 /* Find the entry which is currently doing name request */
2639 for (p_cur = BTM_InqDbFirst(); p_cur; p_cur = BTM_InqDbNext (p_cur))
2640 {
2641 if (p_cur->remote_name_state == BTM_INQ_RMT_NAME_PENDING)
2642 {
2643 /* Should be only one */
2644 p_cur->remote_name_state = BTM_INQ_RMT_NAME_FAILED;
2645 break;
2646 }
2647 }
2648 }
2649 }
2650
2651 /* If an inquiry is in progress then update other entries */
2652 if (p_inq->inq_active)
2653 {
2654 /* Check if there are any more entries inquired but not named */
2655 for (p_cur = BTM_InqDbFirst(); p_cur; p_cur = BTM_InqDbNext (p_cur))
2656 {
2657 if (p_cur->remote_name_state == BTM_INQ_RMT_NAME_EMPTY)
2658 {
2659 p_cur->remote_name_state = BTM_INQ_RMT_NAME_PENDING;
2660 #if (BLE_INCLUDED == TRUE)
2661 BTM_ReadDevInfo(remote_bda, &dev_type, &addr_type);
2662 if (dev_type == BT_DEVICE_TYPE_BLE)
2663 {
2664 if (btm_ble_read_remote_name(remote_bda, p_cur, p_cb) != BTM_CMD_STARTED)
2665 p_cur->remote_name_state = BTM_INQ_RMT_NAME_FAILED;
2666 else
2667 return;
2668 }
2669 else
2670 #endif
2671 {
2672 if (btm_initiate_rem_name (p_cur->results.remote_bd_addr,
2673 p_cur, BTM_RMT_NAME_INQ,
2674 BTM_INQ_RMT_NAME_TIMEOUT, NULL) != BTM_CMD_STARTED)
2675 p_cur->remote_name_state = BTM_INQ_RMT_NAME_FAILED;
2676 else
2677 return;
2678 }
2679 }
2680 }
2681
2682 /* The inquiry has finished so call the callback for the inquiry */
2683 p_inq_cb = p_inq->p_inq_cmpl_cb;
2684 p_inq->state = BTM_INQ_INACTIVE_STATE;
2685 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
2686 p_inq->p_inq_cmpl_cb = NULL;
2687
2688 /* If we have a callback registered for inquiry complete, call it */
2689 if (p_inq_cb)
2690 (p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info);
2691
2692 /* In some cases we can not get name of the device once but will be */
2693 /* able to do it next time. Until we have better solution we will */
2694 /* try to get name every time */
2695 for (p_cur = BTM_InqDbFirst(); p_cur; p_cur = BTM_InqDbNext (p_cur))
2696 {
2697 if (p_cur->remote_name_state == BTM_INQ_RMT_NAME_FAILED)
2698 p_cur->remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
2699 }
2700 }
2701 #endif /* BTM_INQ_GET_REMOTE_NAME == TRUE */
2702 }
2703
2704 /*******************************************************************************
2705 **
2706 ** Function btm_inq_rmt_name_failed
2707 **
2708 ** Description This function is if timeout expires while getting remote
2709 ** name. This is done for devices that incorrectly do not
2710 ** report operation failure
2711 **
2712 ** Returns void
2713 **
2714 *******************************************************************************/
btm_inq_rmt_name_failed(void)2715 void btm_inq_rmt_name_failed (void)
2716 {
2717 BTM_TRACE_ERROR1 ("btm_inq_rmt_name_failed() remname_active=%d", btm_cb.btm_inq_vars.remname_active);
2718
2719 if (btm_cb.btm_inq_vars.remname_active)
2720 btm_process_remote_name (btm_cb.btm_inq_vars.remname_bda, NULL, 0, HCI_ERR_UNSPECIFIED);
2721 else
2722 btm_process_remote_name (NULL, NULL, 0, HCI_ERR_UNSPECIFIED);
2723
2724 btm_sec_rmt_name_request_complete (NULL, NULL, HCI_ERR_UNSPECIFIED);
2725 }
2726 /*******************************************************************************
2727 **
2728 ** Function btm_read_linq_tx_power_complete
2729 **
2730 ** Description read inquiry tx power level complete callback function.
2731 **
2732 ** Returns void
2733 **
2734 *******************************************************************************/
btm_read_linq_tx_power_complete(UINT8 * p)2735 void btm_read_linq_tx_power_complete(UINT8 *p)
2736 {
2737 tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_txpwer_cmpl_cb;
2738 tBTM_INQ_TXPWR_RESULTS results;
2739
2740 btu_stop_timer (&btm_cb.devcb.txpwer_timer);
2741 /* If there was a callback registered for read inq tx power, call it */
2742 btm_cb.devcb.p_txpwer_cmpl_cb = NULL;
2743
2744 if (p_cb)
2745 {
2746 STREAM_TO_UINT8 (results.hci_status, p);
2747
2748 if (results.hci_status == HCI_SUCCESS)
2749 {
2750 results.status = BTM_SUCCESS;
2751
2752 STREAM_TO_UINT8 (results.tx_power, p);
2753 BTM_TRACE_EVENT2 ("BTM INQ TX POWER Complete: tx_power %d, hci status 0x%02x",
2754 results.tx_power, results.hci_status);
2755 }
2756 else
2757 results.status = BTM_ERR_PROCESSING;
2758
2759 (*p_cb)(&results);
2760 }
2761
2762 }
2763 /*******************************************************************************
2764 **
2765 ** Function BTM_WriteEIR
2766 **
2767 ** Description This function is called to write EIR data to controller.
2768 **
2769 ** Parameters p_buff - allocated HCI command buffer including extended
2770 ** inquriry response
2771 **
2772 ** Returns BTM_SUCCESS - if successful
2773 ** BTM_MODE_UNSUPPORTED - if local device cannot support it
2774 **
2775 *******************************************************************************/
BTM_WriteEIR(BT_HDR * p_buff)2776 tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff )
2777 {
2778 #if (BTM_EIR_SERVER_INCLUDED == TRUE)
2779 if (HCI_EXT_INQ_RSP_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
2780 {
2781 BTM_TRACE_API0("Write Extended Inquiry Response to controller");
2782 btsnd_hcic_write_ext_inquiry_response (p_buff, BTM_EIR_DEFAULT_FEC_REQUIRED);
2783 return BTM_SUCCESS;
2784 }
2785 else
2786 {
2787 GKI_freebuf(p_buff);
2788 return BTM_MODE_UNSUPPORTED;
2789 }
2790 #else
2791 GKI_freebuf(p_buff);
2792 return BTM_SUCCESS;
2793 #endif
2794 }
2795
2796 /*******************************************************************************
2797 **
2798 ** Function BTM_CheckEirData
2799 **
2800 ** Description This function is called to get EIR data from significant part.
2801 **
2802 ** Parameters p_eir - pointer of EIR significant part
2803 ** type - finding EIR data type
2804 ** p_length - return the length of EIR data not including type
2805 **
2806 ** Returns pointer of EIR data
2807 **
2808 *******************************************************************************/
BTM_CheckEirData(UINT8 * p_eir,UINT8 type,UINT8 * p_length)2809 UINT8 *BTM_CheckEirData( UINT8 *p_eir, UINT8 type, UINT8 *p_length )
2810 {
2811 #if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2812 UINT8 *p = p_eir;
2813 UINT8 length;
2814 UINT8 eir_type;
2815 BTM_TRACE_API1("BTM_CheckEirData type=0x%02X", type);
2816
2817 STREAM_TO_UINT8(length, p);
2818 while( length && (p - p_eir <= HCI_EXT_INQ_RESPONSE_LEN))
2819 {
2820 STREAM_TO_UINT8(eir_type, p);
2821 if( eir_type == type )
2822 {
2823 /* length doesn't include itself */
2824 *p_length = length - 1; /* minus the length of type */
2825 return p;
2826 }
2827 p += length - 1; /* skip the length of data */
2828 STREAM_TO_UINT8(length, p);
2829 }
2830
2831 *p_length = 0;
2832 return NULL;
2833 #else
2834 return NULL;
2835 #endif
2836 }
2837
2838 /*******************************************************************************
2839 **
2840 ** Function btm_convert_uuid_to_eir_service
2841 **
2842 ** Description This function is called to get the bit position of UUID.
2843 **
2844 ** Parameters uuid16 - UUID 16-bit
2845 **
2846 ** Returns BTM EIR service ID if found
2847 ** BTM_EIR_MAX_SERVICES - if not found
2848 **
2849 *******************************************************************************/
2850 #if (( BTM_EIR_CLIENT_INCLUDED == TRUE )||( BTM_EIR_SERVER_INCLUDED == TRUE ))
btm_convert_uuid_to_eir_service(UINT16 uuid16)2851 static UINT8 btm_convert_uuid_to_eir_service( UINT16 uuid16 )
2852 {
2853 UINT8 xx;
2854
2855 for( xx = 0; xx < BTM_EIR_MAX_SERVICES; xx++ )
2856 {
2857 if( uuid16 == BTM_EIR_UUID_LKUP_TBL[xx])
2858 {
2859 return xx;
2860 }
2861 }
2862 return BTM_EIR_MAX_SERVICES;
2863 }
2864 #endif
2865
2866 /*******************************************************************************
2867 **
2868 ** Function BTM_HasEirService
2869 **
2870 ** Description This function is called to know if UUID in bit map of UUID.
2871 **
2872 ** Parameters p_eir_uuid - bit map of UUID list
2873 ** uuid16 - UUID 16-bit
2874 **
2875 ** Returns TRUE - if found
2876 ** FALSE - if not found
2877 **
2878 *******************************************************************************/
BTM_HasEirService(UINT32 * p_eir_uuid,UINT16 uuid16)2879 BOOLEAN BTM_HasEirService( UINT32 *p_eir_uuid, UINT16 uuid16 )
2880 {
2881 #if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
2882 UINT8 service_id;
2883
2884 service_id = btm_convert_uuid_to_eir_service(uuid16);
2885 if( service_id < BTM_EIR_MAX_SERVICES )
2886 return( BTM_EIR_HAS_SERVICE( p_eir_uuid, service_id ));
2887 else
2888 return( FALSE );
2889 #else
2890 return( FALSE );
2891 #endif
2892 }
2893
2894 /*******************************************************************************
2895 **
2896 ** Function BTM_HasInquiryEirService
2897 **
2898 ** Description This function is called to know if UUID in bit map of UUID list.
2899 **
2900 ** Parameters p_results - inquiry results
2901 ** uuid16 - UUID 16-bit
2902 **
2903 ** Returns BTM_EIR_FOUND - if found
2904 ** BTM_EIR_NOT_FOUND - if not found and it is complete list
2905 ** BTM_EIR_UNKNOWN - if not found and it is not complete list
2906 **
2907 *******************************************************************************/
BTM_HasInquiryEirService(tBTM_INQ_RESULTS * p_results,UINT16 uuid16)2908 tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService( tBTM_INQ_RESULTS *p_results, UINT16 uuid16 )
2909 {
2910 #if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
2911 if( BTM_HasEirService( p_results->eir_uuid, uuid16 ))
2912 {
2913 return BTM_EIR_FOUND;
2914 }
2915 else if( p_results->eir_complete_list )
2916 {
2917 return BTM_EIR_NOT_FOUND;
2918 }
2919 else
2920 return BTM_EIR_UNKNOWN;
2921 #else
2922 return BTM_EIR_UNKNOWN;
2923 #endif
2924 }
2925
2926 /*******************************************************************************
2927 **
2928 ** Function BTM_AddEirService
2929 **
2930 ** Description This function is called to add a service in bit map of UUID list.
2931 **
2932 ** Parameters p_eir_uuid - bit mask of UUID list for EIR
2933 ** uuid16 - UUID 16-bit
2934 **
2935 ** Returns None
2936 **
2937 *******************************************************************************/
BTM_AddEirService(UINT32 * p_eir_uuid,UINT16 uuid16)2938 void BTM_AddEirService( UINT32 *p_eir_uuid, UINT16 uuid16 )
2939 {
2940 #if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
2941 UINT8 service_id;
2942
2943 service_id = btm_convert_uuid_to_eir_service(uuid16);
2944 if( service_id < BTM_EIR_MAX_SERVICES )
2945 BTM_EIR_SET_SERVICE( p_eir_uuid, service_id );
2946 #endif
2947 }
2948
2949 /*******************************************************************************
2950 **
2951 ** Function BTM_RemoveEirService
2952 **
2953 ** Description This function is called to remove a service in bit map of UUID list.
2954 **
2955 ** Parameters p_eir_uuid - bit mask of UUID list for EIR
2956 ** uuid16 - UUID 16-bit
2957 **
2958 ** Returns None
2959 **
2960 *******************************************************************************/
BTM_RemoveEirService(UINT32 * p_eir_uuid,UINT16 uuid16)2961 void BTM_RemoveEirService( UINT32 *p_eir_uuid, UINT16 uuid16 )
2962 {
2963 #if (BTM_EIR_SERVER_INCLUDED == TRUE)
2964 UINT8 service_id;
2965
2966 service_id = btm_convert_uuid_to_eir_service(uuid16);
2967 if( service_id < BTM_EIR_MAX_SERVICES )
2968 BTM_EIR_CLR_SERVICE( p_eir_uuid, service_id );
2969 #endif
2970 }
2971
2972 /*******************************************************************************
2973 **
2974 ** Function BTM_GetEirSupportedServices
2975 **
2976 ** Description This function is called to get UUID list from bit map of UUID list.
2977 **
2978 ** Parameters p_eir_uuid - bit mask of UUID list for EIR
2979 ** p - reference of current pointer of EIR
2980 ** max_num_uuid16 - max number of UUID can be written in EIR
2981 ** num_uuid16 - number of UUID have been written in EIR
2982 **
2983 ** Returns BTM_EIR_MORE_16BITS_UUID_TYPE, if it has more than max
2984 ** BTM_EIR_COMPLETE_16BITS_UUID_TYPE, otherwise
2985 **
2986 *******************************************************************************/
BTM_GetEirSupportedServices(UINT32 * p_eir_uuid,UINT8 ** p,UINT8 max_num_uuid16,UINT8 * p_num_uuid16)2987 UINT8 BTM_GetEirSupportedServices( UINT32 *p_eir_uuid, UINT8 **p,
2988 UINT8 max_num_uuid16, UINT8 *p_num_uuid16)
2989 {
2990 #if (BTM_EIR_SERVER_INCLUDED == TRUE)
2991 UINT8 service_index;
2992
2993 *p_num_uuid16 = 0;
2994
2995 for(service_index = 0; service_index < BTM_EIR_MAX_SERVICES; service_index++)
2996 {
2997 if( BTM_EIR_HAS_SERVICE( p_eir_uuid, service_index ))
2998 {
2999 if( *p_num_uuid16 < max_num_uuid16 )
3000 {
3001 UINT16_TO_STREAM(*p, BTM_EIR_UUID_LKUP_TBL[service_index]);
3002 (*p_num_uuid16)++;
3003 }
3004 /* if max number of UUIDs are stored and found one more */
3005 else
3006 {
3007 return BTM_EIR_MORE_16BITS_UUID_TYPE;
3008 }
3009 }
3010 }
3011 return BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3012 #else
3013 return BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3014 #endif
3015 }
3016
3017 /*******************************************************************************
3018 **
3019 ** Function BTM_GetEirUuidList
3020 **
3021 ** Description This function parses EIR and returns UUID list.
3022 **
3023 ** Parameters p_eir - EIR
3024 ** uuid_size - LEN_UUID_16, LEN_UUID_32, LEN_UUID_128
3025 ** p_num_uuid - return number of UUID in found list
3026 ** p_uuid_list - return UUID list
3027 ** max_num_uuid - maximum number of UUID to be returned
3028 **
3029 ** Returns 0 - if not found
3030 ** BTM_EIR_COMPLETE_16BITS_UUID_TYPE
3031 ** BTM_EIR_MORE_16BITS_UUID_TYPE
3032 ** BTM_EIR_COMPLETE_32BITS_UUID_TYPE
3033 ** BTM_EIR_MORE_32BITS_UUID_TYPE
3034 ** BTM_EIR_COMPLETE_128BITS_UUID_TYPE
3035 ** BTM_EIR_MORE_128BITS_UUID_TYPE
3036 **
3037 *******************************************************************************/
BTM_GetEirUuidList(UINT8 * p_eir,UINT8 uuid_size,UINT8 * p_num_uuid,UINT8 * p_uuid_list,UINT8 max_num_uuid)3038 UINT8 BTM_GetEirUuidList( UINT8 *p_eir, UINT8 uuid_size, UINT8 *p_num_uuid,
3039 UINT8 *p_uuid_list, UINT8 max_num_uuid)
3040 {
3041 #if (BTM_EIR_CLIENT_INCLUDED == TRUE)
3042 UINT8 *p_uuid_data;
3043 UINT8 type;
3044 UINT8 yy, xx;
3045 UINT16 *p_uuid16 = (UINT16 *)p_uuid_list;
3046 UINT32 *p_uuid32 = (UINT32 *)p_uuid_list;
3047 char buff[LEN_UUID_128 * 2 + 1];
3048
3049 p_uuid_data = btm_eir_get_uuid_list( p_eir, uuid_size, p_num_uuid, &type );
3050 if( p_uuid_data == NULL )
3051 {
3052 return 0x00;
3053 }
3054
3055 if( *p_num_uuid > max_num_uuid )
3056 {
3057 BTM_TRACE_WARNING2("BTM_GetEirUuidList number of uuid in EIR = %d, size of uuid list = %d",
3058 *p_num_uuid, max_num_uuid );
3059 *p_num_uuid = max_num_uuid;
3060 }
3061
3062 BTM_TRACE_DEBUG2("BTM_GetEirUuidList type = %02X, number of uuid = %d", type, *p_num_uuid );
3063
3064 if( uuid_size == LEN_UUID_16 )
3065 {
3066 for( yy = 0; yy < *p_num_uuid; yy++ )
3067 {
3068 STREAM_TO_UINT16(*(p_uuid16 + yy), p_uuid_data);
3069 BTM_TRACE_DEBUG1(" 0x%04X", *(p_uuid16 + yy));
3070 }
3071 }
3072 else if( uuid_size == LEN_UUID_32 )
3073 {
3074 for( yy = 0; yy < *p_num_uuid; yy++ )
3075 {
3076 STREAM_TO_UINT32(*(p_uuid32 + yy), p_uuid_data);
3077 BTM_TRACE_DEBUG1(" 0x%08X", *(p_uuid32 + yy));
3078 }
3079 }
3080 else if( uuid_size == LEN_UUID_128 )
3081 {
3082 for( yy = 0; yy < *p_num_uuid; yy++ )
3083 {
3084 STREAM_TO_ARRAY16(p_uuid_list + yy * LEN_UUID_128, p_uuid_data);
3085 for( xx = 0; xx < LEN_UUID_128; xx++ )
3086 sprintf(buff + xx*2, "%02X", *(p_uuid_list + yy * LEN_UUID_128 + xx));
3087 BTM_TRACE_DEBUG1(" 0x%s", buff);
3088 }
3089 }
3090
3091 return type;
3092 #else
3093 *p_num_uuid = 0;
3094 return 0x00;
3095 #endif
3096 }
3097
3098
3099 #if (BTM_EIR_CLIENT_INCLUDED == TRUE)
3100 /*******************************************************************************
3101 **
3102 ** Function btm_eir_get_uuid_list
3103 **
3104 ** Description This function searches UUID list in EIR.
3105 **
3106 ** Parameters p_eir - address of EIR
3107 ** uuid_size - size of UUID to find
3108 ** p_num_uuid - number of UUIDs found
3109 ** p_uuid_list_type - EIR data type
3110 **
3111 ** Returns NULL - if UUID list with uuid_size is not found
3112 ** beginning of UUID list in EIR - otherwise
3113 **
3114 *******************************************************************************/
btm_eir_get_uuid_list(UINT8 * p_eir,UINT8 uuid_size,UINT8 * p_num_uuid,UINT8 * p_uuid_list_type)3115 static UINT8 *btm_eir_get_uuid_list( UINT8 *p_eir, UINT8 uuid_size,
3116 UINT8 *p_num_uuid, UINT8 *p_uuid_list_type )
3117 {
3118 UINT8 *p_uuid_data;
3119 UINT8 complete_type, more_type;
3120 UINT8 uuid_len;
3121
3122 switch( uuid_size )
3123 {
3124 case LEN_UUID_16:
3125 complete_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3126 more_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3127 break;
3128 case LEN_UUID_32:
3129 complete_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3130 more_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
3131 break;
3132 case LEN_UUID_128:
3133 complete_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3134 more_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
3135 break;
3136 default:
3137 *p_num_uuid = 0;
3138 return NULL;
3139 break;
3140 }
3141
3142 p_uuid_data = BTM_CheckEirData( p_eir, complete_type, &uuid_len );
3143 if(p_uuid_data == NULL)
3144 {
3145 p_uuid_data = BTM_CheckEirData( p_eir, more_type, &uuid_len );
3146 *p_uuid_list_type = more_type;
3147 }
3148 else
3149 {
3150 *p_uuid_list_type = complete_type;
3151 }
3152
3153 *p_num_uuid = uuid_len / uuid_size;
3154 return p_uuid_data;
3155 }
3156
3157 /*******************************************************************************
3158 **
3159 ** Function btm_convert_uuid_to_uuid16
3160 **
3161 ** Description This function converts UUID to UUID 16-bit.
3162 **
3163 ** Parameters p_uuid - address of UUID
3164 ** uuid_size - size of UUID
3165 **
3166 ** Returns 0 - if UUID cannot be converted to UUID 16-bit
3167 ** UUID 16-bit - otherwise
3168 **
3169 *******************************************************************************/
btm_convert_uuid_to_uuid16(UINT8 * p_uuid,UINT8 uuid_size)3170 static UINT16 btm_convert_uuid_to_uuid16( UINT8 *p_uuid, UINT8 uuid_size )
3171 {
3172 static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
3173 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3174 UINT16 uuid16 = 0;
3175 UINT32 uuid32;
3176 BOOLEAN is_base_uuid;
3177 UINT8 xx;
3178
3179 switch (uuid_size)
3180 {
3181 case LEN_UUID_16:
3182 STREAM_TO_UINT16 (uuid16, p_uuid);
3183 break;
3184 case LEN_UUID_32:
3185 STREAM_TO_UINT32 (uuid32, p_uuid);
3186 if (uuid32 < 0x10000)
3187 uuid16 = (UINT16) uuid32;
3188 break;
3189 case LEN_UUID_128:
3190 /* See if we can compress his UUID down to 16 or 32bit UUIDs */
3191 is_base_uuid = TRUE;
3192 for (xx = 0; xx < LEN_UUID_128 - 4; xx++)
3193 {
3194 if (p_uuid[xx] != base_uuid[xx])
3195 {
3196 is_base_uuid = FALSE;
3197 break;
3198 }
3199 }
3200 if (is_base_uuid)
3201 {
3202 if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0))
3203 {
3204 p_uuid += (LEN_UUID_128 - 4);
3205 STREAM_TO_UINT16(uuid16, p_uuid);
3206 }
3207 }
3208 break;
3209 default:
3210 BTM_TRACE_WARNING0("btm_convert_uuid_to_uuid16 invalid uuid size");
3211 break;
3212 }
3213
3214 return( uuid16);
3215 }
3216
3217 /*******************************************************************************
3218 **
3219 ** Function btm_set_eir_uuid
3220 **
3221 ** Description This function is called to store received UUID into inquiry result.
3222 **
3223 ** Parameters p_eir - pointer of EIR significant part
3224 ** p_results - pointer of inquiry result
3225 **
3226 ** Returns None
3227 **
3228 *******************************************************************************/
btm_set_eir_uuid(UINT8 * p_eir,tBTM_INQ_RESULTS * p_results)3229 void btm_set_eir_uuid( UINT8 *p_eir, tBTM_INQ_RESULTS *p_results )
3230 {
3231 UINT8 *p_uuid_data;
3232 UINT8 num_uuid;
3233 UINT16 uuid16;
3234 UINT8 yy;
3235 UINT8 type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3236
3237 p_uuid_data = btm_eir_get_uuid_list( p_eir, LEN_UUID_16, &num_uuid, &type );
3238
3239 if(type == BTM_EIR_COMPLETE_16BITS_UUID_TYPE)
3240 {
3241 p_results->eir_complete_list = TRUE;
3242 }
3243 else
3244 {
3245 p_results->eir_complete_list = FALSE;
3246 }
3247
3248 BTM_TRACE_API1("btm_set_eir_uuid eir_complete_list=0x%02X", p_results->eir_complete_list);
3249
3250 if( p_uuid_data )
3251 {
3252 for( yy = 0; yy < num_uuid; yy++ )
3253 {
3254 STREAM_TO_UINT16(uuid16, p_uuid_data);
3255 BTM_AddEirService( p_results->eir_uuid, uuid16 );
3256 }
3257 }
3258
3259 p_uuid_data = btm_eir_get_uuid_list( p_eir, LEN_UUID_32, &num_uuid, &type );
3260 if( p_uuid_data )
3261 {
3262 for( yy = 0; yy < num_uuid; yy++ )
3263 {
3264 uuid16 = btm_convert_uuid_to_uuid16( p_uuid_data, LEN_UUID_32 );
3265 p_uuid_data += LEN_UUID_32;
3266 if( uuid16 )
3267 BTM_AddEirService( p_results->eir_uuid, uuid16 );
3268 }
3269 }
3270
3271 p_uuid_data = btm_eir_get_uuid_list( p_eir, LEN_UUID_128, &num_uuid, &type );
3272 if( p_uuid_data )
3273 {
3274 for( yy = 0; yy < num_uuid; yy++ )
3275 {
3276 uuid16 = btm_convert_uuid_to_uuid16( p_uuid_data, LEN_UUID_128 );
3277 p_uuid_data += LEN_UUID_128;
3278 if( uuid16 )
3279 BTM_AddEirService( p_results->eir_uuid, uuid16 );
3280 }
3281 }
3282
3283 BTM_TRACE_DEBUG2("btm_set_eir_uuid eir_uuid=0x%08X %08X",
3284 p_results->eir_uuid[1], p_results->eir_uuid[0] );
3285 }
3286 #endif
3287
3288