diff --git a/doorbird/deviceplugindoorbird.cpp b/doorbird/deviceplugindoorbird.cpp index 09123d25..03f117eb 100644 --- a/doorbird/deviceplugindoorbird.cpp +++ b/doorbird/deviceplugindoorbird.cpp @@ -35,64 +35,74 @@ DevicePluginDoorbird::DevicePluginDoorbird() { } -DevicePluginDoorbird::~DevicePluginDoorbird() -{ -} - -Device::DeviceError DevicePluginDoorbird::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) +void DevicePluginDoorbird::discoverDevices(DeviceDiscoveryInfo *info) { - Q_UNUSED(params) - if (deviceClassId == doorBirdDeviceClassId) { - ZeroConfServiceBrowser *serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser(); - QTimer::singleShot(5000, this, [this, serviceBrowser](){ - QList deviceDescriptors; + if (info->deviceClassId() == doorBirdDeviceClassId) { + ZeroConfServiceBrowser *serviceBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_axis-video._tcp"); + connect(info, &QObject::destroyed, serviceBrowser, &QObject::deleteLater); + + QTimer::singleShot(5000, this, [this, info, serviceBrowser](){ foreach (const ZeroConfServiceEntry serviceEntry, serviceBrowser->serviceEntries()) { if (serviceEntry.hostName().startsWith("bha-")) { - qCDebug(dcDoorBird) << "Found DoorBird device"; + qCDebug(dcDoorBird) << "Found DoorBird device, name: " << serviceEntry.name() << "\n host address:" << serviceEntry.hostAddress().toString() << "\n text:" << serviceEntry.txt() << serviceEntry.protocol() << serviceEntry.serviceType(); DeviceDescriptor deviceDescriptor(doorBirdDeviceClassId, serviceEntry.name(), serviceEntry.hostAddress().toString()); ParamList params; - //TODO add rediscovery - params.append(Param(doorBirdDeviceSerialnumberParamTypeId, serviceEntry.hostName())); + QString macAddress = serviceEntry.txt().first(); + if (!myDevices().filterByParam(doorBirdDeviceSerialnumberParamTypeId, macAddress).isEmpty()) { + Device *existingDevice = myDevices().filterByParam(doorBirdDeviceSerialnumberParamTypeId, serviceEntry.hostName()).first(); + deviceDescriptor.setDeviceId(existingDevice->id()); + } + params.append(Param(doorBirdDeviceSerialnumberParamTypeId, macAddress)); params.append(Param(doorBirdDeviceAddressParamTypeId, serviceEntry.hostAddress().toString())); deviceDescriptor.setParams(params); - deviceDescriptors.append(deviceDescriptor); + info->addDeviceDescriptor(deviceDescriptor); } } - emit devicesDiscovered(doorBirdDeviceClassId, deviceDescriptors); serviceBrowser->deleteLater(); + info->finish(Device::DeviceErrorNoError); }); - return Device::DeviceErrorAsync; + return; } - return Device::DeviceErrorDeviceClassNotFound; -} - -DevicePairingInfo DevicePluginDoorbird::pairDevice(DevicePairingInfo &devicePairingInfo) -{ - qCDebug(dcDoorBird()) << "PairDevice:" << devicePairingInfo.deviceClassId(); - - devicePairingInfo.setStatus(Device::DeviceErrorNoError); - devicePairingInfo.setMessage(tr("Please enter username and password for your Doorbird device.")); - return devicePairingInfo; -} - -DevicePairingInfo DevicePluginDoorbird::confirmPairing(DevicePairingInfo &devicePairingInfo, const QString &username, const QString &secret) -{ - qCDebug(dcDoorBird()) << "confirm pairing called"; - - pluginStorage()->beginGroup(devicePairingInfo.deviceId().toString()); - pluginStorage()->setValue("username", username); - pluginStorage()->setValue("password", secret); - pluginStorage()->endGroup(); - - devicePairingInfo.setStatus(Device::DeviceErrorNoError); - - return devicePairingInfo; + qCWarning(dcDoorBird()) << "Cannot discover for deviceClassId" << info->deviceClassId(); + info->finish(Device::DeviceErrorDeviceNotFound); } -Device::DeviceSetupStatus DevicePluginDoorbird::setupDevice(Device *device) +void DevicePluginDoorbird::startPairing(DevicePairingInfo *info) { + + if (info->deviceClassId() == doorBirdDeviceClassId) { + qCDebug(dcDoorBird()) << "User and password. Login is \"user\" and \"password\"."; + info->finish(Device::DeviceErrorNoError, QT_TR_NOOP("Please enter the user credentials")); + return; + } + info->finish(Device::DeviceErrorCreationMethodNotSupported); +} + + +void DevicePluginDoorbird::confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret) +{ + if (info->deviceClassId() == doorBirdDeviceClassId) { + qCDebug(dcDoorBird()) << "confirm pairing called"; + + pluginStorage()->beginGroup(info->deviceId().toString()); + pluginStorage()->setValue("username", username); + pluginStorage()->setValue("password", secret); + pluginStorage()->endGroup(); + + info->finish(Device::DeviceErrorNoError); + return; + } + info->finish(Device::DeviceErrorDeviceClassNotFound); + return; +} + + +void DevicePluginDoorbird::setupDevice(DeviceSetupInfo *info) +{ + Device *device = info->device(); + if (device->deviceClassId() == doorBirdDeviceClassId) { QHostAddress address = QHostAddress(device->paramValue(doorBirdDeviceAddressParamTypeId).toString()); @@ -101,32 +111,61 @@ Device::DeviceSetupStatus DevicePluginDoorbird::setupDevice(Device *device) QString password = pluginStorage()->value("password").toString(); pluginStorage()->endGroup(); + qCDebug(dcDoorBird()) << "Device setup" << device->name() << username << password; Doorbird *doorbird = new Doorbird(address, username, password, this); + connect(doorbird, &Doorbird::deviceConnected, this, &DevicePluginDoorbird::onDoorBirdConnected); + connect(doorbird, &Doorbird::eventReveiced, this, &DevicePluginDoorbird::onDoorBirdEvent); + connect(doorbird, &Doorbird::requestSent, this, &DevicePluginDoorbird::onDoorBirdRequestSent); doorbird->connectToEventMonitor(); m_doorbirdConnections.insert(device, doorbird); - return Device::DeviceSetupStatusSuccess; + info->finish(Device::DeviceErrorNoError); + return; } - return Device::DeviceSetupStatusFailure; + qCWarning(dcDoorBird()) << "Unhandled device class" << info->device()->deviceClass(); + info->finish(Device::DeviceErrorDeviceClassNotFound); } -Device::DeviceError DevicePluginDoorbird::executeAction(Device *device, const Action &action) + +void DevicePluginDoorbird::postSetupDevice(Device *device) { if (device->deviceClassId() == doorBirdDeviceClassId) { - Doorbird *doorbird = m_doorbirdConnections.value(device); - if (!doorbird) - return Device::DeviceErrorDeviceNotFound; - - if (action.actionTypeId() == doorBirdOpenDoorActionTypeId) { - //Todo get action param - doorbird->openDoor(1); - return Device::DeviceErrorNoError; - } - if (action.actionTypeId() == doorBirdLightOnActionTypeId) { - doorbird->lightOn(); - return Device::DeviceErrorNoError; - } + Doorbird *doorbird = m_doorbirdConnections.value(device); + doorbird->infoRequest(); + doorbird->listFavorites(); + doorbird->listSchedules(); } - return Device::DeviceErrorDeviceClassNotFound; +} + + +void DevicePluginDoorbird::executeAction(DeviceActionInfo *info) +{ + Device *device = info->device(); + Action action = info->action(); + + if (device->deviceClassId() == doorBirdDeviceClassId) { + Doorbird *doorbird = m_doorbirdConnections.value(device); + if (!doorbird) { + info->finish(Device::DeviceErrorHardwareFailure); + return; + } + if (action.actionTypeId() == doorBirdOpenDoorActionTypeId) { + int number = action.param(doorBirdOpenDoorActionNumberParamTypeId).value().toInt(); + doorbird->openDoor(number); + info->finish(Device::DeviceErrorNoError); + return; + } else if (action.actionTypeId() == doorBirdLightOnActionTypeId) { + doorbird->lightOn(); + info->finish(Device::DeviceErrorNoError); + return; + } else if (action.actionTypeId() == doorBirdRestartActionTypeId) { + doorbird->restart(); + info->finish(Device::DeviceErrorNoError); + return; + } + info->finish(Device::DeviceErrorActionTypeNotFound); + return; + } + info->finish(Device::DeviceErrorDeviceClassNotFound); } void DevicePluginDoorbird::deviceRemoved(Device *device) @@ -136,3 +175,59 @@ void DevicePluginDoorbird::deviceRemoved(Device *device) doorbirdConnection->deleteLater(); } } + +void DevicePluginDoorbird::onDoorBirdConnected(bool status) +{ + Doorbird *doorbird = static_cast(sender()); + Device *device = m_doorbirdConnections.key(doorbird); + if (!device) + return; + + device->setStateValue(doorBirdConnectedStateTypeId, status); +} + +void DevicePluginDoorbird::onDoorBirdEvent(Doorbird::EventType eventType, bool status) +{ + Doorbird *doorbird = static_cast(sender()); + Device *device = m_doorbirdConnections.key(doorbird); + if (!device) + return; + + switch (eventType) { + case Doorbird::EventType::Rfid: + break; + case Doorbird::EventType::Input: + break; + case Doorbird::EventType::Motion: + device->setStateValue(doorBirdIsPresentStateTypeId, status); + if (status) { + doorbird->liveImageRequest(); + } + break; + case Doorbird::EventType::Doorbell: + if (status) { + emit emitEvent(Event(doorBirdDoorbellPressedEventTypeId ,device->id())); + } + break; + } +} + +void DevicePluginDoorbird::onDoorBirdRequestSent(QUuid requestId, bool success) +{ + Doorbird *doorbird = static_cast(sender()); + Device *device = m_doorbirdConnections.key(doorbird); + if (!device) + return; + + if (!m_asyncActions.contains(requestId)) + return; + + DeviceActionInfo* actionInfo = m_asyncActions.take(requestId); + actionInfo->finish(success ? Device::DeviceErrorNoError : Device::DeviceErrorInvalidParameter); +} + +void DevicePluginDoorbird::onImageReceived(QImage image) +{ + Q_UNUSED(image) + //QString code = +} diff --git a/doorbird/deviceplugindoorbird.h b/doorbird/deviceplugindoorbird.h index e18b250e..9be0a4ee 100644 --- a/doorbird/deviceplugindoorbird.h +++ b/doorbird/deviceplugindoorbird.h @@ -21,6 +21,8 @@ #ifndef DEVICEPLUGINDOORBIRD_H #define DEVICEPLUGINDOORBIRD_H +#include + #include "devices/deviceplugin.h" #include "devices/devicemanager.h" #include "doorbird.h" @@ -35,22 +37,28 @@ class DevicePluginDoorbird: public DevicePlugin Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "deviceplugindoorbird.json") Q_INTERFACES(DevicePlugin) - public: explicit DevicePluginDoorbird(); - ~DevicePluginDoorbird() override; - Device::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override; + void discoverDevices(DeviceDiscoveryInfo *info) override; + void setupDevice(DeviceSetupInfo *info) override; + void postSetupDevice(Device *device) override; + void executeAction(DeviceActionInfo *info) override; - Device::DeviceSetupStatus setupDevice(Device *device) override; - Device::DeviceError executeAction(Device *device, const Action &action) override; + void startPairing(DevicePairingInfo *info) override; + void confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret) override; - DevicePairingInfo confirmPairing(DevicePairingInfo &devicePairingInfo, const QString &username, const QString &secret) override; - DevicePairingInfo pairDevice(DevicePairingInfo &devicePairingInfo) override; void deviceRemoved(Device *device)override; private: QHash m_doorbirdConnections; + QHash m_asyncActions; + +private slots: + void onDoorBirdConnected(bool status); + void onDoorBirdEvent(Doorbird::EventType eventType, bool status); + void onDoorBirdRequestSent(QUuid requestId, bool success); + void onImageReceived(QImage image); }; #endif // DEVICEPLUGINDOORBIRD_H diff --git a/doorbird/deviceplugindoorbird.json b/doorbird/deviceplugindoorbird.json index 8f9ed2ee..caa78c48 100644 --- a/doorbird/deviceplugindoorbird.json +++ b/doorbird/deviceplugindoorbird.json @@ -33,12 +33,30 @@ { "id": "b6c3377b-91de-411a-9d48-8b509c39d67c", "name": "openDoor", - "displayName": "Open door" + "displayName": "Open door", + "paramTypes": [ + { + "id": "95dd35d7-0bc3-49e1-af96-d8da8ea5244d", + "name": "number", + "displayName": "Relay number", + "type": "QString", + "allowedValues": [ + "1", + "2" + ], + "defaultValue": 1 + } + ] }, { "id": "3a6cfc5d-804c-4d21-91b5-999913d4f1a5", "name": "lightOn", "displayName": "Light on" + }, + { + "id": "e874242e-5acb-4d98-94c7-0a70db65150c", + "name": "restart", + "displayName": "Restart" } ], "stateTypes": [ diff --git a/doorbird/doorbird.cpp b/doorbird/doorbird.cpp index a2a6dce9..429b4b45 100644 --- a/doorbird/doorbird.cpp +++ b/doorbird/doorbird.cpp @@ -218,11 +218,11 @@ QUuid Doorbird::infoRequest() reply->deleteLater(); if (reply->error() != QNetworkReply::NoError) { - qCWarning(dcDoorBird) << "Error unlatching DoorBird device"; + qCWarning(dcDoorBird) << "Error DoorBird" << reply->error() << reply->errorString(); emit requestSent(requestId, false); return; } - qCDebug(dcDoorBird) << "DoorBird unlatched:" << reply->error() << reply->errorString(); + qCDebug(dcDoorBird) << "DoorBird info:" << reply->readAll() ; emit requestSent(requestId, true); }); return requestId; @@ -247,6 +247,36 @@ QUuid Doorbird::listFavorites() return requestId; } +QUuid Doorbird::addFavorite(FavoriteType type, const QString &name, const QUrl &commandUrl, int id) +{ + QUrl url(QString("http://%1/bha-api/favorites.cgi").arg(m_address.toString())); + QUrlQuery query; + query.addQueryItem("action", "save"); + if (type == FavoriteType::Http) { + query.addQueryItem("type", "http"); + } else { + query.addQueryItem("type", "sip"); + } + query.addQueryItem("title", name); + query.addQueryItem("value", commandUrl.toString()); + query.addQueryItem("id", QString::number(id)); + url.setQuery(query); + + QNetworkReply *reply = m_networkAccessManager->get(QNetworkRequest(url)); + QUuid requestId = QUuid::createUuid(); + connect(reply, &QNetworkReply::finished, this, [this, reply, requestId](){ + reply->deleteLater(); + + if (reply->error() != QNetworkReply::NoError) { + qCWarning(dcDoorBird) << "Error DoorBird device" << reply->error() << reply->errorString(); + emit requestSent(requestId, false); + return; + } + emit requestSent(requestId, true); + }); + return requestId; +} + QUuid Doorbird::listSchedules() { QNetworkRequest request(QString("http://%1/bha-api/schedule.cgi").arg(m_address.toString())); @@ -297,35 +327,34 @@ void Doorbird::connectToEventMonitor() Q_UNUSED(bytesReceived) Q_UNUSED(bytesTotal); - //TODO emit signal connected - m_readBuffers.append(reply->readAll()); - // qCDebug(dcDoorBird) << "Monitor data for" << device->name(); - // qCDebug(dcDoorBird) << m_readBuffers[device]; + emit deviceConnected(true); + m_readBuffer.append(reply->readAll()); + qCDebug(dcDoorBird) << "Event received" << m_readBuffer; // Input data looks like: // "--ioboundary\r\nContent-Type: text/plain\r\n\r\ndoorbell:H\r\n\r\n" - while (!m_readBuffers.isEmpty()) { + while (!m_readBuffer.isEmpty()) { // find next --ioboundary - /*QString boundary = QStringLiteral("--ioboundary"); - int startIndex = m_readBuffers.indexOf(boundary); + QString boundary = QStringLiteral("--ioboundary"); + int startIndex = m_readBuffer.indexOf(boundary); if (startIndex == -1) { - qCWarning(dcDoorBird) << "No meaningful data in buffer:" << m_readBuffers; - if (m_readBuffers.size() > 1024) { + qCWarning(dcDoorBird) << "No meaningful data in buffer:" << m_readBuffer; + if (m_readBuffer.size() > 1024) { qCWarning(dcDoorBird) << "Buffer size > 1KB and still no meaningful data. Discarding buffer..."; - m_readBuffers.clear(); + m_readBuffer.clear(); } // Assuming we don't have enough data yet... return; } QByteArray contentType = QByteArrayLiteral("Content-Type: text/plain"); - int contentTypeIndex = m_readBuffers.indexOf(contentType); + int contentTypeIndex = m_readBuffer.indexOf(contentType); if (contentTypeIndex == -1) { - qCWarning(dcDoorBird) << "Cannot find Content-Type in buffer:" << m_readBuffers; - if (m_readBuffers.size() > startIndex + 50) { + qCWarning(dcDoorBird) << "Cannot find Content-Type in buffer:" << m_readBuffer; + if (m_readBuffer.size() > startIndex + 50) { qCWarning(dcDoorBird) << boundary << "found but unexpected data follows. Skipping this element..."; - m_readBuffers.remove(0, startIndex + boundary.length()); + m_readBuffer.remove(0, startIndex + boundary.length()); continue; } // Assuming we don't have enough data yet... @@ -333,15 +362,15 @@ void Doorbird::connectToEventMonitor() } // At this point we have the boundary and Content-Type. Remove all of that and take the entire string to either end or next boundary - m_readBuffers.remove(0, contentTypeIndex + contentType.length()); - int nextStartIndex = m_readBuffers.indexOf(boundary); + m_readBuffer.remove(0, contentTypeIndex + contentType.length()); + int nextStartIndex = m_readBuffer.indexOf(boundary); QByteArray data; if (nextStartIndex == -1) { - data = m_readBuffers; - m_readBuffers.clear(); + data = m_readBuffer; + m_readBuffer.clear(); } else { - data = m_readBuffers.left(nextStartIndex); - m_readBuffers.remove(0, nextStartIndex); + data = m_readBuffer.left(nextStartIndex); + m_readBuffer.remove(0, nextStartIndex); } QString message = data.trimmed(); @@ -353,23 +382,27 @@ void Doorbird::connectToEventMonitor() if (parts.first() == "doorbell") { if (parts.at(1) == "H") { qCDebug(dcDoorBird) << "Doorbell ringing!"; - //emitEvent(Event(doorBirdTriggeredEventTypeId, device->id())); + emit eventReveiced(EventType::Doorbell, true); + } else { + emit eventReveiced(EventType::Doorbell, false); } } else if (parts.first() == "motionsensor") { if (parts.at(1) == "H") { qCDebug(dcDoorBird) << "Motion sensor detected a person"; - //emitEvent(Event(doorBirdMotionDetectedEventTypeId, device->id())); + emit eventReveiced(EventType::Motion, true); + } else { + emit eventReveiced(EventType::Motion, false); } } else { qCWarning(dcDoorBird) << "Unhandled DoorBird data:" << message; - }*/ + } } }); connect(reply, &QNetworkReply::finished, this, [this, reply]() { reply->deleteLater(); - //device->setStateValue(doorBirdConnectedStateTypeId, false); + emit deviceConnected(false); qCDebug(dcDoorBird) << "Monitor request finished:" << reply->error(); QTimer::singleShot(2000, this, [this] { @@ -378,3 +411,40 @@ void Doorbird::connectToEventMonitor() }); } +void Doorbird::onUdpBroadcast(const QByteArray &data) +{ + Q_UNUSED(data); + //TODO decryption +} + + +/*NotifyBroadcastCiphertext decryptBroadcastNotification(const NotifyBroadcast* notification, const + StretchedPassword* password) { + NotifyBroadcastCiphertext decrypted = {{0},{0},0}; + if(crypto_aead_chacha20poly1305_decrypt((unsigned char*)&decrypted, NULL, NULL, notification->ciphertext, + sizeof(notification->ciphertext), NULL, 0, notification->nonce, password->key)!=0){ + LOGGING("crypto_aead_chacha20poly1305_decrypt() failed"); + } + return decrypted; +} + +unsigned char* stretchPasswordArgon(const char *password, unsigned char *salt, unsigned* oplimit, unsigned* memlimit) { + if (sodium_is_zero(salt, CRYPTO_SALT_BYTES) && random_bytes(salt, CRYPTO_SALT_BYTES)) { + return NULL; + } + unsigned char* key = malloc(CRYPTO_ARGON_OUT_SIZE); + if (!*oplimit) { + *oplimit = crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE; + } + if (!*memlimit) { + *memlimit = crypto_pwhash_MEMLIMIT_MIN; + } + if (crypto_pwhash(key, CRYPTO_ARGON_OUT_SIZE, password, str_len(password), salt, *oplimit, *memlimit, crypto_pwhash_ALG_ARGON2I13)) { + LOGGING("Argon2 Failed"); + *oplimit = 0; + *memlimit = 0; + CLEAN(key); + return NULL; + } + return key; +}*/ diff --git a/doorbird/doorbird.h b/doorbird/doorbird.h index 69e05d0b..1f376345 100644 --- a/doorbird/doorbird.h +++ b/doorbird/doorbird.h @@ -1,4 +1,4 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2019 Bernhard Trinnes * * Copyright (C) 2019 Michael Zanetti * @@ -33,6 +33,24 @@ class Doorbird : public QObject public: explicit Doorbird(const QHostAddress &address, const QString &username, const QString &password, QObject *parent = nullptr); + enum EventType { + Doorbell, + Motion, + Input, + Rfid + }; + enum FavoriteType { + Http, + Sip + }; + + struct FavoriteObject { + FavoriteType type; + QString title; + QUrl value; + int id; + }; + QUuid getSession(); QUuid openDoor(int value); QUuid lightOn(); @@ -45,11 +63,11 @@ public: QUuid infoRequest(); QUuid listFavorites(); - QUuid addFavorite(); + QUuid addFavorite(FavoriteType type, const QString &name, const QUrl &url, int id); QUuid deleteFavorite(); QUuid listSchedules(); - QUuid daddScheduleEntry(); + QUuid addScheduleEntry(EventType event, int favoriteNumber, bool enabled); QUuid deleteScheduleEntry(); QUuid restart(); @@ -57,7 +75,7 @@ public: void connectToEventMonitor(); private: QNetworkAccessManager *m_networkAccessManager; - QList m_readBuffers; + QByteArray m_readBuffer; QHostAddress m_address; QList m_networkRequests; @@ -68,9 +86,14 @@ private: QByteArray sessionId; signals: + void deviceConnected(bool status); void requestSent(QUuid requestId, bool success); + void eventReveiced(EventType eventType, bool status); + void favoritesReceived(QList favourites); + public slots: + void onUdpBroadcast(const QByteArray &data); }; #endif // DOORBIRD_H diff --git a/doorbird/qrcodereader.cpp b/doorbird/qrcodereader.cpp index 658a2496..e16fa363 100644 --- a/doorbird/qrcodereader.cpp +++ b/doorbird/qrcodereader.cpp @@ -17,7 +17,7 @@ * along with this program. If not, see . * * * ****************************************************************************/ - +/* #include "qrcodereader.h" #include @@ -87,7 +87,7 @@ void QRCodeReader::grab(QImage image) connect(reader, SIGNAL(resultReady(QString, QString, QImage)), this, SLOT(handleResults(QString, QString, QImage))); m_readerThread.start(); - QMetaObject::invokeMethod(reader, "doWork", Q_ARG(QImage, img), Q_ARG(bool, false)); + //QMetaObject::invokeMethod(reader, "doWork", Q_ARG(QImage, img), Q_ARG(bool, false)); } void QRCodeReader::processImage(const QUrl &url) @@ -187,3 +187,4 @@ void Reader::doWork(const QImage &image, bool invert) emit finished(); } +*/ diff --git a/doorbird/qrcodereader.h b/doorbird/qrcodereader.h index f0c22b05..7b2edd15 100644 --- a/doorbird/qrcodereader.h +++ b/doorbird/qrcodereader.h @@ -17,7 +17,7 @@ * along with this program. If not, see . * * * ****************************************************************************/ - +/* #ifndef QRCODEREADER_H #define QRCODEREADER_H @@ -36,7 +36,6 @@ class QRCodeReader : public QObject Q_PROPERTY(QString imageSource READ imageSource NOTIFY validChanged) Q_PROPERTY(QRect scanRect READ scanRect WRITE setScanRect NOTIFY scanRectChanged) Q_PROPERTY(bool scanning READ scanning NOTIFY scanningChanged) - Q_PROPERTY(HistoryModel* history READ history CONSTANT) public: explicit QRCodeReader(QObject *parent = nullptr); @@ -86,3 +85,4 @@ signals: }; #endif // QRCODEREADER_H +*/