]> granicus.if.org Git - esp-idf/blob - components/bt/bluedroid/stack/btm/btm_ble_privacy.c
Merge branch 'bugfix/spiram_malloc_reserve_internal_fragments' into 'master'
[esp-idf] / components / bt / bluedroid / stack / btm / btm_ble_privacy.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-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 controller based privacy.
22  *
23  ******************************************************************************/
24 #include <string.h>
25 #include "common/bt_target.h"
26
27 #if (BLE_INCLUDED == TRUE && BLE_PRIVACY_SPT == TRUE)
28 #include "stack/bt_types.h"
29 #include "stack/hcimsgs.h"
30 #include "stack/btu.h"
31 //#include "vendor_hcidefs.h"
32 #include "btm_int.h"
33 #include "device/controller.h"
34 #include "stack/hcidefs.h"
35
36 #define HCI_VENDOR_BLE_RPA_VSC          (0x0155 | HCI_GRP_VENDOR_SPECIFIC)
37
38 /* RPA offload VSC specifics */
39 #define BTM_BLE_META_IRK_ENABLE         0x01
40 #define BTM_BLE_META_ADD_IRK_ENTRY      0x02
41 #define BTM_BLE_META_REMOVE_IRK_ENTRY   0x03
42 #define BTM_BLE_META_CLEAR_IRK_LIST     0x04
43 #define BTM_BLE_META_READ_IRK_ENTRY     0x05
44 #define BTM_BLE_META_CS_RESOLVE_ADDR    0x00000001
45 #define BTM_BLE_IRK_ENABLE_LEN          2
46
47 #define BTM_BLE_META_ADD_IRK_LEN        24
48 #define BTM_BLE_META_REMOVE_IRK_LEN     8
49 #define BTM_BLE_META_CLEAR_IRK_LEN      1
50 #define BTM_BLE_META_READ_IRK_LEN       2
51 #define BTM_BLE_META_ADD_WL_ATTR_LEN    9
52
53 /*******************************************************************************
54 **         Functions implemented controller based privacy using Resolving List
55 *******************************************************************************/
56 /*******************************************************************************
57 **
58 ** Function         btm_ble_enq_resolving_list_pending
59 **
60 ** Description      add target address into resolving pending operation queue
61 **
62 ** Parameters       target_bda: target device address
63 **                  add_entry: TRUE for add entry, FALSE for remove entry
64 **
65 ** Returns          void
66 **
67 *******************************************************************************/
68 void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, UINT8 op_code)
69 {
70     tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
71
72     memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN);
73     p_q->resolve_q_action[p_q->q_next] = op_code;
74     p_q->q_next ++;
75     p_q->q_next %= controller_get_interface()->get_ble_resolving_list_max_size();
76 }
77
78 /*******************************************************************************
79 **
80 ** Function         btm_ble_brcm_find_resolving_pending_entry
81 **
82 ** Description      check to see if the action is in pending list
83 **
84 ** Parameters       TRUE: action pending;
85 **                  FALSE: new action
86 **
87 ** Returns          void
88 **
89 *******************************************************************************/
90 BOOLEAN btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr, UINT8 action)
91 {
92     tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
93
94     for (UINT8 i = p_q->q_pending; i != p_q->q_next;) {
95         if (memcmp(p_q->resolve_q_random_pseudo[i], pseudo_addr, BD_ADDR_LEN) == 0 &&
96                 action == p_q->resolve_q_action[i]) {
97             return TRUE;
98         }
99
100         i ++;
101         i %= controller_get_interface()->get_ble_resolving_list_max_size();
102     }
103     return FALSE;
104 }
105
106 /*******************************************************************************
107 **
108 ** Function         btm_ble_deq_resolving_pending
109 **
110 ** Description      dequeue target address from resolving pending operation queue
111 **
112 ** Parameters       pseudo_addr: pseudo_addr device address
113 **
114 ** Returns          void
115 **
116 *******************************************************************************/
117 BOOLEAN btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr)
118 {
119     tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
120
121     if (p_q->q_next != p_q->q_pending) {
122         memcpy(pseudo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending], BD_ADDR_LEN);
123         memset(p_q->resolve_q_random_pseudo[p_q->q_pending], 0, BD_ADDR_LEN);
124         p_q->q_pending ++;
125         p_q->q_pending %= controller_get_interface()->get_ble_resolving_list_max_size();
126         return TRUE;
127     }
128
129     return FALSE;
130 }
131
132 /*******************************************************************************
133 **
134 ** Function         btm_ble_clear_irk_index
135 **
136 ** Description      clear IRK list index mask for availability
137 **
138 ** Returns          none
139 **
140 *******************************************************************************/
141 void btm_ble_clear_irk_index(UINT8 index)
142 {
143     UINT8 byte;
144     UINT8 bit;
145
146     if (index < controller_get_interface()->get_ble_resolving_list_max_size()) {
147         byte = index / 8;
148         bit = index % 8;
149         btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit));
150     }
151 }
152
153 /*******************************************************************************
154 **
155 ** Function         btm_ble_find_irk_index
156 **
157 ** Description      find the first available IRK list index
158 **
159 ** Returns          index from 0 ~ max (127 default)
160 **
161 *******************************************************************************/
162 UINT8 btm_ble_find_irk_index(void)
163 {
164     UINT8 i = 0;
165     UINT8 byte;
166     UINT8 bit;
167
168     while (i < controller_get_interface()->get_ble_resolving_list_max_size()) {
169         byte = i / 8;
170         bit = i % 8;
171
172         if ((btm_cb.ble_ctr_cb.irk_list_mask[byte] & (1 << bit)) == 0) {
173             btm_cb.ble_ctr_cb.irk_list_mask[byte] |= (1 << bit);
174             return i;
175         }
176         i++;
177     }
178
179     BTM_TRACE_ERROR ("%s failed, list full", __func__);
180     return i;
181 }
182
183 /*******************************************************************************
184 **
185 ** Function         btm_ble_update_resolving_list
186 **
187 ** Description      update resolving list entry in host maintained record
188 **
189 ** Returns          void
190 **
191 *******************************************************************************/
192 void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, BOOLEAN add)
193 {
194     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_bda);
195     if (p_dev_rec == NULL) {
196         return;
197     }
198
199     if (add) {
200         p_dev_rec->ble.in_controller_list |= BTM_RESOLVING_LIST_BIT;
201         if (!controller_get_interface()->supports_ble_privacy()) {
202             p_dev_rec->ble.resolving_list_index = btm_ble_find_irk_index();
203         }
204     } else {
205         p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
206         if (!controller_get_interface()->supports_ble_privacy()) {
207             /* clear IRK list index mask */
208             btm_ble_clear_irk_index(p_dev_rec->ble.resolving_list_index);
209             p_dev_rec->ble.resolving_list_index = 0;
210         }
211     }
212 }
213
214 /*******************************************************************************
215 **
216 ** Function         btm_ble_clear_resolving_list_complete
217 **
218 ** Description      This function is called when command complete for
219 **                  clear resolving list
220 **
221 ** Returns          void
222 **
223 *******************************************************************************/
224 void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len)
225 {
226     UINT8 status = 0;
227     STREAM_TO_UINT8(status, p);
228
229     BTM_TRACE_DEBUG("%s status=%d", __func__, status);
230
231     if (status == HCI_SUCCESS) {
232         if (evt_len >= 3) {
233             /* VSC complete has one extra byte for op code and list size, skip it here */
234             p ++;
235
236             /* updated the available list size, and current list size */
237             uint8_t irk_list_sz_max = 0;
238             STREAM_TO_UINT8(irk_list_sz_max, p);
239
240             if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
241                 btm_ble_resolving_list_init(irk_list_sz_max);
242             }
243
244             uint8_t irk_mask_size = (irk_list_sz_max % 8) ?
245                                     (irk_list_sz_max / 8 + 1) : (irk_list_sz_max / 8);
246             memset(btm_cb.ble_ctr_cb.irk_list_mask, 0, irk_mask_size);
247         }
248
249         btm_cb.ble_ctr_cb.resolving_list_avail_size =
250             controller_get_interface()->get_ble_resolving_list_max_size();
251
252         BTM_TRACE_DEBUG("%s resolving_list_avail_size=%d",
253                         __func__, btm_cb.ble_ctr_cb.resolving_list_avail_size);
254
255         for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; ++i) {
256             btm_cb.sec_dev_rec[i].ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
257         }
258     }
259 }
260
261 /*******************************************************************************
262 **
263 ** Function         btm_ble_add_resolving_list_entry_complete
264 **
265 ** Description      This function is called when command complete for
266 **                  add resolving list entry
267 **
268 ** Returns          void
269 **
270 *******************************************************************************/
271 void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
272 {
273     UINT8 status;
274     STREAM_TO_UINT8(status, p);
275
276     BTM_TRACE_DEBUG("%s status = %d", __func__, status);
277
278     BD_ADDR pseudo_bda;
279     if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
280         BTM_TRACE_DEBUG("no pending resolving list operation");
281         return;
282     }
283
284     if (status == HCI_SUCCESS) {
285         /* privacy 1.2 command complete does not have these extra byte */
286         if (evt_len > 2) {
287             /* VSC complete has one extra byte for op code, skip it here */
288             p ++;
289             STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
290         } else {
291             btm_cb.ble_ctr_cb.resolving_list_avail_size --;
292         }
293     } else if (status == HCI_ERR_MEMORY_FULL) { /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED  */
294         btm_cb.ble_ctr_cb.resolving_list_avail_size = 0;
295         BTM_TRACE_DEBUG("%s Resolving list Full ", __func__);
296     }
297 }
298
299 /*******************************************************************************
300 **
301 ** Function         btm_ble_remove_resolving_list_entry_complete
302 **
303 ** Description      This function is called when command complete for
304 **                  remove resolving list entry
305 **
306 ** Returns          void
307 **
308 *******************************************************************************/
309 void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
310 {
311     BD_ADDR pseudo_bda;
312     UINT8 status;
313
314     STREAM_TO_UINT8(status, p);
315
316     BTM_TRACE_DEBUG("%s status = %d", __func__, status);
317
318     if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
319         BTM_TRACE_ERROR("%s no pending resolving list operation", __func__);
320         return;
321     }
322
323     if (status == HCI_SUCCESS) {
324         /* proprietary: spec does not have these extra bytes */
325         if (evt_len > 2) {
326             p ++; /* skip opcode */
327             STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
328         } else {
329             btm_cb.ble_ctr_cb.resolving_list_avail_size++;
330         }
331     }
332 }
333
334 /*******************************************************************************
335 **
336 ** Function         btm_ble_read_resolving_list_entry_complete
337 **
338 ** Description      This function is called when command complete for
339 **                  remove resolving list entry
340 **
341 ** Returns          void
342 **
343 *******************************************************************************/
344 void btm_ble_read_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
345 {
346     UINT8           status, rra_type = BTM_BLE_ADDR_PSEUDO;
347     BD_ADDR         rra, pseudo_bda;
348
349     STREAM_TO_UINT8  (status, p);
350
351     BTM_TRACE_DEBUG("%s status = %d", __func__, status);
352
353     if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
354         BTM_TRACE_ERROR("no pending resolving list operation");
355         return;
356     }
357
358     if (status == HCI_SUCCESS) {
359         /* proprietary spec has extra bytes */
360         if (evt_len > 8) {
361             p += (2 + 16 + 1 + 6); /* skip subcode, index, IRK value, address type, identity addr type */
362             STREAM_TO_BDADDR(rra, p);
363
364             BTM_TRACE_ERROR("%s peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
365                             __func__, rra[0], rra[1], rra[2], rra[3], rra[4], rra[5]);
366         } else {
367             STREAM_TO_BDADDR(rra, p);
368         }
369         btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type);
370     }
371 }
372 /*******************************************************************************
373                 VSC that implement controller based privacy
374 ********************************************************************************/
375 /*******************************************************************************
376 **
377 ** Function         btm_ble_resolving_list_vsc_op_cmpl
378 **
379 ** Description      IRK operation VSC complete handler
380 **
381 ** Parameters
382 **
383 ** Returns          void
384 **
385 *******************************************************************************/
386 void btm_ble_resolving_list_vsc_op_cmpl (tBTM_VSC_CMPL *p_params)
387 {
388     UINT8  *p = p_params->p_param_buf, op_subcode;
389     UINT16  evt_len = p_params->param_len;
390
391     op_subcode   = *(p + 1);
392
393     BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode);
394
395     if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) {
396         btm_ble_clear_resolving_list_complete(p, evt_len);
397     } else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY) {
398         btm_ble_add_resolving_list_entry_complete(p, evt_len);
399     } else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY) {
400         btm_ble_remove_resolving_list_entry_complete(p, evt_len);
401     } else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY) {
402         btm_ble_read_resolving_list_entry_complete(p, evt_len);
403     } else if (op_subcode == BTM_BLE_META_IRK_ENABLE) {
404         /* RPA offloading enable/disabled */
405     }
406 }
407
408 /*******************************************************************************
409 **
410 ** Function         btm_ble_remove_resolving_list_entry
411 **
412 ** Description      This function to remove an IRK entry from the list
413 **
414 ** Parameters       ble_addr_type: address type
415 **                  ble_addr: LE adddress
416 **
417 ** Returns          status
418 **
419 *******************************************************************************/
420 tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
421 {
422     /* if controller does not support RPA offloading or privacy 1.2, skip */
423     if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
424         return BTM_WRONG_MODE;
425     }
426
427     tBTM_STATUS st = BTM_NO_RESOURCES;
428     if (controller_get_interface()->supports_ble_privacy()) {
429         if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
430                 p_dev_rec->ble.static_addr)) {
431             st =  BTM_CMD_STARTED;
432         }
433     } else {
434         UINT8 param[20] = {0};
435         UINT8 *p = param;
436
437         UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY);
438         UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
439         BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
440
441         st = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
442                                        BTM_BLE_META_REMOVE_IRK_LEN,
443                                        param,
444                                        btm_ble_resolving_list_vsc_op_cmpl);
445     }
446
447     if (st == BTM_CMD_STARTED) {
448         btm_ble_enq_resolving_list_pending( p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY);
449     }
450
451     return st;
452 }
453
454 /*******************************************************************************
455 **
456 ** Function         btm_ble_clear_resolving_list
457 **
458 ** Description      This function clears the resolving  list
459 **
460 ** Parameters       None.
461 **
462 ** Returns          status
463 **
464 *******************************************************************************/
465 tBTM_STATUS btm_ble_clear_resolving_list(void)
466 {
467     tBTM_STATUS st = BTM_NO_RESOURCES;
468
469     if (controller_get_interface()->supports_ble_privacy()) {
470         if (btsnd_hcic_ble_clear_resolving_list()) {
471             st =  BTM_SUCCESS;
472         }
473     } else {
474         UINT8 param[20] = {0};
475         UINT8 *p = param;
476
477         UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST);
478         st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
479                                         BTM_BLE_META_CLEAR_IRK_LEN,
480                                         param,
481                                         btm_ble_resolving_list_vsc_op_cmpl);
482     }
483
484     return st;
485 }
486
487 /*******************************************************************************
488 **
489 ** Function         btm_ble_read_resolving_list_entry
490 **
491 ** Description      This function read an IRK entry by index
492 **
493 ** Parameters       entry index.
494 **
495 ** Returns          status
496 **
497 *******************************************************************************/
498 tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
499 {
500     tBTM_STATUS st = BTM_NO_RESOURCES;
501
502     if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)) {
503         return BTM_WRONG_MODE;
504     }
505
506     if (controller_get_interface()->supports_ble_privacy()) {
507         if (btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type,
508                 p_dev_rec->ble.static_addr)) {
509             st =  BTM_CMD_STARTED;
510         }
511     } else {
512         UINT8 param[20] = {0};
513         UINT8 *p = param;
514
515         UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY);
516         UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index);
517
518         st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
519                                         BTM_BLE_META_READ_IRK_LEN,
520                                         param,
521                                         btm_ble_resolving_list_vsc_op_cmpl);
522     }
523
524     if (st == BTM_CMD_STARTED)
525         btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
526                                            BTM_BLE_META_READ_IRK_ENTRY);
527
528     return st;
529 }
530
531
532 /*******************************************************************************
533 **
534 ** Function         btm_ble_suspend_resolving_list_activity
535 **
536 ** Description      This function suspends all resolving list activity, including
537 **                  scan, initiating, and advertising, if resolving list is being
538 **                  enabled.
539 **
540 ** Parameters
541 **
542 ** Returns          TRUE if suspended; FALSE otherwise
543 **
544 *******************************************************************************/
545 BOOLEAN btm_ble_suspend_resolving_list_activity(void)
546 {
547     tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
548
549     /* if resolving list is not enabled, do not need to terminate any activity */
550     /* if asking for stop all activity */
551     /* if already suspended */
552     if (p_ble_cb->suspended_rl_state != BTM_BLE_RL_IDLE) {
553         return TRUE;
554     }
555
556     /* direct connection active, wait until it completed */
557     if (btm_ble_get_conn_st() == BLE_DIR_CONN) {
558         BTM_TRACE_ERROR("resolving list can not be edited, EnQ now");
559         return FALSE;
560     }
561
562     p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
563
564     if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) {
565         btm_ble_stop_adv();
566         p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV;
567     }
568
569     if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
570         btm_ble_stop_scan();
571         p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN;
572     }
573
574     if (btm_ble_suspend_bg_conn()) {
575         p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT;
576     }
577
578     return TRUE;
579 }
580
581 /*******************************************************************************
582 **
583 ** Function         btm_ble_resume_resolving_list_activity
584 **
585 ** Description      This function resumes the resolving list activity, including
586 **                  scanning, initiating, and advertising, if any of these
587 **                  activities has been suspended earlier.
588 **
589 ** Returns          none
590 **
591 *******************************************************************************/
592 void btm_ble_resume_resolving_list_activity(void)
593 {
594     tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
595
596     if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) {
597         btm_ble_start_adv();
598     }
599
600     if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) {
601         btm_ble_start_scan();
602     }
603
604     if  (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) {
605         btm_ble_resume_bg_conn();
606     }
607
608     p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
609 }
610
611 /*******************************************************************************
612 **
613 ** Function         btm_ble_vendor_enable_irk_feature
614 **
615 ** Description      This function is called to enable or disable the RRA
616 **                  offloading feature.
617 **
618 ** Parameters       enable: enable or disable the RRA offloading feature
619 **
620 ** Returns          BTM_SUCCESS if successful
621 **
622 *******************************************************************************/
623 tBTM_STATUS btm_ble_vendor_enable_irk_feature(BOOLEAN enable)
624 {
625     UINT8           param[20], *p;
626     tBTM_STATUS     st = BTM_MODE_UNSUPPORTED;
627
628     p = param;
629     memset(param, 0, 20);
630
631     /* select feature based on control block settings */
632     UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
633     UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);
634
635     st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
636                                     param, btm_ble_resolving_list_vsc_op_cmpl);
637
638     return st;
639 }
640
641 /*******************************************************************************
642 **
643 ** Function         btm_ble_exe_disable_resolving_list
644 **
645 ** Description      execute resolving list disable
646 **
647 ** Returns          none
648 **
649 *******************************************************************************/
650 BOOLEAN btm_ble_exe_disable_resolving_list(void)
651 {
652     if (!btm_ble_suspend_resolving_list_activity()) {
653         return FALSE;
654     }
655
656     if (!controller_get_interface()->supports_ble_privacy()) {
657         btm_ble_vendor_enable_irk_feature(FALSE);
658     } else {
659         btsnd_hcic_ble_set_addr_resolution_enable(FALSE);
660     }
661
662     return TRUE;
663 }
664
665 /*******************************************************************************
666 **
667 ** Function         btm_ble_exe_enable_resolving_list
668 **
669 ** Description      enable LE resolve address list
670 **
671 ** Returns          none
672 **
673 *******************************************************************************/
674 void btm_ble_exe_enable_resolving_list(void)
675 {
676     if (!btm_ble_suspend_resolving_list_activity()) {
677         return;
678     }
679
680     if (!controller_get_interface()->supports_ble_privacy()) {
681         btm_ble_vendor_enable_irk_feature(TRUE);
682     } else {
683         btsnd_hcic_ble_set_addr_resolution_enable(TRUE);
684     }
685 }
686
687 /*******************************************************************************
688 **
689 ** Function         btm_ble_disable_resolving_list
690 **
691 ** Description      Disable LE Address resolution
692 **
693 ** Returns          none
694 **
695 *******************************************************************************/
696 BOOLEAN btm_ble_disable_resolving_list(UINT8 rl_mask, BOOLEAN to_resume )
697 {
698     UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
699
700     /* if controller does not support RPA offloading or privacy 1.2, skip */
701     if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
702         return FALSE;
703     }
704
705     btm_cb.ble_ctr_cb.rl_state &= ~rl_mask;
706
707     if (rl_state != BTM_BLE_RL_IDLE && btm_cb.ble_ctr_cb.rl_state == BTM_BLE_RL_IDLE) {
708         if (btm_ble_exe_disable_resolving_list()) {
709             if (to_resume) {
710                 btm_ble_resume_resolving_list_activity();
711             }
712
713             return TRUE;
714         } else {
715             return FALSE;
716         }
717     }
718
719     return TRUE;
720 }
721
722 /*******************************************************************************
723 **
724 ** Function         btm_ble_resolving_list_load_dev
725 **
726 ** Description      This function add a device which is using RPA into white list
727 **
728 ** Parameters       pointer to device security record
729 **
730 ** Returns          TRUE if device added, otherwise falase.
731 **
732 *******************************************************************************/
733 BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
734 {
735     BOOLEAN rt = FALSE;
736 #if (SMP_INCLUDED == TRUE)
737     UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
738
739     BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d\n", __func__,
740                     btm_cb.ble_ctr_cb.privacy_mode);
741
742     /* if controller does not support RPA offloading or privacy 1.2, skip */
743     if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
744         return FALSE;
745     }
746
747     BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d\n",
748                     __func__, btm_cb.ble_ctr_cb.privacy_mode);
749
750     /* only add RPA enabled device into resolving list */
751     if (p_dev_rec != NULL && /* RPA is being used and PID is known */
752             (p_dev_rec->sec_flags & BTM_SEC_IN_USE) != 0 &&
753             ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
754              (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0)) {
755         if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
756                 btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
757                         BTM_BLE_META_ADD_IRK_ENTRY) == FALSE) {
758             if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0) {
759                 if (rl_mask) {
760                     if (!btm_ble_disable_resolving_list (rl_mask, FALSE)) {
761                         return FALSE;
762                     }
763                 }
764
765                 btm_ble_update_resolving_list(p_dev_rec->bd_addr, TRUE);
766                 if (controller_get_interface()->supports_ble_privacy()) {
767                     BD_ADDR dummy_bda = {0};
768                     if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0) {
769                         memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
770                         p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
771                     }
772                     /* It will cause that scanner doesn't send scan request to advertiser
773                      * which has sent IRK to us and we have stored the IRK in controller.
774                      * It is a design problem of hardware. The temporal solution is not to 
775                      * send the key to the controller and then resolve the random address in host. */
776                     /*
777                     BTM_TRACE_DEBUG("%s:adding device to controller resolving list\n", __func__);
778                     UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
779                     UINT8 *local_irk = btm_cb.devcb.id_keys.irk;
780                     //use identical IRK for now
781                     rt = btsnd_hcic_ble_add_device_resolving_list(p_dev_rec->ble.static_addr_type,
782                            p_dev_rec->ble.static_addr, peer_irk, local_irk);
783                     */
784                 } else {
785                     UINT8 param[40] = {0};
786                     UINT8 *p = param;
787
788                     UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
789                     ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN);
790                     UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
791                     BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
792
793                     if (BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
794                                                    BTM_BLE_META_ADD_IRK_LEN,
795                                                    param,
796                                                    btm_ble_resolving_list_vsc_op_cmpl)
797                             == BTM_CMD_STARTED) {
798                         rt = TRUE;
799                     }
800                 }
801
802                 if (rt)
803                     btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
804                                                        BTM_BLE_META_ADD_IRK_ENTRY);
805
806                 /* if resolving list has been turned on, re-enable it */
807                 if (rl_mask) {
808                     btm_ble_enable_resolving_list(rl_mask);
809                 } else {
810                     btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
811                 }
812             }
813         } else {
814             BTM_TRACE_DEBUG("Device already in Resolving list\n");
815             rt = TRUE;
816         }
817     } else {
818         BTM_TRACE_DEBUG("Device not a RPA enabled device\n");
819     }
820 #endif  ///SMP_INCLUDED == TRUE
821     return rt;
822 }
823
824 /*******************************************************************************
825 **
826 ** Function         btm_ble_resolving_list_remove_dev
827 **
828 ** Description      This function removes the device from resolving list
829 **
830 ** Parameters
831 **
832 ** Returns          status
833 **
834 *******************************************************************************/
835 void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
836 {
837     UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
838
839     BTM_TRACE_EVENT ("%s\n", __func__);
840     if (rl_mask) {
841         if (!btm_ble_disable_resolving_list (rl_mask, FALSE)) {
842             return;
843         }
844     }
845
846     if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
847             btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
848                     BTM_BLE_META_REMOVE_IRK_ENTRY) == FALSE) {
849         btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
850         btm_ble_remove_resolving_list_entry(p_dev_rec);
851     } else {
852         BTM_TRACE_DEBUG("Device not in resolving list\n");
853     }
854
855     /* if resolving list has been turned on, re-enable it */
856     if (rl_mask) {
857         btm_ble_enable_resolving_list(rl_mask);
858     }
859 }
860
861 /*******************************************************************************
862 **
863 ** Function         btm_ble_enable_resolving_list
864 **
865 ** Description      enable LE resolve address list
866 **
867 ** Returns          none
868 **
869 *******************************************************************************/
870 void btm_ble_enable_resolving_list(UINT8 rl_mask)
871 {
872     UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
873
874     btm_cb.ble_ctr_cb.rl_state |= rl_mask;
875     if (rl_state == BTM_BLE_RL_IDLE &&
876             btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
877             controller_get_interface()->get_ble_resolving_list_max_size() != 0) {
878         btm_ble_exe_enable_resolving_list();
879         btm_ble_resume_resolving_list_activity();
880     }
881 }
882
883 /*******************************************************************************
884 **
885 ** Function         btm_ble_resolving_list_empty
886 **
887 ** Description      check to see if resoving list is empty or not
888 **
889 ** Returns          TRUE: empty; FALSE non-empty
890 **
891 *******************************************************************************/
892 BOOLEAN btm_ble_resolving_list_empty(void)
893 {
894     return (controller_get_interface()->get_ble_resolving_list_max_size() ==
895             btm_cb.ble_ctr_cb.resolving_list_avail_size);
896 }
897
898 /*******************************************************************************
899 **
900 ** Function         btm_ble_enable_resolving_list_for_platform
901 **
902 ** Description      enable/disable resolving list feature depending on if any
903 **                  resolving list is empty and whitelist is involoved in the
904 **                  operation.
905 **
906 ** Returns          none
907 **
908 *******************************************************************************/
909 void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask)
910 {
911     /* if controller does not support, skip */
912     if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
913         return;
914     }
915
916     if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE) {
917         if (controller_get_interface()->get_ble_resolving_list_max_size() >
918                 btm_cb.ble_ctr_cb.resolving_list_avail_size) {
919             btm_ble_enable_resolving_list(rl_mask);
920         } else {
921             btm_ble_disable_resolving_list(rl_mask, TRUE);
922         }
923         return;
924     }
925
926     tBTM_SEC_DEV_REC *p_dev = &btm_cb.sec_dev_rec[0];
927     for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev ++) {
928         if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
929                 (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT)) {
930             btm_ble_enable_resolving_list(rl_mask);
931             return;
932         }
933     }
934     btm_ble_disable_resolving_list(rl_mask, TRUE);
935 }
936
937 /*******************************************************************************
938 **
939 ** Function         btm_ble_resolving_list_init
940 **
941 ** Description      Initialize resolving list in host stack
942 **
943 ** Parameters       Max resolving list size
944 **
945 ** Returns          void
946 **
947 *******************************************************************************/
948 void btm_ble_resolving_list_init(UINT8 max_irk_list_sz)
949 {
950     tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
951     UINT8 irk_mask_size =  (max_irk_list_sz % 8) ?
952                            (max_irk_list_sz / 8 + 1) : (max_irk_list_sz / 8);
953
954     if (max_irk_list_sz > 0) {
955         p_q->resolve_q_random_pseudo = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz);
956         p_q->resolve_q_action = (UINT8 *)osi_malloc(max_irk_list_sz);
957
958         /* RPA offloading feature */
959         if (btm_cb.ble_ctr_cb.irk_list_mask == NULL) {
960             btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)osi_malloc(irk_mask_size);
961         }
962
963         BTM_TRACE_DEBUG ("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
964     }
965
966     controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
967     btm_ble_clear_resolving_list();
968     btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
969 }
970
971 /*******************************************************************************
972 **
973 ** Function         btm_ble_resolving_list_cleanup
974 **
975 ** Description      Cleanup resolving list dynamic memory
976 **
977 ** Parameters
978 **
979 ** Returns          void
980 **
981 *******************************************************************************/
982 void btm_ble_resolving_list_cleanup(void)
983 {
984     tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
985
986     if (p_q->resolve_q_random_pseudo) {
987         osi_free(p_q->resolve_q_random_pseudo);
988         p_q->resolve_q_random_pseudo = NULL;
989     }
990
991     if (p_q->resolve_q_action) {
992         osi_free(p_q->resolve_q_action);
993         p_q->resolve_q_action = NULL;
994     }
995
996     controller_get_interface()->set_ble_resolving_list_max_size(0);
997     if (btm_cb.ble_ctr_cb.irk_list_mask) {
998         osi_free(btm_cb.ble_ctr_cb.irk_list_mask);
999         btm_cb.ble_ctr_cb.irk_list_mask = NULL;
1000     }
1001
1002 }
1003 #endif