diff --git a/OmobiDisplayApp/OmobiDisplayApp.pro b/OmobiDisplayApp/OmobiDisplayApp.pro index 696c527..0ec8ca4 100644 --- a/OmobiDisplayApp/OmobiDisplayApp.pro +++ b/OmobiDisplayApp/OmobiDisplayApp.pro @@ -1,4 +1,4 @@ -QT += quick bluetooth +QT += quick bluetooth quickcontrols2 CONFIG += c++11 TARGET = OmobiDisplayApp @@ -20,7 +20,11 @@ HEADERS += \ RESOURCES += \ ressources/qml/qml.qrc \ - ressources/shared/shared.qrc + ressources/shared/shared.qrc \ + ressources/translations/translations.qrc + +TRANSLATIONS += \ + ressources/translations/de.ts # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = diff --git a/OmobiDisplayApp/QBluetoothLeUart b/OmobiDisplayApp/QBluetoothLeUart index 76e4575..534277a 160000 --- a/OmobiDisplayApp/QBluetoothLeUart +++ b/OmobiDisplayApp/QBluetoothLeUart @@ -1 +1 @@ -Subproject commit 76e457593e889885fd410fdbcdd659706a1eceb8 +Subproject commit 534277a19867f2e41a2699fc863e1cae48dee741 diff --git a/OmobiDisplayApp/main.cpp b/OmobiDisplayApp/main.cpp index 4d73779..79e3c05 100644 --- a/OmobiDisplayApp/main.cpp +++ b/OmobiDisplayApp/main.cpp @@ -1,7 +1,8 @@ #include #include #include -#include +#include +#include #include "omobidisplaybackend.h" #include "omobidisplaytextmodel.h" @@ -12,9 +13,14 @@ int main(int argc, char *argv[]) QGuiApplication app(argc, argv); + QTranslator translator; + translator.load(":/" + QLocale::system().name() + ".qm"); + translator.load(":/de.qm"); + app.installTranslator(&translator); + qmlRegisterType("de.itsblue.omobidisplayapp", 1, 0, "OmobiDisplayBackend"); qmlRegisterUncreatableType("de.itsblue.omobidisplayapp", 1, 0, "OmobiDisplayTextModel", "OmobiDisplayTextModel cannot be created"); - QBluetoothLeUart::init(); + QBluetoothLeUartClient::init(); QQuickStyle::setStyle("Material"); diff --git a/OmobiDisplayApp/omobidisplaybackend.cpp b/OmobiDisplayApp/omobidisplaybackend.cpp index ff3cc48..393dc51 100644 --- a/OmobiDisplayApp/omobidisplaybackend.cpp +++ b/OmobiDisplayApp/omobidisplaybackend.cpp @@ -2,8 +2,8 @@ OmobiDisplayBackend::OmobiDisplayBackend(QObject *parent) : QObject(parent) { - this->ble = new QBluetoothLeUart(); - this->ble->setUUIDs("92fecb20-1406-426a-afa5-cd5c1f306462", "92fecb21-1406-426a-afa5-cd5c1f306462", "92fecb22-1406-426a-afa5-cd5c1f306462"); + this->bleClient = new QBluetoothLeUartClient(); + this->bleClient->setUUIDs("92fecb20-1406-426a-afa5-cd5c1f306462", "92fecb21-1406-426a-afa5-cd5c1f306462", "92fecb22-1406-426a-afa5-cd5c1f306462"); this->displayTextModel = new OmobiDisplayTextModel(this); this->textSetsBuffer.clear(); this->displayBrightness = -1; @@ -14,72 +14,74 @@ OmobiDisplayBackend::OmobiDisplayBackend(QObject *parent) : QObject(parent) this->keepAliveTimer->setSingleShot(false); connect(this->keepAliveTimer, &QTimer::timeout, this, &OmobiDisplayBackend::sendBluetoothKeepAlive); - connect(this->ble, &QBluetoothLeUart::stateChanged, this, &OmobiDisplayBackend::handleBluetoothStateChange); - connect(this->ble, &QBluetoothLeUart::foundNewDevice, this, &OmobiDisplayBackend::handleFoundNewDevice); - connect(this->ble, &QBluetoothLeUart::dataReceived, this, &OmobiDisplayBackend::handleBluetoothDataReceived); - connect(this->ble, &QBluetoothLeUart::connectedToDevice, this, &OmobiDisplayBackend::handleBluetoothDeviceConected); + connect(this->bleClient, &QBluetoothLeUartClient::stateChanged, this, &OmobiDisplayBackend::handleBluetoothStateChange); + connect(this->bleClient, &QBluetoothLeUartClient::foundNewDevice, this, &OmobiDisplayBackend::handleFoundNewDevice); + connect(this->bleClient, &QBluetoothLeUartClient::dataReceived, this, &OmobiDisplayBackend::handleBluetoothDataReceived); + connect(this->bleClient, &QBluetoothLeUartClient::connectedToDevice, this, &OmobiDisplayBackend::handleBluetoothDeviceConected); connect(this->displayTextModel, &OmobiDisplayTextModel::dataChanged, this, &OmobiDisplayBackend::handleDisplayTextModelDataChanged); connect(this->displayTextModel, &OmobiDisplayTextModel::rowsInserted, this, &OmobiDisplayBackend::handleDisplayTextModelRowsInserted); connect(this->displayTextModel, &OmobiDisplayTextModel::rowsRemoved, this, &OmobiDisplayBackend::handleDisplayTextModelRowsRemoved); this->setState(Idle); - this->ble->startScanningForDevices(); - - qDebug() << QCryptographicHash::hash("HalloTest", QCryptographicHash::Sha256).toHex(); - // dd86fcfda3a20cbb8fbb3026a84550e0d70c2c79e7e8e36d6ffa04b9eef0401f - // dd86fcfda3a20cbb8fbb3026a84550e0d70c2c79e7e8e36d6ffa04b9eef0401f + this->bleClient->startScanningForDevices(); } void OmobiDisplayBackend::startScanning() { - this->ble->startScanningForDevices(); + this->bleClient->startScanningForDevices(); } -void OmobiDisplayBackend::handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state){ +void OmobiDisplayBackend::authenticate(QString code) { + // tell display to send over existing model data + this->setState(Authenticating); + QString combinedCode = this->bleClient->getCurrentDevice()->getAddress().toUpper() + code; + QString secret = QCryptographicHash::hash(combinedCode.toUtf8(), QCryptographicHash::Sha256).toHex(); + + this->sendBluetoothCommand(AuthorizeSessionCommand, QVariantMap{{"secret", secret}}); +} + +void OmobiDisplayBackend::handleBluetoothStateChange(QBluetoothLeUartClient::BluetoothLeUartClientState state){ switch(state){ - case QBluetoothLeUart::Idle: { + case QBluetoothLeUartClient::Idle: { this->setState(Idle); break; } - case QBluetoothLeUart::Scanning: { + case QBluetoothLeUartClient::Scanning: { this->setState(Scanning); break; } - case QBluetoothLeUart::ScanFinished: { + case QBluetoothLeUartClient::ScanFinished: { this->setState(ReadyToConnect); break; } - case QBluetoothLeUart::Connecting: { + case QBluetoothLeUartClient::Connecting: { this->setState(Connecting); break; } - case QBluetoothLeUart::ScanningForService: { + case QBluetoothLeUartClient::ScanningForService: { this->setState(Connecting); break; } - case QBluetoothLeUart::ServiceFound: { + case QBluetoothLeUartClient::ServiceFound: { this->setState(Connecting); break; } - case QBluetoothLeUart::Connected: + case QBluetoothLeUartClient::Connected: { break; } } - if(state == QBluetoothLeUart::Connected) + if(state == QBluetoothLeUartClient::Connected) this->keepAliveTimer->start(); else if(this->keepAliveTimer->isActive()) this->keepAliveTimer->stop(); } void OmobiDisplayBackend::handleBluetoothDeviceConected() { - this->setState(Initing); - - // tell display to send over existing model data - this->sendBluetoothCommand(AuthorizeSessionCommand, QVariantMap{{"secret", QCryptographicHash::hash("1234", QCryptographicHash::Sha256).toHex()}}); - this->sendBluetoothCommand(GetAllTextSetsCommand); - this->sendBluetoothCommand(GetDisplayBrightnessCommand); + this->setState(AuthenticationRequired); + this->authenticate("1234"); + // TODO: stuff } void OmobiDisplayBackend::handleFoundNewDevice(QBluetoothLeUartDevice* device) { @@ -123,7 +125,7 @@ void OmobiDisplayBackend::sendBluetoothCommand(OmobiDisplayCommand command, QVar if(this->state == Connected) this->setState(Loading); - this->ble->sendData(doc.toJson(QJsonDocument::Compact)); + this->bleClient->sendData(doc.toJson(QJsonDocument::Compact)); } void OmobiDisplayBackend::sendBluetoothKeepAlive() { @@ -131,7 +133,7 @@ void OmobiDisplayBackend::sendBluetoothKeepAlive() { qDebug() << "Sending keep alive: \n" << qPrintable(doc.toJson(QJsonDocument::Indented)); - this->ble->sendData(doc.toJson(QJsonDocument::Compact)); + this->bleClient->sendData(doc.toJson(QJsonDocument::Compact)); } void OmobiDisplayBackend::handleBluetoothDataReceived(QString s){ @@ -149,8 +151,16 @@ void OmobiDisplayBackend::handleBluetoothDataReceived(QString s){ switch (header) { case AuthorizeSessionCommand: { - // TODO: handle error - this->refreshLoadingState(); + if(status != Success) { + this->setState(AuthenticationRequired); + return; + } + + this->waitingCommands = 0; + this->setState(Initing); + this->sendBluetoothCommand(GetAllTextSetsCommand); + this->sendBluetoothCommand(GetDisplayBrightnessCommand); + break; } case KeepAliveCommand: { @@ -200,16 +210,14 @@ void OmobiDisplayBackend::handleBluetoothDataReceived(QString s){ this->refreshLoadingState(); break; } - case SetTextSetParameterCommand: { + case SetTextSetParameterCommand: + case SetDisplayBrightnessCommand: + case SetDisplayCodeCommand: + case SetDisplayNameCommand: // TODO: Error handling this->refreshLoadingState(); break; - } - case SetDisplayBrightnessCommand: { - // TODO: Error handling - this->refreshLoadingState(); - break; - } + } } @@ -233,8 +241,8 @@ void OmobiDisplayBackend::updateDisplayTextSetParameter(int index, int parameter this->sendBluetoothCommand(SetTextSetParameterCommand, dataMap); } -QBluetoothLeUart* OmobiDisplayBackend::getBleController() { - return this->ble; +QBluetoothLeUartClient* OmobiDisplayBackend::getBleClient() { + return this->bleClient; } @@ -270,7 +278,7 @@ void OmobiDisplayBackend::setState(OmobiDisplayAppState state) { qDebug() << "Now in " << state << " state"; if(this->state == Idle) - this->ble->startScanningForDevices(); + this->bleClient->startScanningForDevices(); } int OmobiDisplayBackend::getDisplayBrightness() { @@ -287,3 +295,13 @@ void OmobiDisplayBackend::setDisplayBrightness(int brightness) { emit this->displayBrightnessChanged(); } + + +void OmobiDisplayBackend::setDisplayCode(QString code) { + this->sendBluetoothCommand(SetDisplayCodeCommand, QVariantMap{{"displayCode",code}}); +} + +void OmobiDisplayBackend::setDisplayName(QString name) { + // This will restart the display!! + this->sendBluetoothCommand(SetDisplayNameCommand, QVariantMap{{"displayName", name}}); +} diff --git a/OmobiDisplayApp/omobidisplaybackend.h b/OmobiDisplayApp/omobidisplaybackend.h index f0bdfdb..8da8338 100644 --- a/OmobiDisplayApp/omobidisplaybackend.h +++ b/OmobiDisplayApp/omobidisplaybackend.h @@ -6,13 +6,13 @@ #include #include -#include +#include #include class OmobiDisplayBackend : public QObject { Q_OBJECT - Q_PROPERTY(QBluetoothLeUart* bleController READ getBleController NOTIFY bleControllerChanged) + Q_PROPERTY(QBluetoothLeUartClient* bleClient READ getBleClient NOTIFY bleClientChanged) Q_PROPERTY(OmobiDisplayAppState state READ getState WRITE setState NOTIFY stateChanged) Q_PROPERTY(OmobiDisplayTextModel* displayTextModel READ getDisplayTextModel NOTIFY displayTextModelChanged) Q_PROPERTY(int displayBrightness READ getDisplayBrightness WRITE setDisplayBrightness NOTIFY displayBrightnessChanged) @@ -25,6 +25,8 @@ public: Scanning, ReadyToConnect, Connecting, + AuthenticationRequired, + Authenticating, Initing, Connected, Loading @@ -39,7 +41,9 @@ private: GetTextSetParameterCommand = 11, GetDisplayBrightnessCommand = 12, SetTextSetParameterCommand = 20, - SetDisplayBrightnessCommand = 21 + SetDisplayBrightnessCommand = 21, + SetDisplayCodeCommand = 22, + SetDisplayNameCommand = 23 }; enum OmobiDisplayStatusCode { @@ -48,7 +52,7 @@ private: }; OmobiDisplayAppState state; - QBluetoothLeUart *ble; + QBluetoothLeUartClient *bleClient; QTimer *keepAliveTimer; OmobiDisplayTextModel* displayTextModel; int waitingCommands; @@ -57,14 +61,17 @@ private: public slots: Q_INVOKABLE void startScanning(); - Q_INVOKABLE QBluetoothLeUart* getBleController(); + Q_INVOKABLE void authenticate(QString secret); + Q_INVOKABLE QBluetoothLeUartClient* getBleClient(); Q_INVOKABLE OmobiDisplayAppState getState(); Q_INVOKABLE OmobiDisplayTextModel* getDisplayTextModel(); Q_INVOKABLE int getDisplayBrightness(); Q_INVOKABLE void setDisplayBrightness(int brightness); + Q_INVOKABLE void setDisplayCode(QString code); + Q_INVOKABLE void setDisplayName(QString name); private slots: - void handleBluetoothStateChange(QBluetoothLeUart::BluetoothLeUartState state); + void handleBluetoothStateChange(QBluetoothLeUartClient::BluetoothLeUartClientState state); void handleFoundNewDevice(QBluetoothLeUartDevice* device); void handleBluetoothDeviceConected(); @@ -83,7 +90,7 @@ private slots: signals: void stateChanged(); - void bleControllerChanged(); + void bleClientChanged(); void displayTextModelChanged(); void displayBrightnessChanged(); diff --git a/OmobiDisplayApp/ressources/qml/Chip.qml b/OmobiDisplayApp/ressources/qml/Chip.qml index 32ce03b..351bc8a 100644 --- a/OmobiDisplayApp/ressources/qml/Chip.qml +++ b/OmobiDisplayApp/ressources/qml/Chip.qml @@ -1,6 +1,10 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 import QtGraphicalEffects 1.12 +import QtQuick.Templates 2.12 as T +import QtQuick.Controls.impl 2.12 +import QtQuick.Controls.Material 2.12 +import QtQuick.Controls.Material.impl 2.12 Item { id: control @@ -10,11 +14,12 @@ Item { property string text: "" property string color: "" property bool isDarkColor: control.checkIsDarkColor(color) - property double glowRadius: 0.001 - property double glowSpread: 0.2 + property double glowRadius: 0.01 + property double glowSpread: 0.01 property bool glowVisible: true - property double glowScale: 0.9 - property double glowOpacity: Math.pow( control.opacity, 100 ) + property double glowScale: 1 + property double glowOpacity: Math.pow( control.opacity, 100 ) * 0.5 + property bool interactive: true signal clicked @@ -49,10 +54,42 @@ Item { anchors.fill: parent color: control.color radius: height * 0.5 + clip: true Behavior on color { ColorAnimation {} } + + + Ripple { + id: ripple + clipRadius: height + clip: true + width: parent.width + height: parent.height + pressed: mouseArea.pressed + anchor: background + active: mouseArea.pressed || mouseArea.visualFocus || mouseArea.containsMouse + color: control.Material.rippleColor + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Item { + width: ripple.width + height: ripple.height + Rectangle { + anchors.fill: parent + radius: Math.min(width, height) * 0.5 + } + } + } + } + } + + + ColorOverlay { + source: ripple + color: "red" } Text { @@ -75,7 +112,7 @@ Item { MouseArea { id: mouseArea anchors.fill: parent - enabled: control.enabled + enabled: control.enabled && control.interactive onClicked: control.clicked() } } diff --git a/OmobiDisplayApp/ressources/qml/ColorPickerDelegate.qml b/OmobiDisplayApp/ressources/qml/ColorPickerDelegate.qml index a5f799e..848075e 100644 --- a/OmobiDisplayApp/ressources/qml/ColorPickerDelegate.qml +++ b/OmobiDisplayApp/ressources/qml/ColorPickerDelegate.qml @@ -44,10 +44,11 @@ ItemDelegate { } font.pixelSize: parent.height * 0.5 + font.styleName: fontAwesome.name verticalAlignment: Text.AlignVCenter - text: ">" + text: "\uf105" } Dialog { diff --git a/OmobiDisplayApp/ressources/qml/ComboBoxDelegate.qml b/OmobiDisplayApp/ressources/qml/ComboBoxDelegate.qml index 9ad453f..8b82948 100644 --- a/OmobiDisplayApp/ressources/qml/ComboBoxDelegate.qml +++ b/OmobiDisplayApp/ressources/qml/ComboBoxDelegate.qml @@ -42,12 +42,13 @@ ItemDelegate { } font.pixelSize: parent.height * 0.5 + font.styleName: fontAwesome.name verticalAlignment: Text.AlignVCenter color: control.Material.foreground - text: ">" + text: "\uf105" } Dialog { diff --git a/OmobiDisplayApp/ressources/qml/ConnectPage.qml b/OmobiDisplayApp/ressources/qml/ConnectPage.qml index b765333..a8d229c 100644 --- a/OmobiDisplayApp/ressources/qml/ConnectPage.qml +++ b/OmobiDisplayApp/ressources/qml/ConnectPage.qml @@ -4,38 +4,72 @@ import QtQuick.Layouts 1.0 import de.itsblue.omobidisplayapp 1.0 import de.itsblue.bluetoothleuart 1.0 import QtQuick.Controls.Material 2.0 +import QtGraphicalEffects 1.0 Page { id: root + property bool actionButtonVisible: false + property bool backButtonVisible: false property string statusText property bool working + title: qsTr("Available displays") + ColumnLayout { + id: mainLayout anchors { fill: parent - margins: parent.height * 0.01 - topMargin: 0 + margins: Math.min(parent.height, parent.width) * 0.05 } - Text { - Layout.preferredWidth: parent.width * 0.6 - Layout.preferredHeight: parent.height * 0.1 + Chip { + Layout.fillWidth: true + Layout.preferredHeight: mainLayout.height * 0.05 Layout.alignment: Layout.Center + color: "white" - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter + onClicked: { + backend.bleClient.startScanningForDevices() + } - fontSizeMode: Text.Fit - font.pixelSize: 500 - minimumPixelSize: 1 + RowLayout { + spacing: mainLayout.anchors.margins - text: qsTr("Available devices") + anchors.fill: parent + anchors.leftMargin: width * 0.05 + anchors.rightMargin: 0 + + Text { + Layout.fillHeight: true + Layout.fillWidth: true + verticalAlignment: Text.AlignVCenter + font.pixelSize: parent.height * 0.4 + text: root.statusText + } + + BusyIndicator { + Layout.fillHeight: true + Layout.preferredWidth: height + + id: busyIndicator + + scale: 0.8 + + opacity: root.working ? 1:0 + } + + } + } + + Item { + Layout.fillWidth: true + Layout.preferredHeight: mainLayout.height * 0.025 } ListView { - id: availableDevicesListView + id: availableDisplaysListView Layout.preferredWidth: parent.width Layout.fillHeight: true @@ -44,7 +78,7 @@ Page { clip: true boundsBehavior: Flickable.OvershootBounds - model: backend.bleController.availableDevicesModel + model: backend.bleClient.availableDevicesModel add: Transition { NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200 } @@ -58,64 +92,19 @@ Page { spacing: 5 - header: ItemDelegate { - id: headerDelegate - - width: parent.width - height: implicitHeight * 0.8 - - topInset: 10 - bottomInset: 10 - - text: root.statusText - - onClicked: backend.bleController.startScanningForDevices() - - Rectangle { - anchors.fill: parent - anchors.topMargin: 10 - anchors.bottomMargin: 10 - color: "transparent" - border.color: "lightgrey" - border.width: 3 - } - - Item { - anchors { - right: parent.right - rightMargin: parent.height * 0.15 - verticalCenter: parent.verticalCenter - } - - height: (parent.height - 20) * 0.7 - width: height - - BusyIndicator { - id: busyIndicator - - anchors.centerIn: parent - - width: parent.width - height: parent.height - - opacity: root.working ? 1:0 - } - } - } - delegate: ItemDelegate { width: parent.width text: name - onClicked: backend.bleController.connectToDevice(device) + onClicked: backend.bleClient.connectToDevice(device) Rectangle { anchors { top: parent.top left: parent.left right: parent.right - topMargin: - availableDevicesListView.spacing * 0.5 + topMargin: - availableDisplaysListView.spacing * 0.5 } color: "lightgrey" @@ -123,6 +112,100 @@ Page { visible: index !== 0 } } + + Item { + anchors.centerIn: parent + + width: Math.min(parent.height, parent.width) + height: Math.min(parent.height, parent.width) + + opacity: availableDisplaysListView.model.rowCount === 0 ? 1:0 + + Behavior on opacity { + NumberAnimation {} + } + + Rectangle { + id: noDisplaysRect + + anchors { + top: parent.top + topMargin: parent.height * 0.2 + horizontalCenter: parent.horizontalCenter + } + + width: parent.width * 0.7 + height: width * 0.3 + + color: "transparent" + + border.width: height * 0.15 + border.color: "lightgrey" + + Text { + anchors.centerIn: parent + anchors.verticalCenterOffset: text === "..." ? -height * 0.25:0 + color: "lightgrey" + font.pixelSize: parent.height * 0.6 + font.bold: true + text: parseInt(root.state) === OmobiDisplayBackend.Scanning ? "...":"?" + } + } + + Text { + id: noDisplaysText + anchors { + top: noDisplaysRect.bottom + topMargin: noDisplaysRect.height * 0.15 + horizontalCenter: parent.horizontalCenter + } + + font.bold: true + font.pixelSize: noDisplaysRect.height * 0.3 + + color: Qt.darker("lightgrey", 1.1) + text: parseInt(root.state) === OmobiDisplayBackend.Scanning ? qsTr("Still scanning"):qsTr("No displays found") + } + } + } + } + + Dialog { + id: authenticationDialog + + property bool shouldBeOpened: false + + parent: Overlay.overlay + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + width: parent.width * 0.9 + + modal: true + closePolicy: Popup.NoAutoClose + standardButtons: Dialog.Ok | Dialog.Cancel + + title: qsTr("Input code") + + onShouldBeOpenedChanged: { + if(shouldBeOpened) + open() + else + close() + } + + onAccepted: { + backend.authenticate(secretTextInput.text) + } + + onRejected: { + backend.bleClient.disconnectFromDevice() + } + + contentItem: TextField { + id: secretTextInput + placeholderText: qsTr("code") + Keys.onReturnPressed: authenticationDialog.accept() } } @@ -132,7 +215,7 @@ Page { PropertyChanges { target: root - statusText: "Tap here to scan" + statusText: qsTr("Tap here to scan") working: false } }, @@ -141,7 +224,7 @@ Page { PropertyChanges { target: root - statusText: "Scanning..." + statusText: qsTr("Scanning...") working: true } }, @@ -150,21 +233,56 @@ Page { PropertyChanges { target: root - statusText: availableDevicesListView.model.rowCount() > 0 ? "Please select a device or tap to scan again":"No devices found. Tap to scan again" + statusText: availableDisplaysListView.model.rowCount > 0 ? qsTr("Please select a device or tap to scan again"):qsTr("No displays found. Tap to scan again") working: false } }, + State { - name: OmobiDisplayBackend.Connecting + name: OmobiDisplayBackend.AuthenticationRequired PropertyChanges { - target: availableDevicesListView + target: authenticationDialog + shouldBeOpened: true + } + + PropertyChanges { + target: availableDisplaysListView enabled: false } PropertyChanges { target: root - statusText: "trying to connect..." + statusText: qsTr("trying to authenticate...") + working: true + } + }, + State { + name: OmobiDisplayBackend.Authenticating + + PropertyChanges { + target: availableDisplaysListView + enabled: false + } + + PropertyChanges { + target: root + statusText: qsTr("trying to authenticate...") + working: true + } + }, + + State { + name: OmobiDisplayBackend.Connecting + + PropertyChanges { + target: availableDisplaysListView + enabled: false + } + + PropertyChanges { + target: root + statusText: qsTr("trying to connect...") working: true } }, @@ -172,13 +290,13 @@ Page { name: OmobiDisplayBackend.Initing PropertyChanges { - target: availableDevicesListView + target: availableDisplaysListView enabled: false } PropertyChanges { target: root - statusText: "loading data..." + statusText: qsTr("loading data...") working: true } } diff --git a/OmobiDisplayApp/ressources/qml/ConnectedPage.qml b/OmobiDisplayApp/ressources/qml/ConnectedPage.qml index 4a98d13..9788b0b 100644 --- a/OmobiDisplayApp/ressources/qml/ConnectedPage.qml +++ b/OmobiDisplayApp/ressources/qml/ConnectedPage.qml @@ -2,6 +2,7 @@ import QtQuick 2.0 import QtQuick.Controls 2.9 import QtQuick.Layouts 1.0 import QtQuick.Controls.Material 2.0 +import QtGraphicalEffects 1.0 import de.itsblue.omobidisplayapp 1.0 import de.itsblue.bluetoothleuart 1.0 @@ -9,53 +10,79 @@ import de.itsblue.bluetoothleuart 1.0 Page { id: root + property bool actionButtonVisible: true + property bool backButtonVisible: true + + title: backend.bleClient.currentDevice === null ? "":backend.bleClient.currentDevice.name + + function backButtonClicked() { + backend.bleClient.disconnectFromDevice() + } + + function actionButtonClicked() { + displayEditDialog.edit() + } + ColumnLayout { + id: mainLayout anchors { fill: parent - margins: parent.height * 0.01 - topMargin: 0 + margins: Math.min(parent.height, parent.width) * 0.05 } - Text { - Layout.preferredWidth: parent.width * 0.6 - Layout.preferredHeight: parent.height * 0.1 - Layout.alignment: Layout.Center - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - - fontSizeMode: Text.Fit - font.pixelSize: 500 - minimumPixelSize: 1 - - color: root.Material.foreground - - text: "Omobi Display 1" //backend.bleController.currentDevice.name - } - - Text { - Layout.alignment: Layout.Center - - color: root.Material.foreground - - text: qsTr("Brightness:") - } - - Slider { + Chip { Layout.fillWidth: true + Layout.preferredHeight: mainLayout.height * 0.05 + Layout.alignment: Layout.Center - from: 0 - to: 10 - stepSize: 1 + interactive: false - value: backend.displayBrightness + color: "white" - onPressedChanged: { - if(!pressed) - backend.displayBrightness = value + RowLayout { + spacing: mainLayout.anchors.margins + + anchors.fill: parent + anchors.leftMargin: width * 0.05 + anchors.rightMargin: anchors.leftMargin + + Text { + Layout.fillHeight: true + verticalAlignment: Text.AlignVCenter + font.pixelSize: parent.height * 0.5 + text: "\uf186" + } + + Slider { + Layout.fillWidth: true + Layout.fillHeight: true + + from: 0 + to: 10 + stepSize: 1 + + value: backend.displayBrightness + + onPressedChanged: { + if(!pressed) + backend.displayBrightness = value + } + } + + Text { + Layout.fillHeight: true + verticalAlignment: Text.AlignVCenter + font.pixelSize: parent.height * 0.5 + text: "\uf185" + } } } + Item { + Layout.fillWidth: true + Layout.preferredHeight: mainLayout.height * 0.025 + } + DisplayTextModelListView { Layout.preferredWidth: parent.width Layout.fillHeight: true @@ -65,6 +92,10 @@ Page { } } + DisplayEditDialog { + id: displayEditDialog + } + Dialog { id: loadingDialog diff --git a/OmobiDisplayApp/ressources/qml/DisplayEditDialog.qml b/OmobiDisplayApp/ressources/qml/DisplayEditDialog.qml new file mode 100644 index 0000000..1dd331b --- /dev/null +++ b/OmobiDisplayApp/ressources/qml/DisplayEditDialog.qml @@ -0,0 +1,91 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.9 +import QtQuick.Controls.Material 2.0 + +import de.itsblue.omobidisplayapp 1.0 + +Dialog { + id: control + + parent: Overlay.overlay + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + width: parent.width * 0.9 + + modal: true + + title: qsTr("Edit display settings") + + onAccepted: { + backend.setDisplayCode(codeTextField.value) + backend.setDisplayName(nameTextField.value) + } + + contentItem: ColumnLayout { + id: dataFieldsGridLayout + + width: control.width * 0.9 + + TextInputDelegate { + id: nameTextField + Layout.fillWidth: true + required: true + text: qsTr("Display name\n(needs restart)") + } + + PasswordInputDelegate { + id: codeTextField + Layout.fillWidth: true + required: true + text: qsTr("Display code (4 digits)") + placeholderText: qsTr("Enter new display code") + repeatPlaceholderText: qsTr("Enter new display code again") + } + } + + + footer: DialogButtonBox { + + // alignment: Qt.AlignHCenter + buttonLayout: DialogButtonBox.GnomeLayout + + Material.background: "transparent" + + Button { + flat: true + enabled: nameTextField.value !== "" + text: "save" + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + + Button { + flat: true + text: "cancel" + DialogButtonBox.buttonRole: DialogButtonBox.RejectRole + } + } + + function edit() { + + reset() + + nameTextField.value = backend.bleClient.currentDevice.name + + open() + } + + function add(model) { + editingModel = model + editing = false + reset() + open() + } + + function reset() { + nameTextField.value = "" + codeTextField.value = "" + } +} diff --git a/OmobiDisplayApp/ressources/qml/DisplayTextDelegate.qml b/OmobiDisplayApp/ressources/qml/DisplayTextDelegate.qml index 25df49e..1daff2c 100644 --- a/OmobiDisplayApp/ressources/qml/DisplayTextDelegate.qml +++ b/OmobiDisplayApp/ressources/qml/DisplayTextDelegate.qml @@ -56,7 +56,7 @@ ItemDelegate { ColorAnimation {} } - text: model.scroll ? qsTr("scrolling"):qsTr("false") + text: model.scroll ? qsTr("scrolling"):"" onClicked: { control.clicked() diff --git a/OmobiDisplayApp/ressources/qml/NextPageDelegate.qml b/OmobiDisplayApp/ressources/qml/NextPageDelegate.qml deleted file mode 100644 index b5b034a..0000000 --- a/OmobiDisplayApp/ressources/qml/NextPageDelegate.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 2.9 - -ItemDelegate { - -} diff --git a/OmobiDisplayApp/ressources/qml/PasswordInputDelegate.qml b/OmobiDisplayApp/ressources/qml/PasswordInputDelegate.qml new file mode 100644 index 0000000..707ca94 --- /dev/null +++ b/OmobiDisplayApp/ressources/qml/PasswordInputDelegate.qml @@ -0,0 +1,120 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.9 +import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.0 + +ItemDelegate { + id: control + + property string value: "" + property bool required: false + property color textColor: control.required && value === "" ? "red":control.Material.foreground + property string placeholderText: "" + property string repeatPlaceholderText: "" + property int minimumLength: 4 + property int maximumLength: 4 + + onClicked: { + textField.text = value + textEditDialog.open() + } + + Text { + anchors { + right: nextPageIconText.left + verticalCenter: parent.verticalCenter + rightMargin: control.padding + } + + width: parent.width * 0.6 + elide: Text.ElideRight + font.pixelSize: parent.font.pixelSize + + horizontalAlignment: Text.AlignRight + + text: "****" + } + + Text { + id: nextPageIconText + + anchors { + right: parent.right + verticalCenter: parent.verticalCenter + rightMargin: control.padding + } + + font.pixelSize: parent.height * 0.5 + font.styleName: fontAwesome.name + + verticalAlignment: Text.AlignVCenter + + text: "\uf105" + } + + Dialog { + id: textEditDialog + parent: Overlay.overlay + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + width: parent.width * 0.9 + + Material.theme: control.Material.theme + Material.accent: control.Material.accent + modal: true + + title: control.text + + contentItem: ColumnLayout { + TextField { + id: textField + + Layout.fillWidth: true + + placeholderText: control.placeholderText + text: control.value + + color: text.length < 4 || text.length > 4 ? "red":control.Material.foreground + } + + TextField { + id: repeatTextField + + Layout.fillWidth: true + + placeholderText: control.repeatPlaceholderText + text: control.value + + color: repeatTextField.text !== textField.text ? "red":control.Material.foreground + } + } + + + footer: DialogButtonBox { + + // alignment: Qt.AlignHCenter + buttonLayout: DialogButtonBox.GnomeLayout + + Material.background: "transparent" + + Button { + flat: true + enabled: !(textField.text.length < 4 || textField.text.length > 4) && textField.text === repeatTextField.text + text: "save" + DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole + } + + Button { + flat: true + text: "cancel" + DialogButtonBox.buttonRole: DialogButtonBox.RejectRole + } + } + + onAccepted: { + control.value = textField.text + } + } +} diff --git a/OmobiDisplayApp/ressources/qml/SpinBoxDelegate.qml b/OmobiDisplayApp/ressources/qml/SpinBoxDelegate.qml index 34c13d2..f8d8d98 100644 --- a/OmobiDisplayApp/ressources/qml/SpinBoxDelegate.qml +++ b/OmobiDisplayApp/ressources/qml/SpinBoxDelegate.qml @@ -38,12 +38,13 @@ ItemDelegate { } font.pixelSize: parent.height * 0.5 + font.styleName: fontAwesome.name verticalAlignment: Text.AlignVCenter color: control.Material.foreground - text: ">" + text: "\uf105" } Dialog { diff --git a/OmobiDisplayApp/ressources/qml/TextEditDialog.qml b/OmobiDisplayApp/ressources/qml/TextEditDialog.qml index 9c3359a..f248110 100644 --- a/OmobiDisplayApp/ressources/qml/TextEditDialog.qml +++ b/OmobiDisplayApp/ressources/qml/TextEditDialog.qml @@ -62,9 +62,6 @@ Dialog { ColumnLayout { id: dataFieldsGridLayout - property double fontSizeMultiplier: 0.14 - property double labelWidthMultiplier: 0.4 - width: control.width * 0.9 SwitchDelegate { @@ -119,7 +116,7 @@ Dialog { id: scrollCountSpinBox Layout.fillWidth: true from: 0 - text: qsTr("Scroll count:") + text: qsTr("Scroll count") } } } diff --git a/OmobiDisplayApp/ressources/qml/TextInputDelegate.qml b/OmobiDisplayApp/ressources/qml/TextInputDelegate.qml index e60d694..54d3618 100644 --- a/OmobiDisplayApp/ressources/qml/TextInputDelegate.qml +++ b/OmobiDisplayApp/ressources/qml/TextInputDelegate.qml @@ -22,7 +22,7 @@ ItemDelegate { rightMargin: control.padding } - width: parent.width * 0.6 + width: parent.width * 0.4 elide: Text.ElideRight font.pixelSize: parent.font.pixelSize @@ -43,12 +43,13 @@ ItemDelegate { } font.pixelSize: parent.height * 0.5 + font.styleName: fontAwesome.name verticalAlignment: Text.AlignVCenter color: control.textColor - text: ">" + text: "\uf105" } Dialog { @@ -73,6 +74,8 @@ ItemDelegate { placeholderText: control.placeholderText text: control.value + + Keys.onReturnPressed: textEditDialog.accept() } onAccepted: { diff --git a/OmobiDisplayApp/ressources/qml/main.qml b/OmobiDisplayApp/ressources/qml/main.qml index 8cb292e..31f4139 100644 --- a/OmobiDisplayApp/ressources/qml/main.qml +++ b/OmobiDisplayApp/ressources/qml/main.qml @@ -4,12 +4,13 @@ import QtQuick.Window 2.12 import de.itsblue.omobidisplayapp 1.0 import de.itsblue.bluetoothleuart 1.0 import QtQuick.Controls.Material 2.0 +import QtQuick.Layouts 1.0 ApplicationWindow { width: 540 height: 960 visible: true - title: qsTr("Hello World") + title: qsTr("Itsblue smart display") Page { id: app @@ -26,22 +27,84 @@ ApplicationWindow { Material.theme: Material.System header: ToolBar { + id: headerToolBar + + height: 50 + implicitWidth: parent.width + Material.background: "white" - Image { + RowLayout { anchors.fill: parent - anchors.margins: parent.height * 0.1 - fillMode: Image.PreserveAspectFit - source: "qrc:/omobi.png" + ToolButton { + id: backToolButton + + enabled: false + Layout.fillHeight: true + Layout.preferredWidth: height + + opacity: mainStack.currentItem.backButtonVisible ? 1:0 + + font.styleName: fontAwesome.name + font.pixelSize: height * 0.6 + Material.foreground: "black" + + text: "\uf104" + + contentItem: Item {} + + Text { + anchors.centerIn: parent + font.pixelSize: parent.font.pixelSize + text: parent.text + } + + onClicked: mainStack.currentItem.backButtonClicked() + } + + Text { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.alignment: Layout.Center + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + text: mainStack.currentItem.title + } + + ToolButton { + id: actionToolButton + + Layout.fillHeight: true + Layout.preferredWidth: height + + opacity: mainStack.currentItem.actionButtonVisible ? 1:0 + + font.styleName: fontAwesome.name + font.pixelSize: height * 0.4 + Material.foreground: "black" + + flat: true + + text: "\uf013" + + onClicked: mainStack.currentItem.actionButtonClicked() + + } } - } OmobiDisplayBackend { id: backend } + FontLoader { + id: fontAwesome + source: "qrc:/fa5regular.woff" + } + StackView { id: mainStack @@ -56,6 +119,22 @@ ApplicationWindow { initialItem: connectedPageComp + replaceEnter: Transition { + NumberAnimation { + properties: "opacity" + from: 0 + to: 1 + } + } + + replaceExit: Transition { + NumberAnimation { + properties: "opacity" + from: 1 + to: 0 + } + } + Component { id: connectPageComp ConnectPage { @@ -66,6 +145,7 @@ ApplicationWindow { Component { id: connectedPageComp ConnectedPage { + opacity: 0 state: app.state } } @@ -87,7 +167,7 @@ ApplicationWindow { currentComponent: connectPageComp } }, - + State { name: OmobiDisplayBackend.ReadyToConnect PropertyChanges { @@ -104,6 +184,22 @@ ApplicationWindow { } }, + State { + name: OmobiDisplayBackend.AuthenticationRequired + PropertyChanges { + target: mainStack + currentComponent: connectPageComp + } + }, + + State { + name: OmobiDisplayBackend.Authenticating + PropertyChanges { + target: mainStack + currentComponent: connectPageComp + } + }, + State { name: OmobiDisplayBackend.Initing PropertyChanges { @@ -118,6 +214,14 @@ ApplicationWindow { target: mainStack currentComponent: connectedPageComp } + PropertyChanges { + target: headerToolBar + state: "open" + } + PropertyChanges { + target: backToolButton + enabled: true + } }, State { @@ -126,6 +230,14 @@ ApplicationWindow { target: mainStack currentComponent: connectedPageComp } + PropertyChanges { + target: headerToolBar + state: "open" + } + PropertyChanges { + target: backToolButton + enabled: true + } } ] } diff --git a/OmobiDisplayApp/ressources/qml/qml.qrc b/OmobiDisplayApp/ressources/qml/qml.qrc index 0875c94..40ec2cd 100644 --- a/OmobiDisplayApp/ressources/qml/qml.qrc +++ b/OmobiDisplayApp/ressources/qml/qml.qrc @@ -7,11 +7,12 @@ DisplayTextModelListView.qml TextEditDialog.qml TextInputDelegate.qml - NextPageDelegate.qml SpinBoxDelegate.qml ComboBoxDelegate.qml ColorPickerDelegate.qml ColorPicker.qml Chip.qml + DisplayEditDialog.qml + PasswordInputDelegate.qml diff --git a/OmobiDisplayApp/ressources/shared/fa5regular.woff b/OmobiDisplayApp/ressources/shared/fa5regular.woff new file mode 100644 index 0000000..24de566 Binary files /dev/null and b/OmobiDisplayApp/ressources/shared/fa5regular.woff differ diff --git a/OmobiDisplayApp/ressources/shared/shared.qrc b/OmobiDisplayApp/ressources/shared/shared.qrc index 8be7d48..74f0f89 100644 --- a/OmobiDisplayApp/ressources/shared/shared.qrc +++ b/OmobiDisplayApp/ressources/shared/shared.qrc @@ -2,5 +2,6 @@ omobi.png itsblue.png + fa5regular.woff diff --git a/OmobiDisplayApp/ressources/translations/de.qm b/OmobiDisplayApp/ressources/translations/de.qm new file mode 100644 index 0000000..55c0917 Binary files /dev/null and b/OmobiDisplayApp/ressources/translations/de.qm differ diff --git a/OmobiDisplayApp/ressources/translations/de.ts b/OmobiDisplayApp/ressources/translations/de.ts new file mode 100644 index 0000000..8ffc4b5 --- /dev/null +++ b/OmobiDisplayApp/ressources/translations/de.ts @@ -0,0 +1,163 @@ + + + + + ConnectPage + + Available devices + Verfügbare Geräte + + + Input code + Geben sie den Code ein + + + code + Code + + + Tap here to scan + Tippe hier um zu suchen + + + Scanning... + Suchen... + + + Please select a device or tap to scan again + Wähle ein Display, oder tippe um erneut zu suchen + + + trying to authenticate... + Versuche anzumelden... + + + trying to connect... + Versuche zu verbinden... + + + loading data... + Lade Daten... + + + Available displays + Verfügbare Displays + + + Still scanning + Suche läuft + + + No displays found + Keine Displays gefunden + + + No displays found. Tap to scan again + Keine Displays gefunden. Tippe um erneut zu suchen + + + + ConnectedPage + + Brightness: + Helligkeit: + + + loading... + laden... + + + + DisplayEditDialog + + Edit display settings + Display Einstellungen bearbeiten + + + Display name +(needs restart) + Displayname\n(neutstart nötig) + + + Display code (4 digits) + Display Code (4 Zeichen) + + + Enter new display code + Geben sie den neuen Display Code ein + + + Enter new display code again + Geben sie den neuen Display Code erneut ein + + + + DisplayTextDelegate + + scrolling + scrollen + + + false + nein + + + active + aktiv + + + inactive + inaktiv + + + + TextEditDialog + + Active + Aktiv + + + Enter some text to be displayed + Geben sie den anzuzeigenden Text ein + + + Text + Text + + + Runtime (in s) + Laufzeit (in s) + + + Color + Farbe + + + Alignment + Ausrichtung + + + Scroll + Scrollen + + + Scroll speed + Scrollgeschwindigkeit + + + Scroll count: + Scrolldurchläufe + + + Scroll count + Scrolldurchläufe + + + + main + + Itsblue smart display + Itsblue smart display + + + diff --git a/OmobiDisplayApp/ressources/translations/translations.qrc b/OmobiDisplayApp/ressources/translations/translations.qrc new file mode 100644 index 0000000..4923ee3 --- /dev/null +++ b/OmobiDisplayApp/ressources/translations/translations.qrc @@ -0,0 +1,5 @@ + + + de.qm + + diff --git a/vscode/OmobiLEDdisplayBluetooth/include/BluetoothLeUartServer.h b/vscode/OmobiLEDdisplayBluetooth/include/BluetoothLeUartServer.h index 5421e4c..f957974 100644 --- a/vscode/OmobiLEDdisplayBluetooth/include/BluetoothLeUartServer.h +++ b/vscode/OmobiLEDdisplayBluetooth/include/BluetoothLeUartServer.h @@ -62,6 +62,8 @@ public: bool getDeviceConnected(); bool disconnectCurrentDevice(); + String getDeviceAddress(); + protected: // callbacks for BLEServer void onConnect(BLEServer *pServer, esp_ble_gatts_cb_param_t *param) override; diff --git a/vscode/OmobiLEDdisplayBluetooth/include/EepromManager.h b/vscode/OmobiLEDdisplayBluetooth/include/EepromManager.h index e38964e..ce1b5f5 100644 --- a/vscode/OmobiLEDdisplayBluetooth/include/EepromManager.h +++ b/vscode/OmobiLEDdisplayBluetooth/include/EepromManager.h @@ -27,25 +27,22 @@ private: template const T &writeToEeprom(int address, size_t size, const T &t) { - Serial.println("Writing at: " + String(address) + " size: " + String(sizeof(T))); if (sizeof(T) > size) { - Serial.println("Error writing: Size should be: " + String(size)); + Serial.println("[Error][EepromManager] writing: Size should be: " + String(size) + " but was: " + String(sizeof(T))); return t; } const T &res = EEPROM.put(address, t); - Serial.println("Eeprom commit returned: " + String(EEPROM.commit())); + EEPROM.commit(); return res; } template T &readFromEeprom(int address, size_t size, T &t) { - Serial.println("Reading at: " + String(address) + " size: " + String(sizeof(T))); - if (sizeof(T) > size) { - Serial.println("Error reading: Size should be: " + String(size)); + Serial.println("[Error][EepromManager] reading: Size should be: " + String(size) + " but was: " + String(sizeof(T))); return t; } diff --git a/vscode/OmobiLEDdisplayBluetooth/include/OmobiLedDisplay.h b/vscode/OmobiLEDdisplayBluetooth/include/OmobiLedDisplay.h index 2a0f09d..98c7f8a 100644 --- a/vscode/OmobiLEDdisplayBluetooth/include/OmobiLedDisplay.h +++ b/vscode/OmobiLEDdisplayBluetooth/include/OmobiLedDisplay.h @@ -54,12 +54,15 @@ private: GetTextSetParameterCommand = 11, GetDisplayBrightnessCommand = 12, SetTextSetParameterCommand = 20, - SetDisplayBrightnessCommand = 21 + SetDisplayBrightnessCommand = 21, + SetDisplayCodeCommand = 22, + SetDisplayNameCommand = 23 }; enum OmobiDisplayStatusCode { Success = 200, + BadRequestError = 400, Unauthorized = 401, InternalError = 500, DisplayControllerError = 501 diff --git a/vscode/OmobiLEDdisplayBluetooth/src/BluetoothLeUartServer.cpp b/vscode/OmobiLEDdisplayBluetooth/src/BluetoothLeUartServer.cpp index 6ed7215..f6ec47a 100644 --- a/vscode/OmobiLEDdisplayBluetooth/src/BluetoothLeUartServer.cpp +++ b/vscode/OmobiLEDdisplayBluetooth/src/BluetoothLeUartServer.cpp @@ -56,6 +56,27 @@ void BluetoothLeUartServer::sendData(String data) txCharacteristic->notify(); } +bool BluetoothLeUartServer::getDeviceConnected() +{ + return this->deviceConnected; +} + +bool BluetoothLeUartServer::disconnectCurrentDevice() { + if(!this->getDeviceConnected()) + return false; + + this->bleServer->disconnect(this->deviceConnectionId); + return true; +} + +String BluetoothLeUartServer::getDeviceAddress() { + + String address = BLEDevice::getAddress().toString().c_str(); + address.toUpperCase(); + + return address; +} + void BluetoothLeUartServer::onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param) { // only allow one device @@ -84,17 +105,4 @@ void BluetoothLeUartServer::onWrite(BLECharacteristic *rxCharacteristic) { if (this->callbacks != nullptr) this->callbacks->onDataReceived(rxCharacteristic->getValue().c_str()); -} - -bool BluetoothLeUartServer::getDeviceConnected() -{ - return this->deviceConnected; -} - -bool BluetoothLeUartServer::disconnectCurrentDevice() { - if(!this->getDeviceConnected()) - return false; - - this->bleServer->disconnect(this->deviceConnectionId); - return true; } \ No newline at end of file diff --git a/vscode/OmobiLEDdisplayBluetooth/src/EepromManager.cpp b/vscode/OmobiLEDdisplayBluetooth/src/EepromManager.cpp index 5deb52d..22c7370 100644 --- a/vscode/OmobiLEDdisplayBluetooth/src/EepromManager.cpp +++ b/vscode/OmobiLEDdisplayBluetooth/src/EepromManager.cpp @@ -8,7 +8,6 @@ EepromManager::EepromManager() EepromUnit *EepromManager::registerEempromUnit(size_t size) { - Serial.println("Registering new EepromUnit with size: " + String(size) + " at " + String(this->currentAddressEnding)); // create a new Unit at the current address ending EepromUnit *newUnit = new EepromUnit(this, this->currentAddressEnding, size); // move the new address ending diff --git a/vscode/OmobiLEDdisplayBluetooth/src/OmobiLedDisplay.cpp b/vscode/OmobiLEDdisplayBluetooth/src/OmobiLedDisplay.cpp index 968d955..57acb28 100644 --- a/vscode/OmobiLEDdisplayBluetooth/src/OmobiLedDisplay.cpp +++ b/vscode/OmobiLEDdisplayBluetooth/src/OmobiLedDisplay.cpp @@ -48,18 +48,21 @@ void OmobiLedDisplay::onDataReceived(String dataString) OmobiDisplayStatusCode replyStatus = InternalError; JsonObject replyData = replyDoc.createNestedObject("data"); - if (requestHeader != AuthorizeSessionCommand && !this->sessionAuthorized) + if (requestHeader > KeepAliveCommand && !this->sessionAuthorized) replyStatus = Unauthorized; else switch (requestHeader) { case AuthorizeSessionCommand: { + String combinedCode = this->bleServer->getDeviceAddress() + String(this->properties.deviceCode); + String secret = this->sha256(combinedCode); + if (this->sessionAuthorized) { replyStatus = Success; } - else if (requestData["secret"] == this->sha256(this->properties.deviceCode)) + else if (requestData["secret"] == secret) { replyStatus = Success; this->sessionAuthorized = true; @@ -150,6 +153,30 @@ void OmobiLedDisplay::onDataReceived(String dataString) replyStatus = Success; break; } + case SetDisplayCodeCommand: { + String code = requestData["displayCode"]; + if(code.length() != 4) { + replyStatus = BadRequestError; + break; + } + + strncpy(this->properties.deviceCode, code.c_str(), sizeof(this->properties.deviceCode)); + this->storeProperties(); + replyStatus = Success; + break; + } + case SetDisplayNameCommand: { + String name = requestData["displayName"]; + if(name.length() <= 0) { + replyStatus = BadRequestError; + break; + } + + strncpy(this->properties.deviceName, name.c_str(), sizeof(this->properties.deviceName)); + this->storeProperties(); + replyStatus = Success; + break; + } default: break; }