Add two new external libraries. SimpleCrypt is used to encrypt passwords, QMQTT is an MQTT
library that I was able to integrate into the codebase so there aren't any external dependencies. Both external projects have their own open source licenses. Those licenses are included. Also in this commit is some preliminary work to start adding MQTT support to SavvyCAN.
This commit is contained in:
+35
-1
@@ -4,11 +4,12 @@
|
|||||||
#
|
#
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
|
|
||||||
QT = core gui printsupport qml serialbus serialport widgets help
|
QT = core gui printsupport qml serialbus serialport widgets help network
|
||||||
|
|
||||||
CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
|
CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
|
||||||
|
|
||||||
CONFIG += c++11
|
CONFIG += c++11
|
||||||
|
CONFIG += NO_UNIT_TESTS
|
||||||
|
|
||||||
DEFINES += QCUSTOMPLOT_USE_OPENGL
|
DEFINES += QCUSTOMPLOT_USE_OPENGL
|
||||||
|
|
||||||
@@ -16,9 +17,22 @@ TARGET = SavvyCAN
|
|||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|
||||||
SOURCES += main.cpp\
|
SOURCES += main.cpp\
|
||||||
|
mqtt/qmqtt_client.cpp \
|
||||||
|
mqtt/qmqtt_client_p.cpp \
|
||||||
|
mqtt/qmqtt_frame.cpp \
|
||||||
|
mqtt/qmqtt_message.cpp \
|
||||||
|
mqtt/qmqtt_network.cpp \
|
||||||
|
mqtt/qmqtt_router.cpp \
|
||||||
|
mqtt/qmqtt_routesubscription.cpp \
|
||||||
|
mqtt/qmqtt_socket.cpp \
|
||||||
|
mqtt/qmqtt_ssl_socket.cpp \
|
||||||
|
mqtt/qmqtt_timer.cpp \
|
||||||
|
mqtt/qmqtt_websocket.cpp \
|
||||||
|
mqtt/qmqtt_websocketiodevice.cpp \
|
||||||
re/dbccomparatorwindow.cpp \
|
re/dbccomparatorwindow.cpp \
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
canframemodel.cpp \
|
canframemodel.cpp \
|
||||||
|
simplecrypt.cpp \
|
||||||
utility.cpp \
|
utility.cpp \
|
||||||
qcustomplot.cpp \
|
qcustomplot.cpp \
|
||||||
frameplaybackwindow.cpp \
|
frameplaybackwindow.cpp \
|
||||||
@@ -77,7 +91,27 @@ SOURCES += main.cpp\
|
|||||||
HEADERS += mainwindow.h \
|
HEADERS += mainwindow.h \
|
||||||
can_structs.h \
|
can_structs.h \
|
||||||
canframemodel.h \ \
|
canframemodel.h \ \
|
||||||
|
mqtt/qmqtt.h \
|
||||||
|
mqtt/qmqtt_client.h \
|
||||||
|
mqtt/qmqtt_client_p.h \
|
||||||
|
mqtt/qmqtt_frame.h \
|
||||||
|
mqtt/qmqtt_global.h \
|
||||||
|
mqtt/qmqtt_message.h \
|
||||||
|
mqtt/qmqtt_message_p.h \
|
||||||
|
mqtt/qmqtt_network_p.h \
|
||||||
|
mqtt/qmqtt_networkinterface.h \
|
||||||
|
mqtt/qmqtt_routedmessage.h \
|
||||||
|
mqtt/qmqtt_router.h \
|
||||||
|
mqtt/qmqtt_routesubscription.h \
|
||||||
|
mqtt/qmqtt_socket_p.h \
|
||||||
|
mqtt/qmqtt_socketinterface.h \
|
||||||
|
mqtt/qmqtt_ssl_socket_p.h \
|
||||||
|
mqtt/qmqtt_timer_p.h \
|
||||||
|
mqtt/qmqtt_timerinterface.h \
|
||||||
|
mqtt/qmqtt_websocket_p.h \
|
||||||
|
mqtt/qmqtt_websocketiodevice_p.h \
|
||||||
re/dbccomparatorwindow.h \
|
re/dbccomparatorwindow.h \
|
||||||
|
simplecrypt.h \
|
||||||
utility.h \
|
utility.h \
|
||||||
qcustomplot.h \
|
qcustomplot.h \
|
||||||
frameplaybackwindow.h \
|
frameplaybackwindow.h \
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace CANCon {
|
|||||||
KVASER,
|
KVASER,
|
||||||
SERIALBUS,
|
SERIALBUS,
|
||||||
REMOTE,
|
REMOTE,
|
||||||
|
MQTT,
|
||||||
NONE
|
NONE
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ NewConnectionDialog::NewConnectionDialog(QVector<QString>* ips, QWidget *parent)
|
|||||||
connect(ui->rbGVRET, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
|
connect(ui->rbGVRET, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
|
||||||
connect(ui->rbSocketCAN, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
|
connect(ui->rbSocketCAN, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
|
||||||
connect(ui->rbRemote, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
|
connect(ui->rbRemote, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
|
||||||
|
connect(ui->rbMQTT, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
|
||||||
|
|
||||||
connect(ui->cbDeviceType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NewConnectionDialog::handleDeviceTypeChanged);
|
connect(ui->cbDeviceType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NewConnectionDialog::handleDeviceTypeChanged);
|
||||||
connect(ui->btnOK, &QPushButton::clicked, this, &NewConnectionDialog::handleCreateButton);
|
connect(ui->btnOK, &QPushButton::clicked, this, &NewConnectionDialog::handleCreateButton);
|
||||||
|
|
||||||
@@ -50,6 +52,7 @@ void NewConnectionDialog::handleConnTypeChanged()
|
|||||||
if (ui->rbGVRET->isChecked()) selectSerial();
|
if (ui->rbGVRET->isChecked()) selectSerial();
|
||||||
if (ui->rbSocketCAN->isChecked()) selectSocketCan();
|
if (ui->rbSocketCAN->isChecked()) selectSocketCan();
|
||||||
if (ui->rbRemote->isChecked()) selectRemote();
|
if (ui->rbRemote->isChecked()) selectRemote();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewConnectionDialog::handleDeviceTypeChanged()
|
void NewConnectionDialog::handleDeviceTypeChanged()
|
||||||
@@ -102,6 +105,14 @@ void NewConnectionDialog::selectRemote()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NewConnectionDialog::selectMQTT()
|
||||||
|
{
|
||||||
|
ui->lPort->setText("Topic Name:");
|
||||||
|
ui->lblDeviceType->setHidden(true);
|
||||||
|
ui->cbDeviceType->setHidden(true);
|
||||||
|
ui->cbPort->clear();
|
||||||
|
}
|
||||||
|
|
||||||
void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QString pDriver)
|
void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QString pDriver)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -156,6 +167,7 @@ QString NewConnectionDialog::getPortName()
|
|||||||
case CANCon::GVRET_SERIAL:
|
case CANCon::GVRET_SERIAL:
|
||||||
case CANCon::SERIALBUS:
|
case CANCon::SERIALBUS:
|
||||||
case CANCon::REMOTE:
|
case CANCon::REMOTE:
|
||||||
|
case CANCon::MQTT:
|
||||||
return ui->cbPort->currentText();
|
return ui->cbPort->currentText();
|
||||||
default:
|
default:
|
||||||
qDebug() << "getPortName: can't get port";
|
qDebug() << "getPortName: can't get port";
|
||||||
@@ -178,6 +190,7 @@ CANCon::type NewConnectionDialog::getConnectionType()
|
|||||||
if (ui->rbGVRET->isChecked()) return CANCon::GVRET_SERIAL;
|
if (ui->rbGVRET->isChecked()) return CANCon::GVRET_SERIAL;
|
||||||
if (ui->rbSocketCAN->isChecked()) return CANCon::SERIALBUS;
|
if (ui->rbSocketCAN->isChecked()) return CANCon::SERIALBUS;
|
||||||
if (ui->rbRemote->isChecked()) return CANCon::REMOTE;
|
if (ui->rbRemote->isChecked()) return CANCon::REMOTE;
|
||||||
|
if (ui->rbMQTT->isChecked()) return CANCon::MQTT;
|
||||||
qDebug() << "getConnectionType: error";
|
qDebug() << "getConnectionType: error";
|
||||||
|
|
||||||
return CANCon::NONE;
|
return CANCon::NONE;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ private:
|
|||||||
void selectKvaser();
|
void selectKvaser();
|
||||||
void selectSocketCan();
|
void selectSocketCan();
|
||||||
void selectRemote();
|
void selectRemote();
|
||||||
|
void selectMQTT();
|
||||||
bool isSerialBusAvailable();
|
bool isSerialBusAvailable();
|
||||||
void setPortName(CANCon::type pType, QString pPortName, QString pDriver);
|
void setPortName(CANCon::type pType, QString pPortName, QString pDriver);
|
||||||
};
|
};
|
||||||
|
|||||||
+18
-5
@@ -1,8 +1,13 @@
|
|||||||
#include "mainsettingsdialog.h"
|
#include "mainsettingsdialog.h"
|
||||||
#include "ui_mainsettingsdialog.h"
|
#include "ui_mainsettingsdialog.h"
|
||||||
#include "helpwindow.h"
|
#include "helpwindow.h"
|
||||||
|
|
||||||
#include <qevent.h>
|
#include <qevent.h>
|
||||||
|
#include "simplecrypt.h"
|
||||||
|
|
||||||
|
//using this simple encryption library to obfuscate stored password a bit. It's not super secure but better than
|
||||||
|
//storing a password in straight plaintext. You have the source to this application anyway, whatever algorithm used,
|
||||||
|
//whatever key, you'd see it. Just behave yourselves
|
||||||
|
SimpleCrypt crypto(Q_UINT64_C(0xdeadbeefface6285));
|
||||||
|
|
||||||
MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
@@ -11,6 +16,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
|||||||
QSettings settings;
|
QSettings settings;
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
//TODO: This is still hard coded to support only two buses. Sometimes there is none, sometimes 1, sometimes much more than 2. Fix this.
|
||||||
ui->comboSendingBus->addItem(tr("None"));
|
ui->comboSendingBus->addItem(tr("None"));
|
||||||
ui->comboSendingBus->addItem(tr("0"));
|
ui->comboSendingBus->addItem(tr("0"));
|
||||||
ui->comboSendingBus->addItem(tr("1"));
|
ui->comboSendingBus->addItem(tr("1"));
|
||||||
@@ -30,8 +36,12 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
|||||||
ui->spinPlaybackSpeed->setValue(settings.value("Playback/DefSpeed", 5).toInt());
|
ui->spinPlaybackSpeed->setValue(settings.value("Playback/DefSpeed", 5).toInt());
|
||||||
ui->lineClockFormat->setText(settings.value("Main/TimeFormat", "MMM-dd HH:mm:ss.zzz").toString());
|
ui->lineClockFormat->setText(settings.value("Main/TimeFormat", "MMM-dd HH:mm:ss.zzz").toString());
|
||||||
ui->lineRemoteHost->setText(settings.value("Remote/Host", "api.savvycan.com").toString());
|
ui->lineRemoteHost->setText(settings.value("Remote/Host", "api.savvycan.com").toString());
|
||||||
ui->lineRemotePort->setText(settings.value("Remote/Port", "21315").toString()); // = 0x5343 = SC. Yep, really creative port number
|
ui->lineRemotePort->setText(settings.value("Remote/Port", "8883").toString()); //default port for SSL enabled MQTT
|
||||||
ui->cbAutoStartRemote->setChecked(settings.value("Remote/AutoStart", false).toBool());
|
ui->lineRemoteUser->setText(settings.value("Remote/User", "Anonymous").toString());
|
||||||
|
QByteArray encPass = settings.value("Remote/Pass", "").toByteArray();
|
||||||
|
QString decPass = crypto.decryptToString(encPass);
|
||||||
|
ui->lineRemotePassword->setText(decPass);
|
||||||
|
|
||||||
ui->cbLoadConnections->setChecked(settings.value("Main/SaveRestoreConnections", false).toBool());
|
ui->cbLoadConnections->setChecked(settings.value("Main/SaveRestoreConnections", false).toBool());
|
||||||
|
|
||||||
ui->spinFontSize->setValue(settings.value("Main/FontSize", ui->cbDisplayHex->font().pointSize()).toUInt());
|
ui->spinFontSize->setValue(settings.value("Main/FontSize", ui->cbDisplayHex->font().pointSize()).toUInt());
|
||||||
@@ -82,9 +92,10 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
|||||||
connect(ui->cbUseFiltered, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
connect(ui->cbUseFiltered, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||||
connect(ui->lineClockFormat, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
connect(ui->lineClockFormat, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
||||||
connect(ui->cbUseOpenGL, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
connect(ui->cbUseOpenGL, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||||
connect(ui->cbAutoStartRemote, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
|
||||||
connect(ui->lineRemoteHost, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
connect(ui->lineRemoteHost, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
||||||
connect(ui->lineRemotePort, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
connect(ui->lineRemotePort, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
||||||
|
connect(ui->lineRemoteUser, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
||||||
|
connect(ui->lineRemotePassword, SIGNAL(editingFinished()), this, SLOT(updateSettings()));
|
||||||
connect(ui->cbLoadConnections, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
connect(ui->cbLoadConnections, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||||
connect(ui->cbFilterLabeling, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
connect(ui->cbFilterLabeling, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
@@ -144,7 +155,9 @@ void MainSettingsDialog::updateSettings()
|
|||||||
settings.setValue("Main/FontSize", ui->spinFontSize->value());
|
settings.setValue("Main/FontSize", ui->spinFontSize->value());
|
||||||
settings.setValue("Remote/Host", ui->lineRemoteHost->text());
|
settings.setValue("Remote/Host", ui->lineRemoteHost->text());
|
||||||
settings.setValue("Remote/Port", ui->lineRemotePort->text());
|
settings.setValue("Remote/Port", ui->lineRemotePort->text());
|
||||||
settings.setValue("Remote/AutoStart", ui->cbAutoStartRemote->isChecked());
|
settings.setValue("Remote/User", ui->lineRemoteUser->text());
|
||||||
|
QByteArray encPass = crypto.encryptToByteArray(ui->lineRemotePassword->text());
|
||||||
|
settings.setValue("Remote/Pass", encPass);
|
||||||
settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked());
|
settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked());
|
||||||
|
|
||||||
settings.sync();
|
settings.sync();
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
This project is dual licensed under the Eclipse Public License 1.0 and the
|
||||||
|
Eclipse Distribution License 1.0 as described in the epl-v10 and edl-v10 files.
|
||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
QMQTT
|
||||||
|
=====
|
||||||
|
|
||||||
|
mqtt client for Qt
|
||||||
|
|
||||||
|
**Please compile the library with Qt >= 5.3 version. On Windows you need to specify `CONFIG += NO_UNIT_TESTS`, since gtest is not supported.**
|
||||||
|
|
||||||
|
SSL is enabled by default, if the version of OpenSSL < 1.0.2, SSL may not be supported.
|
||||||
|
|
||||||
|
Disable the SSL in CMakeLists.txt (cmake):
|
||||||
|
|
||||||
|
option( ${PROJECT_NAME}_SSL "Enable SSL support for MQTT" OFF )
|
||||||
|
|
||||||
|
Disable the SSL with src/mqtt/qmqtt.pro (qmake):
|
||||||
|
|
||||||
|
CONFIG+=QMQTT_NO_SSL
|
||||||
|
|
||||||
|
To add websocket support, compile the library with Qt >= 5.7, and specify 'CONFIG += QMQTT_WEBSOCKETS'.
|
||||||
|
This also works when compiling qmqtt for WebAssembly.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
In your QMake project, add:
|
||||||
|
|
||||||
|
QT += qmqtt
|
||||||
|
|
||||||
|
Connect using TCP:
|
||||||
|
|
||||||
|
#include "qmqtt.h"
|
||||||
|
|
||||||
|
QMQTT::Client *client = new QMQTT::Client(QHostAddress::LocalHost, 1883);
|
||||||
|
client->setClientId("clientId");
|
||||||
|
client->setUsername("user");
|
||||||
|
client->setPassword("password");
|
||||||
|
client->connectToHost();
|
||||||
|
|
||||||
|
Connect using SSL:
|
||||||
|
|
||||||
|
QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
|
||||||
|
// Add custom SSL options here (for example extra certificates)
|
||||||
|
QMQTT::Client *client = new QMQTT::Client("example.com", 8883, sslConfig);
|
||||||
|
client->setClientId("clientId");
|
||||||
|
client->setUsername("user");
|
||||||
|
client->setPassword("password");
|
||||||
|
// Optionally, set ssl errors you want to ignore. Be careful, because this may weaken security.
|
||||||
|
// See QSslSocket::ignoreSslErrors(const QList<QSslError> &) for more information.
|
||||||
|
client->ignoreSslErrors(<list of expected ssl errors>)
|
||||||
|
client->connectToHost();
|
||||||
|
// Here's another option to suppress SSL errors (again, be careful)
|
||||||
|
QObject::connect(client, &QMQTT::Client::sslErrors, [&](const QList<QSslError> &errors) {
|
||||||
|
// Investigate the errors here, if you find no serious problems, call ignoreSslErrors()
|
||||||
|
// to continue connecting.
|
||||||
|
client->ignoreSslErrors();
|
||||||
|
});
|
||||||
|
|
||||||
|
Connect using WebSockets:
|
||||||
|
|
||||||
|
QMQTT::Client *client = new QMQTT::Client("ws://www.example.com/mqtt", "<origin>", QWebSocketProtocol::VersionLatest);
|
||||||
|
client->setClientId("clientId");
|
||||||
|
client->setUsername("user");
|
||||||
|
client->setPassword("password");
|
||||||
|
client->connectToHost();
|
||||||
|
|
||||||
|
Slots
|
||||||
|
=====
|
||||||
|
|
||||||
|
void setHost(const QHostAddress& host);
|
||||||
|
void setPort(const quint16 port);
|
||||||
|
void setClientId(const QString& clientId);
|
||||||
|
void setUsername(const QString& username);
|
||||||
|
void setPassword(const QString& password);
|
||||||
|
void setKeepAlive(const int keepAlive);
|
||||||
|
void setCleanSession(const bool cleansess);
|
||||||
|
void setAutoReconnect(const bool value);
|
||||||
|
void setAutoReconnectInterval(const int autoReconnectInterval);
|
||||||
|
void setWillTopic(const QString& willTopic);
|
||||||
|
void setWillQos(const quint8 willQos);
|
||||||
|
void setWillRetain(const bool willRetain);
|
||||||
|
void setWillMessage(const QString& willMessage);
|
||||||
|
|
||||||
|
void connectToHost();
|
||||||
|
void disconnectFromHost();
|
||||||
|
|
||||||
|
quint16 subscribe(const QString& topic, const quint8 qos);
|
||||||
|
void unsubscribe(const QString& topic);
|
||||||
|
|
||||||
|
quint16 publish(const Message& message);
|
||||||
|
|
||||||
|
Signals
|
||||||
|
=======
|
||||||
|
|
||||||
|
void connected();
|
||||||
|
void disconnected();
|
||||||
|
void error(const QMQTT::ClientError error);
|
||||||
|
|
||||||
|
void subscribed(const QString& topic, const quint8 qos);
|
||||||
|
void unsubscribed(const QString& topic);
|
||||||
|
void published(const quint16 msgid, const quint8 qos);
|
||||||
|
void pingresp();
|
||||||
|
void received(const QMQTT::Message& message);
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
=======
|
||||||
|
|
||||||
|
New BSD License
|
||||||
|
|
||||||
|
|
||||||
|
Contributors
|
||||||
|
=============
|
||||||
|
|
||||||
|
[@Kampfgnom](https://github.com/Kampfgnom)
|
||||||
|
|
||||||
|
[@rafaeldelucena](https://github.com/rafaeldelucena)
|
||||||
|
|
||||||
|
[@Vortex375](https://github.com/Vortex375)
|
||||||
|
|
||||||
|
[@mwallnoefer](https://github.com/mwallnoefer)
|
||||||
|
|
||||||
|
[@KonstantinRitt](https://github.com/KonstantinRitt)
|
||||||
|
|
||||||
|
[@cncap](https://github.com/cncap)
|
||||||
|
|
||||||
|
[@Psy-Kai](https://github.com/Psy-Kai)
|
||||||
|
|
||||||
|
[@ejvr](https://github.com/ejvr)
|
||||||
|
|
||||||
|
[@keytee](https://github.com/keytee)
|
||||||
|
|
||||||
|
|
||||||
|
Authors
|
||||||
|
=======
|
||||||
|
|
||||||
|
[@emqplus](https://github.com/emqplus) Feng Lee <feng@emqtt.io>
|
||||||
|
|
||||||
|
[@wguynes](https://github.com/wguynes) William Guynes <wguynes@gmail.com>
|
||||||
|
|
||||||
|
[@wuming123057](https://github.com/wuming123057) Xuan <huacai123057@163.com>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
Eclipse Distribution License - v 1.0
|
||||||
|
|
||||||
|
Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors.
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
Neither the name of the Eclipse Foundation, Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from this
|
||||||
|
software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
+220
@@ -0,0 +1,220 @@
|
|||||||
|
Eclipse Public License - v 1.0
|
||||||
|
|
||||||
|
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
|
||||||
|
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
|
||||||
|
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
|
||||||
|
|
||||||
|
|
||||||
|
1. DEFINITIONS
|
||||||
|
|
||||||
|
"Contribution" means:
|
||||||
|
a) in the case of the initial Contributor, the initial code and
|
||||||
|
documentation distributed under this Agreement, and
|
||||||
|
|
||||||
|
b) in the case of each subsequent Contributor:
|
||||||
|
|
||||||
|
i) changes to the Program, and
|
||||||
|
ii) additions to the Program;
|
||||||
|
|
||||||
|
where such changes and/or additions to the Program originate from and are
|
||||||
|
distributed by that particular Contributor. A Contribution 'originates' from a
|
||||||
|
Contributor if it was added to the Program by such Contributor itself or anyone
|
||||||
|
acting on such Contributor's behalf. Contributions do not include additions to
|
||||||
|
the Program which: (i) are separate modules of software distributed in
|
||||||
|
conjunction with the Program under their own license agreement, and (ii) are
|
||||||
|
not derivative works of the Program.
|
||||||
|
|
||||||
|
"Contributor" means any person or entity that distributes the Program.
|
||||||
|
|
||||||
|
"Licensed Patents " mean patent claims licensable by a Contributor which are
|
||||||
|
necessarily infringed by the use or sale of its Contribution alone or when
|
||||||
|
combined with the Program.
|
||||||
|
|
||||||
|
"Program" means the Contributions distributed in accordance with this Agreement.
|
||||||
|
|
||||||
|
"Recipient" means anyone who receives the Program under this Agreement,
|
||||||
|
including all Contributors.
|
||||||
|
|
||||||
|
|
||||||
|
2. GRANT OF RIGHTS
|
||||||
|
|
||||||
|
a) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||||
|
Recipient a non-exclusive, worldwide, royalty-free copyright license to
|
||||||
|
reproduce, prepare derivative works of, publicly display, publicly
|
||||||
|
perform, distribute and sublicense the Contribution of such Contributor,
|
||||||
|
if any, and such derivative works, in source code and object code form.
|
||||||
|
|
||||||
|
b) Subject to the terms of this Agreement, each Contributor hereby grants
|
||||||
|
Recipient a non-exclusive, worldwide, royalty-free patent license under
|
||||||
|
Licensed Patents to make, use, sell, offer to sell, import and otherwise
|
||||||
|
transfer the Contribution of such Contributor, if any, in source code and
|
||||||
|
object code form. This patent license shall apply to the combination of the
|
||||||
|
Contribution and the Program if, at the time the Contribution is added by the
|
||||||
|
Contributor, such addition of the Contribution causes such combination to be
|
||||||
|
covered by the Licensed Patents. The patent license shall not apply to any
|
||||||
|
other combinations which include the Contribution. No hardware per se is
|
||||||
|
licensed hereunder.
|
||||||
|
|
||||||
|
c) Recipient understands that although each Contributor grants the licenses
|
||||||
|
to its Contributions set forth herein, no assurances are provided by any
|
||||||
|
Contributor that the Program does not infringe the patent or other
|
||||||
|
intellectual property rights of any other entity. Each Contributor disclaims
|
||||||
|
any liability to Recipient for claims brought by any other entity based on
|
||||||
|
infringement of intellectual property rights or otherwise. As a condition to
|
||||||
|
exercising the rights and licenses granted hereunder, each Recipient hereby
|
||||||
|
assumes sole responsibility to secure any other intellectual property rights
|
||||||
|
needed, if any. For example, if a third party patent license is required to
|
||||||
|
allow Recipient to distribute the Program, it is Recipient's responsibility
|
||||||
|
to acquire that license before distributing the Program.
|
||||||
|
|
||||||
|
d) Each Contributor represents that to its knowledge it has sufficient
|
||||||
|
copyright rights in its Contribution, if any, to grant the copyright license
|
||||||
|
set forth in this Agreement.
|
||||||
|
|
||||||
|
|
||||||
|
3. REQUIREMENTS
|
||||||
|
|
||||||
|
A Contributor may choose to distribute the Program in object code form under
|
||||||
|
its own license agreement, provided that:
|
||||||
|
|
||||||
|
a) it complies with the terms and conditions of this Agreement; and
|
||||||
|
|
||||||
|
b) its license agreement:
|
||||||
|
|
||||||
|
i) effectively disclaims on behalf of all Contributors all warranties and
|
||||||
|
conditions, express and implied, including warranties or conditions of
|
||||||
|
title and non-infringement, and implied warranties or conditions of
|
||||||
|
merchantability and fitness for a particular purpose;
|
||||||
|
|
||||||
|
ii) effectively excludes on behalf of all Contributors all liability for
|
||||||
|
damages, including direct, indirect, special, incidental and consequential
|
||||||
|
damages, such as lost profits;
|
||||||
|
|
||||||
|
iii) states that any provisions which differ from this Agreement are offered
|
||||||
|
by that Contributor alone and not by any other party; and
|
||||||
|
|
||||||
|
iv) states that source code for the Program is available from such
|
||||||
|
Contributor, and informs licensees how to obtain it in a reasonable manner
|
||||||
|
on or through a medium customarily used for software exchange.
|
||||||
|
|
||||||
|
When the Program is made available in source code form:
|
||||||
|
|
||||||
|
a) it must be made available under this Agreement; and
|
||||||
|
|
||||||
|
b) a copy of this Agreement must be included with each copy of the Program.
|
||||||
|
|
||||||
|
Contributors may not remove or alter any copyright notices contained within
|
||||||
|
the Program.
|
||||||
|
|
||||||
|
Each Contributor must identify itself as the originator of its Contribution,
|
||||||
|
if any, in a manner that reasonably allows subsequent Recipients to identify
|
||||||
|
the originator of the Contribution.
|
||||||
|
|
||||||
|
|
||||||
|
4. COMMERCIAL DISTRIBUTION
|
||||||
|
|
||||||
|
Commercial distributors of software may accept certain responsibilities with
|
||||||
|
respect to end users, business partners and the like. While this license is
|
||||||
|
intended to facilitate the commercial use of the Program, the Contributor who
|
||||||
|
includes the Program in a commercial product offering should do so in a
|
||||||
|
manner which does not create potential liability for other Contributors.
|
||||||
|
Therefore, if a Contributor includes the Program in a commercial product
|
||||||
|
offering, such Contributor ("Commercial Contributor") hereby agrees to defend
|
||||||
|
and indemnify every other Contributor ("Indemnified Contributor") against any
|
||||||
|
losses, damages and costs (collectively "Losses") arising from claims,
|
||||||
|
lawsuits and other legal actions brought by a third party against the
|
||||||
|
Indemnified Contributor to the extent caused by the acts or omissions of such
|
||||||
|
Commercial Contributor in connection with its distribution of the Program in
|
||||||
|
a commercial product offering. The obligations in this section do not apply
|
||||||
|
to any claims or Losses relating to any actual or alleged intellectual
|
||||||
|
property infringement. In order to qualify, an Indemnified Contributor must:
|
||||||
|
a) promptly notify the Commercial Contributor in writing of such claim, and
|
||||||
|
b) allow the Commercial Contributor to control, and cooperate with the
|
||||||
|
Commercial Contributor in, the defense and any related settlement
|
||||||
|
negotiations. The Indemnified Contributor may participate in any such claim
|
||||||
|
at its own expense.
|
||||||
|
|
||||||
|
For example, a Contributor might include the Program in a commercial product
|
||||||
|
offering, Product X. That Contributor is then a Commercial Contributor. If
|
||||||
|
that Commercial Contributor then makes performance claims, or offers
|
||||||
|
warranties related to Product X, those performance claims and warranties are
|
||||||
|
such Commercial Contributor's responsibility alone. Under this section, the
|
||||||
|
Commercial Contributor would have to defend claims against the other
|
||||||
|
Contributors related to those performance claims and warranties, and if a
|
||||||
|
court requires any other Contributor to pay any damages as a result, the
|
||||||
|
Commercial Contributor must pay those damages.
|
||||||
|
|
||||||
|
|
||||||
|
5. NO WARRANTY
|
||||||
|
|
||||||
|
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
|
||||||
|
AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
|
||||||
|
EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
|
||||||
|
CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
|
||||||
|
appropriateness of using and distributing the Program and assumes all risks
|
||||||
|
associated with its exercise of rights under this Agreement , including but
|
||||||
|
not limited to the risks and costs of program errors, compliance with
|
||||||
|
applicable laws, damage to or loss of data, programs or equipment, and
|
||||||
|
unavailability or interruption of operations.
|
||||||
|
|
||||||
|
|
||||||
|
6. DISCLAIMER OF LIABILITY
|
||||||
|
|
||||||
|
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
|
||||||
|
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
|
||||||
|
LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
|
||||||
|
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
|
||||||
|
7. GENERAL
|
||||||
|
|
||||||
|
If any provision of this Agreement is invalid or unenforceable under
|
||||||
|
applicable law, it shall not affect the validity or enforceability of the
|
||||||
|
remainder of the terms of this Agreement, and without further action by the
|
||||||
|
parties hereto, such provision shall be reformed to the minimum extent
|
||||||
|
necessary to make such provision valid and enforceable.
|
||||||
|
|
||||||
|
If Recipient institutes patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
|
||||||
|
(excluding combinations of the Program with other software or hardware)
|
||||||
|
infringes such Recipient's patent(s), then such Recipient's rights granted
|
||||||
|
under Section 2(b) shall terminate as of the date such litigation is filed.
|
||||||
|
|
||||||
|
All Recipient's rights under this Agreement shall terminate if it fails to
|
||||||
|
comply with any of the material terms or conditions of this Agreement and
|
||||||
|
does not cure such failure in a reasonable period of time after becoming
|
||||||
|
aware of such noncompliance. If all Recipient's rights under this Agreement
|
||||||
|
terminate, Recipient agrees to cease use and distribution of the Program as
|
||||||
|
soon as reasonably practicable. However, Recipient's obligations under this
|
||||||
|
Agreement and any licenses granted by Recipient relating to the Program shall
|
||||||
|
continue and survive.
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute copies of this Agreement, but in
|
||||||
|
order to avoid inconsistency the Agreement is copyrighted and may only be
|
||||||
|
modified in the following manner. The Agreement Steward reserves the right to
|
||||||
|
publish new versions (including revisions) of this Agreement from time to
|
||||||
|
time. No one other than the Agreement Steward has the right to modify this
|
||||||
|
Agreement. The Eclipse Foundation is the initial Agreement Steward. The
|
||||||
|
Eclipse Foundation may assign the responsibility to serve as the Agreement
|
||||||
|
Steward to a suitable separate entity. Each new version of the Agreement will
|
||||||
|
be given a distinguishing version number. The Program (including
|
||||||
|
Contributions) may always be distributed subject to the version of the
|
||||||
|
Agreement under which it was received. In addition, after a new version of
|
||||||
|
the Agreement is published, Contributor may elect to distribute the Program
|
||||||
|
(including its Contributions) under the new version. Except as expressly
|
||||||
|
stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
|
||||||
|
licenses to the intellectual property of any Contributor under this
|
||||||
|
Agreement, whether expressly, by implication, estoppel or otherwise. All
|
||||||
|
rights in the Program not expressly granted under this Agreement are
|
||||||
|
reserved.
|
||||||
|
|
||||||
|
This Agreement is governed by the laws of the State of New York and the
|
||||||
|
intellectual property laws of the United States of America. No party to this
|
||||||
|
Agreement will bring a legal action under this Agreement more than one year
|
||||||
|
after the cause of action arose. Each party waives its rights to a jury trial
|
||||||
|
in any resulting litigation.
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt.h - qmqtt library heaer
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_H
|
||||||
|
#define QMQTT_H
|
||||||
|
|
||||||
|
#include <qmqtt_message.h>
|
||||||
|
#include <qmqtt_client.h>
|
||||||
|
|
||||||
|
#endif // QMQTT_H
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
|
PUBLIC_HEADERS += \
|
||||||
|
$$PWD/qmqtt_client.h \
|
||||||
|
$$PWD/qmqtt_frame.h \
|
||||||
|
$$PWD/qmqtt_message.h \
|
||||||
|
$$PWD/qmqtt_routesubscription.h \
|
||||||
|
$$PWD/qmqtt_routedmessage.h \
|
||||||
|
$$PWD/qmqtt_router.h \
|
||||||
|
$$PWD/qmqtt_networkinterface.h \
|
||||||
|
$$PWD/qmqtt_socketinterface.h \
|
||||||
|
$$PWD/qmqtt_timerinterface.h
|
||||||
|
|
||||||
|
PRIVATE_HEADERS += \
|
||||||
|
$$PWD/qmqtt_client_p.h \
|
||||||
|
$$PWD/qmqtt_message_p.h \
|
||||||
|
$$PWD/qmqtt_network_p.h \
|
||||||
|
$$PWD/qmqtt_socket_p.h \
|
||||||
|
$$PWD/qmqtt_timer_p.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/qmqtt_client_p.cpp \
|
||||||
|
$$PWD/qmqtt_client.cpp \
|
||||||
|
$$PWD/qmqtt_frame.cpp \
|
||||||
|
$$PWD/qmqtt_message.cpp \
|
||||||
|
$$PWD/qmqtt_network.cpp \
|
||||||
|
$$PWD/qmqtt_routesubscription.cpp \
|
||||||
|
$$PWD/qmqtt_router.cpp \
|
||||||
|
$$PWD/qmqtt_socket.cpp \
|
||||||
|
$$PWD/qmqtt_timer.cpp
|
||||||
|
|
||||||
|
QMQTT_WEBSOCKETS {
|
||||||
|
PRIVATE_HEADERS += \
|
||||||
|
$$PWD/qmqtt_websocket_p.h \
|
||||||
|
$$PWD/qmqtt_websocketiodevice_p.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/qmqtt_websocket.cpp \
|
||||||
|
$$PWD/qmqtt_websocketiodevice.cpp
|
||||||
|
}
|
||||||
|
|
||||||
|
!contains(CONFIG, QMQTT_NO_SSL) {
|
||||||
|
PRIVATE_HEADERS += \
|
||||||
|
$$PWD/qmqtt_ssl_socket_p.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/qmqtt_ssl_socket.cpp
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
TARGET = QtQmqtt
|
||||||
|
QT = core network
|
||||||
|
qtHaveModule(websockets): QMQTT_WEBSOCKETS: QT += websockets
|
||||||
|
|
||||||
|
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
|
||||||
|
|
||||||
|
# CONFIG += QMQTT_NO_SSL
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/qmqtt_global.h \
|
||||||
|
$$PWD/qmqtt.h
|
||||||
|
|
||||||
|
include(qmqtt.pri)
|
||||||
|
|
||||||
|
HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
|
||||||
|
|
||||||
|
load(qt_module)
|
||||||
+134
@@ -0,0 +1,134 @@
|
|||||||
|
import qbs
|
||||||
|
import qbs.TextFile
|
||||||
|
import qbs.FileInfo
|
||||||
|
|
||||||
|
Product {
|
||||||
|
name: "qmqtt"
|
||||||
|
type: [libraryType]
|
||||||
|
property bool webSocketSupport: false
|
||||||
|
property string libraryType: "dynamiclibrary"
|
||||||
|
targetName: "qmqtt"
|
||||||
|
version: "1.0.0"
|
||||||
|
|
||||||
|
cpp.defines: [
|
||||||
|
"QT_BUILD_QMQTT_LIB",
|
||||||
|
"QT_NO_CAST_TO_ASCII",
|
||||||
|
"QT_NO_CAST_FROM_ASCII",
|
||||||
|
]
|
||||||
|
|
||||||
|
cpp.includePaths: sourceDirectory
|
||||||
|
|
||||||
|
files: [
|
||||||
|
"*.cpp"
|
||||||
|
]
|
||||||
|
|
||||||
|
Group {
|
||||||
|
name: "Public Headers"
|
||||||
|
fileTags: [
|
||||||
|
"hpp",
|
||||||
|
"public_headers"
|
||||||
|
]
|
||||||
|
files: [
|
||||||
|
"*.h"
|
||||||
|
]
|
||||||
|
excludeFiles: privateHeaders.files
|
||||||
|
}
|
||||||
|
|
||||||
|
Group {
|
||||||
|
id: privateHeaders
|
||||||
|
name: "Private Headers"
|
||||||
|
fileTags: [
|
||||||
|
"hpp",
|
||||||
|
"private_headers",
|
||||||
|
]
|
||||||
|
files: [
|
||||||
|
"*_p.h"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Group {
|
||||||
|
fileTagsFilter: libraryType
|
||||||
|
qbs.install: true
|
||||||
|
qbs.installDir: "lib"
|
||||||
|
}
|
||||||
|
|
||||||
|
Group {
|
||||||
|
fileTagsFilter: "public_headers"
|
||||||
|
qbs.install: true
|
||||||
|
qbs.installDir: FileInfo.joinPaths("include", product.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
Group {
|
||||||
|
fileTagsFilter: "private_headers"
|
||||||
|
qbs.install: true
|
||||||
|
qbs.installDir: FileInfo.joinPaths("include", product.name, version, product.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
Group {
|
||||||
|
fileTagsFilter: "Exporter.qbs.module"
|
||||||
|
qbs.installDir: FileInfo.joinPaths("qbs", "modules", product.name, "private")
|
||||||
|
qbs.install: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Group {
|
||||||
|
fileTagsFilter: "Exporter.pkgconfig.pc"
|
||||||
|
qbs.installDir: FileInfo.joinPaths("lib" ,"pkgconfig")
|
||||||
|
qbs.install: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Depends {
|
||||||
|
name: "cpp"
|
||||||
|
}
|
||||||
|
|
||||||
|
Depends {
|
||||||
|
name: "Qt"
|
||||||
|
property var baseModules: ["core", "network"]
|
||||||
|
|
||||||
|
Properties {
|
||||||
|
condition: webSocketSupport
|
||||||
|
submodules: baseModules.concat(["websockets"])
|
||||||
|
}
|
||||||
|
Properties {
|
||||||
|
condition: !webSocketSupport
|
||||||
|
submodules: baseModules
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Depends {
|
||||||
|
name: "Exporter.qbs"
|
||||||
|
}
|
||||||
|
Depends {
|
||||||
|
name: "Exporter.pkgconfig"
|
||||||
|
}
|
||||||
|
|
||||||
|
Export {
|
||||||
|
Depends {
|
||||||
|
name: "cpp"
|
||||||
|
}
|
||||||
|
|
||||||
|
Depends {
|
||||||
|
name: "Qt"
|
||||||
|
property var baseModules: ["core", "network"]
|
||||||
|
Properties {
|
||||||
|
condition: product.webSocketSupport
|
||||||
|
submodules: baseModules.concat(["websockets"])
|
||||||
|
}
|
||||||
|
Properties {
|
||||||
|
condition: !product.webSocketSupport
|
||||||
|
submodules: baseModules
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cpp.includePaths: [
|
||||||
|
product.sourceDirectory,
|
||||||
|
FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, "include"),
|
||||||
|
]
|
||||||
|
prefixMapping: [
|
||||||
|
{
|
||||||
|
prefix: product.sourceDirectory,
|
||||||
|
replacement: FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, "include",
|
||||||
|
product.name)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,412 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_client.cpp - qmqtt client
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_client.h"
|
||||||
|
#include "qmqtt_client_p.h"
|
||||||
|
|
||||||
|
QMQTT::Client::Client(const QHostAddress& host,
|
||||||
|
const quint16 port,
|
||||||
|
QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, d_ptr(new ClientPrivate(this))
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->init(host, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
QMQTT::Client::Client(const QString &hostName,
|
||||||
|
const quint16 port,
|
||||||
|
const QSslConfiguration &config,
|
||||||
|
const bool ignoreSelfSigned, QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, d_ptr(new ClientPrivate(this))
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->init(hostName, port, config, ignoreSelfSigned);
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
QMQTT::Client::Client(const QString &hostName,
|
||||||
|
const quint16 port,
|
||||||
|
const bool ssl,
|
||||||
|
const bool ignoreSelfSigned,
|
||||||
|
QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, d_ptr(new ClientPrivate(this))
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->init(hostName, port, ssl, ignoreSelfSigned);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
QMQTT::Client::Client(const QString& url,
|
||||||
|
const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
bool ignoreSelfSigned,
|
||||||
|
QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, d_ptr(new ClientPrivate(this))
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
d->init(url, origin, version, NULL, ignoreSelfSigned);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(ignoreSelfSigned)
|
||||||
|
d->init(url, origin, version);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
QMQTT::Client::Client(const QString& url,
|
||||||
|
const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
const QSslConfiguration& sslConfig,
|
||||||
|
const bool ignoreSelfSigned,
|
||||||
|
QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, d_ptr(new ClientPrivate(this))
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->init(url, origin, version, &sslConfig, ignoreSelfSigned);
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
QMQTT::Client::Client(NetworkInterface* network,
|
||||||
|
const QHostAddress& host,
|
||||||
|
const quint16 port,
|
||||||
|
QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, d_ptr(new ClientPrivate(this))
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->init(host, port, network);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::Client::~Client()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QHostAddress QMQTT::Client::host() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->host();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setHost(const QHostAddress& host)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setHost(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QMQTT::Client::hostName() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->hostName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setHostName(const QString &hostName)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setHostName(hostName);
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::Client::port() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->port();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setPort(const quint16 port)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setPort(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QMQTT::Client::clientId() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->clientId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setClientId(const QString& clientId)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setClientId(clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QMQTT::Client::username() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->username();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setUsername(const QString& username)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setUsername(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::MQTTVersion QMQTT::Client::version() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->version();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setVersion(const QMQTT::MQTTVersion version)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setVersion(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray QMQTT::Client::password() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->password();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setPassword(const QByteArray &password)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setPassword(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::Client::keepAlive() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->keepAlive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setKeepAlive(const quint16 keepAlive)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setKeepAlive(keepAlive);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::Client::cleanSession() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->cleanSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setCleanSession(const bool cleanSession)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setCleanSession(cleanSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::Client::autoReconnect() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->autoReconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setAutoReconnect(const bool value)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setAutoReconnect(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int QMQTT::Client::autoReconnectInterval() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->autoReconnectInterval();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setAutoReconnectInterval(const int autoReconnectInterval)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setAutoReconnectInterval(autoReconnectInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QMQTT::Client::willTopic() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->willTopic();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setWillTopic(const QString& willTopic)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setWillTopic(willTopic);
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 QMQTT::Client::willQos() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->willQos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setWillQos(const quint8 willQos)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setWillQos(willQos);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::Client::willRetain() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->willRetain();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setWillRetain(const bool willRetain)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setWillRetain(willRetain);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray QMQTT::Client::willMessage() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->willMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setWillMessage(const QByteArray &willMessage)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setWillMessage(willMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::ConnectionState QMQTT::Client::connectionState() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->connectionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::Client::isConnectedToHost() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->isConnectedToHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
QSslConfiguration QMQTT::Client::sslConfiguration() const
|
||||||
|
{
|
||||||
|
Q_D(const Client);
|
||||||
|
return d->sslConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::setSslConfiguration(const QSslConfiguration& config)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->setSslConfiguration(config);
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
void QMQTT::Client::connectToHost()
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->connectToHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::onNetworkConnected()
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->onNetworkConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::Client::publish(const Message& message)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
return d->publish(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::subscribe(const QString& topic, const quint8 qos)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->subscribe(topic, qos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::unsubscribe(const QString& topic)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->unsubscribe(topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::onTimerPingReq()
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->onTimerPingReq();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::onPingTimeout()
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->onPingTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::disconnectFromHost()
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->disconnectFromHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::onNetworkReceived(const QMQTT::Frame& frame)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->onNetworkReceived(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::onNetworkDisconnected()
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->onNetworkDisconnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::onNetworkError(QAbstractSocket::SocketError error)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->onNetworkError(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void QMQTT::Client::onSslErrors(const QList<QSslError>& errors)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->onSslErrors(errors);
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void QMQTT::Client::ignoreSslErrors()
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->ignoreSslErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Client::ignoreSslErrors(const QList<QSslError>& errors)
|
||||||
|
{
|
||||||
|
Q_D(Client);
|
||||||
|
d->ignoreSslErrors(errors);
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
@@ -0,0 +1,276 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_client.h - qmqtt client header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_CLIENT_H
|
||||||
|
#define QMQTT_CLIENT_H
|
||||||
|
|
||||||
|
#include "qmqtt_global.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QAbstractSocket>
|
||||||
|
#include <QScopedPointer>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
#include <QWebSocket>
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
#include <QSslConfiguration>
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSslError)
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
static const quint8 LIBRARY_VERSION_MAJOR = 0;
|
||||||
|
static const quint8 LIBRARY_VERSION_MINOR = 3;
|
||||||
|
static const quint8 LIBRARY_VERSION_REVISION = 1;
|
||||||
|
//static const char* LIBRARY_VERSION = "0.3.1";
|
||||||
|
|
||||||
|
enum MQTTVersion
|
||||||
|
{
|
||||||
|
V3_1_0 = 3,
|
||||||
|
V3_1_1 = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ConnectionState
|
||||||
|
{
|
||||||
|
STATE_INIT = 0,
|
||||||
|
STATE_CONNECTING,
|
||||||
|
STATE_CONNECTED,
|
||||||
|
STATE_DISCONNECTED
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ClientError
|
||||||
|
{
|
||||||
|
UnknownError = 0,
|
||||||
|
SocketConnectionRefusedError,
|
||||||
|
SocketRemoteHostClosedError,
|
||||||
|
SocketHostNotFoundError,
|
||||||
|
SocketAccessError,
|
||||||
|
SocketResourceError,
|
||||||
|
SocketTimeoutError,
|
||||||
|
SocketDatagramTooLargeError,
|
||||||
|
SocketNetworkError,
|
||||||
|
SocketAddressInUseError,
|
||||||
|
SocketAddressNotAvailableError,
|
||||||
|
SocketUnsupportedSocketOperationError,
|
||||||
|
SocketUnfinishedSocketOperationError,
|
||||||
|
SocketProxyAuthenticationRequiredError,
|
||||||
|
SocketSslHandshakeFailedError,
|
||||||
|
SocketProxyConnectionRefusedError,
|
||||||
|
SocketProxyConnectionClosedError,
|
||||||
|
SocketProxyConnectionTimeoutError,
|
||||||
|
SocketProxyNotFoundError,
|
||||||
|
SocketProxyProtocolError,
|
||||||
|
SocketOperationError,
|
||||||
|
SocketSslInternalError,
|
||||||
|
SocketSslInvalidUserDataError,
|
||||||
|
SocketTemporaryError,
|
||||||
|
MqttUnacceptableProtocolVersionError=1<<16,
|
||||||
|
MqttIdentifierRejectedError,
|
||||||
|
MqttServerUnavailableError,
|
||||||
|
MqttBadUserNameOrPasswordError,
|
||||||
|
MqttNotAuthorizedError,
|
||||||
|
MqttNoPingResponse
|
||||||
|
};
|
||||||
|
|
||||||
|
class ClientPrivate;
|
||||||
|
class Message;
|
||||||
|
class Frame;
|
||||||
|
class NetworkInterface;
|
||||||
|
|
||||||
|
class Q_MQTT_EXPORT Client : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(quint16 _port READ port WRITE setPort)
|
||||||
|
Q_PROPERTY(QHostAddress _host READ host WRITE setHost)
|
||||||
|
Q_PROPERTY(QString _hostName READ hostName WRITE setHostName)
|
||||||
|
Q_PROPERTY(QString _clientId READ clientId WRITE setClientId)
|
||||||
|
Q_PROPERTY(QString _username READ username WRITE setUsername)
|
||||||
|
Q_PROPERTY(QByteArray _password READ password WRITE setPassword)
|
||||||
|
Q_PROPERTY(quint16 _keepAlive READ keepAlive WRITE setKeepAlive)
|
||||||
|
Q_PROPERTY(MQTTVersion _version READ version WRITE setVersion)
|
||||||
|
Q_PROPERTY(bool _autoReconnect READ autoReconnect WRITE setAutoReconnect)
|
||||||
|
Q_PROPERTY(int _autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval)
|
||||||
|
Q_PROPERTY(bool _cleanSession READ cleanSession WRITE setCleanSession)
|
||||||
|
Q_PROPERTY(QString _willTopic READ willTopic WRITE setWillTopic)
|
||||||
|
Q_PROPERTY(quint8 _willQos READ willQos WRITE setWillQos)
|
||||||
|
Q_PROPERTY(bool _willRetain READ willRetain WRITE setWillRetain)
|
||||||
|
Q_PROPERTY(QByteArray _willMessage READ willMessage WRITE setWillMessage)
|
||||||
|
Q_PROPERTY(QString _connectionState READ connectionState)
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
Q_PROPERTY(QSslConfiguration _sslConfiguration READ sslConfiguration WRITE setSslConfiguration)
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
public:
|
||||||
|
Client(const QHostAddress& host = QHostAddress::LocalHost,
|
||||||
|
const quint16 port = 1883,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
Client(const QString& hostName,
|
||||||
|
const quint16 port,
|
||||||
|
const QSslConfiguration& config,
|
||||||
|
const bool ignoreSelfSigned=false,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
// This function is provided for backward compatibility with older versions of QMQTT.
|
||||||
|
// If the ssl parameter is true, this function will load a private key ('cert.key') and a local
|
||||||
|
// certificate ('cert.crt') from the current working directory. It will also set PeerVerifyMode
|
||||||
|
// to None. This may not be the safest way to set up an SSL connection.
|
||||||
|
Client(const QString& hostName,
|
||||||
|
const quint16 port,
|
||||||
|
const bool ssl,
|
||||||
|
const bool ignoreSelfSigned,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
// Create a connection over websockets
|
||||||
|
Client(const QString& url,
|
||||||
|
const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
bool ignoreSelfSigned = false,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
Client(const QString& url,
|
||||||
|
const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
const QSslConfiguration& config,
|
||||||
|
const bool ignoreSelfSigned = false,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
// for testing purposes only
|
||||||
|
Client(NetworkInterface* network,
|
||||||
|
const QHostAddress& host = QHostAddress::LocalHost,
|
||||||
|
const quint16 port = 1883,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
|
||||||
|
virtual ~Client();
|
||||||
|
|
||||||
|
QHostAddress host() const;
|
||||||
|
QString hostName() const;
|
||||||
|
quint16 port() const;
|
||||||
|
QString clientId() const;
|
||||||
|
QString username() const;
|
||||||
|
QByteArray password() const;
|
||||||
|
QMQTT::MQTTVersion version() const;
|
||||||
|
quint16 keepAlive() const;
|
||||||
|
bool cleanSession() const;
|
||||||
|
bool autoReconnect() const;
|
||||||
|
int autoReconnectInterval() const;
|
||||||
|
ConnectionState connectionState() const;
|
||||||
|
QString willTopic() const;
|
||||||
|
quint8 willQos() const;
|
||||||
|
bool willRetain() const;
|
||||||
|
QByteArray willMessage() const;
|
||||||
|
|
||||||
|
bool isConnectedToHost() const;
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
QSslConfiguration sslConfiguration() const;
|
||||||
|
void setSslConfiguration(const QSslConfiguration& config);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setHost(const QHostAddress& host);
|
||||||
|
void setHostName(const QString& hostName);
|
||||||
|
void setPort(const quint16 port);
|
||||||
|
void setClientId(const QString& clientId);
|
||||||
|
void setUsername(const QString& username);
|
||||||
|
void setPassword(const QByteArray& password);
|
||||||
|
void setVersion(const MQTTVersion version);
|
||||||
|
void setKeepAlive(const quint16 keepAlive);
|
||||||
|
void setCleanSession(const bool cleanSession);
|
||||||
|
void setAutoReconnect(const bool value);
|
||||||
|
void setAutoReconnectInterval(const int autoReconnectInterval);
|
||||||
|
void setWillTopic(const QString& willTopic);
|
||||||
|
void setWillQos(const quint8 willQos);
|
||||||
|
void setWillRetain(const bool willRetain);
|
||||||
|
void setWillMessage(const QByteArray& willMessage);
|
||||||
|
|
||||||
|
void connectToHost();
|
||||||
|
void disconnectFromHost();
|
||||||
|
|
||||||
|
void subscribe(const QString& topic, const quint8 qos = 0);
|
||||||
|
void unsubscribe(const QString& topic);
|
||||||
|
|
||||||
|
quint16 publish(const QMQTT::Message& message);
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void ignoreSslErrors();
|
||||||
|
void ignoreSslErrors(const QList<QSslError>& errors);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void connected();
|
||||||
|
void disconnected();
|
||||||
|
void error(const QMQTT::ClientError error);
|
||||||
|
|
||||||
|
void subscribed(const QString& topic, const quint8 qos = 0);
|
||||||
|
void unsubscribed(const QString& topic);
|
||||||
|
void published(const QMQTT::Message& message, quint16 msgid = 0);
|
||||||
|
void received(const QMQTT::Message& message);
|
||||||
|
void pingresp();
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void sslErrors(const QList<QSslError>& errors);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void onNetworkConnected();
|
||||||
|
void onNetworkDisconnected();
|
||||||
|
void onNetworkReceived(const QMQTT::Frame& frame);
|
||||||
|
void onTimerPingReq();
|
||||||
|
void onPingTimeout();
|
||||||
|
void onNetworkError(QAbstractSocket::SocketError error);
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void onSslErrors(const QList<QSslError>& errors);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QScopedPointer<ClientPrivate> d_ptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(Client)
|
||||||
|
Q_DECLARE_PRIVATE(Client)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QMQTT::ClientError)
|
||||||
|
|
||||||
|
#endif // QMQTT_CLIENT_H
|
||||||
@@ -0,0 +1,811 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_client_p.cpp - qmqtt client private
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_client_p.h"
|
||||||
|
#include "qmqtt_network_p.h"
|
||||||
|
#include "qmqtt_frame.h"
|
||||||
|
#include "qmqtt_message.h"
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QUuid>
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
#include <QFile>
|
||||||
|
#include <QSslConfiguration>
|
||||||
|
#include <QSslKey>
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(client, "qmqtt.client")
|
||||||
|
|
||||||
|
static const quint8 QOS0 = 0x00;
|
||||||
|
static const quint8 QOS1 = 0x01;
|
||||||
|
static const quint8 QOS2 = 0x02;
|
||||||
|
|
||||||
|
QMQTT::ClientPrivate::ClientPrivate(Client* qq_ptr)
|
||||||
|
: _host(QHostAddress::LocalHost)
|
||||||
|
, _port(1883)
|
||||||
|
, _gmid(1)
|
||||||
|
, _version(MQTTVersion::V3_1_0)
|
||||||
|
, _clientId(QUuid::createUuid().toString())
|
||||||
|
, _cleanSession(false)
|
||||||
|
, _connectionState(STATE_INIT)
|
||||||
|
, _willQos(0)
|
||||||
|
, _willRetain(false)
|
||||||
|
, q_ptr(qq_ptr)
|
||||||
|
{
|
||||||
|
setKeepAlive(300);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::ClientPrivate::~ClientPrivate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::init(const QHostAddress& host, const quint16 port, NetworkInterface* network)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
_host = host;
|
||||||
|
_port = port;
|
||||||
|
if(network == NULL)
|
||||||
|
{
|
||||||
|
init(new Network(q));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
init(network);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port,
|
||||||
|
const QSslConfiguration &config, const bool ignoreSelfSigned)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
_hostName = hostName;
|
||||||
|
_port = port;
|
||||||
|
_ignoreSelfSigned = ignoreSelfSigned;
|
||||||
|
init(new Network(config, q));
|
||||||
|
QObject::connect(_network.data(), &QMQTT::Network::sslErrors, q, &QMQTT::Client::onSslErrors);
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port, const bool ssl,
|
||||||
|
const bool ignoreSelfSigned)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
_hostName = hostName;
|
||||||
|
_port = port;
|
||||||
|
if (ssl)
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
QSslConfiguration sslConf = QSslConfiguration::defaultConfiguration();
|
||||||
|
QList<QSslCertificate> certs = QSslCertificate::fromPath(QStringLiteral("./cert.crt"));
|
||||||
|
if (!certs.isEmpty())
|
||||||
|
sslConf.setLocalCertificate(certs.first());
|
||||||
|
QFile file(QStringLiteral("./cert.key"));
|
||||||
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
|
sslConf.setPrivateKey(QSslKey(file.readAll(), QSsl::Rsa));
|
||||||
|
}
|
||||||
|
sslConf.setPeerVerifyMode(QSslSocket::VerifyNone);
|
||||||
|
init(hostName, port, sslConf, ignoreSelfSigned);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(ignoreSelfSigned)
|
||||||
|
qCritical() << "SSL not supported in this QT build";
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
init(new Network(q));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void QMQTT::ClientPrivate::init(const QString& url,
|
||||||
|
const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
const QSslConfiguration* sslConfig,
|
||||||
|
bool ignoreSelfSigned)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
_hostName = url;
|
||||||
|
_ignoreSelfSigned = ignoreSelfSigned;
|
||||||
|
init(new Network(origin, version, sslConfig, q));
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::init(const QString& url,
|
||||||
|
const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
_hostName = url;
|
||||||
|
init(new Network(origin, version, q));
|
||||||
|
}
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::init(NetworkInterface* network)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
|
||||||
|
_network.reset(network);
|
||||||
|
_timer.setSingleShot(true);
|
||||||
|
_pingResponseTimer.setSingleShot(true);
|
||||||
|
|
||||||
|
QObject::connect(&_timer, &QTimer::timeout, q, &Client::onTimerPingReq);
|
||||||
|
QObject::connect(&_pingResponseTimer, &QTimer::timeout, q, &Client::onPingTimeout);
|
||||||
|
QObject::connect(_network.data(), &Network::connected,
|
||||||
|
q, &Client::onNetworkConnected);
|
||||||
|
QObject::connect(_network.data(), &Network::disconnected,
|
||||||
|
q, &Client::onNetworkDisconnected);
|
||||||
|
QObject::connect(_network.data(), &Network::received,
|
||||||
|
q, &Client::onNetworkReceived);
|
||||||
|
QObject::connect(_network.data(), &Network::error,
|
||||||
|
q, &Client::onNetworkError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::connectToHost()
|
||||||
|
{
|
||||||
|
_connectionState = ConnectionState::STATE_CONNECTING;
|
||||||
|
if (_hostName.isEmpty())
|
||||||
|
{
|
||||||
|
_network->connectToHost(_host, _port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_network->connectToHost(_hostName, _port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::onNetworkConnected()
|
||||||
|
{
|
||||||
|
sendConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::sendConnect()
|
||||||
|
{
|
||||||
|
quint8 header = CONNECT;
|
||||||
|
quint8 flags = 0;
|
||||||
|
|
||||||
|
//header
|
||||||
|
Frame frame(header);
|
||||||
|
|
||||||
|
//flags
|
||||||
|
flags = FLAG_CLEANSESS(flags, _cleanSession ? 1 : 0 );
|
||||||
|
flags = FLAG_WILL(flags, willTopic().isEmpty() ? 0 : 1);
|
||||||
|
if (!willTopic().isEmpty())
|
||||||
|
{
|
||||||
|
flags = FLAG_WILLQOS(flags, willQos());
|
||||||
|
flags = FLAG_WILLRETAIN(flags, willRetain() ? 1 : 0);
|
||||||
|
}
|
||||||
|
if (!username().isEmpty())
|
||||||
|
{
|
||||||
|
flags = FLAG_USERNAME(flags, 1);
|
||||||
|
flags = FLAG_PASSWD(flags, !password().isEmpty() ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//payload
|
||||||
|
if(_version == V3_1_1)
|
||||||
|
{
|
||||||
|
frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_0));
|
||||||
|
}
|
||||||
|
frame.writeChar(_version);
|
||||||
|
frame.writeChar(flags);
|
||||||
|
frame.writeInt(keepAlive());
|
||||||
|
frame.writeString(_clientId);
|
||||||
|
if(!willTopic().isEmpty())
|
||||||
|
{
|
||||||
|
frame.writeString(willTopic());
|
||||||
|
// According to the specs (http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718031)
|
||||||
|
// the will message gets always sent together with the topic, also when it is empty which is perfectly valid.
|
||||||
|
frame.writeByteArray(_willMessage);
|
||||||
|
}
|
||||||
|
if (!_username.isEmpty())
|
||||||
|
{
|
||||||
|
frame.writeString(_username);
|
||||||
|
if (!_password.isEmpty())
|
||||||
|
{
|
||||||
|
frame.writeByteArray(_password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::ClientPrivate::sendPublish(const Message &message)
|
||||||
|
{
|
||||||
|
quint16 msgid = message.id();
|
||||||
|
|
||||||
|
quint8 header = PUBLISH;
|
||||||
|
header = SETRETAIN(header, message.retain() ? 1 : 0);
|
||||||
|
header = SETQOS(header, message.qos());
|
||||||
|
header = SETDUP(header, message.dup() ? 1 : 0);
|
||||||
|
Frame frame(header);
|
||||||
|
frame.writeString(message.topic());
|
||||||
|
if(message.qos() > QOS0) {
|
||||||
|
if (msgid == 0)
|
||||||
|
msgid = nextmid();
|
||||||
|
frame.writeInt(msgid);
|
||||||
|
}
|
||||||
|
if(!message.payload().isEmpty()) {
|
||||||
|
frame.writeRawData(message.payload());
|
||||||
|
}
|
||||||
|
sendFrame(frame);
|
||||||
|
return msgid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::sendPuback(const quint8 type, const quint16 mid)
|
||||||
|
{
|
||||||
|
Frame frame(type);
|
||||||
|
frame.writeInt(mid);
|
||||||
|
sendFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::ClientPrivate::sendSubscribe(const QString & topic, const quint8 qos)
|
||||||
|
{
|
||||||
|
quint16 mid = nextmid();
|
||||||
|
Frame frame(SETQOS(SUBSCRIBE, QOS1));
|
||||||
|
frame.writeInt(mid);
|
||||||
|
frame.writeString(topic);
|
||||||
|
frame.writeChar(qos);
|
||||||
|
sendFrame(frame);
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::ClientPrivate::sendUnsubscribe(const QString &topic)
|
||||||
|
{
|
||||||
|
quint16 mid = nextmid();
|
||||||
|
Frame frame(SETQOS(UNSUBSCRIBE, QOS1));
|
||||||
|
frame.writeInt(mid);
|
||||||
|
frame.writeString(topic);
|
||||||
|
sendFrame(frame);
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::onTimerPingReq()
|
||||||
|
{
|
||||||
|
if (!isConnectedToHost())
|
||||||
|
return;
|
||||||
|
Frame frame(PINGREQ);
|
||||||
|
sendFrame(frame);
|
||||||
|
_pingResponseTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::onPingTimeout()
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
emit q->error(MqttNoPingResponse);
|
||||||
|
disconnectFromHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::disconnectFromHost()
|
||||||
|
{
|
||||||
|
_connectionState = ConnectionState::STATE_DISCONNECTED;
|
||||||
|
sendDisconnect();
|
||||||
|
_network->disconnectFromHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::sendDisconnect()
|
||||||
|
{
|
||||||
|
Frame frame(DISCONNECT);
|
||||||
|
sendFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::sendFrame(const Frame &frame)
|
||||||
|
{
|
||||||
|
_network->sendFrame(frame);
|
||||||
|
_timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::stopKeepAlive()
|
||||||
|
{
|
||||||
|
_timer.stop();
|
||||||
|
_pingResponseTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::ClientPrivate::nextmid()
|
||||||
|
{
|
||||||
|
return _gmid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::ClientPrivate::publish(const Message& message)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
quint16 msgid = sendPublish(message);
|
||||||
|
|
||||||
|
// Emit published only at QOS0
|
||||||
|
if (message.qos() == QOS0)
|
||||||
|
emit q->published(message, msgid);
|
||||||
|
else
|
||||||
|
_midToMessage[msgid] = message;
|
||||||
|
|
||||||
|
return msgid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::puback(const quint8 type, const quint16 msgid)
|
||||||
|
{
|
||||||
|
sendPuback(type, msgid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::subscribe(const QString& topic, const quint8 qos)
|
||||||
|
{
|
||||||
|
quint16 msgid = sendSubscribe(topic, qos);
|
||||||
|
_midToTopic[msgid] = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::unsubscribe(const QString& topic)
|
||||||
|
{
|
||||||
|
quint16 msgid = sendUnsubscribe(topic);
|
||||||
|
_midToTopic[msgid] = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::onNetworkDisconnected()
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
|
||||||
|
stopKeepAlive();
|
||||||
|
_midToTopic.clear();
|
||||||
|
_midToMessage.clear();
|
||||||
|
emit q->disconnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::onNetworkReceived(const QMQTT::Frame& frm)
|
||||||
|
{
|
||||||
|
QMQTT::Frame frame(frm);
|
||||||
|
quint8 qos = 0;
|
||||||
|
bool retain, dup;
|
||||||
|
QString topic;
|
||||||
|
quint16 mid = 0;
|
||||||
|
quint8 header = frame.header();
|
||||||
|
quint8 type = GETTYPE(header);
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case CONNACK:
|
||||||
|
frame.readChar();
|
||||||
|
handleConnack(frame.readChar());
|
||||||
|
break;
|
||||||
|
case PUBLISH:
|
||||||
|
qos = GETQOS(header);
|
||||||
|
retain = GETRETAIN(header);
|
||||||
|
dup = GETDUP(header);
|
||||||
|
topic = frame.readString();
|
||||||
|
if( qos > QOS0) {
|
||||||
|
mid = frame.readInt();
|
||||||
|
}
|
||||||
|
handlePublish(Message(mid, topic, frame.data(), qos, retain, dup));
|
||||||
|
break;
|
||||||
|
case PUBACK:
|
||||||
|
case PUBREC:
|
||||||
|
case PUBREL:
|
||||||
|
case PUBCOMP:
|
||||||
|
mid = frame.readInt();
|
||||||
|
handlePuback(type, mid);
|
||||||
|
break;
|
||||||
|
case SUBACK:
|
||||||
|
mid = frame.readInt();
|
||||||
|
topic = _midToTopic.take(mid);
|
||||||
|
qos = frame.readChar();
|
||||||
|
handleSuback(topic, qos);
|
||||||
|
break;
|
||||||
|
case UNSUBACK:
|
||||||
|
mid = frame.readInt();
|
||||||
|
topic = _midToTopic.take(mid);
|
||||||
|
handleUnsuback(topic);
|
||||||
|
break;
|
||||||
|
case PINGRESP:
|
||||||
|
handlePingresp();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::handleConnack(const quint8 ack)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
|
||||||
|
switch (ack)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
_connectionState = ConnectionState::STATE_CONNECTED;
|
||||||
|
emit q->connected();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
emit q->error(MqttUnacceptableProtocolVersionError);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
emit q->error(MqttIdentifierRejectedError);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
emit q->error(MqttServerUnavailableError);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
emit q->error(MqttBadUserNameOrPasswordError);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
emit q->error(MqttNotAuthorizedError);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
emit q->error(UnknownError);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::handlePublish(const Message& message)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
|
||||||
|
if(message.qos() == QOS1)
|
||||||
|
{
|
||||||
|
sendPuback(PUBACK, message.id());
|
||||||
|
}
|
||||||
|
else if(message.qos() == QOS2)
|
||||||
|
{
|
||||||
|
sendPuback(PUBREC, message.id());
|
||||||
|
}
|
||||||
|
emit q->received(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::handlePuback(const quint8 type, const quint16 msgid)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case PUBREC:
|
||||||
|
sendPuback(SETQOS(PUBREL, QOS1), msgid);
|
||||||
|
break;
|
||||||
|
case PUBREL:
|
||||||
|
sendPuback(PUBCOMP, msgid);
|
||||||
|
break;
|
||||||
|
case PUBACK:
|
||||||
|
case PUBCOMP:
|
||||||
|
// Emit published on PUBACK at QOS1 and on PUBCOMP at QOS2
|
||||||
|
emit q->published(_midToMessage.take(msgid), msgid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::handlePingresp()
|
||||||
|
{
|
||||||
|
// Stop the ping response timer to prevent disconnection. It will be restarted when the next
|
||||||
|
// ping request has been sent.
|
||||||
|
_pingResponseTimer.stop();
|
||||||
|
Q_Q(Client);
|
||||||
|
emit q->pingresp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::handleSuback(const QString &topic, const quint8 qos)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
emit q->subscribed(topic, qos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::handleUnsuback(const QString &topic) {
|
||||||
|
Q_Q(Client);
|
||||||
|
emit q->unsubscribed(topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::ClientPrivate::autoReconnect() const
|
||||||
|
{
|
||||||
|
return _network->autoReconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setAutoReconnect(const bool autoReconnect)
|
||||||
|
{
|
||||||
|
_network->setAutoReconnect(autoReconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
int QMQTT::ClientPrivate::autoReconnectInterval() const
|
||||||
|
{
|
||||||
|
return _network->autoReconnectInterval();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setAutoReconnectInterval(const int autoReconnectInterval)
|
||||||
|
{
|
||||||
|
_network->setAutoReconnectInterval(autoReconnectInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::ClientPrivate::isConnectedToHost() const
|
||||||
|
{
|
||||||
|
return _network->isConnectedToHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::ConnectionState QMQTT::ClientPrivate::connectionState() const
|
||||||
|
{
|
||||||
|
return _connectionState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setCleanSession(const bool cleanSession)
|
||||||
|
{
|
||||||
|
_cleanSession = cleanSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::ClientPrivate::cleanSession() const
|
||||||
|
{
|
||||||
|
return _cleanSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setKeepAlive(const quint16 keepAlive)
|
||||||
|
{
|
||||||
|
// _timer will be started when a message is sent.
|
||||||
|
_timer.setInterval(keepAlive*1000);
|
||||||
|
// The MQTT specification does not mention a timeout value in this case, so we use 10% of the
|
||||||
|
// keep alive interval.
|
||||||
|
_pingResponseTimer.setInterval(qBound(keepAlive * 100, 10000, keepAlive * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::ClientPrivate::keepAlive() const
|
||||||
|
{
|
||||||
|
return _timer.interval() / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setPassword(const QByteArray& password)
|
||||||
|
{
|
||||||
|
_password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray QMQTT::ClientPrivate::password() const
|
||||||
|
{
|
||||||
|
return _password;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setUsername(const QString& username)
|
||||||
|
{
|
||||||
|
_username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QMQTT::ClientPrivate::username() const
|
||||||
|
{
|
||||||
|
return _username;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setVersion(const MQTTVersion version)
|
||||||
|
{
|
||||||
|
_version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::MQTTVersion QMQTT::ClientPrivate::version() const
|
||||||
|
{
|
||||||
|
return _version;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setClientId(const QString& clientId)
|
||||||
|
{
|
||||||
|
if(clientId.isEmpty())
|
||||||
|
{
|
||||||
|
_clientId = QUuid::createUuid().toString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_clientId = clientId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QMQTT::ClientPrivate::clientId() const
|
||||||
|
{
|
||||||
|
return _clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setPort(const quint16 port)
|
||||||
|
{
|
||||||
|
_port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QMQTT::ClientPrivate::port() const
|
||||||
|
{
|
||||||
|
return _port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setHost(const QHostAddress& host)
|
||||||
|
{
|
||||||
|
_host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHostAddress QMQTT::ClientPrivate::host() const
|
||||||
|
{
|
||||||
|
return _host;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setHostName(const QString& hostName)
|
||||||
|
{
|
||||||
|
_hostName = hostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QMQTT::ClientPrivate::hostName() const
|
||||||
|
{
|
||||||
|
return _hostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QMQTT::ClientPrivate::willTopic() const
|
||||||
|
{
|
||||||
|
return _willTopic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setWillTopic(const QString& willTopic)
|
||||||
|
{
|
||||||
|
_willTopic = willTopic;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 QMQTT::ClientPrivate::willQos() const
|
||||||
|
{
|
||||||
|
return _willQos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setWillQos(const quint8 willQos)
|
||||||
|
{
|
||||||
|
_willQos = willQos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::ClientPrivate::willRetain() const
|
||||||
|
{
|
||||||
|
return _willRetain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setWillRetain(const bool willRetain)
|
||||||
|
{
|
||||||
|
_willRetain = willRetain;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray QMQTT::ClientPrivate::willMessage() const
|
||||||
|
{
|
||||||
|
return _willMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setWillMessage(const QByteArray& willMessage)
|
||||||
|
{
|
||||||
|
_willMessage = willMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::onNetworkError(QAbstractSocket::SocketError socketError)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
|
||||||
|
switch (socketError)
|
||||||
|
{
|
||||||
|
case QAbstractSocket::ConnectionRefusedError:
|
||||||
|
emit q->error(SocketConnectionRefusedError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::RemoteHostClosedError:
|
||||||
|
emit q->error(SocketRemoteHostClosedError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::HostNotFoundError:
|
||||||
|
emit q->error(SocketHostNotFoundError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::SocketAccessError:
|
||||||
|
emit q->error(SocketAccessError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::SocketResourceError:
|
||||||
|
emit q->error(SocketResourceError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::SocketTimeoutError:
|
||||||
|
emit q->error(SocketTimeoutError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::DatagramTooLargeError:
|
||||||
|
emit q->error(SocketDatagramTooLargeError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::NetworkError:
|
||||||
|
emit q->error(SocketNetworkError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::AddressInUseError:
|
||||||
|
emit q->error(SocketAddressInUseError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::SocketAddressNotAvailableError:
|
||||||
|
emit q->error(SocketAddressNotAvailableError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::UnsupportedSocketOperationError:
|
||||||
|
emit q->error(SocketUnsupportedSocketOperationError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::UnfinishedSocketOperationError:
|
||||||
|
emit q->error(SocketUnfinishedSocketOperationError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::ProxyAuthenticationRequiredError:
|
||||||
|
emit q->error(SocketProxyAuthenticationRequiredError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::SslHandshakeFailedError:
|
||||||
|
emit q->error(SocketSslHandshakeFailedError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::ProxyConnectionRefusedError:
|
||||||
|
emit q->error(SocketProxyConnectionRefusedError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::ProxyConnectionClosedError:
|
||||||
|
emit q->error(SocketProxyConnectionClosedError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::ProxyConnectionTimeoutError:
|
||||||
|
emit q->error(SocketProxyConnectionTimeoutError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::ProxyNotFoundError:
|
||||||
|
emit q->error(SocketProxyNotFoundError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::ProxyProtocolError:
|
||||||
|
emit q->error(SocketProxyProtocolError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::OperationError:
|
||||||
|
emit q->error(SocketOperationError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::SslInternalError:
|
||||||
|
emit q->error(SocketSslInternalError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::SslInvalidUserDataError:
|
||||||
|
emit q->error(SocketSslInvalidUserDataError);
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::TemporaryError:
|
||||||
|
emit q->error(SocketTemporaryError);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
emit q->error(UnknownError);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void QMQTT::ClientPrivate::ignoreSslErrors()
|
||||||
|
{
|
||||||
|
_network->ignoreSslErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::ignoreSslErrors(const QList<QSslError>& errors)
|
||||||
|
{
|
||||||
|
_network->ignoreSslErrors(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSslConfiguration QMQTT::ClientPrivate::sslConfiguration() const
|
||||||
|
{
|
||||||
|
return _network->sslConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::setSslConfiguration(const QSslConfiguration& config)
|
||||||
|
{
|
||||||
|
_network->setSslConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::ClientPrivate::onSslErrors(const QList<QSslError>& errors)
|
||||||
|
{
|
||||||
|
Q_Q(Client);
|
||||||
|
|
||||||
|
emit q->sslErrors(errors);
|
||||||
|
|
||||||
|
if (!_ignoreSelfSigned)
|
||||||
|
return;
|
||||||
|
foreach (QSslError error, errors)
|
||||||
|
{
|
||||||
|
if (error.error() != QSslError::SelfSignedCertificate &&
|
||||||
|
error.error() != QSslError::SelfSignedCertificateInChain)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ignoreSslErrors();
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_client_p.h - qmqtt client private header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_CLIENT_P_H
|
||||||
|
#define QMQTT_CLIENT_P_H
|
||||||
|
|
||||||
|
#include "qmqtt_client.h"
|
||||||
|
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QString>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QAbstractSocket>
|
||||||
|
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
#include <QWebSocket>
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
#include <QSslConfiguration>
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSslError)
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class NetworkInterface;
|
||||||
|
|
||||||
|
class ClientPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClientPrivate(Client* qq_ptr);
|
||||||
|
~ClientPrivate();
|
||||||
|
|
||||||
|
void init(const QHostAddress& host, const quint16 port, NetworkInterface* network = NULL);
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void init(const QString& hostName, const quint16 port, const QSslConfiguration& config,
|
||||||
|
const bool ignoreSelfSigned=false);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
void init(const QString& hostName, const quint16 port, const bool ssl, const bool ignoreSelfSigned);
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void init(const QString& url,
|
||||||
|
const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
const QSslConfiguration* sslConfig,
|
||||||
|
bool ignoreSelfSigned);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
void init(const QString& url,
|
||||||
|
const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version);
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
void init(NetworkInterface* network);
|
||||||
|
|
||||||
|
QHostAddress _host;
|
||||||
|
QString _hostName;
|
||||||
|
quint16 _port;
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
QWebSocketProtocol::Version _webSocketVersion;
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
bool _ignoreSelfSigned;
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
quint16 _gmid;
|
||||||
|
MQTTVersion _version;
|
||||||
|
QString _clientId;
|
||||||
|
QString _username;
|
||||||
|
QByteArray _password;
|
||||||
|
bool _cleanSession;
|
||||||
|
ConnectionState _connectionState;
|
||||||
|
QScopedPointer<NetworkInterface> _network;
|
||||||
|
QTimer _timer;
|
||||||
|
QTimer _pingResponseTimer;
|
||||||
|
QString _willTopic;
|
||||||
|
quint8 _willQos;
|
||||||
|
bool _willRetain;
|
||||||
|
QByteArray _willMessage;
|
||||||
|
QHash<quint16, QString> _midToTopic;
|
||||||
|
QHash<quint16, Message> _midToMessage;
|
||||||
|
|
||||||
|
Client* const q_ptr;
|
||||||
|
|
||||||
|
quint16 nextmid();
|
||||||
|
void connectToHost();
|
||||||
|
void sendConnect();
|
||||||
|
void onTimerPingReq();
|
||||||
|
void onPingTimeout();
|
||||||
|
quint16 sendUnsubscribe(const QString &topic);
|
||||||
|
quint16 sendSubscribe(const QString &topic, const quint8 qos);
|
||||||
|
quint16 sendPublish(const Message &message);
|
||||||
|
void sendPuback(const quint8 type, const quint16 mid);
|
||||||
|
void sendDisconnect();
|
||||||
|
void sendFrame(const Frame &frame);
|
||||||
|
void disconnectFromHost();
|
||||||
|
void stopKeepAlive();
|
||||||
|
void onNetworkConnected();
|
||||||
|
void onNetworkDisconnected();
|
||||||
|
quint16 publish(const Message& message);
|
||||||
|
void puback(const quint8 type, const quint16 msgid);
|
||||||
|
void subscribe(const QString& topic, const quint8 qos);
|
||||||
|
void unsubscribe(const QString& topic);
|
||||||
|
void onNetworkReceived(const QMQTT::Frame& frame);
|
||||||
|
void handleConnack(const quint8 ack);
|
||||||
|
void handlePublish(const Message& message);
|
||||||
|
void handlePuback(const quint8 type, const quint16 msgid);
|
||||||
|
void handleSuback(const QString& topic, const quint8 qos);
|
||||||
|
void handleUnsuback(const QString& topic);
|
||||||
|
void handlePingresp();
|
||||||
|
bool autoReconnect() const;
|
||||||
|
void setAutoReconnect(const bool autoReconnect);
|
||||||
|
int autoReconnectInterval() const;
|
||||||
|
void setAutoReconnectInterval(const int autoReconnectInterval);
|
||||||
|
bool isConnectedToHost() const;
|
||||||
|
QMQTT::ConnectionState connectionState() const;
|
||||||
|
void setCleanSession(const bool cleanSession);
|
||||||
|
bool cleanSession() const;
|
||||||
|
void setKeepAlive(const quint16 keepAlive);
|
||||||
|
quint16 keepAlive() const;
|
||||||
|
void setPassword(const QByteArray& password);
|
||||||
|
QByteArray password() const;
|
||||||
|
void setUsername(const QString& username);
|
||||||
|
QString username() const;
|
||||||
|
void setVersion(const MQTTVersion);
|
||||||
|
MQTTVersion version() const;
|
||||||
|
void setClientId(const QString& clientId);
|
||||||
|
QString clientId() const;
|
||||||
|
void setPort(const quint16 port);
|
||||||
|
quint16 port() const;
|
||||||
|
void setHost(const QHostAddress& host);
|
||||||
|
QHostAddress host() const;
|
||||||
|
void setHostName(const QString& hostName);
|
||||||
|
QString hostName() const;
|
||||||
|
void setWillTopic(const QString& willTopic);
|
||||||
|
void setWillQos(const quint8 willQos);
|
||||||
|
void setWillRetain(const bool willRetain);
|
||||||
|
void setWillMessage(const QByteArray& willMessage);
|
||||||
|
QString willTopic() const;
|
||||||
|
quint8 willQos() const;
|
||||||
|
bool willRetain() const;
|
||||||
|
QByteArray willMessage() const;
|
||||||
|
void onNetworkError(QAbstractSocket::SocketError error);
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void ignoreSslErrors();
|
||||||
|
void ignoreSslErrors(const QList<QSslError>& errors);
|
||||||
|
QSslConfiguration sslConfiguration() const;
|
||||||
|
void setSslConfiguration(const QSslConfiguration& config);
|
||||||
|
void onSslErrors(const QList<QSslError>& errors);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
Q_DECLARE_PUBLIC(Client)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
#endif // QMQTT_CLIENT_P_H
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_frame.cpp - qmqtt frame
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_frame.h"
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(frame, "qmqtt.frame")
|
||||||
|
|
||||||
|
Frame::Frame()
|
||||||
|
: _header(0)
|
||||||
|
, _data(QByteArray())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame::Frame(const quint8 header)
|
||||||
|
: _header(header)
|
||||||
|
, _data(QByteArray())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame::Frame(const quint8 header, const QByteArray &data)
|
||||||
|
: _header(header)
|
||||||
|
, _data(data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame::Frame(const Frame& other)
|
||||||
|
{
|
||||||
|
_header = other._header;
|
||||||
|
_data = other._data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Frame& Frame::operator=(const Frame& other)
|
||||||
|
{
|
||||||
|
_header = other._header;
|
||||||
|
_data = other._data;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Frame::operator==(const Frame& other) const
|
||||||
|
{
|
||||||
|
return _header == other._header
|
||||||
|
&& _data == other._data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Frame::~Frame()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 Frame::header() const
|
||||||
|
{
|
||||||
|
return _header;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Frame::data() const
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 Frame::readChar()
|
||||||
|
{
|
||||||
|
char c = _data.at(0);
|
||||||
|
_data.remove(0, 1);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 Frame::readInt()
|
||||||
|
{
|
||||||
|
quint8 msb = static_cast<quint8>(_data.at(0));
|
||||||
|
quint8 lsb = static_cast<quint8>(_data.at(1));
|
||||||
|
_data.remove(0, 2);
|
||||||
|
return (msb << 8) | lsb;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Frame::readByteArray()
|
||||||
|
{
|
||||||
|
quint16 len = readInt();
|
||||||
|
QByteArray data = _data.left(len);
|
||||||
|
_data.remove(0, len);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Frame::readString()
|
||||||
|
{
|
||||||
|
quint16 len = readInt();
|
||||||
|
QString s = QString::fromUtf8(_data.left(len));
|
||||||
|
_data.remove(0, len);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Frame::writeInt(const quint16 i)
|
||||||
|
{
|
||||||
|
_data.append(MSB(i));
|
||||||
|
_data.append(LSB(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Frame::writeByteArray(const QByteArray &data)
|
||||||
|
{
|
||||||
|
if (data.size() > (int)USHRT_MAX)
|
||||||
|
{
|
||||||
|
qCritical("qmqtt: Binary data size bigger than %u bytes, truncate it!", USHRT_MAX);
|
||||||
|
writeInt(USHRT_MAX);
|
||||||
|
_data.append(data.left(USHRT_MAX));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeInt(data.size());
|
||||||
|
_data.append(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Frame::writeString(const QString &string)
|
||||||
|
{
|
||||||
|
QByteArray data = string.toUtf8();
|
||||||
|
if (data.size() > (int)USHRT_MAX)
|
||||||
|
{
|
||||||
|
qCritical("qmqtt: String size bigger than %u bytes, truncate it!", USHRT_MAX);
|
||||||
|
data.resize(USHRT_MAX);
|
||||||
|
}
|
||||||
|
writeInt(data.size());
|
||||||
|
_data.append(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Frame::writeChar(const quint8 c)
|
||||||
|
{
|
||||||
|
_data.append(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Frame::writeRawData(const QByteArray &data)
|
||||||
|
{
|
||||||
|
_data.append(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Frame::write(QDataStream &stream) const
|
||||||
|
{
|
||||||
|
QByteArray lenbuf;
|
||||||
|
|
||||||
|
if (!encodeLength(lenbuf, _data.size()))
|
||||||
|
{
|
||||||
|
qCritical("qmqtt: Control packet bigger than 256 MB, dropped!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream << (quint8)_header;
|
||||||
|
if(_data.size() == 0) {
|
||||||
|
stream << (quint8)0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (stream.writeRawData(lenbuf.data(), lenbuf.size()) != lenbuf.size())
|
||||||
|
{
|
||||||
|
qCritical("qmqtt: Control packet write error!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (stream.writeRawData(_data.data(), _data.size()) != _data.size())
|
||||||
|
{
|
||||||
|
qCritical("qmqtt: Control packet write error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Frame::encodeLength(QByteArray &lenbuf, int length) const
|
||||||
|
{
|
||||||
|
lenbuf.clear();
|
||||||
|
quint8 d;
|
||||||
|
do {
|
||||||
|
d = length % 128;
|
||||||
|
length /= 128;
|
||||||
|
if (length > 0) {
|
||||||
|
d |= 0x80;
|
||||||
|
}
|
||||||
|
lenbuf.append(d);
|
||||||
|
} while (length > 0);
|
||||||
|
|
||||||
|
return lenbuf.size() <= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_frame.h - qmqtt frame heaer
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_FRAME_H
|
||||||
|
#define QMQTT_FRAME_H
|
||||||
|
|
||||||
|
#include "qmqtt_global.h"
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QDataStream)
|
||||||
|
|
||||||
|
#define PROTOCOL_MAGIC_3_1_0 "MQIsdp"
|
||||||
|
#define PROTOCOL_MAGIC_3_1_1 "MQTT"
|
||||||
|
|
||||||
|
#define RANDOM_CLIENT_PREFIX "QMQTT-"
|
||||||
|
|
||||||
|
#define CONNECT 0x10
|
||||||
|
#define CONNACK 0x20
|
||||||
|
#define PUBLISH 0x30
|
||||||
|
#define PUBACK 0x40
|
||||||
|
#define PUBREC 0x50
|
||||||
|
#define PUBREL 0x60
|
||||||
|
#define PUBCOMP 0x70
|
||||||
|
#define SUBSCRIBE 0x80
|
||||||
|
#define SUBACK 0x90
|
||||||
|
#define UNSUBSCRIBE 0xA0
|
||||||
|
#define UNSUBACK 0xB0
|
||||||
|
#define PINGREQ 0xC0
|
||||||
|
#define PINGRESP 0xD0
|
||||||
|
#define DISCONNECT 0xE0
|
||||||
|
|
||||||
|
#define LSB(A) quint8(A & 0x00FF)
|
||||||
|
#define MSB(A) quint8((A & 0xFF00) >> 8)
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------
|
||||||
|
| 7 6 5 4 | 3 | 2 1 | 0 |
|
||||||
|
| Type | DUP flag | QoS | RETAIN |
|
||||||
|
|--------------------------------------
|
||||||
|
*/
|
||||||
|
#define GETTYPE(HDR) (HDR & 0xF0)
|
||||||
|
#define SETQOS(HDR, Q) (HDR | ((Q) << 1))
|
||||||
|
#define GETQOS(HDR) ((HDR & 0x06) >> 1)
|
||||||
|
#define SETDUP(HDR, D) (HDR | ((D) << 3))
|
||||||
|
#define GETDUP(HDR) ((HDR & 0x08) >> 3)
|
||||||
|
#define SETRETAIN(HDR, R) (HDR | (R))
|
||||||
|
#define GETRETAIN(HDR) (HDR & 0x01)
|
||||||
|
|
||||||
|
/*
|
||||||
|
|----------------------------------------------------------------------------------
|
||||||
|
| 7 | 6 | 5 | 4 3 | 2 | 1 | 0 |
|
||||||
|
| username | password | willretain | willqos | willflag | cleansession | reserved |
|
||||||
|
|----------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#define FLAG_CLEANSESS(F, C) (F | ((C) << 1))
|
||||||
|
#define FLAG_WILL(F, W) (F | ((W) << 2))
|
||||||
|
#define FLAG_WILLQOS(F, Q) (F | ((Q) << 3))
|
||||||
|
#define FLAG_WILLRETAIN(F, R) (F | ((R) << 5))
|
||||||
|
#define FLAG_PASSWD(F, P) (F | ((P) << 6))
|
||||||
|
#define FLAG_USERNAME(F, U) (F | ((U) << 7))
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class Q_MQTT_EXPORT Frame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Frame();
|
||||||
|
explicit Frame(const quint8 header);
|
||||||
|
explicit Frame(const quint8 header, const QByteArray &data);
|
||||||
|
virtual ~Frame();
|
||||||
|
|
||||||
|
Frame(const Frame& other);
|
||||||
|
Frame& operator=(const Frame& other);
|
||||||
|
|
||||||
|
bool operator==(const Frame& other) const;
|
||||||
|
inline bool operator!=(const Frame& other) const
|
||||||
|
{ return !operator==(other); }
|
||||||
|
|
||||||
|
quint8 header() const;
|
||||||
|
QByteArray data() const;
|
||||||
|
|
||||||
|
quint16 readInt();
|
||||||
|
quint8 readChar();
|
||||||
|
QByteArray readByteArray();
|
||||||
|
QString readString();
|
||||||
|
|
||||||
|
void writeInt(const quint16 i);
|
||||||
|
void writeChar(const quint8 c);
|
||||||
|
void writeByteArray(const QByteArray &data);
|
||||||
|
void writeString(const QString &string);
|
||||||
|
void writeRawData(const QByteArray &data);
|
||||||
|
|
||||||
|
//TODO: FIXME LATER
|
||||||
|
void write(QDataStream &stream) const;
|
||||||
|
bool encodeLength(QByteArray &lenbuf, int length) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
quint8 _header;
|
||||||
|
QByteArray _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QMQTT::Frame)
|
||||||
|
|
||||||
|
#endif // QMQTT_FRAME_H
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_global.h - qmqtt libray global
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_GLOBAL_H
|
||||||
|
#define QMQTT_GLOBAL_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#ifndef QT_STATIC
|
||||||
|
# if defined(QT_BUILD_QMQTT_LIB)
|
||||||
|
# define Q_MQTT_EXPORT Q_DECL_EXPORT
|
||||||
|
# else
|
||||||
|
# define Q_MQTT_EXPORT Q_DECL_IMPORT
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define Q_MQTT_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // QMQTT_GLOBAL_H
|
||||||
|
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_message.cpp - qmqtt message
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_message.h"
|
||||||
|
#include "qmqtt_message_p.h"
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
Message::Message()
|
||||||
|
: d(new MessagePrivate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Message::Message(const quint16 id, const QString &topic, const QByteArray &payload,
|
||||||
|
const quint8 qos, const bool retain, const bool dup)
|
||||||
|
: d(new MessagePrivate(id, topic, payload, qos, retain, dup))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Message::Message(const Message &other)
|
||||||
|
: d(other.d)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Message::~Message()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Message &Message::operator=(const Message &other)
|
||||||
|
{
|
||||||
|
d = other.d;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Message::operator==(const Message &other) const
|
||||||
|
{
|
||||||
|
if (d == other.d)
|
||||||
|
return true;
|
||||||
|
return d->id == other.d->id
|
||||||
|
&& d->qos == other.d->qos
|
||||||
|
&& d->retain == other.d->retain
|
||||||
|
&& d->dup == other.d->dup
|
||||||
|
&& d->topic == other.d->topic
|
||||||
|
&& d->payload == other.d->payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 Message::id() const
|
||||||
|
{
|
||||||
|
return d->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Message::setId(const quint16 id)
|
||||||
|
{
|
||||||
|
d->id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 Message::qos() const
|
||||||
|
{
|
||||||
|
return d->qos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Message::setQos(const quint8 qos)
|
||||||
|
{
|
||||||
|
d->qos = qos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Message::retain() const
|
||||||
|
{
|
||||||
|
return d->retain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Message::setRetain(const bool retain)
|
||||||
|
{
|
||||||
|
d->retain = retain;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Message::dup() const
|
||||||
|
{
|
||||||
|
return d->dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Message::setDup(const bool dup)
|
||||||
|
{
|
||||||
|
d->dup = dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Message::topic() const
|
||||||
|
{
|
||||||
|
return d->topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Message::setTopic(const QString &topic)
|
||||||
|
{
|
||||||
|
d->topic = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Message::payload() const
|
||||||
|
{
|
||||||
|
return d->payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Message::setPayload(const QByteArray &payload)
|
||||||
|
{
|
||||||
|
d->payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_message.h - qmqtt message header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_MESSAGE_H
|
||||||
|
#define QMQTT_MESSAGE_H
|
||||||
|
|
||||||
|
#include "qmqtt_global.h"
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QString>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QSharedDataPointer>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class MessagePrivate;
|
||||||
|
|
||||||
|
class Q_MQTT_EXPORT Message
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Message();
|
||||||
|
explicit Message(const quint16 id, const QString &topic, const QByteArray &payload,
|
||||||
|
const quint8 qos = 0, const bool retain = false, const bool dup = false);
|
||||||
|
Message(const Message &other);
|
||||||
|
~Message();
|
||||||
|
|
||||||
|
Message &operator=(const Message &other);
|
||||||
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
|
inline Message &operator=(Message &&other) Q_DECL_NOTHROW
|
||||||
|
{ swap(other); return *this; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool operator==(const Message &other) const;
|
||||||
|
inline bool operator!=(const Message &other) const
|
||||||
|
{ return !operator==(other); }
|
||||||
|
|
||||||
|
inline void swap(Message &other) Q_DECL_NOTHROW
|
||||||
|
{ qSwap(d, other.d); }
|
||||||
|
|
||||||
|
quint16 id() const;
|
||||||
|
void setId(const quint16 id);
|
||||||
|
|
||||||
|
quint8 qos() const;
|
||||||
|
void setQos(const quint8 qos);
|
||||||
|
|
||||||
|
bool retain() const;
|
||||||
|
void setRetain(const bool retain);
|
||||||
|
|
||||||
|
bool dup() const;
|
||||||
|
void setDup(const bool dup);
|
||||||
|
|
||||||
|
QString topic() const;
|
||||||
|
void setTopic(const QString &topic);
|
||||||
|
|
||||||
|
QByteArray payload() const;
|
||||||
|
void setPayload(const QByteArray &payload);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedDataPointer<MessagePrivate> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
Q_DECLARE_SHARED(QMQTT::Message)
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QMQTT::Message)
|
||||||
|
|
||||||
|
#endif // QMQTT_MESSAGE_H
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_message.h - qmqtt message private header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_MESSAGE_P_H
|
||||||
|
#define QMQTT_MESSAGE_P_H
|
||||||
|
|
||||||
|
#include <QSharedData>
|
||||||
|
#include <QString>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class MessagePrivate : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline MessagePrivate()
|
||||||
|
: QSharedData(),
|
||||||
|
id(0),
|
||||||
|
qos(0),
|
||||||
|
retain(false),
|
||||||
|
dup(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline MessagePrivate(const MessagePrivate &other)
|
||||||
|
: QSharedData(other),
|
||||||
|
id(other.id),
|
||||||
|
qos(other.qos),
|
||||||
|
retain(other.retain),
|
||||||
|
dup(other.dup),
|
||||||
|
topic(other.topic),
|
||||||
|
payload(other.payload)
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline MessagePrivate(quint16 id, const QString &topic, const QByteArray &payload,
|
||||||
|
quint8 qos, bool retain, bool dup)
|
||||||
|
: QSharedData(),
|
||||||
|
id(id),
|
||||||
|
qos(qos),
|
||||||
|
retain(retain),
|
||||||
|
dup(dup),
|
||||||
|
topic(topic),
|
||||||
|
payload(payload)
|
||||||
|
{}
|
||||||
|
|
||||||
|
quint16 id;
|
||||||
|
quint8 qos : 2;
|
||||||
|
quint8 retain: 1;
|
||||||
|
quint8 dup: 1;
|
||||||
|
QString topic;
|
||||||
|
QByteArray payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
#endif // QMQTT_MESSAGE_P_H
|
||||||
@@ -0,0 +1,295 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_network.cpp - qmqtt network
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_network_p.h"
|
||||||
|
#include "qmqtt_socket_p.h"
|
||||||
|
#include "qmqtt_ssl_socket_p.h"
|
||||||
|
#include "qmqtt_timer_p.h"
|
||||||
|
#include "qmqtt_websocket_p.h"
|
||||||
|
#include "qmqtt_frame.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
|
const quint16 DEFAULT_PORT = 1883;
|
||||||
|
const quint16 DEFAULT_SSL_PORT = 8883;
|
||||||
|
const bool DEFAULT_AUTORECONNECT = false;
|
||||||
|
const int DEFAULT_AUTORECONNECT_INTERVAL_MS = 5000;
|
||||||
|
|
||||||
|
QMQTT::Network::Network(QObject* parent)
|
||||||
|
: NetworkInterface(parent)
|
||||||
|
, _port(DEFAULT_PORT)
|
||||||
|
, _autoReconnect(DEFAULT_AUTORECONNECT)
|
||||||
|
, _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
|
||||||
|
, _socket(new QMQTT::Socket)
|
||||||
|
, _autoReconnectTimer(new QMQTT::Timer)
|
||||||
|
, _readState(Header)
|
||||||
|
{
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
QMQTT::Network::Network(const QSslConfiguration& config, QObject *parent)
|
||||||
|
: NetworkInterface(parent)
|
||||||
|
, _port(DEFAULT_SSL_PORT)
|
||||||
|
, _autoReconnect(DEFAULT_AUTORECONNECT)
|
||||||
|
, _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
|
||||||
|
, _socket(new QMQTT::SslSocket(config))
|
||||||
|
, _autoReconnectTimer(new QMQTT::Timer)
|
||||||
|
, _readState(Header)
|
||||||
|
{
|
||||||
|
initialize();
|
||||||
|
connect(_socket, &QMQTT::SslSocket::sslErrors, this, &QMQTT::Network::sslErrors);
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
QMQTT::Network::Network(const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
const QSslConfiguration* sslConfig,
|
||||||
|
QObject* parent)
|
||||||
|
: NetworkInterface(parent)
|
||||||
|
, _port(DEFAULT_SSL_PORT)
|
||||||
|
, _autoReconnect(DEFAULT_AUTORECONNECT)
|
||||||
|
, _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
|
||||||
|
, _socket(new QMQTT::WebSocket(origin, version, sslConfig))
|
||||||
|
, _autoReconnectTimer(new QMQTT::Timer)
|
||||||
|
, _readState(Header)
|
||||||
|
{
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
QMQTT::Network::Network(const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
QObject* parent)
|
||||||
|
: NetworkInterface(parent)
|
||||||
|
, _port(DEFAULT_PORT)
|
||||||
|
, _autoReconnect(DEFAULT_AUTORECONNECT)
|
||||||
|
, _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
|
||||||
|
, _socket(new QMQTT::WebSocket(origin, version))
|
||||||
|
, _autoReconnectTimer(new QMQTT::Timer)
|
||||||
|
, _readState(Header)
|
||||||
|
{
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
QMQTT::Network::Network(SocketInterface* socketInterface, TimerInterface* timerInterface,
|
||||||
|
QObject* parent)
|
||||||
|
: NetworkInterface(parent)
|
||||||
|
, _port(DEFAULT_PORT)
|
||||||
|
, _autoReconnect(DEFAULT_AUTORECONNECT)
|
||||||
|
, _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
|
||||||
|
, _socket(socketInterface)
|
||||||
|
, _autoReconnectTimer(timerInterface)
|
||||||
|
, _readState(Header)
|
||||||
|
{
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::initialize()
|
||||||
|
{
|
||||||
|
_socket->setParent(this);
|
||||||
|
_autoReconnectTimer->setParent(this);
|
||||||
|
_autoReconnectTimer->setSingleShot(true);
|
||||||
|
_autoReconnectTimer->setInterval(_autoReconnectInterval);
|
||||||
|
|
||||||
|
QObject::connect(_socket, &SocketInterface::connected, this, &Network::connected);
|
||||||
|
QObject::connect(_socket, &SocketInterface::disconnected, this, &Network::onDisconnected);
|
||||||
|
QObject::connect(_socket->ioDevice(), &QIODevice::readyRead, this, &Network::onSocketReadReady);
|
||||||
|
QObject::connect(
|
||||||
|
_autoReconnectTimer, &TimerInterface::timeout,
|
||||||
|
this, static_cast<void (Network::*)()>(&Network::connectToHost));
|
||||||
|
QObject::connect(_socket,
|
||||||
|
static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error),
|
||||||
|
this, &Network::onSocketError);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::Network::~Network()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::Network::isConnectedToHost() const
|
||||||
|
{
|
||||||
|
return _socket->state() == QAbstractSocket::ConnectedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::connectToHost(const QHostAddress& host, const quint16 port)
|
||||||
|
{
|
||||||
|
// Reset the hostname, because if it is not empty connectToHost() will use it instead of _host.
|
||||||
|
_hostName.clear();
|
||||||
|
_host = host;
|
||||||
|
_port = port;
|
||||||
|
connectToHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::connectToHost(const QString& hostName, const quint16 port)
|
||||||
|
{
|
||||||
|
_hostName = hostName;
|
||||||
|
_port = port;
|
||||||
|
connectToHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::connectToHost()
|
||||||
|
{
|
||||||
|
_readState = Header;
|
||||||
|
if (_hostName.isEmpty())
|
||||||
|
{
|
||||||
|
_socket->connectToHost(_host, _port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_socket->connectToHost(_hostName, _port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::onSocketError(QAbstractSocket::SocketError socketError)
|
||||||
|
{
|
||||||
|
emit error(socketError);
|
||||||
|
if(_autoReconnect)
|
||||||
|
{
|
||||||
|
_autoReconnectTimer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::sendFrame(const Frame& frame)
|
||||||
|
{
|
||||||
|
if(_socket->state() == QAbstractSocket::ConnectedState)
|
||||||
|
{
|
||||||
|
QDataStream out(_socket->ioDevice());
|
||||||
|
frame.write(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::disconnectFromHost()
|
||||||
|
{
|
||||||
|
_socket->disconnectFromHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractSocket::SocketState QMQTT::Network::state() const
|
||||||
|
{
|
||||||
|
return _socket->state();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::Network::autoReconnect() const
|
||||||
|
{
|
||||||
|
return _autoReconnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::setAutoReconnect(const bool autoReconnect)
|
||||||
|
{
|
||||||
|
_autoReconnect = autoReconnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QMQTT::Network::autoReconnectInterval() const
|
||||||
|
{
|
||||||
|
return _autoReconnectInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::setAutoReconnectInterval(const int autoReconnectInterval)
|
||||||
|
{
|
||||||
|
_autoReconnectInterval = autoReconnectInterval;
|
||||||
|
_autoReconnectTimer->setInterval(_autoReconnectInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::onSocketReadReady()
|
||||||
|
{
|
||||||
|
QIODevice *ioDevice = _socket->ioDevice();
|
||||||
|
// Only read the available (cached) bytes, so the read will never block.
|
||||||
|
QByteArray data = ioDevice->read(ioDevice->bytesAvailable());
|
||||||
|
foreach(char byte, data) {
|
||||||
|
switch (_readState) {
|
||||||
|
case Header:
|
||||||
|
_header = static_cast<quint8>(byte);
|
||||||
|
_readState = Length;
|
||||||
|
_length = 0;
|
||||||
|
_shift = 0;
|
||||||
|
_data.resize(0); // keep allocated buffer
|
||||||
|
break;
|
||||||
|
case Length:
|
||||||
|
_length |= (byte & 0x7F) << _shift;
|
||||||
|
_shift += 7;
|
||||||
|
if ((byte & 0x80) != 0)
|
||||||
|
break;
|
||||||
|
if (_length == 0) {
|
||||||
|
_readState = Header;
|
||||||
|
Frame frame(_header, _data);
|
||||||
|
emit received(frame);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_readState = PayLoad;
|
||||||
|
_data.reserve(_length);
|
||||||
|
break;
|
||||||
|
case PayLoad:
|
||||||
|
_data.append(byte);
|
||||||
|
--_length;
|
||||||
|
if (_length > 0)
|
||||||
|
break;
|
||||||
|
_readState = Header;
|
||||||
|
Frame frame(_header, _data);
|
||||||
|
emit received(frame);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::onDisconnected()
|
||||||
|
{
|
||||||
|
emit disconnected();
|
||||||
|
if(_autoReconnect)
|
||||||
|
{
|
||||||
|
_autoReconnectTimer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void QMQTT::Network::ignoreSslErrors(const QList<QSslError>& errors)
|
||||||
|
{
|
||||||
|
_socket->ignoreSslErrors(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::ignoreSslErrors()
|
||||||
|
{
|
||||||
|
_socket->ignoreSslErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSslConfiguration QMQTT::Network::sslConfiguration() const
|
||||||
|
{
|
||||||
|
return _socket->sslConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Network::setSslConfiguration(const QSslConfiguration& config)
|
||||||
|
{
|
||||||
|
_socket->setSslConfiguration(config);
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_network_p.h - qmqtt network private header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_NETWORK_P_H
|
||||||
|
#define QMQTT_NETWORK_P_H
|
||||||
|
|
||||||
|
#include "qmqtt_networkinterface.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QString>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
#include <QWebSocket>
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
#include <QSslConfiguration>
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSslError)
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class SocketInterface;
|
||||||
|
class TimerInterface;
|
||||||
|
class Frame;
|
||||||
|
|
||||||
|
class Network : public NetworkInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Network(QObject* parent = NULL);
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
Network(const QSslConfiguration& config, QObject* parent = NULL);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
Network(const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
const QSslConfiguration* sslConfig,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
Network(const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
Network(SocketInterface* socketInterface, TimerInterface* timerInterface,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
~Network();
|
||||||
|
|
||||||
|
void sendFrame(const Frame &frame);
|
||||||
|
bool isConnectedToHost() const;
|
||||||
|
bool autoReconnect() const;
|
||||||
|
void setAutoReconnect(const bool autoReconnect);
|
||||||
|
QAbstractSocket::SocketState state() const;
|
||||||
|
int autoReconnectInterval() const;
|
||||||
|
void setAutoReconnectInterval(const int autoReconnectInterval);
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void ignoreSslErrors(const QList<QSslError>& errors);
|
||||||
|
QSslConfiguration sslConfiguration() const;
|
||||||
|
void setSslConfiguration(const QSslConfiguration& config);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void connectToHost(const QHostAddress& host, const quint16 port);
|
||||||
|
void connectToHost(const QString& hostName, const quint16 port);
|
||||||
|
void disconnectFromHost();
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void ignoreSslErrors();
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void onSocketError(QAbstractSocket::SocketError socketError);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
quint16 _port;
|
||||||
|
QHostAddress _host;
|
||||||
|
QString _hostName;
|
||||||
|
bool _autoReconnect;
|
||||||
|
int _autoReconnectInterval;
|
||||||
|
SocketInterface* _socket;
|
||||||
|
TimerInterface* _autoReconnectTimer;
|
||||||
|
|
||||||
|
enum ReadState {
|
||||||
|
Header,
|
||||||
|
Length,
|
||||||
|
PayLoad
|
||||||
|
};
|
||||||
|
|
||||||
|
ReadState _readState;
|
||||||
|
quint8 _header;
|
||||||
|
int _length;
|
||||||
|
int _shift;
|
||||||
|
QByteArray _data;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void onSocketReadReady();
|
||||||
|
void onDisconnected();
|
||||||
|
void connectToHost();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(Network)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
#endif // QMQTT_NETWORK_P_H
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_networkinterface.h - qmqtt network interface header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_NETWORK_INTERFACE_H
|
||||||
|
#define QMQTT_NETWORK_INTERFACE_H
|
||||||
|
|
||||||
|
#include "qmqtt_global.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QAbstractSocket>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QString>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
#include <QSslConfiguration>
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSslError)
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class Frame;
|
||||||
|
|
||||||
|
class Q_MQTT_EXPORT NetworkInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit NetworkInterface(QObject* parent = NULL) : QObject(parent) {}
|
||||||
|
virtual ~NetworkInterface() {}
|
||||||
|
|
||||||
|
virtual void sendFrame(const Frame& frame) = 0;
|
||||||
|
virtual bool isConnectedToHost() const = 0;
|
||||||
|
virtual bool autoReconnect() const = 0;
|
||||||
|
virtual void setAutoReconnect(const bool autoReconnect) = 0;
|
||||||
|
virtual int autoReconnectInterval() const = 0;
|
||||||
|
virtual void setAutoReconnectInterval(const int autoReconnectInterval) = 0;
|
||||||
|
virtual QAbstractSocket::SocketState state() const = 0;
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
virtual void ignoreSslErrors(const QList<QSslError>& errors) = 0;
|
||||||
|
virtual QSslConfiguration sslConfiguration() const = 0;
|
||||||
|
virtual void setSslConfiguration(const QSslConfiguration& config) = 0;
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void connectToHost(const QHostAddress& host, const quint16 port) = 0;
|
||||||
|
virtual void connectToHost(const QString& hostName, const quint16 port) = 0;
|
||||||
|
virtual void disconnectFromHost() = 0;
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
virtual void ignoreSslErrors() = 0;
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void connected();
|
||||||
|
void disconnected();
|
||||||
|
void received(const QMQTT::Frame& frame);
|
||||||
|
void error(QAbstractSocket::SocketError error);
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void sslErrors(const QList<QSslError>& errors);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
#endif // QMQTT_NETWORK_INTERFACE_H
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_router.h - qmqtt router
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* Router added by Niklas Wulf <nwulf at geenen-it-systeme dot de>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_ROUTEDMESSAGE_H
|
||||||
|
#define QMQTT_ROUTEDMESSAGE_H
|
||||||
|
|
||||||
|
#include "qmqtt_message.h"
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class RouteSubscription;
|
||||||
|
|
||||||
|
class Q_MQTT_EXPORT RoutedMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline RoutedMessage()
|
||||||
|
{}
|
||||||
|
inline RoutedMessage(const Message &message)
|
||||||
|
: _message(message)
|
||||||
|
{}
|
||||||
|
|
||||||
|
inline const Message &message() const
|
||||||
|
{ return _message; }
|
||||||
|
inline QHash<QString, QString> parameters() const
|
||||||
|
{ return _parameters; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class RouteSubscription;
|
||||||
|
|
||||||
|
Message _message;
|
||||||
|
QHash<QString, QString> _parameters;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QMQTT::RoutedMessage)
|
||||||
|
|
||||||
|
#endif // QMQTT_ROUTEDMESSAGE_H
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_router.cpp - qmqtt router
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* Router added by Niklas Wulf <nwulf at geenen-it-systeme dot de>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_router.h"
|
||||||
|
#include "qmqtt_client.h"
|
||||||
|
#include "qmqtt_routesubscription.h"
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(router, "qmqtt.router")
|
||||||
|
|
||||||
|
Router::Router(Client *parent) : QObject(parent), _client(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RouteSubscription *Router::subscribe(const QString &route)
|
||||||
|
{
|
||||||
|
RouteSubscription *subscription = new RouteSubscription(this);
|
||||||
|
subscription->setRoute(route);
|
||||||
|
connect(_client, &Client::connected, subscription, [this, subscription]() {
|
||||||
|
_client->subscribe(subscription->_topic, 0);
|
||||||
|
});
|
||||||
|
if (_client->isConnectedToHost())
|
||||||
|
_client->subscribe(subscription->_topic, 0);
|
||||||
|
connect(_client, &Client::received, subscription, &RouteSubscription::routeMessage);
|
||||||
|
return subscription;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client *Router::client() const
|
||||||
|
{
|
||||||
|
return _client;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_router.h - qmqtt router
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* Router added by Niklas Wulf <nwulf at geenen-it-systeme dot de>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_ROUTER_H
|
||||||
|
#define QMQTT_ROUTER_H
|
||||||
|
|
||||||
|
#include "qmqtt_global.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
class RouteSubscription;
|
||||||
|
|
||||||
|
class Q_MQTT_EXPORT Router : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Router(Client *parent = 0);
|
||||||
|
|
||||||
|
RouteSubscription *subscribe(const QString &route);
|
||||||
|
Client *client() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Client *_client;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
#endif // QMQTT_ROUTER_H
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_router.cpp - qmqtt router
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* Router added by Niklas Wulf <nwulf at geenen-it-systeme dot de>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_routesubscription.h"
|
||||||
|
#include "qmqtt_router.h"
|
||||||
|
#include "qmqtt_client.h"
|
||||||
|
#include "qmqtt_routedmessage.h"
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QLatin1String>
|
||||||
|
#include <QLatin1Char>
|
||||||
|
#include <QRegularExpressionMatch>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(routerSubscription, "qmqtt.routersubscription")
|
||||||
|
|
||||||
|
RouteSubscription::RouteSubscription(Router *parent)
|
||||||
|
: QObject(parent),
|
||||||
|
_client(parent->client())
|
||||||
|
{
|
||||||
|
Q_ASSERT(!_client.isNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
RouteSubscription::~RouteSubscription()
|
||||||
|
{
|
||||||
|
if (Q_LIKELY(!_client.isNull() && _client->isConnectedToHost()))
|
||||||
|
_client->unsubscribe(_topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RouteSubscription::route() const
|
||||||
|
{
|
||||||
|
return _topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouteSubscription::setRoute(const QString &route)
|
||||||
|
{
|
||||||
|
QRegularExpression parameterNamesRegExp(QStringLiteral("\\:([a-zA-Z0-9]+)")); // note how names must not contain dashes or underscores
|
||||||
|
|
||||||
|
// Remove paramter names to get the actual topic "route"
|
||||||
|
QString topic = route;
|
||||||
|
topic.remove(parameterNamesRegExp);
|
||||||
|
|
||||||
|
// Remove the MQTT wildcards to get a regular expression, which matches the parameters
|
||||||
|
QString parameterRegExp = route;
|
||||||
|
parameterRegExp
|
||||||
|
.remove(QLatin1Char('+'))
|
||||||
|
.replace(parameterNamesRegExp, QStringLiteral("([a-zA-Z0-9_-]+)")) // note how parameter values may contain dashes or underscores
|
||||||
|
.remove(QLatin1Char('#'))
|
||||||
|
.replace(QLatin1String("$"), QLatin1String("\\$"));
|
||||||
|
|
||||||
|
// Extract the parameter names
|
||||||
|
QRegularExpressionMatchIterator it = parameterNamesRegExp.globalMatch(route);
|
||||||
|
QStringList names;
|
||||||
|
while(it.hasNext()) {
|
||||||
|
QRegularExpressionMatch match = it.next();
|
||||||
|
QString parameterName = match.captured(1);
|
||||||
|
names << parameterName;
|
||||||
|
}
|
||||||
|
|
||||||
|
_topic = topic;
|
||||||
|
_parameterNames = names;
|
||||||
|
_regularExpression = QRegularExpression(parameterRegExp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouteSubscription::routeMessage(const Message &message)
|
||||||
|
{
|
||||||
|
QString topic = message.topic();
|
||||||
|
QRegularExpressionMatch match = _regularExpression.match(topic);
|
||||||
|
if(!match.hasMatch()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RoutedMessage routedMessage(message);
|
||||||
|
|
||||||
|
for(int i = 0, c = _parameterNames.size(); i < c; ++i) {
|
||||||
|
QString name = _parameterNames.at(i);
|
||||||
|
QString value = match.captured(i + 1);
|
||||||
|
|
||||||
|
routedMessage._parameters.insert(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit received(routedMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_router.h - qmqtt router
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* Router added by Niklas Wulf <nwulf at geenen-it-systeme dot de>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_ROUTESUBSCRIPTION_H
|
||||||
|
#define QMQTT_ROUTESUBSCRIPTION_H
|
||||||
|
|
||||||
|
#include "qmqtt_global.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QString>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
class Message;
|
||||||
|
class RoutedMessage;
|
||||||
|
class Router;
|
||||||
|
|
||||||
|
class Q_MQTT_EXPORT RouteSubscription : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
~RouteSubscription();
|
||||||
|
|
||||||
|
QString route() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void received(const RoutedMessage &message);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void routeMessage(const Message &message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Router;
|
||||||
|
|
||||||
|
explicit RouteSubscription(Router *parent = 0);
|
||||||
|
void setRoute(const QString &route);
|
||||||
|
|
||||||
|
QPointer<Client> _client;
|
||||||
|
QString _topic;
|
||||||
|
QRegularExpression _regularExpression;
|
||||||
|
QStringList _parameterNames;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QMQTT
|
||||||
|
|
||||||
|
#endif // QMQTT_ROUTESUBSCRIPTION_H
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_socket.cpp - qmqtt socket
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_socket_p.h"
|
||||||
|
|
||||||
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
QMQTT::Socket::Socket(QObject* parent)
|
||||||
|
: SocketInterface(parent)
|
||||||
|
, _socket(new QTcpSocket(this))
|
||||||
|
{
|
||||||
|
connect(_socket.data(), &QTcpSocket::connected, this, &SocketInterface::connected);
|
||||||
|
connect(_socket.data(), &QTcpSocket::disconnected, this, &SocketInterface::disconnected);
|
||||||
|
connect(_socket.data(),
|
||||||
|
static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error),
|
||||||
|
this,
|
||||||
|
static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error));
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::Socket::~Socket()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QIODevice *QMQTT::Socket::ioDevice()
|
||||||
|
{
|
||||||
|
return _socket.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Socket::connectToHost(const QHostAddress& address, quint16 port)
|
||||||
|
{
|
||||||
|
_socket->connectToHost(address, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Socket::connectToHost(const QString& hostName, quint16 port)
|
||||||
|
{
|
||||||
|
_socket->connectToHost(hostName, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Socket::disconnectFromHost()
|
||||||
|
{
|
||||||
|
_socket->disconnectFromHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractSocket::SocketState QMQTT::Socket::state() const
|
||||||
|
{
|
||||||
|
return _socket->state();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractSocket::SocketError QMQTT::Socket::error() const
|
||||||
|
{
|
||||||
|
return _socket->error();
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_socket_p.h - qmqtt socket private header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_SOCKET_P_H
|
||||||
|
#define QMQTT_SOCKET_P_H
|
||||||
|
|
||||||
|
#include "qmqtt_socketinterface.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QString>
|
||||||
|
#include <QAbstractSocket>
|
||||||
|
#include <QScopedPointer>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QIODevice)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QTcpSocket)
|
||||||
|
|
||||||
|
namespace QMQTT
|
||||||
|
{
|
||||||
|
|
||||||
|
class Socket : public SocketInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Socket(QObject* parent = NULL);
|
||||||
|
virtual ~Socket();
|
||||||
|
|
||||||
|
virtual QIODevice *ioDevice();
|
||||||
|
void connectToHost(const QHostAddress& address, quint16 port);
|
||||||
|
void connectToHost(const QString& hostName, quint16 port);
|
||||||
|
void disconnectFromHost();
|
||||||
|
QAbstractSocket::SocketState state() const;
|
||||||
|
QAbstractSocket::SocketError error() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QScopedPointer<QTcpSocket> _socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QMQTT_SOCKET_P_H
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_socketinterface.h - qmqtt socket interface header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_SOCKET_INTERFACE_H
|
||||||
|
#define QMQTT_SOCKET_INTERFACE_H
|
||||||
|
|
||||||
|
#include "qmqtt_global.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QString>
|
||||||
|
#include <QAbstractSocket>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
#include <QSslConfiguration>
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSslError)
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QIODevice)
|
||||||
|
|
||||||
|
namespace QMQTT
|
||||||
|
{
|
||||||
|
|
||||||
|
class Q_MQTT_EXPORT SocketInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SocketInterface(QObject* parent = NULL) : QObject(parent) {}
|
||||||
|
virtual ~SocketInterface() {}
|
||||||
|
|
||||||
|
virtual QIODevice* ioDevice() = 0;
|
||||||
|
virtual void connectToHost(const QHostAddress& address, quint16 port) = 0;
|
||||||
|
virtual void connectToHost(const QString& hostName, quint16 port) = 0;
|
||||||
|
virtual void disconnectFromHost() = 0;
|
||||||
|
virtual QAbstractSocket::SocketState state() const = 0;
|
||||||
|
virtual QAbstractSocket::SocketError error() const = 0;
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
virtual void ignoreSslErrors(const QList<QSslError>& errors) { Q_UNUSED(errors); }
|
||||||
|
virtual void ignoreSslErrors() {}
|
||||||
|
virtual QSslConfiguration sslConfiguration() const { return QSslConfiguration(); }
|
||||||
|
virtual void setSslConfiguration(const QSslConfiguration& config) { Q_UNUSED(config); }
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void connected();
|
||||||
|
void disconnected();
|
||||||
|
void error(QAbstractSocket::SocketError socketError);
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void sslErrors(const QList<QSslError>& errors);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QMQTT_SOCKET_INTERFACE_H
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_ssl_socket.cpp - qmqtt SSL socket
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* Copyright (c) 2016 Matthias Dieter Wallnöfer
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_ssl_socket_p.h"
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
|
||||||
|
#include <QSslSocket>
|
||||||
|
#include <QSslError>
|
||||||
|
|
||||||
|
QMQTT::SslSocket::SslSocket(const QSslConfiguration& config, QObject* parent)
|
||||||
|
: SocketInterface(parent)
|
||||||
|
, _socket(new QSslSocket(this))
|
||||||
|
{
|
||||||
|
_socket->setSslConfiguration(config);
|
||||||
|
connect(_socket.data(), &QSslSocket::encrypted, this, &SocketInterface::connected);
|
||||||
|
connect(_socket.data(), &QSslSocket::disconnected, this, &SocketInterface::disconnected);
|
||||||
|
connect(_socket.data(),
|
||||||
|
static_cast<void (QSslSocket::*)(QAbstractSocket::SocketError)>(&QSslSocket::error),
|
||||||
|
this,
|
||||||
|
static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error));
|
||||||
|
connect(_socket.data(),
|
||||||
|
static_cast<void (QSslSocket::*)(const QList<QSslError>&)>(&QSslSocket::sslErrors),
|
||||||
|
this,
|
||||||
|
&SslSocket::sslErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::SslSocket::~SslSocket()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QIODevice *QMQTT::SslSocket::ioDevice()
|
||||||
|
{
|
||||||
|
return _socket.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::SslSocket::connectToHost(const QHostAddress& address, quint16 port)
|
||||||
|
{
|
||||||
|
_socket->connectToHostEncrypted(address.toString(), port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::SslSocket::connectToHost(const QString& hostName, quint16 port)
|
||||||
|
{
|
||||||
|
_socket->connectToHostEncrypted(hostName, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::SslSocket::disconnectFromHost()
|
||||||
|
{
|
||||||
|
_socket->disconnectFromHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractSocket::SocketState QMQTT::SslSocket::state() const
|
||||||
|
{
|
||||||
|
return _socket->state();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractSocket::SocketError QMQTT::SslSocket::error() const
|
||||||
|
{
|
||||||
|
return _socket->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::SslSocket::ignoreSslErrors(const QList<QSslError>& errors)
|
||||||
|
{
|
||||||
|
_socket->ignoreSslErrors(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::SslSocket::ignoreSslErrors()
|
||||||
|
{
|
||||||
|
_socket->ignoreSslErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSslConfiguration QMQTT::SslSocket::sslConfiguration() const
|
||||||
|
{
|
||||||
|
return _socket->sslConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::SslSocket::setSslConfiguration(const QSslConfiguration& config)
|
||||||
|
{
|
||||||
|
_socket->setSslConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QT_NO_SSL
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_ssl_socket_p.h - qmqtt SSL socket private header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* Copyright (c) 2016 Matthias Dieter Wallnöfer
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_SSL_SOCKET_P_H
|
||||||
|
#define QMQTT_SSL_SOCKET_P_H
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
|
||||||
|
#include "qmqtt_socketinterface.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QString>
|
||||||
|
#include <QList>
|
||||||
|
#include <QScopedPointer>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSslSocket)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSslError)
|
||||||
|
#include <QSslConfiguration>
|
||||||
|
|
||||||
|
namespace QMQTT
|
||||||
|
{
|
||||||
|
|
||||||
|
class SslSocket : public SocketInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SslSocket(const QSslConfiguration& config, QObject* parent = NULL);
|
||||||
|
virtual ~SslSocket();
|
||||||
|
|
||||||
|
virtual QIODevice *ioDevice();
|
||||||
|
void connectToHost(const QHostAddress& address, quint16 port);
|
||||||
|
void connectToHost(const QString& hostName, quint16 port);
|
||||||
|
void disconnectFromHost();
|
||||||
|
QAbstractSocket::SocketState state() const;
|
||||||
|
QAbstractSocket::SocketError error() const;
|
||||||
|
void ignoreSslErrors(const QList<QSslError>& errors);
|
||||||
|
void ignoreSslErrors();
|
||||||
|
QSslConfiguration sslConfiguration() const;
|
||||||
|
void setSslConfiguration(const QSslConfiguration& config);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QScopedPointer<QSslSocket> _socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
#endif // QMQTT_SSL_SOCKET_P_H
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_timer.cpp - qmqtt timer
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qmqtt_timer_p.h"
|
||||||
|
|
||||||
|
QMQTT::Timer::Timer(QObject* parent)
|
||||||
|
: TimerInterface(parent)
|
||||||
|
{
|
||||||
|
connect(&_timer, &QTimer::timeout, this, &TimerInterface::timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::Timer::~Timer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::Timer::isSingleShot() const
|
||||||
|
{
|
||||||
|
return _timer.isSingleShot();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Timer::setSingleShot(bool singleShot)
|
||||||
|
{
|
||||||
|
_timer.setSingleShot(singleShot);
|
||||||
|
}
|
||||||
|
|
||||||
|
int QMQTT::Timer::interval() const
|
||||||
|
{
|
||||||
|
return _timer.interval();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Timer::setInterval(int msec)
|
||||||
|
{
|
||||||
|
_timer.setInterval(msec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Timer::start()
|
||||||
|
{
|
||||||
|
_timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::Timer::stop()
|
||||||
|
{
|
||||||
|
_timer.stop();
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_timer_p.h - qmqtt timer private header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_TIMER_P_H
|
||||||
|
#define QMQTT_TIMER_P_H
|
||||||
|
|
||||||
|
#include "qmqtt_timerinterface.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class Timer : public TimerInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Timer(QObject *parent = 0);
|
||||||
|
virtual ~Timer();
|
||||||
|
|
||||||
|
bool isSingleShot() const;
|
||||||
|
void setSingleShot(bool singleShot);
|
||||||
|
int interval() const;
|
||||||
|
void setInterval(int msec);
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QTimer _timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QMQTT_TIMER_P_H
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_timerinterface.h - qmqtt timer interface header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_TIMER_INTERFACE_H
|
||||||
|
#define QMQTT_TIMER_INTERFACE_H
|
||||||
|
|
||||||
|
#include "qmqtt_global.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace QMQTT {
|
||||||
|
|
||||||
|
class Q_MQTT_EXPORT TimerInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit TimerInterface(QObject* parent = NULL) : QObject(parent) {}
|
||||||
|
virtual ~TimerInterface() {}
|
||||||
|
|
||||||
|
virtual bool isSingleShot() const = 0;
|
||||||
|
virtual void setSingleShot(bool singleShot) = 0;
|
||||||
|
virtual int interval() const = 0;
|
||||||
|
virtual void setInterval(int msec) = 0;
|
||||||
|
virtual void start() = 0;
|
||||||
|
virtual void stop() = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void timeout();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QMQTT_TIMER_INTERFACE_H
|
||||||
|
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
#include "qmqtt_websocket_p.h"
|
||||||
|
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QSslError>
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
QMQTT::WebSocket::WebSocket(const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
const QSslConfiguration* sslConfig,
|
||||||
|
QObject* parent)
|
||||||
|
: SocketInterface(parent)
|
||||||
|
, _socket(new QWebSocket(origin, version, this))
|
||||||
|
, _ioDevice(new WebSocketIODevice(_socket, this))
|
||||||
|
{
|
||||||
|
initialize();
|
||||||
|
if (sslConfig != NULL)
|
||||||
|
_socket->setSslConfiguration(*sslConfig);
|
||||||
|
connect(_socket, &QWebSocket::sslErrors, this, &WebSocket::sslErrors);
|
||||||
|
}
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
QMQTT::WebSocket::WebSocket(const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
QObject* parent)
|
||||||
|
: SocketInterface(parent)
|
||||||
|
, _socket(new QWebSocket(origin, version, this))
|
||||||
|
, _ioDevice(new WebSocketIODevice(_socket, this))
|
||||||
|
{
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::WebSocket::initialize()
|
||||||
|
{
|
||||||
|
connect(_socket, &QWebSocket::connected, this, &WebSocket::connected);
|
||||||
|
connect(_socket, &QWebSocket::disconnected, this, &WebSocket::disconnected);
|
||||||
|
connect(_socket,
|
||||||
|
static_cast<void (QWebSocket::*)(QAbstractSocket::SocketError)>(&QWebSocket::error),
|
||||||
|
this,
|
||||||
|
static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error));
|
||||||
|
}
|
||||||
|
|
||||||
|
QMQTT::WebSocket::~WebSocket()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::WebSocket::connectToHost(const QHostAddress& address, quint16 port)
|
||||||
|
{
|
||||||
|
Q_UNUSED(address)
|
||||||
|
Q_UNUSED(port)
|
||||||
|
qFatal("No supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::WebSocket::connectToHost(const QString& hostName, quint16 port)
|
||||||
|
{
|
||||||
|
Q_UNUSED(port)
|
||||||
|
QUrl url(hostName);
|
||||||
|
QNetworkRequest request(url);
|
||||||
|
request.setRawHeader("Sec-WebSocket-Protocol", "mqtt");
|
||||||
|
_ioDevice->connectToHost(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::WebSocket::disconnectFromHost()
|
||||||
|
{
|
||||||
|
_socket->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractSocket::SocketState QMQTT::WebSocket::state() const
|
||||||
|
{
|
||||||
|
return _socket->state();
|
||||||
|
}
|
||||||
|
|
||||||
|
QAbstractSocket::SocketError QMQTT::WebSocket::error() const
|
||||||
|
{
|
||||||
|
return _socket->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void QMQTT::WebSocket::ignoreSslErrors(const QList<QSslError>& errors)
|
||||||
|
{
|
||||||
|
_socket->ignoreSslErrors(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::WebSocket::ignoreSslErrors()
|
||||||
|
{
|
||||||
|
_socket->ignoreSslErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSslConfiguration QMQTT::WebSocket::sslConfiguration() const
|
||||||
|
{
|
||||||
|
return _socket->sslConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::WebSocket::setSslConfiguration(const QSslConfiguration& config)
|
||||||
|
{
|
||||||
|
_socket->setSslConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_websocket_p.h - qmqtt socket private header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef QMQTT_WEBSOCKET_H
|
||||||
|
#define QMQTT_WEBSOCKET_H
|
||||||
|
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
#include <qmqtt_socketinterface.h>
|
||||||
|
#include <qmqtt_websocketiodevice_p.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QWebSocket>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QString>
|
||||||
|
#include <QList>
|
||||||
|
#include <QAbstractSocket>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QIODevice)
|
||||||
|
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
#include <QSslConfiguration>
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSslError)
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
namespace QMQTT
|
||||||
|
{
|
||||||
|
|
||||||
|
class WebSocket : public SocketInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
WebSocket(const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
const QSslConfiguration* sslConfig,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
WebSocket(const QString& origin,
|
||||||
|
QWebSocketProtocol::Version version,
|
||||||
|
QObject* parent = NULL);
|
||||||
|
|
||||||
|
virtual ~WebSocket();
|
||||||
|
|
||||||
|
QIODevice *ioDevice()
|
||||||
|
{
|
||||||
|
return _ioDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
void connectToHost(const QHostAddress& address, quint16 port);
|
||||||
|
void connectToHost(const QString& hostName, quint16 port);
|
||||||
|
void disconnectFromHost();
|
||||||
|
QAbstractSocket::SocketState state() const;
|
||||||
|
QAbstractSocket::SocketError error() const;
|
||||||
|
#ifndef QT_NO_SSL
|
||||||
|
void ignoreSslErrors(const QList<QSslError>& errors);
|
||||||
|
void ignoreSslErrors();
|
||||||
|
QSslConfiguration sslConfiguration() const;
|
||||||
|
void setSslConfiguration(const QSslConfiguration& config);
|
||||||
|
#endif // QT_NO_SSL
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
QWebSocket *_socket;
|
||||||
|
WebSocketIODevice *_ioDevice;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
#endif // QMQTT_WEBSOCKET_H
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
#include "qmqtt_websocketiodevice_p.h"
|
||||||
|
|
||||||
|
#include <QWebSocket>
|
||||||
|
|
||||||
|
QMQTT::WebSocketIODevice::WebSocketIODevice(QWebSocket *socket, QObject *parent)
|
||||||
|
: QIODevice(parent)
|
||||||
|
, _webSocket(socket)
|
||||||
|
{
|
||||||
|
connect(_webSocket, &QWebSocket::bytesWritten, this, &WebSocketIODevice::bytesWritten);
|
||||||
|
connect(_webSocket, &QWebSocket::binaryMessageReceived,
|
||||||
|
this, &WebSocketIODevice::binaryMessageReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QMQTT::WebSocketIODevice::connectToHost(const QNetworkRequest &request)
|
||||||
|
{
|
||||||
|
_webSocket->open(request);
|
||||||
|
return QIODevice::open(QIODevice::ReadWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QMQTT::WebSocketIODevice::bytesAvailable() const
|
||||||
|
{
|
||||||
|
return _buffer.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMQTT::WebSocketIODevice::binaryMessageReceived(const QByteArray &frame)
|
||||||
|
{
|
||||||
|
_buffer.append(frame);
|
||||||
|
emit readyRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QMQTT::WebSocketIODevice::readData(char *data, qint64 maxSize)
|
||||||
|
{
|
||||||
|
int size = qMin(static_cast<int>(maxSize), _buffer.count());
|
||||||
|
for (int i=0; i<size; ++ i)
|
||||||
|
data[i] = _buffer[i];
|
||||||
|
_buffer.remove(0, size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QMQTT::WebSocketIODevice::writeData(const char *data, qint64 maxSize)
|
||||||
|
{
|
||||||
|
QByteArray d(data, static_cast<int>(maxSize));
|
||||||
|
return _webSocket->sendBinaryMessage(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* qmqtt_socketinterface.h - qmqtt socket interface header
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of mqttc nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QMQTT_WEBSOCKETIODEVICE_H
|
||||||
|
#define QMQTT_WEBSOCKETIODEVICE_H
|
||||||
|
|
||||||
|
#ifdef QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QIODevice>
|
||||||
|
#include <QList>
|
||||||
|
#include <QAbstractSocket>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QWebSocket)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QNetworkRequest)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSslError)
|
||||||
|
|
||||||
|
namespace QMQTT
|
||||||
|
{
|
||||||
|
|
||||||
|
class WebSocketIODevice : public QIODevice
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit WebSocketIODevice(QWebSocket *socket, QObject *parent = NULL);
|
||||||
|
|
||||||
|
bool connectToHost(const QNetworkRequest &request);
|
||||||
|
|
||||||
|
virtual qint64 bytesAvailable() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void connected();
|
||||||
|
|
||||||
|
void disconnected();
|
||||||
|
|
||||||
|
void error(QAbstractSocket::SocketError error);
|
||||||
|
|
||||||
|
void sslErrors(const QList<QSslError> &errors);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual qint64 readData(char *data, qint64 maxSize);
|
||||||
|
|
||||||
|
virtual qint64 writeData(const char *data, qint64 maxSize);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void binaryMessageReceived(const QByteArray &frame);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray _buffer;
|
||||||
|
QWebSocket *_webSocket;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // QT_WEBSOCKETS_LIB
|
||||||
|
|
||||||
|
#endif // QMQTT_WEBSOCKETIODEVICE_H
|
||||||
+252
@@ -0,0 +1,252 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011, Andre Somers
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Rathenau Instituut, Andre Somers nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR #######; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "simplecrypt.h"
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QtDebug>
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
|
SimpleCrypt::SimpleCrypt():
|
||||||
|
m_key(0),
|
||||||
|
m_compressionMode(CompressionAuto),
|
||||||
|
m_protectionMode(ProtectionChecksum),
|
||||||
|
m_lastError(ErrorNoError)
|
||||||
|
{
|
||||||
|
qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleCrypt::SimpleCrypt(quint64 key):
|
||||||
|
m_key(key),
|
||||||
|
m_compressionMode(CompressionAuto),
|
||||||
|
m_protectionMode(ProtectionChecksum),
|
||||||
|
m_lastError(ErrorNoError)
|
||||||
|
{
|
||||||
|
qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF));
|
||||||
|
splitKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimpleCrypt::setKey(quint64 key)
|
||||||
|
{
|
||||||
|
m_key = key;
|
||||||
|
splitKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimpleCrypt::splitKey()
|
||||||
|
{
|
||||||
|
m_keyParts.clear();
|
||||||
|
m_keyParts.resize(8);
|
||||||
|
for (int i=0;i<8;i++) {
|
||||||
|
quint64 part = m_key;
|
||||||
|
for (int j=i; j>0; j--)
|
||||||
|
part = part >> 8;
|
||||||
|
part = part & 0xff;
|
||||||
|
m_keyParts[i] = static_cast<char>(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SimpleCrypt::encryptToByteArray(const QString& plaintext)
|
||||||
|
{
|
||||||
|
QByteArray plaintextArray = plaintext.toUtf8();
|
||||||
|
return encryptToByteArray(plaintextArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext)
|
||||||
|
{
|
||||||
|
if (m_keyParts.isEmpty()) {
|
||||||
|
qWarning() << "No key set.";
|
||||||
|
m_lastError = ErrorNoKeySet;
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QByteArray ba = plaintext;
|
||||||
|
|
||||||
|
CryptoFlags flags = CryptoFlagNone;
|
||||||
|
if (m_compressionMode == CompressionAlways) {
|
||||||
|
ba = qCompress(ba, 9); //maximum compression
|
||||||
|
flags |= CryptoFlagCompression;
|
||||||
|
} else if (m_compressionMode == CompressionAuto) {
|
||||||
|
QByteArray compressed = qCompress(ba, 9);
|
||||||
|
if (compressed.count() < ba.count()) {
|
||||||
|
ba = compressed;
|
||||||
|
flags |= CryptoFlagCompression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray integrityProtection;
|
||||||
|
if (m_protectionMode == ProtectionChecksum) {
|
||||||
|
flags |= CryptoFlagChecksum;
|
||||||
|
QDataStream s(&integrityProtection, QIODevice::WriteOnly);
|
||||||
|
s << qChecksum(ba.constData(), ba.length());
|
||||||
|
} else if (m_protectionMode == ProtectionHash) {
|
||||||
|
flags |= CryptoFlagHash;
|
||||||
|
QCryptographicHash hash(QCryptographicHash::Sha1);
|
||||||
|
hash.addData(ba);
|
||||||
|
|
||||||
|
integrityProtection += hash.result();
|
||||||
|
}
|
||||||
|
|
||||||
|
//prepend a random char to the string
|
||||||
|
char randomChar = char(qrand() & 0xFF);
|
||||||
|
ba = randomChar + integrityProtection + ba;
|
||||||
|
|
||||||
|
int pos(0);
|
||||||
|
char lastChar(0);
|
||||||
|
|
||||||
|
int cnt = ba.count();
|
||||||
|
|
||||||
|
while (pos < cnt) {
|
||||||
|
ba[pos] = ba.at(pos) ^ m_keyParts.at(pos % 8) ^ lastChar;
|
||||||
|
lastChar = ba.at(pos);
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray resultArray;
|
||||||
|
resultArray.append(char(0x03)); //version for future updates to algorithm
|
||||||
|
resultArray.append(char(flags)); //encryption flags
|
||||||
|
resultArray.append(ba);
|
||||||
|
|
||||||
|
m_lastError = ErrorNoError;
|
||||||
|
return resultArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SimpleCrypt::encryptToString(const QString& plaintext)
|
||||||
|
{
|
||||||
|
QByteArray plaintextArray = plaintext.toUtf8();
|
||||||
|
QByteArray cypher = encryptToByteArray(plaintextArray);
|
||||||
|
QString cypherString = QString::fromLatin1(cypher.toBase64());
|
||||||
|
return cypherString;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SimpleCrypt::encryptToString(QByteArray plaintext)
|
||||||
|
{
|
||||||
|
QByteArray cypher = encryptToByteArray(plaintext);
|
||||||
|
QString cypherString = QString::fromLatin1(cypher.toBase64());
|
||||||
|
return cypherString;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SimpleCrypt::decryptToString(const QString &cyphertext)
|
||||||
|
{
|
||||||
|
QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1());
|
||||||
|
QByteArray plaintextArray = decryptToByteArray(cyphertextArray);
|
||||||
|
QString plaintext = QString::fromUtf8(plaintextArray, plaintextArray.size());
|
||||||
|
|
||||||
|
return plaintext;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SimpleCrypt::decryptToString(QByteArray cypher)
|
||||||
|
{
|
||||||
|
QByteArray ba = decryptToByteArray(cypher);
|
||||||
|
QString plaintext = QString::fromUtf8(ba, ba.size());
|
||||||
|
|
||||||
|
return plaintext;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SimpleCrypt::decryptToByteArray(const QString& cyphertext)
|
||||||
|
{
|
||||||
|
QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1());
|
||||||
|
QByteArray ba = decryptToByteArray(cyphertextArray);
|
||||||
|
|
||||||
|
return ba;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SimpleCrypt::decryptToByteArray(QByteArray cypher)
|
||||||
|
{
|
||||||
|
if (m_keyParts.isEmpty()) {
|
||||||
|
qWarning() << "No key set.";
|
||||||
|
m_lastError = ErrorNoKeySet;
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ba = cypher;
|
||||||
|
|
||||||
|
if( cypher.count() < 3 )
|
||||||
|
return QByteArray();
|
||||||
|
|
||||||
|
char version = ba.at(0);
|
||||||
|
|
||||||
|
if (version !=3) { //we only work with version 3
|
||||||
|
m_lastError = ErrorUnknownVersion;
|
||||||
|
qWarning() << "Invalid version or not a cyphertext.";
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoFlags flags = CryptoFlags(ba.at(1));
|
||||||
|
|
||||||
|
ba = ba.mid(2);
|
||||||
|
int pos(0);
|
||||||
|
int cnt(ba.count());
|
||||||
|
char lastChar = 0;
|
||||||
|
|
||||||
|
while (pos < cnt) {
|
||||||
|
char currentChar = ba[pos];
|
||||||
|
ba[pos] = ba.at(pos) ^ lastChar ^ m_keyParts.at(pos % 8);
|
||||||
|
lastChar = currentChar;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
ba = ba.mid(1); //chop off the random number at the start
|
||||||
|
|
||||||
|
bool integrityOk(true);
|
||||||
|
if (flags.testFlag(CryptoFlagChecksum)) {
|
||||||
|
if (ba.length() < 2) {
|
||||||
|
m_lastError = ErrorIntegrityFailed;
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
quint16 storedChecksum;
|
||||||
|
{
|
||||||
|
QDataStream s(&ba, QIODevice::ReadOnly);
|
||||||
|
s >> storedChecksum;
|
||||||
|
}
|
||||||
|
ba = ba.mid(2);
|
||||||
|
quint16 checksum = qChecksum(ba.constData(), ba.length());
|
||||||
|
integrityOk = (checksum == storedChecksum);
|
||||||
|
} else if (flags.testFlag(CryptoFlagHash)) {
|
||||||
|
if (ba.length() < 20) {
|
||||||
|
m_lastError = ErrorIntegrityFailed;
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
QByteArray storedHash = ba.left(20);
|
||||||
|
ba = ba.mid(20);
|
||||||
|
QCryptographicHash hash(QCryptographicHash::Sha1);
|
||||||
|
hash.addData(ba);
|
||||||
|
integrityOk = (hash.result() == storedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!integrityOk) {
|
||||||
|
m_lastError = ErrorIntegrityFailed;
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags.testFlag(CryptoFlagCompression))
|
||||||
|
ba = qUncompress(ba);
|
||||||
|
|
||||||
|
m_lastError = ErrorNoError;
|
||||||
|
return ba;
|
||||||
|
}
|
||||||
+225
@@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2011, Andre Somers
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Rathenau Instituut, Andre Somers nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR #######; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SIMPLECRYPT_H
|
||||||
|
#define SIMPLECRYPT_H
|
||||||
|
#include <QString>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QFlags>
|
||||||
|
|
||||||
|
/**
|
||||||
|
@short Simple encryption and decryption of strings and byte arrays
|
||||||
|
|
||||||
|
This class provides a simple implementation of encryption and decryption
|
||||||
|
of strings and byte arrays.
|
||||||
|
|
||||||
|
@warning The encryption provided by this class is NOT strong encryption. It may
|
||||||
|
help to shield things from curious eyes, but it will NOT stand up to someone
|
||||||
|
determined to break the encryption. Don't say you were not warned.
|
||||||
|
|
||||||
|
The class uses a 64 bit key. Simply create an instance of the class, set the key,
|
||||||
|
and use the encryptToString() method to calculate an encrypted version of the input string.
|
||||||
|
To decrypt that string again, use an instance of SimpleCrypt initialized with
|
||||||
|
the same key, and call the decryptToString() method with the encrypted string. If the key
|
||||||
|
matches, the decrypted version of the string will be returned again.
|
||||||
|
|
||||||
|
If you do not provide a key, or if something else is wrong, the encryption and
|
||||||
|
decryption function will return an empty string or will return a string containing nonsense.
|
||||||
|
lastError() will return a value indicating if the method was succesful, and if not, why not.
|
||||||
|
|
||||||
|
SimpleCrypt is prepared for the case that the encryption and decryption
|
||||||
|
algorithm is changed in a later version, by prepending a version identifier to the cypertext.
|
||||||
|
*/
|
||||||
|
class SimpleCrypt
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
CompressionMode describes if compression will be applied to the data to be
|
||||||
|
encrypted.
|
||||||
|
*/
|
||||||
|
enum CompressionMode {
|
||||||
|
CompressionAuto, /*!< Only apply compression if that results in a shorter plaintext. */
|
||||||
|
CompressionAlways, /*!< Always apply compression. Note that for short inputs, a compression may result in longer data */
|
||||||
|
CompressionNever /*!< Never apply compression. */
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
IntegrityProtectionMode describes measures taken to make it possible to detect problems with the data
|
||||||
|
or wrong decryption keys.
|
||||||
|
|
||||||
|
Measures involve adding a checksum or a cryptograhpic hash to the data to be encrypted. This
|
||||||
|
increases the length of the resulting cypertext, but makes it possible to check if the plaintext
|
||||||
|
appears to be valid after decryption.
|
||||||
|
*/
|
||||||
|
enum IntegrityProtectionMode {
|
||||||
|
ProtectionNone, /*!< The integerity of the encrypted data is not protected. It is not really possible to detect a wrong key, for instance. */
|
||||||
|
ProtectionChecksum,/*!< A simple checksum is used to verify that the data is in order. If not, an empty string is returned. */
|
||||||
|
ProtectionHash /*!< A cryptographic hash is used to verify the integrity of the data. This method produces a much stronger, but longer check */
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
Error describes the type of error that occured.
|
||||||
|
*/
|
||||||
|
enum Error {
|
||||||
|
ErrorNoError, /*!< No error occurred. */
|
||||||
|
ErrorNoKeySet, /*!< No key was set. You can not encrypt or decrypt without a valid key. */
|
||||||
|
ErrorUnknownVersion, /*!< The version of this data is unknown, or the data is otherwise not valid. */
|
||||||
|
ErrorIntegrityFailed, /*!< The integrity check of the data failed. Perhaps the wrong key was used. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constructor.
|
||||||
|
|
||||||
|
Constructs a SimpleCrypt instance without a valid key set on it.
|
||||||
|
*/
|
||||||
|
SimpleCrypt();
|
||||||
|
/**
|
||||||
|
Constructor.
|
||||||
|
|
||||||
|
Constructs a SimpleCrypt instance and initializes it with the given @arg key.
|
||||||
|
*/
|
||||||
|
explicit SimpleCrypt(quint64 key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
(Re-) initializes the key with the given @arg key.
|
||||||
|
*/
|
||||||
|
void setKey(quint64 key);
|
||||||
|
/**
|
||||||
|
Returns true if SimpleCrypt has been initialized with a key.
|
||||||
|
*/
|
||||||
|
bool hasKey() const {return !m_keyParts.isEmpty();}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the compression mode to use when encrypting data. The default mode is Auto.
|
||||||
|
|
||||||
|
Note that decryption is not influenced by this mode, as the decryption recognizes
|
||||||
|
what mode was used when encrypting.
|
||||||
|
*/
|
||||||
|
void setCompressionMode(CompressionMode mode) {m_compressionMode = mode;}
|
||||||
|
/**
|
||||||
|
Returns the CompressionMode that is currently in use.
|
||||||
|
*/
|
||||||
|
CompressionMode compressionMode() const {return m_compressionMode;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the integrity mode to use when encrypting data. The default mode is Checksum.
|
||||||
|
|
||||||
|
Note that decryption is not influenced by this mode, as the decryption recognizes
|
||||||
|
what mode was used when encrypting.
|
||||||
|
*/
|
||||||
|
void setIntegrityProtectionMode(IntegrityProtectionMode mode) {m_protectionMode = mode;}
|
||||||
|
/**
|
||||||
|
Returns the IntegrityProtectionMode that is currently in use.
|
||||||
|
*/
|
||||||
|
IntegrityProtectionMode integrityProtectionMode() const {return m_protectionMode;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the last error that occurred.
|
||||||
|
*/
|
||||||
|
Error lastError() const {return m_lastError;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Encrypts the @arg plaintext string with the key the class was initialized with, and returns
|
||||||
|
a cyphertext the result. The result is a base64 encoded version of the binary array that is the
|
||||||
|
actual result of the string, so it can be stored easily in a text format.
|
||||||
|
*/
|
||||||
|
QString encryptToString(const QString& plaintext) ;
|
||||||
|
/**
|
||||||
|
Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns
|
||||||
|
a cyphertext the result. The result is a base64 encoded version of the binary array that is the
|
||||||
|
actual result of the encryption, so it can be stored easily in a text format.
|
||||||
|
*/
|
||||||
|
QString encryptToString(QByteArray plaintext) ;
|
||||||
|
/**
|
||||||
|
Encrypts the @arg plaintext string with the key the class was initialized with, and returns
|
||||||
|
a binary cyphertext in a QByteArray the result.
|
||||||
|
|
||||||
|
This method returns a byte array, that is useable for storing a binary format. If you need
|
||||||
|
a string you can store in a text file, use encryptToString() instead.
|
||||||
|
*/
|
||||||
|
QByteArray encryptToByteArray(const QString& plaintext) ;
|
||||||
|
/**
|
||||||
|
Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns
|
||||||
|
a binary cyphertext in a QByteArray the result.
|
||||||
|
|
||||||
|
This method returns a byte array, that is useable for storing a binary format. If you need
|
||||||
|
a string you can store in a text file, use encryptToString() instead.
|
||||||
|
*/
|
||||||
|
QByteArray encryptToByteArray(QByteArray plaintext) ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Decrypts a cyphertext string encrypted with this class with the set key back to the
|
||||||
|
plain text version.
|
||||||
|
|
||||||
|
If an error occured, such as non-matching keys between encryption and decryption,
|
||||||
|
an empty string or a string containing nonsense may be returned.
|
||||||
|
*/
|
||||||
|
QString decryptToString(const QString& cyphertext) ;
|
||||||
|
/**
|
||||||
|
Decrypts a cyphertext string encrypted with this class with the set key back to the
|
||||||
|
plain text version.
|
||||||
|
|
||||||
|
If an error occured, such as non-matching keys between encryption and decryption,
|
||||||
|
an empty string or a string containing nonsense may be returned.
|
||||||
|
*/
|
||||||
|
QByteArray decryptToByteArray(const QString& cyphertext) ;
|
||||||
|
/**
|
||||||
|
Decrypts a cyphertext binary encrypted with this class with the set key back to the
|
||||||
|
plain text version.
|
||||||
|
|
||||||
|
If an error occured, such as non-matching keys between encryption and decryption,
|
||||||
|
an empty string or a string containing nonsense may be returned.
|
||||||
|
*/
|
||||||
|
QString decryptToString(QByteArray cypher) ;
|
||||||
|
/**
|
||||||
|
Decrypts a cyphertext binary encrypted with this class with the set key back to the
|
||||||
|
plain text version.
|
||||||
|
|
||||||
|
If an error occured, such as non-matching keys between encryption and decryption,
|
||||||
|
an empty string or a string containing nonsense may be returned.
|
||||||
|
*/
|
||||||
|
QByteArray decryptToByteArray(QByteArray cypher) ;
|
||||||
|
|
||||||
|
//enum to describe options that have been used for the encryption. Currently only one, but
|
||||||
|
//that only leaves room for future extensions like adding a cryptographic hash...
|
||||||
|
enum CryptoFlag{CryptoFlagNone = 0,
|
||||||
|
CryptoFlagCompression = 0x01,
|
||||||
|
CryptoFlagChecksum = 0x02,
|
||||||
|
CryptoFlagHash = 0x04
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(CryptoFlags, CryptoFlag);
|
||||||
|
private:
|
||||||
|
|
||||||
|
void splitKey();
|
||||||
|
|
||||||
|
quint64 m_key;
|
||||||
|
QVector<char> m_keyParts;
|
||||||
|
CompressionMode m_compressionMode;
|
||||||
|
IntegrityProtectionMode m_protectionMode;
|
||||||
|
Error m_lastError;
|
||||||
|
};
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(SimpleCrypt::CryptoFlags)
|
||||||
|
|
||||||
|
#endif // SimpleCrypt_H
|
||||||
+26
-10
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>965</width>
|
<width>965</width>
|
||||||
<height>591</height>
|
<height>668</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -287,10 +287,10 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_8">
|
<widget class="QGroupBox" name="groupBox_8">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Remote Connection:</string>
|
<string>MQTT Remote CAN Settings:</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
@@ -300,6 +300,9 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineRemoteHost"/>
|
||||||
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_7">
|
<widget class="QLabel" name="label_7">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -307,16 +310,30 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineRemoteHost"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLineEdit" name="lineRemotePort"/>
|
<widget class="QLineEdit" name="lineRemotePort"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="cbAutoStartRemote">
|
<widget class="QLabel" name="label_8">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Auto start remote hosting</string>
|
<string>User Name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineRemoteUser"/>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>Password</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineRemotePassword">
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -371,7 +388,6 @@
|
|||||||
<tabstop>cbInfoAutoExpand</tabstop>
|
<tabstop>cbInfoAutoExpand</tabstop>
|
||||||
<tabstop>lineRemoteHost</tabstop>
|
<tabstop>lineRemoteHost</tabstop>
|
||||||
<tabstop>lineRemotePort</tabstop>
|
<tabstop>lineRemotePort</tabstop>
|
||||||
<tabstop>cbAutoStartRemote</tabstop>
|
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>356</width>
|
<width>359</width>
|
||||||
<height>282</height>
|
<height>291</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QRadioButton" name="rbSocketCAN">
|
<widget class="QRadioButton" name="rbSocketCAN">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
@@ -46,7 +46,14 @@
|
|||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QRadioButton" name="rbRemote">
|
<widget class="QRadioButton" name="rbRemote">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Network connection</string>
|
<string>Network Connection</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbMQTT">
|
||||||
|
<property name="text">
|
||||||
|
<string>MQTT Connection</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user