blob: d178f32aa9e21da335ee7fa5ea153f74af5461d1 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
2 *
Mudumba Ananth819a2402014-07-04 02:46:05 -07003 * Copyright (C) 1999-2014 Broadcom Corporation
The Android Open Source Project5738f832012-12-12 16:00:35 -08004 *
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/********************************************************************************/
50static const LAP general_inq_lap = {0x9e,0x8b,0x33};
51static 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
55const 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/*
129If customized UUID look-up table needs to be used,
130the followings should be defined in bdroid_buildcfg.h.
131BTM_EIR_UUID_LKUP_TBL = <customized UUID list>
132BTM_EIR_MAX_SERVICES = <number of UUID in list>
133*/
134#if (BTM_EIR_MAX_SERVICES == 0)
135const UINT16 BTM_EIR_UUID_LKUP_TBL[];
136#else
137extern 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/********************************************************************************/
145static void btm_initiate_inquiry (tBTM_INQUIRY_VAR_ST *p_inq);
146static tBTM_STATUS btm_set_inq_event_filter (UINT8 filter_cond_type, tBTM_INQ_FILT_COND *p_filt_cond);
147static void btm_clr_inq_result_flt (void);
148
149#if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
150static UINT8 btm_convert_uuid_to_eir_service( UINT16 uuid16 );
151#endif
152#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
153static void btm_set_eir_uuid( UINT8 *p_eir, tBTM_INQ_RESULTS *p_results );
154static UINT8 *btm_eir_get_uuid_list( UINT8 *p_eir, UINT8 uuid_size,
155 UINT8 *p_num_uuid, UINT8 *p_uuid_list_type );
156static 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*******************************************************************************/
175tBTM_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
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700186 BTM_TRACE_API ("BTM_SetDiscoverability");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800187#if (BLE_INCLUDED == TRUE && BLE_INCLUDED == TRUE)
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700188 if (HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800189 {
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700190 if (btm_ble_set_discoverability((UINT16)(inq_mode))
191 == BTM_SUCCESS)
192 {
193 btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_BLE_DISCOVERABLE_MASK);
Mudumba Ananth819a2402014-07-04 02:46:05 -0700194 btm_cb.btm_inq_vars.discoverable_mode |= (inq_mode & BTM_BLE_DISCOVERABLE_MASK);
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700195 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800196 }
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
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700215 BTM_TRACE_API ("BTM_SetDiscoverability: mode %d [NonDisc-0, Lim-1, Gen-2], window 0x%04x, interval 0x%04x",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800216 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*******************************************************************************/
311tBTM_STATUS BTM_SetInquiryScanType (UINT16 scan_type)
312{
313
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700314 BTM_TRACE_API ("BTM_SetInquiryScanType");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800315 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 */
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700319 if (!HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800320 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*******************************************************************************/
349tBTM_STATUS BTM_SetPageScanType (UINT16 scan_type)
350{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700351 BTM_TRACE_API ("BTM_SetPageScanType");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800352 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 */
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700356 if (!HCI_LMP_INTERLACED_PAGE_SCAN_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800357 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*******************************************************************************/
390tBTM_STATUS BTM_SetInquiryMode (UINT8 mode)
391{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700392 BTM_TRACE_API ("BTM_SetInquiryMode");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800393 if (mode == BTM_INQ_RESULT_STANDARD)
394 {
395 /* mandatory mode */
396 }
397 else if (mode == BTM_INQ_RESULT_WITH_RSSI)
398 {
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700399 if (!HCI_LMP_INQ_RSSI_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800400 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 {
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700405 if (!HCI_EXT_INQ_RSP_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800406 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*******************************************************************************/
435UINT16 BTM_ReadDiscoverability (UINT16 *p_window, UINT16 *p_interval)
436{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700437 BTM_TRACE_API ("BTM_ReadDiscoverability");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800438 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*******************************************************************************/
477tBTM_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
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700483 BTM_TRACE_API ("BTM_SetPeriodicInquiryMode: mode: %d, dur: %d, rsps: %d, flt: %d, min: %d, max: %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800484 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 ||
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800508 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*/
The Android Open Source Project5738f832012-12-12 16:00:35 -0800511 {
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)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700527 BTM_TRACE_WARNING("BTM: Bypassing event filtering...");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800528
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*******************************************************************************/
572tBTM_STATUS BTM_CancelPeriodicInquiry(void)
573{
574 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
575 tBTM_STATUS status = BTM_SUCCESS;
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700576 BTM_TRACE_API ("BTM_CancelPeriodicInquiry called");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800577
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*******************************************************************************/
617tBTM_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
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700622 BTM_TRACE_API ("BTM_SetConnectability");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800623
624#if (BLE_INCLUDED == TRUE && BLE_INCLUDED == TRUE)
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700625 if (HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800626 {
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700627 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);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800633 }
634 page_mode &= ~BTM_BLE_CONNECTABLE_MASK;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800635#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
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700652 BTM_TRACE_API ("BTM_SetConnectability: mode %d [NonConn-0, Conn-1], window 0x%04x, interval 0x%04x",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800653 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*******************************************************************************/
709UINT16 BTM_ReadConnectability (UINT16 *p_window, UINT16 *p_interval)
710{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700711 BTM_TRACE_API ("BTM_ReadConnectability");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800712 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*******************************************************************************/
735UINT16 BTM_IsInquiryActive (void)
736{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700737 BTM_TRACE_API ("BTM_IsInquiryActive");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800738
739 return(btm_cb.btm_inq_vars.inq_active);
740}
741
Srinu Jellaaec80382013-12-14 20:04:41 +0530742UINT8 BTM_IsRnrActive (void)
743{
744 BTM_TRACE_API ("BTM_IsRNRActive");
745
746 return (btm_cb.btm_inq_vars.remname_active);
747}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800748
749
750/*******************************************************************************
751**
752** Function BTM_CancelInquiry
753**
754** Description This function cancels an inquiry if active
755**
756** Returns BTM_SUCCESS if successful
757** BTM_NO_RESOURCES if could not allocate a message buffer
758** BTM_WRONG_MODE if the device is not up.
759**
760*******************************************************************************/
761tBTM_STATUS BTM_CancelInquiry(void)
762{
763 tBTM_STATUS status = BTM_SUCCESS;
764 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
Matthew Xie7f3e4292013-09-30 12:44:10 -0700765#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
766 UINT8 active_mode=p_inq->inq_active;
767#endif
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700768 BTM_TRACE_API ("BTM_CancelInquiry called");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800769
770 /*** Make sure the device is ready ***/
771 if (!BTM_IsDeviceUp())
772 return (BTM_WRONG_MODE);
773
774 /* Only cancel if not in periodic mode, otherwise the caller should call BTM_CancelPeriodicMode */
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800775 if ((p_inq->inq_active &BTM_INQUIRY_ACTIVE_MASK) != 0 &&
The Android Open Source Project5738f832012-12-12 16:00:35 -0800776 (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)))
777 {
778 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
779 p_inq->state = BTM_INQ_INACTIVE_STATE;
780 p_inq->p_inq_results_cb = (tBTM_INQ_RESULTS_CB *) NULL; /* Do not notify caller anymore */
781 p_inq->p_inq_cmpl_cb = (tBTM_CMPL_CB *) NULL; /* Do not notify caller anymore */
782
783 /* If the event filter is in progress, mark it so that the processing of the return
784 event will be ignored */
785 if (p_inq->inqfilt_active)
786 {
787 p_inq->inqfilt_active = FALSE;
788 p_inq->pending_filt_complete_event++;
789 }
790 /* Initiate the cancel inquiry */
791 else
792 {
Matthew Xie7f3e4292013-09-30 12:44:10 -0700793 if (((p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK) != 0)
794#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
795 &&(active_mode & BTM_BR_INQUIRY_MASK)
796#endif
797 )
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800798 {
799 if (!btsnd_hcic_inq_cancel())
800 status = BTM_NO_RESOURCES;
801 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800802#if BLE_INCLUDED == TRUE
Matthew Xie7f3e4292013-09-30 12:44:10 -0700803 if (((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
804#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700805 &&(active_mode & BTM_BLE_INQ_ACTIVE_MASK)
Matthew Xie7f3e4292013-09-30 12:44:10 -0700806#endif
807 )
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700808 btm_ble_stop_inquiry();
The Android Open Source Project5738f832012-12-12 16:00:35 -0800809#endif
810 }
811
812#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
813 /* Do not send the BUSY_LEVEL event yet. Wait for the cancel_complete event
814 * and then send the BUSY_LEVEL event
815 * btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
816 */
817#endif
818
Nitin Arora0830ad42014-02-21 18:20:37 -0800819 p_inq->inq_counter++;
820 btm_clr_inq_result_flt();
The Android Open Source Project5738f832012-12-12 16:00:35 -0800821 }
822
823 return (status);
824}
825
826
827/*******************************************************************************
828**
829** Function BTM_StartInquiry
830**
831** Description This function is called to start an inquiry.
832**
833** Parameters: p_inqparms - pointer to the inquiry information
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800834** mode - GENERAL or LIMITED inquiry, BR/LE bit mask seperately
The Android Open Source Project5738f832012-12-12 16:00:35 -0800835** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED)
836** max_resps - maximum amount of devices to search for before ending the inquiry
837** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or
838** BTM_FILTER_COND_BD_ADDR
839** filter_cond - value for the filter (based on filter_cond_type)
840**
841** p_results_cb - Pointer to the callback routine which gets called
842** upon receipt of an inquiry result. If this field is
843** NULL, the application is not notified.
844**
845** p_cmpl_cb - Pointer to the callback routine which gets called
846** upon completion. If this field is NULL, the
847** application is not notified when completed.
848** Returns tBTM_STATUS
849** BTM_CMD_STARTED if successfully initiated
850** BTM_BUSY if already in progress
851** BTM_ILLEGAL_VALUE if parameter(s) are out of range
852** BTM_NO_RESOURCES if could not allocate resources to start the command
853** BTM_WRONG_MODE if the device is not up.
854**
855*******************************************************************************/
856tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p_results_cb,
857 tBTM_CMPL_CB *p_cmpl_cb)
858{
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800859 tBTM_STATUS status = BTM_CMD_STARTED;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800860 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
861
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700862 BTM_TRACE_API ("BTM_StartInquiry: mode: %d, dur: %d, rsps: %d, flt: %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800863 p_inqparms->mode, p_inqparms->duration, p_inqparms->max_resps,
864 p_inqparms->filter_cond_type);
865
866 /* Only one active inquiry is allowed in this implementation.
867 Also do not allow an inquiry if the inquiry filter is being updated */
868 if (p_inq->inq_active || p_inq->inqfilt_active)
Nitin Arora0830ad42014-02-21 18:20:37 -0800869 {
870#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
871 /*check if LE observe is already running*/
872 if(p_inq->scan_type==INQ_LE_OBSERVE && p_inq->p_inq_ble_results_cb!=NULL)
873 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700874 BTM_TRACE_API("BTM_StartInquiry: LE observe in progress");
Nitin Arora0830ad42014-02-21 18:20:37 -0800875 p_inq->scan_type = INQ_GENERAL;
876 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
877 btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
Nitin Arora0830ad42014-02-21 18:20:37 -0800878 btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
879 }
880 else
881#endif
882 {
883 return (BTM_BUSY);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700884 BTM_TRACE_API("BTM_StartInquiry: return BUSY");
Nitin Arora0830ad42014-02-21 18:20:37 -0800885 }
886 }
887 else
888 p_inq->scan_type = INQ_GENERAL;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800889
890 /*** Make sure the device is ready ***/
891 if (!BTM_IsDeviceUp())
892 return (BTM_WRONG_MODE);
893
894 if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_GENERAL_INQUIRY &&
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800895 (p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_LIMITED_INQUIRY
896#if (BLE_INCLUDED == TRUE)
897 && (p_inqparms->mode & BTM_BLE_INQUIRY_MASK)!= BTM_BLE_GENERAL_INQUIRY
898 && (p_inqparms->mode & BTM_BLE_INQUIRY_MASK)!= BTM_BLE_LIMITED_INQUIRY
899#endif
900 )
The Android Open Source Project5738f832012-12-12 16:00:35 -0800901 return (BTM_ILLEGAL_VALUE);
902
Matthew Xie7f3e4292013-09-30 12:44:10 -0700903#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
904 if(p_inq->next_state==BTM_FINISH)
905 return BTM_ILLEGAL_VALUE;
906#endif
907
908
The Android Open Source Project5738f832012-12-12 16:00:35 -0800909 /* Save the inquiry parameters to be used upon the completion of setting/clearing the inquiry filter */
910 p_inq->inqparms = *p_inqparms;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800911
912 /* Initialize the inquiry variables */
913 p_inq->state = BTM_INQ_ACTIVE_STATE;
914 p_inq->p_inq_cmpl_cb = p_cmpl_cb;
915 p_inq->p_inq_results_cb = p_results_cb;
916 p_inq->inq_cmpl_info.num_resp = 0; /* Clear the results counter */
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800917 p_inq->inq_active = p_inqparms->mode;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800918
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700919 BTM_TRACE_DEBUG("BTM_StartInquiry: p_inq->inq_active = 0x%02x", p_inq->inq_active);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800920
Matthew Xie7f3e4292013-09-30 12:44:10 -0700921/* interleave scan minimal conditions */
922#if (BLE_INCLUDED==TRUE && (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE))
923
924 /* check if both modes are present */
925 if((p_inqparms->mode & BTM_BLE_INQUIRY_MASK) && (p_inqparms->mode & BTM_BR_INQUIRY_MASK))
926 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700927 BTM_TRACE_API("BTM:Interleave Inquiry Mode Set");
Matthew Xie7f3e4292013-09-30 12:44:10 -0700928 p_inqparms->duration=p_inqparms->intl_duration[p_inq->next_state];
929 p_inq->inqparms.duration=p_inqparms->duration;
930 }
931 else
932 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700933 BTM_TRACE_API("BTM:Single Mode: No interleaving, Mode:0x%02x", p_inqparms->mode);
Matthew Xie7f3e4292013-09-30 12:44:10 -0700934 p_inq->next_state=BTM_NO_INTERLEAVING;
935 }
936#endif
937
938
939
The Android Open Source Project5738f832012-12-12 16:00:35 -0800940/* start LE inquiry here if requested */
941#if BLE_INCLUDED == TRUE
Matthew Xie7f3e4292013-09-30 12:44:10 -0700942 if ((p_inqparms->mode & BTM_BLE_INQUIRY_MASK)
943#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
944 &&(p_inq->next_state==BTM_BLE_ONE || p_inq->next_state==BTM_BLE_TWO ||
945 p_inq->next_state==BTM_NO_INTERLEAVING)
946#endif
947 )
948
The Android Open Source Project5738f832012-12-12 16:00:35 -0800949 {
Matthew Xie7f3e4292013-09-30 12:44:10 -0700950#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
951 p_inq->inq_active = (p_inqparms->mode & BTM_BLE_INQUIRY_MASK);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700952 BTM_TRACE_API("BTM:Starting LE Scan with duration %d and activeMode:0x%02x",
Matthew Xie7f3e4292013-09-30 12:44:10 -0700953 p_inqparms->duration, (p_inqparms->mode & BTM_BLE_INQUIRY_MASK));
954#endif
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700955 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
956 {
957 p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK;
958 status = BTM_ILLEGAL_VALUE;
959 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800960 /* BLE for now does not support filter condition for inquiry */
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700961 else if ((status = btm_ble_start_inquiry((UINT8)(p_inqparms->mode & BTM_BLE_INQUIRY_MASK),
962 p_inqparms->duration)) != BTM_CMD_STARTED)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800963 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700964 BTM_TRACE_ERROR("Err Starting LE Inquiry.");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800965 p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK;
966 }
Matthew Xie7f3e4292013-09-30 12:44:10 -0700967#if (!defined(BTA_HOST_INTERLEAVE_SEARCH) || BTA_HOST_INTERLEAVE_SEARCH == FALSE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800968 p_inqparms->mode &= ~BTM_BLE_INQUIRY_MASK;
Matthew Xie7f3e4292013-09-30 12:44:10 -0700969#endif
970
971#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
972 if(p_inq->next_state==BTM_NO_INTERLEAVING)
973 {
974 p_inq->next_state=BTM_FINISH;
975 }
976 else
977 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700978 BTM_TRACE_API("BTM:Interleaving: started LE scan, Advancing to next state: %d",
Matthew Xie7f3e4292013-09-30 12:44:10 -0700979 p_inq->next_state+1);
980 p_inq->next_state+=1;
981 }
982 /* reset next_state if status <> BTM_Started */
983 if(status!=BTM_CMD_STARTED)
984 p_inq->next_state=BTM_BR_ONE;
985
986 /* if interleave scan..return here */
987 return status;
988#endif
989
The Android Open Source Project5738f832012-12-12 16:00:35 -0800990
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700991 BTM_TRACE_DEBUG("BTM_StartInquiry: mode = %02x", p_inqparms->mode);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800992 }
993#endif /* end of BLE_INCLUDED */
994
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800995 /* we're done with this routine if BR/EDR inquiry is not desired. */
996 if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK) == BTM_INQUIRY_NONE)
997 return status;
998
Matthew Xie7f3e4292013-09-30 12:44:10 -0700999 /* BR/EDR inquiry portion */
1000#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
1001 if((p_inq->next_state==BTM_BR_ONE || p_inq->next_state==BTM_BR_TWO ||
1002 p_inq->next_state==BTM_NO_INTERLEAVING ))
1003 {
1004 p_inq->inq_active = (p_inqparms->mode & BTM_BR_INQUIRY_MASK);
1005#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -08001006#if (defined(BTM_BYPASS_EVENT_FILTERING) && BTM_BYPASS_EVENT_FILTERING == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001007 BTM_TRACE_WARNING("BTM: Bypassing event filtering...");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001008 p_inq->inqfilt_active = FALSE;
1009 btm_initiate_inquiry (p_inq);
1010 status = BTM_CMD_STARTED;
1011#else
1012 /* If a filter is specified, then save it for later and clear the current filter.
1013 The setting of the filter is done upon completion of clearing of the previous
1014 filter.
1015 */
1016 switch (p_inqparms->filter_cond_type)
1017 {
1018 case BTM_CLR_INQUIRY_FILTER:
1019 p_inq->state = BTM_INQ_SET_FILT_STATE;
1020 break;
1021
1022 case BTM_FILTER_COND_DEVICE_CLASS:
1023 case BTM_FILTER_COND_BD_ADDR:
1024 /* The filter is not being used so simply clear it;
1025 the inquiry can start after this operation */
1026 p_inq->state = BTM_INQ_CLR_FILT_STATE;
1027 p_inqparms->filter_cond_type = BTM_CLR_INQUIRY_FILTER;
1028 /* =============>>>> adding LE filtering here ????? */
1029 break;
1030
1031 default:
1032 return (BTM_ILLEGAL_VALUE);
1033 }
1034
1035 /* Before beginning the inquiry the current filter must be cleared, so initiate the command */
Matthew Xie7f3e4292013-09-30 12:44:10 -07001036 if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type,
1037 &p_inqparms->filter_cond)) != BTM_CMD_STARTED)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001038 p_inq->state = BTM_INQ_INACTIVE_STATE;
1039#endif
Matthew Xie7f3e4292013-09-30 12:44:10 -07001040
1041#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
1042 if (p_inq->next_state==BTM_NO_INTERLEAVING)
1043 p_inq->next_state=BTM_FINISH;
1044 else
1045 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001046 BTM_TRACE_API("BTM:Interleaving: Started BTM inq, Advancing to next state: %d",
Matthew Xie7f3e4292013-09-30 12:44:10 -07001047 p_inq->next_state+1);
1048 p_inq->next_state+=1;
1049 }
1050 }
1051 if (status!=BTM_CMD_STARTED)
1052 {
1053 /* Some error beginning the scan process.
1054 Reset the next_state parameter.. Do we need to reset the inq_active also?
1055 */
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001056 BTM_TRACE_API("BTM:Interleaving: Error in Starting inquiry, status: 0x%02x", status);
Matthew Xie7f3e4292013-09-30 12:44:10 -07001057 p_inq->next_state=BTM_BR_ONE;
1058 }
1059#endif
1060
1061
The Android Open Source Project5738f832012-12-12 16:00:35 -08001062 return (status);
1063}
1064
1065
1066/*******************************************************************************
1067**
1068** Function BTM_ReadRemoteDeviceName
1069**
1070** Description This function initiates a remote device HCI command to the
1071** controller and calls the callback when the process has completed.
1072**
1073** Input Params: remote_bda - device address of name to retrieve
1074** p_cb - callback function called when BTM_CMD_STARTED
1075** is returned.
1076** A pointer to tBTM_REMOTE_DEV_NAME is passed to the
1077** callback.
1078**
1079** Returns
1080** BTM_CMD_STARTED is returned if the request was successfully sent
1081** to HCI.
1082** BTM_BUSY if already in progress
1083** BTM_UNKNOWN_ADDR if device address is bad
1084** BTM_NO_RESOURCES if could not allocate resources to start the command
1085** BTM_WRONG_MODE if the device is not up.
1086**
1087*******************************************************************************/
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001088tBTM_STATUS BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb
1089 ,tBT_TRANSPORT transport)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001090{
1091 tBTM_INQ_INFO *p_cur = NULL;
1092 tINQ_DB_ENT *p_i;
1093
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001094 BTM_TRACE_API ("BTM_ReadRemoteDeviceName: bd addr [%02x%02x%02x%02x%02x%02x]",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001095 remote_bda[0], remote_bda[1], remote_bda[2],
1096 remote_bda[3], remote_bda[4], remote_bda[5]);
1097
1098 /* Use the remote device's clock offset if it is in the local inquiry database */
1099 if ((p_i = btm_inq_db_find (remote_bda)) != NULL)
1100 {
1101 p_cur = &p_i->inq_info;
1102
1103#if (BTM_INQ_GET_REMOTE_NAME == TRUE)
1104 p_cur->remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
1105#endif
1106 }
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001107 BTM_TRACE_API ("no device found in inquiry db");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001108
1109#if (BLE_INCLUDED == TRUE)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001110 if (transport == BT_TRANSPORT_LE)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001111 {
1112 return btm_ble_read_remote_name(remote_bda, p_cur, p_cb);
1113 }
1114 else
1115#endif
1116
1117 return (btm_initiate_rem_name (remote_bda, p_cur, BTM_RMT_NAME_EXT,
1118 BTM_EXT_RMT_NAME_TIMEOUT, p_cb));
1119}
1120
1121/*******************************************************************************
1122**
1123** Function BTM_CancelRemoteDeviceName
1124**
1125** Description This function initiates the cancel request for the specified
1126** remote device.
1127**
1128** Input Params: None
1129**
1130** Returns
1131** BTM_CMD_STARTED is returned if the request was successfully sent
1132** to HCI.
1133** BTM_NO_RESOURCES if could not allocate resources to start the command
1134** BTM_WRONG_MODE if there is not an active remote name request.
1135**
1136*******************************************************************************/
1137tBTM_STATUS BTM_CancelRemoteDeviceName (void)
1138{
1139 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1140
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001141 BTM_TRACE_API ("BTM_CancelRemoteDeviceName()");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001142
1143 /* Make sure there is not already one in progress */
1144 if (p_inq->remname_active)
1145 {
1146#if BLE_INCLUDED == TRUE
Andre Eisenbach6975b4d2013-08-05 16:55:38 -07001147 if (BTM_UseLeLink(p_inq->remname_bda))
The Android Open Source Project5738f832012-12-12 16:00:35 -08001148 {
1149 if (btm_ble_cancel_remote_name(p_inq->remname_bda))
1150 return (BTM_CMD_STARTED);
1151 else
1152 return (BTM_UNKNOWN_ADDR);
1153 }
1154 else
1155#endif
1156 if (btsnd_hcic_rmt_name_req_cancel (p_inq->remname_bda))
1157 return (BTM_CMD_STARTED);
1158 else
1159 return (BTM_NO_RESOURCES);
1160 }
1161 else
1162 return (BTM_WRONG_MODE);
1163}
1164
1165/*******************************************************************************
1166**
1167** Function BTM_InqFirstResult
1168**
1169** Description This function looks through the inquiry database for the first
1170** used entrysince the LAST inquiry. This is used in conjunction
1171** with BTM_InqNext by applications as a way to walk through the
1172** inquiry results database.
1173**
1174** Returns pointer to first in-use entry, or NULL if DB is empty
1175**
1176*******************************************************************************/
1177tBTM_INQ_INFO *BTM_InqFirstResult (void)
1178{
1179 UINT16 xx;
1180 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1181 UINT32 cur_inq_count = btm_cb.btm_inq_vars.inq_counter - 1;
1182
1183 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1184 {
1185 if (p_ent->in_use && p_ent->inq_count == cur_inq_count)
1186 return (&p_ent->inq_info);
1187 }
1188
1189 /* If here, no used entry found */
1190 return ((tBTM_INQ_INFO *)NULL);
1191}
1192
1193
1194/*******************************************************************************
1195**
1196** Function BTM_InqNextResult
1197**
1198** Description This function looks through the inquiry database for the next
1199** used entrysince the LAST inquiry. If the input parameter is NULL,
1200** the first entry is returned.
1201**
1202** Returns pointer to next in-use entry, or NULL if no more found.
1203**
1204*******************************************************************************/
1205tBTM_INQ_INFO *BTM_InqNextResult (tBTM_INQ_INFO *p_cur)
1206{
1207 tINQ_DB_ENT *p_ent;
1208 UINT16 inx;
1209 UINT32 cur_inq_count = btm_cb.btm_inq_vars.inq_counter - 1;
1210
1211 if (p_cur)
1212 {
1213 p_ent = (tINQ_DB_ENT *) ((UINT8 *)p_cur - offsetof (tINQ_DB_ENT, inq_info));
1214 inx = (UINT16)((p_ent - btm_cb.btm_inq_vars.inq_db) + 1);
1215
1216 for (p_ent = &btm_cb.btm_inq_vars.inq_db[inx]; inx < BTM_INQ_DB_SIZE; inx++, p_ent++)
1217 {
1218 if (p_ent->in_use && p_ent->inq_count == cur_inq_count)
1219 return (&p_ent->inq_info);
1220 }
1221
1222 /* If here, more entries found */
1223 return ((tBTM_INQ_INFO *)NULL);
1224 }
1225 else
1226 return (BTM_InqDbFirst());
1227}
1228
1229
1230/*******************************************************************************
1231**
1232** Function BTM_InqDbRead
1233**
1234** Description This function looks through the inquiry database for a match
1235** based on Bluetooth Device Address. This is the application's
1236** interface to get the inquiry details of a specific BD address.
1237**
1238** Returns pointer to entry, or NULL if not found
1239**
1240*******************************************************************************/
1241tBTM_INQ_INFO *BTM_InqDbRead (BD_ADDR p_bda)
1242{
1243 UINT16 xx;
1244 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1245
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001246 BTM_TRACE_API ("BTM_InqDbRead: bd addr [%02x%02x%02x%02x%02x%02x]",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001247 p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
1248
1249 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1250 {
1251 if ((p_ent->in_use) && (!memcmp (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
1252 return (&p_ent->inq_info);
1253 }
1254
1255 /* If here, not found */
1256 return ((tBTM_INQ_INFO *)NULL);
1257}
1258
1259
1260/*******************************************************************************
1261**
1262** Function BTM_InqDbFirst
1263**
1264** Description This function looks through the inquiry database for the first
1265** used entry, and returns that. This is used in conjunction with
1266** BTM_InqDbNext by applications as a way to walk through the
1267** inquiry database.
1268**
1269** Returns pointer to first in-use entry, or NULL if DB is empty
1270**
1271*******************************************************************************/
1272tBTM_INQ_INFO *BTM_InqDbFirst (void)
1273{
1274 UINT16 xx;
1275 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1276
1277 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1278 {
1279 if (p_ent->in_use)
1280 return (&p_ent->inq_info);
1281 }
1282
1283 /* If here, no used entry found */
1284 return ((tBTM_INQ_INFO *)NULL);
1285}
1286
1287
1288/*******************************************************************************
1289**
1290** Function BTM_InqDbNext
1291**
1292** Description This function looks through the inquiry database for the next
1293** used entry, and returns that. If the input parameter is NULL,
1294** the first entry is returned.
1295**
1296** Returns pointer to next in-use entry, or NULL if no more found.
1297**
1298*******************************************************************************/
1299tBTM_INQ_INFO *BTM_InqDbNext (tBTM_INQ_INFO *p_cur)
1300{
1301 tINQ_DB_ENT *p_ent;
1302 UINT16 inx;
1303
1304 if (p_cur)
1305 {
1306 p_ent = (tINQ_DB_ENT *) ((UINT8 *)p_cur - offsetof (tINQ_DB_ENT, inq_info));
1307 inx = (UINT16)((p_ent - btm_cb.btm_inq_vars.inq_db) + 1);
1308
1309 for (p_ent = &btm_cb.btm_inq_vars.inq_db[inx]; inx < BTM_INQ_DB_SIZE; inx++, p_ent++)
1310 {
1311 if (p_ent->in_use)
1312 return (&p_ent->inq_info);
1313 }
1314
1315 /* If here, more entries found */
1316 return ((tBTM_INQ_INFO *)NULL);
1317 }
1318 else
1319 return (BTM_InqDbFirst());
1320}
1321
1322
1323/*******************************************************************************
1324**
1325** Function BTM_ClearInqDb
1326**
1327** Description This function is called to clear out a device or all devices
1328** from the inquiry database.
1329**
1330** Parameter p_bda - (input) BD_ADDR -> Address of device to clear
1331** (NULL clears all entries)
1332**
1333** Returns BTM_BUSY if an inquiry, get remote name, or event filter
1334** is active, otherwise BTM_SUCCESS
1335**
1336*******************************************************************************/
1337tBTM_STATUS BTM_ClearInqDb (BD_ADDR p_bda)
1338{
1339 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1340
1341 /* If an inquiry or remote name is in progress return busy */
1342 if (p_inq->inq_active != BTM_INQUIRY_INACTIVE ||
1343 p_inq->inqfilt_active)
1344 return (BTM_BUSY);
1345
1346 btm_clr_inq_db(p_bda);
1347
1348 return (BTM_SUCCESS);
1349}
1350
1351
1352/*******************************************************************************
1353**
1354** Function BTM_ReadNumInqDbEntries
1355**
1356** Returns This function returns the number of entries in the inquiry database.
1357**
1358*******************************************************************************/
1359UINT8 BTM_ReadNumInqDbEntries (void)
1360{
1361 UINT8 num_entries;
1362 UINT8 num_results;
1363 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1364
1365 for (num_entries = 0, num_results = 0; num_entries < BTM_INQ_DB_SIZE; num_entries++, p_ent++)
1366 {
1367 if (p_ent->in_use)
1368 num_results++;
1369 }
1370
1371 return (num_results);
1372}
1373
1374
1375/*******************************************************************************
1376**
1377** Function BTM_InquiryRegisterForChanges
1378**
1379** Returns This function is called to register a callback for when the
1380** inquiry database changes, i.e. new entry or entry deleted.
1381**
1382*******************************************************************************/
1383tBTM_STATUS BTM_InquiryRegisterForChanges (tBTM_INQ_DB_CHANGE_CB *p_cb)
1384{
1385 if (!p_cb)
1386 btm_cb.btm_inq_vars.p_inq_change_cb = NULL;
1387 else if (btm_cb.btm_inq_vars.p_inq_change_cb)
1388 return (BTM_BUSY);
1389 else
1390 btm_cb.btm_inq_vars.p_inq_change_cb = p_cb;
1391
1392 return (BTM_SUCCESS);
1393}
1394
1395
1396/*******************************************************************************
1397**
1398** Function BTM_SetInquiryFilterCallback
1399**
1400** Description Host can register to be asked whenever an inquiry result
1401** is received. If host does not like the device no name
1402** request is issued for the device
1403**
1404** Returns void
1405**
1406*******************************************************************************/
1407void BTM_SetInquiryFilterCallback (tBTM_FILTER_CB *p_callback)
1408{
1409 btm_cb.p_inq_filter_cb = p_callback;
1410}
1411
1412/*******************************************************************************
1413**
1414** Function BTM_ReadInquiryRspTxPower
1415**
1416** Description This command will read the inquiry Transmit Power level used
1417** to transmit the FHS and EIR data packets.
1418** This can be used directly in the Tx Power Level EIR data type.
1419**
1420** Returns BTM_SUCCESS if successful
1421**
1422*******************************************************************************/
1423tBTM_STATUS BTM_ReadInquiryRspTxPower (tBTM_CMPL_CB *p_cb)
1424{
1425 if (btm_cb.devcb.p_txpwer_cmpl_cb)
1426 return (BTM_BUSY);
1427
1428 btu_start_timer (&btm_cb.devcb.txpwer_timer, BTU_TTYPE_BTM_ACL, BTM_INQ_REPLY_TIMEOUT );
1429
1430
1431 btm_cb.devcb.p_txpwer_cmpl_cb = p_cb;
1432
1433 if (!btsnd_hcic_read_inq_tx_power ())
1434 {
1435 btm_cb.devcb.p_txpwer_cmpl_cb = NULL;
1436 btu_stop_timer (&btm_cb.devcb.txpwer_timer);
1437 return (BTM_NO_RESOURCES);
1438 }
1439 else
1440 return (BTM_CMD_STARTED);
1441}
1442/*******************************************************************************
1443**
1444** Function BTM_WriteInquiryTxPower
1445**
1446** Description This command is used to write the inquiry transmit power level
1447** used to transmit the inquiry (ID) data packets. The Controller
1448** should use the supported TX power level closest to the Tx_Power
1449** parameter.
1450**
1451** Returns BTM_SUCCESS if successful
1452**
1453*******************************************************************************/
1454tBTM_STATUS BTM_WriteInquiryTxPower (INT8 tx_power)
1455{
1456 tBTM_STATUS status = BTM_SUCCESS;
1457
1458 if (tx_power < BTM_MIN_INQ_TX_POWER || tx_power > BTM_MAX_INQ_TX_POWER)
1459 {
1460 status = BTM_ILLEGAL_VALUE;
1461 }
1462 else if (!btsnd_hcic_write_inq_tx_power(tx_power))
1463 status = BTM_NO_RESOURCES;
1464
1465 return status;
1466}
1467/*********************************************************************************
1468**********************************************************************************
1469** **
1470** BTM Internal Inquiry Functions **
1471** **
1472**********************************************************************************
1473*********************************************************************************/
1474/*******************************************************************************
1475**
1476** Function btm_inq_db_reset
1477**
1478** Description This function is called at at reset to clear the inquiry
1479** database & pending callback.
1480**
1481** Returns void
1482**
1483*******************************************************************************/
1484void btm_inq_db_reset (void)
1485{
1486 tBTM_REMOTE_DEV_NAME rem_name;
1487 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1488 UINT8 num_responses;
1489 UINT8 temp_inq_active;
1490 tBTM_STATUS status;
1491
1492 btu_stop_timer (&p_inq->inq_timer_ent);
1493
1494 /* If an inquiry or periodic inquiry is active, reset the mode to inactive */
1495 if (p_inq->inq_active != BTM_INQUIRY_INACTIVE)
1496 {
1497 temp_inq_active = p_inq->inq_active; /* Save so state can change BEFORE
1498 callback is called */
1499 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1500
1501 /* If not a periodic inquiry, the complete callback must be called to notify caller */
1502 if (temp_inq_active == BTM_LIMITED_INQUIRY_ACTIVE ||
1503 temp_inq_active == BTM_GENERAL_INQUIRY_ACTIVE)
1504 {
1505 if (p_inq->p_inq_cmpl_cb)
1506 {
1507 num_responses = 0;
1508 (*p_inq->p_inq_cmpl_cb)(&num_responses);
1509 }
1510 }
1511 }
1512
1513 /* Cancel a remote name request if active, and notify the caller (if waiting) */
1514 if (p_inq->remname_active )
1515 {
1516 btu_stop_timer (&p_inq->rmt_name_timer_ent);
1517 p_inq->remname_active = FALSE;
1518 memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
1519
1520 if (p_inq->p_remname_cmpl_cb)
1521 {
1522 rem_name.status = BTM_DEV_RESET;
1523
1524 (*p_inq->p_remname_cmpl_cb)(&rem_name);
1525 p_inq->p_remname_cmpl_cb = NULL;
1526 }
1527 }
1528
1529 /* Cancel an inquiry filter request if active, and notify the caller (if waiting) */
1530 if (p_inq->inqfilt_active)
1531 {
1532 p_inq->inqfilt_active = FALSE;
1533
1534 if (p_inq->p_inqfilter_cmpl_cb)
1535 {
1536 status = BTM_DEV_RESET;
1537 (*p_inq->p_inqfilter_cmpl_cb)(&status);
1538 }
1539 }
1540
1541 p_inq->state = BTM_INQ_INACTIVE_STATE;
1542 p_inq->pending_filt_complete_event = 0;
1543 p_inq->p_inq_results_cb = NULL;
1544 btm_clr_inq_db(NULL); /* Clear out all the entries in the database */
1545 btm_clr_inq_result_flt();
1546
1547 p_inq->discoverable_mode = BTM_NON_DISCOVERABLE;
1548 p_inq->connectable_mode = BTM_NON_CONNECTABLE;
1549 p_inq->page_scan_type = BTM_SCAN_TYPE_STANDARD;
1550 p_inq->inq_scan_type = BTM_SCAN_TYPE_STANDARD;
1551
1552#if BLE_INCLUDED == TRUE
1553 p_inq->discoverable_mode |= BTM_BLE_NON_DISCOVERABLE;
1554 p_inq->connectable_mode |= BTM_BLE_NON_CONNECTABLE;
1555#endif
1556 return;
1557}
1558
1559
1560/*********************************************************************************
1561**
1562** Function btm_inq_db_init
1563**
1564** Description This function is called at startup to initialize the inquiry
1565** database.
1566**
1567** Returns void
1568**
1569*******************************************************************************/
1570void btm_inq_db_init (void)
1571{
1572#if 0 /* cleared in btm_init; put back in if called from anywhere else! */
1573 memset (&btm_cb.btm_inq_vars, 0, sizeof (tBTM_INQUIRY_VAR_ST));
1574#endif
1575 btm_cb.btm_inq_vars.no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;
1576}
1577
1578/*********************************************************************************
1579**
1580** Function btm_inq_stop_on_ssp
1581**
1582** Description This function is called on incoming SSP
1583**
1584** Returns void
1585**
1586*******************************************************************************/
1587void btm_inq_stop_on_ssp(void)
1588{
1589 UINT8 normal_active = (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE);
1590
1591#if (BTM_INQ_DEBUG == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001592 BTM_TRACE_DEBUG ("btm_inq_stop_on_ssp: no_inc_ssp=%d inq_active:0x%x state:%d inqfilt_active:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001593 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);
1594#endif
1595 if (btm_cb.btm_inq_vars.no_inc_ssp)
1596 {
1597 if (btm_cb.btm_inq_vars.state == BTM_INQ_ACTIVE_STATE)
1598 {
1599 if (btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)
1600 {
1601 BTM_CancelPeriodicInquiry();
1602 }
1603 else if (btm_cb.btm_inq_vars.inq_active & normal_active)
1604 {
1605 /* can not call BTM_CancelInquiry() here. We need to report inquiry complete evt */
1606 btsnd_hcic_inq_cancel();
1607 }
1608 }
1609 /* do not allow inquiry to start */
1610 btm_cb.btm_inq_vars.inq_active |= BTM_SSP_INQUIRY_ACTIVE;
1611 }
1612}
1613
1614/*********************************************************************************
1615**
1616** Function btm_inq_clear_ssp
1617**
1618** Description This function is called when pairing_state becomes idle
1619**
1620** Returns void
1621**
1622*******************************************************************************/
1623void btm_inq_clear_ssp(void)
1624{
1625 btm_cb.btm_inq_vars.inq_active &= ~BTM_SSP_INQUIRY_ACTIVE;
1626}
1627
1628/*********************************************************************************
1629**
1630** Function btm_clr_inq_db
1631**
1632** Description This function is called to clear out a device or all devices
1633** from the inquiry database.
1634**
1635** Parameter p_bda - (input) BD_ADDR -> Address of device to clear
1636** (NULL clears all entries)
1637**
1638** Returns void
1639**
1640*******************************************************************************/
1641void btm_clr_inq_db (BD_ADDR p_bda)
1642{
1643 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1644 tINQ_DB_ENT *p_ent = p_inq->inq_db;
1645 UINT16 xx;
1646
1647#if (BTM_INQ_DEBUG == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001648 BTM_TRACE_DEBUG ("btm_clr_inq_db: inq_active:0x%x state:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001649 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1650#endif
1651 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1652 {
1653 if (p_ent->in_use)
1654 {
1655 /* If this is the specified BD_ADDR or clearing all devices */
1656 if (p_bda == NULL ||
1657 (!memcmp (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
1658 {
1659 p_ent->in_use = FALSE;
1660#if (BTM_INQ_GET_REMOTE_NAME == TRUE)
1661 p_ent->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
1662#endif
1663
1664 if (btm_cb.btm_inq_vars.p_inq_change_cb)
1665 (*btm_cb.btm_inq_vars.p_inq_change_cb) (&p_ent->inq_info, FALSE);
1666 }
1667 }
1668 }
1669#if (BTM_INQ_DEBUG == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001670 BTM_TRACE_DEBUG ("inq_active:0x%x state:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001671 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1672#endif
1673}
1674
1675
1676/*******************************************************************************
1677**
1678** Function btm_clr_inq_result_flt
1679**
1680** Description This function looks through the bdaddr database for a match
1681** based on Bluetooth Device Address
1682**
1683** Returns TRUE if found, else FALSE (new entry)
1684**
1685*******************************************************************************/
1686static void btm_clr_inq_result_flt (void)
1687{
1688#if BTM_USE_INQ_RESULTS_FILTER == TRUE
1689 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1690
1691 if (p_inq->p_bd_db)
1692 {
1693 GKI_freebuf(p_inq->p_bd_db);
1694 p_inq->p_bd_db = NULL;
1695 }
1696 p_inq->num_bd_entries = 0;
1697 p_inq->max_bd_entries = 0;
1698#endif
1699}
1700
1701/*******************************************************************************
1702**
1703** Function btm_inq_find_bdaddr
1704**
1705** Description This function looks through the bdaddr database for a match
1706** based on Bluetooth Device Address
1707**
1708** Returns TRUE if found, else FALSE (new entry)
1709**
1710*******************************************************************************/
1711BOOLEAN btm_inq_find_bdaddr (BD_ADDR p_bda)
1712{
1713#if BTM_USE_INQ_RESULTS_FILTER == TRUE
1714 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1715 tINQ_BDADDR *p_db = &p_inq->p_bd_db[0];
1716 UINT16 xx;
1717
1718 /* Don't bother searching, database doesn't exist or periodic mode */
1719 if ((p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) || !p_db)
1720 return (FALSE);
1721
1722 for (xx = 0; xx < p_inq->num_bd_entries; xx++, p_db++)
1723 {
1724 if (!memcmp(p_db->bd_addr, p_bda, BD_ADDR_LEN)
1725 && p_db->inq_count == p_inq->inq_counter)
1726 return (TRUE);
1727 }
1728
1729 if (xx < p_inq->max_bd_entries)
1730 {
1731 p_db->inq_count = p_inq->inq_counter;
1732 memcpy(p_db->bd_addr, p_bda, BD_ADDR_LEN);
1733 p_inq->num_bd_entries++;
1734 }
1735
1736#endif
1737 /* If here, New Entry */
1738 return (FALSE);
1739}
1740
1741/*******************************************************************************
1742**
1743** Function btm_inq_db_find
1744**
1745** Description This function looks through the inquiry database for a match
1746** based on Bluetooth Device Address
1747**
1748** Returns pointer to entry, or NULL if not found
1749**
1750*******************************************************************************/
1751tINQ_DB_ENT *btm_inq_db_find (BD_ADDR p_bda)
1752{
1753 UINT16 xx;
1754 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1755
1756 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1757 {
1758 if ((p_ent->in_use) && (!memcmp (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
1759 return (p_ent);
1760 }
1761
1762 /* If here, not found */
1763 return (NULL);
1764}
1765
1766
1767/*******************************************************************************
1768**
1769** Function btm_inq_db_new
1770**
1771** Description This function looks through the inquiry database for an unused
1772** entry. If no entry is free, it allocates the oldest entry.
1773**
1774** Returns pointer to entry
1775**
1776*******************************************************************************/
1777tINQ_DB_ENT *btm_inq_db_new (BD_ADDR p_bda)
1778{
1779 UINT16 xx;
1780 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
1781 tINQ_DB_ENT *p_old = btm_cb.btm_inq_vars.inq_db;
1782 UINT32 ot = 0xFFFFFFFF;
1783
1784 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1785 {
1786 if (!p_ent->in_use)
1787 {
1788 memset (p_ent, 0, sizeof (tINQ_DB_ENT));
1789 memcpy (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN);
1790 p_ent->in_use = TRUE;
1791
1792#if (BTM_INQ_GET_REMOTE_NAME==TRUE)
1793 p_ent->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
1794#endif
1795
1796 return (p_ent);
1797 }
1798
1799 if (p_ent->time_of_resp < ot)
1800 {
1801 p_old = p_ent;
1802 ot = p_ent->time_of_resp;
1803 }
1804 }
1805
1806 /* If here, no free entry found. Return the oldest. */
1807
1808 /* Before deleting the oldest, if anyone is registered for change */
1809 /* notifications, then tell him we are deleting an entry. */
1810 if (btm_cb.btm_inq_vars.p_inq_change_cb)
1811 (*btm_cb.btm_inq_vars.p_inq_change_cb) (&p_old->inq_info, FALSE);
1812
1813 memset (p_old, 0, sizeof (tINQ_DB_ENT));
1814 memcpy (p_old->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN);
1815 p_old->in_use = TRUE;
1816
1817#if (BTM_INQ_GET_REMOTE_NAME==TRUE)
1818 p_old->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
1819#endif
1820
1821 return (p_old);
1822}
1823
1824
1825/*******************************************************************************
1826**
1827** Function btm_set_inq_event_filter
1828**
1829** Description This function is called to set the inquiry event filter.
1830** It is called by either internally, or by the external API function
1831** (BTM_SetInqEventFilter). It is used internally as part of the
1832** inquiry processing.
1833**
1834** Input Params:
1835** filter_cond_type - this is the type of inquiry filter to apply:
1836** BTM_FILTER_COND_DEVICE_CLASS,
1837** BTM_FILTER_COND_BD_ADDR, or
1838** BTM_CLR_INQUIRY_FILTER
1839**
1840** p_filt_cond - this is either a BD_ADDR or DEV_CLASS depending on the
1841** filter_cond_type (See section 4.7.3 of Core Spec 1.0b).
1842**
1843** Returns BTM_CMD_STARTED if successfully initiated
1844** BTM_NO_RESOURCES if couldn't get a memory pool buffer
1845** BTM_ILLEGAL_VALUE if a bad parameter was detected
1846**
1847*******************************************************************************/
1848static tBTM_STATUS btm_set_inq_event_filter (UINT8 filter_cond_type,
1849 tBTM_INQ_FILT_COND *p_filt_cond)
1850{
1851 UINT8 condition_length = DEV_CLASS_LEN * 2;
1852 UINT8 condition_buf[DEV_CLASS_LEN * 2];
1853 UINT8 *p_cond = condition_buf; /* points to the condition to pass to HCI */
1854
1855#if (BTM_INQ_DEBUG == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001856 BTM_TRACE_DEBUG ("btm_set_inq_event_filter: filter type %d [Clear-0, COD-1, BDADDR-2]",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001857 filter_cond_type);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001858 BTM_TRACE_DEBUG (" condition [%02x%02x%02x %02x%02x%02x]",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001859 p_filt_cond->bdaddr_cond[0], p_filt_cond->bdaddr_cond[1], p_filt_cond->bdaddr_cond[2],
1860 p_filt_cond->bdaddr_cond[3], p_filt_cond->bdaddr_cond[4], p_filt_cond->bdaddr_cond[5]);
1861#endif
1862
1863 /* Load the correct filter condition to pass to the lower layer */
1864 switch (filter_cond_type)
1865 {
1866 case BTM_FILTER_COND_DEVICE_CLASS:
1867 /* copy the device class and device class fields into contiguous memory to send to HCI */
1868 memcpy (condition_buf, p_filt_cond->cod_cond.dev_class, DEV_CLASS_LEN);
1869 memcpy (&condition_buf[DEV_CLASS_LEN],
1870 p_filt_cond->cod_cond.dev_class_mask, DEV_CLASS_LEN);
1871
1872 /* condition length should already be set as the default */
1873 break;
1874
1875 case BTM_FILTER_COND_BD_ADDR:
1876 p_cond = p_filt_cond->bdaddr_cond;
1877
1878 /* condition length should already be set as the default */
1879 break;
1880
1881 case BTM_CLR_INQUIRY_FILTER:
1882 condition_length = 0;
1883 break;
1884
1885 default:
1886 return (BTM_ILLEGAL_VALUE); /* Bad parameter was passed in */
1887 }
1888
1889 btm_cb.btm_inq_vars.inqfilt_active = TRUE;
1890
1891 /* Filter the inquiry results for the specified condition type and value */
1892 if (btsnd_hcic_set_event_filter(HCI_FILTER_INQUIRY_RESULT, filter_cond_type,
1893 p_cond, condition_length))
1894
1895 return (BTM_CMD_STARTED);
1896 else
1897 return (BTM_NO_RESOURCES);
1898}
1899
1900
1901/*******************************************************************************
1902**
1903** Function btm_event_filter_complete
1904**
1905** Description This function is called when a set event filter has completed.
1906** Note: This routine currently only handles inquiry filters.
1907** Connection filters are ignored for now.
1908**
1909** Returns void
1910**
1911*******************************************************************************/
1912void btm_event_filter_complete (UINT8 *p)
1913{
1914 UINT8 hci_status;
1915 tBTM_STATUS status;
1916 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1917 tBTM_CMPL_CB *p_cb = p_inq->p_inqfilter_cmpl_cb;
1918
1919#if (BTM_INQ_DEBUG == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001920 BTM_TRACE_DEBUG ("btm_event_filter_complete: inq_active:0x%x state:%d inqfilt_active:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001921 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
1922#endif
1923 /* If the filter complete event is from an old or cancelled request, ignore it */
1924 if(p_inq->pending_filt_complete_event)
1925 {
1926 p_inq->pending_filt_complete_event--;
1927 return;
1928 }
1929
1930 /* Only process the inquiry filter; Ignore the connection filter until it
1931 is used by the upper layers */
1932 if (p_inq->inqfilt_active == TRUE )
1933 {
1934 /* Extract the returned status from the buffer */
1935 STREAM_TO_UINT8 (hci_status, p);
1936 if (hci_status != HCI_SUCCESS)
1937 {
1938 /* If standalone operation, return the error status; if embedded in the inquiry, continue the inquiry */
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001939 BTM_TRACE_WARNING ("BTM Warning: Set Event Filter Failed (HCI returned 0x%x)", hci_status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001940 status = BTM_ERR_PROCESSING;
1941 }
1942 else
1943 status = BTM_SUCCESS;
1944
1945 /* If the set filter was initiated externally (via BTM_SetInqEventFilter), call the
1946 callback function to notify the initiator that it has completed */
1947 if (p_inq->state == BTM_INQ_INACTIVE_STATE)
1948 {
1949 p_inq->inqfilt_active = FALSE;
1950 if (p_cb)
1951 (*p_cb) (&status);
1952 }
1953 else /* An inquiry is active (the set filter command was internally generated),
1954 process the next state of the process (Set a new filter or start the inquiry). */
1955 {
1956 if(status != BTM_SUCCESS)
1957 {
1958 /* Process the inquiry complete (Error Status) */
1959 btm_process_inq_complete (BTM_ERR_PROCESSING, (UINT8)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
1960
1961 /* btm_process_inq_complete() does not restore the following settings on periodic inquiry */
1962 p_inq->inqfilt_active = FALSE;
1963 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1964 p_inq->state = BTM_INQ_INACTIVE_STATE;
1965
1966 return;
1967 }
1968
1969 /* Check to see if a new filter needs to be set up */
1970 if (p_inq->state == BTM_INQ_CLR_FILT_STATE)
1971 {
1972 if ((status = btm_set_inq_event_filter (p_inq->inqparms.filter_cond_type, &p_inq->inqparms.filter_cond)) == BTM_CMD_STARTED)
1973 {
1974 p_inq->state = BTM_INQ_SET_FILT_STATE;
1975 }
1976 else /* Error setting the filter: Call the initiator's callback function to indicate a failure */
1977 {
1978 p_inq->inqfilt_active = FALSE;
1979
1980 /* Process the inquiry complete (Error Status) */
1981 btm_process_inq_complete (BTM_ERR_PROCESSING, (UINT8)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
1982 }
1983 }
1984 else /* Initiate the Inquiry or Periodic Inquiry */
1985 {
1986 p_inq->state = BTM_INQ_ACTIVE_STATE;
1987 p_inq->inqfilt_active = FALSE;
1988 btm_initiate_inquiry (p_inq);
1989 }
1990 }
1991 }
1992}
1993
1994
1995/*******************************************************************************
1996**
1997** Function btm_initiate_inquiry
1998**
1999** Description This function is called to start an inquiry or periodic inquiry
2000** upon completion of the setting and/or clearing of the inquiry filter.
2001**
2002** Inputs: p_inq (btm_cb.btm_inq_vars) - pointer to saved inquiry information
2003** mode - GENERAL or LIMITED inquiry
2004** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED)
2005** max_resps - maximum amount of devices to search for before ending the inquiry
2006** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or
2007** BTM_FILTER_COND_BD_ADDR
2008** filter_cond - value for the filter (based on filter_cond_type)
2009**
2010** Returns If an error occurs the initiator's callback is called with the error status.
2011**
2012*******************************************************************************/
2013static void btm_initiate_inquiry (tBTM_INQUIRY_VAR_ST *p_inq)
2014{
2015 const LAP *lap;
2016 tBTM_INQ_PARMS *p_inqparms = &p_inq->inqparms;
2017
2018#if (BTM_INQ_DEBUG == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002019 BTM_TRACE_DEBUG ("btm_initiate_inquiry: inq_active:0x%x state:%d inqfilt_active:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002020 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
2021#endif
2022#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2023 btm_acl_update_busy_level (BTM_BLI_INQ_EVT);
2024#endif
2025
2026 if (p_inq->inq_active & BTM_SSP_INQUIRY_ACTIVE)
2027 {
2028 btm_process_inq_complete (BTM_NO_RESOURCES, (UINT8)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
2029 return;
2030 }
2031
2032 /* Make sure the number of responses doesn't overflow the database configuration */
2033 p_inqparms->max_resps = (UINT8)((p_inqparms->max_resps <= BTM_INQ_DB_SIZE) ? p_inqparms->max_resps : BTM_INQ_DB_SIZE);
2034
2035 lap = (p_inq->inq_active & BTM_LIMITED_INQUIRY_ACTIVE) ? &limited_inq_lap : &general_inq_lap;
2036
2037 if (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)
2038 {
2039 if (!btsnd_hcic_per_inq_mode (p_inq->per_max_delay,
2040 p_inq->per_min_delay,
2041 *lap, p_inqparms->duration,
2042 p_inqparms->max_resps))
2043 btm_process_inq_complete (BTM_NO_RESOURCES, (UINT8)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
2044 }
2045 else
2046 {
2047#if BTM_USE_INQ_RESULTS_FILTER == TRUE
2048 btm_clr_inq_result_flt();
2049
2050 /* Allocate memory to hold bd_addrs responding */
2051 if ((p_inq->p_bd_db = (tINQ_BDADDR *)GKI_getbuf(GKI_MAX_BUF_SIZE)) != NULL)
2052 {
2053 p_inq->max_bd_entries = (UINT16)(GKI_MAX_BUF_SIZE / sizeof(tINQ_BDADDR));
2054 memset(p_inq->p_bd_db, 0, GKI_MAX_BUF_SIZE);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002055/* BTM_TRACE_DEBUG("btm_initiate_inquiry: memory allocated for %d bdaddrs",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002056 p_inq->max_bd_entries); */
2057 }
2058
2059 if (!btsnd_hcic_inquiry(*lap, p_inqparms->duration, 0))
2060#else
2061 if (!btsnd_hcic_inquiry(*lap, p_inqparms->duration, p_inqparms->max_resps))
2062#endif /* BTM_USE_INQ_RESULTS_FILTER */
2063 btm_process_inq_complete (BTM_NO_RESOURCES, (UINT8)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
2064 }
2065}
2066
2067/*******************************************************************************
2068**
2069** Function btm_process_inq_results
2070**
2071** Description This function is called when inquiry results are received from
2072** the device. It updates the inquiry database. If the inquiry
2073** database is full, the oldest entry is discarded.
2074**
2075** Parameters inq_res_mode - BTM_INQ_RESULT_STANDARD
2076** BTM_INQ_RESULT_WITH_RSSI
2077** BTM_INQ_RESULT_EXTENDED
2078**
2079** Returns void
2080**
2081*******************************************************************************/
2082void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
2083{
2084 UINT8 num_resp, xx;
2085 BD_ADDR bda;
2086 tINQ_DB_ENT *p_i;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002087 tBTM_INQ_RESULTS *p_cur=NULL;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002088 BOOLEAN is_new = TRUE;
2089 BOOLEAN update = FALSE;
2090 INT8 i_rssi;
2091 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2092 tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb;
2093 UINT8 page_scan_rep_mode = 0;
2094 UINT8 page_scan_per_mode = 0;
2095 UINT8 page_scan_mode = 0;
2096 UINT8 rssi = 0;
2097 DEV_CLASS dc;
2098 UINT16 clock_offset;
2099#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2100 UINT8 *p_eir_data = NULL;
2101#if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2102 UINT8 remote_name_len;
2103#endif
2104#endif
2105
2106#if (BTM_INQ_DEBUG == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002107 BTM_TRACE_DEBUG ("btm_process_inq_results inq_active:0x%x state:%d inqfilt_active:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002108 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
2109#endif
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002110 /* Only process the results if the BR inquiry is still active */
2111 if (!(p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002112 return;
2113
2114 STREAM_TO_UINT8 (num_resp, p);
2115
2116 for (xx = 0; xx < num_resp; xx++)
2117 {
2118 update = FALSE;
2119 /* Extract inquiry results */
2120 STREAM_TO_BDADDR (bda, p);
2121 STREAM_TO_UINT8 (page_scan_rep_mode, p);
2122 STREAM_TO_UINT8 (page_scan_per_mode, p);
2123
2124 if (inq_res_mode == BTM_INQ_RESULT_STANDARD)
2125 {
2126 STREAM_TO_UINT8(page_scan_mode, p);
2127 }
2128
2129 STREAM_TO_DEVCLASS (dc, p);
2130 STREAM_TO_UINT16 (clock_offset, p);
2131 if (inq_res_mode != BTM_INQ_RESULT_STANDARD)
2132 {
2133 STREAM_TO_UINT8(rssi, p);
2134 }
2135
2136 p_i = btm_inq_db_find (bda);
2137
2138#if BTM_USE_INQ_RESULTS_FILTER == TRUE
2139 /* Only process the num_resp is smaller than max_resps.
2140 If results are queued to BTU task while canceling inquiry,
2141 or when more than one result is in this response, > max_resp
2142 responses could be processed which can confuse some apps
2143 */
2144 if (p_inq->inqparms.max_resps &&
2145 p_inq->inq_cmpl_info.num_resp >= p_inq->inqparms.max_resps
2146#if BLE_INCLUDED == TRUE
2147 /* new device response */
2148 && ( p_i == NULL ||
2149 /* exisiting device with BR/EDR info */
2150 (p_i && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)
2151 )
2152#endif
2153
2154 )
2155 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002156/* BTM_TRACE_WARNING("INQ RES: Extra Response Received...ignoring"); */
The Android Open Source Project5738f832012-12-12 16:00:35 -08002157 return;
2158 }
2159#endif
2160
2161 /* Check if this address has already been processed for this inquiry */
2162 if (btm_inq_find_bdaddr(bda))
2163 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002164/* BTM_TRACE_DEBUG("BDA seen before [%02x%02x %02x%02x %02x%02x]",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002165 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);*/
2166 /* By default suppose no update needed */
2167 i_rssi = (INT8)rssi;
2168
2169 /* If this new RSSI is higher than the last one */
2170 if(p_inq->inqparms.report_dup && (rssi != 0) &&
2171 p_i && (i_rssi > p_i->inq_info.results.rssi || p_i->inq_info.results.rssi == 0
2172#if BLE_INCLUDED == TRUE
2173 /* BR/EDR inquiry information update */
2174 || (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0
2175#endif
2176 ))
2177 {
2178 p_cur = &p_i->inq_info.results;
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002179 BTM_TRACE_DEBUG("update RSSI new:%d, old:%d", i_rssi, p_cur->rssi);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002180 p_cur->rssi = i_rssi;
2181 update = TRUE;
2182 }
2183 /* If we received a second Extended Inq Event for an already */
2184 /* discovered device, this is because for the first one EIR was not received */
2185 else if ((inq_res_mode == BTM_INQ_RESULT_EXTENDED) && (p_i))
2186 {
2187 p_cur = &p_i->inq_info.results;
2188 update = TRUE;
2189 }
2190 /* If no update needed continue with next response (if any) */
2191 else
2192 continue;
2193 }
2194
2195 /* Host can be registered to verify comming BDA or DC */
2196 if (btm_cb.p_inq_filter_cb)
2197 {
2198 if (!(* btm_cb.p_inq_filter_cb) (bda, dc))
2199 {
2200 continue;
2201 }
2202 }
2203
2204 /* If existing entry, use that, else get a new one (possibly reusing the oldest) */
2205 if (p_i == NULL)
2206 {
2207 p_i = btm_inq_db_new (bda);
2208 is_new = TRUE;
2209 }
2210
2211 /* If an entry for the device already exists, overwrite it ONLY if it is from
2212 a previous inquiry. (Ignore it if it is a duplicate response from the same
2213 inquiry.
2214 */
2215 else if (p_i->inq_count == p_inq->inq_counter
2216#if (BLE_INCLUDED == TRUE )
Nitin Arora6c54d5a2014-01-22 10:33:26 -08002217 && (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BREDR)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002218#endif
2219 )
2220 is_new = FALSE;
2221
2222 /* keep updating RSSI to have latest value */
2223 if( inq_res_mode != BTM_INQ_RESULT_STANDARD )
2224 p_i->inq_info.results.rssi = (INT8)rssi;
2225 else
2226 p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI;
2227
2228 if (is_new == TRUE)
2229 {
2230 /* Save the info */
2231 p_cur = &p_i->inq_info.results;
2232 p_cur->page_scan_rep_mode = page_scan_rep_mode;
2233 p_cur->page_scan_per_mode = page_scan_per_mode;
2234 p_cur->page_scan_mode = page_scan_mode;
2235 p_cur->dev_class[0] = dc[0];
2236 p_cur->dev_class[1] = dc[1];
2237 p_cur->dev_class[2] = dc[2];
2238 p_cur->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
2239
Pramod Sivaraman9b661c52014-03-07 18:30:48 +05302240 BTM_TRACE_WARNING ("btm_process_inq_results: BDA: %02x-%02x-%02x-%02x-%02x-%02x",
2241 bda[0], bda[1], bda[2],bda[3], bda[4], bda[5]);
2242
2243 BTM_TRACE_WARNING ("btm_process_inq_results: Dev class: %02x-%02x-%02x",
2244 p_cur->dev_class[0], p_cur->dev_class[1], p_cur->dev_class[2]);
2245
The Android Open Source Project5738f832012-12-12 16:00:35 -08002246 p_i->time_of_resp = GKI_get_tick_count ();
2247
2248 if (p_i->inq_count != p_inq->inq_counter)
2249 p_inq->inq_cmpl_info.num_resp++; /* A new response was found */
2250
2251#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
2252 p_cur->inq_result_type = BTM_INQ_RESULT_BR;
2253 if (p_i->inq_count != p_inq->inq_counter)
2254 {
2255 p_cur->device_type = BT_DEVICE_TYPE_BREDR;
2256 p_i->scan_rsp = FALSE;
2257 }
2258 else
2259 p_cur->device_type |= BT_DEVICE_TYPE_BREDR;
2260#endif
2261 p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */
2262
2263#if BTM_USE_INQ_RESULTS_FILTER == TRUE
2264 /* If the number of responses found and not unlimited, issue a cancel inquiry */
2265 if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) &&
2266 p_inq->inqparms.max_resps &&
2267 p_inq->inq_cmpl_info.num_resp == p_inq->inqparms.max_resps
2268#if BLE_INCLUDED == TRUE
2269 /* BLE scanning is active and received adv */
2270 && ((((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) &&
2271 p_cur->device_type == BT_DEVICE_TYPE_DUMO && p_i->scan_rsp) ||
2272 (p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) == 0)
2273#endif
2274 )
2275 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002276/* BTM_TRACE_DEBUG("BTMINQ: Found devices, cancelling inquiry..."); */
The Android Open Source Project5738f832012-12-12 16:00:35 -08002277 btsnd_hcic_inq_cancel();
2278
2279#if BLE_INCLUDED == TRUE
2280 if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002281 btm_ble_stop_inquiry();
The Android Open Source Project5738f832012-12-12 16:00:35 -08002282#endif
2283
2284
2285#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2286 btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
2287#endif
2288 }
2289#endif
2290 /* Initialize flag to FALSE. This flag is set/used by application */
2291 p_i->inq_info.appl_knows_rem_name = FALSE;
2292 }
2293
2294 if (is_new || update)
2295 {
2296#if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2297#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2298 if( inq_res_mode == BTM_INQ_RESULT_EXTENDED )
2299 {
2300 if((p_eir_data = BTM_CheckEirData( p, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE,
2301 &remote_name_len )) == NULL)
2302 {
2303 p_eir_data = BTM_CheckEirData( p, BTM_EIR_SHORTENED_LOCAL_NAME_TYPE,
2304 &remote_name_len );
2305 }
2306
2307 if( p_eir_data )
2308 {
2309 if( remote_name_len > BTM_MAX_REM_BD_NAME_LEN )
2310 remote_name_len = BTM_MAX_REM_BD_NAME_LEN;
2311
2312 p_i->inq_info.remote_name_len = remote_name_len;
2313 memcpy( p_i->inq_info.remote_name, p_eir_data, p_i->inq_info.remote_name_len );
2314 p_i->inq_info.remote_name[p_i->inq_info.remote_name_len] = 0;
2315 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_DONE;
2316 }
2317 else
2318 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
2319 }
2320 else
2321#endif
2322 {
2323 /* Clear out the device name so that it can be re-read */
2324 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
2325 }
2326#endif /*(BTM_INQ_GET_REMOTE_NAME==TRUE)*/
2327
2328#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2329 if( inq_res_mode == BTM_INQ_RESULT_EXTENDED )
2330 {
2331 memset( p_cur->eir_uuid, 0,
2332 BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS/8));
2333 /* set bit map of UUID list from received EIR */
2334 btm_set_eir_uuid( p, p_cur );
2335 p_eir_data = p;
2336 }
2337 else
2338 p_eir_data = NULL;
2339#endif
2340
2341 /* If a callback is registered, call it with the results */
2342 if (p_inq_results_cb)
2343#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2344 (p_inq_results_cb)((tBTM_INQ_RESULTS *) p_cur, p_eir_data);
2345#else
2346 (p_inq_results_cb)((tBTM_INQ_RESULTS *) p_cur, NULL);
2347#endif
2348
2349 /* If anyone is registered for change notifications, then tell him we added an entry. */
2350 if (p_inq->p_inq_change_cb)
2351 (*p_inq->p_inq_change_cb) (&p_i->inq_info, TRUE);
2352 }
2353 }
2354}
2355
2356/*******************************************************************************
2357**
2358** Function btm_sort_inq_result
2359**
2360** Description This function is called when inquiry complete is received
2361** from the device to sort inquiry results based on rssi.
2362**
2363** Returns void
2364**
2365*******************************************************************************/
2366void btm_sort_inq_result(void)
2367{
2368 UINT8 xx, yy, num_resp;
2369 tINQ_DB_ENT *p_tmp = NULL;
2370 tINQ_DB_ENT *p_ent = btm_cb.btm_inq_vars.inq_db;
2371 tINQ_DB_ENT *p_next = btm_cb.btm_inq_vars.inq_db+1;
2372 int size;
2373
2374 num_resp = (btm_cb.btm_inq_vars.inq_cmpl_info.num_resp<BTM_INQ_DB_SIZE)?
2375 btm_cb.btm_inq_vars.inq_cmpl_info.num_resp: BTM_INQ_DB_SIZE;
2376
2377 if((p_tmp = (tINQ_DB_ENT *)GKI_getbuf(sizeof(tINQ_DB_ENT))) != NULL)
2378 {
2379 size = sizeof(tINQ_DB_ENT);
2380 for(xx = 0; xx < num_resp-1; xx++, p_ent++)
2381 {
2382 for(yy = xx+1, p_next = p_ent+1; yy < num_resp; yy++, p_next++)
2383 {
2384 if(p_ent->inq_info.results.rssi < p_next->inq_info.results.rssi)
2385 {
2386 memcpy (p_tmp, p_next, size);
2387 memcpy (p_next, p_ent, size);
2388 memcpy (p_ent, p_tmp, size);
2389 }
2390 }
2391 }
2392
2393 GKI_freebuf(p_tmp);
2394 }
2395}
2396
2397/*******************************************************************************
2398**
2399** Function btm_process_inq_complete
2400**
2401** Description This function is called when inquiry complete is received
2402** from the device. Call the callback if not in periodic inquiry
2403** mode AND it is not NULL (The caller wants the event).
2404**
2405** The callback pass back the status and the number of responses
2406**
2407** Returns void
2408**
2409*******************************************************************************/
2410void btm_process_inq_complete (UINT8 status, UINT8 mode)
2411{
2412 tBTM_CMPL_CB *p_inq_cb = btm_cb.btm_inq_vars.p_inq_cmpl_cb;
2413 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2414
2415#if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2416 tBTM_INQ_INFO *p_cur;
2417 UINT8 tempstate;
2418#endif
Matthew Xie7f3e4292013-09-30 12:44:10 -07002419#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
2420 /* inquiry inactive case happens when inquiry is cancelled.
2421 Make mode 0 for no further inquiries from the current inquiry process
2422 */
2423 if(status!=HCI_SUCCESS || p_inq->next_state==BTM_FINISH || !p_inq->inq_active)
2424 {
2425 /* re-initialize for next inquiry request */
2426 p_inq->next_state=BTM_BR_ONE;
2427 /* make the mode 0 here */
2428 p_inq->inqparms.mode &= ~(p_inq->inqparms.mode);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002429
Matthew Xie7f3e4292013-09-30 12:44:10 -07002430 }
2431#endif
2432
2433#if (!defined(BTA_HOST_INTERLEAVE_SEARCH) || BTA_HOST_INTERLEAVE_SEARCH == FALSE)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002434 p_inq->inqparms.mode &= ~(mode);
Matthew Xie7f3e4292013-09-30 12:44:10 -07002435#endif
2436
Nitin Arora0830ad42014-02-21 18:20:37 -08002437 if(p_inq->scan_type == INQ_LE_OBSERVE && !p_inq->inq_active)
2438 {
2439 /*end of LE observe*/
2440 p_inq->p_inq_ble_results_cb = (tBTM_INQ_RESULTS_CB *) NULL;
2441 p_inq->p_inq_ble_cmpl_cb = (tBTM_CMPL_CB *) NULL;
2442 p_inq->scan_type=INQ_NONE;
2443 }
Matthew Xie7f3e4292013-09-30 12:44:10 -07002444
The Android Open Source Project5738f832012-12-12 16:00:35 -08002445
2446#if (BTM_INQ_DEBUG == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002447 BTM_TRACE_DEBUG ("btm_process_inq_complete inq_active:0x%x state:%d inqfilt_active:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002448 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
2449#endif
2450#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2451 btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
2452#endif
2453 /* Ignore any stray or late complete messages if the inquiry is not active */
2454 if (p_inq->inq_active)
2455 {
2456 p_inq->inq_cmpl_info.status = (tBTM_STATUS)((status == HCI_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING);
2457
2458#if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2459 if (p_inq->inq_cmpl_info.status == BTM_SUCCESS)
2460 {
2461 for (p_cur = BTM_InqDbFirst(); p_cur; p_cur = BTM_InqDbNext (p_cur))
2462 {
2463 if (p_cur->remote_name_state == BTM_INQ_RMT_NAME_EMPTY)
2464 {
2465 tempstate = p_cur->remote_name_state;
2466 p_cur->remote_name_state = BTM_INQ_RMT_NAME_PENDING;
2467
2468 if (btm_initiate_rem_name (p_cur->results.remote_bd_addr,
2469 p_cur, BTM_RMT_NAME_INQ,
2470 BTM_INQ_RMT_NAME_TIMEOUT, NULL) != BTM_CMD_STARTED)
2471 p_cur->remote_name_state = tempstate;
2472 else
2473 return;
2474 }
2475 }
2476 }
2477#endif
2478
2479 /* Notify caller that the inquiry has completed; (periodic inquiries do not send completion events */
2480 if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) && p_inq->inqparms.mode == 0)
2481 {
2482 p_inq->state = BTM_INQ_INACTIVE_STATE;
2483
2484 /* Increment so the start of a next inquiry has a new count */
2485 p_inq->inq_counter++;
2486
2487 btm_clr_inq_result_flt();
2488
Andre Eisenbach3aa60542013-03-22 18:00:51 -07002489 if((p_inq->inq_cmpl_info.status == BTM_SUCCESS) &&
2490 HCI_LMP_INQ_RSSI_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002491 {
2492 btm_sort_inq_result();
2493 }
2494
2495 /* Clear the results callback if set */
2496 p_inq->p_inq_results_cb = (tBTM_INQ_RESULTS_CB *) NULL;
2497 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
2498 p_inq->p_inq_cmpl_cb = (tBTM_CMPL_CB *) NULL;
2499
2500 /* If we have a callback registered for inquiry complete, call it */
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002501 BTM_TRACE_DEBUG ("BTM Inq Compl Callback: status 0x%02x, num results %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002502 p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp);
2503
2504 if (p_inq_cb)
2505 (p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info);
2506 }
Matthew Xie7f3e4292013-09-30 12:44:10 -07002507#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002508 if(p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE))
2509 {
2510 /* make inquiry inactive for next iteration */
2511 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
2512 /* call the inquiry again */
2513 BTM_StartInquiry(&p_inq->inqparms,p_inq->p_inq_results_cb,p_inq->p_inq_cmpl_cb);
2514 }
Matthew Xie7f3e4292013-09-30 12:44:10 -07002515#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -08002516 }
Nitin Arora0830ad42014-02-21 18:20:37 -08002517 if(p_inq->inqparms.mode == 0 && p_inq->scan_type == INQ_GENERAL)//this inquiry is complete
2518 {
2519 p_inq->scan_type = INQ_NONE;
2520#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
2521 /* check if the LE observe is pending */
2522 if(p_inq->p_inq_ble_results_cb != NULL)
2523 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002524 BTM_TRACE_DEBUG("BTM Inq Compl: resuming a pending LE scan");
Nitin Arora0830ad42014-02-21 18:20:37 -08002525 BTM_BleObserve(1,0, p_inq->p_inq_ble_results_cb, p_inq->p_inq_ble_cmpl_cb);
2526 }
2527#endif
2528 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002529#if (BTM_INQ_DEBUG == TRUE)
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002530 BTM_TRACE_DEBUG ("inq_active:0x%x state:%d inqfilt_active:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002531 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
2532#endif
2533}
2534
2535/*******************************************************************************
2536**
2537** Function btm_process_cancel_complete
2538**
2539** Description This function is called when inquiry cancel complete is received
2540** from the device.This function will also call the btm_process_inq_complete
2541** This function is needed to differentiate a cancel_cmpl_evt from the
2542** inq_cmpl_evt
2543**
2544** Returns void
2545**
2546*******************************************************************************/
2547void btm_process_cancel_complete(UINT8 status, UINT8 mode)
2548{
2549#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2550 btm_acl_update_busy_level (BTM_BLI_INQ_CANCEL_EVT);
2551#endif
2552 btm_process_inq_complete(status, mode);
2553}
2554/*******************************************************************************
2555**
2556** Function btm_initiate_rem_name
2557**
2558** Description This function looks initiates a remote name request. It is called
2559** either by GAP or by the API call BTM_ReadRemoteDeviceName.
2560**
2561** Input Params: p_cur - pointer to an inquiry result structure (NULL if nonexistent)
2562** p_cb - callback function called when BTM_CMD_STARTED
2563** is returned.
2564** A pointer to tBTM_REMOTE_DEV_NAME is passed to the
2565** callback.
2566**
2567** Returns
2568** BTM_CMD_STARTED is returned if the request was sent to HCI.
2569** BTM_BUSY if already in progress
2570** BTM_NO_RESOURCES if could not allocate resources to start the command
2571** BTM_WRONG_MODE if the device is not up.
2572**
2573*******************************************************************************/
2574tBTM_STATUS btm_initiate_rem_name (BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur,
2575 UINT8 origin, UINT32 timeout, tBTM_CMPL_CB *p_cb)
2576{
2577 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2578 BOOLEAN cmd_ok;
2579
2580
2581 /*** Make sure the device is ready ***/
2582 if (!BTM_IsDeviceUp())
2583 return (BTM_WRONG_MODE);
2584
2585
2586 if (origin == BTM_RMT_NAME_SEC)
2587 {
2588 cmd_ok = btsnd_hcic_rmt_name_req (remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
2589 HCI_MANDATARY_PAGE_SCAN_MODE, 0);
2590 if (cmd_ok)
2591 return BTM_CMD_STARTED;
2592 else
2593 return BTM_NO_RESOURCES;
2594 }
2595 /* Make sure there are no two remote name requests from external API in progress */
2596 else if (origin == BTM_RMT_NAME_EXT)
2597 {
2598 if (p_inq->remname_active)
2599 {
2600 return (BTM_BUSY);
2601 }
2602 else
2603 {
2604 /* If there is no remote name request running,call the callback function and start timer */
2605 p_inq->p_remname_cmpl_cb = p_cb;
2606 memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
2607 btu_start_timer (&p_inq->rmt_name_timer_ent,
2608 BTU_TTYPE_BTM_RMT_NAME,
2609 timeout);
2610
2611 /* If the database entry exists for the device, use its clock offset */
2612 if (p_cur)
2613 {
2614 cmd_ok = btsnd_hcic_rmt_name_req (remote_bda,
2615 p_cur->results.page_scan_rep_mode,
2616 p_cur->results.page_scan_mode,
2617 (UINT16)(p_cur->results.clock_offset |
2618 BTM_CLOCK_OFFSET_VALID));
2619 }
2620 else /* Otherwise use defaults and mark the clock offset as invalid */
2621 {
2622 cmd_ok = btsnd_hcic_rmt_name_req (remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
2623 HCI_MANDATARY_PAGE_SCAN_MODE, 0);
2624 }
2625 if (cmd_ok)
2626 {
2627 p_inq->remname_active = TRUE;
2628 return BTM_CMD_STARTED;
2629 }
2630 else
2631 return BTM_NO_RESOURCES;
2632 }
2633 }
2634 /* If the inquire feature is on */
2635#if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2636
2637 else if (origin == BTM_RMT_NAME_INQ)
2638 {
2639 /* If the database entry exists for the device, use its clock offset */
2640 if (p_cur)
2641 {
2642 cmd_ok = btsnd_hcic_rmt_name_req (remote_bda,
2643 p_cur->results.page_scan_rep_mode,
2644 p_cur->results.page_scan_mode,
2645 (UINT16)(p_cur->results.clock_offset |
2646 BTM_CLOCK_OFFSET_VALID));
2647 }
2648 else
2649 {
2650 cmd_ok = FALSE
2651 }
2652
2653 if (cmd_ok)
2654 return BTM_CMD_STARTED;
2655 else
2656 return BTM_NO_RESOURCES;
2657 }
2658#endif
2659 else
2660 {
2661
2662 return BTM_ILLEGAL_VALUE;
2663
2664
2665 }
2666
2667
2668}
2669
2670/*******************************************************************************
2671**
2672** Function btm_process_remote_name
2673**
2674** Description This function is called when a remote name is received from
2675** the device. If remote names are cached, it updates the inquiry
2676** database.
2677**
2678** Returns void
2679**
2680*******************************************************************************/
2681void btm_process_remote_name (BD_ADDR bda, BD_NAME bdn, UINT16 evt_len, UINT8 hci_status)
2682{
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002683 tBTM_REMOTE_DEV_NAME rem_name;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002684 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2685 tBTM_CMPL_CB *p_cb = p_inq->p_remname_cmpl_cb;
2686 UINT8 *p_n1;
2687
2688 UINT16 temp_evt_len;
2689
2690#if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2691 /*** These are only used if part of the Inquiry Process ***/
2692 tBTM_CMPL_CB *p_inq_cb;
2693 tINQ_DB_ENT *p_i = NULL;
2694 UINT8 *p_n;
2695 tBTM_INQ_INFO *p_cur;
2696#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -08002697
2698 if (bda != NULL)
2699 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002700 BTM_TRACE_EVENT("BDA %02x:%02x:%02x:%02x:%02x:%02x",bda[0], bda[1],
The Android Open Source Project5738f832012-12-12 16:00:35 -08002701 bda[2], bda[3],
2702 bda[4], bda[5]);
2703 }
2704
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002705 BTM_TRACE_EVENT("Inquire BDA %02x:%02x:%02x:%02x:%02x:%02x",p_inq->remname_bda[0], p_inq->remname_bda[1],
The Android Open Source Project5738f832012-12-12 16:00:35 -08002706 p_inq->remname_bda[2], p_inq->remname_bda[3],
2707 p_inq->remname_bda[4], p_inq->remname_bda[5]);
2708
2709
2710
2711 /* If the inquire BDA and remote DBA are the same, then stop the timer and set the active to false */
2712 if ((p_inq->remname_active ==TRUE)&&
2713 (((bda != NULL) &&
2714 (memcmp(bda, p_inq->remname_bda,BD_ADDR_LEN)==0)) || bda == NULL))
2715
2716 {
2717#if BLE_INCLUDED == TRUE
Andre Eisenbach6975b4d2013-08-05 16:55:38 -07002718 if (BTM_UseLeLink(p_inq->remname_bda))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002719 {
2720 if (hci_status == HCI_ERR_UNSPECIFIED)
2721 btm_ble_cancel_remote_name(p_inq->remname_bda);
2722 }
2723#endif
2724 btu_stop_timer (&p_inq->rmt_name_timer_ent);
2725 p_inq->remname_active = FALSE;
2726 /* Clean up and return the status if the command was not successful */
2727 /* Note: If part of the inquiry, the name is not stored, and the */
2728 /* inquiry complete callback is called. */
2729
2730 if ((hci_status == HCI_SUCCESS))
2731 {
2732 /* Copy the name from the data stream into the return structure */
2733 /* Note that even if it is not being returned, it is used as a */
2734 /* temporary buffer. */
2735 p_n1 = (UINT8 *)rem_name.remote_bd_name;
2736 rem_name.length = (evt_len < BD_NAME_LEN) ? evt_len : BD_NAME_LEN;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002737 rem_name.remote_bd_name[rem_name.length] = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002738 rem_name.status = BTM_SUCCESS;
2739 temp_evt_len = rem_name.length;
2740
2741 while (temp_evt_len > 0)
2742 {
2743 *p_n1++ = *bdn++;
2744 temp_evt_len--;
2745 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002746 rem_name.remote_bd_name[rem_name.length] = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002747 }
2748
2749
2750 /* If processing a stand alone remote name then report the error in the callback */
2751 else
2752 {
2753 rem_name.status = BTM_BAD_VALUE_RET;
2754 rem_name.length = 0;
2755 rem_name.remote_bd_name[0] = 0;
2756 }
2757 /* Reset the remote BAD to zero and call callback if possible */
2758 memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
2759
2760 p_inq->p_remname_cmpl_cb = NULL;
2761 if (p_cb)
2762 (p_cb)((tBTM_REMOTE_DEV_NAME *)&rem_name);
2763 }
2764
2765
2766#if (BTM_INQ_GET_REMOTE_NAME==TRUE)
2767 /* If existing entry, update the name */
2768 if ((bda != NULL) && ((p_i = btm_inq_db_find (bda)) != NULL)
2769 && (hci_status == HCI_SUCCESS))
2770 {
2771 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_DONE;
2772 p_n = p_i->inq_info.remote_name;
2773 memset(p_n, 0, BTM_MAX_REM_BD_NAME_LEN + 1);
2774 p_i->inq_info.remote_name_len = (rem_name.length < BTM_MAX_REM_BD_NAME_LEN) ?
2775 rem_name.length : BTM_MAX_REM_BD_NAME_LEN;
2776 evt_len = p_i->inq_info.remote_name_len;
2777 p_n1 = (UINT8 *)rem_name.remote_bd_name;
2778 while (evt_len > 0)
2779 {
2780 *p_n++ = *p_n1++;
2781 evt_len--;
2782 }
2783
2784 if (btm_cb.btm_inq_vars.p_inq_change_cb)
2785 (*btm_cb.btm_inq_vars.p_inq_change_cb) (&p_i->inq_info, TRUE);
2786 }
2787 else
2788 {
2789 if (p_i)
2790 p_i->inq_info.remote_name_state = BTM_INQ_RMT_NAME_FAILED;
2791 else
2792 {
2793 /* Find the entry which is currently doing name request */
2794 for (p_cur = BTM_InqDbFirst(); p_cur; p_cur = BTM_InqDbNext (p_cur))
2795 {
2796 if (p_cur->remote_name_state == BTM_INQ_RMT_NAME_PENDING)
2797 {
2798 /* Should be only one */
2799 p_cur->remote_name_state = BTM_INQ_RMT_NAME_FAILED;
2800 break;
2801 }
2802 }
2803 }
2804 }
2805
2806 /* If an inquiry is in progress then update other entries */
2807 if (p_inq->inq_active)
2808 {
2809 /* Check if there are any more entries inquired but not named */
2810 for (p_cur = BTM_InqDbFirst(); p_cur; p_cur = BTM_InqDbNext (p_cur))
2811 {
2812 if (p_cur->remote_name_state == BTM_INQ_RMT_NAME_EMPTY)
2813 {
2814 p_cur->remote_name_state = BTM_INQ_RMT_NAME_PENDING;
2815#if (BLE_INCLUDED == TRUE)
Andre Eisenbach6975b4d2013-08-05 16:55:38 -07002816 if (BTM_UseLeLink(remote_bda))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002817 {
2818 if (btm_ble_read_remote_name(remote_bda, p_cur, p_cb) != BTM_CMD_STARTED)
2819 p_cur->remote_name_state = BTM_INQ_RMT_NAME_FAILED;
2820 else
2821 return;
2822 }
2823 else
2824#endif
2825 {
2826 if (btm_initiate_rem_name (p_cur->results.remote_bd_addr,
2827 p_cur, BTM_RMT_NAME_INQ,
2828 BTM_INQ_RMT_NAME_TIMEOUT, NULL) != BTM_CMD_STARTED)
2829 p_cur->remote_name_state = BTM_INQ_RMT_NAME_FAILED;
2830 else
2831 return;
2832 }
2833 }
2834 }
2835
2836 /* The inquiry has finished so call the callback for the inquiry */
2837 p_inq_cb = p_inq->p_inq_cmpl_cb;
2838 p_inq->state = BTM_INQ_INACTIVE_STATE;
2839 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
2840 p_inq->p_inq_cmpl_cb = NULL;
2841
2842 /* If we have a callback registered for inquiry complete, call it */
2843 if (p_inq_cb)
2844 (p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info);
2845
2846 /* In some cases we can not get name of the device once but will be */
2847 /* able to do it next time. Until we have better solution we will */
2848 /* try to get name every time */
2849 for (p_cur = BTM_InqDbFirst(); p_cur; p_cur = BTM_InqDbNext (p_cur))
2850 {
2851 if (p_cur->remote_name_state == BTM_INQ_RMT_NAME_FAILED)
2852 p_cur->remote_name_state = BTM_INQ_RMT_NAME_EMPTY;
2853 }
2854 }
2855#endif /* BTM_INQ_GET_REMOTE_NAME == TRUE */
2856}
2857
2858/*******************************************************************************
2859**
2860** Function btm_inq_rmt_name_failed
2861**
2862** Description This function is if timeout expires while getting remote
2863** name. This is done for devices that incorrectly do not
2864** report operation failure
2865**
2866** Returns void
2867**
2868*******************************************************************************/
2869void btm_inq_rmt_name_failed (void)
2870{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002871 BTM_TRACE_ERROR ("btm_inq_rmt_name_failed() remname_active=%d", btm_cb.btm_inq_vars.remname_active);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002872
2873 if (btm_cb.btm_inq_vars.remname_active)
2874 btm_process_remote_name (btm_cb.btm_inq_vars.remname_bda, NULL, 0, HCI_ERR_UNSPECIFIED);
2875 else
2876 btm_process_remote_name (NULL, NULL, 0, HCI_ERR_UNSPECIFIED);
2877
2878 btm_sec_rmt_name_request_complete (NULL, NULL, HCI_ERR_UNSPECIFIED);
2879}
2880/*******************************************************************************
2881**
2882** Function btm_read_linq_tx_power_complete
2883**
2884** Description read inquiry tx power level complete callback function.
2885**
2886** Returns void
2887**
2888*******************************************************************************/
2889void btm_read_linq_tx_power_complete(UINT8 *p)
2890{
2891 tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_txpwer_cmpl_cb;
2892 tBTM_INQ_TXPWR_RESULTS results;
2893
2894 btu_stop_timer (&btm_cb.devcb.txpwer_timer);
2895 /* If there was a callback registered for read inq tx power, call it */
2896 btm_cb.devcb.p_txpwer_cmpl_cb = NULL;
2897
2898 if (p_cb)
2899 {
2900 STREAM_TO_UINT8 (results.hci_status, p);
2901
2902 if (results.hci_status == HCI_SUCCESS)
2903 {
2904 results.status = BTM_SUCCESS;
2905
2906 STREAM_TO_UINT8 (results.tx_power, p);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002907 BTM_TRACE_EVENT ("BTM INQ TX POWER Complete: tx_power %d, hci status 0x%02x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002908 results.tx_power, results.hci_status);
2909 }
2910 else
2911 results.status = BTM_ERR_PROCESSING;
2912
2913 (*p_cb)(&results);
2914 }
2915
2916}
2917/*******************************************************************************
2918**
2919** Function BTM_WriteEIR
2920**
2921** Description This function is called to write EIR data to controller.
2922**
2923** Parameters p_buff - allocated HCI command buffer including extended
2924** inquriry response
2925**
2926** Returns BTM_SUCCESS - if successful
2927** BTM_MODE_UNSUPPORTED - if local device cannot support it
2928**
2929*******************************************************************************/
2930tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff )
2931{
2932#if (BTM_EIR_SERVER_INCLUDED == TRUE)
Andre Eisenbach3aa60542013-03-22 18:00:51 -07002933 if (HCI_EXT_INQ_RSP_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002934 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002935 BTM_TRACE_API("Write Extended Inquiry Response to controller");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002936 btsnd_hcic_write_ext_inquiry_response (p_buff, BTM_EIR_DEFAULT_FEC_REQUIRED);
2937 return BTM_SUCCESS;
2938 }
2939 else
2940 {
2941 GKI_freebuf(p_buff);
2942 return BTM_MODE_UNSUPPORTED;
2943 }
2944#else
2945 GKI_freebuf(p_buff);
2946 return BTM_SUCCESS;
2947#endif
2948}
2949
2950/*******************************************************************************
2951**
2952** Function BTM_CheckEirData
2953**
2954** Description This function is called to get EIR data from significant part.
2955**
2956** Parameters p_eir - pointer of EIR significant part
2957** type - finding EIR data type
2958** p_length - return the length of EIR data not including type
2959**
2960** Returns pointer of EIR data
2961**
2962*******************************************************************************/
2963UINT8 *BTM_CheckEirData( UINT8 *p_eir, UINT8 type, UINT8 *p_length )
2964{
2965#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2966 UINT8 *p = p_eir;
2967 UINT8 length;
2968 UINT8 eir_type;
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002969 BTM_TRACE_API("BTM_CheckEirData type=0x%02X", type);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002970
2971 STREAM_TO_UINT8(length, p);
2972 while( length && (p - p_eir <= HCI_EXT_INQ_RESPONSE_LEN))
2973 {
2974 STREAM_TO_UINT8(eir_type, p);
2975 if( eir_type == type )
2976 {
2977 /* length doesn't include itself */
2978 *p_length = length - 1; /* minus the length of type */
2979 return p;
2980 }
2981 p += length - 1; /* skip the length of data */
2982 STREAM_TO_UINT8(length, p);
2983 }
2984
2985 *p_length = 0;
2986 return NULL;
2987#else
2988 return NULL;
2989#endif
2990}
2991
2992/*******************************************************************************
2993**
2994** Function btm_convert_uuid_to_eir_service
2995**
2996** Description This function is called to get the bit position of UUID.
2997**
2998** Parameters uuid16 - UUID 16-bit
2999**
3000** Returns BTM EIR service ID if found
3001** BTM_EIR_MAX_SERVICES - if not found
3002**
3003*******************************************************************************/
3004#if (( BTM_EIR_CLIENT_INCLUDED == TRUE )||( BTM_EIR_SERVER_INCLUDED == TRUE ))
3005static UINT8 btm_convert_uuid_to_eir_service( UINT16 uuid16 )
3006{
3007 UINT8 xx;
3008
3009 for( xx = 0; xx < BTM_EIR_MAX_SERVICES; xx++ )
3010 {
3011 if( uuid16 == BTM_EIR_UUID_LKUP_TBL[xx])
3012 {
3013 return xx;
3014 }
3015 }
3016 return BTM_EIR_MAX_SERVICES;
3017}
3018#endif
3019
3020/*******************************************************************************
3021**
3022** Function BTM_HasEirService
3023**
3024** Description This function is called to know if UUID in bit map of UUID.
3025**
3026** Parameters p_eir_uuid - bit map of UUID list
3027** uuid16 - UUID 16-bit
3028**
3029** Returns TRUE - if found
3030** FALSE - if not found
3031**
3032*******************************************************************************/
3033BOOLEAN BTM_HasEirService( UINT32 *p_eir_uuid, UINT16 uuid16 )
3034{
3035#if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
3036 UINT8 service_id;
3037
3038 service_id = btm_convert_uuid_to_eir_service(uuid16);
3039 if( service_id < BTM_EIR_MAX_SERVICES )
3040 return( BTM_EIR_HAS_SERVICE( p_eir_uuid, service_id ));
3041 else
3042 return( FALSE );
3043#else
3044 return( FALSE );
3045#endif
3046}
3047
3048/*******************************************************************************
3049**
3050** Function BTM_HasInquiryEirService
3051**
3052** Description This function is called to know if UUID in bit map of UUID list.
3053**
3054** Parameters p_results - inquiry results
3055** uuid16 - UUID 16-bit
3056**
3057** Returns BTM_EIR_FOUND - if found
3058** BTM_EIR_NOT_FOUND - if not found and it is complete list
3059** BTM_EIR_UNKNOWN - if not found and it is not complete list
3060**
3061*******************************************************************************/
3062tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService( tBTM_INQ_RESULTS *p_results, UINT16 uuid16 )
3063{
3064#if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
3065 if( BTM_HasEirService( p_results->eir_uuid, uuid16 ))
3066 {
3067 return BTM_EIR_FOUND;
3068 }
3069 else if( p_results->eir_complete_list )
3070 {
3071 return BTM_EIR_NOT_FOUND;
3072 }
3073 else
3074 return BTM_EIR_UNKNOWN;
3075#else
3076 return BTM_EIR_UNKNOWN;
3077#endif
3078}
3079
3080/*******************************************************************************
3081**
3082** Function BTM_AddEirService
3083**
3084** Description This function is called to add a service in bit map of UUID list.
3085**
3086** Parameters p_eir_uuid - bit mask of UUID list for EIR
3087** uuid16 - UUID 16-bit
3088**
3089** Returns None
3090**
3091*******************************************************************************/
3092void BTM_AddEirService( UINT32 *p_eir_uuid, UINT16 uuid16 )
3093{
3094#if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
3095 UINT8 service_id;
3096
3097 service_id = btm_convert_uuid_to_eir_service(uuid16);
3098 if( service_id < BTM_EIR_MAX_SERVICES )
3099 BTM_EIR_SET_SERVICE( p_eir_uuid, service_id );
3100#endif
3101}
3102
3103/*******************************************************************************
3104**
3105** Function BTM_RemoveEirService
3106**
3107** Description This function is called to remove a service in bit map of UUID list.
3108**
3109** Parameters p_eir_uuid - bit mask of UUID list for EIR
3110** uuid16 - UUID 16-bit
3111**
3112** Returns None
3113**
3114*******************************************************************************/
3115void BTM_RemoveEirService( UINT32 *p_eir_uuid, UINT16 uuid16 )
3116{
3117#if (BTM_EIR_SERVER_INCLUDED == TRUE)
3118 UINT8 service_id;
3119
3120 service_id = btm_convert_uuid_to_eir_service(uuid16);
3121 if( service_id < BTM_EIR_MAX_SERVICES )
3122 BTM_EIR_CLR_SERVICE( p_eir_uuid, service_id );
3123#endif
3124}
3125
3126/*******************************************************************************
3127**
3128** Function BTM_GetEirSupportedServices
3129**
3130** Description This function is called to get UUID list from bit map of UUID list.
3131**
3132** Parameters p_eir_uuid - bit mask of UUID list for EIR
3133** p - reference of current pointer of EIR
3134** max_num_uuid16 - max number of UUID can be written in EIR
3135** num_uuid16 - number of UUID have been written in EIR
3136**
3137** Returns BTM_EIR_MORE_16BITS_UUID_TYPE, if it has more than max
3138** BTM_EIR_COMPLETE_16BITS_UUID_TYPE, otherwise
3139**
3140*******************************************************************************/
3141UINT8 BTM_GetEirSupportedServices( UINT32 *p_eir_uuid, UINT8 **p,
3142 UINT8 max_num_uuid16, UINT8 *p_num_uuid16)
3143{
3144#if (BTM_EIR_SERVER_INCLUDED == TRUE)
3145 UINT8 service_index;
3146
3147 *p_num_uuid16 = 0;
3148
3149 for(service_index = 0; service_index < BTM_EIR_MAX_SERVICES; service_index++)
3150 {
3151 if( BTM_EIR_HAS_SERVICE( p_eir_uuid, service_index ))
3152 {
3153 if( *p_num_uuid16 < max_num_uuid16 )
3154 {
3155 UINT16_TO_STREAM(*p, BTM_EIR_UUID_LKUP_TBL[service_index]);
3156 (*p_num_uuid16)++;
3157 }
3158 /* if max number of UUIDs are stored and found one more */
3159 else
3160 {
3161 return BTM_EIR_MORE_16BITS_UUID_TYPE;
3162 }
3163 }
3164 }
3165 return BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3166#else
3167 return BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3168#endif
3169}
3170
3171/*******************************************************************************
3172**
3173** Function BTM_GetEirUuidList
3174**
3175** Description This function parses EIR and returns UUID list.
3176**
3177** Parameters p_eir - EIR
3178** uuid_size - LEN_UUID_16, LEN_UUID_32, LEN_UUID_128
3179** p_num_uuid - return number of UUID in found list
3180** p_uuid_list - return UUID list
3181** max_num_uuid - maximum number of UUID to be returned
3182**
3183** Returns 0 - if not found
3184** BTM_EIR_COMPLETE_16BITS_UUID_TYPE
3185** BTM_EIR_MORE_16BITS_UUID_TYPE
3186** BTM_EIR_COMPLETE_32BITS_UUID_TYPE
3187** BTM_EIR_MORE_32BITS_UUID_TYPE
3188** BTM_EIR_COMPLETE_128BITS_UUID_TYPE
3189** BTM_EIR_MORE_128BITS_UUID_TYPE
3190**
3191*******************************************************************************/
3192UINT8 BTM_GetEirUuidList( UINT8 *p_eir, UINT8 uuid_size, UINT8 *p_num_uuid,
3193 UINT8 *p_uuid_list, UINT8 max_num_uuid)
3194{
3195#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
3196 UINT8 *p_uuid_data;
3197 UINT8 type;
3198 UINT8 yy, xx;
3199 UINT16 *p_uuid16 = (UINT16 *)p_uuid_list;
3200 UINT32 *p_uuid32 = (UINT32 *)p_uuid_list;
3201 char buff[LEN_UUID_128 * 2 + 1];
3202
3203 p_uuid_data = btm_eir_get_uuid_list( p_eir, uuid_size, p_num_uuid, &type );
3204 if( p_uuid_data == NULL )
3205 {
3206 return 0x00;
3207 }
3208
3209 if( *p_num_uuid > max_num_uuid )
3210 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003211 BTM_TRACE_WARNING("BTM_GetEirUuidList number of uuid in EIR = %d, size of uuid list = %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003212 *p_num_uuid, max_num_uuid );
3213 *p_num_uuid = max_num_uuid;
3214 }
3215
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003216 BTM_TRACE_DEBUG("BTM_GetEirUuidList type = %02X, number of uuid = %d", type, *p_num_uuid );
The Android Open Source Project5738f832012-12-12 16:00:35 -08003217
3218 if( uuid_size == LEN_UUID_16 )
3219 {
3220 for( yy = 0; yy < *p_num_uuid; yy++ )
3221 {
3222 STREAM_TO_UINT16(*(p_uuid16 + yy), p_uuid_data);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003223 BTM_TRACE_DEBUG(" 0x%04X", *(p_uuid16 + yy));
The Android Open Source Project5738f832012-12-12 16:00:35 -08003224 }
3225 }
3226 else if( uuid_size == LEN_UUID_32 )
3227 {
3228 for( yy = 0; yy < *p_num_uuid; yy++ )
3229 {
3230 STREAM_TO_UINT32(*(p_uuid32 + yy), p_uuid_data);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003231 BTM_TRACE_DEBUG(" 0x%08X", *(p_uuid32 + yy));
The Android Open Source Project5738f832012-12-12 16:00:35 -08003232 }
3233 }
3234 else if( uuid_size == LEN_UUID_128 )
3235 {
3236 for( yy = 0; yy < *p_num_uuid; yy++ )
3237 {
3238 STREAM_TO_ARRAY16(p_uuid_list + yy * LEN_UUID_128, p_uuid_data);
3239 for( xx = 0; xx < LEN_UUID_128; xx++ )
3240 sprintf(buff + xx*2, "%02X", *(p_uuid_list + yy * LEN_UUID_128 + xx));
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003241 BTM_TRACE_DEBUG(" 0x%s", buff);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003242 }
3243 }
3244
3245 return type;
3246#else
3247 *p_num_uuid = 0;
3248 return 0x00;
3249#endif
3250}
3251
3252
3253#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
3254/*******************************************************************************
3255**
3256** Function btm_eir_get_uuid_list
3257**
3258** Description This function searches UUID list in EIR.
3259**
3260** Parameters p_eir - address of EIR
3261** uuid_size - size of UUID to find
3262** p_num_uuid - number of UUIDs found
3263** p_uuid_list_type - EIR data type
3264**
3265** Returns NULL - if UUID list with uuid_size is not found
3266** beginning of UUID list in EIR - otherwise
3267**
3268*******************************************************************************/
3269static UINT8 *btm_eir_get_uuid_list( UINT8 *p_eir, UINT8 uuid_size,
3270 UINT8 *p_num_uuid, UINT8 *p_uuid_list_type )
3271{
3272 UINT8 *p_uuid_data;
3273 UINT8 complete_type, more_type;
3274 UINT8 uuid_len;
3275
3276 switch( uuid_size )
3277 {
3278 case LEN_UUID_16:
3279 complete_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3280 more_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3281 break;
3282 case LEN_UUID_32:
3283 complete_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3284 more_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
3285 break;
3286 case LEN_UUID_128:
3287 complete_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3288 more_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
3289 break;
3290 default:
3291 *p_num_uuid = 0;
3292 return NULL;
3293 break;
3294 }
3295
3296 p_uuid_data = BTM_CheckEirData( p_eir, complete_type, &uuid_len );
3297 if(p_uuid_data == NULL)
3298 {
3299 p_uuid_data = BTM_CheckEirData( p_eir, more_type, &uuid_len );
3300 *p_uuid_list_type = more_type;
3301 }
3302 else
3303 {
3304 *p_uuid_list_type = complete_type;
3305 }
3306
3307 *p_num_uuid = uuid_len / uuid_size;
3308 return p_uuid_data;
3309}
3310
3311/*******************************************************************************
3312**
3313** Function btm_convert_uuid_to_uuid16
3314**
3315** Description This function converts UUID to UUID 16-bit.
3316**
3317** Parameters p_uuid - address of UUID
3318** uuid_size - size of UUID
3319**
3320** Returns 0 - if UUID cannot be converted to UUID 16-bit
3321** UUID 16-bit - otherwise
3322**
3323*******************************************************************************/
3324static UINT16 btm_convert_uuid_to_uuid16( UINT8 *p_uuid, UINT8 uuid_size )
3325{
3326 static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
3327 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3328 UINT16 uuid16 = 0;
3329 UINT32 uuid32;
3330 BOOLEAN is_base_uuid;
3331 UINT8 xx;
3332
3333 switch (uuid_size)
3334 {
3335 case LEN_UUID_16:
3336 STREAM_TO_UINT16 (uuid16, p_uuid);
3337 break;
3338 case LEN_UUID_32:
3339 STREAM_TO_UINT32 (uuid32, p_uuid);
3340 if (uuid32 < 0x10000)
3341 uuid16 = (UINT16) uuid32;
3342 break;
3343 case LEN_UUID_128:
3344 /* See if we can compress his UUID down to 16 or 32bit UUIDs */
3345 is_base_uuid = TRUE;
3346 for (xx = 0; xx < LEN_UUID_128 - 4; xx++)
3347 {
3348 if (p_uuid[xx] != base_uuid[xx])
3349 {
3350 is_base_uuid = FALSE;
3351 break;
3352 }
3353 }
3354 if (is_base_uuid)
3355 {
3356 if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0))
3357 {
3358 p_uuid += (LEN_UUID_128 - 4);
3359 STREAM_TO_UINT16(uuid16, p_uuid);
3360 }
3361 }
3362 break;
3363 default:
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003364 BTM_TRACE_WARNING("btm_convert_uuid_to_uuid16 invalid uuid size");
The Android Open Source Project5738f832012-12-12 16:00:35 -08003365 break;
3366 }
3367
3368 return( uuid16);
3369}
3370
3371/*******************************************************************************
3372**
3373** Function btm_set_eir_uuid
3374**
3375** Description This function is called to store received UUID into inquiry result.
3376**
3377** Parameters p_eir - pointer of EIR significant part
3378** p_results - pointer of inquiry result
3379**
3380** Returns None
3381**
3382*******************************************************************************/
3383void btm_set_eir_uuid( UINT8 *p_eir, tBTM_INQ_RESULTS *p_results )
3384{
3385 UINT8 *p_uuid_data;
3386 UINT8 num_uuid;
3387 UINT16 uuid16;
3388 UINT8 yy;
3389 UINT8 type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3390
3391 p_uuid_data = btm_eir_get_uuid_list( p_eir, LEN_UUID_16, &num_uuid, &type );
3392
3393 if(type == BTM_EIR_COMPLETE_16BITS_UUID_TYPE)
3394 {
3395 p_results->eir_complete_list = TRUE;
3396 }
3397 else
3398 {
3399 p_results->eir_complete_list = FALSE;
3400 }
3401
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003402 BTM_TRACE_API("btm_set_eir_uuid eir_complete_list=0x%02X", p_results->eir_complete_list);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003403
3404 if( p_uuid_data )
3405 {
3406 for( yy = 0; yy < num_uuid; yy++ )
3407 {
3408 STREAM_TO_UINT16(uuid16, p_uuid_data);
3409 BTM_AddEirService( p_results->eir_uuid, uuid16 );
3410 }
3411 }
3412
3413 p_uuid_data = btm_eir_get_uuid_list( p_eir, LEN_UUID_32, &num_uuid, &type );
3414 if( p_uuid_data )
3415 {
3416 for( yy = 0; yy < num_uuid; yy++ )
3417 {
3418 uuid16 = btm_convert_uuid_to_uuid16( p_uuid_data, LEN_UUID_32 );
3419 p_uuid_data += LEN_UUID_32;
3420 if( uuid16 )
3421 BTM_AddEirService( p_results->eir_uuid, uuid16 );
3422 }
3423 }
3424
3425 p_uuid_data = btm_eir_get_uuid_list( p_eir, LEN_UUID_128, &num_uuid, &type );
3426 if( p_uuid_data )
3427 {
3428 for( yy = 0; yy < num_uuid; yy++ )
3429 {
3430 uuid16 = btm_convert_uuid_to_uuid16( p_uuid_data, LEN_UUID_128 );
3431 p_uuid_data += LEN_UUID_128;
3432 if( uuid16 )
3433 BTM_AddEirService( p_results->eir_uuid, uuid16 );
3434 }
3435 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08003436}
3437#endif