~aleteoryx/muditaos

5f8af17f96c8b3d97f649971e2ebf6563cab80b9 — SP2FET 5 years ago 2bbfab8
[EGD-3641] working key storage in json file
A link_key_db => link_key_db +0 -0
A module-bluetooth/Bluetooth/BtKeysStorage.cpp => module-bluetooth/Bluetooth/BtKeysStorage.cpp +124 -0
@@ 0,0 1,124 @@
#include <algorithm>
#include "BtKeysStorage.hpp"

json11::Json Bt::KeyStorage::fileJson = json11::Json();
btstack_link_key_db_t Bt::KeyStorage::keyStorage;
json11::Json::array Bt::KeyStorage::keys;
std::string Bt::KeyStorage::fileContent;

namespace Bt
{

    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()
    {
        std::string err;

        LOG_INFO("opening storage from API");
        fileContent.clear();
        fileContent = vfs.loadFileAsString(strings::keysFilename);
        if (fileContent.empty()) {
            LOG_WARN("opening empty key file!");
            return;
        }

        fileJson = json11::Json::parse(fileContent.c_str(), err);
        if (!err.empty()) {
            LOG_ERROR("Error while parsing json: %s", err.c_str());
            return;
        }

        keys = std::move(fileJson[strings::keys].array_items());
        LOG_INFO("Imported keys: %d", static_cast<unsigned int>(keys.size()));
    }

    void KeyStorage::closeStorage()
    {
        LOG_INFO("closing storage from API");
        writeToFile();
    }
    //
    auto KeyStorage::getLinkKey(uint8_t *bd_addr, link_key_t link_key, link_key_type_t *type) -> int
    {
        LOG_INFO("getting key for address %s from API", bd_addr_to_str(bd_addr));
        if (keys.size() == 0) {
            return 0;
        }
        for (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) {
                auto foundLinkKey = key[strings::link_key].string_value().c_str();
                memcpy(link_key, foundLinkKey, sizeof(link_key_t));
                *type = static_cast<link_key_type_t>(key[strings::type].int_value());
                return 1;
            }
        }
        return 0;
    }
    void KeyStorage::putLinkKey(uint8_t *bd_addr, uint8_t *link_key, link_key_type_t type)
    {
        LOG_INFO("putting key for address %s from API", bd_addr_to_str(bd_addr));
        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);
        writeToFile();
        LOG_INFO("keys written to the file");
        LOG_INFO("Keys in file: %d", (int)keys.size());
    }
    void KeyStorage::deleteLinkKey(uint8_t *bd_addr)
    {
        auto keysSize = keys.size();
        LOG_INFO("deleting key for address %s from API", bd_addr_to_str(bd_addr));
        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);
        });

        keys.erase(end, keys.end());
        if (keysSize != keys.size()) {
            LOG_INFO("Key successfully deleted");
        }
        writeToFile();
    }
    //
    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::writeToFile()
    {
        json11::Json finalJson = json11::Json::object{{strings::keys, keys}};
        fileContent            = finalJson.dump();
        vfs.replaceWithString(strings::keysFilename, fileContent);
    }

} // namespace Bt
\ No newline at end of file

A module-bluetooth/Bluetooth/BtKeysStorage.hpp => module-bluetooth/Bluetooth/BtKeysStorage.hpp +46 -0
@@ 0,0 1,46 @@
#pragma once

extern "C"
{
#include <btstack_link_key_db_memory.h>
#include <btstack_util.h>
};
#include <json/json11.hpp>
#include <vfs.hpp>

namespace Bt
{

    namespace strings
    {
        inline std::string keysFilename = USER_PATH("btkeys.json");
        inline std::string keys         = "keys";
        inline std::string link_key     = "link_key";
        inline std::string bd_addr      = "bd_addr";
        inline std::string type         = "type";
    } // namespace strings

