blob: c8fe5412700303b2c5c4f8222832f8351f33ef44 [file] [log] [blame]
Satya Calloji444a8da2015-03-06 10:38:22 -08001/******************************************************************************
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*******************************************************************************/
Chaojing Sune2805532015-04-22 13:40:21 -070065void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, UINT8 op_code)
Satya Calloji444a8da2015-03-06 10:38:22 -080066{
Chaojing Sune2805532015-04-22 13:40:21 -070067 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
Satya Calloji444a8da2015-03-06 10:38:22 -080068
Chaojing Sune2805532015-04-22 13:40:21 -070069 memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN);
Satya Calloji444a8da2015-03-06 10:38:22 -080070 p_q->resolve_q_action[p_q->q_next] = op_code;
Satya Calloji444a8da2015-03-06 10:38:22 -080071 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*******************************************************************************/
Chaojing Sune2805532015-04-22 13:40:21 -070087BOOLEAN btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr, UINT8 action)
Satya Calloji444a8da2015-03-06 10:38:22 -080088{
89 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
90
Chaojing Sune2805532015-04-22 13:40:21 -070091 for (UINT8 i = p_q->q_pending; i != p_q->q_next;)
Satya Calloji444a8da2015-03-06 10:38:22 -080092 {
Chaojing Sune2805532015-04-22 13:40:21 -070093 if (memcmp(p_q->resolve_q_random_pseudo[i], pseudo_addr, BD_ADDR_LEN) == 0 &&
Satya Calloji444a8da2015-03-06 10:38:22 -080094 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**
Chaojing Sune2805532015-04-22 13:40:21 -0700109** Parameters pseudo_addr: pseudo_addr device address
Satya Calloji444a8da2015-03-06 10:38:22 -0800110**
111** Returns void
112**
113*******************************************************************************/
Chaojing Sune2805532015-04-22 13:40:21 -0700114BOOLEAN btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr)
Satya Calloji444a8da2015-03-06 10:38:22 -0800115{
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 {
Chaojing Sune2805532015-04-22 13:40:21 -0700120 memcpy(pseudo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending], BD_ADDR_LEN);
Satya Calloji444a8da2015-03-06 10:38:22 -0800121 memset(p_q->resolve_q_random_pseudo[p_q->q_pending], 0, BD_ADDR_LEN);
Satya Calloji444a8da2015-03-06 10:38:22 -0800122 p_q->q_pending ++;
123 p_q->q_pending %= controller_get_interface()->get_ble_resolving_list_max_size();
Satya Calloji444a8da2015-03-06 10:38:22 -0800124 return TRUE;
125 }
Chaojing Sune2805532015-04-22 13:40:21 -0700126
Satya Calloji444a8da2015-03-06 10:38:22 -0800127 return FALSE;
128}
129
130/*******************************************************************************
131**
Chaojing Sune2805532015-04-22 13:40:21 -0700132** Function btm_ble_clear_irk_index
Satya Calloji444a8da2015-03-06 10:38:22 -0800133**
Chaojing Sune2805532015-04-22 13:40:21 -0700134** Description clear IRK list index mask for availability
Satya Calloji444a8da2015-03-06 10:38:22 -0800135**
Chaojing Sune2805532015-04-22 13:40:21 -0700136** Returns none
Satya Calloji444a8da2015-03-06 10:38:22 -0800137**
138*******************************************************************************/
Chaojing Sune2805532015-04-22 13:40:21 -0700139void btm_ble_clear_irk_index(UINT8 index)
Satya Calloji444a8da2015-03-06 10:38:22 -0800140{
Chaojing Sune2805532015-04-22 13:40:21 -0700141 UINT8 byte;
142 UINT8 bit;
Satya Calloji444a8da2015-03-06 10:38:22 -0800143
Satya Calloji0baef632015-05-19 16:08:40 -0700144 if (index < controller_get_interface()->get_ble_resolving_list_max_size())
Satya Calloji444a8da2015-03-06 10:38:22 -0800145 {
Satya Calloji0baef632015-05-19 16:08:40 -0700146 byte = index / 8;
147 bit = index % 8;
148 btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit));
Satya Calloji444a8da2015-03-06 10:38:22 -0800149 }
Chaojing Sune2805532015-04-22 13:40:21 -0700150}
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*******************************************************************************/
161UINT8 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;
Satya Calloji444a8da2015-03-06 10:38:22 -0800182}
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*******************************************************************************/
193void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, BOOLEAN add)
194{
Chaojing Sune2805532015-04-22 13:40:21 -0700195 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_bda);
Satya Calloji444a8da2015-03-06 10:38:22 -0800196 if (p_dev_rec == NULL)
197 return;
198
199 if (add)
200 {
201 p_dev_rec->ble.in_controller_list |= BTM_RESOLVING_LIST_BIT;
Chaojing Sune2805532015-04-22 13:40:21 -0700202 if (!controller_get_interface()->supports_ble_privacy())
203 p_dev_rec->ble.resolving_list_index = btm_ble_find_irk_index();
204 }
205 else
206 {
Satya Calloji444a8da2015-03-06 10:38:22 -0800207 p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
Chaojing Sune2805532015-04-22 13:40:21 -0700208 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 }
Satya Calloji444a8da2015-03-06 10:38:22 -0800214 }
215}
216
Jakub Pawlowskicac784d2016-02-01 11:53:36 -0800217bool 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
Satya Calloji444a8da2015-03-06 10:38:22 -0800224/*******************************************************************************
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*******************************************************************************/
234void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len)
235{
Chaojing Sune2805532015-04-22 13:40:21 -0700236 UINT8 status = 0;
Satya Calloji444a8da2015-03-06 10:38:22 -0800237 STREAM_TO_UINT8(status, p);
238
Chaojing Sune2805532015-04-22 13:40:21 -0700239 BTM_TRACE_DEBUG("%s status=%d", __func__, status);
Satya Calloji444a8da2015-03-06 10:38:22 -0800240
241 if (status == HCI_SUCCESS)
242 {
Chaojing Sune2805532015-04-22 13:40:21 -0700243 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 =
Satya Calloji444a8da2015-03-06 10:38:22 -0800261 controller_get_interface()->get_ble_resolving_list_max_size();
262
Chaojing Sune2805532015-04-22 13:40:21 -0700263 BTM_TRACE_DEBUG("%s resolving_list_avail_size=%d",
Satya Calloji444a8da2015-03-06 10:38:22 -0800264 __func__, btm_cb.ble_ctr_cb.resolving_list_avail_size);
265
Jakub Pawlowskicac784d2016-02-01 11:53:36 -0800266 list_foreach(btm_cb.sec_dev_rec, clear_resolving_list_bit, NULL);
Satya Calloji444a8da2015-03-06 10:38:22 -0800267 }
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*******************************************************************************/
280void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
281{
Chaojing Sune2805532015-04-22 13:40:21 -0700282 UINT8 status;
Satya Calloji444a8da2015-03-06 10:38:22 -0800283 STREAM_TO_UINT8(status, p);
284
285 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
286
287 BD_ADDR pseudo_bda;
Chaojing Sune2805532015-04-22 13:40:21 -0700288 if (!btm_ble_deq_resolving_pending(pseudo_bda))
Satya Calloji444a8da2015-03-06 10:38:22 -0800289 {
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 --;
Satya Calloji444a8da2015-03-06 10:38:22 -0800305 }
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*******************************************************************************/
323void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
324{
Chaojing Sune2805532015-04-22 13:40:21 -0700325 BD_ADDR pseudo_bda;
326 UINT8 status;
Satya Calloji444a8da2015-03-06 10:38:22 -0800327
Chaojing Sune2805532015-04-22 13:40:21 -0700328 STREAM_TO_UINT8(status, p);
Satya Calloji444a8da2015-03-06 10:38:22 -0800329
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 {
Chaojing Sune2805532015-04-22 13:40:21 -0700343 p ++; /* skip opcode */
Satya Calloji444a8da2015-03-06 10:38:22 -0800344 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
345 }
346 else
Chaojing Sune2805532015-04-22 13:40:21 -0700347 btm_cb.ble_ctr_cb.resolving_list_avail_size++;
Satya Calloji444a8da2015-03-06 10:38:22 -0800348 }
349}
Chaojing Sune2805532015-04-22 13:40:21 -0700350
Satya Calloji444a8da2015-03-06 10:38:22 -0800351/*******************************************************************************
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*******************************************************************************/
361void 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*******************************************************************************/
408void 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*******************************************************************************/
451tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
452{
Chaojing Sune2805532015-04-22 13:40:21 -0700453 /* if controller does not support RPA offloading or privacy 1.2, skip */
Nitin Arora04b5e922015-05-21 17:58:36 -0700454 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
Chaojing Sune2805532015-04-22 13:40:21 -0700455 return BTM_WRONG_MODE;
Satya Calloji444a8da2015-03-06 10:38:22 -0800456
Chaojing Sune2805532015-04-22 13:40:21 -0700457 tBTM_STATUS st = BTM_NO_RESOURCES;
Satya Calloji444a8da2015-03-06 10:38:22 -0800458 if (controller_get_interface()->supports_ble_privacy())
459 {
Chaojing Sune2805532015-04-22 13:40:21 -0700460 if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
461 p_dev_rec->ble.static_addr))
Satya Calloji444a8da2015-03-06 10:38:22 -0800462 st = BTM_CMD_STARTED;
Chaojing Sune2805532015-04-22 13:40:21 -0700463 }
464 else
465 {
Satya Calloji444a8da2015-03-06 10:38:22 -0800466 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
Chaojing Sune2805532015-04-22 13:40:21 -0700473 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);
Satya Calloji444a8da2015-03-06 10:38:22 -0800477 }
478
479 if (st == BTM_CMD_STARTED)
Satya Calloji444a8da2015-03-06 10:38:22 -0800480 btm_ble_enq_resolving_list_pending( p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY);
Satya Calloji444a8da2015-03-06 10:38:22 -0800481
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*******************************************************************************/
496tBTM_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*******************************************************************************/
531tBTM_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,
Chaojing Sune2805532015-04-22 13:40:21 -0700541 p_dev_rec->ble.static_addr))
542 st = BTM_CMD_STARTED;
Satya Calloji444a8da2015-03-06 10:38:22 -0800543 }
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)
Chaojing Sune2805532015-04-22 13:40:21 -0700559 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
560 BTM_BLE_META_READ_IRK_ENTRY);
Satya Calloji444a8da2015-03-06 10:38:22 -0800561
562 return st;
563}
564
Satya Calloji877123f2015-04-23 23:39:49 -0700565
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*******************************************************************************/
579BOOLEAN 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*******************************************************************************/
627void 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*******************************************************************************/
655tBTM_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*******************************************************************************/
682BOOLEAN 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*******************************************************************************/
704void 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*******************************************************************************/
724BOOLEAN 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
Satya Calloji444a8da2015-03-06 10:38:22 -0800750/*******************************************************************************
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*******************************************************************************/
761BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
762{
Chaojing Sune2805532015-04-22 13:40:21 -0700763 BOOLEAN rt = FALSE;
Satya Calloji877123f2015-04-23 23:39:49 -0700764 UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
765
Satya Calloji444a8da2015-03-06 10:38:22 -0800766 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__,
Chaojing Sune2805532015-04-22 13:40:21 -0700767 btm_cb.ble_ctr_cb.privacy_mode);
Satya Calloji444a8da2015-03-06 10:38:22 -0800768
Chaojing Sune2805532015-04-22 13:40:21 -0700769 /* 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 */
Satya Calloji444a8da2015-03-06 10:38:22 -0800777 if (p_dev_rec != NULL && /* RPA is being used and PID is known */
Satya Calloji0baef632015-05-19 16:08:40 -0700778 ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
779 (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0))
Satya Calloji444a8da2015-03-06 10:38:22 -0800780 {
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 {
Chaojing Sune2805532015-04-22 13:40:21 -0700785 if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0)
Satya Calloji444a8da2015-03-06 10:38:22 -0800786 {
Satya Calloji877123f2015-04-23 23:39:49 -0700787 if (rl_mask)
788 {
789 if (!btm_ble_disable_resolving_list (rl_mask, FALSE))
790 return FALSE;
791 }
792
Chaojing Sune2805532015-04-22 13:40:21 -0700793 btm_ble_update_resolving_list(p_dev_rec->bd_addr, TRUE);
Satya Calloji444a8da2015-03-06 10:38:22 -0800794 if (controller_get_interface()->supports_ble_privacy())
795 {
Satya Calloji444a8da2015-03-06 10:38:22 -0800796 BD_ADDR dummy_bda = {0};
Satya Calloji0baef632015-05-19 16:08:40 -0700797 UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
798 UINT8 *local_irk = btm_cb.devcb.id_keys.irk;
Chaojing Sune2805532015-04-22 13:40:21 -0700799
Satya Calloji444a8da2015-03-06 10:38:22 -0800800 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
Chaojing Sune2805532015-04-22 13:40:21 -0700806 BTM_TRACE_DEBUG("%s:adding device to controller resolving list", __func__);
807 // use identical IRK for now
Satya Calloji444a8da2015-03-06 10:38:22 -0800808 rt = btsnd_hcic_ble_add_device_resolving_list(p_dev_rec->ble.static_addr_type,
Chaojing Sune2805532015-04-22 13:40:21 -0700809 p_dev_rec->ble.static_addr, peer_irk, local_irk);
Satya Calloji444a8da2015-03-06 10:38:22 -0800810 }
Chaojing Sune2805532015-04-22 13:40:21 -0700811 else
812 {
Satya Calloji444a8da2015-03-06 10:38:22 -0800813 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,
Chaojing Sune2805532015-04-22 13:40:21 -0700822 BTM_BLE_META_ADD_IRK_LEN,
823 param,
824 btm_ble_resolving_list_vsc_op_cmpl)
825 == BTM_CMD_STARTED)
Satya Calloji444a8da2015-03-06 10:38:22 -0800826 rt = TRUE;
Chaojing Sune2805532015-04-22 13:40:21 -0700827 }
Satya Calloji444a8da2015-03-06 10:38:22 -0800828
829 if (rt)
Chaojing Sune2805532015-04-22 13:40:21 -0700830 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
831 BTM_BLE_META_ADD_IRK_ENTRY);
Satya Calloji877123f2015-04-23 23:39:49 -0700832
833 /* if resolving list has been turned on, re-enable it */
834 if (rl_mask)
835 btm_ble_enable_resolving_list(rl_mask);
Satya Calloji483847a2015-06-19 10:46:03 -0700836 else
837 btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
Satya Calloji444a8da2015-03-06 10:38:22 -0800838 }
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*******************************************************************************/
864void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
865{
Satya Calloji877123f2015-04-23 23:39:49 -0700866 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 }
Satya Calloji444a8da2015-03-06 10:38:22 -0800874
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 {
Chaojing Sune2805532015-04-22 13:40:21 -0700879 btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
Satya Calloji444a8da2015-03-06 10:38:22 -0800880 btm_ble_remove_resolving_list_entry(p_dev_rec);
Chaojing Sune2805532015-04-22 13:40:21 -0700881 }
882 else
883 {
Satya Calloji444a8da2015-03-06 10:38:22 -0800884 BTM_TRACE_DEBUG("Device not in resolving list");
885 }
Satya Calloji444a8da2015-03-06 10:38:22 -0800886
Satya Calloji877123f2015-04-23 23:39:49 -0700887 /* if resolving list has been turned on, re-enable it */
888 if (rl_mask)
889 btm_ble_enable_resolving_list(rl_mask);
Satya Calloji444a8da2015-03-06 10:38:22 -0800890}
891
892/*******************************************************************************
893**
894** Function btm_ble_enable_resolving_list
895**
896** Description enable LE resolve address list
897**
898** Returns none
899**
900*******************************************************************************/
Satya Calloji877123f2015-04-23 23:39:49 -0700901void btm_ble_enable_resolving_list(UINT8 rl_mask)
Satya Calloji444a8da2015-03-06 10:38:22 -0800902{
Satya Calloji877123f2015-04-23 23:39:49 -0700903 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 &&
Satya Calloji444a8da2015-03-06 10:38:22 -0800908 controller_get_interface()->get_ble_resolving_list_max_size() != 0)
909 {
Satya Calloji877123f2015-04-23 23:39:49 -0700910 btm_ble_exe_enable_resolving_list();
911 btm_ble_resume_resolving_list_activity();
Satya Calloji444a8da2015-03-06 10:38:22 -0800912 }
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*******************************************************************************/
924BOOLEAN btm_ble_resolving_list_empty(void)
925{
926 return (controller_get_interface()->get_ble_resolving_list_max_size() ==
Chaojing Sune2805532015-04-22 13:40:21 -0700927 btm_cb.ble_ctr_cb.resolving_list_avail_size);
Satya Calloji444a8da2015-03-06 10:38:22 -0800928}
929
Jakub Pawlowskicac784d2016-02-01 11:53:36 -0800930
931bool 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
Satya Calloji444a8da2015-03-06 10:38:22 -0800942/*******************************************************************************
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*******************************************************************************/
Satya Calloji877123f2015-04-23 23:39:49 -0700953void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask)
Satya Calloji444a8da2015-03-06 10:38:22 -0800954{
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() >
Satya Calloji877123f2015-04-23 23:39:49 -0700962 btm_cb.ble_ctr_cb.resolving_list_avail_size)
963 btm_ble_enable_resolving_list(rl_mask);
Satya Calloji444a8da2015-03-06 10:38:22 -0800964 else
Satya Calloji877123f2015-04-23 23:39:49 -0700965 btm_ble_disable_resolving_list(rl_mask, TRUE);
Satya Calloji444a8da2015-03-06 10:38:22 -0800966 return;
967 }
968
Jakub Pawlowskicac784d2016-02-01 11:53:36 -0800969 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);
Satya Calloji444a8da2015-03-06 10:38:22 -0800974}
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*******************************************************************************/
987void btm_ble_resolving_list_init(UINT8 max_irk_list_sz)
988{
Chaojing Sune2805532015-04-22 13:40:21 -0700989 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);
Satya Calloji444a8da2015-03-06 10:38:22 -0800992
993 if (max_irk_list_sz > 0)
994 {
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -0800995 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);
Chaojing Sune2805532015-04-22 13:40:21 -0700997
998 /* RPA offloading feature */
999 if (btm_cb.ble_ctr_cb.irk_list_mask == NULL)
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001000 btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)osi_malloc(irk_mask_size);
Satya Calloji444a8da2015-03-06 10:38:22 -08001001
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();
Satya Calloji877123f2015-04-23 23:39:49 -07001007 btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
Satya Calloji444a8da2015-03-06 10:38:22 -08001008}
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*******************************************************************************/
1021void btm_ble_resolving_list_cleanup(void)
1022{
Chaojing Sune2805532015-04-22 13:40:21 -07001023 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
Satya Calloji444a8da2015-03-06 10:38:22 -08001024
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001025 osi_free_and_reset((void **)&p_q->resolve_q_random_pseudo);
1026 osi_free_and_reset((void **)&p_q->resolve_q_action);
Satya Calloji444a8da2015-03-06 10:38:22 -08001027
1028 controller_get_interface()->set_ble_resolving_list_max_size(0);
Chaojing Sune2805532015-04-22 13:40:21 -07001029
Pavlin Radoslavovcceb4302016-02-05 13:54:43 -08001030 osi_free_and_reset((void **)&btm_cb.ble_ctr_cb.irk_list_mask);
Satya Calloji444a8da2015-03-06 10:38:22 -08001031}
1032#endif