From 649cacd1c3e61d813dbbd18e1d66413629353cbf Mon Sep 17 00:00:00 2001 From: Bartosz Cichocki Date: Thu, 14 Oct 2021 15:21:06 +0200 Subject: [PATCH] [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 --- .../interface/BluetoothDriverImpl.cpp | 3 + .../Bluetooth/interface/profiles/GAP/GAP.cpp | 56 +++++++++++++++++-- .../Bluetooth/interface/profiles/GAP/GAP.hpp | 4 ++ .../service-bluetooth/ServiceBluetooth.cpp | 1 + .../BluetoothDevicesModel.cpp | 1 - 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.cpp b/module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.cpp index ca5cac3ab1ff35c0caa145e2978ada5e244999ec..8f232e88b0ec233a88ee5d885c0a7ba84a3f23ab 100644 --- a/module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.cpp +++ b/module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.cpp @@ -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; } diff --git a/module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.cpp b/module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.cpp index 789f6dfe447291d974004e66eb6a0170b6654e79..e4ed1aa358e3ae0847806e6bea702763cf773ffa 100644 --- a/module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.cpp +++ b/module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.cpp @@ -8,6 +8,7 @@ #include #include #include +#include extern "C" { #include "btstack.h" @@ -20,6 +21,9 @@ namespace bluetooth std::vector 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(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(&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(device, status == 0u); + ownerService->bus.sendUnicast(std::move(msg), service::name::bluetooth); } } // namespace bluetooth diff --git a/module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.hpp b/module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.hpp index 5745990dbacdee0bb1a452cd772cf18f84a9bbb2..1cef15065909e4e4a15932e0227a604ae6a8c164 100644 --- a/module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.hpp +++ b/module-bluetooth/Bluetooth/interface/profiles/GAP/GAP.hpp @@ -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 &devs, const bd_addr_t addr) -> int; diff --git a/module-services/service-bluetooth/ServiceBluetooth.cpp b/module-services/service-bluetooth/ServiceBluetooth.cpp index d1573648a65d2f9184098efea7118993229fd96c..c54a42422970ebd6e4a38bfef12f210ad7e1be32 100644 --- a/module-services/service-bluetooth/ServiceBluetooth.cpp +++ b/module-services/service-bluetooth/ServiceBluetooth.cpp @@ -230,6 +230,7 @@ auto ServiceBluetooth::handle(BluetoothPairMessage *msg) -> std::shared_ptr std::shared_ptr { auto device = msg->getDevice(); + bluetoothDevicesModel->mergeDevicesList(bluetooth::GAP::getDevicesList()); if (msg->isSucceed()) { bluetoothDevicesModel->setInternalDeviceState(device, DeviceState::Paired); } diff --git a/module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.cpp b/module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.cpp index 4a1acd5d6f67ce0819cac4ebce5ad28e78355678..29cdc741d9bd04cb713feeb03e4c17b8b28031ff 100644 --- a/module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.cpp +++ b/module-services/service-bluetooth/service-bluetooth/BluetoothDevicesModel.cpp @@ -28,7 +28,6 @@ void BluetoothDevicesModel::insertDevice(const Devicei &device) auto BluetoothDevicesModel::getDeviceByAddress(const std::string &address) -> std::optional> { - auto deviceIt = std::find_if(std::begin(devices), std::end(devices), [address](const Devicei &device) { return bd_addr_to_str(device.address) == address; });