~aleteoryx/muditaos

649cacd1c3e61d813dbbd18e1d66413629353cbf — Bartosz Cichocki 4 years ago 6e69eb6
[EGD-7799] Enable SSP authorised pairing

This enables Simple Secure Pairing which is required to pair
from another device (device -> Pure). As for now, only KeyboardOnly
capabilities are enabled as we have all frontend and backend
already enabled for entering the pin code/passkey
M module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.cpp => module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.cpp +3 -0
@@ 81,6 81,9 @@ namespace bluetooth
        hci_set_link_key_db(bluetooth::KeyStorage::getKeyStorage());
        hci_event_callback_registration.callback = &hci_packet_handler;
        hci_add_event_handler(&hci_event_callback_registration);

        gap_ssp_set_io_capability(SSP_IO_CAPABILITY_KEYBOARD_ONLY);
        gap_ssp_set_auto_accept(false);
        LOG_DEBUG("BT worker run success");
        return Error::Success;
    }

M module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.cpp => module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.cpp +50 -6
@@ 8,6 8,7 @@
#include <service-bluetooth/messages/ResponseVisibleDevices.hpp>
#include <service-bluetooth/messages/Unpair.hpp>
#include <service-bluetooth/messages/Passkey.hpp>
#include <service-bluetooth/Constants.hpp>
extern "C"
{
#include "btstack.h"


@@ 20,6 21,9 @@ namespace bluetooth
    std::vector<Devicei> GAP::devices;
    btstack_packet_callback_registration_t GAP::cb_handler;
    ScanState GAP::state;
    bd_addr_t GAP::SSPaddress;
    bool GAP::legacyPairing = false;
    std::string GAP::SSPname{};

    auto GAP::registerScan() -> Error
    {


@@ 208,7 212,7 @@ namespace bluetooth
        auto result = packet[2];

        auto msg = std::make_shared<BluetoothPairResultMessage>(currentlyProccesedDevice, result == 0u);
        ownerService->bus.sendUnicast(std::move(msg), "ServiceBluetooth");
        ownerService->bus.sendUnicast(std::move(msg), service::name::bluetooth);
    }
    /* @text In ACTIVE, the following events are processed:
     *  - GAP Inquiry result event: BTstack provides a unified inquiry result that contain


@@ 230,13 234,33 @@ namespace bluetooth
        case GAP_EVENT_INQUIRY_COMPLETE:
            processInquiryComplete();
            break;

        case HCI_EVENT_USER_PASSKEY_REQUEST: {
            hci_event_user_passkey_request_get_bd_addr(packet, SSPaddress);
            gap_remote_name_request(SSPaddress, PAGE_SCAN_MODE_STANDARD, 0);
            auto msg = std::make_shared<::message::bluetooth::RequestPasskey>();
            ownerService->bus.sendMulticast(std::move(msg), sys::BusChannel::BluetoothNotifications);
        } break;
        case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
            processNameRequestComplete(packet, addr);
            if (legacyPairing) {
                processNameRequestComplete(packet, addr);
            }
            else {
                SSPname = reinterpret_cast<const char *>(&packet[9]);
                LOG_SENSITIVE("Name: %s", SSPname.c_str());
                Devicei newDevice(SSPname);
                newDevice.setAddress(&SSPaddress);
                devices.push_back(newDevice);
            }
            break;
        case GAP_EVENT_DEDICATED_BONDING_COMPLETED:
            processDedicatedBondingCompleted(packet, addr);
            break;
        case HCI_EVENT_SIMPLE_PAIRING_COMPLETE:
            processSimplePairingCompleted(packet, addr);
            break;
        case GAP_EVENT_PAIRING_COMPLETE:
            legacyPairing = false;
            break;
        default:
            break;
        }


@@ 257,9 281,9 @@ namespace bluetooth
            return;
        }
        if (hci_event_packet_get_type(packet) == HCI_EVENT_PIN_CODE_REQUEST) {
            bd_addr_t address;
            LOG_DEBUG("PIN code request!");
            hci_event_pin_code_request_get_bd_addr(packet, address);
            legacyPairing = true;
            hci_event_pin_code_request_get_bd_addr(packet, addr);
            auto msg = std::make_shared<::message::bluetooth::RequestPasskey>();
            ownerService->bus.sendMulticast(std::move(msg), sys::BusChannel::BluetoothNotifications);
        }


@@ 296,6 320,26 @@ namespace bluetooth
    }
    void GAP::respondPinCode(const std::string &pin)
    {
        gap_pin_code_response(currentlyProccesedDevice.address, pin.c_str());
        if (legacyPairing) {
            gap_pin_code_response(currentlyProccesedDevice.address, pin.c_str());
            return;
        }
        unsigned int passkey = 0;
        try {
            passkey = stoi(pin);
            LOG_DEBUG("Sending %06u as a passkey", passkey);
        }
        catch (const std::invalid_argument &e) {
            LOG_ERROR("STOI error: %s", e.what());
        }

        gap_ssp_passkey_response(SSPaddress, passkey);
    }
    void GAP::processSimplePairingCompleted(std::uint8_t *packet, bd_addr_t &addr)
    {
        auto status = hci_event_simple_pairing_complete_get_status(packet);
        auto device = devices.at(getDeviceIndexForAddress(devices, SSPaddress));
        auto msg    = std::make_shared<BluetoothPairResultMessage>(device, status == 0u);
        ownerService->bus.sendUnicast(std::move(msg), service::name::bluetooth);
    }
} // namespace bluetooth

M module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.hpp => module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.hpp +4 -0
@@ 25,6 25,9 @@ namespace bluetooth
        static btstack_packet_callback_registration_t cb_handler;
        static constexpr auto inquiryIntervalSeconds = 5;
        static ScanState state;
        static bd_addr_t SSPaddress;
        static bool legacyPairing;
        static std::string SSPname;
        static void sendDevices();
        static auto startScan() -> int;
        static auto remoteNameToFetch() -> bool;


@@ 41,6 44,7 @@ namespace bluetooth
        static void processInquiryComplete();
        static void processNameRequestComplete(std::uint8_t *packet, bd_addr_t &addr);
        static void processDedicatedBondingCompleted(std::uint8_t *packet, bd_addr_t &addr);
        static void processSimplePairingCompleted(std::uint8_t *packet, bd_addr_t &addr);
        static void initStateHandler(std::uint8_t eventType, std::uint8_t *packet);
        static auto getDeviceIndexForAddress(const std::vector<Devicei> &devs, const bd_addr_t addr) -> int;


M module-services/service-bluetooth/ServiceBluetooth.cpp => module-services/service-bluetooth/ServiceBluetooth.cpp +1 -0
@@ 230,6 230,7 @@ auto ServiceBluetooth::handle(BluetoothPairMessage *msg) -> std::shared_ptr<sys:
auto ServiceBluetooth::handle(BluetoothPairResultMessage *msg) -> std::shared_ptr<sys::Message>
{
    auto device = msg->getDevice();
    bluetoothDevicesModel->mergeDevicesList(bluetooth::GAP::getDevicesList());
    if (msg->isSucceed()) {
        bluetoothDevicesModel->setInternalDeviceState(device, DeviceState::Paired);
    }

M module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.cpp => module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.cpp +0 -1
@@ 28,7 28,6 @@ void BluetoothDevicesModel::insertDevice(const Devicei &device)
auto BluetoothDevicesModel::getDeviceByAddress(const std::string &address)
    -> std::optional<std::reference_wrapper<Devicei>>
{

    auto deviceIt = std::find_if(std::begin(devices), std::end(devices), [address](const Devicei &device) {
        return bd_addr_to_str(device.address) == address;
    });