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