Bluetooth multiplexer integration and assorted fixes

This commit is contained in:
Matthijs Tijink 2019-03-08 19:18:01 +01:00
parent cda1280456
commit 0b6224fc0e
10 changed files with 145 additions and 173 deletions

View file

@ -25,22 +25,24 @@
#include "bluetoothuploadjob.h"
#include "bluetoothdownloadjob.h"
#include "core_debug.h"
#include "connectionmultiplexer.h"
#include "multiplexchannel.h"
BluetoothDeviceLink::BluetoothDeviceLink(const QString& deviceId, LinkProvider* parent, QBluetoothSocket* socket)
BluetoothDeviceLink::BluetoothDeviceLink(const QString& deviceId, LinkProvider* parent, ConnectionMultiplexer* connection, QSharedPointer<MultiplexChannel> socket)
: DeviceLink(deviceId, parent)
, mSocketReader(new DeviceLineReader(socket, this))
, mBluetoothSocket(socket)
, mSocketReader(new DeviceLineReader(socket.data(), this))
, mConnection(connection)
, mChannel(socket)
, mPairingHandler(new BluetoothPairingHandler(this))
{
connect(mSocketReader, SIGNAL(readyRead()),
this, SLOT(dataReceived()));
connect(mSocketReader, &DeviceLineReader::readyRead, this, &BluetoothDeviceLink::dataReceived);
//We take ownership of the socket.
//We take ownership of the connection.
//When the link provider destroys us,
//the socket (and the reader) will be
//destroyed as well
mBluetoothSocket->setParent(this);
connect(mBluetoothSocket, SIGNAL(disconnected()), this, SLOT(deleteLater()));
mConnection->setParent(this);
connect(socket.data(), &MultiplexChannel::aboutToClose, this, &QObject::deleteLater);
}
QString BluetoothDeviceLink::name()
@ -51,10 +53,11 @@ QString BluetoothDeviceLink::name()
bool BluetoothDeviceLink::sendPacket(NetworkPacket& np)
{
if (np.hasPayload()) {
BluetoothUploadJob* uploadJob = new BluetoothUploadJob(np.payload(), mBluetoothSocket->peerAddress(), this);
BluetoothUploadJob* uploadJob = new BluetoothUploadJob(np.payload(), mConnection, this);
np.setPayloadTransferInfo(uploadJob->transferInfo());
uploadJob->start();
}
//TODO: handle too-big packets
int written = mSocketReader->write(np.serialize());
return (written != -1);
}
@ -89,8 +92,7 @@ void BluetoothDeviceLink::dataReceived()
}
if (packet.hasPayloadTransferInfo()) {
BluetoothDownloadJob* downloadJob = new BluetoothDownloadJob(mBluetoothSocket->peerAddress(),
packet.payloadTransferInfo(), this);
BluetoothDownloadJob* downloadJob = new BluetoothDownloadJob(mConnection, packet.payloadTransferInfo(), this);
downloadJob->start();
packet.setPayload(downloadJob->payload(), packet.payloadSize());
}
@ -98,6 +100,6 @@ void BluetoothDeviceLink::dataReceived()
Q_EMIT receivedPacket(packet);
if (mSocketReader->bytesAvailable() > 0) {
QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, &BluetoothDeviceLink::dataReceived, Qt::QueuedConnection);
}
}

View file

