diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 03b28e78c..ef079aa18 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -12,7 +12,7 @@ option(MDNS_ENABLED "Use MDNS for device discovery" ON) add_subdirectory(backends/lan) add_subdirectory(backends/loopback) -option(BLUETOOTH_ENABLED "Bluetooth support for kdeconnect" OFF) +option(BLUETOOTH_ENABLED "Bluetooth support for kdeconnect" ON) if(BLUETOOTH_ENABLED) find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} REQUIRED COMPONENTS Bluetooth) add_subdirectory(backends/bluetooth) diff --git a/core/backends/bluetooth/bluetoothlinkprovider.cpp b/core/backends/bluetooth/bluetoothlinkprovider.cpp index 44325a950..60fd3f241 100644 --- a/core/backends/bluetooth/bluetoothlinkprovider.cpp +++ b/core/backends/bluetooth/bluetoothlinkprovider.cpp @@ -37,18 +37,23 @@ void BluetoothLinkProvider::onStart() return; } + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::onStart executed"; + mBluetoothServer = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this); mBluetoothServer->setSecurityFlags(QBluetooth::Security::Encryption | QBluetooth::Security::Secure); connect(mBluetoothServer, &QBluetoothServer::newConnection, this, &BluetoothLinkProvider::serverNewConnection); - mServiceDiscoveryAgent->start(); - - connectTimer->start(); + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::About to start server listen"; mKdeconnectService = mBluetoothServer->listen(mServiceUuid, QStringLiteral("KDE Connect")); + + // Disabled for the moment as once the server is listening, the client will not be able to connect anyway + //mServiceDiscoveryAgent->start(); + //connectTimer->start(); } void BluetoothLinkProvider::onStop() { + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::onStop executed"; if (!mBluetoothServer) { return; } @@ -67,15 +72,21 @@ void BluetoothLinkProvider::onNetworkChange() void BluetoothLinkProvider::connectError() { + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::connectError executed"; QBluetoothSocket *socket = qobject_cast(sender()); if (!socket) return; - qCWarning(KDECONNECT_CORE) << "Couldn't connect to socket:" << socket->errorString(); + qCWarning(KDECONNECT_CORE) << "Couldn't connect to bluetooth socket:" << socket->errorString(); disconnect(socket, &QBluetoothSocket::connected, this, nullptr); disconnect(socket, &QBluetoothSocket::readyRead, this, nullptr); + +#if QT_VERSION_MAJOR == 5 disconnect(socket, QOverload::of(&QBluetoothSocket::error), this, nullptr); +#else + disconnect(socket, QOverload::of(&QBluetoothSocket::errorOccurred), this, nullptr); +#endif mSockets.remove(socket->peerAddress()); socket->deleteLater(); @@ -83,42 +94,60 @@ void BluetoothLinkProvider::connectError() void BluetoothLinkProvider::addLink(BluetoothDeviceLink *deviceLink, const QString &deviceId) { - QMap::iterator oldLinkIterator = mLinks.find(deviceId); - delete oldLinkIterator.value(); // not calling deleteLater because this triggers onLinkDestroyed + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::addLink executed"; + if (mLinks.contains(deviceId)) { + delete mLinks.take(deviceId); // not calling deleteLater because this triggers onLinkDestroyed + } mLinks[deviceId] = deviceLink; } void BluetoothLinkProvider::serviceDiscovered(const QBluetoothServiceInfo &old_info) { - auto info = old_info; + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::serviceDiscovered executed "; + + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::serviceDiscovered info: " << old_info.device().address() << old_info.serviceName() << old_info.serviceDescription() << old_info.socketProtocol() << old_info.isValid() << old_info.isComplete() << old_info.isRegistered() << old_info.serviceClassUuids(); + + auto info = *(new QBluetoothServiceInfo(old_info)); info.setServiceUuid(mServiceUuid); if (mSockets.contains(info.device().address())) { + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::serviceDiscovered sockets contains address, returning"; return; } - + + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::serviceDiscovered before creating socket"; QBluetoothSocket *socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol); // Delay before sending data QPointer deleteableSocket = socket; connect(socket, &QBluetoothSocket::connected, this, [this, deleteableSocket]() { QTimer::singleShot(500, this, [this, deleteableSocket]() { + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::serviceDiscovered after delay, executing clientConnected"; clientConnected(deleteableSocket); }); }); - connect(socket, QOverload::of(&QBluetoothSocket::error), this, &BluetoothLinkProvider::connectError); + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::serviceDiscovered about to call connect"; +#if QT_VERSION_MAJOR == 5 + connect(socket, QOverload::of(&QBluetoothSocket::error), this, &BluetoothLinkProvider::connectError); +#else + connect(socket, QOverload::of(&QBluetoothSocket::errorOccurred), this, &BluetoothLinkProvider::connectError); +#endif + + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::serviceDiscovered about to call connectToService"; + socket->connectToService(info); - qCDebug(KDECONNECT_CORE) << "Connecting to" << info.device().address(); + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider Connecting to" << info.device().address(); if (socket->error() != QBluetoothSocket::SocketError::NoSocketError) { - qCWarning(KDECONNECT_CORE) << "Socket connection error:" << socket->errorString(); + qCWarning(KDECONNECT_CORE) << "BluetoothLinkProvider Socket connection error:" << socket->errorString(); } } // I'm the new device and I'm connected to the existing device. Time to get data. void BluetoothLinkProvider::clientConnected(QPointer socket) { + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::clientConnected executed"; if (!socket) return; @@ -155,6 +184,7 @@ void BluetoothLinkProvider::clientConnected(QPointer socket) // I'm the new device and the existing device sent me data. void BluetoothLinkProvider::clientIdentityReceived(const QBluetoothAddress &peer, QSharedPointer socket) { + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::clientIdentityReceived executed"; socket->startTransaction(); QByteArray identityArray = socket->readLine(); @@ -170,14 +200,14 @@ void BluetoothLinkProvider::clientIdentityReceived(const QBluetoothAddress &peer bool success = NetworkPacket::unserialize(identityArray, &receivedPacket); if (!success || receivedPacket.type() != PACKET_TYPE_IDENTITY) { - qCWarning(KDECONNECT_CORE) << "Not an identity packet"; + qCWarning(KDECONNECT_CORE) << "BluetoothLinkProvider Received not an identity packet"; mSockets.remove(peer); socket->close(); socket->deleteLater(); return; } - qCDebug(KDECONNECT_CORE) << "Received identity packet from" << peer; + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider Received identity packet from" << peer; // TODO? // disconnect(socket, &QAbstractSocket::error, this, &BluetoothLinkProvider::connectError); @@ -192,7 +222,7 @@ void BluetoothLinkProvider::clientIdentityReceived(const QBluetoothAddress &peer success = deviceLink->sendPacket(myIdentity); if (success) { - qCDebug(KDECONNECT_CORE) << "Handshaking done (I'm the new device)"; + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider Handshaking done (I'm the new device)"; Q_EMIT onConnectionReceived(deviceLink); @@ -210,9 +240,10 @@ void BluetoothLinkProvider::clientIdentityReceived(const QBluetoothAddress &peer // I'm the existing device, a new device is kindly introducing itself. void BluetoothLinkProvider::serverNewConnection() { + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::serverNewConnection executed"; QBluetoothSocket *socket = mBluetoothServer->nextPendingConnection(); - qCDebug(KDECONNECT_CORE) << "Received connection from" << socket->peerAddress(); + qCDebug(KDECONNECT_CORE) << socket->peerAddress() << "Received connection"; QBluetoothAddress peer = socket->peerAddress(); @@ -225,6 +256,8 @@ void BluetoothLinkProvider::serverNewConnection() ConnectionMultiplexer *multiplexer = new ConnectionMultiplexer(socket, this); + qCDebug(KDECONNECT_CORE) << socket->peerAddress() << "Multiplexer Instantiated"; + mSockets.insert(peer, multiplexer); disconnect(socket, nullptr, this, nullptr); @@ -241,17 +274,22 @@ void BluetoothLinkProvider::serverNewConnection() return; } + qCDebug(KDECONNECT_CORE) << socket->peerAddress() << "Building and sending identity Packet "; + DeviceInfo myDeviceInfo = KdeConnectConfig::instance().deviceInfo(); NetworkPacket myIdentity = myDeviceInfo.toIdentityPacket(); myIdentity.set(QStringLiteral("certificate"), QString::fromLatin1(myDeviceInfo.certificate.toPem())); - socket->write(myIdentity.serialize()); + auto identityPacket = myIdentity.serialize(); - qCDebug(KDECONNECT_CORE) << "Sent identity packet to" << socket->peerAddress(); + channel->write(identityPacket); + + qCDebug(KDECONNECT_CORE) << "Sent identity packet on default channel to" << socket->peerAddress(); } // I'm the existing device and this is the answer to my identity packet (data received) void BluetoothLinkProvider::serverDataReceived(const QBluetoothAddress &peer, QSharedPointer socket) { + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider::serverDataReceived executed"; QByteArray identityArray; socket->startTransaction(); identityArray = socket->readLine(); @@ -295,10 +333,12 @@ void BluetoothLinkProvider::onLinkDestroyed(const QString &deviceId, DeviceLink void BluetoothLinkProvider::socketDisconnected(const QBluetoothAddress &peer, MultiplexChannel *socket) { - qCDebug(KDECONNECT_CORE) << "Disconnected"; + qCDebug(KDECONNECT_CORE) << "BluetoothLinkProvider socketDisconnected"; disconnect(socket, nullptr, this, nullptr); + qCDebug(KDECONNECT_CORE) << "socketDisconnected :: After calling disconnect"; mSockets.remove(peer); + qCDebug(KDECONNECT_CORE) << "socketDisconnected :: After calling remove"; } BluetoothLinkProvider::~BluetoothLinkProvider() diff --git a/core/backends/bluetooth/connectionmultiplexer.cpp b/core/backends/bluetooth/connectionmultiplexer.cpp index 759f54cc4..6745b5825 100644 --- a/core/backends/bluetooth/connectionmultiplexer.cpp +++ b/core/backends/bluetooth/connectionmultiplexer.cpp @@ -44,7 +44,8 @@ ConnectionMultiplexer::ConnectionMultiplexer(QBluetoothSocket *socket, QObject * // Only support version 1 (lowest supported = highest supported = 1) qToBigEndian(1, &message.data()[19]); qToBigEndian(1, &message.data()[21]); - to_write_bytes.append(message); + + socket->write(message); // Send the protocol version message (queued) QMetaObject::invokeMethod(this, &ConnectionMultiplexer::bytesWritten, Qt::QueuedConnection); @@ -125,16 +126,16 @@ bool ConnectionMultiplexer::tryParseMessage() */ char message_type = header[0]; uint16_t message_length = qFromBigEndian(&header.data()[1]); -#if QT_VERSION_MAJOR == 5 + quint128 message_uuid_raw; + #ifndef QT_SUPPORTS_INT128 for (int i = 0; i < 16; ++i) { message_uuid_raw.data[i] = header[3 + i]; } + #else + message_uuid_raw = qFromBigEndian(&header.data()[3]); + #endif QBluetoothUuid message_uuid = QBluetoothUuid(message_uuid_raw); -#else - const QByteArray uuisByteArray = header.sliced(3, 16); // Faster than mid, see https://doc.qt.io/qt-6/qbytearray.html#mid - QBluetoothUuid message_uuid = QBluetoothUuid::fromBytes(uuisByteArray.constData()); -#endif // Check if we have the full message including its data QByteArray data = mSocket->read(message_length); @@ -283,6 +284,7 @@ void ConnectionMultiplexer::addChannel(QBluetoothUuid new_id) closeChannel(new_id); }, Qt::QueuedConnection); + auto channelStatePtr = QSharedPointer{channelState}; channels[new_id] = channelStatePtr; unrequested_channels[new_id] = new MultiplexChannel{channelStatePtr}; diff --git a/daemon/kdeconnectd.cpp b/daemon/kdeconnectd.cpp index c0eea676d..183d21ccf 100644 --- a/daemon/kdeconnectd.cpp +++ b/daemon/kdeconnectd.cpp @@ -202,6 +202,8 @@ int main(int argc, char *argv[]) QObject::connect(&app, &QGuiApplication::commitDataRequest, disableSessionManagement); QObject::connect(&app, &QGuiApplication::saveStateRequest, disableSessionManagement); + qSetMessagePattern(QStringLiteral("%{time} %{category}: %{message}")); + return app.exec(); }