    class KeyStorage
    {
      public:
        static auto getKeyStorage() -> btstack_link_key_db_t *;
        static void openStorage();
        static void closeStorage();
        static auto getLinkKey(uint8_t *bd_addr, link_key_t link_key, link_key_type_t *type) -> int;
        static void putLinkKey(uint8_t *bd_addr, uint8_t *link_key, link_key_type_t type);
        static void deleteLinkKey(uint8_t *bd_addr);
        static auto iterator_init(btstack_link_key_iterator_t *it) -> int;
        static auto iterator_get_next(btstack_link_key_iterator_t *it,
                                      bd_addr_t bd_addr,
                                      link_key_t link_key,
                                      link_key_type_t *type) -> int;
        static void iterator_done(btstack_link_key_iterator_t *it);
        static void set_local_bd_addr(bd_addr_t bd_addr);
        static void writeToFile();
        static json11::Json fileJson;
        static btstack_link_key_db_t keyStorage;
        static json11::Json::array keys;
        static std::string fileContent;
    };

} // namespace Bt

R module-bluetooth/Bluetooth/interface/profiles/Worker.cpp => module-bluetooth/Bluetooth/BtstackWorker.cpp +19 -21
@@ 1,18 1,13 @@
#include <log/log.hpp>

// #define __BTSTACK_FILE__ ".c"

extern "C"
{
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

#include "btstack_config.h"
#include <cstdint>
#include <cstdlib>
#include <csignal>

#include <btstack_event.h>
// #include <btstack_link_key_db_fs.h>

#include <btstack_memory.h>
#include <btstack_run_loop.h>
#include <bluetooth_company_id.h>


@@ 37,6 32,7 @@ extern "C"

#include <Error.hpp>
#include <functional>
#include "BtKeysStorage.hpp"

// #define TLV_DB_PATH_PREFIX "/tmp/btstack_"
// #define TLV_DB_PATH_POSTFIX ".tlv"


@@ 51,7 47,7 @@ static hci_transport_config_uart_t config = {
    .baudrate_init = 115200,
    .baudrate_main = 0, // main baudrate
    .flowcontrol   = 1, // flow control
    .device_name   = NULL,
    .device_name   = nullptr,
};

static btstack_packet_callback_registration_t hci_event_callback_registration;


@@ 59,12 55,14 @@ static btstack_packet_callback_registration_t hci_event_callback_registration;
static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
    bd_addr_t addr;
    if (packet_type != HCI_EVENT_PACKET)
    if (packet_type != HCI_EVENT_PACKET) {
        return;
    }
    switch (hci_event_packet_get_type(packet)) {
    case BTSTACK_EVENT_STATE:
        if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING)
        if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) {
            break;
        }
        gap_local_bd_addr(addr);
        LOG_INFO("BTstack up and running at %s", bd_addr_to_str(addr));
        // setup TLV


@@ 76,7 74,7 @@ static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
        break;
    case HCI_EVENT_COMMAND_COMPLETE:
        if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)) {
            if (hci_event_command_complete_get_return_parameters(packet)[0])
            if (hci_event_command_complete_get_return_parameters(packet)[0] != 0u)
                break;
            // terminate, name 248 chars
            packet[6 + 248] = 0;


@@ 107,12 105,12 @@ static void sigint_handler(int param)
}

