File indexing completed on 2024-04-28 04:57:01
0001 /** 0002 * SPDX-FileCopyrightText: 2015 Albert Vaca Cintora <albertvaka@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "pairinghandler.h" 0008 0009 #include "core_debug.h" 0010 0011 #include <KLocalizedString> 0012 0013 PairingHandler::PairingHandler(Device *parent, PairState initialState) 0014 : QObject(parent) 0015 , m_device(parent) 0016 , m_pairState(initialState) 0017 { 0018 m_pairingTimeout.setSingleShot(true); 0019 m_pairingTimeout.setInterval(pairingTimeoutMsec); 0020 connect(&m_pairingTimeout, &QTimer::timeout, this, &PairingHandler::pairingTimeout); 0021 } 0022 0023 void PairingHandler::packetReceived(const NetworkPacket &np) 0024 { 0025 m_pairingTimeout.stop(); 0026 bool wantsPair = np.get<bool>(QStringLiteral("pair")); 0027 if (wantsPair) { 0028 switch (m_pairState) { 0029 case PairState::Requested: 0030 pairingDone(); 0031 break; 0032 case PairState::RequestedByPeer: 0033 qCDebug(KDECONNECT_CORE) << "Ignoring second pairing request before the first one timed out"; 0034 break; 0035 case PairState::Paired: 0036 case PairState::NotPaired: 0037 if (m_pairState == PairState::Paired) { 0038 qWarning() << "Received pairing request from a device we already trusted."; 0039 // It would be nice to auto-accept the pairing request here, but since the pairing accept and pairing request 0040 // messages are identical, this could create an infinite loop if both devices are "accepting" each other pairs. 0041 // Instead, unpair and handle as if "NotPaired". 0042 m_pairState = PairState::NotPaired; 0043 Q_EMIT unpaired(); 0044 } 0045 m_pairState = PairState::RequestedByPeer; 0046 m_pairingTimeout.start(); 0047 Q_EMIT incomingPairRequest(); 0048 break; 0049 } 0050 } else { // wantsPair == false 0051 qCDebug(KDECONNECT_CORE) << "Unpair request received"; 0052 switch (m_pairState) { 0053 case PairState::NotPaired: 0054 qCDebug(KDECONNECT_CORE) << "Ignoring unpair request for already unpaired device"; 0055 break; 0056 case PairState::Requested: // We started pairing and got rejected 0057 case PairState::RequestedByPeer: // They stared pairing, then cancelled 0058 m_pairState = PairState::NotPaired; 0059 Q_EMIT pairingFailed(i18n("Canceled by other peer")); 0060 break; 0061 case PairState::Paired: 0062 m_pairState = PairState::NotPaired; 0063 Q_EMIT unpaired(); 0064 break; 0065 } 0066 } 0067 } 0068 0069 bool PairingHandler::requestPairing() 0070 { 0071 m_pairingTimeout.stop(); 0072 0073 if (m_pairState == PairState::Paired) { 0074 qWarning() << m_device->name() << ": requestPairing was called on an already paired device."; 0075 Q_EMIT pairingFailed(i18n("%1: Already paired", m_device->name())); 0076 return false; 0077 } 0078 if (m_pairState == PairState::RequestedByPeer) { 0079 qWarning() << m_device->name() << ": Pairing already started by the other end, accepting their request."; 0080 return acceptPairing(); 0081 } 0082 0083 if (!m_device->isReachable()) { 0084 Q_EMIT pairingFailed(i18n("%1: Device not reachable", m_device->name())); 0085 return false; 0086 } 0087 0088 m_pairState = PairState::Requested; 0089 0090 m_pairingTimeout.start(); 0091 0092 NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), true}}); 0093 const bool success = m_device->sendPacket(np); 0094 if (!success) { 0095 m_pairingTimeout.stop(); 0096 qWarning() << m_device->name() << ": Failed to send pair request packet."; 0097 m_pairState = PairState::NotPaired; 0098 Q_EMIT pairingFailed(i18n("%1: Device not reachable", m_device->name())); 0099 } 0100 return success; 0101 } 0102 0103 bool PairingHandler::acceptPairing() 0104 { 0105 m_pairingTimeout.stop(); 0106 NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), true}}); 0107 const bool success = m_device->sendPacket(np); 0108 if (success) { 0109 pairingDone(); 0110 } else { 0111 qWarning() << "Failed to send packet accepting pairing"; 0112 m_pairState = PairState::NotPaired; 0113 Q_EMIT pairingFailed(i18n("Device not reachable")); 0114 } 0115 return success; 0116 } 0117 0118 void PairingHandler::cancelPairing() 0119 { 0120 m_pairingTimeout.stop(); 0121 m_pairState = PairState::NotPaired; 0122 NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}}); 0123 m_device->sendPacket(np); 0124 Q_EMIT pairingFailed(i18n("Cancelled by user")); 0125 } 0126 0127 void PairingHandler::unpair() 0128 { 0129 m_pairState = PairState::NotPaired; 0130 NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}}); 0131 m_device->sendPacket(np); 0132 Q_EMIT unpaired(); 0133 } 0134 0135 void PairingHandler::pairingTimeout() 0136 { 0137 NetworkPacket np(PACKET_TYPE_PAIR, {{QStringLiteral("pair"), false}}); 0138 m_device->sendPacket(np); 0139 m_pairState = PairState::NotPaired; 0140 Q_EMIT pairingFailed(i18n("Timed out")); 0141 } 0142 0143 void PairingHandler::pairingDone() 0144 { 0145 qCDebug(KDECONNECT_CORE) << "Pairing done"; 0146 m_pairState = PairState::Paired; 0147 Q_EMIT pairingSuccessful(); 0148 } 0149 0150 #include "moc_pairinghandler.cpp"