mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-16 01:48:42 -05:00
176 lines
6.0 KiB
C++
176 lines
6.0 KiB
C++
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include <algorithm>
|
|
#include "BtKeysStorage.hpp"
|
|
#include <log/log.hpp>
|
|
|
|
json11::Json bluetooth::KeyStorage::keysJson = json11::Json();
|
|
btstack_link_key_db_t bluetooth::KeyStorage::keyStorage;
|
|
json11::Json::array bluetooth::KeyStorage::keys;
|
|
std::shared_ptr<bluetooth::SettingsHolder> bluetooth::KeyStorage::settings = nullptr;
|
|
|
|
namespace bluetooth
|
|
{
|
|
namespace strings
|
|
{
|
|
constexpr auto keys = "keys";
|
|
constexpr auto link_key = "link_key";
|
|
constexpr auto bd_addr = "bd_addr";
|
|
constexpr auto type = "type";
|
|
} // namespace strings
|
|
|
|
auto KeyStorage::getKeyStorage() -> btstack_link_key_db_t *
|
|
{
|
|
keyStorage.open = openStorage;
|
|
keyStorage.set_local_bd_addr = set_local_bd_addr;
|
|
keyStorage.close = closeStorage;
|
|
keyStorage.get_link_key = getLinkKey;
|
|
keyStorage.put_link_key = putLinkKey;
|
|
keyStorage.delete_link_key = deleteLinkKey;
|
|
keyStorage.iterator_init = iterator_init;
|
|
keyStorage.iterator_get_next = iterator_get_next;
|
|
keyStorage.iterator_done = iterator_done;
|
|
|
|
return &keyStorage;
|
|
}
|
|
|
|
void KeyStorage::openStorage()
|
|
{
|
|
LOG_INFO("Opening storage from API");
|
|
std::string keysEntry;
|
|
if (settings) {
|
|
keysEntry = std::visit(bluetooth::StringVisitor(), settings->getValue(bluetooth::Settings::BtKeys));
|
|
}
|
|
else {
|
|
LOG_ERROR("Failed opening settings for BT!");
|
|
return;
|
|
}
|
|
if (keysEntry.empty()) {
|
|
LOG_WARN("Opening empty key entry!");
|
|
return;
|
|
}
|
|
|
|
std::string err;
|
|
keysJson = json11::Json::parse(keysEntry.c_str(), err);
|
|
if (!err.empty()) {
|
|
LOG_ERROR("Error while parsing json: %s", err.c_str());
|
|
return;
|
|
}
|
|
|
|
keys = std::move(keysJson[strings::keys].array_items());
|
|
}
|
|
|
|
void KeyStorage::closeStorage()
|
|
{
|
|
LOG_INFO("Closing storage from API");
|
|
writeSettings();
|
|
}
|
|
|
|
auto KeyStorage::getLinkKey(uint8_t *bd_addr, link_key_t link_key, link_key_type_t *type) -> int
|
|
{
|
|
if (type != nullptr && bd_addr != nullptr) {
|
|
LOG_INFO("Getting key from API");
|
|
|
|
json11::Json finalJson = json11::Json::object{{strings::keys, keys}};
|
|
auto keysEntryDump = finalJson.dump();
|
|
LOG_DEBUG("Current keys state: %s", keysEntryDump.c_str());
|
|
|
|
if (keys.empty()) {
|
|
LOG_ERROR("Keys empty!");
|
|
return 0;
|
|
}
|
|
|
|
auto ret = processOnFoundKey(bd_addr, [&type, &link_key](const json11::Json &key, bd_addr_t) {
|
|
auto foundLinkKey = key[strings::link_key].string_value().c_str();
|
|
memcpy(link_key, reinterpret_cast<const uint8_t *>(foundLinkKey), sizeof(link_key_t));
|
|
LOG_DEBUG("Getting key: %s", foundLinkKey);
|
|
*type = static_cast<link_key_type_t>(key[strings::type].int_value());
|
|
|
|
return 1;
|
|
});
|
|
if (ret == 0) {
|
|
LOG_ERROR("Can't find key for this address!");
|
|
}
|
|
return ret;
|
|
}
|
|
return 0;
|
|
}
|
|
void KeyStorage::putLinkKey(uint8_t *bd_addr, uint8_t *link_key, link_key_type_t type)
|
|
{
|
|
|
|
processOnFoundKey(bd_addr, [](const json11::Json &, bd_addr_t bd_addr) {
|
|
LOG_ERROR("Key already found in the key storage - deleting!");
|
|
deleteLinkKey(bd_addr);
|
|
return 1;
|
|
});
|
|
|
|
auto keyEntry = json11::Json::object{{strings::bd_addr, bd_addr_to_str(bd_addr)},
|
|
{strings::link_key, std::string(reinterpret_cast<char *>(link_key))},
|
|
{strings::type, type}};
|
|
keys.emplace_back(keyEntry);
|
|
|
|
if (settings->onLinkKeyAdded) {
|
|
settings->onLinkKeyAdded(bd_addr_to_str(bd_addr));
|
|
}
|
|
writeSettings();
|
|
LOG_INFO("Keys in file: %d", (int)keys.size());
|
|
}
|
|
void KeyStorage::deleteLinkKey(uint8_t *bd_addr)
|
|
{
|
|
auto keysSize = keys.size();
|
|
LOG_INFO("Deleting key from API");
|
|
auto end = std::remove_if(keys.begin(), keys.end(), [&](auto &key) {
|
|
bd_addr_t addr;
|
|
sscanf_bd_addr(key[strings::bd_addr].string_value().c_str(), addr);
|
|
return bd_addr_cmp(addr, bd_addr) == 0;
|
|
});
|
|
|
|
keys.erase(end, keys.end());
|
|
if (keysSize != keys.size()) {
|
|
LOG_INFO("Key successfully deleted");
|
|
}
|
|
writeSettings();
|
|
}
|
|
//
|
|
auto KeyStorage::iterator_init(btstack_link_key_iterator_t *it) -> int
|
|
{
|
|
return 0;
|
|
}
|
|
auto KeyStorage::iterator_get_next(btstack_link_key_iterator_t *it,
|
|
uint8_t *bd_addr,
|
|
uint8_t *link_key,
|
|
link_key_type_t *type) -> int
|
|
{
|
|
return 0;
|
|
}
|
|
void KeyStorage::iterator_done(btstack_link_key_iterator_t *it)
|
|
{}
|
|
void KeyStorage::set_local_bd_addr(bd_addr_t bd_addr)
|
|
{}
|
|
void KeyStorage::writeSettings()
|
|
{
|
|
json11::Json finalJson = json11::Json::object{{strings::keys, keys}};
|
|
auto keysEntry = finalJson.dump();
|
|
if (settings) {
|
|
settings->setValue(bluetooth::Settings::BtKeys, keysEntry);
|
|
}
|
|
else {
|
|
LOG_ERROR("Failed to open settings to write!");
|
|
return;
|
|
}
|
|
}
|
|
auto KeyStorage::processOnFoundKey(bd_addr_t bd_addr, const std::function<int(json11::Json, bd_addr_t)> &fun) -> int
|
|
{
|
|
for (const auto &key : keys) {
|
|
bd_addr_t addr;
|
|
sscanf_bd_addr(key[strings::bd_addr].string_value().c_str(), addr);
|
|
|
|
if (bd_addr_cmp(addr, bd_addr) == 0 && fun) {
|
|
return fun(key, bd_addr);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
} // namespace bluetooth
|