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:
Szymon Janc
2017-09-01 09:38:50 +02:00
committed by GitHub
12 changed files with 436 additions and 17 deletions
+2 -1
View File
@@ -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
View File
@@ -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;
}
+1
View File
@@ -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
}
+1 -1
View File
@@ -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();
}
+126
View File
@@ -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;
}
+1
View File
@@ -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();
+4 -2
View File
@@ -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 });
}
+1 -1
View File
@@ -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);
+33
View File
@@ -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
+29
View File
@@ -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
+109
View File
@@ -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;
}
+21
View File
@@ -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: