nuki: Add Qt6 support
parent
d991034b61
commit
35abae7683
|
|
@ -1,6 +1,6 @@
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright 2013 - 2020, nymea GmbH
|
* Copyright 2013 - 2025, nymea GmbH
|
||||||
* Contact: contact@nymea.io
|
* Contact: contact@nymea.io
|
||||||
*
|
*
|
||||||
* This file is part of nymea.
|
* This file is part of nymea.
|
||||||
|
|
@ -29,9 +29,11 @@
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#include "integrationpluginnuki.h"
|
#include "integrationpluginnuki.h"
|
||||||
#include "integrations/thing.h"
|
|
||||||
#include "plugininfo.h"
|
#include "plugininfo.h"
|
||||||
#include "hardware/bluetoothlowenergy/bluetoothlowenergymanager.h"
|
|
||||||
|
#include <integrations/thing.h>
|
||||||
|
#include <hardware/bluetoothlowenergy/bluetoothlowenergymanager.h>
|
||||||
|
|
||||||
|
|
||||||
extern "C"{
|
extern "C"{
|
||||||
#include "sodium.h"
|
#include "sodium.h"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright 2013 - 2020, nymea GmbH
|
* Copyright 2013 - 2025, nymea GmbH
|
||||||
* Contact: contact@nymea.io
|
* Contact: contact@nymea.io
|
||||||
*
|
*
|
||||||
* This file is part of nymea.
|
* This file is part of nymea.
|
||||||
|
|
@ -31,9 +31,9 @@
|
||||||
#ifndef INTEGRATIONPLUGINNUKI_H
|
#ifndef INTEGRATIONPLUGINNUKI_H
|
||||||
#define INTEGRATIONPLUGINNUKI_H
|
#define INTEGRATIONPLUGINNUKI_H
|
||||||
|
|
||||||
#include "plugintimer.h"
|
#include <integrations/integrationplugin.h>
|
||||||
#include "integrations/integrationplugin.h"
|
#include <bluez/bluetoothmanager.h>
|
||||||
#include "bluez/bluetoothmanager.h"
|
#include <plugintimer.h>
|
||||||
|
|
||||||
#include "nuki.h"
|
#include "nuki.h"
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ class IntegrationPluginNuki : public IntegrationPlugin
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "integrationpluginnuki.json")
|
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginnuki.json")
|
||||||
Q_INTERFACES(IntegrationPlugin)
|
Q_INTERFACES(IntegrationPlugin)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,15 @@ void Nuki::printServices()
|
||||||
void Nuki::readDeviceInformationCharacteristics()
|
void Nuki::readDeviceInformationCharacteristics()
|
||||||
{
|
{
|
||||||
qCDebug(dcNuki()) << "Start reading device information";
|
qCDebug(dcNuki()) << "Start reading device information";
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
m_initUuidsToRead.append(QBluetoothUuid::CharacteristicType::SerialNumberString);
|
||||||
|
m_initUuidsToRead.append(QBluetoothUuid::CharacteristicType::HardwareRevisionString);
|
||||||
|
m_initUuidsToRead.append(QBluetoothUuid::CharacteristicType::FirmwareRevisionString);
|
||||||
|
|
||||||
|
m_deviceInformationService->readCharacteristic(QBluetoothUuid::CharacteristicType::SerialNumberString);
|
||||||
|
m_deviceInformationService->readCharacteristic(QBluetoothUuid::CharacteristicType::HardwareRevisionString);
|
||||||
|
m_deviceInformationService->readCharacteristic(QBluetoothUuid::CharacteristicType::FirmwareRevisionString);
|
||||||
|
#else
|
||||||
m_initUuidsToRead.append(QBluetoothUuid::SerialNumberString);
|
m_initUuidsToRead.append(QBluetoothUuid::SerialNumberString);
|
||||||
m_initUuidsToRead.append(QBluetoothUuid::HardwareRevisionString);
|
m_initUuidsToRead.append(QBluetoothUuid::HardwareRevisionString);
|
||||||
m_initUuidsToRead.append(QBluetoothUuid::FirmwareRevisionString);
|
m_initUuidsToRead.append(QBluetoothUuid::FirmwareRevisionString);
|
||||||
|
|
@ -161,6 +170,8 @@ void Nuki::readDeviceInformationCharacteristics()
|
||||||
m_deviceInformationService->readCharacteristic(QBluetoothUuid::SerialNumberString);
|
m_deviceInformationService->readCharacteristic(QBluetoothUuid::SerialNumberString);
|
||||||
m_deviceInformationService->readCharacteristic(QBluetoothUuid::HardwareRevisionString);
|
m_deviceInformationService->readCharacteristic(QBluetoothUuid::HardwareRevisionString);
|
||||||
m_deviceInformationService->readCharacteristic(QBluetoothUuid::FirmwareRevisionString);
|
m_deviceInformationService->readCharacteristic(QBluetoothUuid::FirmwareRevisionString);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nuki::executeCurrentAction()
|
void Nuki::executeCurrentAction()
|
||||||
|
|
@ -253,6 +264,18 @@ void Nuki::onBluetoothDeviceStateChanged(const BluetoothDevice::State &state)
|
||||||
void Nuki::onDeviceInfoCharacteristicReadFinished(BluetoothGattCharacteristic *characteristic, const QByteArray &value)
|
void Nuki::onDeviceInfoCharacteristicReadFinished(BluetoothGattCharacteristic *characteristic, const QByteArray &value)
|
||||||
{
|
{
|
||||||
qCDebug(dcNuki()) << "Read thing information characteristic finished" << characteristic->chararcteristicName() << qUtf8Printable(value);
|
qCDebug(dcNuki()) << "Read thing information characteristic finished" << characteristic->chararcteristicName() << qUtf8Printable(value);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
if (characteristic->uuid() == QBluetoothUuid::CharacteristicType::SerialNumberString) {
|
||||||
|
m_serialNumber = QString::fromUtf8(value);
|
||||||
|
m_initUuidsToRead.removeOne(QBluetoothUuid::CharacteristicType::SerialNumberString);
|
||||||
|
} else if (characteristic->uuid() == QBluetoothUuid::CharacteristicType::HardwareRevisionString) {
|
||||||
|
m_hardwareRevision = QString::fromUtf8(value);
|
||||||
|
m_initUuidsToRead.removeOne(QBluetoothUuid::CharacteristicType::HardwareRevisionString);
|
||||||
|
} else if (characteristic->uuid() == QBluetoothUuid::CharacteristicType::FirmwareRevisionString) {
|
||||||
|
m_firmwareRevision = QString::fromUtf8(value);
|
||||||
|
m_initUuidsToRead.removeOne(QBluetoothUuid::CharacteristicType::FirmwareRevisionString);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (characteristic->uuid() == QBluetoothUuid::SerialNumberString) {
|
if (characteristic->uuid() == QBluetoothUuid::SerialNumberString) {
|
||||||
m_serialNumber = QString::fromUtf8(value);
|
m_serialNumber = QString::fromUtf8(value);
|
||||||
m_initUuidsToRead.removeOne(QBluetoothUuid::SerialNumberString);
|
m_initUuidsToRead.removeOne(QBluetoothUuid::SerialNumberString);
|
||||||
|
|
@ -263,6 +286,7 @@ void Nuki::onDeviceInfoCharacteristicReadFinished(BluetoothGattCharacteristic *c
|
||||||
m_firmwareRevision = QString::fromUtf8(value);
|
m_firmwareRevision = QString::fromUtf8(value);
|
||||||
m_initUuidsToRead.removeOne(QBluetoothUuid::FirmwareRevisionString);
|
m_initUuidsToRead.removeOne(QBluetoothUuid::FirmwareRevisionString);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_initUuidsToRead.isEmpty()) {
|
if (m_initUuidsToRead.isEmpty()) {
|
||||||
// Initial read done. Make thing available
|
// Initial read done. Make thing available
|
||||||
|
|
@ -412,7 +436,11 @@ bool Nuki::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify services
|
// Verify services
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
if (!m_bluetoothDevice->hasService(QBluetoothUuid::ServiceClassUuid::DeviceInformation)) {
|
||||||
|
#else
|
||||||
if (!m_bluetoothDevice->hasService(QBluetoothUuid::DeviceInformation)) {
|
if (!m_bluetoothDevice->hasService(QBluetoothUuid::DeviceInformation)) {
|
||||||
|
#endif
|
||||||
qCWarning(dcNuki()) << "Could not find device information service on device" << m_bluetoothDevice;
|
qCWarning(dcNuki()) << "Could not find device information service on device" << m_bluetoothDevice;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -429,7 +457,11 @@ bool Nuki::init()
|
||||||
|
|
||||||
// Create service and characteristic objects
|
// Create service and characteristic objects
|
||||||
// Device information
|
// Device information
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
m_deviceInformationService = m_bluetoothDevice->getService(QBluetoothUuid::ServiceClassUuid::DeviceInformation);
|
||||||
|
#else
|
||||||
m_deviceInformationService = m_bluetoothDevice->getService(QBluetoothUuid::DeviceInformation);
|
m_deviceInformationService = m_bluetoothDevice->getService(QBluetoothUuid::DeviceInformation);
|
||||||
|
#endif
|
||||||
connect(m_deviceInformationService, &BluetoothGattService::characteristicReadFinished, this, &Nuki::onDeviceInfoCharacteristicReadFinished);
|
connect(m_deviceInformationService, &BluetoothGattService::characteristicReadFinished, this, &Nuki::onDeviceInfoCharacteristicReadFinished);
|
||||||
|
|
||||||
// Keyturner service
|
// Keyturner service
|
||||||
|
|
|
||||||
11
nuki/nuki.h
11
nuki/nuki.h
|
|
@ -1,6 +1,6 @@
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright 2013 - 2020, nymea GmbH
|
* Copyright 2013 - 2025, nymea GmbH
|
||||||
* Contact: contact@nymea.io
|
* Contact: contact@nymea.io
|
||||||
*
|
*
|
||||||
* This file is part of nymea.
|
* This file is part of nymea.
|
||||||
|
|
@ -37,15 +37,16 @@
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
#include "typeutils.h"
|
#include <typeutils.h>
|
||||||
#include "integrations/thing.h"
|
#include <integrations/thing.h>
|
||||||
#include "bluez/bluetoothdevice.h"
|
#include <integrations/thingactioninfo.h>
|
||||||
#include "integrations/thingactioninfo.h"
|
|
||||||
|
|
||||||
#include "nukiutils.h"
|
#include "nukiutils.h"
|
||||||
#include "nukicontroller.h"
|
#include "nukicontroller.h"
|
||||||
#include "nukiauthenticator.h"
|
#include "nukiauthenticator.h"
|
||||||
|
|
||||||
|
#include "bluez/bluetoothdevice.h"
|
||||||
|
|
||||||
//#include "nacl-20110221/crypto_auth/"
|
//#include "nacl-20110221/crypto_auth/"
|
||||||
|
|
||||||
class Nuki : public QObject
|
class Nuki : public QObject
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
include(../plugins.pri)
|
include(../plugins.pri)
|
||||||
|
|
||||||
TARGET = $$qtLibraryTarget(nymea_integrationpluginnuki)
|
QT *= bluetooth dbus
|
||||||
|
|
||||||
QT += bluetooth dbus
|
|
||||||
|
|
||||||
# apt install libsodium-dev
|
# apt install libsodium-dev
|
||||||
LIBS += -lsodium
|
LIBS += -lsodium
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,9 @@ QByteArray NukiAuthenticator::encryptData(const QByteArray &data, const QByteArr
|
||||||
* const unsigned char *sk The private key of nymea for this Nuki
|
* const unsigned char *sk The private key of nymea for this Nuki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned char encrypted[crypto_box_MACBYTES + data.length()];
|
unsigned char *encrypted = NULL;
|
||||||
|
std::vector<unsigned char> realBuffer(crypto_box_MACBYTES + data.length());
|
||||||
|
encrypted = &realBuffer[0];
|
||||||
int result = crypto_box_easy(encrypted,
|
int result = crypto_box_easy(encrypted,
|
||||||
reinterpret_cast<const unsigned char *>(data.data()),
|
reinterpret_cast<const unsigned char *>(data.data()),
|
||||||
static_cast<unsigned long long>(data.length()),
|
static_cast<unsigned long long>(data.length()),
|
||||||
|
|
@ -165,8 +167,9 @@ QByteArray NukiAuthenticator::decryptData(const QByteArray &data, const QByteArr
|
||||||
* const unsigned char *pk The public key of the Nuki
|
* const unsigned char *pk The public key of the Nuki
|
||||||
* const unsigned char *sk The private key of nymea for this Nuki
|
* const unsigned char *sk The private key of nymea for this Nuki
|
||||||
*/
|
*/
|
||||||
|
unsigned char *decrypted = NULL;
|
||||||
unsigned char decrypted[data.length() - crypto_box_MACBYTES];
|
std::vector<unsigned char> realBuffer(data.length() - crypto_box_MACBYTES);
|
||||||
|
decrypted = &realBuffer[0];
|
||||||
int result = crypto_box_open_easy(decrypted,
|
int result = crypto_box_open_easy(decrypted,
|
||||||
reinterpret_cast<const unsigned char *>(data.data()),
|
reinterpret_cast<const unsigned char *>(data.data()),
|
||||||
static_cast<unsigned long long>(data.length()),
|
static_cast<unsigned long long>(data.length()),
|
||||||
|
|
@ -190,9 +193,11 @@ QByteArray NukiAuthenticator::decryptData(const QByteArray &data, const QByteArr
|
||||||
return decryptedData;
|
return decryptedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray NukiAuthenticator::generateNonce(const int &length) const
|
QByteArray NukiAuthenticator::generateNonce(int length) const
|
||||||
{
|
{
|
||||||
unsigned char nounce[length];
|
unsigned char *nounce = NULL;
|
||||||
|
std::vector<unsigned char> realBuffer(length);
|
||||||
|
nounce = &realBuffer[0];
|
||||||
randombytes_buf(nounce, length);
|
randombytes_buf(nounce, length);
|
||||||
return QByteArray(reinterpret_cast<const char *>(nounce), length);
|
return QByteArray(reinterpret_cast<const char *>(nounce), length);
|
||||||
}
|
}
|
||||||
|
|
@ -295,7 +300,11 @@ void NukiAuthenticator::requestPublicKey()
|
||||||
qCDebug(dcNuki()) << "Authenticator: Request public key fom Nuki";
|
qCDebug(dcNuki()) << "Authenticator: Request public key fom Nuki";
|
||||||
|
|
||||||
QByteArray payload;
|
QByteArray payload;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&payload, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&payload, QIODevice::WriteOnly);
|
QDataStream stream(&payload, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint16>(NukiUtils::CommandPublicKey);
|
stream << static_cast<quint16>(NukiUtils::CommandPublicKey);
|
||||||
QByteArray data = NukiUtils::createRequestMessageForUnencrypted(NukiUtils::CommandRequestData, payload);
|
QByteArray data = NukiUtils::createRequestMessageForUnencrypted(NukiUtils::CommandRequestData, payload);
|
||||||
|
|
@ -351,7 +360,11 @@ void NukiAuthenticator::sendAuthenticateData()
|
||||||
m_nonce = generateNonce();
|
m_nonce = generateNonce();
|
||||||
|
|
||||||
QByteArray content;
|
QByteArray content;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&content, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&content, QIODevice::WriteOnly);
|
QDataStream stream(&content, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
// Note: 0x00 = App, 0x01 = Bridge, 0x02 = Fob
|
// Note: 0x00 = App, 0x01 = Bridge, 0x02 = Fob
|
||||||
stream << static_cast<quint8>(0x01);
|
stream << static_cast<quint8>(0x01);
|
||||||
// Note: app id (42)
|
// Note: app id (42)
|
||||||
|
|
@ -359,7 +372,7 @@ void NukiAuthenticator::sendAuthenticateData()
|
||||||
|
|
||||||
// Note: the name of the bridge in 32 bytes [ 0 0 0 ... n y m e a ]
|
// Note: the name of the bridge in 32 bytes [ 0 0 0 ... n y m e a ]
|
||||||
QByteArray name = QByteArray(27, '\0').append(QByteArray("nymea"));
|
QByteArray name = QByteArray(27, '\0').append(QByteArray("nymea"));
|
||||||
Q_ASSERT_X(name.count() == 32, "data length", "Name has not the correct length.");
|
Q_ASSERT_X(name.length() == 32, "data length", "Name has not the correct length.");
|
||||||
|
|
||||||
QByteArray valueR = content;
|
QByteArray valueR = content;
|
||||||
valueR.append(name);
|
valueR.append(name);
|
||||||
|
|
@ -454,7 +467,11 @@ void NukiAuthenticator::onPairingDataCharacteristicChanged(const QByteArray &val
|
||||||
|
|
||||||
// Process pairing characteristic data
|
// Process pairing characteristic data
|
||||||
QByteArray data = QByteArray(value);
|
QByteArray data = QByteArray(value);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&data, QDataStream::ReadOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&data, QIODevice::ReadOnly);
|
QDataStream stream(&data, QIODevice::ReadOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint16 command;
|
quint16 command;
|
||||||
stream >> command;
|
stream >> command;
|
||||||
|
|
@ -517,21 +534,25 @@ void NukiAuthenticator::onPairingDataCharacteristicChanged(const QByteArray &val
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse data
|
// Parse data
|
||||||
QByteArray message = m_currentReceivingData.mid(2, m_currentReceivingData.count() - 4);
|
QByteArray message = m_currentReceivingData.mid(2, m_currentReceivingData.length() - 4);
|
||||||
QByteArray authenticator = message.left(32);
|
QByteArray authenticator = message.left(32);
|
||||||
Q_ASSERT_X(authenticator.count() == 32, "data length", "Nuki nonce has not the correct length.");
|
Q_ASSERT_X(authenticator.length() == 32, "data length", "Nuki nonce has not the correct length.");
|
||||||
|
|
||||||
// Read authorization ID
|
// Read authorization ID
|
||||||
m_authorizationIdRawData = message.mid(32, 4);
|
m_authorizationIdRawData = message.mid(32, 4);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&m_authorizationIdRawData, QDataStream::ReadOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&m_authorizationIdRawData, QIODevice::ReadOnly);
|
QDataStream stream(&m_authorizationIdRawData, QIODevice::ReadOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream >> m_authorizationId;
|
stream >> m_authorizationId;
|
||||||
|
|
||||||
m_uuid = message.mid(36, 16);
|
m_uuid = message.mid(36, 16);
|
||||||
Q_ASSERT_X(m_uuid.count() == 16, "data length", "UUID has not the correct length.");
|
Q_ASSERT_X(m_uuid.length() == 16, "data length", "UUID has not the correct length.");
|
||||||
|
|
||||||
m_nonceNuki = message.mid(52, 32);
|
m_nonceNuki = message.mid(52, 32);
|
||||||
Q_ASSERT_X(m_nonceNuki.count() == 32, "data length", "Nuki nonce has not the correct length.");
|
Q_ASSERT_X(m_nonceNuki.length() == 32, "data length", "Nuki nonce has not the correct length.");
|
||||||
|
|
||||||
if (m_debug) qCDebug(dcNuki()) << " Full message :" << NukiUtils::convertByteArrayToHexStringCompact(message);
|
if (m_debug) qCDebug(dcNuki()) << " Full message :" << NukiUtils::convertByteArrayToHexStringCompact(message);
|
||||||
if (m_debug) qCDebug(dcNuki()) << " Authenticator :" << NukiUtils::convertByteArrayToHexStringCompact(authenticator);
|
if (m_debug) qCDebug(dcNuki()) << " Authenticator :" << NukiUtils::convertByteArrayToHexStringCompact(authenticator);
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ public:
|
||||||
QByteArray decryptData(const QByteArray &data, const QByteArray &nonce);
|
QByteArray decryptData(const QByteArray &data, const QByteArray &nonce);
|
||||||
|
|
||||||
// Generate 32 byte nonce data
|
// Generate 32 byte nonce data
|
||||||
QByteArray generateNonce(const int &length = 32) const;
|
QByteArray generateNonce(int length = 32) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QBluetoothHostInfo m_hostInfo;
|
QBluetoothHostInfo m_hostInfo;
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,11 @@ void NukiController::processNukiStatesData(const QByteArray &data)
|
||||||
quint8 batteryCritical = 0;
|
quint8 batteryCritical = 0;
|
||||||
|
|
||||||
QByteArray payload = data;
|
QByteArray payload = data;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&payload, QDataStream::ReadOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&payload, QIODevice::ReadOnly);
|
QDataStream stream(&payload, QIODevice::ReadOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream >> nukiState >> nukiLockState >> nukiLockTrigger >> year >> month >> day >> hour >> minute >> second >> utcOffset >> batteryCritical;
|
stream >> nukiState >> nukiLockState >> nukiLockTrigger >> year >> month >> day >> hour >> minute >> second >> utcOffset >> batteryCritical;
|
||||||
|
|
||||||
|
|
@ -273,7 +277,11 @@ void NukiController::processNukiErrorReport(const QByteArray &data)
|
||||||
quint16 nukiCommand;
|
quint16 nukiCommand;
|
||||||
|
|
||||||
QByteArray payload = data;
|
QByteArray payload = data;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&payload, QDataStream::ReadOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&payload, QIODevice::ReadOnly);
|
QDataStream stream(&payload, QIODevice::ReadOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream >> errorCode >> nukiCommand;
|
stream >> errorCode >> nukiCommand;
|
||||||
|
|
||||||
|
|
@ -441,7 +449,11 @@ void NukiController::sendReadLockStateRequest()
|
||||||
|
|
||||||
// Create data for encryption
|
// Create data for encryption
|
||||||
QByteArray payload;
|
QByteArray payload;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&payload, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&payload, QIODevice::WriteOnly);
|
QDataStream stream(&payload, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint16>(NukiUtils::CommandNukiStates);
|
stream << static_cast<quint16>(NukiUtils::CommandNukiStates);
|
||||||
|
|
||||||
|
|
@ -477,7 +489,11 @@ void NukiController::sendReadConfigurationRequest()
|
||||||
|
|
||||||
// Create data for encryption
|
// Create data for encryption
|
||||||
QByteArray payload;
|
QByteArray payload;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&payload, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&payload, QIODevice::WriteOnly);
|
QDataStream stream(&payload, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint16>(NukiUtils::CommandRequestConfig);
|
stream << static_cast<quint16>(NukiUtils::CommandRequestConfig);
|
||||||
for (int i = 0; i < m_nukiNonce.length(); i++) {
|
for (int i = 0; i < m_nukiNonce.length(); i++) {
|
||||||
|
|
@ -516,7 +532,11 @@ void NukiController::sendRequestChallengeRequest()
|
||||||
|
|
||||||
// Create data for encryption
|
// Create data for encryption
|
||||||
QByteArray payload;
|
QByteArray payload;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&payload, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&payload, QIODevice::WriteOnly);
|
QDataStream stream(&payload, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint16>(NukiUtils::CommandChallenge);
|
stream << static_cast<quint16>(NukiUtils::CommandChallenge);
|
||||||
|
|
||||||
|
|
@ -554,7 +574,11 @@ void NukiController::sendLockActionRequest(NukiUtils::LockAction lockAction, qui
|
||||||
|
|
||||||
// Create data for encryption
|
// Create data for encryption
|
||||||
QByteArray payload;
|
QByteArray payload;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&payload, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&payload, QIODevice::WriteOnly);
|
QDataStream stream(&payload, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint8>(lockAction);
|
stream << static_cast<quint8>(lockAction);
|
||||||
stream << static_cast<quint32>(m_nukiAuthenticator->authorizationId());
|
stream << static_cast<quint32>(m_nukiAuthenticator->authorizationId());
|
||||||
|
|
@ -596,7 +620,7 @@ void NukiController::onUserDataCharacteristicChanged(const QByteArray &value)
|
||||||
|
|
||||||
m_messageBuffer = value;
|
m_messageBuffer = value;
|
||||||
|
|
||||||
if (m_messageBuffer.count() < 30) {
|
if (m_messageBuffer.length() < 30) {
|
||||||
qCWarning(dcNuki()) << "Controller: Cannot understand message. Rejecting.";
|
qCWarning(dcNuki()) << "Controller: Cannot understand message. Rejecting.";
|
||||||
resetMessageBuffer();
|
resetMessageBuffer();
|
||||||
return;
|
return;
|
||||||
|
|
@ -605,14 +629,18 @@ void NukiController::onUserDataCharacteristicChanged(const QByteArray &value)
|
||||||
// Parse message length
|
// Parse message length
|
||||||
// ADATA: 24 byte nonce, 4 byte autorization, 2 byte encrypted message length
|
// ADATA: 24 byte nonce, 4 byte autorization, 2 byte encrypted message length
|
||||||
m_messageBufferAData = m_messageBuffer.left(30);
|
m_messageBufferAData = m_messageBuffer.left(30);
|
||||||
m_messageBufferPData = m_messageBuffer.right(m_messageBuffer.count() - 30);
|
m_messageBufferPData = m_messageBuffer.right(m_messageBuffer.length() - 30);
|
||||||
m_messageBufferNonce = m_messageBufferAData.left(24);
|
m_messageBufferNonce = m_messageBufferAData.left(24);
|
||||||
QByteArray messageInformation = m_messageBufferAData.right(6);
|
QByteArray messageInformation = m_messageBufferAData.right(6);
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&messageInformation, QDataStream::ReadOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&messageInformation, QIODevice::ReadOnly);
|
QDataStream stream(&messageInformation, QIODevice::ReadOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream >> m_messageBufferIdentifier >> m_messageBufferLength;
|
stream >> m_messageBufferIdentifier >> m_messageBufferLength;
|
||||||
if (m_messageBufferPData.count() == m_messageBufferLength) {
|
if (m_messageBufferPData.length() == m_messageBufferLength) {
|
||||||
processUserDataNotification(m_messageBufferNonce, m_messageBufferIdentifier, m_messageBufferPData);
|
processUserDataNotification(m_messageBufferNonce, m_messageBufferIdentifier, m_messageBufferPData);
|
||||||
resetMessageBuffer();
|
resetMessageBuffer();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@ QString NukiUtils::convertByteToHexString(const quint8 &byte)
|
||||||
QString NukiUtils::convertByteArrayToHexString(const QByteArray &byteArray)
|
QString NukiUtils::convertByteArrayToHexString(const QByteArray &byteArray)
|
||||||
{
|
{
|
||||||
QString hexString;
|
QString hexString;
|
||||||
for (int i = 0; i < byteArray.count(); i++) {
|
for (int i = 0; i < byteArray.length(); i++) {
|
||||||
hexString.append(convertByteToHexString(static_cast<quint8>(byteArray.at(i))));
|
hexString.append(convertByteToHexString(static_cast<quint8>(byteArray.at(i))));
|
||||||
if (i != byteArray.count() - 1) {
|
if (i != byteArray.length() - 1) {
|
||||||
hexString.append(" ");
|
hexString.append(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +67,11 @@ QString NukiUtils::convertByteArrayToHexStringCompact(const QByteArray &byteArra
|
||||||
QString NukiUtils::convertUint16ToHexString(const quint16 &value)
|
QString NukiUtils::convertUint16ToHexString(const quint16 &value)
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&data, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream << value;
|
stream << value;
|
||||||
|
|
||||||
return QString("0x%1").arg(convertByteArrayToHexString(data).remove(" ").remove("0x"));
|
return QString("0x%1").arg(convertByteArrayToHexString(data).remove(" ").remove("0x"));
|
||||||
|
|
@ -76,7 +80,11 @@ QString NukiUtils::convertUint16ToHexString(const quint16 &value)
|
||||||
QByteArray NukiUtils::converUint32ToByteArrayLittleEndian(const quint32 &value)
|
QByteArray NukiUtils::converUint32ToByteArrayLittleEndian(const quint32 &value)
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&data, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << value;
|
stream << value;
|
||||||
Q_ASSERT_X(data.length() == 4, "data converting", "Could not convert quint32 value to byte array (little endian)");
|
Q_ASSERT_X(data.length() == 4, "data converting", "Could not convert quint32 value to byte array (little endian)");
|
||||||
|
|
@ -86,7 +94,11 @@ QByteArray NukiUtils::converUint32ToByteArrayLittleEndian(const quint32 &value)
|
||||||
QByteArray NukiUtils::converUint16ToByteArrayLittleEndian(const quint16 &value)
|
QByteArray NukiUtils::converUint16ToByteArrayLittleEndian(const quint16 &value)
|
||||||
{
|
{
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&data, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << value;
|
stream << value;
|
||||||
Q_ASSERT_X(data.length() == 2, "data converting", "Could not convert quint16 value to byte array (little endian)");
|
Q_ASSERT_X(data.length() == 2, "data converting", "Could not convert quint16 value to byte array (little endian)");
|
||||||
|
|
@ -99,7 +111,11 @@ quint16 NukiUtils::convertByteArrayToUint16BigEndian(const QByteArray &littleEnd
|
||||||
|
|
||||||
quint16 value = 0;
|
quint16 value = 0;
|
||||||
QByteArray data(littleEndianByteArray);
|
QByteArray data(littleEndianByteArray);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&data, QDataStream::ReadOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&data, QIODevice::ReadOnly);
|
QDataStream stream(&data, QIODevice::ReadOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream >> value;
|
stream >> value;
|
||||||
return value;
|
return value;
|
||||||
|
|
@ -111,7 +127,11 @@ quint32 NukiUtils::convertByteArrayToUint32BigEndian(const QByteArray &littleEnd
|
||||||
|
|
||||||
quint32 value = 0;
|
quint32 value = 0;
|
||||||
QByteArray data(littleEndianByteArray);
|
QByteArray data(littleEndianByteArray);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&data, QDataStream::ReadOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&data, QIODevice::ReadOnly);
|
QDataStream stream(&data, QIODevice::ReadOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream >> value;
|
stream >> value;
|
||||||
return value;
|
return value;
|
||||||
|
|
@ -140,11 +160,15 @@ bool NukiUtils::validateMessageCrc(const QByteArray &message)
|
||||||
{
|
{
|
||||||
quint16 crcValue = 0;
|
quint16 crcValue = 0;
|
||||||
QByteArray crcValueRaw = message.right(2);
|
QByteArray crcValueRaw = message.right(2);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&crcValueRaw, QDataStream::ReadOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&crcValueRaw, QIODevice::ReadOnly);
|
QDataStream stream(&crcValueRaw, QIODevice::ReadOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream >> crcValue;
|
stream >> crcValue;
|
||||||
|
|
||||||
QByteArray content = message.left(message.count() - 2);
|
QByteArray content = message.left(message.length() - 2);
|
||||||
|
|
||||||
quint16 calculatedCrcValue = calculateCrc(content);
|
quint16 calculatedCrcValue = calculateCrc(content);
|
||||||
if (crcValue != calculatedCrcValue) {
|
if (crcValue != calculatedCrcValue) {
|
||||||
|
|
@ -163,7 +187,11 @@ QByteArray NukiUtils::createRequestMessageForUnencrypted(NukiUtils::Command comm
|
||||||
* 2 Bytes: crc (LittleEndian)
|
* 2 Bytes: crc (LittleEndian)
|
||||||
*/
|
*/
|
||||||
QByteArray message;
|
QByteArray message;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&message, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&message, QIODevice::WriteOnly);
|
QDataStream stream(&message, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint16>(command);
|
stream << static_cast<quint16>(command);
|
||||||
|
|
||||||
|
|
@ -186,7 +214,11 @@ QByteArray NukiUtils::createRequestMessageForUnencryptedForEncryption(quint32 au
|
||||||
*/
|
*/
|
||||||
|
|
||||||
QByteArray message;
|
QByteArray message;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QDataStream stream(&message, QDataStream::WriteOnly);
|
||||||
|
#else
|
||||||
QDataStream stream(&message, QIODevice::WriteOnly);
|
QDataStream stream(&message, QIODevice::WriteOnly);
|
||||||
|
#endif
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << authenticationId;
|
stream << authenticationId;
|
||||||
stream << static_cast<quint16>(command);
|
stream << static_cast<quint16>(command);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue