mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-10-09 07:57:21 +00:00
Merge pull request #483 from ccollins476ad/ble-auto-addr
BLE Host - Automatic own-addr-type resolution X-Original-Commit: 4ab14f93e7a057d1a66a6dea72a036dd67211415
This commit is contained in:
@@ -40,9 +40,10 @@ int ble_gatt_write_test_all(void);
|
||||
int ble_gatts_notify_test_all(void);
|
||||
int ble_gatts_read_test_suite(void);
|
||||
int ble_gatts_reg_test_all(void);
|
||||
int ble_hs_hci_test_all(void);
|
||||
int ble_hs_adv_test_all(void);
|
||||
int ble_hs_conn_test_all(void);
|
||||
int ble_hs_hci_test_all(void);
|
||||
int ble_hs_id_test_all(void);
|
||||
int ble_l2cap_test_all(void);
|
||||
int ble_os_test_all(void);
|
||||
int ble_sm_lgcy_test_suite(void);
|
||||
|
||||
+108
-12
@@ -117,10 +117,14 @@ done:
|
||||
* o BLE_ADDR_PUBLIC
|
||||
* o BLE_ADDR_RANDOM
|
||||
* @param out_id_addr On success, this is reseated to point to the
|
||||
* retrieved 6-byte identity address.
|
||||
* retrieved 6-byte identity address. Pass
|
||||
* NULL if you do not require this
|
||||
* information.
|
||||
|
||||
* @param out_is_nrpa On success, the pointed-to value indicates
|
||||
* whether the retrieved address is a
|
||||
* non-resolvable private address.
|
||||
* non-resolvable private address. Pass NULL
|
||||
* if you do not require this information.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* BLE_HS_EINVAL if an invalid address type was
|
||||
@@ -178,10 +182,12 @@ ble_hs_id_addr(uint8_t id_addr_type, const uint8_t **out_id_addr,
|
||||
* o BLE_ADDR_RANDOM
|
||||
* @param out_id_addr On success, the requested identity address is
|
||||
* copied into this buffer. The buffer must
|
||||
* be at least six bytes in size.
|
||||
* be at least six bytes in size. Pass NULL
|
||||
* if you do not require this information.
|
||||
* @param out_is_nrpa On success, the pointed-to value indicates
|
||||
* whether the retrieved address is a
|
||||
* non-resolvable private address.
|
||||
* non-resolvable private address. Pass NULL
|
||||
* if you do not require this information.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* BLE_HS_EINVAL if an invalid address type was
|
||||
@@ -200,7 +206,7 @@ ble_hs_id_copy_addr(uint8_t id_addr_type, uint8_t *out_id_addr,
|
||||
ble_hs_lock();
|
||||
|
||||
rc = ble_hs_id_addr(id_addr_type, &addr, out_is_nrpa);
|
||||
if (rc == 0) {
|
||||
if (rc == 0 && out_id_addr != NULL) {
|
||||
memcpy(out_id_addr, addr, 6);
|
||||
}
|
||||
|
||||
@@ -209,8 +215,8 @@ ble_hs_id_copy_addr(uint8_t id_addr_type, uint8_t *out_id_addr,
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_id_use_addr(uint8_t own_addr_type)
|
||||
static int
|
||||
ble_hs_id_addr_type_usable(uint8_t own_addr_type)
|
||||
{
|
||||
uint8_t id_addr_type;
|
||||
int nrpa;
|
||||
@@ -235,11 +241,6 @@ ble_hs_id_use_addr(uint8_t own_addr_type)
|
||||
if (nrpa) {
|
||||
return BLE_HS_ENOADDR;
|
||||
}
|
||||
|
||||
rc = ble_hs_pvcy_ensure_started();
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -248,3 +249,98 @@ ble_hs_id_use_addr(uint8_t own_addr_type)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_id_use_addr(uint8_t own_addr_type)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ble_hs_id_addr_type_usable(own_addr_type);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* If privacy is being used, make sure RPA rotation is in effect. */
|
||||
if (own_addr_type == BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT ||
|
||||
own_addr_type == BLE_OWN_ADDR_RPA_RANDOM_DEFAULT) {
|
||||
|
||||
rc = ble_hs_pvcy_ensure_started();
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the best address type to use for automatic address type
|
||||
* resolution. Calculation of the best address type is done as follows:
|
||||
*
|
||||
* if privacy requested:
|
||||
* if we have a random static address:
|
||||
* --> RPA with static random ID
|
||||
* else
|
||||
* --> RPA with public ID
|
||||
* end
|
||||
* else
|
||||
* if we have a random static address:
|
||||
* --> random static address
|
||||
* else
|
||||
* --> public address
|
||||
* end
|
||||
* end
|
||||
*
|
||||
* @param privacy (0/1) Whether to use a private address.
|
||||
* @param out_addr_type On success, the "own addr type" code gets
|
||||
* written here.
|
||||
*
|
||||
* @return 0 if an address type was successfully inferred.
|
||||
* BLE_HS_ENOADDR if the device does not have a
|
||||
* suitable address.
|
||||
* Other BLE host core code on error.
|
||||
*/
|
||||
int
|
||||
ble_hs_id_infer_auto(int privacy, uint8_t *out_addr_type)
|
||||
{
|
||||
static const uint8_t pub_addr_types[] = {
|
||||
BLE_OWN_ADDR_RANDOM,
|
||||
BLE_OWN_ADDR_PUBLIC,
|
||||
};
|
||||
static const uint8_t priv_addr_types[] = {
|
||||
BLE_OWN_ADDR_RPA_RANDOM_DEFAULT,
|
||||
BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT,
|
||||
};
|
||||
const uint8_t *addr_types;
|
||||
uint8_t addr_type;
|
||||
int num_addr_types;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
if (privacy) {
|
||||
addr_types = priv_addr_types;
|
||||
num_addr_types = sizeof priv_addr_types / sizeof priv_addr_types[0];
|
||||
} else {
|
||||
addr_types = pub_addr_types;
|
||||
num_addr_types = sizeof pub_addr_types / sizeof pub_addr_types[0];
|
||||
}
|
||||
|
||||
for (i = 0; i < num_addr_types; i++) {
|
||||
addr_type = addr_types[i];
|
||||
|
||||
rc = ble_hs_id_addr_type_usable(addr_type);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
*out_addr_type = addr_type;
|
||||
return 0;
|
||||
|
||||
case BLE_HS_ENOADDR:
|
||||
break;
|
||||
|
||||
default:
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return BLE_HS_ENOADDR;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ void ble_hs_id_set_pub(const uint8_t *pub_addr);
|
||||
int ble_hs_id_addr(uint8_t id_addr_type, const uint8_t **out_id_addr,
|
||||
int *out_is_nrpa);
|
||||
int ble_hs_id_use_addr(uint8_t addr_type);
|
||||
int ble_hs_id_infer_auto(int privacy, uint8_t *out_addr_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ static void
|
||||
ble_gap_test_util_init(void)
|
||||
{
|
||||
ble_hs_test_util_init();
|
||||
ble_hs_test_util_set_static_rnd_addr();
|
||||
ble_hs_test_util_set_static_rnd_addr((uint8_t[6]){ 1, 2, 3, 4, 5, 0xc0 });
|
||||
ble_gap_test_util_reset_cb_info();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "testutil/testutil.h"
|
||||
#include "nimble/hci_common.h"
|
||||
#include "host/ble_hs_adv.h"
|
||||
#include "host/ble_hs_test.h"
|
||||
#include "ble_hs_test_util.h"
|
||||
|
||||
static int
|
||||
ble_hs_id_test_util_infer_auto(int privacy, uint8_t *own_addr_type)
|
||||
{
|
||||
int rc;
|
||||
|
||||
ble_hs_lock();
|
||||
rc = ble_hs_id_infer_auto(privacy, own_addr_type);
|
||||
ble_hs_unlock();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
TEST_CASE(ble_hs_id_test_case_auto_none)
|
||||
{
|
||||
uint8_t own_addr_type;
|
||||
int rc;
|
||||
|
||||
ble_hs_test_util_init();
|
||||
|
||||
/* Clear public address. */
|
||||
ble_hs_id_set_pub((uint8_t[6]){ 0, 0, 0, 0, 0, 0 });
|
||||
|
||||
rc = ble_hs_id_test_util_infer_auto(0, &own_addr_type);
|
||||
TEST_ASSERT_FATAL(rc == BLE_HS_ENOADDR);
|
||||
}
|
||||
|
||||
TEST_CASE(ble_hs_id_test_case_auto_public)
|
||||
{
|
||||
uint8_t own_addr_type;
|
||||
int rc;
|
||||
|
||||
ble_hs_test_util_init();
|
||||
|
||||
rc = ble_hs_id_test_util_infer_auto(0, &own_addr_type);
|
||||
TEST_ASSERT_FATAL(rc == 0);
|
||||
TEST_ASSERT(own_addr_type == BLE_OWN_ADDR_PUBLIC);
|
||||
}
|
||||
|
||||
TEST_CASE(ble_hs_id_test_case_auto_random)
|
||||
{
|
||||
uint8_t own_addr_type;
|
||||
int rc;
|
||||
|
||||
ble_hs_test_util_init();
|
||||
|
||||
/* Configure a random address. */
|
||||
ble_hs_test_util_set_static_rnd_addr((uint8_t[6]){ 1, 2, 3, 4, 5, 0xc0 });
|
||||
|
||||
rc = ble_hs_id_test_util_infer_auto(0, &own_addr_type);
|
||||
TEST_ASSERT_FATAL(rc == 0);
|
||||
TEST_ASSERT(own_addr_type == BLE_OWN_ADDR_RANDOM);
|
||||
}
|
||||
|
||||
TEST_CASE(ble_hs_id_test_case_auto_rpa_pub)
|
||||
{
|
||||
uint8_t own_addr_type;
|
||||
int rc;
|
||||
|
||||
ble_hs_test_util_init();
|
||||
|
||||
rc = ble_hs_id_test_util_infer_auto(1, &own_addr_type);
|
||||
TEST_ASSERT_FATAL(rc == 0);
|
||||
TEST_ASSERT(own_addr_type == BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT);
|
||||
}
|
||||
|
||||
TEST_CASE(ble_hs_id_test_case_auto_rpa_rnd)
|
||||
{
|
||||
uint8_t own_addr_type;
|
||||
int rc;
|
||||
|
||||
ble_hs_test_util_init();
|
||||
|
||||
/* Configure a random address. */
|
||||
ble_hs_test_util_set_static_rnd_addr((uint8_t[6]){ 1, 2, 3, 4, 5, 0xc0 });
|
||||
|
||||
rc = ble_hs_id_test_util_infer_auto(1, &own_addr_type);
|
||||
TEST_ASSERT_FATAL(rc == 0);
|
||||
TEST_ASSERT(own_addr_type == BLE_OWN_ADDR_RPA_RANDOM_DEFAULT);
|
||||
}
|
||||
|
||||
TEST_SUITE(ble_hs_id_test_suite_auto)
|
||||
{
|
||||
tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
|
||||
|
||||
ble_hs_id_test_case_auto_none();
|
||||
ble_hs_id_test_case_auto_public();
|
||||
ble_hs_id_test_case_auto_random();
|
||||
ble_hs_id_test_case_auto_rpa_pub();
|
||||
ble_hs_id_test_case_auto_rpa_rnd();
|
||||
}
|
||||
|
||||
int
|
||||
ble_hs_id_test_all(void)
|
||||
{
|
||||
ble_hs_id_test_suite_auto();
|
||||
|
||||
return tu_any_failed;
|
||||
}
|
||||
@@ -48,6 +48,7 @@ main(int argc, char **argv)
|
||||
ble_hs_adv_test_all();
|
||||
ble_hs_conn_test_all();
|
||||
ble_hs_hci_test_all();
|
||||
ble_hs_id_test_all();
|
||||
ble_l2cap_test_all();
|
||||
ble_os_test_all();
|
||||
ble_sm_test_all();
|
||||
|
||||
@@ -2006,9 +2006,8 @@ ble_hs_test_util_verify_tx_l2cap_update_rsp(uint8_t exp_id,
|
||||
}
|
||||
|
||||
void
|
||||
ble_hs_test_util_set_static_rnd_addr(void)
|
||||
ble_hs_test_util_set_static_rnd_addr(const uint8_t *addr)
|
||||
{
|
||||
uint8_t addr[6] = { 1, 2, 3, 4, 5, 0xc1 };
|
||||
int rc;
|
||||
|
||||
ble_hs_test_util_set_ack(
|
||||
@@ -2454,4 +2453,7 @@ ble_hs_test_util_init(void)
|
||||
TEST_ASSERT_FATAL(rc == 0);
|
||||
|
||||
ble_hs_test_util_prev_hci_tx_clear();
|
||||
|
||||
/* Clear random address. */
|
||||
ble_hs_test_util_set_static_rnd_addr((uint8_t[6]){ 0, 0, 0, 0, 0, 0 });
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ int ble_hs_test_util_rx_l2cap_update_rsp(uint16_t conn_handle,
|
||||
uint8_t id, uint16_t result);
|
||||
void ble_hs_test_util_verify_tx_l2cap_update_rsp(uint8_t exp_id,
|
||||
uint16_t exp_result);
|
||||
void ble_hs_test_util_set_static_rnd_addr(void);
|
||||
void ble_hs_test_util_set_static_rnd_addr(const uint8_t *addr);
|
||||
struct os_mbuf *ble_hs_test_util_om_from_flat(const void *buf, uint16_t len);
|
||||
int ble_hs_test_util_flat_attr_cmp(const struct ble_hs_test_util_flat_attr *a,
|
||||
const struct ble_hs_test_util_flat_attr *b);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef H_HOST_UTIL_
|
||||
#define H_HOST_UTIL_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ble_hs_util_ensure_addr(int prefer_random);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
pkg.name: net/nimble/host/util
|
||||
pkg.description: Supplementary utilities for the NimBLE host
|
||||
pkg.author: "Apache Mynewt <[email protected]>"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
pkg.keywords:
|
||||
- ble
|
||||
- bluetooth
|
||||
|
||||
pkg.deps:
|
||||
- net/nimble/host
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "hal/hal_bsp.h"
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/util/util.h"
|
||||
|
||||
#if MYNEWT_VAL(BLE_DEVICE)
|
||||
#include "controller/ble_hw.h"
|
||||
#endif
|
||||
|
||||
static int
|
||||
ble_hs_util_load_rand_addr(ble_addr_t *addr)
|
||||
{
|
||||
/* XXX: It is unfortunate that the function to retrieve the random address
|
||||
* is in the controller package. A host-only device ought to be able to
|
||||
* automically restore a random address.
|
||||
*/
|
||||
#if MYNEWT_VAL(BLE_DEVICE)
|
||||
int rc;
|
||||
|
||||
rc = ble_hw_get_static_addr(addr);
|
||||
if (rc == 0) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return BLE_HS_ENOADDR;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_hs_util_ensure_rand_addr(void)
|
||||
{
|
||||
ble_addr_t addr;
|
||||
int rc;
|
||||
|
||||
/* If we already have a random address, then we are done. */
|
||||
rc = ble_hs_id_copy_addr(BLE_ADDR_RANDOM, NULL, NULL);
|
||||
if (rc == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, try to load a random address. */
|
||||
rc = ble_hs_util_load_rand_addr(&addr);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Configure nimble to use the random address. */
|
||||
rc = ble_hs_id_set_rnd(addr.val);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to configure the device with at least one Bluetooth address.
|
||||
* Addresses are restored in a hardware-specific fasion.
|
||||
*
|
||||
* @param prefer_random Whether to attempt to restore a random address
|
||||
* before checking if a public address has
|
||||
* already been configured.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* BLE_HS_ENOADDR if the device does not have any
|
||||
* available addresses.
|
||||
* Other BLE host core code on error.
|
||||
*/
|
||||
int
|
||||
ble_hs_util_ensure_addr(int prefer_random)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (prefer_random) {
|
||||
/* Try to load a random address. */
|
||||
rc = ble_hs_util_ensure_rand_addr();
|
||||
if (rc == BLE_HS_ENOADDR) {
|
||||
/* No random address; try to load a public address. */
|
||||
rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
/* Try to load a public address. */
|
||||
rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, NULL, NULL);
|
||||
if (rc == BLE_HS_ENOADDR) {
|
||||
/* No random address; try to load a random address. */
|
||||
rc = ble_hs_util_ensure_rand_addr();
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
# Package: net/nimble/host/util
|
||||
|
||||
syscfg.defs:
|
||||
Reference in New Issue
Block a user