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