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 address management. 22 * 23 ******************************************************************************/ 24 25 #include <string.h> 26 27 #include "bt_types.h" 28 #include "hcimsgs.h" 29 #include "btu.h" 30 #include "btm_int.h" 31 #include "gap_api.h" 32 #include "device/include/controller.h" 33 34 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) 35 #include "btm_ble_int.h" 36 #include "smp_api.h" 37 38 39 /******************************************************************************* 40 ** 41 ** Function btm_gen_resolve_paddr_cmpl 42 ** 43 ** Description This is callback functioin when resolvable private address 44 ** generation is complete. 45 ** 46 ** Returns void 47 ** 48 *******************************************************************************/ 49 static void btm_gen_resolve_paddr_cmpl(tSMP_ENC *p) 50 { 51 tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 52 BTM_TRACE_EVENT ("btm_gen_resolve_paddr_cmpl"); 53 54 if (p) 55 { 56 /* set hash to be LSB of rpAddress */ 57 p_cb->private_addr[5] = p->param_buf[0]; 58 p_cb->private_addr[4] = p->param_buf[1]; 59 p_cb->private_addr[3] = p->param_buf[2]; 60 /* set it to controller */ 61 btsnd_hcic_ble_set_random_addr(p_cb->private_addr); 62 63 p_cb->own_addr_type = BLE_ADDR_RANDOM; 64 65 /* start a periodical timer to refresh random addr */ 66 btu_stop_timer_oneshot(&p_cb->raddr_timer_ent); 67 #if (BTM_BLE_CONFORMANCE_TESTING == TRUE) 68 btu_start_timer_oneshot(&p_cb->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR, 69 btm_cb.ble_ctr_cb.rpa_tout); 70 #else 71 btu_start_timer_oneshot(&p_cb->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR, 72 BTM_BLE_PRIVATE_ADDR_INT); 73 #endif 74 } 75 else 76 { 77 /* random address set failure */ 78 BTM_TRACE_DEBUG("set random address failed"); 79 } 80 } 81 /******************************************************************************* 82 ** 83 ** Function btm_gen_resolve_paddr_low 84 ** 85 ** Description This function is called when random address has generate the 86 ** random number base for low 3 byte bd address. 87 ** 88 ** Returns void 89 ** 90 *******************************************************************************/ 91 void btm_gen_resolve_paddr_low(tBTM_RAND_ENC *p) 92 { 93 #if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE) 94 tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 95 tSMP_ENC output; 96 97 BTM_TRACE_EVENT ("btm_gen_resolve_paddr_low"); 98 if (p) 99 { 100 p->param_buf[2] &= (~BLE_RESOLVE_ADDR_MASK); 101 p->param_buf[2] |= BLE_RESOLVE_ADDR_MSB; 102 103 p_cb->private_addr[2] = p->param_buf[0]; 104 p_cb->private_addr[1] = p->param_buf[1]; 105 p_cb->private_addr[0] = p->param_buf[2]; 106 107 /* encrypt with ur IRK */ 108 if (!SMP_Encrypt(btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN, p->param_buf, 3, &output)) 109 { 110 btm_gen_resolve_paddr_cmpl(NULL); 111 } 112 else 113 { 114 btm_gen_resolve_paddr_cmpl(&output); 115 } 116 } 117 #endif 118 } 119 /******************************************************************************* 120 ** 121 ** Function btm_gen_resolvable_private_addr 122 ** 123 ** Description This function generate a resolvable private address. 124 ** 125 ** Returns void 126 ** 127 *******************************************************************************/ 128 void btm_gen_resolvable_private_addr (void *p_cmd_cplt_cback) 129 { 130 BTM_TRACE_EVENT ("btm_gen_resolvable_private_addr"); 131 /* generate 3B rand as BD LSB, SRK with it, get BD MSB */ 132 if (!btsnd_hcic_ble_rand((void *)p_cmd_cplt_cback)) 133 btm_gen_resolve_paddr_cmpl(NULL); 134 } 135 /******************************************************************************* 136 ** 137 ** Function btm_gen_non_resolve_paddr_cmpl 138 ** 139 ** Description This is the callback function when non-resolvable private 140 ** function is generated and write to controller. 141 ** 142 ** Returns void 143 ** 144 *******************************************************************************/ 145 static void btm_gen_non_resolve_paddr_cmpl(tBTM_RAND_ENC *p) 146 { 147 tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 148 tBTM_BLE_ADDR_CBACK *p_cback = p_cb->p_generate_cback; 149 void *p_data = p_cb->p; 150 UINT8 *pp; 151 BD_ADDR static_random; 152 153 BTM_TRACE_EVENT ("btm_gen_non_resolve_paddr_cmpl"); 154 155 p_cb->p_generate_cback = NULL; 156 if (p) 157 { 158 159 pp = p->param_buf; 160 STREAM_TO_BDADDR(static_random, pp); 161 /* mask off the 2 MSB */ 162 static_random[0] &= BLE_STATIC_PRIVATE_MSB_MASK; 163 164 /* report complete */ 165 if (p_cback) 166 (* p_cback)(static_random, p_data); 167 } 168 else 169 { 170 BTM_TRACE_DEBUG("btm_gen_non_resolvable_private_addr failed"); 171 if (p_cback) 172 (* p_cback)(NULL, p_data); 173 } 174 } 175 /******************************************************************************* 176 ** 177 ** Function btm_gen_non_resolvable_private_addr 178 ** 179 ** Description This function generate a non-resolvable private address. 180 ** 181 ** 182 ** Returns void 183 ** 184 *******************************************************************************/ 185 void btm_gen_non_resolvable_private_addr (tBTM_BLE_ADDR_CBACK *p_cback, void *p) 186 { 187 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 188 189 BTM_TRACE_EVENT ("btm_gen_non_resolvable_private_addr"); 190 191 if (p_mgnt_cb->p_generate_cback != NULL) 192 return; 193 194 p_mgnt_cb->p_generate_cback = p_cback; 195 p_mgnt_cb->p = p; 196 if (!btsnd_hcic_ble_rand((void *)btm_gen_non_resolve_paddr_cmpl)) 197 { 198 btm_gen_non_resolve_paddr_cmpl(NULL); 199 } 200 201 } 202 203 #if SMP_INCLUDED == TRUE 204 /******************************************************************************* 205 ** Utility functions for Random address resolving 206 *******************************************************************************/ 207 /******************************************************************************* 208 ** 209 ** Function btm_ble_resolve_address_cmpl 210 ** 211 ** Description This function sends the random address resolving complete 212 ** callback. 213 ** 214 ** Returns None. 215 ** 216 *******************************************************************************/ 217 static void btm_ble_resolve_address_cmpl(void) 218 { 219 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 220 tBTM_SEC_DEV_REC *p_dev_rec = NULL; 221 222 BTM_TRACE_EVENT ("btm_ble_resolve_address_cmpl p_mgnt_cb->index = %d", p_mgnt_cb->index); 223 224 if (p_mgnt_cb->index < BTM_SEC_MAX_DEVICE_RECORDS) 225 { 226 p_dev_rec = &btm_cb.sec_dev_rec[p_mgnt_cb->index]; 227 } 228 229 p_mgnt_cb->busy = FALSE; 230 231 (* p_mgnt_cb->p_resolve_cback)(p_dev_rec, p_mgnt_cb->p); 232 } 233 /******************************************************************************* 234 ** 235 ** Function btm_ble_proc_resolve_x 236 ** 237 ** Description This function compares the X with random address 3 MSO bytes 238 ** to find a match, if not match, continue for next record. 239 ** 240 ** Returns None. 241 ** 242 *******************************************************************************/ 243 static BOOLEAN btm_ble_proc_resolve_x(tSMP_ENC *p) 244 { 245 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 246 UINT8 comp[3]; 247 BTM_TRACE_EVENT ("btm_ble_proc_resolve_x"); 248 /* compare the hash with 3 LSB of bd address */ 249 comp[0] = p_mgnt_cb->random_bda[5]; 250 comp[1] = p_mgnt_cb->random_bda[4]; 251 comp[2] = p_mgnt_cb->random_bda[3]; 252 253 if (p) 254 { 255 if (!memcmp(p->param_buf, &comp[0], 3)) 256 { 257 /* match is found */ 258 BTM_TRACE_EVENT ("match is found"); 259 btm_ble_resolve_address_cmpl(); 260 return TRUE; 261 } 262 } 263 return FALSE; 264 } 265 266 /******************************************************************************* 267 ** 268 ** Function btm_ble_init_pseudo_addr 269 ** 270 ** Description This function is used to initialize pseudo address. 271 ** If pseudo address is not available, use dummy address 272 ** 273 ** Returns TRUE is updated; FALSE otherwise. 274 ** 275 *******************************************************************************/ 276 BOOLEAN btm_ble_init_pseudo_addr (tBTM_SEC_DEV_REC *p_dev_rec, BD_ADDR new_pseudo_addr) 277 { 278 BD_ADDR dummy_bda = {0}; 279 280 if (memcmp(p_dev_rec->ble.pseudo_addr, dummy_bda, BD_ADDR_LEN) == 0) 281 { 282 memcpy(p_dev_rec->ble.pseudo_addr, new_pseudo_addr, BD_ADDR_LEN); 283 return TRUE; 284 } 285 286 return FALSE; 287 } 288 289 /******************************************************************************* 290 ** 291 ** Function btm_ble_addr_resolvable 292 ** 293 ** Description This function checks if a RPA is resolvable by the device key. 294 ** 295 ** Returns TRUE is resolvable; FALSE otherwise. 296 ** 297 *******************************************************************************/ 298 BOOLEAN btm_ble_addr_resolvable (BD_ADDR rpa, tBTM_SEC_DEV_REC *p_dev_rec) 299 { 300 BOOLEAN rt = FALSE; 301 302 if (!BTM_BLE_IS_RESOLVE_BDA(rpa)) 303 return rt; 304 305 UINT8 rand[3]; 306 tSMP_ENC output; 307 if ((p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) && 308 (p_dev_rec->ble.key_type & BTM_LE_KEY_PID)) 309 { 310 BTM_TRACE_DEBUG("%s try to resolve", __func__); 311 /* use the 3 MSB of bd address as prand */ 312 rand[0] = rpa[2]; 313 rand[1] = rpa[1]; 314 rand[2] = rpa[0]; 315 316 /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */ 317 SMP_Encrypt(p_dev_rec->ble.keys.irk, BT_OCTET16_LEN, 318 &rand[0], 3, &output); 319 320 rand[0] = rpa[5]; 321 rand[1] = rpa[4]; 322 rand[2] = rpa[3]; 323 324 if (!memcmp(output.param_buf, &rand[0], 3)) 325 { 326 btm_ble_init_pseudo_addr (p_dev_rec, rpa); 327 rt = TRUE; 328 } 329 } 330 return rt; 331 } 332 333 /******************************************************************************* 334 ** 335 ** Function btm_ble_match_random_bda 336 ** 337 ** Description This function match the random address to the appointed device 338 ** record, starting from calculating IRK. If record index exceed 339 ** the maximum record number, matching failed and send callback. 340 ** 341 ** Returns None. 342 ** 343 *******************************************************************************/ 344 static BOOLEAN btm_ble_match_random_bda(UINT16 rec_index) 345 { 346 #if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE) 347 /* use the 3 MSB of bd address as prand */ 348 349 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 350 UINT8 rand[3]; 351 rand[0] = p_mgnt_cb->random_bda[2]; 352 rand[1] = p_mgnt_cb->random_bda[1]; 353 rand[2] = p_mgnt_cb->random_bda[0]; 354 355 BTM_TRACE_EVENT("%s rec_index = %d", __func__, rec_index); 356 357 if (rec_index < BTM_SEC_MAX_DEVICE_RECORDS) 358 { 359 tSMP_ENC output; 360 tBTM_SEC_DEV_REC *p_dev_rec; 361 p_dev_rec = &btm_cb.sec_dev_rec[rec_index]; 362 363 BTM_TRACE_DEBUG("sec_flags = %02x device_type = %d", p_dev_rec->sec_flags, 364 p_dev_rec->device_type); 365 366 if ((p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) && 367 (p_dev_rec->ble.key_type & BTM_LE_KEY_PID)) 368 { 369 /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */ 370 SMP_Encrypt(p_dev_rec->ble.keys.irk, BT_OCTET16_LEN, 371 &rand[0], 3, &output); 372 return btm_ble_proc_resolve_x(&output); 373 } 374 else 375 { 376 // not completed 377 return FALSE; 378 } 379 } 380 else /* no match found */ 381 { 382 btm_ble_resolve_address_cmpl(); 383 return TRUE; 384 } 385 #endif 386 } 387 388 /******************************************************************************* 389 ** 390 ** Function btm_ble_resolve_random_addr 391 ** 392 ** Description This function is called to resolve a random address. 393 ** 394 ** Returns pointer to the security record of the device whom a random 395 ** address is matched to. 396 ** 397 *******************************************************************************/ 398 void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK * p_cback, void *p) 399 { 400 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 401 402 BTM_TRACE_EVENT ("btm_ble_resolve_random_addr"); 403 if ( !p_mgnt_cb->busy) 404 { 405 p_mgnt_cb->p = p; 406 p_mgnt_cb->busy = TRUE; 407 p_mgnt_cb->index = 0; 408 p_mgnt_cb->p_resolve_cback = p_cback; 409 memcpy(p_mgnt_cb->random_bda, random_bda, BD_ADDR_LEN); 410 /* start to resolve random address */ 411 /* check for next security record */ 412 while (TRUE) 413 { 414 if (btm_ble_match_random_bda(p_mgnt_cb->index)) 415 { 416 /* atch found or went through the list */ 417 break; 418 } 419 p_mgnt_cb->index ++; 420 } 421 } 422 else 423 (*p_cback)(NULL, p); 424 } 425 #endif 426 427 /******************************************************************************* 428 ** address mapping between pseudo address and real connection address 429 *******************************************************************************/ 430 /******************************************************************************* 431 ** 432 ** Function btm_find_dev_by_identity_addr 433 ** 434 ** Description find the security record whose LE static address is matching 435 ** 436 *******************************************************************************/ 437 tBTM_SEC_DEV_REC* btm_find_dev_by_identity_addr(BD_ADDR bd_addr, UINT8 addr_type) 438 { 439 #if BLE_PRIVACY_SPT == TRUE 440 UINT8 i; 441 tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; 442 443 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev_rec ++) 444 { 445 if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) && 446 memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) == 0) 447 { 448 if ((p_dev_rec->ble.static_addr_type & (~BLE_ADDR_TYPE_ID_BIT)) != 449 (addr_type & (~BLE_ADDR_TYPE_ID_BIT))) 450 { 451 BTM_TRACE_WARNING("%s find pseudo->random match with diff addr type: %d vs %d", 452 __func__, p_dev_rec->ble.static_addr_type, addr_type); 453 } 454 455 /* found the match */ 456 return p_dev_rec; 457 } 458 } 459 #endif 460 461 return NULL; 462 } 463 464 /******************************************************************************* 465 ** 466 ** Function btm_identity_addr_to_random_pseudo 467 ** 468 ** Description This function map a static BD address to a pseudo random address 469 ** in security database. 470 ** 471 *******************************************************************************/ 472 BOOLEAN btm_identity_addr_to_random_pseudo(BD_ADDR bd_addr, UINT8 *p_addr_type, BOOLEAN refresh) 473 { 474 #if BLE_PRIVACY_SPT == TRUE 475 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_identity_addr(bd_addr, *p_addr_type); 476 477 BTM_TRACE_EVENT ("%s", __func__); 478 /* evt reported on static address, map static address to random pseudo */ 479 if (p_dev_rec != NULL) 480 { 481 /* if RPA offloading is supported, or 4.2 controller, do RPA refresh */ 482 if (refresh && controller_get_interface()->get_ble_resolving_list_max_size() != 0) 483 btm_ble_read_resolving_list_entry(p_dev_rec); 484 485 /* assign the original address to be the current report address */ 486 if (!btm_ble_init_pseudo_addr (p_dev_rec, bd_addr)) 487 memcpy(bd_addr, p_dev_rec->ble.pseudo_addr, BD_ADDR_LEN); 488 489 *p_addr_type = p_dev_rec->ble.ble_addr_type; 490 return TRUE; 491 } 492 #endif 493 return FALSE; 494 } 495 496 /******************************************************************************* 497 ** 498 ** Function btm_random_pseudo_to_identity_addr 499 ** 500 ** Description This function map a random pseudo address to a public address 501 ** random_pseudo is input and output parameter 502 ** 503 *******************************************************************************/ 504 BOOLEAN btm_random_pseudo_to_identity_addr(BD_ADDR random_pseudo, UINT8 *p_static_addr_type) 505 { 506 #if BLE_PRIVACY_SPT == TRUE 507 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (random_pseudo); 508 509 if (p_dev_rec != NULL) 510 { 511 if (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) 512 { 513 * p_static_addr_type = p_dev_rec->ble.static_addr_type; 514 memcpy(random_pseudo, p_dev_rec->ble.static_addr, BD_ADDR_LEN); 515 if (controller_get_interface()->supports_ble_privacy()) 516 *p_static_addr_type |= BLE_ADDR_TYPE_ID_BIT; 517 return TRUE; 518 } 519 } 520 #endif 521 return FALSE; 522 } 523 524 /******************************************************************************* 525 ** 526 ** Function btm_ble_refresh_peer_resolvable_private_addr 527 ** 528 ** Description This function refresh the currently used resolvable remote private address into security 529 ** database and set active connection address. 530 ** 531 *******************************************************************************/ 532 void btm_ble_refresh_peer_resolvable_private_addr(BD_ADDR pseudo_bda, BD_ADDR rpa, 533 UINT8 rra_type) 534 { 535 #if BLE_PRIVACY_SPT == TRUE 536 UINT8 rra_dummy = FALSE; 537 BD_ADDR dummy_bda = {0}; 538 539 if (memcmp(dummy_bda, rpa, BD_ADDR_LEN) == 0) 540 rra_dummy = TRUE; 541 542 /* update security record here, in adv event or connection complete process */ 543 tBTM_SEC_DEV_REC *p_sec_rec = btm_find_dev(pseudo_bda); 544 if (p_sec_rec != NULL) 545 { 546 memcpy(p_sec_rec->ble.cur_rand_addr, rpa, BD_ADDR_LEN); 547 548 /* unknown, if dummy address, set to static */ 549 if (rra_type == BTM_BLE_ADDR_PSEUDO) 550 p_sec_rec->ble.active_addr_type = rra_dummy ? BTM_BLE_ADDR_STATIC: BTM_BLE_ADDR_RRA; 551 else 552 p_sec_rec->ble.active_addr_type = rra_type; 553 } 554 else 555 { 556 BTM_TRACE_ERROR("No matching known device in record"); 557 return; 558 } 559 560 BTM_TRACE_DEBUG("%s: active_addr_type: %d ", 561 __func__, p_sec_rec->ble.active_addr_type); 562 563 /* connection refresh remote address */ 564 tACL_CONN *p_acl = btm_bda_to_acl(p_sec_rec->bd_addr, BT_TRANSPORT_LE); 565 if (p_acl == NULL) 566 p_acl = btm_bda_to_acl(p_sec_rec->ble.pseudo_addr, BT_TRANSPORT_LE); 567 568 if (p_acl != NULL) 569 { 570 if (rra_type == BTM_BLE_ADDR_PSEUDO) 571 { 572 /* use static address, resolvable_private_addr is empty */ 573 if (rra_dummy) 574 { 575 p_acl->active_remote_addr_type = p_sec_rec->ble.static_addr_type; 576 memcpy(p_acl->active_remote_addr, p_sec_rec->ble.static_addr, BD_ADDR_LEN); 577 } 578 else 579 { 580 p_acl->active_remote_addr_type = BLE_ADDR_RANDOM; 581 memcpy(p_acl->active_remote_addr, rpa, BD_ADDR_LEN); 582 } 583 } 584 else 585 { 586 p_acl->active_remote_addr_type = rra_type; 587 memcpy(p_acl->active_remote_addr, rpa, BD_ADDR_LEN); 588 } 589 590 BTM_TRACE_DEBUG("p_acl->active_remote_addr_type: %d ", p_acl->active_remote_addr_type); 591 BTM_TRACE_DEBUG("%s conn_addr: %02x:%02x:%02x:%02x:%02x:%02x", 592 __func__,p_acl->active_remote_addr[0], p_acl->active_remote_addr[1], 593 p_acl->active_remote_addr[2], p_acl->active_remote_addr[3], 594 p_acl->active_remote_addr[4], p_acl->active_remote_addr[5]); 595 } 596 #endif 597 } 598 599 /******************************************************************************* 600 ** 601 ** Function btm_ble_refresh_local_resolvable_private_addr 602 ** 603 ** Description This function refresh the currently used resolvable private address for the 604 ** active link to the remote device 605 ** 606 *******************************************************************************/ 607 void btm_ble_refresh_local_resolvable_private_addr(BD_ADDR pseudo_addr, 608 BD_ADDR local_rpa) 609 { 610 #if BLE_PRIVACY_SPT == TRUE 611 tACL_CONN *p = btm_bda_to_acl(pseudo_addr, BT_TRANSPORT_LE); 612 BD_ADDR dummy_bda = {0}; 613 614 if (p != NULL) 615 { 616 if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) 617 { 618 p->conn_addr_type = BLE_ADDR_RANDOM; 619 if (memcmp(local_rpa, dummy_bda, BD_ADDR_LEN)) 620 memcpy(p->conn_addr, local_rpa, BD_ADDR_LEN); 621 else 622 memcpy(p->conn_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, BD_ADDR_LEN); 623 } 624 else 625 { 626 p->conn_addr_type = BLE_ADDR_PUBLIC; 627 memcpy(p->conn_addr,&controller_get_interface()->get_address()->address, BD_ADDR_LEN); 628 } 629 } 630 #endif 631 } 632 #endif 633 634 635