1 /******************************************************************************
2 *
3 * Copyright (C) 2008-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains functions for BLE GAP.
22 *
23 ******************************************************************************/
24
25 #include <string.h>
26 #include <stdio.h>
27 #include <stddef.h>
28
29 #include "bt_types.h"
30 #include "btu.h"
31 #include "btm_int.h"
32 #include "hcimsgs.h"
33 #if (GAP_INCLUDED == TRUE)
34 #include "gap_api.h"
35 #endif
36 #if (BLE_INCLUDED == TRUE)
37 #include "gattdefs.h"
38
39 #define BTM_BLE_NAME_SHORT 0x01
40 #define BTM_BLE_NAME_CMPL 0x02
41
42 #define BTM_BLE_FILTER_TARGET_UNKNOWN 0xff
43 #define BTM_BLE_POLICY_UNKNOWN 0xff
44
45 #define BTM_EXT_BLE_RMT_NAME_TIMEOUT 30
46
47 /*******************************************************************************
48 ** Local functions
49 *******************************************************************************/
50 static void btm_ble_update_adv_flag(UINT8 flag);
51 static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p);
52 static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data);
53 static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
54 BD_ADDR_PTR p_addr_ptr,
55 tBLE_ADDR_TYPE *p_init_addr_type,
56 tBLE_ADDR_TYPE *p_own_addr_type);
57 static BOOLEAN btm_ble_start_adv(void);
58 static tBTM_STATUS btm_ble_stop_adv(void);
59
60
61
62 /*******************************************************************************
63 **
64 ** Function BTM_BleReset
65 **
66 ** Description This function is called to reset ULP controller.
67 **
68 ** Parameters None.
69 **
70 ** Returns void
71 **
72 *******************************************************************************/
BTM_BleReset(void)73 void BTM_BleReset(void)
74 {
75 btsnd_hcic_ble_reset();
76 }
77 /*******************************************************************************
78 **
79 ** Function BTM_BleUpdateAdvWhitelist
80 **
81 ** Description Add or remove device from advertising white list
82 **
83 ** Returns void
84 **
85 *******************************************************************************/
BTM_BleUpdateAdvWhitelist(BOOLEAN add_remove,BD_ADDR remote_bda)86 BOOLEAN BTM_BleUpdateAdvWhitelist(BOOLEAN add_remove, BD_ADDR remote_bda)
87 {
88 return FALSE;
89 }
90
91 /*******************************************************************************
92 **
93 ** Function BTM_BleUpdateAdvFilterPolicy
94 **
95 ** Description This function update the filter policy of advertiser.
96 **
97 ** Parameter adv_policy: advertising filter policy
98 **
99 ** Return void
100 *******************************************************************************/
BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy)101 void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy)
102 {
103 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
104 tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC;
105 BD_ADDR p_addr_ptr= {0};
106 UINT8 adv_mode = p_cb->adv_mode;
107
108 BTM_TRACE_EVENT0 ("BTM_BleUpdateAdvFilterPolicy");
109
110 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
111 return;
112
113 if (p_cb->afp != adv_policy)
114 {
115 p_cb->afp = adv_policy;
116
117 /* if adv active, stop and restart */
118 btm_ble_stop_adv ();
119
120 if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE)
121 p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &p_cb->adv_addr_type);
122
123 btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min,
124 p_cb->adv_interval_max,
125 p_cb->evt_type,
126 p_cb->adv_addr_type,
127 init_addr_type,
128 p_addr_ptr,
129 p_cb->adv_chnl_map,
130 p_cb->afp);
131
132 if (adv_mode == BTM_BLE_ADV_ENABLE)
133 btm_ble_start_adv ();
134
135 }
136 }
137 /*******************************************************************************
138 **
139 ** Function BTM_BleObserve
140 **
141 ** Description This procedure keep the device listening for advertising
142 ** events from a broadcast device.
143 **
144 ** Parameters start: start or stop observe.
145 ** white_list: use white list in observer mode or not.
146 **
147 ** Returns void
148 **
149 *******************************************************************************/
BTM_BleObserve(BOOLEAN start,UINT8 duration,tBTM_INQ_RESULTS_CB * p_results_cb,tBTM_CMPL_CB * p_cmpl_cb)150 tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT8 duration,
151 tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb)
152 {
153 tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
154 tBTM_STATUS status = BTM_NO_RESOURCES;
155
156 BTM_TRACE_EVENT1 ("BTM_BleObserve : scan_type:%d",btm_cb.btm_inq_vars.scan_type);
157
158 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
159 return BTM_ILLEGAL_VALUE;
160
161 if (start)
162 {
163 /* shared inquiry database, do not allow observe if any inquiry is active */
164 if (btm_cb.btm_inq_vars.inq_active || p_inq->proc_mode != BTM_BLE_INQUIRY_NONE)
165 {
166 /*check if an interleave scan is already in progress*/
167 if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL
168 && btm_cb.btm_inq_vars.p_inq_results_cb != NULL)
169 {
170 BTM_TRACE_EVENT0 ("BTM_BleObserve general inq in progress, redirecting the results");
171 btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb;
172 btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb;
173 return BTM_SUCCESS;
174 }
175 else
176 return BTM_BUSY;
177 }
178 btm_cb.btm_inq_vars.scan_type = INQ_LE_OBSERVE;
179 btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb;
180 btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb;
181 p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type;
182
183 /* allow config scanning type */
184 if (btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
185 (UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval),
186 (UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window),
187 BLE_ADDR_PUBLIC,
188 BTM_BLE_DEFAULT_SFP)) /* assume observe always not using white list */
189 {
190 /* start scan, disable duplicate filtering */
191 if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE))
192 {
193 status = BTM_SUCCESS;
194 p_inq->proc_mode = BTM_BLE_OBSERVE;
195 btm_cb.btm_inq_vars.inq_active |= BTM_LE_OBSERVE_ACTIVE;
196
197 if (duration != 0)
198 {
199 /* start inquiry timer */
200 btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration);
201 }
202 }
203 }
204 }
205 else/*start = 0*/
206 {
207 if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL)
208 {
209 //Dont stop the scan. Just nullify the cbs
210 btm_cb.btm_inq_vars.p_inq_ble_results_cb = NULL;
211 btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = NULL;
212 }
213 else if (p_inq->proc_mode == BTM_BLE_OBSERVE)
214 {
215 btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_OBSERVE_ACTIVE;
216 btm_ble_stop_scan();
217 }
218 }
219
220 return status;
221 }
222
223 /*******************************************************************************
224 **
225 ** Function BTM_BleBroadcast
226 **
227 ** Description This function is to start or stop broadcasting.
228 **
229 ** Parameters start: start or stop broadcasting.
230 **
231 ** Returns status.
232 **
233 *******************************************************************************/
BTM_BleBroadcast(BOOLEAN start)234 tBTM_STATUS BTM_BleBroadcast(BOOLEAN start)
235 {
236 tBTM_STATUS status = BTM_NO_RESOURCES;
237 tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
238 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
239 UINT8 evt_type = p_cb->scan_rsp ? BTM_BLE_DISCOVER_EVT: BTM_BLE_NON_CONNECT_EVT;
240
241 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
242 return BTM_ILLEGAL_VALUE;
243
244 #ifdef BTM_BLE_PC_ADV_TEST_MODE
245 if (BTM_BLE_PC_ADV_TEST_MODE)
246 {
247 evt_type = p_cb->scan_rsp ? BTM_BLE_CONNECT_EVT: BTM_BLE_NON_CONNECT_EVT;
248 }
249 #endif
250
251 if (start && p_cb->adv_mode == BTM_BLE_ADV_DISABLE)
252 {
253 /* update adv params */
254 if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
255 (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
256 evt_type,
257 p_addr_cb->own_addr_type,
258 p_cb->direct_bda.type,
259 p_cb->direct_bda.bda,
260 p_cb->adv_chnl_map,
261 p_cb->afp))
262
263 status = BTM_NO_RESOURCES;
264 else
265 p_cb->evt_type = evt_type;
266
267 status = btm_ble_start_adv ();
268 }
269 else if (!start && p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
270 {
271 status = btm_ble_stop_adv();
272 }
273 else
274 {
275 status = BTM_WRONG_MODE;
276 BTM_TRACE_ERROR2("Can not %s Broadcast, device %s in Broadcast mode",
277 (start ? "Start" : "Stop"), (start ? "alerady" :"not"));
278 }
279 return status;
280 }
281
282 /*******************************************************************************
283 **
284 ** Function BTM_RegisterScanReqEvt
285 **
286 ** Description This function is called to register a scan request callback
287 ** on the advertiser.
288 **
289 ** Parameters p_scan_req_cback: scan request callback. If NULL, remove the
290 ** registration.
291 **
292 ** Returns void
293 **
294 *******************************************************************************/
BTM_RegisterScanReqEvt(tBTM_BLE_SCAN_REQ_CBACK * p_scan_req_cback)295 void BTM_RegisterScanReqEvt(tBTM_BLE_SCAN_REQ_CBACK *p_scan_req_cback)
296 {
297 #ifdef BTM_BLE_PC_ADV_TEST_MODE /* For general stack code (e.g. BTInsight testing), we simply do not define it to exclude or set it to TRUE to include */
298 if (BTM_BLE_PC_ADV_TEST_MODE) /* For stack component, it is always defined and maps to a global variable g_bDraculaAdvertisingMode */
299 {
300 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
301 p_cb->p_scan_req_cback = p_scan_req_cback;
302 }
303 #endif
304 }
305
306 /*******************************************************************************
307 **
308 ** Function BTM_BleSetBgConnType
309 **
310 ** Description This function is called to set BLE connectable mode for a
311 ** peripheral device.
312 **
313 ** Parameters bg_conn_type: it can be auto connection, or selective connection.
314 ** p_select_cback: callback function when selective connection procedure
315 ** is being used.
316 **
317 ** Returns void
318 **
319 *******************************************************************************/
BTM_BleSetBgConnType(tBTM_BLE_CONN_TYPE bg_conn_type,tBTM_BLE_SEL_CBACK * p_select_cback)320 BOOLEAN BTM_BleSetBgConnType(tBTM_BLE_CONN_TYPE bg_conn_type,
321 tBTM_BLE_SEL_CBACK *p_select_cback)
322 {
323 BOOLEAN started = TRUE;
324
325 BTM_TRACE_EVENT0 ("BTM_BleSetBgConnType ");
326 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
327 return FALSE;
328
329 if (btm_cb.ble_ctr_cb.bg_conn_type != bg_conn_type)
330 {
331 switch (bg_conn_type)
332 {
333 case BTM_BLE_CONN_AUTO:
334 btm_ble_start_auto_conn(TRUE);
335 break;
336
337 case BTM_BLE_CONN_SELECTIVE:
338 if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO)
339 {
340 btm_ble_start_auto_conn(FALSE);
341 }
342 started = btm_ble_start_select_conn(TRUE, p_select_cback);
343 break;
344
345 case BTM_BLE_CONN_NONE:
346 if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO)
347 {
348 btm_ble_start_auto_conn(FALSE);
349 }
350 else if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE)
351 {
352 btm_ble_start_select_conn(FALSE, NULL);
353 }
354 started = TRUE;
355 break;
356
357 default:
358 BTM_TRACE_ERROR1("invalid bg connection type : %d ", bg_conn_type);
359 started = FALSE;
360 break;
361 }
362
363 if (started)
364 btm_cb.ble_ctr_cb.bg_conn_type = bg_conn_type;
365 }
366 return started;
367 }
368
369 /*******************************************************************************
370 **
371 ** Function BTM_BleUpdateBgConnDev
372 **
373 ** Description This function is called to add or remove a device into/from
374 ** background connection procedure. The background connection
375 * procedure is decided by the background connection type, it can be
376 * auto connection, or selective connection.
377 **
378 ** Parameters add_remove: TRUE to add; FALSE to remove.
379 ** remote_bda: device address to add/remove.
380 **
381 ** Returns void
382 **
383 *******************************************************************************/
BTM_BleUpdateBgConnDev(BOOLEAN add_remove,BD_ADDR remote_bda)384 BOOLEAN BTM_BleUpdateBgConnDev(BOOLEAN add_remove, BD_ADDR remote_bda)
385 {
386 BOOLEAN ret = TRUE;
387 UINT8 dev_wl_type = 0;
388 BTM_TRACE_EVENT0 (" BTM_BleUpdateBgConnDev");
389
390 /* update white list */
391 ret = btm_update_bg_conn_list(add_remove, remote_bda, &dev_wl_type);
392
393 btm_update_dev_to_white_list(add_remove, remote_bda, dev_wl_type);
394
395 return ret;
396 }
397
398 /*******************************************************************************
399 **
400 ** Function BTM_BleSetConnMode
401 **
402 ** Description This function is called to set BLE connectable mode for a
403 ** peripheral device.
404 **
405 ** Parameters directed: is directed connectable mode, or non-directed.
406 ** p_dir_bda: connectable direct initiator's LE device address
407 **
408 ** Returns void
409 **
410 *******************************************************************************/
BTM_BleSetConnMode(BOOLEAN is_directed)411 tBTM_STATUS BTM_BleSetConnMode(BOOLEAN is_directed)
412 {
413 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
414
415 BTM_TRACE_EVENT1 ("BTM_BleSetConnMode is_directed = %d ", is_directed);
416 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
417 return BTM_ILLEGAL_VALUE;
418
419 p_cb->directed_conn = is_directed;
420 return btm_ble_set_connectability( p_cb->connectable_mode);
421
422 }
423
424 /*******************************************************************************
425 **
426 ** Function btm_set_conn_mode_adv_init_addr
427 **
428 ** Description set initator address type and local address type based on adv
429 ** mode.
430 **
431 **
432 *******************************************************************************/
btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB * p_cb,BD_ADDR_PTR p_addr_ptr,tBLE_ADDR_TYPE * p_init_addr_type,tBLE_ADDR_TYPE * p_own_addr_type)433 static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
434 BD_ADDR_PTR p_addr_ptr,
435 tBLE_ADDR_TYPE *p_init_addr_type,
436 tBLE_ADDR_TYPE *p_own_addr_type)
437 {
438 UINT8 evt_type;
439
440 if ( p_cb->directed_conn)
441 {
442 /* direct adv mode does not have privacy if privacy
443 is not enabled or no reconn addr config */
444 *p_own_addr_type = BLE_ADDR_PUBLIC;
445 *p_init_addr_type = p_cb->direct_bda.type;
446 memcpy(p_addr_ptr, p_cb->direct_bda.bda, BD_ADDR_LEN);
447 evt_type = BTM_BLE_CONNECT_DIR_EVT;
448 }
449 else /* undirect adv mode */
450 {
451 evt_type = BTM_BLE_CONNECT_EVT;
452 }
453
454 return evt_type;
455
456 }
457
458 /*******************************************************************************
459 **
460 ** Function BTM_BleSetAdvParams
461 **
462 ** Description This function is called to set advertising parameters.
463 **
464 ** Parameters adv_int_min: minimum advertising interval
465 ** adv_int_max: maximum advertising interval
466 ** p_dir_bda: connectable direct initiator's LE device address
467 ** chnl_map: advertising channel map.
468 **
469 ** Returns void
470 **
471 *******************************************************************************/
BTM_BleSetAdvParams(UINT16 adv_int_min,UINT16 adv_int_max,tBLE_BD_ADDR * p_dir_bda,tBTM_BLE_ADV_CHNL_MAP chnl_map)472 tBTM_STATUS BTM_BleSetAdvParams(UINT16 adv_int_min, UINT16 adv_int_max,
473 tBLE_BD_ADDR *p_dir_bda,
474 tBTM_BLE_ADV_CHNL_MAP chnl_map)
475 {
476 tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
477 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
478 tBTM_STATUS status = BTM_SUCCESS;
479 BD_ADDR p_addr_ptr = {0};
480 tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC;
481 tBLE_ADDR_TYPE own_addr_type = p_addr_cb->own_addr_type;
482 UINT8 adv_mode = p_cb->adv_mode;
483
484 BTM_TRACE_EVENT0 ("BTM_BleSetAdvParams");
485
486 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
487 return BTM_ILLEGAL_VALUE;
488
489 if (!BTM_BLE_VALID_PRAM(adv_int_min, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX) ||
490 !BTM_BLE_VALID_PRAM(adv_int_max, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX))
491 {
492 return BTM_ILLEGAL_VALUE;
493 }
494
495 p_cb->adv_interval_min = adv_int_min;
496 p_cb->adv_interval_max = adv_int_max;
497 p_cb->adv_chnl_map = chnl_map;
498
499 if (p_dir_bda)
500 {
501 memcpy(&p_cb->direct_bda, p_dir_bda, sizeof(tBLE_BD_ADDR));
502 }
503
504 BTM_TRACE_EVENT0 ("update params for an active adv");
505
506 btm_ble_stop_adv();
507
508 if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE)
509 p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
510
511 /* update adv params */
512 btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min,
513 p_cb->adv_interval_max,
514 p_cb->evt_type,
515 own_addr_type,
516 init_addr_type,
517 p_addr_ptr,
518 p_cb->adv_chnl_map,
519 p_cb->afp);
520
521 if (adv_mode == BTM_BLE_ADV_ENABLE)
522 btm_ble_start_adv();
523
524 return status;
525 }
526
527 /*******************************************************************************
528 **
529 ** Function BTM_BleReadAdvParams
530 **
531 ** Description This function is called to set advertising parameters.
532 **
533 ** Parameters adv_int_min: minimum advertising interval
534 ** adv_int_max: maximum advertising interval
535 ** p_dir_bda: connectable direct initiator's LE device address
536 ** chnl_map: advertising channel map.
537 **
538 ** Returns void
539 **
540 *******************************************************************************/
BTM_BleReadAdvParams(UINT16 * adv_int_min,UINT16 * adv_int_max,tBLE_BD_ADDR * p_dir_bda,tBTM_BLE_ADV_CHNL_MAP * p_chnl_map)541 void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max,
542 tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP *p_chnl_map)
543 {
544 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
545
546 BTM_TRACE_EVENT0 ("BTM_BleReadAdvParams ");
547 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
548 return ;
549
550 *adv_int_min = p_cb->adv_interval_min;
551 *adv_int_max = p_cb->adv_interval_max;
552 *p_chnl_map = p_cb->adv_chnl_map;
553
554 if (p_dir_bda != NULL)
555 {
556 memcpy(p_dir_bda, &p_cb->direct_bda, sizeof(tBLE_BD_ADDR));
557 }
558 }
559
560 /*******************************************************************************
561 **
562 ** Function BTM_BleSetScanParams
563 **
564 ** Description This function is called to set Scan parameters.
565 **
566 ** Parameters adv_int_min: minimum advertising interval
567 ** adv_int_max: maximum advertising interval
568 ** p_dir_bda: connectable direct initiator's LE device address
569 ** chnl_map: advertising channel map.
570 ** scan_type: active scan or passive scan
571 **
572 ** Returns void
573 **
574 *******************************************************************************/
BTM_BleSetScanParams(UINT16 scan_interval,UINT16 scan_window,tBTM_BLE_SCAN_MODE scan_mode)575 void BTM_BleSetScanParams(UINT16 scan_interval, UINT16 scan_window, tBTM_BLE_SCAN_MODE scan_mode)
576 {
577 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
578
579 BTM_TRACE_EVENT0 (" BTM_BleSetScanParams");
580 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
581 return ;
582
583 if (BTM_BLE_VALID_PRAM(scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) &&
584 BTM_BLE_VALID_PRAM(scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX) &&
585 (scan_mode == BTM_BLE_SCAN_MODE_ACTI || scan_mode == BTM_BLE_SCAN_MODE_PASS))
586 {
587 p_cb->scan_type = scan_mode;
588
589 if (BTM_BLE_CONN_PARAM_UNDEF != scan_interval)
590 p_cb->scan_interval = scan_interval;
591
592 if (BTM_BLE_CONN_PARAM_UNDEF != scan_window)
593 p_cb->scan_window = scan_window;
594 }
595 else
596 {
597 BTM_TRACE_ERROR2("Illegal params: scan_interval = %d scan_window = %d",
598 scan_interval, scan_window);
599 }
600
601 }
602
603 /*******************************************************************************
604 **
605 ** Function BTM_BleWriteScanRsp
606 **
607 ** Description This function is called to write LE scan response.
608 **
609 ** Parameters: p_scan_rsp: scan response information.
610 **
611 ** Returns void
612 **
613 *******************************************************************************/
BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask,tBTM_BLE_ADV_DATA * p_data)614 tBTM_STATUS BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p_data)
615 {
616 tBTM_STATUS status = BTM_NO_RESOURCES;
617 UINT8 rsp_data[BTM_BLE_AD_DATA_LEN],
618 *p = rsp_data;
619
620 BTM_TRACE_EVENT0 (" BTM_BleWriteScanRsp");
621
622 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
623 return BTM_ILLEGAL_VALUE;
624
625 memset(rsp_data, 0, BTM_BLE_AD_DATA_LEN);
626 btm_ble_build_adv_data(&data_mask, &p, p_data);
627
628 if (btsnd_hcic_ble_set_scan_rsp_data((UINT8)(p - rsp_data), rsp_data))
629 {
630 status = BTM_SUCCESS;
631
632 if (data_mask != 0)
633 btm_cb.ble_ctr_cb.inq_var.scan_rsp = TRUE;
634 else
635 btm_cb.ble_ctr_cb.inq_var.scan_rsp = FALSE;
636 }
637 else
638 status = BTM_ILLEGAL_VALUE;
639
640 return status;
641 }
642
643 /*******************************************************************************
644 **
645 ** Function BTM_BleWriteAdvData
646 **
647 ** Description This function is called to write advertising data.
648 **
649 ** Parameters: None.
650 **
651 ** Returns void
652 **
653 *******************************************************************************/
BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask,tBTM_BLE_ADV_DATA * p_data)654 tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p_data)
655 {
656 tBTM_BLE_LOCAL_ADV_DATA *p_cb_data = &btm_cb.ble_ctr_cb.inq_var.adv_data;
657 UINT8 *p;
658 UINT16 mask = data_mask;
659
660 BTM_TRACE_EVENT0 ("BTM_BleWriteAdvData ");
661
662 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
663 return BTM_ILLEGAL_VALUE;
664
665 memset(p_cb_data, 0, sizeof(tBTM_BLE_LOCAL_ADV_DATA));
666 p = p_cb_data->ad_data;
667 p_cb_data->data_mask = data_mask;
668
669 p_cb_data->p_flags = btm_ble_build_adv_data(&mask, &p, p_data);
670
671 p_cb_data->p_pad = p;
672
673 if (data_mask != 0)
674 {
675 BTM_TRACE_ERROR0("Partial data write into ADV");
676 }
677
678 p_cb_data->data_mask &= ~mask;
679
680 if (btsnd_hcic_ble_set_adv_data((UINT8)(p_cb_data->p_pad - p_cb_data->ad_data),
681 p_cb_data->ad_data))
682 return BTM_SUCCESS;
683 else
684 return BTM_NO_RESOURCES;
685
686 }
687
688 /*******************************************************************************
689 **
690 ** Function BTM_CheckAdvData
691 **
692 ** Description This function is called to get ADV data for a specific type.
693 **
694 ** Parameters p_adv - pointer of ADV data
695 ** type - finding ADV data type
696 ** p_length - return the length of ADV data not including type
697 **
698 ** Returns pointer of ADV data
699 **
700 *******************************************************************************/
BTM_CheckAdvData(UINT8 * p_adv,UINT8 type,UINT8 * p_length)701 UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length)
702 {
703 UINT8 *p = p_adv;
704 UINT8 length;
705 UINT8 adv_type;
706 BTM_TRACE_API1("BTM_CheckAdvData type=0x%02X", type);
707
708 STREAM_TO_UINT8(length, p);
709
710 while ( length && (p - p_adv <= BTM_BLE_CACHE_ADV_DATA_MAX))
711 {
712 STREAM_TO_UINT8(adv_type, p);
713
714 if ( adv_type == type )
715 {
716 /* length doesn't include itself */
717 *p_length = length - 1; /* minus the length of type */
718 return p;
719 }
720 p += length - 1; /* skip the length of data */
721 STREAM_TO_UINT8(length, p);
722 }
723
724 *p_length = 0;
725 return NULL;
726 }
727
728 /*******************************************************************************
729 **
730 ** Function btm_ble_build_adv_data
731 **
732 ** Description This function is called build the adv data and rsp data.
733 *******************************************************************************/
btm_ble_build_adv_data(tBTM_BLE_AD_MASK * p_data_mask,UINT8 ** p_dst,tBTM_BLE_ADV_DATA * p_data)734 static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data)
735 {
736 UINT16 data_mask = *p_data_mask;
737 UINT8 *p = *p_dst,
738 *p_flag = NULL;
739 UINT16 len = BTM_BLE_AD_DATA_LEN, cp_len = 0;
740 UINT8 i = 0;
741 tBTM_BLE_PROP_ELEM *p_elem;
742
743 BTM_TRACE_EVENT0 (" btm_ble_build_adv_data");
744
745 /* build the adv data structure and build the data string */
746 if (data_mask)
747 {
748 /* flags */
749 if (data_mask & BTM_BLE_AD_BIT_FLAGS)
750 {
751 *p++ = 2;
752 *p++ = BTM_BLE_AD_TYPE_FLAG;
753 p_flag = p;
754 if (p_data)
755 *p++ = p_data->flag;
756 else
757 *p++ = 0;
758
759 len -= 3;
760
761 data_mask &= ~BTM_BLE_AD_BIT_FLAGS;
762 }
763 /* appearance data */
764 if (len > 3 && data_mask & BTM_BLE_AD_BIT_APPEARANCE)
765 {
766 *p++ = 3; /* length */
767 *p++ = BTM_BLE_AD_TYPE_APPEARANCE;
768 UINT16_TO_STREAM(p, p_data->appearance);
769 len -= 4;
770
771 data_mask &= ~BTM_BLE_AD_BIT_APPEARANCE;
772 }
773 /* device name */
774 #if BTM_MAX_LOC_BD_NAME_LEN > 0
775 if (len > 2 && data_mask & BTM_BLE_AD_BIT_DEV_NAME)
776 {
777 if (strlen(btm_cb.cfg.bd_name) > (UINT16)(len - 2))
778 {
779 *p++ = len - 2 + 1;
780 *p++ = BTM_BLE_AD_TYPE_NAME_SHORT;
781 ARRAY_TO_STREAM(p, btm_cb.cfg.bd_name, len - 2);
782 }
783 else
784 {
785 cp_len = (UINT16)strlen(btm_cb.cfg.bd_name);
786 *p++ = cp_len + 1;
787 *p++ = BTM_BLE_AD_TYPE_NAME_CMPL;
788 ARRAY_TO_STREAM(p, btm_cb.cfg.bd_name, cp_len);
789 }
790 len -= (cp_len + 2);
791 data_mask &= ~BTM_BLE_AD_BIT_DEV_NAME;
792 }
793 #endif
794 /* manufacturer data */
795 if (len > 2 && data_mask & BTM_BLE_AD_BIT_MANU &&
796 p_data && p_data->manu.len != 0 && p_data->manu.p_val)
797 {
798 if (p_data->manu.len > (len - 2))
799 cp_len = len - 2;
800 else
801 cp_len = p_data->manu.len;
802
803 *p++ = cp_len + 1;
804 *p++ = BTM_BLE_AD_TYPE_MANU;
805 ARRAY_TO_STREAM(p, p_data->manu.p_val, cp_len);
806
807 len -= (cp_len + 2);
808 data_mask &= ~BTM_BLE_AD_BIT_MANU;
809 }
810 /* TX power */
811 if (len > 2 && data_mask & BTM_BLE_AD_BIT_TX_PWR)
812 {
813 *p++ = 2;
814 *p++ = BTM_BLE_AD_TYPE_TX_PWR;
815 *p++ = btm_cb.ble_ctr_cb.inq_var.tx_power;
816 len -= 3;
817
818 data_mask &= ~BTM_BLE_AD_BIT_TX_PWR;
819 }
820 /* services */
821 if (len > 2 && data_mask & BTM_BLE_AD_BIT_SERVICE &&
822 p_data && p_data->services.num_service != 0 &&
823 p_data->services.p_uuid)
824 {
825 if (p_data->services.num_service * 2 > (len - 2))
826 {
827 cp_len = (len - 2)/2;
828 *p ++ = 1 + cp_len * 2;
829 *p++ = BTM_BLE_AD_TYPE_16SRV_PART;
830 }
831 else
832 {
833 cp_len = p_data->services.num_service;
834 *p++ = 1 + cp_len * 2;
835 *p++ = BTM_BLE_AD_TYPE_16SRV_CMPL;
836 }
837 for (i = 0; i < cp_len; i ++)
838 {
839 UINT16_TO_STREAM(p, *(p_data->services.p_uuid + i));
840 }
841
842 len -= (cp_len * 2 + 2);
843 data_mask &= ~BTM_BLE_AD_BIT_SERVICE;
844 }
845 if (len >= 6 && data_mask & BTM_BLE_AD_BIT_INT_RANGE &&
846 p_data)
847 {
848 *p++ = 5;
849 *p++ = BTM_BLE_AD_TYPE_INT_RANGE;
850 UINT16_TO_STREAM(p, p_data->int_range.low);
851 UINT16_TO_STREAM(p, p_data->int_range.hi);
852 len -= 6;
853 data_mask &= ~BTM_BLE_AD_BIT_INT_RANGE;
854 }
855 if (data_mask & BTM_BLE_AD_BIT_PROPRIETARY && p_data && p_data->p_proprietary)
856 {
857 for (i = 0; i < p_data->p_proprietary->num_elem ; i ++)
858 {
859 p_elem = p_data->p_proprietary->p_elem + i;
860
861 if (len >= (2 + p_elem->len))/* len byte(1) + ATTR type(1) + Uuid len(2) + value length */
862 {
863 *p ++ = p_elem->len + 1; /* Uuid len + value length */
864 *p ++ = p_elem->adv_type;
865 ARRAY_TO_STREAM(p, p_elem->p_val, p_elem->len);
866
867 len -= (2 + p_elem->len);
868 }
869 else
870 {
871 BTM_TRACE_WARNING0("data exceed max adv packet length");
872 break;
873 }
874 }
875 data_mask &= ~BTM_BLE_AD_BIT_PROPRIETARY;
876 }
877 }
878
879 *p_data_mask = data_mask;
880 *p_dst = p;
881
882 return p_flag;
883 }
884
885 /*******************************************************************************
886 **
887 ** Function btm_ble_set_discoverability
888 **
889 ** Description This function is called to set BLE discoverable mode.
890 **
891 ** Parameters: mode: discoverability mode.
892 **
893 ** Returns void
894 **
895 *******************************************************************************/
btm_ble_set_discoverability(UINT16 combined_mode)896 tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
897 {
898 tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
899 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
900 UINT16 mode = (combined_mode & BTM_BLE_DISCOVERABLE_MASK);
901 UINT8 flag = 0;
902 UINT8 new_mode = BTM_BLE_ADV_ENABLE;
903 UINT8 evt_type = (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) ? \
904 ((p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT : BTM_BLE_NON_CONNECT_EVT )\
905 : BTM_BLE_CONNECT_EVT;
906 tBTM_STATUS status = BTM_SUCCESS;
907 BD_ADDR p_addr_ptr= {0};
908 tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC,
909 own_addr_type = p_addr_cb->own_addr_type;;
910
911 BTM_TRACE_EVENT2 ("btm_ble_set_discoverability mode=0x%0x combined_mode=0x%x", mode, combined_mode);
912
913 /*** Check mode parameter ***/
914 if (mode > BTM_BLE_MAX_DISCOVERABLE)
915 return(BTM_ILLEGAL_VALUE);
916
917 p_cb->br_edr_supported_flag |= (combined_mode & BTM_DISCOVERABLE_MASK);
918 p_cb->discoverable_mode = mode;
919
920 if (!p_cb->br_edr_supported_flag)
921 {
922 flag = BTM_BLE_BREDR_NOT_SPT;
923 BTM_TRACE_DEBUG1("btm_ble_set_discoverability (BREDR not sup)flag=0x%x",flag);
924 }
925
926 BTM_TRACE_DEBUG1 ("br_edr_supported=0x%x", p_cb->br_edr_supported_flag);
927
928 if (mode == BTM_BLE_LIMITED_DISCOVERABLE || mode == BTM_BLE_GENERAL_DISCOVERABLE)
929 {
930 BTM_TRACE_EVENT0 ("mode == BTM_BLE_LIMITED_DISCOVERABLE ");
931 /* write ADV data with limited disc flag */
932 if (mode == BTM_BLE_LIMITED_DISCOVERABLE)
933 flag |= BTM_BLE_LIMIT_DISC_FLAG ;
934 else
935 flag |= BTM_BLE_GEN_DISC_FLAG;
936 }
937 else /* non-discoverable */
938 {
939 BTM_TRACE_EVENT0 ("mode == BTM_BLE_NON_DISCOVERABLE ");
940
941 if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE)
942 {
943 p_cb->br_edr_supported_flag = 0;
944
945 BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode if no scan rsp ");
946 if (!p_cb->scan_rsp )
947 new_mode = BTM_BLE_ADV_DISABLE;
948
949 }
950 else
951 {
952 p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
953 }
954 }
955 btm_ble_update_adv_flag(flag);
956
957 /* update adv params if start advertising */
958 BTM_TRACE_EVENT2 ("evt_type=0x%x p-cb->evt_type=0x%x ", evt_type, p_cb->evt_type);
959 if (new_mode == BTM_BLE_ADV_ENABLE &&
960 (evt_type != p_cb->evt_type ||p_cb->adv_addr_type != own_addr_type))
961 {
962 btm_ble_stop_adv();
963
964 /* update adv params */
965 if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
966 (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
967 evt_type,
968 own_addr_type,
969 init_addr_type,
970 p_addr_ptr,
971 p_cb->adv_chnl_map,
972 p_cb->afp))
973
974 status = BTM_NO_RESOURCES;
975 else
976 {
977 p_cb->evt_type = evt_type;
978 p_cb->adv_addr_type = own_addr_type;
979 }
980
981 }
982
983 if (status == BTM_SUCCESS && p_cb->adv_mode != new_mode)
984 {
985 if (new_mode == BTM_BLE_ADV_ENABLE)
986 status = btm_ble_start_adv();
987 else
988 status = btm_ble_stop_adv();
989 }
990
991 /* set up stop advertising timer */
992 if (status == BTM_SUCCESS && mode == BTM_BLE_LIMITED_DISCOVERABLE)
993 {
994 BTM_TRACE_EVENT1 ("start timer for limited disc mode duration=%d (30 secs)", BTM_BLE_GAP_LIM_TOUT);
995 /* start Tgap(lim_timeout) */
996 btu_start_timer (&p_cb->inq_timer_ent, BTU_TTYPE_BLE_GAP_LIM_DISC,
997 BTM_BLE_GAP_LIM_TOUT);
998 }
999 return status;
1000 }
1001
1002 /*******************************************************************************
1003 **
1004 ** Function btm_ble_set_connectability
1005 **
1006 ** Description This function is called to set BLE connectability mode.
1007 **
1008 ** Parameters: mode: connectability mode.
1009 **
1010 ** Returns void
1011 **
1012 *******************************************************************************/
btm_ble_set_connectability(UINT16 combined_mode)1013 tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode)
1014 {
1015 tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
1016 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
1017 UINT16 mode = (combined_mode & BTM_BLE_CONNECTABLE_MASK);
1018 UINT8 cur_flag = 0;
1019 UINT8 cur_br_edr_not_sup_flag;
1020 UINT8 new_flag;
1021 UINT8 new_mode = BTM_BLE_ADV_ENABLE;
1022 UINT8 evt_type = (p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT: BTM_BLE_NON_CONNECT_EVT;
1023 tBTM_STATUS status = BTM_SUCCESS;
1024 BD_ADDR p_addr_ptr = {0};
1025 tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC,
1026 own_addr_type = p_addr_cb->own_addr_type;
1027
1028 BTM_TRACE_EVENT2 ("btm_ble_set_connectability mode=0x%0x combined_mode=0x%x", mode, combined_mode);
1029 /*** Check mode parameter ***/
1030 if (mode > BTM_BLE_MAX_CONNECTABLE)
1031 return(BTM_ILLEGAL_VALUE);
1032 if (btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags)
1033 cur_flag = *btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags ;
1034 cur_br_edr_not_sup_flag = (cur_flag & ((UINT8) BTM_BLE_BREDR_NOT_SPT));
1035
1036 p_cb->br_edr_supported_flag |= ((combined_mode & BTM_CONNECTABLE_MASK) << 4);
1037 if (p_cb->br_edr_supported_flag && cur_br_edr_not_sup_flag)
1038 {
1039 new_flag = cur_flag & ((UINT8) (~BTM_BLE_BREDR_NOT_SPT));
1040 BTM_TRACE_EVENT2 ("new flag=0x%x cur flag=0x%x",new_flag, cur_flag);
1041 btm_ble_update_adv_flag(new_flag);
1042 }
1043 p_cb->connectable_mode = mode;
1044
1045 if (mode == BTM_BLE_NON_CONNECTABLE)
1046 {
1047 if (p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE)
1048 {
1049 p_cb->br_edr_supported_flag = 0;
1050 BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode with no scan rsp");
1051 if(!p_cb->scan_rsp)
1052 new_mode = BTM_BLE_ADV_DISABLE;
1053
1054 }
1055 }
1056 else /* connectable */
1057 {
1058 evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
1059 }
1060
1061 /* update adv params if needed */
1062 if ((p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type)
1063 && new_mode == BTM_BLE_ADV_ENABLE)
1064 {
1065 btm_ble_stop_adv();
1066
1067 if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
1068 (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
1069 evt_type,
1070 own_addr_type,
1071 init_addr_type,
1072 p_addr_ptr,
1073 p_cb->adv_chnl_map,
1074 p_cb->afp))
1075 status = BTM_NO_RESOURCES;
1076 else
1077 {
1078 p_cb->evt_type = evt_type;
1079 p_cb->adv_addr_type = own_addr_type;
1080 }
1081 }
1082
1083 /* update advertising mode */
1084 if (status == BTM_SUCCESS && new_mode != p_cb->adv_mode)
1085 {
1086 if (btsnd_hcic_ble_set_adv_enable (new_mode))
1087 {
1088 status = BTM_SUCCESS;
1089
1090 p_cb->adv_mode = new_mode;
1091
1092 if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE &&
1093 p_cb->afp != AP_SCAN_CONN_ALL)
1094 btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV;
1095 else
1096 btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
1097
1098 }
1099 }
1100
1101 return status;
1102 }
1103
1104 /*******************************************************************************
1105 **
1106 ** Function btm_ble_start_inquiry
1107 **
1108 ** Description This function is called to start BLE inquiry procedure.
1109 ** If the duration is zero, the periodic inquiry mode is cancelled.
1110 **
1111 ** Parameters: mode - GENERAL or LIMITED inquiry
1112 ** p_inq_params - pointer to the BLE inquiry parameter.
1113 ** p_results_cb - callback returning pointer to results (tBTM_INQ_RESULTS)
1114 ** p_cmpl_cb - callback indicating the end of an inquiry
1115 **
1116 **
1117 **
1118 ** Returns BTM_CMD_STARTED if successfully started
1119 ** BTM_NO_RESOURCES if could not allocate a message buffer
1120 ** BTM_BUSY - if an inquiry is already active
1121 **
1122 *******************************************************************************/
btm_ble_start_inquiry(UINT8 mode,UINT8 duration)1123 tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration)
1124 {
1125 tBTM_STATUS status = BTM_NO_RESOURCES;
1126 tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
1127
1128 BTM_TRACE_DEBUG2("btm_ble_start_inquiry: mode = %02x inq_active = %d", mode, btm_cb.btm_inq_vars.inq_active);
1129
1130 if (p_inq->proc_mode != BTM_BLE_INQUIRY_NONE)
1131 {
1132 BTM_TRACE_ERROR0("LE scan is active, can not start inquiry");
1133 return(BTM_BUSY);
1134 }
1135
1136 btm_update_scanner_filter_policy(SP_ADV_ALL);
1137
1138 /* start scan, already enable duplicate filtering */
1139 if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE))
1140 {
1141 status = BTM_CMD_STARTED;
1142 p_inq->proc_mode = mode;
1143
1144 if (duration != 0)
1145 {
1146 /* start inquiry timer */
1147 btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration);
1148 }
1149 }
1150
1151 return status;
1152 }
1153
1154 /*******************************************************************************
1155 **
1156 ** Function btm_ble_read_remote_name_cmpl
1157 **
1158 ** Description This function is called when BLE remote name is received.
1159 **
1160 ** Returns void
1161 **
1162 *******************************************************************************/
btm_ble_read_remote_name_cmpl(BOOLEAN status,BD_ADDR bda,UINT16 length,char * p_name)1163 void btm_ble_read_remote_name_cmpl(BOOLEAN status, BD_ADDR bda, UINT16 length, char *p_name)
1164 {
1165 UINT8 hci_status = HCI_SUCCESS;
1166 BD_NAME bd_name;
1167
1168 memset(bd_name, 0, (BD_NAME_LEN + 1));
1169 memcpy((UINT8*)bd_name, p_name, length);
1170
1171 if ((!status) || (length==0))
1172 {
1173 hci_status = HCI_ERR_HOST_TIMEOUT;
1174 }
1175
1176 btm_process_remote_name(bda, bd_name, length +1, hci_status);
1177 btm_sec_rmt_name_request_complete (bda, (UINT8 *)p_name, hci_status);
1178 }
1179
1180 /*******************************************************************************
1181 **
1182 ** Function btm_ble_read_remote_name
1183 **
1184 ** Description This function read remote LE device name using GATT read
1185 ** procedure.
1186 **
1187 ** Parameters: None.
1188 **
1189 ** Returns void
1190 **
1191 *******************************************************************************/
btm_ble_read_remote_name(BD_ADDR remote_bda,tBTM_INQ_INFO * p_cur,tBTM_CMPL_CB * p_cb)1192 tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur, tBTM_CMPL_CB *p_cb)
1193 {
1194 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1195
1196 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
1197 return BTM_ERR_PROCESSING;
1198
1199 if (p_cur &&
1200 p_cur->results.ble_evt_type != BTM_BLE_EVT_CONN_ADV &&
1201 p_cur->results.ble_evt_type != BTM_BLE_EVT_CONN_DIR_ADV)
1202 {
1203 BTM_TRACE_DEBUG0("name request to non-connectable device failed.");
1204 return BTM_ERR_PROCESSING;
1205 }
1206
1207 /* read remote device name using GATT procedure */
1208 if (p_inq->remname_active)
1209 return BTM_BUSY;
1210
1211 if (!GAP_BleReadPeerDevName(remote_bda, btm_ble_read_remote_name_cmpl))
1212 return BTM_BUSY;
1213
1214 p_inq->p_remname_cmpl_cb = p_cb;
1215 p_inq->remname_active = TRUE;
1216
1217 memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
1218
1219 btu_start_timer (&p_inq->rmt_name_timer_ent,
1220 BTU_TTYPE_BTM_RMT_NAME,
1221 BTM_EXT_BLE_RMT_NAME_TIMEOUT);
1222
1223 return BTM_CMD_STARTED;
1224 }
1225
1226 /*******************************************************************************
1227 **
1228 ** Function btm_ble_cancel_remote_name
1229 **
1230 ** Description This function cancel read remote LE device name.
1231 **
1232 ** Parameters: None.
1233 **
1234 ** Returns void
1235 **
1236 *******************************************************************************/
btm_ble_cancel_remote_name(BD_ADDR remote_bda)1237 BOOLEAN btm_ble_cancel_remote_name(BD_ADDR remote_bda)
1238 {
1239 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1240 BOOLEAN status;
1241
1242 status = GAP_BleCancelReadPeerDevName(remote_bda);
1243
1244 p_inq->remname_active = FALSE;
1245 memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
1246 btu_stop_timer(&p_inq->rmt_name_timer_ent);
1247
1248 return status;
1249 }
1250
1251 /*******************************************************************************
1252 **
1253 ** Function btm_ble_update_adv_flag
1254 **
1255 ** Description This function update the limited discoverable flag in the adv
1256 ** data.
1257 **
1258 ** Parameters: None.
1259 **
1260 ** Returns void
1261 **
1262 *******************************************************************************/
btm_ble_update_adv_flag(UINT8 flag)1263 static void btm_ble_update_adv_flag(UINT8 flag)
1264 {
1265 tBTM_BLE_LOCAL_ADV_DATA *p_adv_data = &btm_cb.ble_ctr_cb.inq_var.adv_data;
1266 UINT8 *p;
1267
1268 BTM_TRACE_DEBUG1 ("btm_ble_update_adv_flag new=0x%x", flag);
1269
1270 if (p_adv_data->p_flags != NULL)
1271 {
1272 BTM_TRACE_DEBUG1 ("btm_ble_update_adv_flag old=0x%x", *p_adv_data->p_flags);
1273 *p_adv_data->p_flags = flag;
1274 }
1275 else /* no FLAGS in ADV data*/
1276 {
1277 p = (p_adv_data->p_pad == NULL) ? p_adv_data->ad_data : p_adv_data->p_pad;
1278 /* need 3 bytes space to stuff in the flags, if not */
1279 /* erase all written data, just for flags */
1280 if ((BTM_BLE_AD_DATA_LEN - (p - p_adv_data->ad_data)) < 3)
1281 {
1282 p = p_adv_data->p_pad = p_adv_data->ad_data;
1283 memset(p_adv_data->ad_data, 0, BTM_BLE_AD_DATA_LEN);
1284 }
1285
1286 *p++ = 2;
1287 *p++ = BTM_BLE_AD_TYPE_FLAG;
1288 p_adv_data->p_flags = p;
1289 *p++ = flag;
1290 p_adv_data->p_pad = p;
1291 }
1292
1293 if (btsnd_hcic_ble_set_adv_data((UINT8)(p_adv_data->p_pad - p_adv_data->ad_data),
1294 p_adv_data->ad_data))
1295 p_adv_data->data_mask |= BTM_BLE_AD_BIT_FLAGS;
1296
1297 }
1298
1299 #if 0
1300 /*******************************************************************************
1301 **
1302 ** Function btm_ble_parse_adv_data
1303 **
1304 ** Description This function parse the adv data into a structure.
1305 **
1306 ** Returns pointer to entry, or NULL if not found
1307 **
1308 *******************************************************************************/
1309 static void btm_ble_parse_adv_data(tBTM_INQ_INFO *p_info, UINT8 *p_data,
1310 UINT8 len, tBTM_BLE_INQ_DATA *p_adv_data, UINT8 *p_buf)
1311 {
1312 UINT8 *p_cur = p_data;
1313 UINT8 ad_len, ad_type, ad_flag;
1314
1315 BTM_TRACE_EVENT0 (" btm_ble_parse_adv_data");
1316
1317 while (len > 0)
1318 {
1319 BTM_TRACE_DEBUG1("btm_ble_parse_adv_data: len = %d", len);
1320 if ((ad_len = *p_cur ++) == 0)
1321 break;
1322
1323 ad_type = *p_cur ++;
1324
1325 BTM_TRACE_DEBUG2(" ad_type = %02x ad_len = %d", ad_type, ad_len);
1326
1327 switch (ad_type)
1328 {
1329 case BTM_BLE_AD_TYPE_NAME_SHORT:
1330
1331 case BTM_BLE_AD_TYPE_NAME_CMPL:
1332 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_DEV_NAME;
1333 if (p_info)
1334 {
1335 p_info->remote_name_type =(ad_type == BTM_BLE_AD_TYPE_NAME_SHORT) ?
1336 BTM_BLE_NAME_SHORT: BTM_BLE_NAME_CMPL;
1337 memcpy(p_info->remote_name, p_cur, ad_len -1);
1338 p_info->remote_name[ad_len] = 0;
1339 p_adv_data->p_remote_name = p_info->remote_name;
1340 p_info->remote_name_len = p_adv_data->remote_name_len = ad_len - 1;
1341 BTM_TRACE_DEBUG1("BTM_BLE_AD_TYPE_NAME name = %s",p_adv_data->p_remote_name);
1342 }
1343 p_cur += (ad_len -1);
1344
1345 break;
1346
1347 case BTM_BLE_AD_TYPE_FLAG:
1348 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_FLAGS;
1349 ad_flag = *p_cur ++;
1350 p_adv_data->flag = (UINT8)(ad_flag & BTM_BLE_ADV_FLAG_MASK) ;
1351 BTM_TRACE_DEBUG3("BTM_BLE_AD_TYPE_FLAG flag = %s | %s | %s",
1352 (p_adv_data->flag & BTM_BLE_LIMIT_DISC_FLAG)? "LE_LIMIT_DISC" : "",
1353 (p_adv_data->flag & BTM_BLE_GEN_DISC_FLAG)? "LE_GENERAL_DISC" : "",
1354 (p_adv_data->flag & BTM_BLE_BREDR_NOT_SPT)? "LE Only device" : "");
1355 break;
1356
1357 case BTM_BLE_AD_TYPE_TX_PWR:
1358 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_TX_PWR;
1359 p_adv_data->tx_power_level = (INT8)*p_cur ++;
1360 BTM_TRACE_DEBUG1("BTM_BLE_AD_TYPE_TX_PWR tx_level = %d", p_adv_data->tx_power_level);
1361 break;
1362
1363 case BTM_BLE_AD_TYPE_MANU:
1364
1365 case BTM_BLE_AD_TYPE_16SRV_PART:
1366 case BTM_BLE_AD_TYPE_16SRV_CMPL:
1367 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_SERVICE;
1368 /* need allocate memory to store UUID list */
1369 p_adv_data->service.num_service = (ad_len - 1)/2;
1370 BTM_TRACE_DEBUG1("service UUID list, num = %d", p_adv_data->service.num_service);
1371 p_cur += (ad_len - 1);
1372 break;
1373
1374 case BTM_BLE_AD_TYPE_SOL_SRV_UUID:
1375 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_SERVICE_SOL;
1376 /* need allocate memory to store UUID list */
1377 p_adv_data->service.num_service = (ad_len - 1)/2;
1378 BTM_TRACE_DEBUG1("service UUID list, num = %d", p_adv_data->service.num_service);
1379 p_cur += (ad_len - 1);
1380 break;
1381
1382 case BTM_BLE_AD_TYPE_128SOL_SRV_UUID:
1383 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_SERVICE_128SOL;
1384 /* need allocate memory to store UUID list */
1385 p_adv_data->service.num_service = (ad_len - 1)/16;
1386 BTM_TRACE_DEBUG1("service UUID list, num = %d", p_adv_data->service.num_service);
1387 p_cur += (ad_len - 1);
1388 break;
1389
1390 case BTM_BLE_AD_TYPE_APPEARANCE:
1391 case BTM_BLE_AD_TYPE_PUBLIC_TARGET:
1392 case BTM_BLE_AD_TYPE_RANDOM_TARGET:
1393 default:
1394 break;
1395 }
1396 len -= (ad_len + 1);
1397 }
1398 }
1399 #endif
1400
1401 /*******************************************************************************
1402 **
1403 ** Function btm_ble_cache_adv_data
1404 **
1405 ** Description Update advertising cache data.
1406 **
1407 ** Returns void
1408 **
1409 *******************************************************************************/
btm_ble_cache_adv_data(tBTM_INQ_RESULTS * p_cur,UINT8 data_len,UINT8 * p,UINT8 evt_type)1410 void btm_ble_cache_adv_data(tBTM_INQ_RESULTS *p_cur, UINT8 data_len, UINT8 *p, UINT8 evt_type)
1411 {
1412 tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
1413 UINT8 *p_cache;
1414 UINT8 length;
1415
1416 /* cache adv report/scan response data */
1417 if (evt_type != BTM_BLE_SCAN_RSP_EVT)
1418 {
1419 p_le_inq_cb->adv_len = 0;
1420 memset(p_le_inq_cb->adv_data_cache, 0, BTM_BLE_CACHE_ADV_DATA_MAX);
1421 }
1422
1423 if (data_len > 0)
1424 {
1425 p_cache = &p_le_inq_cb->adv_data_cache[p_le_inq_cb->adv_len];
1426 STREAM_TO_UINT8(length, p);
1427 while ( length && ((p_le_inq_cb->adv_len + length + 1) <= BTM_BLE_CACHE_ADV_DATA_MAX))
1428 {
1429 /* copy from the length byte & data into cache */
1430 memcpy(p_cache, p-1, length+1);
1431 /* advance the cache pointer past data */
1432 p_cache += length+1;
1433 /* increment cache length */
1434 p_le_inq_cb->adv_len += length+1;
1435 /* skip the length of data */
1436 p += length;
1437 STREAM_TO_UINT8(length, p);
1438 }
1439 }
1440
1441 /* parse service UUID from adv packet and save it in inq db eir_uuid */
1442 /* TODO */
1443 }
1444
1445 /*******************************************************************************
1446 **
1447 ** Function btm_ble_is_discoverable
1448 **
1449 ** Description check ADV flag to make sure device is discoverable and match
1450 ** the search condition
1451 **
1452 ** Parameters
1453 **
1454 ** Returns void
1455 **
1456 *******************************************************************************/
btm_ble_is_discoverable(BD_ADDR bda,UINT8 evt_type,UINT8 * p)1457 BOOLEAN btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p)
1458 {
1459 BOOLEAN is_discoverable = FALSE;
1460 UINT8 *p_flag, flag = 0;
1461 UINT8 data_len;
1462 tBTM_INQ_PARMS *p_cond = &btm_cb.btm_inq_vars.inqparms;
1463
1464 STREAM_TO_UINT8 (data_len, p);
1465
1466 /* for observer, always "discoverable */
1467 if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE ||
1468 (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_SELECT_SCAN &&
1469 btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE))
1470 return TRUE;
1471
1472 /* does not match filter condition */
1473 if (p_cond->filter_cond_type == BTM_FILTER_COND_BD_ADDR &&
1474 memcmp(bda, p_cond->filter_cond.bdaddr_cond, BD_ADDR_LEN) != 0)
1475 {
1476 BTM_TRACE_DEBUG0("BD ADDR does not meet filter condition");
1477 return FALSE;
1478 }
1479
1480 /* scan response does not include the flag */
1481 if (evt_type == BTM_BLE_SCAN_RSP_EVT)
1482 return FALSE;
1483
1484 if (data_len > BTM_BLE_ADV_DATA_LEN_MAX)
1485 {
1486 BTM_TRACE_WARNING1("ADV data too long %d. discard", data_len);
1487 return FALSE;
1488 }
1489
1490 if (data_len != 0)
1491 {
1492 if ((p_flag = BTM_CheckAdvData(p, BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL)
1493 {
1494 flag = * p_flag;
1495
1496 if ((btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_GENERAL_INQUIRY) &&
1497 (flag & (BTM_BLE_LIMIT_DISC_FLAG|BTM_BLE_GEN_DISC_FLAG)) != 0)
1498 {
1499 BTM_TRACE_DEBUG0("Find Generable Discoverable device");
1500 is_discoverable = TRUE;
1501 }
1502
1503 else if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_LIMITED_INQUIRY &&
1504 (flag & BTM_BLE_LIMIT_DISC_FLAG) != 0)
1505 {
1506 BTM_TRACE_DEBUG0("Find limited discoverable device");
1507 is_discoverable = TRUE;
1508 }
1509
1510 }
1511 }
1512
1513 if (!is_discoverable)
1514 {
1515 BTM_TRACE_ERROR1("discoverable flag not desired: %d", flag);
1516 }
1517
1518 return is_discoverable;
1519 }
1520
1521 /*******************************************************************************
1522 **
1523 ** Function btm_ble_update_inq_result
1524 **
1525 ** Description Update adv packet information into inquiry result.
1526 **
1527 ** Parameters
1528 **
1529 ** Returns void
1530 **
1531 *******************************************************************************/
btm_ble_update_inq_result(tINQ_DB_ENT * p_i,UINT8 addr_type,UINT8 evt_type,UINT8 * p)1532 BOOLEAN btm_ble_update_inq_result(tINQ_DB_ENT *p_i, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
1533 {
1534 BOOLEAN to_report = TRUE;
1535 tBTM_INQ_RESULTS *p_cur = &p_i->inq_info.results;
1536 UINT8 len;
1537 UINT8 *p_flag;
1538 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1539 UINT8 data_len, rssi;
1540 tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
1541 UINT8 *p1;
1542
1543 STREAM_TO_UINT8 (data_len, p);
1544
1545 if (data_len > BTM_BLE_ADV_DATA_LEN_MAX)
1546 {
1547 BTM_TRACE_WARNING1("EIR data too long %d. discard", data_len);
1548 return FALSE;
1549 }
1550 btm_ble_cache_adv_data(p_cur, data_len, p, evt_type);
1551
1552 p1 = (p + data_len);
1553 STREAM_TO_UINT8 (rssi, p1);
1554
1555 /* Save the info */
1556 p_cur->inq_result_type = BTM_INQ_RESULT_BLE;
1557 p_cur->ble_addr_type = addr_type;
1558 p_cur->rssi = rssi;
1559
1560 /* active scan, always wait until get scan_rsp to report the result */
1561 if ((btm_cb.ble_ctr_cb.inq_var.scan_type == BTM_BLE_SCAN_MODE_ACTI &&
1562 (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_DISCOVER_EVT)))
1563 {
1564 BTM_TRACE_DEBUG1("btm_ble_update_inq_result scan_rsp=false, to_report=false,\
1565 scan_type_active=%d", btm_cb.ble_ctr_cb.inq_var.scan_type);
1566 p_i->scan_rsp = FALSE;
1567 to_report = FALSE;
1568 }
1569 else
1570 p_i->scan_rsp = TRUE;
1571
1572 if (p_i->inq_count != p_inq->inq_counter)
1573 p_cur->device_type = BT_DEVICE_TYPE_BLE;
1574 else
1575 p_cur->device_type |= BT_DEVICE_TYPE_BLE;
1576
1577 if (evt_type != BTM_BLE_SCAN_RSP_EVT)
1578 p_cur->ble_evt_type = evt_type;
1579
1580 p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */
1581
1582 if (p_le_inq_cb->adv_len != 0)
1583 {
1584 if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, BTM_BLE_AD_TYPE_FLAG, &len)) != NULL)
1585 p_cur->flag = * p_flag;
1586 }
1587
1588 /* if BR/EDR not supported is not set, assume is a DUMO device */
1589 if ((p_cur->flag & BTM_BLE_BREDR_NOT_SPT) == 0 &&
1590 evt_type != BTM_BLE_CONNECT_DIR_EVT)
1591 {
1592 if (p_cur->ble_addr_type != BLE_ADDR_RANDOM)
1593 {
1594 BTM_TRACE_DEBUG0("BR/EDR NOT support bit not set, treat as DUMO");
1595 p_cur->device_type |= BT_DEVICE_TYPE_DUMO;
1596 } else {
1597 BTM_TRACE_DEBUG0("Random address, treating device as LE only");
1598 }
1599 }
1600 else
1601 {
1602 BTM_TRACE_DEBUG0("BR/EDR NOT SUPPORT bit set, LE only device");
1603 }
1604
1605 return to_report;
1606
1607 }
1608
1609 /*******************************************************************************
1610 **
1611 ** Function btm_send_sel_conn_callback
1612 **
1613 ** Description send selection connection request callback.
1614 **
1615 ** Parameters
1616 **
1617 ** Returns void
1618 **
1619 *******************************************************************************/
btm_send_sel_conn_callback(BD_ADDR remote_bda,UINT8 evt_type,UINT8 * p_data,UINT8 addr_type)1620 void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_data, UINT8 addr_type)
1621 {
1622 UINT8 data_len, len;
1623 UINT8 *p_dev_name, remname[31] = {0};
1624
1625 if (btm_cb.ble_ctr_cb.p_select_cback == NULL ||
1626 /* non-connectable device */
1627 (evt_type != BTM_BLE_EVT_CONN_ADV && evt_type != BTM_BLE_EVT_CONN_DIR_ADV))
1628 return;
1629
1630 STREAM_TO_UINT8 (data_len, p_data);
1631
1632 /* get the device name if exist in ADV data */
1633 if (data_len != 0)
1634 {
1635 p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_CMPL, &len);
1636
1637 if (p_dev_name == NULL)
1638 p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_SHORT, &len);
1639
1640 if (p_dev_name)
1641 memcpy(remname, p_dev_name, len);
1642 }
1643 /* allow connection */
1644 if ((* btm_cb.ble_ctr_cb.p_select_cback)(remote_bda, remname))
1645 {
1646 /* terminate selective connection, initiate connection */
1647 btm_ble_initiate_select_conn(remote_bda);
1648 }
1649 }
1650
1651 /*******************************************************************************
1652 **
1653 ** Function btm_ble_process_adv_pkt
1654 **
1655 ** Description This function is called when adv packet report events are
1656 ** received from the device. It updates the inquiry database.
1657 ** If the inquiry database is full, the oldest entry is discarded.
1658 **
1659 ** Parameters
1660 **
1661 ** Returns void
1662 **
1663 *******************************************************************************/
btm_ble_process_adv_pkt(UINT8 * p_data)1664 void btm_ble_process_adv_pkt (UINT8 *p_data)
1665 {
1666 BD_ADDR bda;
1667 UINT8 evt_type = 0, *p = p_data;
1668 UINT8 addr_type = 0;
1669
1670 /* always get one device at a time */
1671 p ++;
1672
1673 /* Extract inquiry results */
1674 STREAM_TO_UINT8 (evt_type, p);
1675 STREAM_TO_UINT8 (addr_type, p);
1676 STREAM_TO_BDADDR (bda, p);
1677
1678 #ifdef BTM_BLE_PC_ADV_TEST_MODE /* For general stack code (e.g. BTInsight testing), we simply do not define it to exclude or set it to TRUE to include */
1679 if (BTM_BLE_PC_ADV_TEST_MODE) /* For stack component, it is always defined and maps to a global variable g_bDraculaAdvertisingMode */
1680 {
1681 if (btm_cb.ble_ctr_cb.p_scan_req_cback)
1682 (*btm_cb.ble_ctr_cb.p_scan_req_cback)(bda, addr_type, evt_type);
1683 }
1684 #endif
1685
1686
1687
1688 /* Only process the results if the inquiry is still active */
1689 if ((btm_cb.btm_inq_vars.inq_active & BTM_LE_SCAN_ACTIVE_MASK) == 0 &&
1690 (btm_cb.ble_ctr_cb.bg_conn_type != BTM_BLE_CONN_SELECTIVE ||
1691 /* or selective auto connection is active */
1692 btm_cb.ble_ctr_cb.p_select_cback == NULL))
1693 return;
1694
1695 BTM_TRACE_DEBUG6("btm_ble_process_adv_pkt:bda= %0x:%0x:%0x:%0x:%0x:%0x",
1696 bda[0],bda[1],bda[2],bda[3],bda[4],bda[5]);
1697 btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, p);
1698 }
1699
1700 /*******************************************************************************
1701 **
1702 ** Function btm_ble_process_adv_pkt_cont
1703 **
1704 ** Description This function is called after random address resolution is
1705 ** done, and proceed to process adv packet.
1706 **
1707 ** Parameters
1708 **
1709 ** Returns void
1710 **
1711 *******************************************************************************/
btm_ble_process_adv_pkt_cont(BD_ADDR bda,UINT8 addr_type,UINT8 evt_type,UINT8 * p)1712 static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
1713 {
1714 tINQ_DB_ENT *p_i;
1715 BOOLEAN to_report = FALSE;
1716 BOOLEAN to_report_LE = TRUE; //var for reporting to LE observe
1717 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1718 tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb;
1719 tBTM_INQ_RESULTS_CB *p_inq_ble_results_cb = p_inq->p_inq_ble_results_cb;
1720 tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
1721 BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: addr_type: %d, evt_type: %d", addr_type, evt_type);
1722
1723 p_i = btm_inq_db_find (bda);
1724
1725 /* Check if this address has already been processed for this inquiry */
1726 if (btm_inq_find_bdaddr(bda))
1727 {
1728 /* never been report as an LE device */
1729 if ((p_i &&
1730 (!(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) ||
1731 /* scan repsonse to be updated */
1732 (!p_i->scan_rsp)))
1733 ||
1734 btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE)
1735 {
1736 BTM_TRACE_DEBUG0("update new BLE information ");
1737 to_report = TRUE;
1738 }
1739 else
1740 {
1741 to_report = FALSE;
1742 }
1743 }
1744 else /* not been processed in this round */
1745 {
1746 to_report = TRUE;
1747 }
1748
1749 /* If existing entry, use that, else get a new one (possibly reusing the oldest) */
1750 if (p_i == NULL)
1751 {
1752 if ((p_i = btm_inq_db_new (bda)) != NULL)
1753 {
1754 p_inq->inq_cmpl_info.num_resp++;
1755 }
1756 else
1757 return;
1758
1759 if (to_report && btm_ble_is_discoverable(bda, evt_type, p))
1760 {
1761 to_report = TRUE;
1762 }
1763 else
1764 {
1765 BTM_TRACE_ERROR0("discard adv pkt");
1766 to_report = FALSE;
1767 }
1768 }
1769 else if (p_i->inq_count != p_inq->inq_counter) /* first time seen in this inquiry */
1770 {
1771 p_inq->inq_cmpl_info.num_resp++;
1772 }
1773 /* update the LE device information in inquiry database */
1774 to_report_LE = btm_ble_update_inq_result(p_i, addr_type, evt_type, p);
1775 if (to_report)
1776 to_report = to_report_LE;
1777 #if BTM_USE_INQ_RESULTS_FILTER == TRUE
1778 /* If the number of responses found and limited, issue a cancel inquiry */
1779 if (p_inq->inqparms.max_resps &&
1780 p_inq->inq_cmpl_info.num_resp == p_inq->inqparms.max_resps)
1781 {
1782 /* new device */
1783 if (p_i == NULL ||
1784 (/* assume a DUMO device, BR/EDR inquiry is always active */
1785 p_i && p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BLE && p_i->scan_rsp))
1786 {
1787 BTM_TRACE_WARNING0("INQ RES: Extra Response Received...cancelling inquiry..");
1788
1789 /* if is non-periodic inquiry active, cancel now */
1790 if ((p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK) != 0 &&
1791 (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) == 0)
1792 btsnd_hcic_inq_cancel();
1793
1794 /* stop LE scan now */
1795 btm_ble_stop_scan();
1796
1797 #if BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE
1798 btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
1799 #endif
1800 }
1801 }
1802 #endif
1803
1804 BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: to_report =%d, to_report_le=%d",
1805 to_report, to_report_LE);
1806 /* background connection in selective connection mode */
1807 if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE)
1808 {
1809 if (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BLE &&
1810 (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_CONNECT_DIR_EVT))
1811 btm_send_sel_conn_callback(bda, evt_type, p, addr_type);
1812 else
1813 {
1814 BTM_TRACE_DEBUG0("None LE device, can not initiate selective connection");
1815 }
1816 }
1817 else if (to_report || to_report_LE)
1818 {
1819 if(p_inq_results_cb && to_report)
1820 (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
1821 if(p_inq_ble_results_cb && to_report_LE)
1822 (p_inq_ble_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results,
1823 p_le_inq_cb->adv_data_cache);
1824 }
1825 }
1826
1827 /*******************************************************************************
1828 **
1829 ** Function btm_ble_stop_scan
1830 **
1831 ** Description Stop the BLE scan.
1832 **
1833 ** Returns void
1834 **
1835 *******************************************************************************/
btm_ble_stop_scan(void)1836 void btm_ble_stop_scan(void)
1837 {
1838 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
1839 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1840
1841 BTM_TRACE_EVENT0 ("btm_ble_stop_scan ");
1842
1843 btu_stop_timer (&p_cb->inq_timer_ent);
1844
1845 /* Clear the inquiry callback if set */
1846 p_cb->scan_type = BTM_BLE_SCAN_MODE_NONE;
1847 p_cb->proc_mode = BTM_BLE_INQUIRY_NONE;
1848
1849 /* stop discovery now */
1850 btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
1851
1852 /* If we have a callback registered for inquiry complete, call it */
1853 BTM_TRACE_DEBUG2 ("BTM Inq Compl Callback: status 0x%02x, num results %d",
1854 p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp);
1855
1856 btm_update_scanner_filter_policy(SP_ADV_ALL);
1857
1858 btm_process_inq_complete(HCI_SUCCESS, (UINT8)(p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK));
1859
1860 }
1861
1862 /*******************************************************************************
1863 **
1864 ** Function btm_ble_start_adv
1865 **
1866 ** Description Stop the BLE advertising.
1867 **
1868 ** Returns void
1869 **
1870 *******************************************************************************/
btm_ble_start_adv(void)1871 static tBTM_STATUS btm_ble_start_adv(void)
1872 {
1873 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
1874 tBTM_STATUS rt = BTM_NO_RESOURCES;
1875
1876 if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE))
1877 {
1878 if (p_cb->afp != AP_SCAN_CONN_ALL)
1879 btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV;
1880
1881 p_cb->adv_mode = BTM_BLE_ADV_ENABLE;
1882
1883 rt = BTM_SUCCESS;
1884 }
1885 else
1886 {
1887 p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
1888 btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
1889 }
1890 return rt;
1891 }
1892 /*******************************************************************************
1893 **
1894 ** Function btm_ble_stop_adv
1895 **
1896 ** Description Stop the BLE advertising.
1897 **
1898 ** Returns void
1899 **
1900 *******************************************************************************/
btm_ble_stop_adv(void)1901 static tBTM_STATUS btm_ble_stop_adv(void)
1902 {
1903 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
1904 tBTM_STATUS rt = BTM_SUCCESS;
1905
1906 if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
1907 {
1908 if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE))
1909 {
1910 p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
1911 btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
1912 }
1913 else
1914 rt = BTM_NO_RESOURCES;
1915 }
1916 return rt;
1917
1918 }
1919
1920 /*******************************************************************************
1921 **
1922 ** Function btm_ble_timeout
1923 **
1924 ** Description Called when BTM BLE inquiry timer expires
1925 **
1926 ** Returns void
1927 **
1928 *******************************************************************************/
btm_ble_timeout(TIMER_LIST_ENT * p_tle)1929 void btm_ble_timeout(TIMER_LIST_ENT *p_tle)
1930 {
1931 switch (p_tle->event)
1932 {
1933 case BTU_TTYPE_BLE_INQUIRY:
1934 btm_ble_stop_scan();
1935 break;
1936
1937 case BTU_TTYPE_BLE_GAP_LIM_DISC:
1938 /* lim_timeout expiried, limited discovery should exit now */
1939 btm_ble_update_adv_flag(BTM_BLE_NON_LIMIT_DISC_FLAG);
1940
1941 btm_ble_stop_adv();
1942 break;
1943
1944 case BTU_TTYPE_BLE_RANDOM_ADDR:
1945 if (btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type == BLE_ADDR_RANDOM)
1946 {
1947 /* refresh the random addr */
1948 btm_gen_resolvable_private_addr();
1949 }
1950 break;
1951
1952 }
1953 }
1954
1955
1956 /*******************************************************************************
1957 **
1958 ** Function btm_ble_read_remote_features_complete
1959 **
1960 ** Description This function is called when the command complete message
1961 ** is received from the HCI for the read LE remote feature supported
1962 ** complete event.
1963 **
1964 ** Returns void
1965 **
1966 *******************************************************************************/
btm_ble_read_remote_features_complete(UINT8 * p)1967 void btm_ble_read_remote_features_complete(UINT8 *p)
1968 {
1969 tACL_CONN *p_acl_cb = &btm_cb.acl_db[0];
1970 UINT8 status;
1971 UINT16 handle;
1972 int xx;
1973
1974 BTM_TRACE_EVENT0 ("btm_ble_read_remote_features_complete ");
1975
1976 STREAM_TO_UINT8 (status, p);
1977 STREAM_TO_UINT16 (handle, p);
1978
1979 /* Look up the connection by handle and copy features */
1980 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_acl_cb++)
1981 {
1982 if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle))
1983 {
1984 STREAM_TO_ARRAY(p_acl_cb->peer_le_features, p, BD_FEATURES_LEN);
1985 break;
1986 }
1987 }
1988 }
1989
1990 /*******************************************************************************
1991 **
1992 ** Function btm_ble_write_adv_enable_complete
1993 **
1994 ** Description This function process the write adv enable command complete.
1995 **
1996 ** Returns void
1997 **
1998 *******************************************************************************/
btm_ble_write_adv_enable_complete(UINT8 * p)1999 void btm_ble_write_adv_enable_complete(UINT8 * p)
2000 {
2001 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
2002
2003 /* if write adv enable/disbale not succeed */
2004 if (*p != HCI_SUCCESS)
2005 {
2006 /* toggle back the adv mode */
2007 p_cb->adv_mode = !p_cb->adv_mode;
2008 }
2009
2010
2011 }
2012
2013 /*******************************************************************************
2014 **
2015 ** Function btm_ble_dir_adv_tout
2016 **
2017 ** Description when directed adv time out
2018 **
2019 ** Returns void
2020 **
2021 *******************************************************************************/
btm_ble_dir_adv_tout(void)2022 void btm_ble_dir_adv_tout(void)
2023 {
2024 btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
2025
2026 /* make device fall back into undirected adv mode by default */
2027 btm_cb.ble_ctr_cb.inq_var.directed_conn = FALSE;
2028 }
2029
2030 /*******************************************************************************
2031 **
2032 ** Function btm_ble_update_mode_operation
2033 **
2034 ** Description This function update the GAP role operation when a link status
2035 ** is updated.
2036 **
2037 ** Returns void
2038 **
2039 *******************************************************************************/
btm_ble_update_mode_operation(UINT8 link_role,BD_ADDR bd_addr,BOOLEAN conn_cancel)2040 void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, BOOLEAN conn_cancel)
2041 {
2042 tACL_CONN *pa = &btm_cb.acl_db[0];
2043 UINT16 xx;
2044 UINT8 dev_role = link_role;
2045
2046 BTM_TRACE_DEBUG1("btm_ble_update_mode_operation adv_mode = %d", btm_cb.ble_ctr_cb.inq_var.adv_mode );
2047
2048 /* update periphera role operation */
2049 /* If we are LE connectable, check if we need to start advertising again */
2050 if (link_role == HCI_ROLE_UNKNOWN)
2051 /* && btm_cb.ble_ctr_cb.inq_var.connectable_mode != BTM_BLE_NON_CONNECTABLE) */
2052 {
2053 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, pa++)
2054 {
2055 /* If any other LE link is up, we are still not connectable */
2056 if (pa->in_use && pa->is_le_link)
2057 {
2058 dev_role = pa->link_role;
2059 break;
2060 }
2061 }
2062 }
2063
2064 if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE &&
2065 (dev_role == HCI_ROLE_UNKNOWN )) /* when device has no connection, update adv here */
2066 /* if already in connection, no connectable adv is allowed unless scatternet is enabled */
2067 {
2068 btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
2069 }
2070
2071 if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
2072 {
2073 if (!btm_send_pending_direct_conn())
2074 {
2075 btm_ble_resume_bg_conn();
2076 }
2077 }
2078 }
2079
2080 /*******************************************************************************
2081 **
2082 ** Function btm_ble_init
2083 **
2084 ** Description Initialize the control block variable values.
2085 **
2086 ** Returns void
2087 **
2088 *******************************************************************************/
btm_ble_init(void)2089 void btm_ble_init (void)
2090 {
2091 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
2092
2093 BTM_TRACE_EVENT0 ("btm_ble_init ");
2094
2095 memset(p_cb, 0, sizeof(tBTM_BLE_CB));
2096
2097 p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
2098 p_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
2099 p_cb->inq_var.adv_chnl_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP;
2100 p_cb->inq_var.afp = BTM_BLE_DEFAULT_AFP;
2101 p_cb->inq_var.sfp = BTM_BLE_DEFAULT_SFP;
2102 p_cb->inq_var.connectable_mode = BTM_BLE_NON_CONNECTABLE;
2103 p_cb->inq_var.discoverable_mode = BTM_BLE_NON_DISCOVERABLE;
2104
2105 /* for background connection, reset connection params to be undefined */
2106 p_cb->scan_int = p_cb->scan_win = BTM_BLE_CONN_PARAM_UNDEF;
2107
2108 p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT;
2109 }
2110
2111 #endif /* BLE_INCLUDED */
2112