aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilippe Lelong <lelong.ph@meltemus.com>2016-12-16 09:21:21 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2016-12-20 13:28:35 +0100
commit2a803ddcf479ba70b08b199e0448521969796a14 (patch)
tree72317f60f7b366a491506f94cb6499ac4aea34c5
parent29be7bef7c0bb700af8992c73ab7a3c6d1fbdfce (diff)
websockets mechanism implemented
Signed-off-by: Philippe Lelong <lelong.ph@meltemus.com>
-rw-r--r--HomeScreen/qml/Home.qml16
-rw-r--r--HomeScreen/qml/MediaAreaBlank.qml4
-rw-r--r--HomeScreen/qml/StatusArea.qml1
-rw-r--r--HomeScreen/qml/images/Utility_Logo_Red-01.pngbin0 -> 7306 bytes
-rw-r--r--HomeScreen/qml/images/images.qrc1
-rw-r--r--HomeScreen/src/main.cpp5
-rw-r--r--HomeScreen/src2/usermanagement.cpp279
-rw-r--r--HomeScreen/src2/usermanagement.h63
8 files changed, 328 insertions, 41 deletions
diff --git a/HomeScreen/qml/Home.qml b/HomeScreen/qml/Home.qml
index 8753d29..63bb385 100644
--- a/HomeScreen/qml/Home.qml
+++ b/HomeScreen/qml/Home.qml
@@ -51,6 +51,17 @@ Item {
anchors.topMargin: 20
source: './images/visa.png'
visible: false
+ Label {
+ id: cardNumber
+ anchors.top: parent.bottom
+ anchors.topMargin: 10
+ anchors.horizontalCenter: parent.horizontalCenter
+ horizontalAlignment: Text.AlignHCenter
+ color: "white"
+ text: "111"
+ font.pixelSize: 20
+ font.family: "Roboto"
+ }
}
Item {
id: hello
@@ -62,7 +73,7 @@ Item {
id: helloText
anchors.centerIn: parent
color: "white"
- text: "Hello José!"
+ text: ""
font.pixelSize: 40
font.family: "Roboto"
SequentialAnimation on font.letterSpacing {
@@ -95,8 +106,9 @@ Item {
sign90.visible = show
}
- function showVisa(show) {
+ function showVisa(show, num) {
visa.visible = show
+ cardNumber.text = num;
}
GridView {
anchors.centerIn: parent
diff --git a/HomeScreen/qml/MediaAreaBlank.qml b/HomeScreen/qml/MediaAreaBlank.qml
index 3d53061..48595eb 100644
--- a/HomeScreen/qml/MediaAreaBlank.qml
+++ b/HomeScreen/qml/MediaAreaBlank.qml
@@ -23,7 +23,11 @@ Image {
source: './images/Utility_Logo_Background-01.png'
Image {
+ objectName: "Logo_colour"
anchors.centerIn: parent
source: './images/Utility_Logo_Colour-01.png'
+ function setImage(imagePath) {
+ source = imagePath
+ }
}
}
diff --git a/HomeScreen/qml/StatusArea.qml b/HomeScreen/qml/StatusArea.qml
index 12d0d46..3d55947 100644
--- a/HomeScreen/qml/StatusArea.qml
+++ b/HomeScreen/qml/StatusArea.qml
@@ -144,6 +144,7 @@ Item {
}
}
}
+ Component.onCompleted: root.languageChanged("en")
}
ColumnLayout {
id: icons
diff --git a/HomeScreen/qml/images/Utility_Logo_Red-01.png b/HomeScreen/qml/images/Utility_Logo_Red-01.png
new file mode 100644
index 0000000..8c49068
--- /dev/null
+++ b/HomeScreen/qml/images/Utility_Logo_Red-01.png
Binary files differ
diff --git a/HomeScreen/qml/images/images.qrc b/HomeScreen/qml/images/images.qrc
index 2d8e902..1323107 100644
--- a/HomeScreen/qml/images/images.qrc
+++ b/HomeScreen/qml/images/images.qrc
@@ -6,5 +6,6 @@
<file>Utility_Music_Background-01.png</file>
<file>Utility_Radio_Background-01.png</file>
<file>AGL_HMI_Background_NoCar-01.png</file>
+ <file>Utility_Logo_Red-01.png</file>
</qresource>
</RCC>
diff --git a/HomeScreen/src/main.cpp b/HomeScreen/src/main.cpp
index 4e928c6..37648a0 100644
--- a/HomeScreen/src/main.cpp
+++ b/HomeScreen/src/main.cpp
@@ -75,10 +75,7 @@ int main(int argc, char *argv[])
engine.rootContext()->setContextProperty("layoutHandler", layoutHandler);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
- QObject *home = engine.rootObjects().first()->findChild<QObject *>("Home");
- QObject *shortcutArea = engine.rootObjects().first()->findChild<QObject *>("ShortcutArea");
- QObject *statusArea = engine.rootObjects().first()->findChild<QObject *>("StatusArea");
- UserManagement userManagement(home, shortcutArea, statusArea);
+ UserManagement userManagement(engine.rootObjects().first());
Q_UNUSED(userManagement);
return a.exec();
}
diff --git a/HomeScreen/src2/usermanagement.cpp b/HomeScreen/src2/usermanagement.cpp
index f973001..54aff23 100644
--- a/HomeScreen/src2/usermanagement.cpp
+++ b/HomeScreen/src2/usermanagement.cpp
@@ -1,62 +1,281 @@
#include "usermanagement.h"
#include <QApplication>
#include <QDebug>
-UserManagement::UserManagement(QObject *home, QObject *shortcutArea, QObject *statusArea) : QObject()
+#include <QtCore/QJsonDocument>
+#include <QByteArray>
+UserManagement::UserManagement(QObject *root) : QObject()
{
- this->home = home;
+ home = root->findChild<QObject *>("Home");
+ logo = root->findChild<QObject *>("Logo_colour");
+ shortcutArea = root->findChild<QObject *>("ShortcutArea");
+ statusArea = root->findChild<QObject *>("StatusArea");
this->appModel = home->findChild<ApplicationModel *>("ApplicationModel");
- this->shortcutArea = shortcutArea;
- this->statusArea = statusArea;
- this->currentLanguage = "en";
+ sequence = 0;
+#ifdef REAL_SERVER
+ connectWebsockets();
+#else
+ pSocket = NULL;
connect(&timerTest, SIGNAL(timeout()), this, SLOT(slot_timerTest()));
timerTest.setSingleShot(false);
timerTest.start(5000);
- connectWebsockets(QStringLiteral("wss://echo.websocket.org"));
+ launchServer();
+#endif
}
-void UserManagement::slot_timerTest()
+void UserManagement::setUser(const User &user)
{
- if(currentLanguage == "fr")
- currentLanguage = "en";
- else
- currentLanguage = "fr";
- appModel->changeLanguage(currentLanguage);
+ appModel->changeLanguage(user.graphPreferredLanguage);
+ QMetaObject::invokeMethod(logo, "setImage", Q_ARG(QVariant, "./images/Utility_Logo_Colour-01.png"));
QMetaObject::invokeMethod(home, "languageChanged");
- QMetaObject::invokeMethod(shortcutArea, "languageChanged", Q_ARG(QVariant, currentLanguage));
- QMetaObject::invokeMethod(statusArea, "languageChanged", Q_ARG(QVariant, currentLanguage));
- if(currentLanguage == "fr") {
- QLocale::setDefault(QLocale("fr_FR"));
- QMetaObject::invokeMethod(home, "showSign90", Q_ARG(QVariant, true));
- QMetaObject::invokeMethod(home, "showVisa", Q_ARG(QVariant, false));
- QMetaObject::invokeMethod(home, "showHello", Q_ARG(QVariant, "Bonjour José!"));
- } else {
- QLocale::setDefault(QLocale("en_US"));
- QMetaObject::invokeMethod(home, "showSign90", Q_ARG(QVariant, false));
- QMetaObject::invokeMethod(home, "showVisa", Q_ARG(QVariant, true));
- QMetaObject::invokeMethod(home, "showHello", Q_ARG(QVariant, "Hello José!"));
- }
-}
-void UserManagement::connectWebsockets(const QUrl &url)
+ QMetaObject::invokeMethod(shortcutArea, "languageChanged", Q_ARG(QVariant, user.graphPreferredLanguage));
+ QMetaObject::invokeMethod(statusArea, "languageChanged", Q_ARG(QVariant, user.graphPreferredLanguage));
+ QMetaObject::invokeMethod(home, "showSign90", Q_ARG(QVariant, true));
+ QMetaObject::invokeMethod(home, "showVisa", Q_ARG(QVariant, true), Q_ARG(QVariant, "---- ---- ---- " + user.ccNumberMasked));
+ const QString welcome = QString("%1").arg(user.graphPreferredLanguage == "fr" ? "Bonjour " : "Hello") + " ";
+ QMetaObject::invokeMethod(home, "showHello", Q_ARG(QVariant, welcome + user.first_name));
+}
+void UserManagement::connectWebsockets()
{
+#ifdef REAL_SERVER
+ const QUrl url(REAL_SERVER);
+#else
+ const QUrl url(QStringLiteral("ws://localhost:1234"));
+#endif
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setProtocol(QSsl::SecureProtocols);
webSocket.setSslConfiguration(config);
connect(&webSocket, &QWebSocket::connected, this, &UserManagement::onConnected);
connect(&webSocket, &QWebSocket::disconnected, this, &UserManagement::onClosed);
+ if(!connect(&webSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onWebSocketError(QAbstractSocket::SocketError)))) {
+ qWarning() << "Failed to connect to QWebSocket::error";
+ }
webSocket.open(QUrl(url));
}
+void UserManagement::onWebSocketError(QAbstractSocket::SocketError)
+{
+ qWarning()<<"Websocket error:" << webSocket.errorString();
+}
+
void UserManagement::onConnected()
{
connect(&webSocket, &QWebSocket::textMessageReceived,
this, &UserManagement::onTextMessageReceived);
- webSocket.sendTextMessage(QStringLiteral("Hello, world!"));
-
+ QVariantList list;
+ QByteArray json;
+ list << 2 << QString().setNum(++sequence) << "agl-identity-agent/subscribe" << true;
+ listToJson(list, &json);
+ webSocket.sendTextMessage(QString(json));
+ list .clear();
+ list << 2 << QString().setNum(++sequence) << "agl-identity-agent/scan" << true;
+ listToJson(list, &json);
+ webSocket.sendTextMessage(QString(json));
}
void UserManagement::onTextMessageReceived(QString message)
{
- qWarning()<<"message received:"<<message;
+ QVariantList list;
+ const bool ok = jsonToList(message.toUtf8(), &list);
+ if(!ok || list.size() < 3) {
+ qWarning()<<"error 1 decoding json"<<list.size()<<message;
+ return;
+ }
+ QVariantMap map = list.at(2).toMap();
+ if(list.first().toInt() == 5) {
+ QMetaObject::invokeMethod(logo, "setImage", Q_ARG(QVariant, "./images/Utility_Logo_Red-01.png"));
+ map = map["data"].toMap();
+ if(map["eventName"].toString() == "login") {
+ //qWarning()<<"login received in client";
+ list.clear();
+ list << 2 << QString().setNum(++sequence) << "agl-identity-agent/get" << true;
+ listToJson(list, &data);
+ QTimer::singleShot(300, this, SLOT(slot_sendData()));
+ }
+ return;
+ }
+ if(list.first().toInt() == 3) {
+ if(!map.contains("response")) {
+ return;
+ }
+ map = map["response"].toMap();
+ User user;
+ user.postal_address = map["postal_address"].toString();
+ QStringList temp = map["loc"].toString().split(",");
+ if(temp.size() == 2) {
+ user.loc.setX(temp.at(0).toDouble());
+ user.loc.setY(temp.at(1).toDouble());
+ }
+ user.country = map["country"].toString();
+ user.mail = map["mail"].toString();
+ user.city = map["city"].toString();
+ user.graphEmail = map["graphEmail"].toString();
+ user.graphPreferredLanguage = map["graphPreferredLanguage"].toString();
+ user.ccNumberMasked = map["ccNumberMasked"].toString();
+ user.ccExpYear = map["ccExpYear"].toString();
+ user.ccExpMonth = map["ccExpMonth"].toString();
+ user.description = map["description"].toString();
+ user.groups = map["groups"].toStringList();
+ user.last_name = map["last_name"].toString();
+ user.ccNumber = map["ccNumber"].toString();
+ user.house_identifier = map["house_identifier"].toString();
+ user.phone = map["phone"].toString();
+ user.name = map["name"].toString();
+ user.state = map["state"].toString();
+ user.common_name = map["common_name"].toString();
+ user.fax = map["fax"].toString();
+ user.postal_code = map["postal_code"].toString();
+ user.first_name = map["first_name"].toString();
+ user.keytoken = map["keytoken"].toString();
+ setUser(user);
+ }
+}
+void UserManagement::slot_sendData()
+{
+ webSocket.sendTextMessage(QString(data));
}
void UserManagement::onClosed()
{
qWarning()<<"webSocket closed";
}
+bool UserManagement::listToJson(const QList<QVariant> &list, QByteArray *json) const
+{
+ QVariant v(list);
+ *json = QJsonDocument::fromVariant(v).toJson(QJsonDocument::Compact);
+ return true;
+}
+bool UserManagement::jsonToList(const QByteArray &buf, QList<QVariant> *list) const
+{
+ if(!list)
+ return false;
+ QJsonParseError err;
+ QVariant v = QJsonDocument::fromJson(buf, &err).toVariant();
+ if(err.error != 0) {
+ qWarning() << "Error parsing json data" << err.errorString() << buf;
+ *list = QList<QVariant>();
+ return false;
+ }
+ *list = v.toList();
+ return true;
+}
+bool UserManagement::mapToJson( const QVariantMap &map, QByteArray *json) const
+{
+ if(!json)
+ return false;
+ QVariant v(map);
+ *json = QJsonDocument::fromVariant(v).toJson(QJsonDocument::Compact);
+ return true;
+}
+bool UserManagement::jsonToMap(const QByteArray &buf, QVariantMap *map) const
+{
+ if(!map)
+ return false;
+ QJsonParseError err;
+ QVariant v = QJsonDocument::fromJson(buf, &err).toVariant();
+ if(err.error != 0) {
+ qWarning() << "Error parsing json data" << err.errorString() << buf;
+ *map = QVariantMap();
+ return false;
+ }
+ *map = v.toMap();
+ return true;
+}
+#ifndef REAL_SERVER
+void UserManagement::launchServer()
+{
+ webSocketServer = new QWebSocketServer(QStringLiteral("My Server"),
+ QWebSocketServer::NonSecureMode, this);
+ if(webSocketServer->listen(QHostAddress::Any, 1234)) {
+ connect(webSocketServer, &QWebSocketServer::newConnection,
+ this, &UserManagement::onServerNewConnection);
+ connect(webSocketServer, &QWebSocketServer::closed, this, &UserManagement::onServerClosed);
+ QTimer::singleShot(100, this, SLOT(connectWebsockets()));
+ } else {
+ qWarning()<<"unable to launch webSocket server";
+ }
+}
+void UserManagement::onServerNewConnection()
+{
+ pSocket = webSocketServer->nextPendingConnection();
+ connect(pSocket, &QWebSocket::textMessageReceived, this, &UserManagement::processTextMessage, Qt::UniqueConnection);
+ connect(pSocket, &QWebSocket::binaryMessageReceived, this, &UserManagement::processBinaryMessage, Qt::UniqueConnection);
+ connect(pSocket, &QWebSocket::disconnected, this, &UserManagement::serverSocketDisconnected, Qt::UniqueConnection);
+}
+void UserManagement::processTextMessage(QString message)
+{
+ QString clientDetails_1 = "{\"postal_address\":\"201 Mission Street\",\"loc\":\"37.7914374,-122.3950694\""
+ ",\"country\":\"USA\",\"mail\":\"bjensen@example.com\",\"city\":\"San Francisco\",\"graphEmail\":"
+ "\"bjensen@example.com\",\"graphPreferredLanguage\":\"en\",\"ccNumberMasked\":\"-111\",\"ccExpYear\""
+ ":\"19\",\"ccExpMonth\":\"01\",\"description\":\"Original description\",\"groups\":[],\"last_name\":\""
+ "Jensen\",\"ccNumber\":\"111-2343-1121-111\",\"house_identifier\":\"ForgeRock\",\"phone\":\""
+ "+1 408 555 1862\",\"name\":\"bjensen\",\"state\":\"CA\",\"common_name\":\"Barbara Jensen\",\"fax\":\""
+ "+1 408 555 1862\",\"postal_code\":\"94105\",\"first_name\":\"Barbara\",\"keytoken\":\"a123456\"}";
+ QString clientDetails_2 = "{\"postal_address\":\"201 Mission Street\",\"loc\":\"37.7914374,-122.3950694\""
+ ",\"country\":\"USA\",\"mail\":\"bjensen@example.com\",\"city\":\"San Francisco\",\"graphEmail\":"
+ "\"bjensen@example.com\",\"graphPreferredLanguage\":\"fr\",\"ccNumberMasked\":\"-222\",\"ccExpYear\""
+ ":\"19\",\"ccExpMonth\":\"01\",\"description\":\"Original description\",\"groups\":[],\"last_name\":\""
+ "Jensen\",\"ccNumber\":\"111-2343-1121-111\",\"house_identifier\":\"ForgeRock\",\"phone\":\""
+ "+1 408 555 1862\",\"name\":\"bjensen\",\"state\":\"CA\",\"common_name\":\"Barbara Jensen\",\"fax\":\""
+ "+1 408 555 1862\",\"postal_code\":\"94105\",\"first_name\":\"José\",\"keytoken\":\"a123456\"}";
+ QString clientDetails = clientDetails_1;
+ if(sequence % 2 == 1)
+ clientDetails = clientDetails_2;
+ QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
+ //qDebug() << "message received in server:" << message;
+ if (!pClient)
+ return;
+ QVariantList list;
+ if(!jsonToList(message.toUtf8(), &list))
+ return;
+ if(list.size() < 2)
+ return;
+ const int messType = list.at(0).toInt();
+ const QString messId = list.at(1).toString();
+ const QString cmd = list.at(2).toString();
+ list.clear();
+ QString reply;
+ switch(messType) {
+ case 2:
+ if(cmd == "agl-identity-agent/subscribe") {
+ reply = "[3,\"999maitai999\",{\"jtype\":\"afb-reply\",\"request\":{\"status\":\"success\",\"uuid\":\"1f2f7678-6f2e-4f54-b7b5-d0d4dcbf2e41\"}}]";
+ } else if (cmd == "agl-identity-agent/get") {
+ reply = "[3,\"999maitai99\",{\"jtype\":\"afb-reply\",\"request\":{\"status\":\"success\"},\"response\":....}]";
+ reply = reply.replace("....", clientDetails);
+ } else {
+ qWarning()<<"invalid cmd received:"<<cmd;
+ return;
+ }
+ break;
+ default:
+ qWarning()<<"invalid message type"<<messType;
+ return;
+ break;
+ }
+ reply = reply.replace("999maitai999", messId);
+ pClient->sendTextMessage(reply);
+}
+void UserManagement::processBinaryMessage(QByteArray message)
+{
+ QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
+ qDebug() << "Binary Message received ????:" << message;
+ if (pClient) {
+ // pClient->sendBinaryMessage(message);
+ }
+}
+void UserManagement::serverSocketDisconnected()
+{
+ QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
+ qDebug() << "socketDisconnected:" << pClient;
+ if (pClient) {
+ pClient->deleteLater();
+ }
+}
+void UserManagement::slot_timerTest()
+{
+ if(!pSocket)
+ return;
+ pSocket->sendTextMessage("[5,\"agl-identity-agent/event\",{\"event\":\"agl-identity-agent\/event\",\"data\":{\"eventName\":\"incoming\",\"accountid\":\"D2:D4:71:0D:B5:F1\",\"nickname\":\"D2:D4:71:0D:B5:F1\"},\"jtype\":\"afb-event\"}]");
+ pSocket->sendTextMessage("[5,\"agl-identity-agent/event\",{\"event\":\"agl-identity-agent\/event\",\"data\":{\"eventName\":\"login\",\"accountid\":\"null\"},\"jtype\":\"afb-event\"}]");
+}
+void UserManagement::onServerClosed()
+{
+ qWarning()<<"websocket server closed";
+}
+#endif
diff --git a/HomeScreen/src2/usermanagement.h b/HomeScreen/src2/usermanagement.h
index 099c991..382d1ac 100644
--- a/HomeScreen/src2/usermanagement.h
+++ b/HomeScreen/src2/usermanagement.h
@@ -1,32 +1,85 @@
#ifndef USERMANAGEMENT_H
#define USERMANAGEMENT_H
+#define REAL_SERVER "ws://your_server.com:1234"
+
#include <QObject>
#include "applicationmodel.h"
#include <QTimer>
+#include <QPointF>
#include <QtWebSockets/QWebSocket>
+#ifndef REAL_SERVER
+#include <QtWebSockets/QWebSocketServer>
+#endif
+struct User {
+ QString postal_address;
+ QPointF loc;
+ QString country;
+ QString mail;
+ QString city;
+ QString graphEmail;
+ QString graphPreferredLanguage;
+ QString ccNumberMasked;
+ QString ccExpYear;
+ QString ccExpMonth;
+ QString description;
+ QStringList groups;
+ QString last_name;
+ QString ccNumber;
+ QString house_identifier;
+ QString phone;
+ QString name;
+ QString state;
+ QString common_name;
+ QString fax;
+ QString postal_code;
+ QString first_name;
+ QString keytoken;
+};
+
class UserManagement : public QObject
{
Q_OBJECT
public:
- explicit UserManagement(QObject *home, QObject *shortcutArea, QObject *statusArea);
+ explicit UserManagement(QObject *root);
signals:
public slots:
- void slot_timerTest();
+ void connectWebsockets();
void onConnected();
void onClosed();
void onTextMessageReceived(QString message);
+ void onWebSocketError(QAbstractSocket::SocketError);
+ void slot_sendData();
+#ifndef REAL_SERVER
+ void onServerNewConnection();
+ void onServerClosed();
+ void processBinaryMessage(QByteArray message);
+ void processTextMessage(QString message);
+ void serverSocketDisconnected();
+ void slot_timerTest();
+#endif
private:
QObject *home;
QObject *shortcutArea;
QObject *statusArea;
+ QObject *logo;
+ QByteArray data;
ApplicationModel *appModel;
- QTimer timerTest;
- QString currentLanguage;
QWebSocket webSocket;
- void connectWebsockets(const QUrl &url);
+ int sequence;
+ bool jsonToMap(const QByteArray &buf, QVariantMap *map) const;
+ bool mapToJson(const QVariantMap &map, QByteArray *json) const;
+ bool jsonToList(const QByteArray &buf, QList<QVariant> *list) const;
+ bool listToJson(const QList<QVariant> &list, QByteArray *json) const;
+ void setUser(const User &user);
+#ifndef REAL_SERVER
+ QTimer timerTest;
+ QWebSocket *pSocket;
+ QWebSocketServer *webSocketServer;
+ void launchServer();
+#endif
};
#endif // USERMANAGEMENT_H