kdeconnect-kde/core/backends/pairinghandler.cpp
Albert Vaca Cintora 064ddfa3fe Refactor PairingHandler
We now have a single PairingHandler for all types of links.

The implementation now is more aligned with the one for Android.
2023-06-02 16:38:52 +00:00

143 lines
4.6 KiB
C++

/**
* SPDX-FileCopyrightText: 2015 Albert Vaca Cintora <albertvaka@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "pairinghandler.h"
#include "core_debug.h"
#include <KLocalizedString>
PairingHandler::PairingHandler(Device *parent, PairState initialState)
: QObject(parent)
, m_device(parent)
, m_pairState(initialState)
{
m_pairingTimeout.setSingleShot(true);
m_pairingTimeout.setInterval(pairingTimeoutMsec);
connect(&m_pairingTimeout, &QTimer::timeout, this, &PairingHandler::pairingTimeout);
}
void PairingHandler::packetReceived(const NetworkPacket &np)
{
m_pairingTimeout.stop();
bool wantsPair = np.get<bool>(QStringLiteral("pair"));
if (wantsPair) {
switch (m_pairState) {
case PairState::Requested:
pairingDone();
break;
case PairState::RequestedByPeer:
qCDebug(KDECONNECT_CORE) << "Ignoring second pairing request before the first one timed out";
break;
case PairState::Paired:
qCDebug(KDECONNECT_CORE) << "Auto-accepting pairing request from a device we already trusted";
acceptPairing();
break;
case PairState::NotPaired:
m_pairState = PairState::RequestedByPeer;
m_pairingTimeout.start();
Q_EMIT incomingPairRequest();
break;
}
} else { // wantsPair == false
qCDebug(KDECONNECT_CORE) << "Unpair request received";
switch (m_pairState) {
case PairState::NotPaired:
qCDebug(KDECONNECT_CORE) << "Ignoring unpair request for already unpaired device";
break;
case PairState::Requested: // We started pairing and got rejected
case PairState::RequestedByPeer: // They stared pairing, then cancelled
m_pairState = PairState::NotPaired;
Q_EMIT pairingFailed(i18n("Canceled by other peer"));
break;
case PairState::Paired:
m_pairState = PairState::NotPaired;
Q_EMIT unpaired();
break;
}
}
}
bool PairingHandler::requestPairing()
{
m_pairingTimeout.stop();
if (m_pairState == PairState::Paired) {
qWarning() << m_device->name() << ": requestPairing was called on an already paired device.";
Q_EMIT pairingFailed(i18n("%1: Already paired", m_device->name()));
return false;
}
if (m_pairState == PairState::RequestedByPeer) {
qWarning() << m_device->name() << ": Pairing already started by the other end, accepting their request.";
return acceptPairing();
}
if (!m_device->isReachable()) {
Q_EMIT pairingFailed(i18n("%1: Device not reachable", m_device->name()));
return false;
}
m_pairingTimeout.stop();
m_pairState = PairState::Requested;
NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), true}});
const bool success = m_device->sendPacket(np);
if (success) {
m_pairingTimeout.start();
} else {
qWarning() << m_device->name() << ": Failed to send pair request packet.";
m_pairState = PairState::NotPaired;
Q_EMIT pairingFailed(i18n("%1: Device not reachable", m_device->name()));
}
return success;
}
bool PairingHandler::acceptPairing()
{
m_pairingTimeout.stop();
NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), true}});
const bool success = m_device->sendPacket(np);
if (success) {
pairingDone();
} else {
qWarning() << "Failed to send packet accepting pairing";
m_pairState = PairState::NotPaired;
Q_EMIT pairingFailed(i18n("Device not reachable"));
}
return success;
}
void PairingHandler::cancelPairing()
{
m_pairingTimeout.stop();
m_pairState = PairState::NotPaired;
NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}});
m_device->sendPacket(np);
Q_EMIT pairingFailed(i18n("Cancelled by user"));
}
void PairingHandler::unpair()
{
m_pairState = PairState::NotPaired;
NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}});
m_device->sendPacket(np);
Q_EMIT unpaired();
}
void PairingHandler::pairingTimeout()
{
NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}});
m_device->sendPacket(np);
m_pairState = PairState::NotPaired;
Q_EMIT pairingFailed(i18n("Timed out"));
}
void PairingHandler::pairingDone() {
qCDebug(KDECONNECT_CORE) << "Pairing done";
m_pairState = PairState::Paired;
Q_EMIT pairingSuccessful();
}