static int led_state = 0;
void hal_led_toggle(void)
void hal_led_toggle()
{
    led_state = 1 - led_state;
    LOG_INFO("LED State %u", led_state);
}
static void use_fast_uart(void)
static void use_fast_uart()
{
#if defined(HAVE_POSIX_B240000_MAPPED_TO_3000000) || defined(HAVE_POSIX_B600_MAPPED_TO_3000000)
    LOG_INFO("Using 3000000 baud.");


@@ 181,7 179,7 @@ namespace Bt
        btstack_run_loop_execute();
    }

    Error initialize_stack()
    auto initialize_stack() -> Error
    {
        btstack_memory_init();
#ifdef TARGET_RT1051


@@ 193,10 191,10 @@ namespace Bt
        LOG_INFO("H4 device: %s", config.device_name);
        const btstack_uart_block_t *uart_driver = btstack_uart_block_posix_instance();
#endif
        const hci_transport_t *transport         = hci_transport_h4_instance(uart_driver);
        const btstack_link_key_db_t *link_key_db = btstack_link_key_db_memory_instance();
        const hci_transport_t *transport = hci_transport_h4_instance(uart_driver);

        hci_init(transport, (void *)&config);
        hci_set_link_key_db(link_key_db);
        hci_set_link_key_db(KeyStorage::getKeyStorage());

        hci_event_callback_registration.callback = &hci_packet_handler;
        hci_add_event_handler(&hci_event_callback_registration);


@@ 204,7 202,7 @@ namespace Bt
        return Error();
    }

    Error register_hw_error_callback(std::function<void(uint8_t)> new_callback)
    auto register_hw_error_callback(std::function<void(uint8_t)> new_callback) -> Error
    {
        static std::function<void(uint8_t)> callback = nullptr;
        callback                                     = new_callback;


@@ 217,7 215,7 @@ namespace Bt
        return Error();
    }

    Error run_stack(TaskHandle_t *handle)
    auto run_stack(TaskHandle_t *handle) -> Error
    {
        BaseType_t taskerr = 0;
        LOG_INFO("Past last moment for Bt registration prior to RUN state");

M module-bluetooth/CMakeLists.txt => module-bluetooth/CMakeLists.txt +2 -0
@@ 6,6 6,8 @@ set(CMAKE_CXX_STANDARD 17)

set(SOURCES
    ${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/BluetoothWorker.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/BtstackWorker.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/BtKeysStorage.cpp
)

message("Build with BlueKitchen")

M module-bluetooth/lib/btstack.cmake => module-bluetooth/lib/btstack.cmake +0 -1
@@ 136,7 136,6 @@ list(APPEND TARGET_LIBRARIES_INCLUDES
    )

set(BOARD_DIR_SOURCES
            ${BT_INT}/Worker.cpp
            ${BT_INT}/GAP.cpp
            ${BT_INT}/PAN.cpp


M module-bsp/bsp/bluetooth/Bluetooth.cpp => module-bsp/bsp/bluetooth/Bluetooth.cpp +0 -13
@@ 21,17 21,4 @@ namespace bsp {
            va_end(args);
        }
    }

    Bluetopia::Bluetopia(unsigned int in_size, unsigned int out_size, int threshold) : BluetoothCommon(in_size,out_size, threshold),rx_thread(0), thandle(NULL)
    {
    }

    Bluetopia::~Bluetopia()
    {
    }

    Bluetopia *Bluetopia::getInstance()
    {
        return Bluetopia::getInstance();
    }
};

M module-bsp/bsp/bluetooth/Bluetooth.hpp => module-bsp/bsp/bluetooth/Bluetooth.hpp +0 -16
@@ 132,22 132,6 @@ namespace bsp {
    };

    /// definitions needed by BT stack
    class Bluetopia : public BluetoothCommon {
        public:
            Bluetopia(unsigned int in_size=default_buff_size, unsigned int out_size=default_buff_size, int threshold=0);
            virtual ~Bluetopia();
            static Bluetopia *getInstance();

            virtual ssize_t read(void *buf, size_t nbytes) override;
            void wait_data();
            void set_data();

            void (*com_cb)(unsigned int transport_id, unsigned int datalen, unsigned char *buff, unsigned long param);
            unsigned long com_cb_param;
            long rx_thread;
            TaskHandle_t thandle;
    };

    class BlueKitchen : public BluetoothCommon {
        public:
            BlueKitchen(unsigned int in_size=default_buff_size, unsigned int out_size=default_buff_size);

M module-services/service-bluetooth/messages/BluetoothMessage.hpp => module-services/service-bluetooth/messages/BluetoothMessage.hpp +3 -2
@@ 41,7 41,7 @@ class BluetoothAddrMessage : public sys::DataMessage
{
  public:
    bd_addr_t addr;
    BluetoothAddrMessage(std::string addr) : sys::DataMessage(MessageType::BluetoothAddrResult)
    explicit BluetoothAddrMessage(std::string addr) : sys::DataMessage(MessageType::BluetoothAddrResult)
    {
        sscanf_bd_addr(addr.c_str(), this->addr);
    };


@@ 52,7 52,8 @@ class BluetoothPairResultMessage : public sys::DataMessage
{
  public:
    bool status;
    BluetoothPairResultMessage(bool status) : sys::DataMessage(MessageType::BluetoothPairResult), status(status){};
    explicit BluetoothPairResultMessage(bool status)
        : sys::DataMessage(MessageType::BluetoothPairResult), status(status){};

    ~BluetoothPairResultMessage() override = default;
};