mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #13037 from paul-szczepanek-arm/ble-sm-fix
BLE: Fix privacy and signing handling in Security Managerpull/13095/head
commit
2466411b83
|
@ -285,6 +285,22 @@ public:
|
||||||
(void)result;
|
(void)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate that a peer address has been saved by the security manager or if we are
|
||||||
|
* bonded to the peer the identity has been retrieved from the database on connection.
|
||||||
|
*
|
||||||
|
* @param[in] connectionHandle Connection handle.
|
||||||
|
* @param[in] peer_address Peer address that has been saved by the security database, NULL it not found.
|
||||||
|
* @param[in] address_is_public Address type, true if public. Invalid if peer_address NULL.
|
||||||
|
*/
|
||||||
|
virtual void peerIdentity(ble::connection_handle_t connectionHandle,
|
||||||
|
const address_t *peer_address,
|
||||||
|
bool address_is_public) {
|
||||||
|
(void)connectionHandle;
|
||||||
|
(void)peer_address;
|
||||||
|
(void)address_is_public;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Security
|
// Security
|
||||||
//
|
//
|
||||||
|
@ -561,6 +577,14 @@ public:
|
||||||
*/
|
*/
|
||||||
ble_error_t setPairingRequestAuthorisation(bool required = true);
|
ble_error_t setPairingRequestAuthorisation(bool required = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve identity address for the peer on the given connection.
|
||||||
|
*
|
||||||
|
* @param[in] connectionHandle Handle to identify the connection.
|
||||||
|
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
|
||||||
|
*/
|
||||||
|
ble_error_t getPeerIdentity(ble::connection_handle_t connectionHandle);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Feature support
|
// Feature support
|
||||||
//
|
//
|
||||||
|
@ -899,6 +923,10 @@ protected:
|
||||||
ble::connection_handle_t connectionHandle
|
ble::connection_handle_t connectionHandle
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ble_error_t getPeerIdentity_(
|
||||||
|
ble::connection_handle_t connectionHandle
|
||||||
|
);
|
||||||
|
|
||||||
ble_error_t setPairingRequestAuthorisation_(
|
ble_error_t setPairingRequestAuthorisation_(
|
||||||
bool required
|
bool required
|
||||||
);
|
);
|
||||||
|
|
|
@ -34,8 +34,6 @@ private:
|
||||||
size_t file_offset;
|
size_t file_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const size_t MAX_ENTRIES = 5;
|
|
||||||
|
|
||||||
static entry_t* as_entry(entry_handle_t db_handle) {
|
static entry_t* as_entry(entry_handle_t db_handle) {
|
||||||
return reinterpret_cast<entry_t*>(db_handle);
|
return reinterpret_cast<entry_t*>(db_handle);
|
||||||
}
|
}
|
||||||
|
@ -118,6 +116,21 @@ public:
|
||||||
sign_count_t sign_counter
|
sign_count_t sign_counter
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* local csrk and identity */
|
||||||
|
|
||||||
|
virtual void set_local_csrk(
|
||||||
|
const csrk_t &csrk
|
||||||
|
);
|
||||||
|
|
||||||
|
virtual void set_local_identity(
|
||||||
|
const irk_t &irk,
|
||||||
|
const address_t &identity_address,
|
||||||
|
bool public_address
|
||||||
|
);
|
||||||
|
|
||||||
|
/* I am not overriding set_local_sign_counter to avoid constant filesystem writes,
|
||||||
|
* instead this is synced by sync (which is called on disconnection) */
|
||||||
|
|
||||||
/* saving and loading from nvm */
|
/* saving and loading from nvm */
|
||||||
|
|
||||||
virtual void restore();
|
virtual void restore();
|
||||||
|
@ -146,7 +159,7 @@ private:
|
||||||
static FILE* erase_db_file(FILE* db_file);
|
static FILE* erase_db_file(FILE* db_file);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
entry_t _entries[MAX_ENTRIES];
|
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
|
||||||
FILE *_db_file;
|
FILE *_db_file;
|
||||||
uint8_t _buffer[sizeof(SecurityEntryKeys_t)];
|
uint8_t _buffer[sizeof(SecurityEntryKeys_t)];
|
||||||
};
|
};
|
||||||
|
|
|
@ -124,6 +124,10 @@ public:
|
||||||
bool required = true
|
bool required = true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ble_error_t getPeerIdentity_(
|
||||||
|
connection_handle_t connection
|
||||||
|
);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Feature support
|
// Feature support
|
||||||
//
|
//
|
||||||
|
@ -321,6 +325,13 @@ private:
|
||||||
*/
|
*/
|
||||||
ble_error_t init_signing();
|
ble_error_t init_signing();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the IRK if needed.
|
||||||
|
*
|
||||||
|
* @return BLE_ERROR_NONE or appropriate error code indicating the failure reason.
|
||||||
|
*/
|
||||||
|
ble_error_t init_identity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills the buffer with the specified number of bytes of random data
|
* Fills the buffer with the specified number of bytes of random data
|
||||||
* produced by the link controller
|
* produced by the link controller
|
||||||
|
|
|
@ -34,8 +34,6 @@ private:
|
||||||
SecurityEntrySigning_t peer_signing;
|
SecurityEntrySigning_t peer_signing;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const size_t MAX_ENTRIES = 5;
|
|
||||||
|
|
||||||
static entry_t* as_entry(entry_handle_t db_handle)
|
static entry_t* as_entry(entry_handle_t db_handle)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<entry_t*>(db_handle);
|
return reinterpret_cast<entry_t*>(db_handle);
|
||||||
|
@ -150,11 +148,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual uint8_t get_entry_count() {
|
virtual uint8_t get_entry_count() {
|
||||||
return MAX_ENTRIES;
|
return BLE_SECURITY_DATABASE_MAX_ENTRIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SecurityDistributionFlags_t* get_entry_handle_by_index(uint8_t index) {
|
virtual SecurityDistributionFlags_t* get_entry_handle_by_index(uint8_t index) {
|
||||||
if (index < MAX_ENTRIES) {
|
if (index < BLE_SECURITY_DATABASE_MAX_ENTRIES) {
|
||||||
return &_entries[index].flags;
|
return &_entries[index].flags;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -187,7 +185,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
entry_t _entries[MAX_ENTRIES];
|
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace pal */
|
} /* namespace pal */
|
||||||
|
|
|
@ -425,6 +425,31 @@ public:
|
||||||
_local_sign_counter = sign_counter;
|
_local_sign_counter = sign_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* local identity */
|
||||||
|
/**
|
||||||
|
* Update the local identity.
|
||||||
|
*
|
||||||
|
* @param[in] csrk new CSRK value
|
||||||
|
*/
|
||||||
|
virtual void set_local_identity(
|
||||||
|
const irk_t &irk,
|
||||||
|
const address_t &identity_address,
|
||||||
|
bool public_address
|
||||||
|
) {
|
||||||
|
_local_identity.irk = irk;
|
||||||
|
_local_identity.identity_address = identity_address;
|
||||||
|
_local_identity.identity_address_is_public = public_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return local irk.
|
||||||
|
*
|
||||||
|
* @return irk
|
||||||
|
*/
|
||||||
|
virtual irk_t get_local_irk() {
|
||||||
|
return _local_identity.irk;
|
||||||
|
}
|
||||||
|
|
||||||
/* list management */
|
/* list management */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -592,6 +617,21 @@ public:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the connection address
|
||||||
|
whitelist->addresses[whitelist->size].address = flags->peer_address.data();
|
||||||
|
|
||||||
|
if (flags->peer_address_is_public) {
|
||||||
|
whitelist->addresses[whitelist->size].type = peer_address_type_t::PUBLIC;
|
||||||
|
} else {
|
||||||
|
whitelist->addresses[whitelist->size].type = peer_address_type_t::RANDOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
whitelist->size++;
|
||||||
|
if (whitelist->size == whitelist->capacity) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the identity address
|
||||||
SecurityEntryIdentity_t* identity = read_in_entry_peer_identity(db_handle);
|
SecurityEntryIdentity_t* identity = read_in_entry_peer_identity(db_handle);
|
||||||
if (!identity) {
|
if (!identity) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -964,7 +964,23 @@ public:
|
||||||
ble_error_t set_private_address_timeout(
|
ble_error_t set_private_address_timeout(
|
||||||
uint16_t timeout_in_seconds
|
uint16_t timeout_in_seconds
|
||||||
) {
|
) {
|
||||||
return impl()->set_private_address_timeout(timeout_in_seconds);
|
return impl()->set_private_address_timeout_(timeout_in_seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the identity address used by the controller
|
||||||
|
*
|
||||||
|
* @param address Will contain the address retrieved.
|
||||||
|
* @param public_address will be true if the address is public and false
|
||||||
|
* otherwise.
|
||||||
|
* @return BLE_ERROR_NONE On success, else an error code indicating the reason
|
||||||
|
* of the failure
|
||||||
|
*/
|
||||||
|
ble_error_t get_identity_address(
|
||||||
|
address_t& address,
|
||||||
|
bool& public_address
|
||||||
|
) {
|
||||||
|
return impl()->get_identity_address_(address, public_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -71,6 +71,11 @@
|
||||||
"help": "Include periodic advertising support, depends on the extended advertising feature.",
|
"help": "Include periodic advertising support, depends on the extended advertising feature.",
|
||||||
"value": true,
|
"value": true,
|
||||||
"macro_name": "BLE_FEATURE_PERIODIC_ADVERTISING"
|
"macro_name": "BLE_FEATURE_PERIODIC_ADVERTISING"
|
||||||
|
},
|
||||||
|
"ble-security-database-max-entries": {
|
||||||
|
"help": "How many entries can be stored in the db, depends on security manager.",
|
||||||
|
"value": 5,
|
||||||
|
"macro_name": "BLE_SECURITY_DATABASE_MAX_ENTRIES"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -54,7 +54,7 @@ const uint16_t DB_VERSION = 1;
|
||||||
)
|
)
|
||||||
|
|
||||||
#define DB_SIZE_STORES \
|
#define DB_SIZE_STORES \
|
||||||
(FileSecurityDb::MAX_ENTRIES * DB_SIZE_STORE)
|
(BLE_SECURITY_DATABASE_MAX_ENTRIES * DB_SIZE_STORE)
|
||||||
|
|
||||||
#define DB_OFFSET_VERSION (0)
|
#define DB_OFFSET_VERSION (0)
|
||||||
#define DB_OFFSET_RESTORE (DB_OFFSET_VERSION + sizeof(DB_VERSION))
|
#define DB_OFFSET_RESTORE (DB_OFFSET_VERSION + sizeof(DB_VERSION))
|
||||||
|
@ -265,6 +265,22 @@ void FileSecurityDb::set_entry_peer_sign_counter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileSecurityDb::set_local_csrk(
|
||||||
|
const csrk_t &csrk
|
||||||
|
) {
|
||||||
|
this->SecurityDb::set_local_csrk(csrk);
|
||||||
|
db_write(&_local_csrk, DB_OFFSET_LOCAL_CSRK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSecurityDb::set_local_identity(
|
||||||
|
const irk_t &irk,
|
||||||
|
const address_t &identity_address,
|
||||||
|
bool public_address
|
||||||
|
) {
|
||||||
|
this->SecurityDb::set_local_identity(irk, identity_address, public_address);
|
||||||
|
db_write(&_local_identity, DB_OFFSET_LOCAL_IDENTITY);
|
||||||
|
}
|
||||||
|
|
||||||
/* saving and loading from nvm */
|
/* saving and loading from nvm */
|
||||||
|
|
||||||
void FileSecurityDb::restore() {
|
void FileSecurityDb::restore() {
|
||||||
|
@ -299,6 +315,7 @@ void FileSecurityDb::sync(entry_handle_t db_handle) {
|
||||||
|
|
||||||
db_write(&entry->peer_sign_counter, entry->file_offset + DB_STORE_OFFSET_PEER_SIGNING_COUNT);
|
db_write(&entry->peer_sign_counter, entry->file_offset + DB_STORE_OFFSET_PEER_SIGNING_COUNT);
|
||||||
db_write(&entry->flags, entry->file_offset + DB_STORE_OFFSET_FLAGS);
|
db_write(&entry->flags, entry->file_offset + DB_STORE_OFFSET_FLAGS);
|
||||||
|
db_write(&_local_sign_counter, DB_OFFSET_LOCAL_SIGN_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSecurityDb::set_restore(bool reload) {
|
void FileSecurityDb::set_restore(bool reload) {
|
||||||
|
@ -308,11 +325,11 @@ void FileSecurityDb::set_restore(bool reload) {
|
||||||
/* helper functions */
|
/* helper functions */
|
||||||
|
|
||||||
uint8_t FileSecurityDb::get_entry_count() {
|
uint8_t FileSecurityDb::get_entry_count() {
|
||||||
return MAX_ENTRIES;
|
return BLE_SECURITY_DATABASE_MAX_ENTRIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityDistributionFlags_t* FileSecurityDb::get_entry_handle_by_index(uint8_t index) {
|
SecurityDistributionFlags_t* FileSecurityDb::get_entry_handle_by_index(uint8_t index) {
|
||||||
if (index < MAX_ENTRIES) {
|
if (index < BLE_SECURITY_DATABASE_MAX_ENTRIES) {
|
||||||
return &_entries[index].flags;
|
return &_entries[index].flags;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -102,13 +102,19 @@ ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::init_(
|
||||||
result = init_resolving_list();
|
result = init_resolving_list();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BLE_FEATURE_PRIVACY
|
||||||
|
// set the local identity address and irk
|
||||||
|
if (result != BLE_ERROR_NONE) {
|
||||||
|
result = init_identity();
|
||||||
|
}
|
||||||
|
#endif // BLE_FEATURE_PRIVACY
|
||||||
|
|
||||||
if (result != BLE_ERROR_NONE) {
|
if (result != BLE_ERROR_NONE) {
|
||||||
delete _db;
|
delete _db;
|
||||||
_db = NULL;
|
_db = NULL;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return BLE_ERROR_NONE;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
|
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
|
||||||
|
@ -161,7 +167,21 @@ template<template<class> class TPalSecurityManager, template<class> class Signin
|
||||||
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::purgeAllBondingState_(void) {
|
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::purgeAllBondingState_(void) {
|
||||||
if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||||
_db->clear_entries();
|
_db->clear_entries();
|
||||||
return BLE_ERROR_NONE;
|
|
||||||
|
ble_error_t ret = BLE_ERROR_NONE;
|
||||||
|
|
||||||
|
#if BLE_FEATURE_SIGNING
|
||||||
|
// generate new csrk and irk
|
||||||
|
ret = init_signing();
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif // BLE_FEATURE_SIGNING
|
||||||
|
#if BLE_FEATURE_PRIVACY
|
||||||
|
ret = init_identity();
|
||||||
|
#endif // BLE_FEATURE_PRIVACY
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
|
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
|
||||||
|
@ -309,6 +329,33 @@ ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::setPair
|
||||||
return BLE_ERROR_NONE;
|
return BLE_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
|
||||||
|
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::getPeerIdentity_(connection_handle_t connection) {
|
||||||
|
if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||||
|
if (eventHandler) {
|
||||||
|
ControlBlock_t *cb = get_control_block(connection);
|
||||||
|
if (!cb) {
|
||||||
|
return BLE_ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
_db->get_entry_identity(
|
||||||
|
[connection,this](SecurityDb::entry_handle_t handle, const SecurityEntryIdentity_t* identity) {
|
||||||
|
if (eventHandler) {
|
||||||
|
eventHandler->peerIdentity(
|
||||||
|
connection,
|
||||||
|
identity ? &identity->identity_address : nullptr,
|
||||||
|
identity ? identity->identity_address_is_public : false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cb->db_entry
|
||||||
|
);
|
||||||
|
return BLE_ERROR_NONE;
|
||||||
|
} else {
|
||||||
|
return BLE_ERROR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Feature support
|
// Feature support
|
||||||
//
|
//
|
||||||
|
@ -901,6 +948,33 @@ ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::init_si
|
||||||
return _pal.set_csrk(*pcsrk, local_sign_counter);
|
return _pal.set_csrk(*pcsrk, local_sign_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
|
||||||
|
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::init_identity() {
|
||||||
|
if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE;
|
||||||
|
const irk_t *pirk = nullptr;
|
||||||
|
|
||||||
|
irk_t irk = _db->get_local_irk();
|
||||||
|
if (irk != irk_t()) {
|
||||||
|
pirk = &irk;
|
||||||
|
} else {
|
||||||
|
ble_error_t ret = get_random_data(irk.data(), irk.size());
|
||||||
|
if (ret != BLE_ERROR_NONE) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pirk = &irk;
|
||||||
|
address_t identity_address;
|
||||||
|
bool public_address;
|
||||||
|
ret = _pal.get_identity_address(identity_address, public_address);
|
||||||
|
if (ret != BLE_ERROR_NONE) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
_db->set_local_identity(irk, identity_address, public_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _pal.set_irk(*pirk);
|
||||||
|
}
|
||||||
|
|
||||||
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
|
template<template<class> class TPalSecurityManager, template<class> class SigningMonitor>
|
||||||
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::get_random_data(uint8_t *buffer, size_t size) {
|
ble_error_t GenericSecurityManager<TPalSecurityManager, SigningMonitor>::get_random_data(uint8_t *buffer, size_t size) {
|
||||||
byte_array_t<8> random_data;
|
byte_array_t<8> random_data;
|
||||||
|
|
|
@ -212,6 +212,11 @@ public:
|
||||||
*/
|
*/
|
||||||
ble_error_t set_private_address_timeout_(uint16_t timeout_in_seconds);
|
ble_error_t set_private_address_timeout_(uint16_t timeout_in_seconds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ::ble::pal::SecurityManager::get_identity_address
|
||||||
|
*/
|
||||||
|
ble_error_t get_identity_address_(address_t& address, bool& public_address);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Keys
|
// Keys
|
||||||
//
|
//
|
||||||
|
|
|
@ -279,6 +279,20 @@ ble_error_t CordioSecurityManager<EventHandler>::set_private_address_timeout_(
|
||||||
return BLE_ERROR_NONE;
|
return BLE_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ::ble::pal::SecurityManager::get_identity_address
|
||||||
|
*/
|
||||||
|
template <class EventHandler>
|
||||||
|
ble_error_t CordioSecurityManager<EventHandler>::get_identity_address_(
|
||||||
|
address_t& address,
|
||||||
|
bool& public_address
|
||||||
|
) {
|
||||||
|
// On cordio, the public address is hardcoded as the identity address.
|
||||||
|
address = address_t(HciGetBdAddr());
|
||||||
|
public_address = true;
|
||||||
|
return BLE_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Keys
|
// Keys
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue