From f25e6eb1d3c25ddd91bc249c3f84be1e5d483837 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 23 Oct 2023 09:33:15 +0200 Subject: GATT Server Auth: Expose PASSKEY_NOTIFY from BTManager -> BTDevice; App using AdapterStatusListener::devicePairingState() + SMPPairingState::PASSKEY_NOTIFY to display generated PassKey --- src/direct_bt/BTAdapter.cpp | 15 +++++++++++++++ src/direct_bt/BTDevice.cpp | 15 +++++++++++++++ src/direct_bt/SMPTypes.cpp | 9 +++++++++ 3 files changed, 39 insertions(+) (limited to 'src') diff --git a/src/direct_bt/BTAdapter.cpp b/src/direct_bt/BTAdapter.cpp index 948a524d..3a8a1436 100644 --- a/src/direct_bt/BTAdapter.cpp +++ b/src/direct_bt/BTAdapter.cpp @@ -327,6 +327,7 @@ bool BTAdapter::enableListening(const bool enable) noexcept { ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::PIN_CODE_REQUEST, jau::bind_member(this, &BTAdapter::mgmtEvPinCodeRequestMgmt)) && ok; ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::USER_CONFIRM_REQUEST, jau::bind_member(this, &BTAdapter::mgmtEvUserConfirmRequestMgmt)) && ok; ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::USER_PASSKEY_REQUEST, jau::bind_member(this, &BTAdapter::mgmtEvUserPasskeyRequestMgmt)) && ok; + ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::PASSKEY_NOTIFY, jau::bind_member(this, &BTAdapter::mgmtEvPasskeyNotifyMgmt)) && ok; ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::AUTH_FAILED, jau::bind_member(this, &BTAdapter::mgmtEvAuthFailedMgmt)) && ok; ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DEVICE_UNPAIRED, jau::bind_member(this, &BTAdapter::mgmtEvDeviceUnpairedMgmt)) && ok; ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::PAIR_DEVICE_COMPLETE, jau::bind_member(this, &BTAdapter::mgmtEvPairDeviceCompleteMgmt)) && ok; @@ -2632,6 +2633,20 @@ void BTAdapter::mgmtEvUserPasskeyRequestMgmt(const MgmtEvent& e) noexcept { device->updatePairingState(device, e, HCIStatusCode::SUCCESS, SMPPairingState::PASSKEY_EXPECTED); } +void BTAdapter::mgmtEvPasskeyNotifyMgmt(const MgmtEvent& e) noexcept { + const MgmtEvtPasskeyNotify &event = *static_cast(&e); + + BTDeviceRef device = findConnectedDevice(event.getAddress(), event.getAddressType()); + if( nullptr == device ) { + WORDY_PRINT("BTAdapter:hci:SMP: dev_id %d: Device not tracked: address[%s, %s], %s", + dev_id, event.getAddress().toString().c_str(), to_string(event.getAddressType()).c_str(), + event.toString().c_str()); + return; + } + DBG_PRINT("BTAdapter:mgmt:PasskeyNotify: %s", event.toString().c_str()); + device->updatePairingState(device, e, HCIStatusCode::SUCCESS, SMPPairingState::PASSKEY_NOTIFY); +} + void BTAdapter::hciSMPMsgCallback(const BDAddressAndType & addressAndType, const SMPPDUMsg& msg, const HCIACLData::l2cap_frame& source) noexcept { BTDeviceRef device = findConnectedDevice(addressAndType.address, addressAndType.type); diff --git a/src/direct_bt/BTDevice.cpp b/src/direct_bt/BTDevice.cpp index 876463ed..caab6c58 100644 --- a/src/direct_bt/BTDevice.cpp +++ b/src/direct_bt/BTDevice.cpp @@ -768,6 +768,7 @@ std::string BTDevice::PairingData::toString(const uint16_t dev_id, const BDAddre res.append(" - IOCap "+to_string(ioCap_resp)+"\n"); res.append(" - EncSz "+std::to_string(maxEncsz_resp)+"\n"); res.append(" - Keys "+to_string(keys_resp_has)+" / "+to_string(keys_resp_exp)+"\n"); + res.append(" - PassKey "+toPassKeyString(passKey_resp)+"\n"); res.append(" - "+ltk_resp.toString()+"\n"); res.append(" - "+lk_resp.toString()+"\n"); res.append(" - "+irk_resp.toString()+"\n"); @@ -836,6 +837,14 @@ bool BTDevice::updatePairingState(const std::shared_ptr& sthis, const dc.detach(); } break; + case SMPPairingState::PASSKEY_NOTIFY: + if( MgmtEvent::Opcode::PASSKEY_NOTIFY == mgmtEvtOpcode ) { + // we must be in slave/responder mode, i.e. peripheral/GATT-server providing auth passkey + const MgmtEvtPasskeyNotify& event = *static_cast(&evt); + mode = PairingMode::PASSKEY_ENTRY_ini; + pairing_data.passKey_resp = event.getPasskey(); + } + break; case SMPPairingState::OOB_EXPECTED: // 2 mode = PairingMode::OUT_OF_BAND; @@ -1864,6 +1873,8 @@ void BTDevice::clearSMPStates(const bool connected) noexcept { pairing_data.use_sc = false; pairing_data.encryption_enabled = false; + pairing_data.passKey_resp = 0; + pairing_data.authReqs_resp = SMPAuthReqs::NONE; pairing_data.ioCap_resp = SMPIOCapability::NO_INPUT_NO_OUTPUT; pairing_data.oobFlag_resp = SMPOOBDataFlag::OOB_AUTH_DATA_NOT_PRESENT; @@ -2314,6 +2325,10 @@ exit: return res; } +std::uint32_t BTDevice::getResponderSMPPassKey() const noexcept { + return pairing_data.passKey_resp; +} + HCIStatusCode BTDevice::unpair() noexcept { if constexpr ( USE_LINUX_BT_SECURITY ) { const BTManagerRef& mngr = adapter.getManager(); diff --git a/src/direct_bt/SMPTypes.cpp b/src/direct_bt/SMPTypes.cpp index cfe68674..c842c8ec 100644 --- a/src/direct_bt/SMPTypes.cpp +++ b/src/direct_bt/SMPTypes.cpp @@ -53,6 +53,7 @@ static void append_bitstr(std::string& out, T mask, T bit, const std::string& bi X(FEATURE_EXCHANGE_COMPLETED) \ X(PASSKEY_EXPECTED) \ X(NUMERIC_COMPARE_EXPECTED) \ + X(PASSKEY_NOTIFY) \ X(OOB_EXPECTED) \ X(KEY_DISTRIBUTION) \ X(COMPLETED) @@ -67,6 +68,14 @@ std::string direct_bt::to_string(const SMPPairingState state) noexcept { return "Unknown SMP PairingState"; } +std::string direct_bt::toPassKeyString(const std::uint32_t passKey) noexcept { + std::string pin; + pin.reserve(6+1); // including EOS for snprintf + pin.resize(6); + snprintf(&pin[0], pin.capacity(), "%06u", passKey%1000000u ); + return pin; +} + #define IOCAP_ENUM(X) \ X(DISPLAY_ONLY) \ X(DISPLAY_YES_NO) \ -- cgit v1.2.3