BLE: Add privacy trace (#14127)

Add traces to the Bluetooth Security Manager and Privacy controller.
The traces are made to be comprehensive to improve the ux when users submit bugs.
A centralized set of helpers has been created to convert BLE types to string.

* BLE: Add SM traces

* BLE: Add traces to Security Manager PAL

* BLE: Make SM traces consistent.
- Prefix with Connection <id> - when appropriate.
- Display parameters after `:`.
- If multiple parameters should be displayed name then and print the value after =. They are separated by a `,`.

* BLE: Fix SM random number generation.

Only the first 8 bytes were generated from the stack.

* BLE: Regenerate CSRK if it is all zeroes.

* BLE: Add trace into privacy modules

Address resolution is set at the debug level as it is a very common operation and may clutter the output.

* Address trace review for SM:

- Put privacy traces in BLPR
- Add missing traces in PALSecurityManagerImpl.cpp
- Add missing EventHandler null pointer check
- Typo and parameters order fix.
pull/14198/head
Vincent Coubard 2021-01-08 12:04:52 +00:00 committed by Paul Szczepanek
parent c73413893f
commit 5aa76e566a
5 changed files with 834 additions and 87 deletions

View File

@ -0,0 +1,206 @@
/* mbed Microcontroller Library
* Copyright (c) 2021 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed 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 BLE_CLIAPP_BLE_TRACE_HELPERS_H
#define BLE_CLIAPP_BLE_TRACE_HELPERS_H
#include "ble/SecurityManager.h"
#include "mbed-trace/mbed_trace.h"
namespace ble {
static inline constexpr const char* to_string(bool v)
{
if (v) {
return "true";
} else {
return "false";
}
}
static inline constexpr const char* to_string(ble::SecurityManager::SecurityIOCapabilities_t capabilities)
{
switch(capabilities) {
case ble::SecurityManager::IO_CAPS_DISPLAY_ONLY:
return "IO_CAPS_DISPLAY_ONLY";
case ble::SecurityManager::IO_CAPS_DISPLAY_YESNO:
return "IO_CAPS_DISPLAY_YESNO";
case ble::SecurityManager::IO_CAPS_KEYBOARD_DISPLAY:
return "IO_CAPS_KEYBOARD_DISPLAY";
case ble::SecurityManager::IO_CAPS_KEYBOARD_ONLY:
return "IO_CAPS_KEYBOARD_ONLY";
case ble::SecurityManager::IO_CAPS_NONE:
return "IO_CAPS_NONE";
default:
return "unknown";
}
}
static inline const char* to_string(ble::io_capability_t capabilities)
{
switch (capabilities.value()) {
case ble::io_capability_t::DISPLAY_ONLY:
return "DISPLAY_ONLY";
case ble::io_capability_t::DISPLAY_YES_NO:
return "IO_CAPS_DISPLAY_DISPLAY_YES_NOYESNO";
case ble::io_capability_t::KEYBOARD_ONLY:
return "KEYBOARD_ONLY";
case ble::io_capability_t::NO_INPUT_NO_OUTPUT:
return "NO_INPUT_NO_OUTPUT";
case ble::io_capability_t::KEYBOARD_DISPLAY:
return "KEYBOARD_DISPLAY";
default:
return "unknown";
}
}
static inline constexpr const char* to_string(ble::SecurityManager::SecurityMode_t security_mode)
{
switch (security_mode) {
case ble::SecurityManager::SECURITY_MODE_NO_ACCESS:
return "SECURITY_MODE_NO_ACCESS";
case ble::SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK:
return "SECURITY_MODE_ENCRYPTION_OPEN_LINK";
case ble::SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
return "SECURITY_MODE_ENCRYPTION_NO_MITM";
case ble::SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
return "SECURITY_MODE_ENCRYPTION_WITH_MITM";
case ble::SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
return "SECURITY_MODE_SIGNED_NO_MITM";
case ble::SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
return "SECURITY_MODE_SIGNED_WITH_MITM";
default:
return "Unknown";
}
}
static inline constexpr const char* passkey_str(const uint8_t* passkey)
{
if (!passkey) {
return "0";
} else {
return (mbed_trace_array)(passkey, 6);
}
}
static inline const char* to_string(const ble::address_t& address)
{
return (mbed_trace_array)(address.data(), address.size());
}
template<size_t size>
const char* to_string(const ble::byte_array_t<size> &array)
{
return (mbed_trace_array)(array.data(), array.size());
}
static inline const char* to_string(const ble::link_encryption_t encryption)
{
using link_encryption_t = ble::link_encryption_t;
switch (encryption.value()) {
case link_encryption_t::NOT_ENCRYPTED:
return "NOT_ENCRYPTED";
case link_encryption_t::ENCRYPTION_IN_PROGRESS:
return "ENCRYPTION_IN_PROGRESS";
case link_encryption_t::ENCRYPTED:
return "ENCRYPTED";
case link_encryption_t::ENCRYPTED_WITH_MITM:
return "ENCRYPTED_WITH_MITM";
case link_encryption_t::ENCRYPTED_WITH_SC_AND_MITM:
return "ENCRYPTED_WITH_SC_AND_MITM";
default:
return "Unknown";
}
}
static inline const char* to_string(Keypress_t keypress)
{
switch (keypress) {
case KEYPRESS_STARTED:
return "KEYPRESS_STARTED";
case KEYPRESS_ENTERED:
return "KEYPRESS_ENTERED";
case KEYPRESS_ERASED:
return "KEYPRESS_ERASED";
case KEYPRESS_CLEARED:
return "KEYPRESS_CLEARED";
case KEYPRESS_COMPLETED:
return "KEYPRESS_COMPLETED";
default:
return "Unknown";
}
}
static inline const char *to_string(ble::pairing_failure_t reason)
{
switch (reason.value()) {
case ble::pairing_failure_t::PASSKEY_ENTRY_FAILED:
return "PASSKEY_ENTRY_FAILED";
case ble::pairing_failure_t::OOB_NOT_AVAILABLE:
return "OOB_NOT_AVAILABLE";
case ble::pairing_failure_t::AUTHENTICATION_REQUIREMENTS:
return "AUTHENTICATION_REQUIREMENTS";
case ble::pairing_failure_t::CONFIRM_VALUE_FAILED:
return "CONFIRM_VALUE_FAILED";
case ble::pairing_failure_t::PAIRING_NOT_SUPPORTED:
return "PAIRING_NOT_SUPPORTED";
case ble::pairing_failure_t::ENCRYPTION_KEY_SIZE:
return "ENCRYPTION_KEY_SIZE";
case ble::pairing_failure_t::COMMAND_NOT_SUPPORTED:
return "COMMAND_NOT_SUPPORTED";
case ble::pairing_failure_t::UNSPECIFIED_REASON:
return "UNSPECIFIED_REASON";
case ble::pairing_failure_t::REPEATED_ATTEMPTS:
return "REPEATED_ATTEMPTS";
case ble::pairing_failure_t::INVALID_PARAMETERS:
return "INVALID_PARAMETERS";
case ble::pairing_failure_t::DHKEY_CHECK_FAILED:
return "DHKEY_CHECK_FAILED";
case ble::pairing_failure_t::NUMERIC_COMPARISON_FAILED:
return "NUMERIC_COMPARISON_FAILED";
case ble::pairing_failure_t::BR_EDR_PAIRING_IN_PROGRESS:
return "BR_EDR_PAIRING_IN_PROGRESS";
case ble::pairing_failure_t::CROSS_TRANSPORT_KEY_DERIVATION_OR_GENERATION_NOT_ALLOWED:
return "CROSS_TRANSPORT_KEY_DERIVATION_OR_GENERATION_NOT_ALLOWED";
default:
return "Unknown";
}
}
static inline const char *to_string(target_peer_address_type_t type)
{
if (type == target_peer_address_type_t::PUBLIC) {
return "PUBLIC";
} else {
return "RANDOM";
}
}
static inline const char *to_string(privacy_mode_t mode)
{
if (mode == privacy_mode_t::NETWORK) {
return "NETWORK";
} else {
return "DEVICE";
}
}
} // namespace ble
#endif //BLE_CLIAPP_BLE_TRACE_HELPERS_H

View File

@ -19,24 +19,32 @@
#include "PalPrivateAddressControllerImpl.h" #include "PalPrivateAddressControllerImpl.h"
#include "dm_api.h" #include "dm_api.h"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLPR"
namespace ble { namespace ble {
namespace impl { namespace impl {
ble_error_t PalPrivateAddressController::initialize() ble_error_t PalPrivateAddressController::initialize()
{ {
tr_info("Initialize privacy PAL");
DmPrivInit(); DmPrivInit();
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t PalPrivateAddressController::terminate() ble_error_t PalPrivateAddressController::terminate()
{ {
tr_info("Terminate privacy PAL");
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t PalPrivateAddressController::generate_resolvable_private_address(const irk_t& local_irk) ble_error_t PalPrivateAddressController::generate_resolvable_private_address(const irk_t& local_irk)
{ {
tr_info("PAL start generation of RPA from local irk: %s", to_string(local_irk));
if (_generating_rpa) { if (_generating_rpa) {
tr_error("PAL can't generate RPA, it is busy handling a previous request");
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
@ -50,6 +58,7 @@ address_t PalPrivateAddressController::generate_non_resolvable_private_address()
address_t address; address_t address;
SecRand(address.data(), address.size()); SecRand(address.data(), address.size());
DM_RAND_ADDR_SET(address, DM_RAND_ADDR_NONRESOLV); DM_RAND_ADDR_SET(address, DM_RAND_ADDR_NONRESOLV);
tr_info("Non resolvable private address generated: %s", to_string(address));
return address; return address;
} }
@ -59,9 +68,11 @@ ble_error_t PalPrivateAddressController::resolve_private_address(
) )
{ {
if (_resolving_rpa) { if (_resolving_rpa) {
tr_error("Failed to start resolution of RPA: Handling a previous request");
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
tr_debug("Start resolution of private address: address=%s, irk=%s", to_string(address), to_string(irk));
DmPrivResolveAddr( DmPrivResolveAddr(
const_cast<uint8_t*>(address.data()), const_cast<uint8_t*>(address.data()),
const_cast<uint8_t*>(irk.data()), const_cast<uint8_t*>(irk.data()),
@ -77,6 +88,7 @@ bool PalPrivateAddressController::is_ll_privacy_supported()
ble_error_t PalPrivateAddressController::set_ll_address_resolution(bool enable) ble_error_t PalPrivateAddressController::set_ll_address_resolution(bool enable)
{ {
tr_info("Enable LL private address resolution");
DmPrivSetAddrResEnable(enable); DmPrivSetAddrResEnable(enable);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -86,9 +98,11 @@ ble_error_t PalPrivateAddressController::set_ll_resolvable_private_address_timeo
) )
{ {
if (HciLlPrivacySupported() == false) { if (HciLlPrivacySupported() == false) {
tr_error("Operation not supported by LL: RPA generation");
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
tr_info("Set LL resolvable private address generation timeout: %d s", timeout.value());
DmPrivSetResolvablePrivateAddrTimeout(timeout.value()); DmPrivSetResolvablePrivateAddrTimeout(timeout.value());
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -106,8 +120,12 @@ ble_error_t PalPrivateAddressController::add_device_to_resolving_list(
) )
{ {
if (is_ll_privacy_supported() == false) { if (is_ll_privacy_supported() == false) {
tr_error("Operation not supported by LL: RPA resolution");
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
tr_info("Add RPA to LL resolving list: peer address=%s, type=%s, peer irk=%s, local irk=%s",
to_string(peer_identity_address), to_string(peer_address_type), to_string(peer_irk), to_string(local_irk));
DmPrivAddDevToResList( DmPrivAddDevToResList(
peer_address_type.value(), peer_address_type.value(),
peer_identity_address.data(), peer_identity_address.data(),
@ -130,9 +148,12 @@ ble_error_t PalPrivateAddressController::remove_device_from_resolving_list(
) )
{ {
if (is_ll_privacy_supported() == false) { if (is_ll_privacy_supported() == false) {
tr_error("Operation not supported by LL: RPA resolution");
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
tr_info("Remove RPA from LL resolving list: peer address=%s, type=%s",
to_string(peer_identity_address), to_string(peer_address_type));
DmPrivRemDevFromResList(peer_address_type.value(), peer_identity_address.data(), 0); DmPrivRemDevFromResList(peer_address_type.value(), peer_identity_address.data(), 0);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -144,8 +165,11 @@ ble_error_t PalPrivateAddressController::set_peer_privacy_mode(
) )
{ {
if (is_ll_privacy_supported() == false) { if (is_ll_privacy_supported() == false) {
tr_error("Operation not supported by LL: privacy");
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
tr_info("Set privacy mode: peer address=%s, type=%s, mode=%s",
to_string(peer_address), to_string(peer_address_type), to_string(privacy_mode));
DmPrivSetPrivacyMode( DmPrivSetPrivacyMode(
peer_address_type.value(), peer_address_type.value(),
peer_address.data(), peer_address.data(),
@ -157,9 +181,11 @@ ble_error_t PalPrivateAddressController::set_peer_privacy_mode(
ble_error_t PalPrivateAddressController::clear_resolving_list() ble_error_t PalPrivateAddressController::clear_resolving_list()
{ {
if (is_ll_privacy_supported() == false) { if (is_ll_privacy_supported() == false) {
tr_error("Operation not supported by LL: privacy resolving list");
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
tr_info("Clear LL resolving list");
DmPrivClearResList(); DmPrivClearResList();
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -178,6 +204,7 @@ PalPrivateAddressController& PalPrivateAddressController::instance()
bool PalPrivateAddressController::cordio_handler(const wsfMsgHdr_t *msg) bool PalPrivateAddressController::cordio_handler(const wsfMsgHdr_t *msg)
{ {
if (msg == nullptr) { if (msg == nullptr) {
tr_warning("Privacy handler received null message");
return false; return false;
} }
@ -185,9 +212,11 @@ bool PalPrivateAddressController::cordio_handler(const wsfMsgHdr_t *msg)
switch (msg->event) { switch (msg->event) {
case DM_PRIV_GENERATE_ADDR_IND: { case DM_PRIV_GENERATE_ADDR_IND: {
tr_info("Privacy handling: DM_PRIV_GENERATE_ADDR_IND");
instance()._generating_rpa = false; instance()._generating_rpa = false;
if (!handler) { if (!handler) {
tr_warning("No user handler registered for PAL privacy");
return true; return true;
} }
@ -217,7 +246,15 @@ bool PalPrivateAddressController::cordio_handler(const wsfMsgHdr_t *msg)
case DM_PRIV_REM_DEV_FROM_RES_LIST_IND: // Device removed from resolving list case DM_PRIV_REM_DEV_FROM_RES_LIST_IND: // Device removed from resolving list
case DM_PRIV_CLEAR_RES_LIST_IND: // Resolving list cleared case DM_PRIV_CLEAR_RES_LIST_IND: // Resolving list cleared
{ {
tr_info("Privacy handling: %s",
msg->event == DM_PRIV_ADD_DEV_TO_RES_LIST_IND ?
"DM_PRIV_ADD_DEV_TO_RES_LIST_IND" :
msg->event == DM_PRIV_ADD_DEV_TO_RES_LIST_IND ?
"DM_PRIV_REM_DEV_FROM_RES_LIST_IND" :
"DM_PRIV_CLEAR_RES_LIST_IND"
);
if (!handler) { if (!handler) {
tr_warning("No user handler registered for PAL privacy");
return true; return true;
} }

View File

@ -30,6 +30,11 @@
#include "wsf_os.h" #include "wsf_os.h"
#include "hci_core.h" #include "hci_core.h"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLSM"
namespace ble { namespace ble {
namespace impl { namespace impl {
@ -51,6 +56,7 @@ PalSecurityManager::~PalSecurityManager()
ble_error_t PalSecurityManager::initialize() ble_error_t PalSecurityManager::initialize()
{ {
tr_info("Initialize PAL SM");
// reset local state // reset local state
_use_default_passkey = false; _use_default_passkey = false;
_default_passkey = 0; _default_passkey = 0;
@ -73,6 +79,7 @@ ble_error_t PalSecurityManager::initialize()
ble_error_t PalSecurityManager::terminate() ble_error_t PalSecurityManager::terminate()
{ {
tr_info("Terminate PAL SM");
#if BLE_FEATURE_SIGNING #if BLE_FEATURE_SIGNING
cleanup_peer_csrks(); cleanup_peer_csrks();
#endif // BLE_FEATURE_SIGNING #endif // BLE_FEATURE_SIGNING
@ -82,6 +89,7 @@ ble_error_t PalSecurityManager::terminate()
ble_error_t PalSecurityManager::reset() ble_error_t PalSecurityManager::reset()
{ {
tr_info("Reset PAL SM");
#if BLE_FEATURE_SIGNING #if BLE_FEATURE_SIGNING
cleanup_peer_csrks(); cleanup_peer_csrks();
#endif // BLE_FEATURE_SIGNING #endif // BLE_FEATURE_SIGNING
@ -134,6 +142,7 @@ ble_error_t PalSecurityManager::set_authentication_timeout(
connection_handle_t connection, uint16_t timeout_in_10ms connection_handle_t connection, uint16_t timeout_in_10ms
) )
{ {
tr_info("Connection %d - pass authentication timeout %d to the stack", connection, timeout_in_10ms);
DmWriteAuthPayloadTimeout(connection, timeout_in_10ms); DmWriteAuthPayloadTimeout(connection, timeout_in_10ms);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -153,6 +162,7 @@ ble_error_t PalSecurityManager::slave_security_request(
AuthenticationMask authentication AuthenticationMask authentication
) )
{ {
tr_info("Connection %d - Pass slave security to the stack: authentication = %02x", connection, authentication.value());
DmSecSlaveReq(connection, authentication.value()); DmSecSlaveReq(connection, authentication.value());
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -171,6 +181,8 @@ ble_error_t PalSecurityManager::enable_encryption(
bool mitm bool mitm
) )
{ {
tr_info("Connection %d - Enable encryption: lth = %s, rand = %s, ediv = %s, mitm = %s",
connection, to_string(ltk), to_string(rand), to_string(ediv), to_string(mitm));
dmSecLtk_t sec_ltk; dmSecLtk_t sec_ltk;
memcpy(sec_ltk.key, ltk.data(), ltk.size()); memcpy(sec_ltk.key, ltk.data(), ltk.size());
memcpy(sec_ltk.rand, rand.data(), rand.size()); memcpy(sec_ltk.rand, rand.data(), rand.size());
@ -192,6 +204,8 @@ ble_error_t PalSecurityManager::enable_encryption(
bool mitm bool mitm
) )
{ {
tr_info("Connection %d - Enable SC encryption: ltk = %s, mitm = %s",
connection, to_string(ltk), to_string(mitm));
dmSecLtk_t sec_ltk = {0}; dmSecLtk_t sec_ltk = {0};
memcpy(sec_ltk.key, ltk.data(), ltk.size()); memcpy(sec_ltk.key, ltk.data(), ltk.size());
@ -213,6 +227,7 @@ ble_error_t PalSecurityManager::encrypt_data(
encryption_block_t &data encryption_block_t &data
) )
{ {
tr_warning("PAL Encrypt data not implemented");
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
@ -229,6 +244,8 @@ ble_error_t PalSecurityManager::set_ltk(
bool secure_connections bool secure_connections
) )
{ {
tr_info("Connection %d - send ltk response: ltk = %s, mitm = %s, sc = %s ",
connection, to_string(ltk), to_string(mitm), to_string(secure_connections));
uint8_t security_level = DM_SEC_LEVEL_NONE; uint8_t security_level = DM_SEC_LEVEL_NONE;
if (secure_connections) { if (secure_connections) {
security_level = DM_SEC_LEVEL_ENC_LESC; security_level = DM_SEC_LEVEL_ENC_LESC;
@ -252,6 +269,7 @@ ble_error_t PalSecurityManager::set_ltk_not_found(
connection_handle_t connection connection_handle_t connection
) )
{ {
tr_info("Connection %d - Reply LTK not found", connection);
DmSecLtkRsp( DmSecLtkRsp(
connection, connection,
/* key found */ false, /* key found */ false,
@ -265,6 +283,7 @@ ble_error_t PalSecurityManager::set_ltk_not_found(
ble_error_t PalSecurityManager::set_irk(const irk_t &irk) ble_error_t PalSecurityManager::set_irk(const irk_t &irk)
{ {
tr_info("Set stack local IRK: %s", to_string(irk));
_irk = irk; _irk = irk;
DmSecSetLocalIrk(_irk.data()); DmSecSetLocalIrk(_irk.data());
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
@ -275,6 +294,7 @@ ble_error_t PalSecurityManager::set_identity_address(
bool public_address bool public_address
) )
{ {
tr_info("Set stack local identity address: address = %s, public = %s", to_string(address), to_string(public_address));
DmSecSetLocalIdentityAddr( DmSecSetLocalIdentityAddr(
address.data(), address.data(),
public_address ? DM_ADDR_PUBLIC : DM_ADDR_RANDOM public_address ? DM_ADDR_PUBLIC : DM_ADDR_RANDOM
@ -288,6 +308,7 @@ ble_error_t PalSecurityManager::set_csrk(
sign_count_t sign_counter sign_count_t sign_counter
) )
{ {
tr_info("Set stack local CSRK: CSRK = %s, sign counter = %" PRIu32, to_string(csrk), sign_counter);
_csrk = csrk; _csrk = csrk;
DmSecSetLocalCsrk(_csrk.data()); DmSecSetLocalCsrk(_csrk.data());
#if BLE_FEATURE_GATT_CLIENT #if BLE_FEATURE_GATT_CLIENT
@ -307,9 +328,13 @@ ble_error_t PalSecurityManager::set_peer_csrk(
) )
{ {
if (connection == 0 || connection > DM_CONN_MAX) { if (connection == 0 || connection > DM_CONN_MAX) {
tr_error("Connection %d - Imposible to set stack peer CSRK, invalid connection ID", connection);
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
tr_info("Connection %d - Set stack peer CSRK: CSRK = %s, authenticated = %s, sign_counter = %" PRIu32,
connection, to_string(csrk), to_string(authenticated), sign_counter);
size_t connection_index = connection - 1; size_t connection_index = connection - 1;
if (_peer_csrks[connection_index]) { if (_peer_csrks[connection_index]) {
@ -330,9 +355,12 @@ ble_error_t PalSecurityManager::set_peer_csrk(
ble_error_t PalSecurityManager::remove_peer_csrk(connection_handle_t connection) ble_error_t PalSecurityManager::remove_peer_csrk(connection_handle_t connection)
{ {
if (connection == 0 || connection > DM_CONN_MAX) { if (connection == 0 || connection > DM_CONN_MAX) {
tr_error("Connection %d - Imposible to set stack peer CSRK, invalid connection ID", connection);
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
tr_info("Connection %d - Remove stack peer CSRK", connection);
size_t connection_index = connection - 1; size_t connection_index = connection - 1;
if (_peer_csrks[connection_index]) { if (_peer_csrks[connection_index]) {
@ -352,6 +380,9 @@ ble_error_t PalSecurityManager::remove_peer_csrk(connection_handle_t connection)
ble_error_t PalSecurityManager::set_display_passkey(passkey_num_t passkey) ble_error_t PalSecurityManager::set_display_passkey(passkey_num_t passkey)
{ {
PasskeyAscii ascii_passkey(passkey);
tr_info("Set stack display passkey: %s", passkey_str(ascii_passkey.value()));
if (passkey) { if (passkey) {
_use_default_passkey = true; _use_default_passkey = true;
_default_passkey = passkey; _default_passkey = passkey;
@ -364,6 +395,7 @@ ble_error_t PalSecurityManager::set_display_passkey(passkey_num_t passkey)
ble_error_t PalSecurityManager::set_io_capability(io_capability_t io_capability) ble_error_t PalSecurityManager::set_io_capability(io_capability_t io_capability)
{ {
tr_info("Set stack I/O capabilities: %s", to_string(io_capability));
pSmpCfg->ioCap = io_capability.value(); pSmpCfg->ioCap = io_capability.value();
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -374,6 +406,7 @@ ble_error_t PalSecurityManager::set_encryption_key_requirements(
uint8_t max_encryption_key_size uint8_t max_encryption_key_size
) )
{ {
tr_info("Set stack encryption key requirements: [%d : %d]", min_encryption_key_size, max_encryption_key_size);
if ((min_encryption_key_size < 7) || (min_encryption_key_size > 16) || if ((min_encryption_key_size < 7) || (min_encryption_key_size > 16) ||
(min_encryption_key_size > max_encryption_key_size)) { (min_encryption_key_size > max_encryption_key_size)) {
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
@ -398,6 +431,8 @@ ble_error_t PalSecurityManager::send_pairing_request(
KeyDistribution responder_dist KeyDistribution responder_dist
) )
{ {
tr_info("Connection %d - send pairing request: oob = %s, auth = %02X, initiator dist = %02x, responder dist = %02X",
connection, to_string(oob_data_flag), authentication_requirements.value(), initiator_dist.value(), responder_dist.value());
DmSecPairReq( DmSecPairReq(
connection, connection,
oob_data_flag, oob_data_flag,
@ -419,6 +454,8 @@ ble_error_t PalSecurityManager::send_pairing_response(
KeyDistribution responder_dist KeyDistribution responder_dist
) )
{ {
tr_info("Connection %d - Send pairing response: oob = %s, auth = %02X, initiator dist = %02x, responder dist = %02X",
connection, to_string(oob_data_flag), authentication_requirements.value(), initiator_dist.value(), responder_dist.value());
DmSecPairRsp( DmSecPairRsp(
connection, connection,
oob_data_flag, oob_data_flag,
@ -436,6 +473,7 @@ ble_error_t PalSecurityManager::cancel_pairing(
connection_handle_t connection, pairing_failure_t reason connection_handle_t connection, pairing_failure_t reason
) )
{ {
tr_info("Connection %d - cancel pairing: reason = %s", connection, to_string(reason));
DmSecCancelReq(connection, reason.value()); DmSecCancelReq(connection, reason.value());
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -444,6 +482,7 @@ ble_error_t PalSecurityManager::cancel_pairing(
ble_error_t PalSecurityManager::get_random_data(byte_array_t<8> &random_data) ble_error_t PalSecurityManager::get_random_data(byte_array_t<8> &random_data)
{ {
SecRand(random_data.data(), random_data.size()); SecRand(random_data.data(), random_data.size());
tr_info("Stack generated random data: %s", to_string(random_data));
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -456,6 +495,7 @@ ble_error_t PalSecurityManager::passkey_request_reply(
connection_handle_t connection, passkey_num_t passkey connection_handle_t connection, passkey_num_t passkey
) )
{ {
tr_info("Connection %d - Reply with passkey %s", connection, passkey_str(PasskeyAscii(passkey).value()));
DmSecAuthRsp( DmSecAuthRsp(
connection, connection,
/* datalength */ 3, /* datalength */ 3,
@ -471,6 +511,7 @@ ble_error_t PalSecurityManager::legacy_pairing_oob_request_reply(
const oob_tk_t &oob_data const oob_tk_t &oob_data
) )
{ {
tr_info("Connection %d - Reply with legacy OOB data %s", connection, to_string(oob_data));
DmSecAuthRsp( DmSecAuthRsp(
connection, connection,
/* data length */16, /* data length */16,
@ -485,6 +526,7 @@ ble_error_t PalSecurityManager::confirmation_entered(
connection_handle_t connection, bool confirmation connection_handle_t connection, bool confirmation
) )
{ {
tr_info("Connection %d - Send confirmation entered: %s", connection, to_string(confirmation));
DmSecCompareRsp(connection, confirmation); DmSecCompareRsp(connection, confirmation);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -497,6 +539,7 @@ ble_error_t PalSecurityManager::send_keypress_notification(
connection_handle_t connection, ble::Keypress_t keypress connection_handle_t connection, ble::Keypress_t keypress
) )
{ {
tr_info("Connection %d - Send keypress notification: %s", connection, to_string(keypress));
DmSecKeypressReq(connection, keypress); DmSecKeypressReq(connection, keypress);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -504,6 +547,7 @@ ble_error_t PalSecurityManager::send_keypress_notification(
ble_error_t PalSecurityManager::generate_secure_connections_oob() ble_error_t PalSecurityManager::generate_secure_connections_oob()
{ {
tr_info("Start generation of SC OOB");
uint8_t oobLocalRandom[SMP_RAND_LEN]; uint8_t oobLocalRandom[SMP_RAND_LEN];
SecRand(oobLocalRandom, SMP_RAND_LEN); SecRand(oobLocalRandom, SMP_RAND_LEN);
DmSecCalcOobReq(oobLocalRandom, _public_key_x); DmSecCalcOobReq(oobLocalRandom, _public_key_x);
@ -518,6 +562,8 @@ ble_error_t PalSecurityManager::secure_connections_oob_request_reply(
const oob_confirm_t &peer_confirm const oob_confirm_t &peer_confirm
) )
{ {
tr_info("Connection %d - Reply to SC OOB request: local_random = %s, peer_random = %s, peer_confirm = %s",
connection, to_string(local_random), to_string(peer_random), to_string(peer_confirm));
dmSecLescOobCfg_t oob_config = {0}; dmSecLescOobCfg_t oob_config = {0};
memcpy(oob_config.localRandom, local_random.data(), local_random.size()); memcpy(oob_config.localRandom, local_random.data(), local_random.size());
@ -547,11 +593,13 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
PalSecurityManagerEventHandler *handler = self.get_event_handler(); PalSecurityManagerEventHandler *handler = self.get_event_handler();
if ((msg == nullptr) || (handler == nullptr)) { if ((msg == nullptr) || (handler == nullptr)) {
tr_warning("PAL Event handler: invalid message (%p) or handler (%p)", msg, handler);
return false; return false;
} }
switch (msg->event) { switch (msg->event) {
case DM_SEC_PAIR_CMPL_IND: { case DM_SEC_PAIR_CMPL_IND: {
tr_info("Handling event DM_SEC_PAIR_CMPL_IND");
auto *evt = (dmSecPairCmplIndEvt_t *) msg; auto *evt = (dmSecPairCmplIndEvt_t *) msg;
// Note: authentication and bonding flags present in the auth field // Note: authentication and bonding flags present in the auth field
handler->on_pairing_completed(evt->hdr.param); handler->on_pairing_completed(evt->hdr.param);
@ -559,6 +607,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
} }
case DM_SEC_PAIR_FAIL_IND: { case DM_SEC_PAIR_FAIL_IND: {
tr_info("Handling event DM_SEC_PAIR_FAIL_IND");
connection_handle_t connection = msg->param; connection_handle_t connection = msg->param;
uint8_t status = msg->status; uint8_t status = msg->status;
@ -587,6 +636,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
} }
case DM_SEC_ENCRYPT_IND: { case DM_SEC_ENCRYPT_IND: {
tr_info("Handling event DM_SEC_ENCRYPT_IND");
auto *evt = (dmSecEncryptIndEvt_t *) msg; auto *evt = (dmSecEncryptIndEvt_t *) msg;
// note: the field usingLtk of the message indicates if an LTK was // note: the field usingLtk of the message indicates if an LTK was
// used to encrypt the link // used to encrypt the link
@ -596,12 +646,14 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
} }
case DM_SEC_ENCRYPT_FAIL_IND: { case DM_SEC_ENCRYPT_FAIL_IND: {
tr_info("Handling event DM_SEC_ENCRYPT_FAIL_IND");
// note: msg->status contains the encryption failure status // note: msg->status contains the encryption failure status
handler->on_link_encryption_result(msg->param, link_encryption_t::NOT_ENCRYPTED); handler->on_link_encryption_result(msg->param, link_encryption_t::NOT_ENCRYPTED);
return true; return true;
} }
case DM_SEC_AUTH_REQ_IND: { case DM_SEC_AUTH_REQ_IND: {
tr_info("Handling event DM_SEC_AUTH_REQ_IND");
auto *evt = (dmSecAuthReqIndEvt_t *) msg; auto *evt = (dmSecAuthReqIndEvt_t *) msg;
connection_handle_t connection = evt->hdr.param; connection_handle_t connection = evt->hdr.param;
@ -618,6 +670,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
connection, connection,
get_security_manager()._default_passkey get_security_manager()._default_passkey
); );
tr_info("Use default passkey");
DmSecAuthRsp( DmSecAuthRsp(
connection, connection,
/* data length */ SMP_PIN_LEN, /* data length */ SMP_PIN_LEN,
@ -625,6 +678,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
); );
} else { } else {
/* generate random passkey, limit to 6 digit max */ /* generate random passkey, limit to 6 digit max */
tr_info("Generate random passkey");
passkey_num_t passkey; passkey_num_t passkey;
SecRand((uint8_t *) &passkey, sizeof(passkey)); SecRand((uint8_t *) &passkey, sizeof(passkey));
passkey %= 1000000; passkey %= 1000000;
@ -640,6 +694,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
} }
case DM_SEC_KEY_IND: { case DM_SEC_KEY_IND: {
tr_info("Handling event DM_SEC_KEY_IND");
// NOTE: also report security level and encryption key len // NOTE: also report security level and encryption key len
auto *evt = (dmSecKeyIndEvt_t *) msg; auto *evt = (dmSecKeyIndEvt_t *) msg;
connection_handle_t connection = evt->hdr.param; connection_handle_t connection = evt->hdr.param;
@ -697,6 +752,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
} }
case DM_SEC_LTK_REQ_IND: { case DM_SEC_LTK_REQ_IND: {
tr_info("Handling event DM_SEC_LTK_REQ_IND");
uint8_t null_rand[HCI_RAND_LEN] = {0}; uint8_t null_rand[HCI_RAND_LEN] = {0};
auto *evt = (hciLeLtkReqEvt_t *) msg; auto *evt = (hciLeLtkReqEvt_t *) msg;
@ -717,6 +773,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
#if BLE_ROLE_PERIPHERAL #if BLE_ROLE_PERIPHERAL
case DM_SEC_PAIR_IND: { case DM_SEC_PAIR_IND: {
tr_info("Handling event DM_SEC_PAIR_IND");
auto *evt = (dmSecPairIndEvt_t *) msg; auto *evt = (dmSecPairIndEvt_t *) msg;
handler->on_pairing_request( handler->on_pairing_request(
/* connection */ evt->hdr.param, /* connection */ evt->hdr.param,
@ -731,6 +788,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
#if BLE_ROLE_CENTRAL #if BLE_ROLE_CENTRAL
case DM_SEC_SLAVE_REQ_IND: { case DM_SEC_SLAVE_REQ_IND: {
tr_info("Handling event DM_SEC_SLAVE_REQ_IND");
auto *evt = (dmSecPairIndEvt_t *) msg; auto *evt = (dmSecPairIndEvt_t *) msg;
handler->on_slave_security_request( handler->on_slave_security_request(
/* connection */ evt->hdr.param, /* connection */ evt->hdr.param,
@ -742,6 +800,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
#if BLE_FEATURE_SECURE_CONNECTIONS #if BLE_FEATURE_SECURE_CONNECTIONS
case DM_SEC_CALC_OOB_IND: { case DM_SEC_CALC_OOB_IND: {
tr_info("Handling event DM_SEC_CALC_OOB_IND");
auto *evt = (dmSecOobCalcIndEvt_t *) msg; auto *evt = (dmSecOobCalcIndEvt_t *) msg;
handler->on_secure_connections_oob_generated( handler->on_secure_connections_oob_generated(
evt->random, evt->random,
@ -751,7 +810,12 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
} }
case DM_SEC_ECC_KEY_IND: { case DM_SEC_ECC_KEY_IND: {
tr_info("Handling event DM_SEC_ECC_KEY_IND");
auto *evt = (secEccMsg_t *) msg; auto *evt = (secEccMsg_t *) msg;
tr_info("ECC Keys generated: public key x=%s, public key y=%s, private key=%s",
tr_array(evt->data.key.pubKey_x, SEC_ECC_KEY_LEN),
tr_array(evt->data.key.pubKey_y, SEC_ECC_KEY_LEN),
tr_array(evt->data.key.privKey, SEC_ECC_KEY_LEN));
DmSecSetEccKey(&evt->data.key); DmSecSetEccKey(&evt->data.key);
memcpy(self._public_key_x, evt->data.key.pubKey_x, sizeof(self._public_key_x)); memcpy(self._public_key_x, evt->data.key.pubKey_x, sizeof(self._public_key_x));
self._lesc_keys_generated = true; self._lesc_keys_generated = true;
@ -759,6 +823,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
} }
case DM_SEC_COMPARE_IND: { case DM_SEC_COMPARE_IND: {
tr_info("Handling event DM_SEC_COMPARE_IND");
auto *evt = (dmSecCnfIndEvt_t *) msg; auto *evt = (dmSecCnfIndEvt_t *) msg;
handler->on_passkey_display( handler->on_passkey_display(
/* connection */ evt->hdr.param, /* connection */ evt->hdr.param,
@ -769,6 +834,7 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
} }
case DM_SEC_KEYPRESS_IND: { case DM_SEC_KEYPRESS_IND: {
tr_info("Handling event DM_SEC_KEYPRESS_IND");
auto *evt = (dmSecKeypressIndEvt_t *) msg; auto *evt = (dmSecKeypressIndEvt_t *) msg;
handler->on_keypress_notification( handler->on_keypress_notification(
/* connection */ evt->hdr.param, /* connection */ evt->hdr.param,

View File

@ -18,6 +18,10 @@
#if BLE_FEATURE_PRIVACY #if BLE_FEATURE_PRIVACY
#include "PrivateAddressController.h" #include "PrivateAddressController.h"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLSM"
namespace ble { namespace ble {
@ -50,12 +54,14 @@ PrivateAddressController::~PrivateAddressController()
void PrivateAddressController::set_local_irk(const irk_t &local_irk) void PrivateAddressController::set_local_irk(const irk_t &local_irk)
{ {
tr_info("Set local irk: %s", to_string(local_irk));
_local_irk = local_irk; _local_irk = local_irk;
generate_resolvable_address(); generate_resolvable_address();
} }
void PrivateAddressController::set_timeout(ble::resolvable_address_timeout_t rotation_timeout) void PrivateAddressController::set_timeout(ble::resolvable_address_timeout_t rotation_timeout)
{ {
tr_info("Set resolvable address timeout: %d s", rotation_timeout.value());
_rotation_timeout = rotation_timeout; _rotation_timeout = rotation_timeout;
_pal.set_ll_resolvable_private_address_timeout(rotation_timeout); _pal.set_ll_resolvable_private_address_timeout(rotation_timeout);
if (_generation_started) { if (_generation_started) {
@ -85,12 +91,15 @@ void PrivateAddressController::start_private_address_generation()
return; return;
} }
tr_info("Start private address generation");
// non resolvable private address generation has been delayed until now, // non resolvable private address generation has been delayed until now,
// generate it. // generate it.
generate_non_resolvable_address(); generate_non_resolvable_address();
_address_rotation_ticker.attach([this] { _address_rotation_ticker.attach([this] {
_event_queue.post([this]{ _event_queue.post([this]{
tr_info("Private address timeout");
generate_resolvable_address(); generate_resolvable_address();
generate_non_resolvable_address(); generate_non_resolvable_address();
}); });
@ -101,6 +110,7 @@ void PrivateAddressController::start_private_address_generation()
void PrivateAddressController::stop_private_address_generation() void PrivateAddressController::stop_private_address_generation()
{ {
if (_generation_started) { if (_generation_started) {
tr_info("Stop private address generation");
_address_rotation_ticker.detach(); _address_rotation_ticker.detach();
_generation_started = false; _generation_started = false;
} }
@ -110,14 +120,19 @@ void PrivateAddressController::generate_resolvable_address()
{ {
if (_local_irk != irk_t{}) { if (_local_irk != irk_t{}) {
_pal.generate_resolvable_private_address(_local_irk); _pal.generate_resolvable_private_address(_local_irk);
} else {
tr_warning("Failed to generate resolvable address, no local irk");
} }
} }
void PrivateAddressController::on_resolvable_private_address_generated(const address_t &rpa) void PrivateAddressController::on_resolvable_private_address_generated(const address_t &rpa)
{ {
tr_info("Resolvable private address generated: %s", to_string(rpa));
_resolvable_address = rpa; _resolvable_address = rpa;
if (_event_handler) { if (_event_handler) {
_event_handler->on_resolvable_private_addresses_generated(_resolvable_address); _event_handler->on_resolvable_private_addresses_generated(_resolvable_address);
} else {
tr_warning("No app handler to receive RPA generated");
} }
} }
@ -127,6 +142,8 @@ void PrivateAddressController::generate_non_resolvable_address()
_event_queue.post([this] { _event_queue.post([this] {
if (_event_handler) { if (_event_handler) {
_event_handler->on_non_resolvable_private_addresses_generated(_non_resolvable_address); _event_handler->on_non_resolvable_private_addresses_generated(_non_resolvable_address);
} else {
tr_warning("No app handler to receive NRPA generated");
} }
}); });
} }
@ -168,7 +185,10 @@ ble_error_t PrivateAddressController::add_device_to_resolving_list(
const irk_t& peer_irk const irk_t& peer_irk
) )
{ {
tr_info("Add device to resolving list: peer address=%s, type=%s, peer irk=%s",
to_string(peer_identity_address), to_string(peer_address_type), to_string(peer_irk));
if (_local_irk == irk_t{}) { if (_local_irk == irk_t{}) {
tr_error("Invalid local IRK: %s", to_string(_local_irk));
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
@ -198,6 +218,7 @@ ble_error_t PrivateAddressController::add_device_to_resolving_list(
} }
if (!entry_added) { if (!entry_added) {
tr_error("Failed to add address into host resolving list, not enough space");
return BLE_ERROR_NO_MEM; return BLE_ERROR_NO_MEM;
} }
@ -221,6 +242,7 @@ ble_error_t PrivateAddressController::add_device_to_resolving_list(
peer_irk peer_irk
); );
} else { } else {
tr_error("Host based private address resolution enabled but not supported by the controller");
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
@ -231,6 +253,8 @@ ble_error_t PrivateAddressController::remove_device_from_resolving_list(
const address_t &peer_identity_address const address_t &peer_identity_address
) )
{ {
tr_info("Remove device from resolving list: peer address=%s, type=%s",
to_string(peer_identity_address), to_string(peer_address_type));
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
for (auto &entry : _resolving_list) { for (auto &entry : _resolving_list) {
if (entry.populated && if (entry.populated &&
@ -252,6 +276,7 @@ ble_error_t PrivateAddressController::remove_device_from_resolving_list(
if (is_controller_privacy_supported()) { if (is_controller_privacy_supported()) {
return queue_remove_device_from_resolving_list(peer_address_type, peer_identity_address); return queue_remove_device_from_resolving_list(peer_address_type, peer_identity_address);
} else { } else {
tr_error("Host based private address resolution enabled but not supported by the controller");
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
@ -259,6 +284,7 @@ ble_error_t PrivateAddressController::remove_device_from_resolving_list(
ble_error_t PrivateAddressController::clear_resolving_list() ble_error_t PrivateAddressController::clear_resolving_list()
{ {
tr_info("Clear resolving list");
#if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #if BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
// Remove entry from the resolving list // Remove entry from the resolving list
for (auto &entry : _resolving_list) { for (auto &entry : _resolving_list) {
@ -277,6 +303,7 @@ ble_error_t PrivateAddressController::clear_resolving_list()
if (is_controller_privacy_supported()) { if (is_controller_privacy_supported()) {
return queue_clear_resolving_list(); return queue_clear_resolving_list();
} else { } else {
tr_error("Host based private address resolution enabled but not supported by the controller");
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NOT_IMPLEMENTED;
} }
#endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION #endif // BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION
@ -310,12 +337,15 @@ bool PrivateAddressController::resolve_address_in_host_cache(
entry->next = _resolved_list; entry->next = _resolved_list;
_resolved_list = entry; _resolved_list = entry;
} }
tr_debug("Resolved address from cache: rpa=%s, resolved address=%s, type=%s",
to_string(peer_address), to_string(entry->identity->peer_address), to_string(entry->identity->peer_address_type));
return true; return true;
} }
previous = entry; previous = entry;
entry = entry->next; entry = entry->next;
} }
tr_debug("Address not found in cache: %s", to_string(peer_address));
return false; return false;
} }
@ -340,6 +370,7 @@ ble_error_t PrivateAddressController::resolve_address_on_host(
void PrivateAddressController::on_resolving_list_action_complete() void PrivateAddressController::on_resolving_list_action_complete()
{ {
tr_info("Resolving list action completed");
process_privacy_control_blocks(true); process_privacy_control_blocks(true);
} }
@ -412,6 +443,7 @@ ble_error_t PrivateAddressController::queue_add_device_to_resolving_list(
peer_irk peer_irk
); );
if (cb == nullptr) { if (cb == nullptr) {
tr_error("Failed to create control block to add device to resolving list");
// Cannot go further // Cannot go further
return BLE_ERROR_NO_MEM; return BLE_ERROR_NO_MEM;
} }
@ -458,6 +490,7 @@ ble_error_t PrivateAddressController::queue_remove_device_from_resolving_list(
peer_identity_address peer_identity_address
); );
if (cb == nullptr) { if (cb == nullptr) {
tr_error("Failed to create control block to remove device from resolving list");
// Cannot go further // Cannot go further
return BLE_ERROR_NO_MEM; return BLE_ERROR_NO_MEM;
} }
@ -488,6 +521,7 @@ ble_error_t PrivateAddressController::queue_clear_resolving_list()
auto *cb = new(std::nothrow) PrivacyClearResListControlBlock(); auto *cb = new(std::nothrow) PrivacyClearResListControlBlock();
if (cb == nullptr) { if (cb == nullptr) {
tr_error("Failed to create control block to clear resolving list");
// Cannot go further // Cannot go further
return BLE_ERROR_NO_MEM; return BLE_ERROR_NO_MEM;
} }
@ -549,6 +583,7 @@ private:
} }
} while (!self._resolving_list[resolving_list_index].populated); } while (!self._resolving_list[resolving_list_index].populated);
tr_debug("Start resolution with next identity entry: %s", to_string(peer_address));
start_resolution(self); start_resolution(self);
return false; return false;
} }
@ -567,6 +602,13 @@ private:
resolving_list_entry_t* identity resolving_list_entry_t* identity
) )
{ {
if (!resolved) {
tr_debug("Address resolution complete: rpa=%s, resolved=%s", to_string(peer_resolvable_address), to_string(resolved));
} else {
tr_debug("Address resolution complete: rpa=%s, resolved=%s, identity address=%s, type=%s",
to_string(peer_resolvable_address), to_string(resolved), to_string(identity->peer_address), to_string(identity->peer_address_type));
}
// First we had the device to the resolution list // First we had the device to the resolution list
self.add_resolution_entry_to_cache(peer_resolvable_address, identity); self.add_resolution_entry_to_cache(peer_resolvable_address, identity);
@ -591,6 +633,7 @@ ble_error_t PrivateAddressController::queue_resolve_address_on_host(const addres
auto *cb = new(std::nothrow) PrivacyResolveAddressOnHost(peer_address); auto *cb = new(std::nothrow) PrivacyResolveAddressOnHost(peer_address);
if (cb == nullptr) { if (cb == nullptr) {
// Cannot go further // Cannot go further
tr_error("Not enough memory to queue host address resolution: %s", to_string(peer_address));
return BLE_ERROR_NO_MEM; return BLE_ERROR_NO_MEM;
} }
@ -605,6 +648,7 @@ void PrivateAddressController::restart_resolution_process_on_host()
{ {
// if processing is active, restart the one running. // if processing is active, restart the one running.
if (_processing_privacy_control_block && _pending_privacy_control_blocks) { if (_processing_privacy_control_block && _pending_privacy_control_blocks) {
tr_info("Restart host address resolution process");
static_cast<PrivacyResolveAddressOnHost*>(_pending_privacy_control_blocks)->invalidate(); static_cast<PrivacyResolveAddressOnHost*>(_pending_privacy_control_blocks)->invalidate();
} }
} }
@ -614,6 +658,7 @@ void PrivateAddressController::on_private_address_resolved(bool success)
if (_pending_privacy_control_blocks == nullptr || if (_pending_privacy_control_blocks == nullptr ||
_processing_privacy_control_block == false _processing_privacy_control_block == false
) { ) {
tr_warning("Received unexpected address resolution event");
return; return;
} }
@ -625,6 +670,7 @@ void PrivateAddressController::on_private_address_resolved(bool success)
void PrivateAddressController::clear_privacy_control_blocks() void PrivateAddressController::clear_privacy_control_blocks()
{ {
tr_info("Clear privacy control blocks");
while (_pending_privacy_control_blocks != nullptr) { while (_pending_privacy_control_blocks != nullptr) {
PrivacyControlBlock *next = _pending_privacy_control_blocks->next(); PrivacyControlBlock *next = _pending_privacy_control_blocks->next();
delete _pending_privacy_control_blocks; delete _pending_privacy_control_blocks;
@ -634,6 +680,7 @@ void PrivateAddressController::clear_privacy_control_blocks()
void PrivateAddressController::queue_privacy_control_block(PrivacyControlBlock *block) void PrivateAddressController::queue_privacy_control_block(PrivacyControlBlock *block)
{ {
tr_info("Queue privacy request");
if (_pending_privacy_control_blocks == nullptr) { if (_pending_privacy_control_blocks == nullptr) {
_pending_privacy_control_blocks = block; _pending_privacy_control_blocks = block;
} else { } else {