@ -29,13 +29,16 @@
#include "../devicelinereader.h"
#include "bluetoothpairinghandler.h"
class ConnectionMultiplexer;
class MultiplexChannel;
class KDECONNECTCORE_EXPORT BluetoothDeviceLink
: public DeviceLink
{
Q_OBJECT
public:
BluetoothDeviceLink(const QString& deviceId, LinkProvider* parent, QBluetoothSocket* socket);
BluetoothDeviceLink(const QString& deviceId, LinkProvider* parent, ConnectionMultiplexer* connection, QSharedPointer<MultiplexChannel> socket);
virtual QString name() override;
bool sendPacket(NetworkPacket& np) override;
@ -50,7 +53,8 @@ private Q_SLOTS:
private:
DeviceLineReader* mSocketReader;
QBluetoothSocket* mBluetoothSocket;
ConnectionMultiplexer* mConnection;
QSharedPointer<MultiplexChannel> mChannel;
BluetoothPairingHandler* mPairingHandler;
void sendMessage(const QString mMessage);

View file

@ -19,13 +19,14 @@
*/
#include "bluetoothdownloadjob.h"
#include "connectionmultiplexer.h"
#include "multiplexchannel.h"
BluetoothDownloadJob::BluetoothDownloadJob(const QBluetoothAddress& remoteAddress, const QVariantMap& transferInfo, QObject* parent)
BluetoothDownloadJob::BluetoothDownloadJob(ConnectionMultiplexer *connection, const QVariantMap& transferInfo, QObject* parent)
: QObject(parent)
, mRemoteAddress(remoteAddress)
, mTransferUuid(QBluetoothUuid(transferInfo.value(QStringLiteral("uuid")).toString()))
, mSocket(new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol))
{
QBluetoothUuid id{transferInfo.value(QStringLiteral("uuid")).toString()};
mSocket = QSharedPointer<MultiplexChannel>{connection->getChannel(id).release()};
}
QSharedPointer<QIODevice> BluetoothDownloadJob::payload() const
@ -35,7 +36,4 @@ QSharedPointer<QIODevice> BluetoothDownloadJob::payload() const
void BluetoothDownloadJob::start()
{
connect(mSocket.data(), &QBluetoothSocket::disconnected, mSocket.data(), &QBluetoothSocket::readyRead);
connect(mSocket.data(), &QBluetoothSocket::disconnected, mSocket.data(), &QBluetoothSocket::readChannelFinished);
mSocket->connectToService(mRemoteAddress, mTransferUuid, QIODevice::ReadOnly);
}

View file

@ -29,19 +29,20 @@
#include <QBluetoothUuid>
#include <QBluetoothSocket>
class ConnectionMultiplexer;
class MultiplexChannel;
class BluetoothDownloadJob
: public QObject
{
Q_OBJECT
public:
explicit BluetoothDownloadJob(const QBluetoothAddress& remoteAddress, const QVariantMap& transferInfo, QObject* parent = 0);
explicit BluetoothDownloadJob(ConnectionMultiplexer *connection, const QVariantMap& transferInfo, QObject* parent = 0);
QSharedPointer<QIODevice> payload() const;
void start();
private:
QBluetoothAddress mRemoteAddress;
QBluetoothUuid mTransferUuid;
QSharedPointer<QBluetoothSocket> mSocket;
QSharedPointer<MultiplexChannel> mSocket;
};
#endif // BLUETOOTHDOWNLOADJOB_H

View file

