pull common logic into secure db

pull/6932/head
paul-szczepanek-arm 2018-05-11 10:19:48 +01:00
parent 473482d204
commit afa4bdcf1a
2 changed files with 97 additions and 76 deletions

View File

@ -28,7 +28,8 @@ private:
enum state_t {
ENTRY_FREE,
ENTRY_RESERVED,
ENTRY_WRITTEN
ENTRY_WRITTEN,
ENTRY_DISCONNECTED
};
struct entry_t {
@ -297,84 +298,18 @@ public:
/* list management */
virtual entry_handle_t open_entry(
BLEProtocol::AddressType_t peer_address_type,
const address_t &peer_address
) {
const bool peer_address_public =
(peer_address_type == BLEProtocol::AddressType::PUBLIC) ||
(peer_address_type == BLEProtocol::AddressType::PUBLIC_IDENTITY);
for (size_t i = 0; i < MAX_ENTRIES; i++) {
entry_t& e = _entries[i];
if (e.state == ENTRY_FREE) {
continue;
} else {
if (peer_address_type == BLEProtocol::AddressType::PUBLIC_IDENTITY &&
e.flags.irk_stored == false
) {
continue;
}
// lookup for the identity address then the connection address.
if (e.flags.irk_stored &&
e.peer_identity.identity_address == peer_address &&
e.peer_identity.identity_address_is_public == peer_address_public
) {
return &e;
// lookup for connection address used during bonding
} else if (e.flags.peer_address == peer_address &&
e.flags.peer_address_is_public == peer_address_public
) {
return &e;
}
}
}
// determine if the address in input is private or not.
bool is_private_address = false;
if (peer_address_type == BLEProtocol::AddressType::RANDOM) {
::Gap::RandomAddressType_t random_type(::Gap::RandomAddressType_t::STATIC);
ble_error_t err = ::Gap::getRandomAddressType(peer_address.data(), &random_type);
if (err) {
return NULL;
}
if (random_type != ::Gap::RandomAddressType_t::STATIC) {
is_private_address = true;
}
}
/* if we din't find one grab the first disconnected slot*/
for (size_t i = 0; i < MAX_ENTRIES; i++) {
if (_entries[i].state == ENTRY_FREE) {
_entries[i] = entry_t();
// do not store private addresses in the flags; just store public
// or random static address so it can be reused latter.
if (is_private_address == false) {
_entries[i].flags.peer_address = peer_address;
_entries[i].flags.peer_address_is_public = peer_address_public;
} else {
_entries[i].flags.peer_address = address_t();
}
_entries[i].state = ENTRY_RESERVED;
return &_entries[i];
}
}
return NULL;
}
virtual void close_entry(entry_handle_t entry_handle)
{
virtual void close_entry(entry_handle_t entry_handle) {
entry_t *entry = as_entry(entry_handle);
if (entry && entry->state == ENTRY_RESERVED) {
entry->state = ENTRY_FREE;
if (entry) {
if (entry->state == ENTRY_RESERVED) {
entry->state = ENTRY_FREE;
} else {
entry->state = ENTRY_DISCONNECTED;
}
}
}
virtual void remove_entry(const address_t peer_identity_address)
{
virtual void remove_entry(const address_t peer_identity_address) {
for (size_t i = 0; i < MAX_ENTRIES; i++) {
if (_entries[i].state == ENTRY_FREE) {
continue;
@ -433,6 +368,41 @@ public:
virtual void set_restore(bool reload) { }
private:
virtual uint8_t get_stored_entry_number() {
return MAX_ENTRIES;
}
virtual SecurityDistributionFlags_t* get_stored_entry_flags(uint8_t index) {
return &_entries[index % MAX_ENTRIES].flags;
}
virtual SecurityEntryIdentity_t* get_stored_entry_identity(uint8_t index) {
return &_entries[index % MAX_ENTRIES].peer_identity;
}
virtual SecurityDistributionFlags_t* get_free_entry_flags() {
/* get a free one if available */
for (size_t i = 0; i < MAX_ENTRIES; i++) {
if (_entries[i].state == ENTRY_FREE) {
_entries[i] = entry_t();
_entries[i].state = ENTRY_RESERVED;
return &_entries[i].flags;
}
}
/* get any disconnected one */
for (size_t i = 0; i < MAX_ENTRIES; i++) {
if (_entries[i].state == ENTRY_DISCONNECTED) {
_entries[i] = entry_t();
_entries[i].state = ENTRY_RESERVED;
return &_entries[i].flags;
}
}
return NULL;
}
private:
entry_t _entries[MAX_ENTRIES];
SecurityEntryIdentity_t _local_identity;

View File

@ -363,7 +363,52 @@ public:
virtual entry_handle_t open_entry(
BLEProtocol::AddressType_t peer_address_type,
const address_t &peer_address
) = 0;
) {
const bool peer_address_public =
(peer_address_type == BLEProtocol::AddressType::PUBLIC) ||
(peer_address_type == BLEProtocol::AddressType::PUBLIC_IDENTITY);
for (size_t i = 0; i < get_stored_entry_number(); i++) {
SecurityDistributionFlags_t* flags = get_stored_entry_flags(i);
if (flags) {
if (peer_address_type == BLEProtocol::AddressType::PUBLIC_IDENTITY &&
flags->irk_stored == false) {
continue;
}
/* lookup for connection address used during bonding */
if (flags->peer_address == peer_address &&
flags->peer_address_is_public == peer_address_public) {
return flags;
}
/* look for the identity address if stored */
if (flags->irk_stored) {
SecurityEntryIdentity_t* identity = get_stored_entry_identity(i);
if (identity &&
identity->identity_address == peer_address &&
identity->identity_address_is_public == peer_address_public) {
return flags;
}
}
}
}
SecurityDistributionFlags_t* flags = get_free_entry_flags();
if (flags) {
/* we need some address to store, so we store even random ones
* this address will be used as an id, possibly replaced later
* by identity address */
flags->peer_address = peer_address;
flags->peer_address_is_public = peer_address_public;
return flags;
}
return NULL;
}
/**
* Close a connection entry.
@ -454,6 +499,12 @@ public:
* @param[in] reload if true values will be preserved across resets.
*/
virtual void set_restore(bool reload) = 0;
protected:
virtual uint8_t get_stored_entry_number() = 0;
virtual SecurityDistributionFlags_t* get_stored_entry_flags(uint8_t index) = 0;
virtual SecurityEntryIdentity_t* get_stored_entry_identity(uint8_t index) = 0;
virtual SecurityDistributionFlags_t* get_free_entry_flags() = 0;
};
} /* namespace pal */