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