OSDN Git Service

Use run time parameters to control LE features
[android-x86/system-bt.git] / vnd / ble / vendor_ble.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2003-2014 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 **  Name:          vendor_ble.c
22 **
23 **  Description:   This file contains vendor specific feature for BLE
24 **
25 ******************************************************************************/
26 #include <string.h>
27 #include "bt_target.h"
28
29 #if (BLE_INCLUDED == TRUE)
30 #include "bt_types.h"
31 #include "hcimsgs.h"
32 #include "btu.h"
33 #include "vendor_ble.h"
34 #include "vendor_hcidefs.h"
35 #include "gatt_int.h"
36
37 /*** This needs to be moved to a VSC control block eventually per coding conventions ***/
38 #if VENDOR_DYNAMIC_MEMORY == FALSE
39 tBTM_BLE_VENDOR_CB  btm_ble_vendor_cb;
40 #endif
41
42 static const BD_ADDR     na_bda= {0};
43
44 /*******************************************************************************
45 **         Resolve Address Using IRK List functions
46 *******************************************************************************/
47
48
49 /*******************************************************************************
50 **
51 ** Function         btm_ble_vendor_enq_irk_pending
52 **
53 ** Description      add target address into IRK pending operation queue
54 **
55 ** Parameters       target_bda: target device address
56 **                  add_entry: TRUE for add entry, FALSE for remove entry
57 **
58 ** Returns          void
59 **
60 *******************************************************************************/
61 void btm_ble_vendor_enq_irk_pending(BD_ADDR target_bda, BD_ADDR psuedo_bda, UINT8 to_add)
62 {
63 #if BLE_PRIVACY_SPT == TRUE
64     tBTM_BLE_IRK_Q          *p_q = &btm_ble_vendor_cb.irk_pend_q;
65
66     memcpy(p_q->irk_q[p_q->q_next], target_bda, BD_ADDR_LEN);
67     memcpy(p_q->irk_q_random_pseudo[p_q->q_next], psuedo_bda, BD_ADDR_LEN);
68     p_q->irk_q_action[p_q->q_next] = to_add;
69
70     p_q->q_next ++;
71     p_q->q_next %= btm_cb.cmn_ble_vsc_cb.max_irk_list_sz;;
72 #endif
73     return ;
74 }
75 /*******************************************************************************
76 **
77 ** Function         btm_ble_vendor_find_irk_pending_entry
78 **
79 ** Description      check to see if the action is in pending list
80 **
81 ** Parameters       TRUE: action pending;
82 **                  FALSE: new action
83 **
84 ** Returns          void
85 **
86 *******************************************************************************/
87 BOOLEAN btm_ble_vendor_find_irk_pending_entry(BD_ADDR psuedo_addr, UINT8 action)
88 {
89 #if BLE_PRIVACY_SPT == TRUE
90     tBTM_BLE_IRK_Q          *p_q = &btm_ble_vendor_cb.irk_pend_q;
91     UINT8   i;
92
93     for (i = p_q->q_pending; i != p_q->q_next; )
94     {
95         if (memcmp(p_q->irk_q_random_pseudo[i], psuedo_addr, BD_ADDR_LEN) == 0 &&
96             action == p_q->irk_q_action[i])
97             return TRUE;
98
99         i ++;
100         i %= btm_cb.cmn_ble_vsc_cb.max_irk_list_sz;
101     }
102 #endif
103     return FALSE;
104 }
105 /*******************************************************************************
106 **
107 ** Function         btm_ble_vendor_deq_irk_pending
108 **
109 ** Description      add target address into IRK pending operation queue
110 **
111 ** Parameters       target_bda: target device address
112 **                  add_entry: TRUE for add entry, FALSE for remove entry
113 **
114 ** Returns          void
115 **
116 *******************************************************************************/
117 BOOLEAN btm_ble_vendor_deq_irk_pending(BD_ADDR target_bda, BD_ADDR psuedo_addr)
118 {
119 #if BLE_PRIVACY_SPT == TRUE
120     tBTM_BLE_IRK_Q          *p_q = &btm_ble_vendor_cb.irk_pend_q;
121
122     if (p_q->q_next != p_q->q_pending)
123     {
124         memcpy(target_bda, p_q->irk_q[p_q->q_pending], BD_ADDR_LEN);
125         memcpy(psuedo_addr, p_q->irk_q_random_pseudo[p_q->q_pending], BD_ADDR_LEN);
126
127         p_q->q_pending ++;
128         p_q->q_pending %= btm_cb.cmn_ble_vsc_cb.max_irk_list_sz;
129
130         return TRUE;
131     }
132 #endif
133     return FALSE;
134
135 }
136 /*******************************************************************************
137 **
138 ** Function         btm_ble_vendor_find_irk_entry
139 **
140 ** Description      find IRK entry in local host IRK list by static address
141 **
142 ** Returns          IRK list entry pointer
143 **
144 *******************************************************************************/
145 tBTM_BLE_IRK_ENTRY * btm_ble_vendor_find_irk_entry(BD_ADDR target_bda)
146 {
147 #if BLE_PRIVACY_SPT == TRUE
148     tBTM_BLE_IRK_ENTRY  *p_irk_entry = &btm_ble_vendor_cb.irk_list[0];
149     UINT8   i;
150
151     for (i = 0; i < btm_cb.cmn_ble_vsc_cb.max_irk_list_sz; i ++, p_irk_entry++)
152     {
153         if (p_irk_entry->in_use && memcmp(p_irk_entry->bd_addr, target_bda, BD_ADDR_LEN) == 0)
154         {
155             return p_irk_entry ;
156         }
157     }
158 #endif
159     return NULL;
160 }
161 /*******************************************************************************
162 **
163 ** Function         btm_ble_vendor_find_irk_entry_by_psuedo_addr
164 **
165 ** Description      find IRK entry in local host IRK list by psuedo address
166 **
167 ** Returns          IRK list entry pointer
168 **
169 *******************************************************************************/
170 tBTM_BLE_IRK_ENTRY * btm_ble_vendor_find_irk_entry_by_psuedo_addr (BD_ADDR psuedo_bda)
171 {
172 #if BLE_PRIVACY_SPT == TRUE
173     tBTM_BLE_IRK_ENTRY  *p_irk_entry = &btm_ble_vendor_cb.irk_list[0];
174     UINT8   i;
175
176     for (i = 0; i < btm_cb.cmn_ble_vsc_cb.max_irk_list_sz; i ++, p_irk_entry++)
177     {
178         if (p_irk_entry->in_use && memcmp(p_irk_entry->psuedo_bda, psuedo_bda, BD_ADDR_LEN) == 0)
179         {
180             return p_irk_entry ;
181         }
182     }
183 #endif
184     return NULL;
185 }
186 /*******************************************************************************
187 **
188 ** Function         btm_ble_vendor_alloc_irk_entry
189 **
190 ** Description      allocate IRK entry in local host IRK list
191 **
192 ** Returns          IRK list index
193 **
194 *******************************************************************************/
195 UINT8 btm_ble_vendor_alloc_irk_entry(BD_ADDR target_bda, BD_ADDR pseudo_bda)
196 {
197 #if BLE_PRIVACY_SPT == TRUE
198     tBTM_BLE_IRK_ENTRY  *p_irk_entry = &btm_ble_vendor_cb.irk_list[0];
199     UINT8   i;
200
201     for (i = 0; i < btm_cb.cmn_ble_vsc_cb.max_irk_list_sz; i ++, p_irk_entry++)
202     {
203         if (!p_irk_entry->in_use)
204         {
205             memcpy(p_irk_entry->bd_addr, target_bda, BD_ADDR_LEN);
206             memcpy(p_irk_entry->psuedo_bda, pseudo_bda, BD_ADDR_LEN);
207
208             p_irk_entry->index = i;
209             p_irk_entry->in_use = TRUE;
210
211             return i;
212         }
213     }
214 #endif
215     return BTM_CS_IRK_LIST_INVALID;
216 }
217
218 /*******************************************************************************
219 **
220 ** Function         btm_ble_vendor_update_irk_list
221 **
222 ** Description      update IRK entry in local host IRK list
223 **
224 ** Returns          void
225 **
226 *******************************************************************************/
227 void btm_ble_vendor_update_irk_list(BD_ADDR target_bda, BD_ADDR pseudo_bda, BOOLEAN add)
228 {
229 #if BLE_PRIVACY_SPT == TRUE
230     tBTM_BLE_IRK_ENTRY   *p_irk_entry = btm_ble_vendor_find_irk_entry(target_bda);
231     UINT8       i;
232
233     if (add)
234     {
235         if (p_irk_entry == NULL)
236         {
237             if ((i = btm_ble_vendor_alloc_irk_entry(target_bda, pseudo_bda)) == BTM_CS_IRK_LIST_INVALID)
238             {
239                 BTM_TRACE_ERROR("max IRK capacity reached");
240             }
241         }
242         else
243         {
244             BTM_TRACE_WARNING(" IRK already in queue");
245         }
246     }
247     else
248     {
249         if (p_irk_entry != NULL)
250         {
251             memset(p_irk_entry, 0, sizeof(tBTM_BLE_IRK_ENTRY));
252         }
253         else
254         {
255             BTM_TRACE_ERROR("No IRK exist in list, can not remove");
256         }
257     }
258 #endif
259     return ;
260 }
261 /*******************************************************************************
262 **
263 ** Function         btm_ble_vendor_irk_vsc_op_cmpl
264 **
265 ** Description      IRK operation VSC complete handler
266 **
267 ** Parameters
268 **
269 ** Returns          void
270 **
271 *******************************************************************************/
272 void btm_ble_vendor_irk_vsc_op_cmpl (tBTM_VSC_CMPL *p_params)
273 {
274     UINT8  status;
275     UINT8  *p = p_params->p_param_buf, op_subcode;
276     UINT16  evt_len = p_params->param_len;
277     UINT8   i;
278     tBTM_BLE_VENDOR_CB  *p_cb = &btm_ble_vendor_cb;
279     BD_ADDR         target_bda, pseudo_bda, rra;
280
281
282     STREAM_TO_UINT8(status, p);
283
284     evt_len--;
285
286     op_subcode   = *p ++;
287     BTM_TRACE_DEBUG("btm_ble_vendor_irk_vsc_op_cmpl op_subcode = %d", op_subcode);
288     if (evt_len < 1)
289     {
290         BTM_TRACE_ERROR("cannot interpret IRK VSC cmpl callback");
291         return;
292     }
293
294     if (BTM_BLE_META_IRK_ENABLE == op_subcode)
295     {
296         BTM_TRACE_DEBUG("IRK enable: %d, %d", status, op_subcode);
297         return;
298     }
299     else
300     if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST)
301     {
302         if (status == HCI_SUCCESS)
303         {
304             STREAM_TO_UINT8(p_cb->irk_avail_size, p);
305             p_cb->irk_list_size = 0;
306
307             BTM_TRACE_DEBUG("p_cb->irk_list_size = %d", p_cb->irk_avail_size);
308
309             for (i = 0; i < btm_cb.cmn_ble_vsc_cb.max_irk_list_sz; i ++)
310                 memset(&p_cb->irk_list[i], 0, sizeof(tBTM_BLE_IRK_ENTRY));
311         }
312     }
313     else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY)
314     {
315         if (!btm_ble_vendor_deq_irk_pending(target_bda, pseudo_bda))
316         {
317             BTM_TRACE_ERROR("no pending IRK operation");
318             return;
319         }
320
321         if (status == HCI_SUCCESS)
322         {
323             STREAM_TO_UINT8(p_cb->irk_avail_size, p);
324             btm_ble_vendor_update_irk_list(target_bda, pseudo_bda, TRUE);
325         }
326         else if (status == 0x07) /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED  */
327         {
328             p_cb->irk_avail_size = 0;
329             BTM_TRACE_ERROR("IRK Full ");
330         }
331         else
332         {
333             /* give the credit back if invalid parameter failed the operation */
334             p_cb->irk_list_size ++;
335         }
336     }
337     else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY)
338     {
339         if (!btm_ble_vendor_deq_irk_pending(target_bda, pseudo_bda))
340         {
341             BTM_TRACE_ERROR("no pending IRK operation");
342             return;
343         }
344         if (status == HCI_SUCCESS)
345         {
346             STREAM_TO_UINT8(p_cb->irk_avail_size, p);
347             btm_ble_vendor_update_irk_list(target_bda, pseudo_bda, FALSE);
348         }
349         else
350         {
351             /* give the credit back if invalid parameter failed the operation */
352             if (p_cb->irk_avail_size > 0)
353                 p_cb->irk_list_size --;
354         }
355
356     }
357     else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY)
358     {
359         if (status == HCI_SUCCESS)
360         {
361             //STREAM_TO_UINT8(index, p);
362             p += (1 + 16 + 1); /* skip index, IRK value, address type */
363             STREAM_TO_BDADDR(target_bda, p);
364             STREAM_TO_BDADDR(rra, p);
365             btm_ble_refresh_rra(target_bda, rra);
366         }
367     }
368
369 }
370 /*******************************************************************************
371 **
372 ** Function         btm_ble_remove_irk_entry
373 **
374 ** Description      This function to remove an IRK entry from the list
375 **
376 ** Parameters       ble_addr_type: address type
377 **                  ble_addr: LE adddress
378 **
379 ** Returns          status
380 **
381 *******************************************************************************/
382 tBTM_STATUS btm_ble_remove_irk_entry(tBTM_SEC_DEV_REC *p_dev_rec)
383 {
384 #if BLE_PRIVACY_SPT == TRUE
385     UINT8           param[20], *p;
386     tBTM_STATUS     st;
387     tBTM_BLE_VENDOR_CB  *p_cb = &btm_ble_vendor_cb;
388
389     p = param;
390     memset(param, 0, 20);
391
392     UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY);
393     UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
394     BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
395
396     if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
397                                     BTM_BLE_META_REMOVE_IRK_LEN,
398                                     param,
399                                     btm_ble_vendor_irk_vsc_op_cmpl))
400         != BTM_NO_RESOURCES)
401     {
402         btm_ble_vendor_enq_irk_pending(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, FALSE);
403         p_cb->irk_list_size --;
404     }
405
406     return st;
407 #endif
408     return BTM_MODE_UNSUPPORTED;
409 }
410 /*******************************************************************************
411 **
412 ** Function         btm_ble_vendor_clear_irk_list
413 **
414 ** Description      This function clears the IRK entry list
415 **
416 ** Parameters       None.
417 **
418 ** Returns          status
419 **
420 *******************************************************************************/
421 tBTM_STATUS btm_ble_vendor_clear_irk_list(void)
422 {
423 #if BLE_PRIVACY_SPT == TRUE
424     UINT8           param[20], *p;
425     tBTM_STATUS     st;
426
427     p = param;
428     memset(param, 0, 20);
429
430     UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST);
431
432     st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
433                                     BTM_BLE_META_CLEAR_IRK_LEN,
434                                     param,
435                                     btm_ble_vendor_irk_vsc_op_cmpl);
436
437     return st;
438 #endif
439     return BTM_MODE_UNSUPPORTED;
440 }
441 /*******************************************************************************
442 **
443 ** Function         btm_ble_read_irk_entry
444 **
445 ** Description      This function read an IRK entry by index
446 **
447 ** Parameters       entry index.
448 **
449 ** Returns          status
450 **
451 *******************************************************************************/
452 tBTM_STATUS btm_ble_read_irk_entry(BD_ADDR target_bda)
453 {
454 #if BLE_PRIVACY_SPT == TRUE
455     UINT8           param[20], *p;
456     tBTM_STATUS     st = BTM_UNKNOWN_ADDR;
457     tBTM_BLE_IRK_ENTRY *p_entry = btm_ble_vendor_find_irk_entry(target_bda);
458
459     if (p_entry == NULL)
460         return st;
461
462     p = param;
463     memset(param, 0, 20);
464
465     UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY);
466     UINT8_TO_STREAM(p, p_entry->index);
467
468     st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
469                                     BTM_BLE_META_READ_IRK_LEN,
470                                     param,
471                                     btm_ble_vendor_irk_vsc_op_cmpl);
472
473     return st;
474 #endif
475     return BTM_MODE_UNSUPPORTED;
476 }
477
478
479 /*******************************************************************************
480 **
481 ** Function         btm_ble_vendor_enable_irk_list_known_dev
482 **
483 ** Description      This function add all known device with random address into
484 **                  IRK list.
485 **
486 ** Parameters       enable: enable IRK list with known device, or disable it
487 **
488 ** Returns          status
489 **
490 *******************************************************************************/
491 void btm_ble_vendor_irk_list_known_dev(BOOLEAN enable)
492 {
493 #if BLE_PRIVACY_SPT == TRUE
494     UINT8               i;
495     UINT8               count = 0;
496     tBTM_SEC_DEV_REC    *p_dev_rec = &btm_cb.sec_dev_rec[0];
497
498     /* add all known device with random address into IRK list */
499     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev_rec ++)
500     {
501         if (p_dev_rec->sec_flags & BTM_SEC_IN_USE)
502         {
503             if (btm_ble_vendor_irk_list_load_dev(p_dev_rec))
504                 count ++;
505         }
506     }
507
508     if ((count > 0 && enable) || !enable)
509         btm_ble_vendor_enable_irk_feature(enable);
510 #endif
511     return ;
512 }
513 /*******************************************************************************
514 **
515 ** Function         btm_ble_vendor_irk_list_load_dev
516 **
517 ** Description      This function add a device which is using RPA into white list
518 **
519 ** Parameters
520 **
521 ** Returns          status
522 **
523 *******************************************************************************/
524 BOOLEAN btm_ble_vendor_irk_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
525 {
526 #if BLE_PRIVACY_SPT == TRUE
527     UINT8           param[40], *p;
528     tBTM_BLE_VENDOR_CB  *p_cb = &btm_ble_vendor_cb;
529     BOOLEAN         rt = FALSE;
530     tBTM_BLE_IRK_ENTRY  *p_irk_entry = NULL;
531     BTM_TRACE_DEBUG ("btm_ble_vendor_irk_list_load_dev:max_irk_size=%d", p_cb->irk_avail_size);
532     memset(param, 0, 40);
533
534     if (p_dev_rec != NULL && /* RPA is being used and PID is known */
535         (p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0)
536     {
537
538         if ((p_irk_entry = btm_ble_vendor_find_irk_entry_by_psuedo_addr(p_dev_rec->bd_addr)) == NULL &&
539             btm_ble_vendor_find_irk_pending_entry(p_dev_rec->bd_addr, TRUE) == FALSE)
540         {
541
542             if (p_cb->irk_avail_size > 0)
543             {
544                 p = param;
545
546                 UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
547                 ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN);
548                 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
549                 BDADDR_TO_STREAM(p,p_dev_rec->ble.static_addr);
550
551                 if (BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
552                                                 BTM_BLE_META_ADD_IRK_LEN,
553                                                 param,
554                                                 btm_ble_vendor_irk_vsc_op_cmpl)
555                        != BTM_NO_RESOURCES)
556                 {
557                     btm_ble_vendor_enq_irk_pending(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, TRUE);
558                     p_cb->irk_list_size ++;
559                     rt = TRUE;
560                 }
561             }
562         }
563         else
564         {
565             BTM_TRACE_ERROR("Device already in IRK list");
566             rt = TRUE;
567         }
568     }
569     else
570     {
571         BTM_TRACE_DEBUG("Device not a RPA enabled device");
572     }
573     return rt;
574 #endif
575     return FALSE;
576 }
577 /*******************************************************************************
578 **
579 ** Function         btm_ble_vendor_irk_list_remove_dev
580 **
581 ** Description      This function remove the device from IRK list
582 **
583 ** Parameters
584 **
585 ** Returns          status
586 **
587 *******************************************************************************/
588 void btm_ble_vendor_irk_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
589 {
590 #if BLE_PRIVACY_SPT == TRUE
591     tBTM_BLE_VENDOR_CB  *p_cs_cb = &btm_ble_vendor_cb;
592     tBTM_BLE_IRK_ENTRY *p_irk_entry;
593
594     if ((p_irk_entry = btm_ble_vendor_find_irk_entry_by_psuedo_addr(p_dev_rec->bd_addr)) != NULL &&
595         btm_ble_vendor_find_irk_pending_entry(p_dev_rec->bd_addr, FALSE) == FALSE)
596     {
597         btm_ble_remove_irk_entry(p_dev_rec);
598     }
599     else
600     {
601         BTM_TRACE_ERROR("Device not in IRK list");
602     }
603
604     if (p_cs_cb->irk_list_size == 0)
605         btm_ble_vendor_enable_irk_feature(FALSE);
606 #endif
607 }
608 /*******************************************************************************
609 **
610 ** Function         btm_ble_vendor_disable_irk_list
611 **
612 ** Description      disable LE resolve address feature
613 **
614 ** Parameters
615 **
616 ** Returns          status
617 **
618 *******************************************************************************/
619 void btm_ble_vendor_disable_irk_list(void)
620 {
621 #if BLE_PRIVACY_SPT == TRUE
622     btm_ble_vendor_enable_irk_feature(FALSE);
623 #endif
624 }
625
626 /*******************************************************************************
627 **
628 ** Function         btm_ble_vendor_enable_irk_feature
629 **
630 ** Description      This function is called to enable or disable the RRA
631 **                  offloading feature.
632 **
633 ** Parameters       enable: enable or disable the RRA offloading feature
634 **
635 ** Returns          BTM_SUCCESS if successful
636 **
637 *******************************************************************************/
638 tBTM_STATUS btm_ble_vendor_enable_irk_feature(BOOLEAN enable)
639 {
640 #if BLE_PRIVACY_SPT == TRUE
641     UINT8           param[20], *p;
642     tBTM_STATUS     st = BTM_WRONG_MODE;
643     tBTM_BLE_PF_COUNT *p_bda_filter;
644
645     p = param;
646     memset(param, 0, 20);
647
648     /* select feature based on control block settings */
649     UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
650     UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);
651
652     st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
653                                param, btm_ble_vendor_irk_vsc_op_cmpl);
654
655     return st;
656 #endif
657     return BTM_MODE_UNSUPPORTED;
658 }
659
660 #endif
661
662 /*******************************************************************************
663 **
664 ** Function         btm_ble_vendor_init
665 **
666 ** Description      Initialize customer specific feature information in host stack
667 **
668 ** Parameters  Max IRK list size
669 **                   Max filter supported
670 **
671 ** Returns          void
672 **
673 *******************************************************************************/
674 void btm_ble_vendor_init(UINT8 max_irk_list_sz)
675 {
676     memset(&btm_ble_vendor_cb, 0, sizeof(tBTM_BLE_VENDOR_CB));
677
678 #if BLE_PRIVACY_SPT == TRUE
679     if (max_irk_list_sz > 0)
680     {
681         btm_ble_vendor_cb.irk_list =  (tBTM_BLE_IRK_ENTRY*)GKI_getbuf (sizeof (tBTM_BLE_IRK_ENTRY)
682                                                                         * max_irk_list_sz);
683         btm_ble_vendor_cb.irk_pend_q.irk_q =  (BD_ADDR*) GKI_getbuf (sizeof (BD_ADDR) *
684                                                                      max_irk_list_sz);
685         btm_ble_vendor_cb.irk_pend_q.irk_q_random_pseudo = (BD_ADDR*)GKI_getbuf (sizeof (BD_ADDR) *
686                                                                                  max_irk_list_sz);
687         btm_ble_vendor_cb.irk_pend_q.irk_q_action = (UINT8*) GKI_getbuf (max_irk_list_sz);
688     }
689
690     btm_ble_vendor_cb.irk_avail_size = max_irk_list_sz;
691
692     if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
693         return;
694 #endif
695 }
696
697 /*******************************************************************************
698 **
699 ** Function         btm_ble_vendor_cleanup
700 **
701 ** Description      Cleanup VSC specific dynamic memory
702 **
703 ** Parameters
704 **
705 ** Returns          void
706 **
707 *******************************************************************************/
708 void btm_ble_vendor_cleanup(void)
709 {
710 #if BLE_PRIVACY_SPT == TRUE
711     if (btm_ble_vendor_cb.irk_list)
712         GKI_freebuf(btm_ble_vendor_cb.irk_list);
713
714     if (btm_ble_vendor_cb.irk_pend_q.irk_q)
715        GKI_freebuf(btm_ble_vendor_cb.irk_pend_q.irk_q);
716
717     if (btm_ble_vendor_cb.irk_pend_q.irk_q_random_pseudo)
718         GKI_freebuf(btm_ble_vendor_cb.irk_pend_q.irk_q_random_pseudo);
719
720     if (btm_ble_vendor_cb.irk_pend_q.irk_q_action)
721         GKI_freebuf(btm_ble_vendor_cb.irk_pend_q.irk_q_action);
722 #endif
723     memset(&btm_ble_vendor_cb, 0, sizeof(tBTM_BLE_VENDOR_CB));
724 }
725
726
727