kdeconnect-kde/core/backends/lan/lanlinkprovider.cpp

507 lines
19 KiB
C++
Raw Normal View History

2013-08-07 10:29:56 +01:00
/**
* Copyright 2013 Albert Vaca <albertvaka@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2013-08-28 22:47:39 +01:00
#include "lanlinkprovider.h"
#include "core_debug.h"
2013-08-07 10:29:56 +01:00
2015-09-10 14:51:38 +01:00
#ifndef Q_OS_WIN
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
2015-09-10 14:51:38 +01:00
#endif
2013-08-07 10:29:56 +01:00
#include <QHostInfo>
#include <QTcpServer>
#include <QUdpSocket>
2015-04-04 18:05:55 +01:00
#include <QtGlobal>
#include <QNetworkSession>
#include <QNetworkConfigurationManager>
2013-08-07 10:29:56 +01:00
2015-07-09 22:51:08 +01:00
#include "../../daemon.h"
#include "landevicelink.h"
2015-12-01 18:45:14 +00:00
#include "lanpairinghandler.h"
#include <kdeconnectconfig.h>
2015-07-09 22:51:08 +01:00
#include <QDBusPendingReply>
2015-07-05 14:23:53 +01:00
#include <QtNetwork/qsslcipher.h>
#include <QtNetwork/qsslconfiguration.h>
LanLinkProvider::LanLinkProvider(bool testMode)
: mTestMode(testMode)
2013-08-07 10:29:56 +01:00
{
2015-04-04 18:05:55 +01:00
mTcpPort = 0;
2013-08-07 10:29:56 +01:00
connect(&mUdpSocket, SIGNAL(readyRead()), this, SLOT(newUdpConnection()));
2013-08-07 10:29:56 +01:00
2015-07-05 14:23:53 +01:00
mServer = new Server(this);
2015-07-09 23:27:27 +01:00
connect(mServer,SIGNAL(newConnection()),this, SLOT(newConnection()));
2013-08-07 10:29:56 +01:00
//Detect when a network interface changes status, so we announce ourelves in the new network
QNetworkConfigurationManager* networkManager = new QNetworkConfigurationManager(this);
connect(networkManager, &QNetworkConfigurationManager::configurationChanged, this, &LanLinkProvider::onNetworkConfigurationChanged);
}
void LanLinkProvider::onNetworkConfigurationChanged(const QNetworkConfiguration &config)
{
if (m_lastConfig != config && config.state() == QNetworkConfiguration::Active) {
m_lastConfig = config;
onNetworkChange();
}
2013-08-07 10:29:56 +01:00
}
2015-04-04 18:05:55 +01:00
LanLinkProvider::~LanLinkProvider()
{
}
2013-08-28 22:47:39 +01:00
void LanLinkProvider::onStart()
2013-08-07 10:29:56 +01:00
{
const QHostAddress bindAddress = mTestMode? QHostAddress::LocalHost : QHostAddress::Any;
bool success = mUdpSocket.bind(bindAddress, port, QUdpSocket::ShareAddress);
Q_ASSERT(success);
2016-03-08 00:01:44 +00:00
qCDebug(KDECONNECT_CORE) << "onStart";
2015-12-02 19:04:35 +00:00
mTcpPort = port;
while (!mServer->listen(bindAddress, mTcpPort)) {
mTcpPort++;
if (mTcpPort > 1764) { //No ports available?
qCritical(KDECONNECT_CORE) << "Error opening a port in range 1714-1764";
mTcpPort = 0;
return;
}
}
2013-08-07 10:29:56 +01:00
onNetworkChange();
2013-08-07 10:29:56 +01:00
}
2013-08-28 22:47:39 +01:00
void LanLinkProvider::onStop()
2013-08-07 10:29:56 +01:00
{
2016-03-08 00:01:44 +00:00
qCDebug(KDECONNECT_CORE) << "onStop";
mUdpSocket.close();
2015-07-05 14:23:53 +01:00
mServer->close();
2013-08-07 10:29:56 +01:00
}
//I'm in a new network, let's be polite and introduce myself
void LanLinkProvider::onNetworkChange()
{
2015-07-05 14:23:53 +01:00
if (!mServer->isListening()) {
//Not started
return;
}
2015-04-04 18:05:55 +01:00
Q_ASSERT(mTcpPort != 0);
qCDebug(KDECONNECT_CORE()) << "Broadcasting identity packet";
2013-08-07 10:29:56 +01:00
NetworkPackage np("");
NetworkPackage::createIdentityPackage(&np);
np.set("tcpPort", mTcpPort);
2015-12-17 16:59:08 +00:00
mUdpSocket.writeDatagram(np.serialize(), mTestMode ? QHostAddress::LocalHost : QHostAddress("255.255.255.255"), port);
2013-08-07 10:29:56 +01:00
}
//I'm the existing device, a new device is kindly introducing itself.
//I will create a TcpSocket and try to connect. This can result in either connected() or connectError().
void LanLinkProvider::newUdpConnection() //udpBroadcastReceived
2013-08-07 10:29:56 +01:00
{
while (mUdpSocket.hasPendingDatagrams()) {
2015-07-05 14:23:53 +01:00
2013-08-07 10:29:56 +01:00
QByteArray datagram;
datagram.resize(mUdpSocket.pendingDatagramSize());
2013-08-07 10:29:56 +01:00
QHostAddress sender;
mUdpSocket.readDatagram(datagram.data(), datagram.size(), &sender);
2013-08-07 10:29:56 +01:00
2015-12-06 00:19:55 +00:00
if (sender.isLoopback() && !mTestMode)
continue;
NetworkPackage* receivedPackage = new NetworkPackage("");
bool success = NetworkPackage::unserialize(datagram, receivedPackage);
2013-08-07 10:29:56 +01:00
2016-03-08 00:01:44 +00:00
//qCDebug(KDECONNECT_CORE) << "udp connection from " << receivedPackage->;
2015-12-02 19:04:35 +00:00
2016-05-31 19:09:52 +01:00
//qCDebug(KDECONNECT_CORE) << "Datagram " << datagram.data() ;
2015-07-05 14:23:53 +01:00
if (!success || receivedPackage->type() != PACKAGE_TYPE_IDENTITY) {
delete receivedPackage;
continue;
}
2013-08-07 12:40:39 +01:00
if (receivedPackage->get<QString>("deviceId") == KdeConnectConfig::instance()->deviceId()) {
2015-03-22 06:12:04 +00:00
//qCDebug(KDECONNECT_CORE) << "Ignoring my own broadcast";
delete receivedPackage;
continue;
}
int tcpPort = receivedPackage->get<int>("tcpPort", port);
2015-03-22 06:12:04 +00:00
//qCDebug(KDECONNECT_CORE) << "Received Udp identity package from" << sender << " asking for a tcp connection on port " << tcpPort;
2015-07-05 14:23:53 +01:00
QSslSocket* socket = new QSslSocket(this);
receivedIdentityPackages[socket].np = receivedPackage;
receivedIdentityPackages[socket].sender = sender;
connect(socket, SIGNAL(connected()), this, SLOT(connected()));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError()));
socket->connectToHost(sender, tcpPort);
2013-08-07 12:40:39 +01:00
}
}
2013-08-07 10:29:56 +01:00
2013-08-28 22:47:39 +01:00
void LanLinkProvider::connectError()
2013-08-07 12:40:39 +01:00
{
2015-07-05 14:23:53 +01:00
QSslSocket* socket = qobject_cast<QSslSocket*>(sender());
if (!socket) return;
2013-08-07 12:40:39 +01:00
disconnect(socket, SIGNAL(connected()), this, SLOT(connected()));
disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError()));
2013-08-07 10:29:56 +01:00
2015-09-09 19:12:16 +01:00
qCDebug(KDECONNECT_CORE) << "Fallback (1), try reverse connection (send udp packet)" << socket->errorString();
NetworkPackage np("");
NetworkPackage::createIdentityPackage(&np);
np.set("tcpPort", mTcpPort);
mUdpSocket.writeDatagram(np.serialize(), receivedIdentityPackages[socket].sender, port);
2013-08-07 12:40:39 +01:00
//The socket we created didn't work, and we didn't manage
//to create a LanDeviceLink from it, deleting everything.
2015-07-14 13:04:04 +01:00
delete receivedIdentityPackages.take(socket).np;
delete socket;
2013-08-07 12:40:39 +01:00
}
2013-08-28 22:47:39 +01:00
void LanLinkProvider::connected()
2013-08-07 12:40:39 +01:00
{
2015-07-05 14:23:53 +01:00
qCDebug(KDECONNECT_CORE) << "Socket connected";
2015-07-13 15:25:22 +01:00
2015-07-05 14:23:53 +01:00
QSslSocket* socket = qobject_cast<QSslSocket*>(sender());
if (!socket) return;
2013-08-07 12:40:39 +01:00
disconnect(socket, SIGNAL(connected()), this, SLOT(connected()));
disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError()));
configureSocket(socket);
// If socket disconnects due to any reason after connection, link on ssl faliure
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
NetworkPackage* receivedPackage = receivedIdentityPackages[socket].np;
const QString& deviceId = receivedPackage->get<QString>("deviceId");
//qCDebug(KDECONNECT_CORE) << "Connected" << socket->isWritable();
2013-08-07 12:40:39 +01:00
2015-07-05 14:23:53 +01:00
// If network is on ssl, do not believe when they are connected, believe when handshake is completed
2013-08-07 12:40:39 +01:00
NetworkPackage np2("");
NetworkPackage::createIdentityPackage(&np2);
2015-07-05 14:23:53 +01:00
socket->write(np2.serialize());
bool success = socket->waitForBytesWritten();
2013-08-07 12:40:39 +01:00
if (success) {
2015-07-05 14:23:53 +01:00
qCDebug(KDECONNECT_CORE) << "Handshaking done (i'm the existing device)";
// if ssl supported
if (receivedPackage->get<int>("protocolVersion") >= NetworkPackage::ProtocolVersion) {
2015-07-05 14:23:53 +01:00
// since I support ssl and remote device support ssl
2016-03-08 15:29:34 +00:00
socket->setPeerVerifyName(deviceId);
2015-07-05 14:23:53 +01:00
QString certString = KdeConnectConfig::instance()->getDeviceProperty(deviceId, "certificate", QString());
if (!certString.isEmpty()) {
2016-03-08 00:01:44 +00:00
qCDebug(KDECONNECT_CORE) << "Device trusted";
2015-07-05 14:23:53 +01:00
socket->addCaCertificate(QSslCertificate(certString.toLatin1()));
socket->setPeerVerifyMode(QSslSocket::VerifyPeer);
2015-07-05 14:23:53 +01:00
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
} else {
2016-03-08 00:01:44 +00:00
qCDebug(KDECONNECT_CORE) << "Device untrusted";
2015-07-05 14:23:53 +01:00
// Do not care about ssl errors here, socket will not be closed due to errors because of query peer
socket->setPeerVerifyMode(QSslSocket::QueryPeer);
2016-03-08 00:01:44 +00:00
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrorsLogButIgnore(QList<QSslError>)));
2015-07-05 14:23:53 +01:00
}
2016-03-08 15:29:34 +00:00
qCDebug(KDECONNECT_CORE) << "Starting server ssl (I'm the client TCP socket)";
2015-07-05 14:23:53 +01:00
connect(socket, SIGNAL(encrypted()), this, SLOT(encrypted()));
socket->startServerEncryption();
return; // Return statement prevents from deleting received package, needed in slot "encrypted"
2015-07-05 14:23:53 +01:00
} else {
qWarning() << "Incompatible protocol version, this won't work";
//addLink(deviceId, socket, receivedPackage, LanDeviceLink::Remotely);
}
2013-08-07 12:40:39 +01:00
} else {
//I think this will never happen, but if it happens the deviceLink
//(or the socket that is now inside it) might not be valid. Delete them.
qCDebug(KDECONNECT_CORE) << "Fallback (2), try reverse connection (send udp packet)";
mUdpSocket.writeDatagram(np2.serialize(), receivedIdentityPackages[socket].sender, port);
2013-08-07 10:29:56 +01:00
}
delete receivedPackage;
receivedIdentityPackages.remove(socket);
//We don't delete the socket because now it's owned by the LanDeviceLink
2013-08-07 10:29:56 +01:00
}
2015-07-14 13:04:04 +01:00
void LanLinkProvider::encrypted()
{
2016-03-08 00:01:44 +00:00
qCDebug(KDECONNECT_CORE) << "Socket succesfully stablished an SSL connection";
2015-07-13 15:25:22 +01:00
2015-07-05 14:23:53 +01:00
QSslSocket* socket = qobject_cast<QSslSocket*>(sender());
if (!socket) return;
2015-07-05 14:23:53 +01:00
disconnect(socket, SIGNAL(encrypted()), this, SLOT(encrypted()));
disconnect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
NetworkPackage* receivedPackage = receivedIdentityPackages[socket].np;
const QString& deviceId = receivedPackage->get<QString>("deviceId");
//qCDebug(KDECONNECT_CORE) << "Connected" << socket->isWritable();
addLink(deviceId, socket, receivedPackage, LanDeviceLink::Remotely);
2015-07-05 14:23:53 +01:00
// Copied from connected slot, now delete received package
delete receivedPackage;
receivedIdentityPackages.remove(socket);
}
2015-07-14 13:04:04 +01:00
void LanLinkProvider::sslErrors(const QList<QSslError>& errors)
2015-07-05 14:23:53 +01:00
{
QSslSocket* socket = qobject_cast<QSslSocket*>(sender());
if (!socket) return;
2015-07-05 14:23:53 +01:00
disconnect(socket, SIGNAL(encrypted()), this, SLOT(encrypted()));
disconnect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
2015-12-01 18:45:14 +00:00
foreach(const QSslError &error, errors) {
qCDebug(KDECONNECT_CORE) << "SSL Error :" << error.errorString();
2015-07-09 22:51:08 +01:00
switch (error.error()) {
case QSslError::CertificateSignatureFailed:
case QSslError::CertificateNotYetValid:
case QSslError::CertificateExpired:
case QSslError::CertificateUntrusted:
case QSslError::SelfSignedCertificate: {
2015-07-09 22:51:08 +01:00
qCDebug(KDECONNECT_CORE) << "Unpairing device due to " << error.errorString();
// Due to simultaneous multiple connections, it may be possible that device instance does not exist anymore
Device *device = Daemon::instance()->getDevice(socket->peerVerifyName());
if (device != Q_NULLPTR) {
device->unpair();
}
2015-07-09 22:51:08 +01:00
break;
}
2015-07-09 22:51:08 +01:00
default:
continue;
// Lots of warnings without this
}
}
2015-07-14 13:04:04 +01:00
delete receivedIdentityPackages.take(socket).np;
// Socket disconnects itself on ssl error and will be deleted by deleteLater slot, no need to delete manually
2015-07-05 14:23:53 +01:00
}
2016-03-08 00:01:44 +00:00
void LanLinkProvider::sslErrorsLogButIgnore(const QList<QSslError>& errors)
{
foreach(const QSslError &error, errors) {
qCDebug(KDECONNECT_CORE) << "SSL Error (ignoring):" << error.errorString();
}
}
2015-07-05 14:23:53 +01:00
//I'm the new device and this is the answer to my UDP identity package (no data received yet)
2015-07-09 23:27:27 +01:00
void LanLinkProvider::newConnection()
2013-08-07 10:29:56 +01:00
{
2015-07-14 13:04:04 +01:00
//qCDebug(KDECONNECT_CORE) << "LanLinkProvider newConnection";
2013-08-07 10:29:56 +01:00
2015-07-09 23:27:27 +01:00
while (mServer->hasPendingConnections()) {
QSslSocket* socket = mServer->nextPendingConnection();
configureSocket(socket);
//This socket is still managed by us (and child of the QTcpServer), if
//it disconnects before we manage to pass it to a LanDeviceLink, it's
//our responsibility to delete it. We do so with this connection.
2015-07-09 23:27:27 +01:00
connect(socket, SIGNAL(disconnected()),
socket, SLOT(deleteLater()));
connect(socket, SIGNAL(readyRead()),
this, SLOT(dataReceived()));
2013-08-07 10:29:56 +01:00
2015-07-09 23:27:27 +01:00
}
2013-08-07 10:29:56 +01:00
}
//I'm the new device and this is the answer to my UDP identity package (data received)
2013-08-28 22:47:39 +01:00
void LanLinkProvider::dataReceived()
2013-08-07 10:29:56 +01:00
{
2015-07-05 14:23:53 +01:00
QSslSocket* socket = qobject_cast<QSslSocket*>(sender());
2013-08-07 10:29:56 +01:00
const QByteArray data = socket->readLine();
2013-08-07 10:29:56 +01:00
2016-05-31 19:09:52 +01:00
//qCDebug(KDECONNECT_CORE) << "LanLinkProvider received reply:" << data;
2013-08-07 10:29:56 +01:00
2015-07-05 14:23:53 +01:00
NetworkPackage* np = new NetworkPackage("");
bool success = NetworkPackage::unserialize(data, np);
2015-07-13 15:25:22 +01:00
2015-07-05 14:23:53 +01:00
if (!success || np->type() != PACKAGE_TYPE_IDENTITY) {
qCDebug(KDECONNECT_CORE) << "LanLinkProvider/newConnection: Not an identification package (wuh?)";
return;
}
2013-08-07 10:29:56 +01:00
2015-07-14 13:04:04 +01:00
// Needed in "encrypted" if ssl is used, similar to "connected"
receivedIdentityPackages[socket].np = np;
2015-07-05 14:23:53 +01:00
const QString& deviceId = np->get<QString>("deviceId");
//qCDebug(KDECONNECT_CORE) << "Handshaking done (i'm the new device)";
//This socket will now be owned by the LanDeviceLink or we don't want more data to be received, forget about it
disconnect(socket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
2015-07-05 14:23:53 +01:00
if (NetworkPackage::ProtocolVersion <= np->get<int>("protocolVersion")) {
// since I support ssl and remote device support ssl
2013-08-07 10:29:56 +01:00
2015-07-05 14:23:53 +01:00
bool isDeviceTrusted = KdeConnectConfig::instance()->trustedDevices().contains(deviceId);
socket->setPeerVerifyName(deviceId);
2015-07-05 14:23:53 +01:00
if (isDeviceTrusted) {
2016-03-08 00:01:44 +00:00
qCDebug(KDECONNECT_CORE) << "Device trusted";
2015-11-30 18:36:01 +00:00
QString certString = KdeConnectConfig::instance()->getDeviceProperty(deviceId, "certificate", QString());
2015-07-05 14:23:53 +01:00
socket->addCaCertificate(QSslCertificate(certString.toLatin1()));
socket->setPeerVerifyMode(QSslSocket::VerifyPeer);
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
} else {
2016-03-08 00:01:44 +00:00
qCDebug(KDECONNECT_CORE) << "Device untrusted";
2015-07-05 14:23:53 +01:00
// Do not care about ssl errors here, socket will not be closed due to errors because of query peer
socket->setPeerVerifyMode(QSslSocket::QueryPeer);
2016-03-08 00:01:44 +00:00
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrorsLogButIgnore(QList<QSslError>)));
2015-07-05 14:23:53 +01:00
}
2016-03-08 15:29:34 +00:00
qCDebug(KDECONNECT_CORE) << "Starting client ssl (but I'm the server TCP socket)";
2015-07-05 14:23:53 +01:00
connect(socket, SIGNAL(encrypted()), this, SLOT(encrypted()));
2013-08-07 10:29:56 +01:00
2015-07-05 14:23:53 +01:00
socket->startClientEncryption();
2015-07-14 13:04:04 +01:00
return;
2015-07-05 14:23:53 +01:00
} else {
addLink(deviceId, socket, np, LanDeviceLink::Locally);
2015-07-05 14:23:53 +01:00
}
2015-07-14 13:04:04 +01:00
delete np;
receivedIdentityPackages.remove(socket);
2013-08-07 10:29:56 +01:00
}
void LanLinkProvider::deviceLinkDestroyed(QObject* destroyedDeviceLink)
2013-08-07 10:29:56 +01:00
{
//qCDebug(KDECONNECT_CORE) << "deviceLinkDestroyed";
const QString id = destroyedDeviceLink->property("deviceId").toString();
2015-12-11 01:11:55 +00:00
Q_ASSERT(mLinks.key(static_cast<LanDeviceLink*>(destroyedDeviceLink)) == id);
QMap< QString, LanDeviceLink* >::iterator linkIterator = mLinks.find(id);
if (linkIterator != mLinks.end()) {
Q_ASSERT(linkIterator.value() == destroyedDeviceLink);
mLinks.erase(linkIterator);
2015-12-17 13:54:24 +00:00
mPairingHandlers.remove(id);
}
2013-08-07 10:29:56 +01:00
}
2015-07-05 14:23:53 +01:00
void LanLinkProvider::configureSocket(QSslSocket* socket)
2013-08-07 10:29:56 +01:00
{
2015-04-04 18:05:55 +01:00
int fd = socket->socketDescriptor();
socket->setSocketOption(QAbstractSocket::KeepAliveOption, QVariant(1));
// Setting supported ciphers manually
// Top 3 ciphers are for new Android devices, botton two are for old Android devices
// FIXME : These cipher suites should be checked whether they are supported or not on device
QList<QSslCipher> socketCiphers;
socketCiphers.append(QSslCipher("ECDHE-ECDSA-AES256-GCM-SHA384"));
socketCiphers.append(QSslCipher("ECDHE-ECDSA-AES128-GCM-SHA256"));
socketCiphers.append(QSslCipher("ECDHE-RSA-AES128-SHA"));
socketCiphers.append(QSslCipher("RC4-SHA"));
socketCiphers.append(QSslCipher("RC4-MD5"));
2015-07-05 14:23:53 +01:00
// Configure for ssl
QSslConfiguration sslConfig;
sslConfig.setCiphers(socketCiphers);
sslConfig.setProtocol(QSsl::TlsV1_0);
socket->setSslConfiguration(sslConfig);
2015-07-05 14:23:53 +01:00
socket->setLocalCertificate(KdeConnectConfig::instance()->certificate());
socket->setPrivateKey(KdeConnectConfig::instance()->privateKeyPath());
2015-04-04 18:05:55 +01:00
#ifdef TCP_KEEPIDLE
// time to start sending keepalive packets (seconds)
int maxIdle = 10;
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &maxIdle, sizeof(maxIdle));
#endif
#ifdef TCP_KEEPINTVL
// interval between keepalive packets after the initial period (seconds)
int interval = 5;
setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
#endif
#ifdef TCP_KEEPCNT
// number of missed keepalive packets before disconnecting
int count = 3;
setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &count, sizeof(count));
#endif
2013-08-07 10:29:56 +01:00
}
2015-07-05 14:23:53 +01:00
void LanLinkProvider::addLink(const QString& deviceId, QSslSocket* socket, NetworkPackage* receivedPackage, LanDeviceLink::ConnectionStarted connectionOrigin)
2015-11-30 18:36:01 +00:00
{
// Socket disconnection will now be handled by LanDeviceLink
disconnect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
2015-12-11 01:11:55 +00:00
LanDeviceLink* deviceLink;
//Do we have a link for this device already?
QMap< QString, LanDeviceLink* >::iterator linkIterator = mLinks.find(deviceId);
if (linkIterator != mLinks.end()) {
deviceLink = linkIterator.value();
deviceLink->reset(socket, connectionOrigin);
} else {
deviceLink = new LanDeviceLink(deviceId, this, socket, connectionOrigin);
connect(deviceLink, SIGNAL(destroyed(QObject*)), this, SLOT(deviceLinkDestroyed(QObject*)));
mLinks[deviceId] = deviceLink;
2015-12-17 13:54:24 +00:00
if (mPairingHandlers.contains(deviceId)) {
//We shouldn't have a pairinghandler if we didn't have a link.
//Crash if debug, recover if release (by setting the new devicelink to the old pairinghandler)
Q_ASSERT(mPairingHandlers.contains(deviceId));
mPairingHandlers[deviceId]->setDeviceLink(deviceLink);
}
2015-12-17 15:44:29 +00:00
Q_EMIT onConnectionReceived(*receivedPackage, deviceLink);
2015-07-05 14:23:53 +01:00
}
}
2015-12-01 18:45:14 +00:00
2015-12-17 14:53:29 +00:00
LanPairingHandler* LanLinkProvider::createPairingHandler(DeviceLink* link)
2015-12-01 18:45:14 +00:00
{
2015-12-17 14:53:29 +00:00
LanPairingHandler* ph = mPairingHandlers.value(link->deviceId());
2015-12-01 18:45:14 +00:00
if (!ph) {
2015-12-17 13:54:24 +00:00
ph = new LanPairingHandler(link);
2016-03-08 00:01:44 +00:00
qCDebug(KDECONNECT_CORE) << "creating pairing handler for" << link->deviceId();
2015-12-17 14:53:29 +00:00
connect (ph, &LanPairingHandler::pairingError, link, &DeviceLink::pairingError);
mPairingHandlers[link->deviceId()] = ph;
2015-12-01 18:45:14 +00:00
}
2015-12-17 14:53:29 +00:00
return ph;
}
2015-12-01 18:45:14 +00:00
2015-12-17 14:53:29 +00:00
void LanLinkProvider::userRequestsPair(const QString& deviceId)
{
LanPairingHandler* ph = createPairingHandler(mLinks.value(deviceId));
2015-12-01 18:45:14 +00:00
ph->requestPairing();
}
2015-12-02 19:04:35 +00:00
2016-03-03 00:17:38 +00:00
void LanLinkProvider::userRequestsUnpair(const QString& deviceId)
{
LanPairingHandler* ph = createPairingHandler(mLinks.value(deviceId));
ph->unpair();
}
void LanLinkProvider::incomingPairPackage(DeviceLink* deviceLink, const NetworkPackage& np)
{
2015-12-17 14:53:29 +00:00
LanPairingHandler* ph = createPairingHandler(deviceLink);
ph->packageReceived(np);
}
2015-12-17 13:54:24 +00:00