@ -20,6 +20,8 @@
#include "bluetoothlinkprovider.h"
#include "core_debug.h"
#include "connectionmultiplexer.h"
#include "multiplexchannel.h"
#include <KSharedConfig>
#include <KConfigGroup>
@ -42,8 +44,11 @@ BluetoothLinkProvider::BluetoothLinkProvider()
mServiceDiscoveryAgent = new QBluetoothServiceDiscoveryAgent(this);
mServiceDiscoveryAgent->setUuidFilter(mServiceUuid);
connect(mServiceDiscoveryAgent, SIGNAL(finished()), this, SLOT(serviceDiscoveryFinished()));
connect(connectTimer, SIGNAL(timeout()), mServiceDiscoveryAgent, SLOT(start()));
connect(connectTimer, &QTimer::timeout, this, [this]() {
mServiceDiscoveryAgent->start();
});
connect(mServiceDiscoveryAgent, &QBluetoothServiceDiscoveryAgent::serviceDiscovered, this, &BluetoothLinkProvider::serviceDiscovered);
}
void BluetoothLinkProvider::onStart()
@ -111,95 +116,94 @@ void BluetoothLinkProvider::addLink(BluetoothDeviceLink* deviceLink, const QStri
mLinks[deviceId] = deviceLink;
}
//I'm the new device and I found an existing device
void BluetoothLinkProvider::serviceDiscoveryFinished()
{
const QList<QBluetoothServiceInfo> services = mServiceDiscoveryAgent->discoveredServices();
void BluetoothLinkProvider::serviceDiscovered(const QBluetoothServiceInfo& old_info) {
auto info = old_info;
info.setServiceUuid(mServiceUuid);
if (mSockets.contains(info.device().address())) {
return;
}
for (QBluetoothServiceInfo info : services) {
if (mSockets.contains(info.device().address())) {
continue;
}
QBluetoothSocket* socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
QBluetoothSocket* socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
//Delay before sending data
QPointer<QBluetoothSocket> deleteableSocket = socket;
connect(socket, &QBluetoothSocket::connected, this, [this,deleteableSocket]() {
QTimer::singleShot(500, this, [this,deleteableSocket]() {
clientConnected(deleteableSocket);
});
});
connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(connectError()));
connect(socket, SIGNAL(connected()), this, SLOT(clientConnected()));
connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(connectError()));
socket->connectToService(info);
socket->connectToService(info);
qCDebug(KDECONNECT_CORE()) << "Connecting to" << info.device().address();
qCDebug(KDECONNECT_CORE()) << "Connecting to" << info.device().address();
if (socket->error() != QBluetoothSocket::NoSocketError) {
qCWarning(KDECONNECT_CORE) << "Socket connection error:" << socket->errorString();
}
if (socket->error() != QBluetoothSocket::NoSocketError) {
qCWarning(KDECONNECT_CORE) << "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()
void BluetoothLinkProvider::clientConnected(QPointer<QBluetoothSocket> socket)
{
QBluetoothSocket* socket = qobject_cast<QBluetoothSocket*>(sender());
if (!socket) return;
qCDebug(KDECONNECT_CORE()) << "Connected to" << socket->peerAddress();
auto peer = socket->peerAddress();
qCDebug(KDECONNECT_CORE()) << "Connected to" << peer;
if (mSockets.contains(socket->peerAddress())) {
qCWarning(KDECONNECT_CORE()) << "Duplicate connection to" << socket->peerAddress();
qCWarning(KDECONNECT_CORE()) << "Duplicate connection to" << peer;
socket->close();
socket->deleteLater();
return;
}
mSockets.insert(socket->peerAddress(), socket);
ConnectionMultiplexer *multiplexer = new ConnectionMultiplexer(socket, this);
disconnect(socket, SIGNAL(connected()), this, SLOT(clientConnected()));
mSockets.insert(peer, multiplexer);
disconnect(socket, nullptr, this, nullptr);
connect(socket, SIGNAL(readyRead()), this, SLOT(clientIdentityReceived()));
connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
auto channel = QSharedPointer<MultiplexChannel>{multiplexer->getDefaultChannel().release()};
connect(channel.data(), &MultiplexChannel::readyRead, this, [this,peer,channel] () { clientIdentityReceived(peer, channel); });
connect(channel.data(), &MultiplexChannel::aboutToClose, this, [this,peer,channel] () { socketDisconnected(peer, channel.data()); });
if (channel->bytesAvailable()) clientIdentityReceived(peer, channel);
if (!channel->isOpen()) socketDisconnected(peer, channel.data());
}
//I'm the new device and the existing device sent me data.
void BluetoothLinkProvider::clientIdentityReceived()
void BluetoothLinkProvider::clientIdentityReceived(const QBluetoothAddress &peer, QSharedPointer<MultiplexChannel> socket)
{
QBluetoothSocket* socket = qobject_cast<QBluetoothSocket*>(sender());
if (!socket) return;
socket->startTransaction();
QByteArray identityArray;
if (socket->property("identityArray").isValid()) {
identityArray = socket->property("identityArray").toByteArray();
}
while (!identityArray.contains('\n') && socket->bytesAvailable() > 0) {
identityArray += socket->readAll();
}
if (!identityArray.contains('\n')) {
// This method will get retriggered when more data is available.
socket->setProperty("identityArray", identityArray);
QByteArray identityArray = socket->readLine();
if (identityArray.isEmpty()) {
socket->rollbackTransaction();
return;
}
socket->setProperty("identityArray", QVariant());
socket->commitTransaction();
disconnect(socket, SIGNAL(readyRead()), this, SLOT(clientIdentityReceived()));
disconnect(socket.data(), &MultiplexChannel::readyRead, this, nullptr);
NetworkPacket receivedPacket;
bool success = NetworkPacket::unserialize(identityArray, &receivedPacket);
if (!success || receivedPacket.type() != PACKET_TYPE_IDENTITY) {
qCWarning(KDECONNECT_CORE) << "Not an identity packet";
mSockets.remove(socket->peerAddress());
mSockets.remove(peer);
socket->close();
socket->deleteLater();
return;
}
qCDebug(KDECONNECT_CORE()) << "Received identity packet from" << socket->peerAddress();
qCDebug(KDECONNECT_CORE()) << "Received identity packet from" << peer;
disconnect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(connectError()));
//TODO?
//disconnect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(connectError()));
const QString& deviceId = receivedPacket.get<QString>(QStringLiteral("deviceId"));
BluetoothDeviceLink* deviceLink = new BluetoothDeviceLink(deviceId, this, socket);
BluetoothDeviceLink* deviceLink = new BluetoothDeviceLink(deviceId, this, mSockets[peer], socket);
NetworkPacket np2;
NetworkPacket::createIdentityPacket(&np2);
@ -232,65 +236,66 @@ void BluetoothLinkProvider::serverNewConnection()
qCDebug(KDECONNECT_CORE()) << "Received connection from" << socket->peerAddress();
if (mSockets.contains(socket->peerAddress())) {
qCDebug(KDECONNECT_CORE()) << "Duplicate connection from" << socket->peerAddress();
QBluetoothAddress peer = socket->peerAddress();
if (mSockets.contains(peer)) {
qCDebug(KDECONNECT_CORE()) << "Duplicate connection from" << peer;
socket->close();
socket->deleteLater();
return;
}
connect(socket, SIGNAL(readyRead()), this, SLOT(serverDataReceived()));
connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(connectError()));
connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
ConnectionMultiplexer *multiplexer = new ConnectionMultiplexer(socket, this);
mSockets.insert(peer, multiplexer);
disconnect(socket, nullptr, this, nullptr);
auto channel = QSharedPointer<MultiplexChannel>{multiplexer->getDefaultChannel().release()};
connect(channel.data(), &MultiplexChannel::readyRead, this, [this,peer,channel] () { serverDataReceived(peer, channel); });
connect(channel.data(), &MultiplexChannel::aboutToClose, this, [this,peer,channel] () { socketDisconnected(peer, channel.data()); });
if (!channel->isOpen()) {
socketDisconnected(peer, channel.data());
return;
}
NetworkPacket np2;
NetworkPacket::createIdentityPacket(&np2);
socket->write(np2.serialize());
qCDebug(KDECONNECT_CORE()) << "Sent identity packet to" << socket->peerAddress();
mSockets.insert(socket->peerAddress(), socket);
}
//I'm the existing device and this is the answer to my identity packet (data received)
void BluetoothLinkProvider::serverDataReceived()
void BluetoothLinkProvider::serverDataReceived(const QBluetoothAddress &peer, QSharedPointer<MultiplexChannel> socket)
{
QBluetoothSocket* socket = qobject_cast<QBluetoothSocket*>(sender());
if (!socket) return;
QByteArray identityArray;
if (socket->property("identityArray").isValid()) {
identityArray = socket->property("identityArray").toByteArray();
}
socket->startTransaction();
identityArray = socket->readLine();
while (!identityArray.contains('\n') && socket->bytesAvailable() > 0) {
identityArray += socket->readAll();
}
if (!identityArray.contains('\n')) {
// This method will get retriggered when more data is available.
socket->setProperty("identityArray", identityArray);
if (identityArray.isEmpty()) {
socket->rollbackTransaction();
return;
}
socket->setProperty("identityArray", QVariant());
socket->commitTransaction();
disconnect(socket, SIGNAL(readyRead()), this, SLOT(serverDataReceived()));
disconnect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(connectError()));
disconnect(socket.data(), &MultiplexChannel::readyRead, this, nullptr);
NetworkPacket receivedPacket;
bool success = NetworkPacket::unserialize(identityArray, &receivedPacket);
if (!success || receivedPacket.type() != PACKET_TYPE_IDENTITY) {
qCWarning(KDECONNECT_CORE) << "Not an identity packet.";
mSockets.remove(socket->peerAddress());
mSockets.remove(peer);
socket->close();
socket->deleteLater();
return;
}
qCDebug(KDECONNECT_CORE()) << "Received identity packet from" << socket->peerAddress();
qCDebug(KDECONNECT_CORE()) << "Received identity packet from" << peer;
const QString& deviceId = receivedPacket.get<QString>(QStringLiteral("deviceId"));
BluetoothDeviceLink* deviceLink = new BluetoothDeviceLink(deviceId, this, socket);
BluetoothDeviceLink* deviceLink = new BluetoothDeviceLink(deviceId, this, mSockets[peer], socket);
connect(deviceLink, SIGNAL(destroyed(QObject*)),
this, SLOT(deviceLinkDestroyed(QObject*)));
@ -310,14 +315,12 @@ void BluetoothLinkProvider::deviceLinkDestroyed(QObject* destroyedDeviceLink)
}
}
void BluetoothLinkProvider::socketDisconnected()
void BluetoothLinkProvider::socketDisconnected(const QBluetoothAddress &peer, MultiplexChannel *socket)
{
QBluetoothSocket* socket = qobject_cast<QBluetoothSocket*>(sender());
if (!socket) return;
qCDebug(KDECONNECT_CORE()) << "Disconnected";
disconnect(socket, nullptr, this, nullptr);
disconnect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
mSockets.remove(mSockets.key(socket));
mSockets.remove(peer);
}
BluetoothLinkProvider::~BluetoothLinkProvider()

View file

@ -35,6 +35,8 @@
#include "../linkprovider.h"
class BluetoothDeviceLink;
class ConnectionMultiplexer;
class MultiplexChannel;
class KDECONNECTCORE_EXPORT BluetoothLinkProvider
: public LinkProvider
@ -53,16 +55,17 @@ public Q_SLOTS:
virtual void onStart() override;
virtual void onStop() override;
void connectError();
void serviceDiscoveryFinished();
private Q_SLOTS:
void deviceLinkDestroyed(QObject* destroyedDeviceLink);
void socketDisconnected();
void socketDisconnected(const QBluetoothAddress &peerAddress, MultiplexChannel *socket);
void serverNewConnection();
void serverDataReceived();
void clientConnected();
void clientIdentityReceived();
void serverDataReceived(const QBluetoothAddress &peerAddress, QSharedPointer<MultiplexChannel> socket);
void clientConnected(QPointer<QBluetoothSocket> socket);
void clientIdentityReceived(const QBluetoothAddress &peerAddress, QSharedPointer<MultiplexChannel> socket);
void serviceDiscovered(const QBluetoothServiceInfo &info);
private:
void addLink(BluetoothDeviceLink* deviceLink, const QString& deviceId);
@ -76,7 +79,7 @@ private:
QMap<QString, DeviceLink*> mLinks;
QMap<QBluetoothAddress, QBluetoothSocket*> mSockets;
QMap<QBluetoothAddress, ConnectionMultiplexer*> mSockets;
};

