blob: fa5a8e0ca3a273bb8d3d507508fa5b88f0a75699 [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
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*******************************************************************************/
227void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len)
228{
Chaojing Sune2805532015-04-22 13:40:21 -0700229 UINT8 status = 0;
Satya Calloji444a8da2015-03-06 10:38:22 -0800230 STREAM_TO_UINT8(status, p);
231
Chaojing Sune2805532015-04-22 13:40:21 -0700232 BTM_TRACE_DEBUG("%s status=%d", __func__, status);
Satya Calloji444a8da2015-03-06 10:38:22 -0800233
234 if (status == HCI_SUCCESS)
235 {
Chaojing Sune2805532015-04-22 13:40:21 -0700236 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 =
Satya Calloji444a8da2015-03-06 10:38:22 -0800254 controller_get_interface()->get_ble_resolving_list_max_size();
255
Chaojing Sune2805532015-04-22 13:40:21 -0700256 BTM_TRACE_DEBUG("%s resolving_list_avail_size=%d",
Satya Calloji444a8da2015-03-06 10:38:22 -0800257 __func__, btm_cb.ble_ctr_cb.resolving_list_avail_size);
258
Chaojing Sune2805532015-04-22 13:40:21 -0700259 for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; ++i)
Satya Calloji444a8da2015-03-06 10:38:22 -0800260 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*******************************************************************************/
274void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
275{
Chaojing Sune2805532015-04-22 13:40:21 -0700276 UINT8 status;
Satya Calloji444a8da2015-03-06 10:38:22 -0800277 STREAM_TO_UINT8(status, p);
278
279 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
280
281 BD_ADDR pseudo_bda;
Chaojing Sune2805532015-04-22 13:40:21 -0700282 if (!btm_ble_deq_resolving_pending(pseudo_bda))
Satya Calloji444a8da2015-03-06 10:38:22 -0800283 {
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 --;
Satya Calloji444a8da2015-03-06 10:38:22 -0800299 }
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*******************************************************************************/
317void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
318{
Chaojing Sune2805532015-04-22 13:40:21 -0700319 BD_ADDR pseudo_bda;
320 UINT8 status;
Satya Calloji444a8da2015-03-06 10:38:22 -0800321
Chaojing Sune2805532015-04-22 13:40:21 -0700322 STREAM_TO_UINT8(status, p);
Satya Calloji444a8da2015-03-06 10:38:22 -0800323
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 {
Chaojing Sune2805532015-04-22 13:40:21 -0700337 p ++; /* skip opcode */
Satya Calloji444a8da2015-03-06 10:38:22 -0800338 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
339 }
340 else
Chaojing Sune2805532015-04-22 13:40:21 -0700341 btm_cb.ble_ctr_cb.resolving_list_avail_size++;
Satya Calloji444a8da2015-03-06 10:38:22 -0800342 }
343}
Chaojing Sune2805532015-04-22 13:40:21 -0700344
Satya Calloji444a8da2015-03-06 10:38:22 -0800345/*******************************************************************************
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*******************************************************************************/
355void 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*******************************************************************************/
402void 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*******************************************************************************/
445tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
446{
Chaojing Sune2805532015-04-22 13:40:21 -0700447 /* if controller does not support RPA offloading or privacy 1.2, skip */
Nitin Arora04b5e922015-05-21 17:58:36 -0700448 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
Chaojing Sune2805532015-04-22 13:40:21 -0700449 return BTM_WRONG_MODE;
Satya Calloji444a8da2015-03-06 10:38:22 -0800450
Chaojing Sune2805532015-04-22 13:40:21 -0700451 tBTM_STATUS st = BTM_NO_RESOURCES;
Satya Calloji444a8da2015-03-06 10:38:22 -0800452 if (controller_get_interface()->supports_ble_privacy())
453 {
Chaojing Sune2805532015-04-22 13:40:21 -0700454 if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
455 p_dev_rec->ble.static_addr))
Satya Calloji444a8da2015-03-06 10:38:22 -0800456 st = BTM_CMD_STARTED;
Chaojing Sune2805532015-04-22 13:40:21 -0700457 }
458 else
459 {
Satya Calloji444a8da2015-03-06 10:38:22 -0800460 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
Chaojing Sune2805532015-04-22 13:40:21 -0700467 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);
Satya Calloji444a8da2015-03-06 10:38:22 -0800471 }
472
473 if (st == BTM_CMD_STARTED)
Satya Calloji444a8da2015-03-06 10:38:22 -0800474 btm_ble_enq_resolving_list_pending( p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY);
Satya Calloji444a8da2015-03-06 10:38:22 -0800475
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*******************************************************************************/
490tBTM_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*******************************************************************************/
525tBTM_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,
Chaojing Sune2805532015-04-22 13:40:21 -0700535 p_dev_rec->ble.static_addr))
536 st = BTM_CMD_STARTED;
Satya Calloji444a8da2015-03-06 10:38:22 -0800537 }
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)
Chaojing Sune2805532015-04-22 13:40:21 -0700553 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
554 BTM_BLE_META_READ_IRK_ENTRY);
Satya Calloji444a8da2015-03-06 10:38:22 -0800555
556 return st;
557}
558
Satya Calloji877123f2015-04-23 23:39:49 -0700559
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*******************************************************************************/
573BOOLEAN 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*******************************************************************************/
621void 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*******************************************************************************/
649tBTM_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*******************************************************************************/
676BOOLEAN 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*******************************************************************************/
698void 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*******************************************************************************/
718BOOLEAN 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
Satya Calloji444a8da2015-03-06 10:38:22 -0800744/*******************************************************************************
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*******************************************************************************/
755BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
756{
Chaojing Sune2805532015-04-22 13:40:21 -0700757 BOOLEAN rt = FALSE;
Satya Calloji877123f2015-04-23 23:39:49 -0700758 UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
759
Satya Calloji444a8da2015-03-06 10:38:22 -0800760 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__,
Chaojing Sune2805532015-04-22 13:40:21 -0700761 btm_cb.ble_ctr_cb.privacy_mode);
Satya Calloji444a8da2015-03-06 10:38:22 -0800762
Chaojing Sune2805532015-04-22 13:40:21 -0700763 /* 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 */
Satya Calloji444a8da2015-03-06 10:38:22 -0800771 if (p_dev_rec != NULL && /* RPA is being used and PID is known */
Satya Calloji0baef632015-05-19 16:08:40 -0700772 (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))
Satya Calloji444a8da2015-03-06 10:38:22 -0800775 {
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 {
Chaojing Sune2805532015-04-22 13:40:21 -0700780 if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0)
Satya Calloji444a8da2015-03-06 10:38:22 -0800781 {
Satya Calloji877123f2015-04-23 23:39:49 -0700782 if (rl_mask)
783 {
784 if (!btm_ble_disable_resolving_list (rl_mask, FALSE))
785 return FALSE;
786 }
787
Chaojing Sune2805532015-04-22 13:40:21 -0700788 btm_ble_update_resolving_list(p_dev_rec->bd_addr, TRUE);
Satya Calloji444a8da2015-03-06 10:38:22 -0800789 if (controller_get_interface()->supports_ble_privacy())
790 {
Satya Calloji444a8da2015-03-06 10:38:22 -0800791 BD_ADDR dummy_bda = {0};
Satya Calloji0baef632015-05-19 16:08:40 -0700792 UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
793 UINT8 *local_irk = btm_cb.devcb.id_keys.irk;
Chaojing Sune2805532015-04-22 13:40:21 -0700794
Satya Calloji444a8da2015-03-06 10:38:22 -0800795 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
Chaojing Sune2805532015-04-22 13:40:21 -0700801 BTM_TRACE_DEBUG("%s:adding device to controller resolving list", __func__);
802 // use identical IRK for now
Satya Calloji444a8da2015-03-06 10:38:22 -0800803 rt = btsnd_hcic_ble_add_device_resolving_list(p_dev_rec->ble.static_addr_type,
Chaojing Sune2805532015-04-22 13:40:21 -0700804 p_dev_rec->ble.static_addr, peer_irk, local_irk);
Satya Calloji444a8da2015-03-06 10:38:22 -0800805 }
Chaojing Sune2805532015-04-22 13:40:21 -0700806 else
807 {
Satya Calloji444a8da2015-03-06 10:38:22 -0800808 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,
Chaojing Sune2805532015-04-22 13:40:21 -0700817 BTM_BLE_META_ADD_IRK_LEN,
818 param,
819 btm_ble_resolving_list_vsc_op_cmpl)
820 == BTM_CMD_STARTED)
Satya Calloji444a8da2015-03-06 10:38:22 -0800821 rt = TRUE;
Chaojing Sune2805532015-04-22 13:40:21 -0700822 }
Satya Calloji444a8da2015-03-06 10:38:22 -0800823
824 if (rt)
Chaojing Sune2805532015-04-22 13:40:21 -0700825 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
826 BTM_BLE_META_ADD_IRK_ENTRY);
Satya Calloji877123f2015-04-23 23:39:49 -0700827
828 /* if resolving list has been turned on, re-enable it */
829 if (rl_mask)
830 btm_ble_enable_resolving_list(rl_mask);
Satya Calloji444a8da2015-03-06 10:38:22 -0800831 }
832 }
833 else
834 {
835 BTM_TRACE_ERROR("Device already in Resolving list");
836 rt = TRUE;
837 }
838 }
839 else
840 {
841 BTM_TRACE_DEBUG("Device not a RPA enabled device");
842 }
843 return rt;
844}
845
846/*******************************************************************************
847**
848** Function btm_ble_resolving_list_remove_dev
849**
850** Description This function removes the device from resolving list
851**
852** Parameters
853**
854** Returns status
855**
856*******************************************************************************/
857void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
858{
Satya Calloji877123f2015-04-23 23:39:49 -0700859 UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
860
861 BTM_TRACE_EVENT ("%s", __func__);
862 if (rl_mask)
863 {
864 if (!btm_ble_disable_resolving_list (rl_mask, FALSE))
865 return;
866 }
Satya Calloji444a8da2015-03-06 10:38:22 -0800867
868 if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
869 btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
870 BTM_BLE_META_REMOVE_IRK_ENTRY) == FALSE)
871 {
Chaojing Sune2805532015-04-22 13:40:21 -0700872 btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
Satya Calloji444a8da2015-03-06 10:38:22 -0800873 btm_ble_remove_resolving_list_entry(p_dev_rec);
Chaojing Sune2805532015-04-22 13:40:21 -0700874 }
875 else
876 {
Satya Calloji444a8da2015-03-06 10:38:22 -0800877 BTM_TRACE_DEBUG("Device not in resolving list");
878 }
Satya Calloji444a8da2015-03-06 10:38:22 -0800879
Satya Calloji877123f2015-04-23 23:39:49 -0700880 /* if resolving list has been turned on, re-enable it */
881 if (rl_mask)
882 btm_ble_enable_resolving_list(rl_mask);
Satya Calloji444a8da2015-03-06 10:38:22 -0800883}
884
885/*******************************************************************************
886**
887** Function btm_ble_enable_resolving_list
888**
889** Description enable LE resolve address list
890**
891** Returns none
892**
893*******************************************************************************/
Satya Calloji877123f2015-04-23 23:39:49 -0700894void btm_ble_enable_resolving_list(UINT8 rl_mask)
Satya Calloji444a8da2015-03-06 10:38:22 -0800895{
Satya Calloji877123f2015-04-23 23:39:49 -0700896 UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
897
898 btm_cb.ble_ctr_cb.rl_state |= rl_mask;
899 if (rl_state == BTM_BLE_RL_IDLE &&
900 btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
Satya Calloji444a8da2015-03-06 10:38:22 -0800901 controller_get_interface()->get_ble_resolving_list_max_size() != 0)
902 {
Satya Calloji877123f2015-04-23 23:39:49 -0700903 btm_ble_exe_enable_resolving_list();
904 btm_ble_resume_resolving_list_activity();
Satya Calloji444a8da2015-03-06 10:38:22 -0800905 }
906}
907
908/*******************************************************************************
909**
910** Function btm_ble_resolving_list_empty
911**
912** Description check to see if resoving list is empty or not
913**
914** Returns TRUE: empty; FALSE non-empty
915**
916*******************************************************************************/
917BOOLEAN btm_ble_resolving_list_empty(void)
918{
919 return (controller_get_interface()->get_ble_resolving_list_max_size() ==
Chaojing Sune2805532015-04-22 13:40:21 -0700920 btm_cb.ble_ctr_cb.resolving_list_avail_size);
Satya Calloji444a8da2015-03-06 10:38:22 -0800921}
922
923/*******************************************************************************
924**
925** Function btm_ble_enable_resolving_list_for_platform
926**
927** Description enable/disable resolving list feature depending on if any
928** resolving list is empty and whitelist is involoved in the
929** operation.
930**
931** Returns none
932**
933*******************************************************************************/
Satya Calloji877123f2015-04-23 23:39:49 -0700934void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask)
Satya Calloji444a8da2015-03-06 10:38:22 -0800935{
936 /* if controller does not support, skip */
937 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
938 return;
939
940 if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE)
941 {
942 if (controller_get_interface()->get_ble_resolving_list_max_size() >
Satya Calloji877123f2015-04-23 23:39:49 -0700943 btm_cb.ble_ctr_cb.resolving_list_avail_size)
944 btm_ble_enable_resolving_list(rl_mask);
Satya Calloji444a8da2015-03-06 10:38:22 -0800945 else
Satya Calloji877123f2015-04-23 23:39:49 -0700946 btm_ble_disable_resolving_list(rl_mask, TRUE);
Satya Calloji444a8da2015-03-06 10:38:22 -0800947 return;
948 }
949
950 tBTM_SEC_DEV_REC *p_dev = &btm_cb.sec_dev_rec[0];
951 for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev ++)
952 {
953 if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
954 (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT))
955 {
Satya Calloji877123f2015-04-23 23:39:49 -0700956 btm_ble_enable_resolving_list(rl_mask);
Satya Calloji444a8da2015-03-06 10:38:22 -0800957 return;
958 }
959 }
Satya Calloji877123f2015-04-23 23:39:49 -0700960 btm_ble_disable_resolving_list(rl_mask, TRUE);
Satya Calloji444a8da2015-03-06 10:38:22 -0800961}
962
963/*******************************************************************************
964**
965** Function btm_ble_resolving_list_init
966**
967** Description Initialize resolving list in host stack
968**
969** Parameters Max resolving list size
970**
971** Returns void
972**
973*******************************************************************************/
974void btm_ble_resolving_list_init(UINT8 max_irk_list_sz)
975{
Chaojing Sune2805532015-04-22 13:40:21 -0700976 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
977 UINT8 irk_mask_size = (max_irk_list_sz % 8) ?
978 (max_irk_list_sz/8 + 1) : (max_irk_list_sz/8);
Satya Calloji444a8da2015-03-06 10:38:22 -0800979
980 if (max_irk_list_sz > 0)
981 {
Chaojing Sune2805532015-04-22 13:40:21 -0700982 p_q->resolve_q_random_pseudo = (BD_ADDR *)GKI_getbuf(sizeof(BD_ADDR) * max_irk_list_sz);
983 p_q->resolve_q_action = (UINT8 *)GKI_getbuf(max_irk_list_sz);
984
985 /* RPA offloading feature */
986 if (btm_cb.ble_ctr_cb.irk_list_mask == NULL)
987 btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)GKI_getbuf(irk_mask_size);
Satya Calloji444a8da2015-03-06 10:38:22 -0800988
989 BTM_TRACE_DEBUG ("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
990 }
991
992 controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
993 btm_ble_clear_resolving_list();
Satya Calloji877123f2015-04-23 23:39:49 -0700994 btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
Satya Calloji444a8da2015-03-06 10:38:22 -0800995}
996
997/*******************************************************************************
998**
999** Function btm_ble_resolving_list_cleanup
1000**
1001** Description Cleanup resolving list dynamic memory
1002**
1003** Parameters
1004**
1005** Returns void
1006**
1007*******************************************************************************/
1008void btm_ble_resolving_list_cleanup(void)
1009{
Chaojing Sune2805532015-04-22 13:40:21 -07001010 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
Satya Calloji444a8da2015-03-06 10:38:22 -08001011
1012 if (p_q->resolve_q_random_pseudo)
1013 GKI_freebuf(p_q->resolve_q_random_pseudo);
1014
1015 if (p_q->resolve_q_action)
1016 GKI_freebuf(p_q->resolve_q_action);
1017
1018 controller_get_interface()->set_ble_resolving_list_max_size(0);
Chaojing Sune2805532015-04-22 13:40:21 -07001019 if (btm_cb.ble_ctr_cb.irk_list_mask)
1020 GKI_freebuf(btm_cb.ble_ctr_cb.irk_list_mask);
1021
1022 btm_cb.ble_ctr_cb.irk_list_mask = NULL;
Satya Calloji444a8da2015-03-06 10:38:22 -08001023}
1024#endif