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