View file

@ -20,19 +20,19 @@
*/
#include "bluetoothuploadjob.h"
#include "connectionmultiplexer.h"
#include "multiplexchannel.h"
#include <QBluetoothSocket>
#include "core_debug.h"
#include <QCoreApplication>
BluetoothUploadJob::BluetoothUploadJob(const QSharedPointer<QIODevice>& data, const QBluetoothAddress& remoteAddress, QObject* parent)
BluetoothUploadJob::BluetoothUploadJob(const QSharedPointer<QIODevice>& data, ConnectionMultiplexer *connection, QObject* parent)
: QObject(parent)
, mData(data)
, mRemoteAddress(remoteAddress)
, mTransferUuid(QBluetoothUuid::createUuid())
, mServer(new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this))
, mTransferUuid(connection->newChannel())
{
mServer->setSecurityFlags(QBluetooth::Encryption | QBluetooth::Secure);
mSocket = QSharedPointer<MultiplexChannel>{connection->getChannel(mTransferUuid).release()};
}
QVariantMap BluetoothUploadJob::transferInfo() const
@ -44,45 +44,20 @@ QVariantMap BluetoothUploadJob::transferInfo() const
void BluetoothUploadJob::start()
{
connect(mServer, &QBluetoothServer::newConnection, this, &BluetoothUploadJob::newConnection);
mServiceInfo = mServer->listen(mTransferUuid, QStringLiteral("KDE Connect Transfer Job"));
Q_ASSERT(mServiceInfo.isValid());
}
void BluetoothUploadJob::newConnection()
{
m_socket = mServer->nextPendingConnection();
Q_ASSERT(m_socket);
m_socket->setParent(this);
connect(m_socket, &QBluetoothSocket::disconnected, this, &BluetoothUploadJob::deleteLater);
if (m_socket->peerAddress() != mRemoteAddress) {
m_socket->close();
} else {
mServer->close();
disconnect(mServer, &QBluetoothServer::newConnection, this, &BluetoothUploadJob::newConnection);
mServiceInfo.unregisterService();
if (!mData->open(QIODevice::ReadOnly)) {
qCWarning(KDECONNECT_CORE) << "error when opening the input to upload";
m_socket->close();
deleteLater();
return;
}
if (!mData->open(QIODevice::ReadOnly)) {
qCWarning(KDECONNECT_CORE) << "error when opening the input to upload";
return; //TODO: Handle error, clean up...
}
connect(m_socket, &QBluetoothSocket::bytesWritten, this, &BluetoothUploadJob::writeSome);
connect(m_socket, &QBluetoothSocket::disconnected, this, &BluetoothUploadJob::closeConnection);
connect(mSocket.data(), &MultiplexChannel::bytesWritten, this, &BluetoothUploadJob::writeSome);
connect(mSocket.data(), &MultiplexChannel::aboutToClose, this, &BluetoothUploadJob::closeConnection);
writeSome();
}
void BluetoothUploadJob::writeSome() {
Q_ASSERT(m_socket);
bool errorOccurred = false;
while (m_socket->bytesToWrite() == 0 && mData->bytesAvailable() && m_socket->isWritable()) {
while (mSocket->bytesToWrite() == 0 && mData->bytesAvailable() && mSocket->isWritable()) {
qint64 bytes = qMin<qint64>(mData->bytesAvailable(), 4096);
int bytesWritten = m_socket->write(mData->read(bytes));
int bytesWritten = mSocket->write(mData->read(bytes));
if (bytesWritten < 0) {
qCWarning(KDECONNECT_CORE()) << "error when writing data to bluetooth upload" << bytes << mData->bytesAvailable();
@ -92,18 +67,8 @@ void BluetoothUploadJob::writeSome() {
}
if (mData->atEnd() || errorOccurred) {
disconnect(m_socket, &QBluetoothSocket::bytesWritten, this, &BluetoothUploadJob::writeSome);
mData->close();
connect(m_socket, &QBluetoothSocket::bytesWritten, this, &BluetoothUploadJob::finishWrites);
finishWrites();
}
}
void BluetoothUploadJob::finishWrites() {
Q_ASSERT(m_socket);
if (m_socket->bytesToWrite() == 0) {
closeConnection();
mSocket->close();
}
}

View file

@ -30,30 +30,28 @@
#include <QBluetoothUuid>
#include <QBluetoothServer>
class ConnectionMultiplexer;
class MultiplexChannel;
class BluetoothUploadJob
: public QObject
{
Q_OBJECT
public:
explicit BluetoothUploadJob(const QSharedPointer<QIODevice>& data, const QBluetoothAddress& remoteAddress, QObject* parent = 0);
explicit BluetoothUploadJob(const QSharedPointer<QIODevice>& data, ConnectionMultiplexer *connection, QObject* parent = 0);
QVariantMap transferInfo() const;
void start();
private:
QSharedPointer<QIODevice> mData;
QBluetoothAddress mRemoteAddress;
QBluetoothUuid mTransferUuid;
QBluetoothServer* mServer;
QBluetoothServiceInfo mServiceInfo;
QBluetoothSocket* m_socket;
QSharedPointer<MultiplexChannel> mSocket;
void closeConnection();
private Q_SLOTS:
void newConnection();
void writeSome();
void finishWrites();
};
#endif // BLUETOOTHUPLOADJOB_H

View file

@ -31,7 +31,7 @@
/**
* The default channel uuid. This channel is opened implicitely (without communication).
*/
constexpr const char DEFAULT_CHANNEL_UUID[] = "a0d0aaf4-1072-4d81-aa35-902a954b1266";
#define DEFAULT_CHANNEL_UUID "a0d0aaf4-1072-4d81-aa35-902a954b1266"
//Message type constants
constexpr char MESSAGE_PROTOCOL_VERSION = 0;
@ -60,7 +60,7 @@ ConnectionMultiplexer::ConnectionMultiplexer(QBluetoothSocket *socket, QObject *
QMetaObject::invokeMethod(this, &ConnectionMultiplexer::bytesWritten, Qt::QueuedConnection);
//Always open the default channel
addChannel(QBluetoothUuid{QString{DEFAULT_CHANNEL_UUID}});
addChannel(QBluetoothUuid{QStringLiteral(DEFAULT_CHANNEL_UUID)});
//Immediately check if we can read stuff ("readyRead" may not be called in that case)
if (mSocket->bytesAvailable()) {
@ -283,7 +283,7 @@ std::unique_ptr<MultiplexChannel> ConnectionMultiplexer::getChannel(QBluetoothUu
}
std::unique_ptr<MultiplexChannel> ConnectionMultiplexer::getDefaultChannel() {
return getChannel(QBluetoothUuid{QString{DEFAULT_CHANNEL_UUID}});
return getChannel(QBluetoothUuid{QStringLiteral(DEFAULT_CHANNEL_UUID)});
}
void ConnectionMultiplexer::bytesWritten() {

View file

@ -25,10 +25,8 @@ DeviceLineReader::DeviceLineReader(QIODevice* device, QObject* parent)
: QObject(parent)
, m_device(device)
{
connect(m_device, SIGNAL(readyRead()),
this, SLOT(dataReceived()));
connect(m_device, SIGNAL(disconnected()),
this, SIGNAL(disconnected()));
connect(m_device, &QIODevice::readyRead, this, &DeviceLineReader::dataReceived);
connect(m_device, &QIODevice::aboutToClose, this, &DeviceLineReader::disconnected);
}
void DeviceLineReader::dataReceived()