• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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