summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaquel Medina <raquel.medina@konsulko.com>2020-03-18 23:56:31 +0100
committerRaquel Medina <raquel.medina@konsulko.com>2020-03-23 14:02:28 +0100
commit0ed292d3ccf93c889734960676a321d1166d3f66 (patch)
treeb8d64d1685d2f4bf599ab3867a0d3ff557ff0479
parent5c750385d02116a92fa4c120ccc26abb8267bc97 (diff)
rework message hierarchy
Rework message hierarchy with the final objective of splitting libqtappfw into several libraries. This commit carries the following changes: - Simplify message hierarchy, keeping abstract Message class, adding specialization for call and event messages, keeping ResponseMessage, and removing all module specific specializations. - Add MessageFactory class to create message objects. - Change messages life cycle: using smart pointers and removing QObject from message hierarchy (a Message is not a QObject anymore and thus 'deleteLater()' is not available). - Adapt all modules to use new message hierarchy. - Keep ResponseMessage original constructor to avoid breaking TaskManager. - Message constructors have been kept public, but will go private on a follow-up patch (once TaskManager class has been modified to use new MessageFactory). Bug-AGL: SPEC-3112 Signed-off-by: Raquel Medina <raquel.medina@konsulko.com> Change-Id: I3a7a6325209ddeca2293f1ac745371861a947bfb
-rw-r--r--CMakeLists.txt4
-rw-r--r--bluetooth/CMakeLists.txt4
-rw-r--r--bluetooth/bluetooth.cpp64
-rw-r--r--bluetooth/bluetooth.h7
-rw-r--r--callmessage.cpp56
-rw-r--r--callmessage.h51
-rw-r--r--eventmessage.cpp67
-rw-r--r--eventmessage.h60
-rw-r--r--hvac/CMakeLists.txt4
-rw-r--r--hvac/hvac.cpp32
-rw-r--r--hvac/hvac.h5
-rw-r--r--map/CMakeLists.txt4
-rw-r--r--map/map.cpp74
-rw-r--r--map/map.h5
-rw-r--r--mediaplayer/CMakeLists.txt4
-rw-r--r--mediaplayer/mediaplayer.cpp67
-rw-r--r--mediaplayer/mediaplayer.h5
-rw-r--r--message.cpp135
-rw-r--r--message.h93
-rw-r--r--messageengine.cpp130
-rw-r--r--messageengine.h14
-rw-r--r--messagefactory.cpp39
-rw-r--r--messagefactory.h42
-rw-r--r--navigation/CMakeLists.txt4
-rw-r--r--navigation/navigation.cpp99
-rw-r--r--navigation/navigation.h5
-rw-r--r--network/CMakeLists.txt4
-rw-r--r--network/network.cpp216
-rw-r--r--network/network.h11
-rw-r--r--pbap/CMakeLists.txt4
-rw-r--r--pbap/pbap.cpp123
-rw-r--r--pbap/pbap.h5
-rw-r--r--radio/CMakeLists.txt4
-rw-r--r--radio/radio.cpp174
-rw-r--r--radio/radio.h4
-rw-r--r--responsemessage.cpp111
-rw-r--r--responsemessage.h69
-rw-r--r--signal-composer/CMakeLists.txt4
-rw-r--r--signal-composer/signalcomposer.cpp74
-rw-r--r--signal-composer/signalcomposer.h5
-rw-r--r--telephony/CMakeLists.txt4
-rw-r--r--telephony/telephony.cpp85
-rw-r--r--telephony/telephony.h5
-rw-r--r--voice-capabilities/CMakeLists.txt4
-rw-r--r--voice-capabilities/guimetadata.cpp43
-rw-r--r--voice-capabilities/guimetadata.h4
-rw-r--r--voice/CMakeLists.txt4
-rw-r--r--voice/voice.cpp105
-rw-r--r--voice/voice.h15
-rw-r--r--weather/CMakeLists.txt4
-rw-r--r--weather/weather.cpp46
-rw-r--r--weather/weather.h5
52 files changed, 1307 insertions, 899 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e769b33..b2f826f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,8 +61,8 @@ set (SUBDIRS
voice-capabilities
weather)
-add_headers(message.h messageengine.h responsemessage.h)
-add_sources(message.cpp messageengine.cpp responsemessage.cpp)
+add_headers(message.h messagefactory.h messageengine.h responsemessage.h callmessage.h eventmessage.h)
+add_sources(message.cpp messagefactory.cpp messageengine.cpp responsemessage.cpp callmessage.cpp eventmessage.cpp)
foreach(subdir ${SUBDIRS})
add_subdirectory(${subdir})
diff --git a/bluetooth/CMakeLists.txt b/bluetooth/CMakeLists.txt
index cdefb0d..0e05d3b 100644
--- a/bluetooth/CMakeLists.txt
+++ b/bluetooth/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(bluetooth.h bluetoothmessage.h bluetoothmodel.h)
-add_sources(bluetooth.cpp bluetoothmessage.cpp bluetoothmodel.cpp)
+add_headers(bluetooth.h bluetoothmodel.h)
+add_sources(bluetooth.cpp bluetoothmodel.cpp)
diff --git a/bluetooth/bluetooth.cpp b/bluetooth/bluetooth.cpp
index f74d60d..e39270a 100644
--- a/bluetooth/bluetooth.cpp
+++ b/bluetooth/bluetooth.cpp
@@ -16,13 +16,13 @@
#include <QDebug>
-#include "message.h"
-#include "bluetoothmessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
#include "responsemessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
-#include "bluetoothmodel.h"
#include "bluetooth.h"
-
+#include "bluetoothmodel.h"
Bluetooth::Bluetooth (QUrl &url, QQmlContext *context, QObject * parent) :
@@ -58,10 +58,13 @@ Bluetooth::~Bluetooth()
void Bluetooth::send_command(QString verb, QJsonObject parameter)
{
- BluetoothMessage *tmsg = new BluetoothMessage();
- tmsg->createRequest(verb, parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* btmsg = static_cast<CallMessage*>(msg.get());
+ btmsg->createRequest("Bluetooth-Manager", verb, parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Bluetooth::setPower(bool state)
@@ -261,32 +264,39 @@ void Bluetooth::processAdapterChangesEvent(QJsonObject data)
m_discoverable = false;
}
-void Bluetooth::onMessageReceived(MessageType type, Message *msg)
+void Bluetooth::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (msg->isEvent() && type == MessageType::BluetoothEventMessage) {
- BluetoothMessage *tmsg = qobject_cast<BluetoothMessage*>(msg);
-
- if (tmsg->isDeviceChangesEvent()) {
- processDeviceChangesEvent(tmsg->eventData());
- } else if (tmsg->isAdapterChangesEvent()) {
- processAdapterChangesEvent(tmsg->eventData());
- } else if (tmsg->isAgentEvent()) {
- emit requestConfirmationEvent(tmsg->eventData());
- }
+ if (!msg)
+ return;
- } else if (msg->isReply() && type == MessageType::ResponseRequestMessage) {
- ResponseMessage *tmsg = qobject_cast<ResponseMessage*>(msg);
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ QString ename = emsg->eventName();
+ QString eapi = emsg->eventApi();
+ QJsonObject data = emsg->eventData();
+ if (eapi != "Bluetooth-Manager")
+ return;
+ if (ename == "device_changes") {
+ processDeviceChangesEvent(data);
+ } else if (ename == "adapter_changes") {
+ processAdapterChangesEvent(data);
+ } else if (ename == "agent") {
+ emit requestConfirmationEvent(data);
+ }
- if (tmsg->requestVerb() == "managed_objects") {
- populateDeviceList(tmsg->replyData());
- } else if (tmsg->requestVerb() == "adapter_state") {
- bool powered = tmsg->replyData().value("powered").toBool();
+ } else if (msg->isReply()) {
+ std::shared_ptr<ResponseMessage> rmsg = std::static_pointer_cast<ResponseMessage>(msg);
+ //get api name
+ QString verb = rmsg->requestVerb();
+ QJsonObject data = rmsg->replyData();
+ if (verb == "managed_objects") {
+ populateDeviceList(data);
+ } else if (verb == "adapter_state") {
+ bool powered = data.value("powered").toBool();
if (m_power != powered) {
m_power = powered;
emit powerChanged(m_power);
}
}
}
-
- msg->deleteLater();
}
diff --git a/bluetooth/bluetooth.h b/bluetooth/bluetooth.h
index 815e180..3953fe6 100644
--- a/bluetooth/bluetooth.h
+++ b/bluetooth/bluetooth.h
@@ -17,17 +17,16 @@
#ifndef BLUETOOTH_H
#define BLUETOOTH_H
+#include <memory>
#include <QObject>
-#include <QJsonArray>
#include <QJsonObject>
+#include <QJsonArray>
#include <QtQml/QQmlContext>
class BluetoothModel;
class MessageEngine;
class Message;
-enum class MessageType;
-
class Bluetooth : public QObject
{
Q_OBJECT
@@ -80,7 +79,7 @@ class Bluetooth : public QObject
// slots
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
QString process_uuid(QString uuid) { if (uuid.length() == 36) return uuid; return uuids.value(uuid); };
diff --git a/callmessage.cpp b/callmessage.cpp
new file mode 100644
index 0000000..4afb071
--- /dev/null
+++ b/callmessage.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <QDebug>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonValue>
+
+#include "callmessage.h"
+#include "message.h"
+
+
+bool CallMessage::createRequest(QString api, QString verb, QJsonValue parameter)
+{
+ if (!m_request.isEmpty()){
+ qWarning("Message instance has already been used. Cannot send another request.");
+ return false;
+ }
+
+ m_request["msgid"] = static_cast<unsigned int>(MessageId::Call);
+ m_request["callid"] = 0;
+ m_request["api"] = api;
+ m_request["verb"] = verb;
+ m_request["parameter"] = parameter;
+
+ m_init = true;
+
+ return m_init;
+}
+
+QByteArray CallMessage::serialize(QJsonDocument::JsonFormat format)
+{
+ QJsonArray array;
+ array.append(m_request["msgid"].toInt());
+ array.append(m_request["callid"].toInt());
+ array.append(m_request["api"].toString() + "/" + m_request["verb"].toString());
+ array.append(m_request["parameter"].toJsonValue());
+
+ QJsonDocument jdoc;
+ jdoc.setArray(array);
+
+ return jdoc.toJson(format).data();
+}
diff --git a/callmessage.h b/callmessage.h
new file mode 100644
index 0000000..41098bc
--- /dev/null
+++ b/callmessage.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CALLMESSAGE_H
+#define CALLMESSAGE_H
+
+#include "message.h"
+
+
+class CallMessage : public Message
+{
+ public:
+ CallMessage() = default;
+
+ bool createRequest(QString api, QString verb, QJsonValue parameter = "None");
+
+ bool isEvent() override
+ {
+ return false;
+ }
+
+ bool isReply() override
+ {
+ return false;
+ }
+
+ void updateCallId(unsigned int id) override
+ {
+ m_request["callid"] = qint32(id);
+ }
+
+ QByteArray serialize(QJsonDocument::JsonFormat format = QJsonDocument::Compact) override;
+
+ private:
+ QMap<QString, QVariant> m_request;
+};
+
+#endif // CALLMESSAGE_H
diff --git a/eventmessage.cpp b/eventmessage.cpp
new file mode 100644
index 0000000..818830f
--- /dev/null
+++ b/eventmessage.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <QDebug>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonValue>
+
+#include "eventmessage.h"
+
+EventMessage::EventMessage(QJsonDocument content): Message()
+{
+ QJsonArray msg = content.array();
+ if (!msg[2].isObject()) {
+ qWarning("Invalid appfw payload: no JSON object");
+ return;
+ }
+
+ //deserialize:
+ QJsonObject payload = msg[2].toObject();
+
+ auto data_iter = payload.find("data");
+ m_event_data = data_iter.value().toObject();
+
+ auto event_iter = payload.find("event");
+ auto event_string = event_iter.value().toString();
+ if (event_string.isEmpty()) {
+ qWarning("Invalid appfw event message: empty event name");
+ return;
+ }
+ QStringList event_strings = event_string.split(QRegExp("/"));
+ if (event_strings.size() != 2) {
+ qWarning("Invalid appfw event message: malformed event name");
+ return;
+ }
+ m_event_api = event_strings[0];
+ m_event_name = event_strings[1];
+ m_init = true;
+}
+
+QByteArray EventMessage::serialize(QJsonDocument::JsonFormat format)
+{
+ QJsonArray array;
+ array.append(static_cast<int>(MessageId::Event));
+ array.append(0); //unused field
+ array.append(m_event_api + "/" + m_event_name);
+ array.append(m_event_data);
+
+ QJsonDocument jdoc;
+ jdoc.setArray(array);
+
+ return jdoc.toJson(format).data();
+}
diff --git a/eventmessage.h b/eventmessage.h
new file mode 100644
index 0000000..41bf7b6
--- /dev/null
+++ b/eventmessage.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef EVENTMESSAGE_H
+#define EVENTMESSAGE_H
+
+#include "message.h"
+
+
+class EventMessage : public Message
+{
+ public:
+ explicit EventMessage(QJsonDocument data);
+
+ inline QString eventApi() const
+ {
+ return m_event_api;
+ }
+
+ inline QString eventName() const
+ {
+ return m_event_name;
+ }
+
+ inline QJsonObject eventData() const
+ {
+ return m_event_data;
+ }
+
+ bool isEvent() override
+ {
+ return true;
+ }
+
+ bool isReply() override
+ {
+ return false;
+ }
+
+ QByteArray serialize(QJsonDocument::JsonFormat format = QJsonDocument::Compact) override;
+
+ private:
+ QString m_event_api, m_event_name;
+ QJsonObject m_event_data;
+};
+
+#endif // EVENTMESSAGE_H
diff --git a/hvac/CMakeLists.txt b/hvac/CMakeLists.txt
index 0ee635a..b5124cb 100644
--- a/hvac/CMakeLists.txt
+++ b/hvac/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(hvac.h hvacmessage.h)
-add_sources(hvac.cpp hvacmessage.cpp)
+add_headers(hvac.h)
+add_sources(hvac.cpp)
diff --git a/hvac/hvac.cpp b/hvac/hvac.cpp
index f9e509b..23aef30 100644
--- a/hvac/hvac.cpp
+++ b/hvac/hvac.cpp
@@ -19,9 +19,9 @@
#include <QMimeDatabase>
#include <QtQml/QQmlEngine>
-#include "message.h"
-#include "hvacmessage.h"
-#include "responsemessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "hvac.h"
@@ -45,13 +45,16 @@ HVAC::~HVAC()
void HVAC::control(QString verb, QString field, int value)
{
- HVACMessage *tmsg = new HVACMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* hmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert(field, value);
- tmsg->createRequest(verb, parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ hmsg->createRequest("hvac", verb, parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void HVAC::set_fanspeed(int speed)
@@ -75,14 +78,19 @@ void HVAC::set_temp_right_zone(int temp)
emit rightTemperatureChanged(temp);
}
-void HVAC::onMessageReceived(MessageType type, Message *msg)
+void HVAC::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (msg->isEvent() && type == MessageType::HVACEventMessage) {
- HVACMessage *tmsg = qobject_cast<HVACMessage*>(msg);
+ if (!msg)
+ return;
+
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ if (emsg->eventApi() != "hvac")
+ return;
- if (tmsg->isLanguageEvent()) {
+ if (emsg->eventName() == "language") {
// TODO: cannot be currently tested with identity service
- QVariantMap data = tmsg->eventData().toVariantMap();
+ QVariantMap data = emsg->eventData().toVariantMap();
emit languageChanged(data.value("language").toString());
}
}
diff --git a/hvac/hvac.h b/hvac/hvac.h
index 47a9e08..81378e4 100644
--- a/hvac/hvac.h
+++ b/hvac/hvac.h
@@ -17,6 +17,7 @@
#ifndef HVAC_H
#define HVAC_H
+#include <memory>
#include <QObject>
#include <QJsonArray>
#include <QtQml/QQmlContext>
@@ -25,8 +26,6 @@
class MessageEngine;
class Message;
-enum class MessageType;
-
class HVAC : public QObject
{
Q_OBJECT
@@ -62,7 +61,7 @@ class HVAC : public QObject
void set_temp_right_zone(int temp);
// slots
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
};
#endif // HVAC_H
diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt
index 2e58fbe..044f81a 100644
--- a/map/CMakeLists.txt
+++ b/map/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(map.h mapmessage.h)
-add_sources(map.cpp mapmessage.cpp)
+add_headers(map.h)
+add_sources(map.cpp)
diff --git a/map/map.cpp b/map/map.cpp
index 666efa1..e7a4157 100644
--- a/map/map.cpp
+++ b/map/map.cpp
@@ -16,9 +16,10 @@
#include <QDebug>
-#include "message.h"
-#include "mapmessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
#include "responsemessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "map.h"
@@ -39,77 +40,76 @@ Map::~Map()
void Map::compose(QString recipient, QString message)
{
- MapMessage *tmsg = new MapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ CallMessage* btmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("recipient", recipient);
parameter.insert("message", message);
- tmsg->createRequest("compose", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ btmsg->createRequest("bluetooth-map", "compose", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Map::message(QString handle)
{
- MapMessage *tmsg = new MapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ CallMessage* btmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("handle", handle);
- tmsg->createRequest("message", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ btmsg->createRequest("bluetooth-map", "message", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Map::listMessages(QString folder)
{
- MapMessage *tmsg = new MapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ CallMessage* btmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("folder", folder);
- tmsg->createRequest("list_messages", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ btmsg->createRequest("bluetooth-map", "list_messages", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Map::onConnected()
{
- MapMessage *tmsg = new MapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ CallMessage* btmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", "notification");
- tmsg->createRequest("subscribe", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ btmsg->createRequest("bluetooth-map", "subscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
listMessages();
}
void Map::onDisconnected()
{
- MapMessage *tmsg = new MapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ CallMessage* btmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", "notification");
- tmsg->createRequest("unsubscribe", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ btmsg->createRequest("bluetooth-map", "unsubscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
-void Map::onMessageReceived(MessageType type, Message *msg)
+void Map::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (type == MessageType::MapEventMessage) {
- MapMessage *tmsg = qobject_cast<MapMessage*>(msg);
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> tmsg = std::static_pointer_cast<EventMessage>(msg);
- if (tmsg->isNotificationEvent()) {
+ if (tmsg->eventApi() != "bluetooth-map")
+ return;
+ if (tmsg->eventName() == "notification") {
emit notificationEvent(tmsg->eventData().toVariantMap());
}
- } else if (msg->isReply() && type == MessageType::ResponseRequestMessage) {
- ResponseMessage *tmsg = qobject_cast<ResponseMessage*>(msg);
-
- if (tmsg->requestVerb() == "list_messages") {
- QString folder = tmsg->requestParameters().value("folder").toString();
- QVariantMap listing = tmsg->replyData().value("messages").toObject().toVariantMap();
+ } else if (msg->isReply()) {
+ auto rmsg = std::static_pointer_cast<ResponseMessage>(msg);
+ if (rmsg->requestVerb() == "list_messages") {
+ QString folder = rmsg->requestParameters().value("folder").toString();
+ QVariantMap listing = rmsg->replyData().value("messages").toObject().toVariantMap();
emit listMessagesResult(folder, listing);
- } else if (tmsg->requestVerb() == "message") {
- QString handle = tmsg->requestParameters().value("handle").toString();
- emit messageResult(handle, tmsg->replyData().toVariantMap());
+ } else if (rmsg->requestVerb() == "message") {
+ QString handle = rmsg->requestParameters().value("handle").toString();
+ emit messageResult(handle, rmsg->replyData().toVariantMap());
}
}
-
- msg->deleteLater();
}
diff --git a/map/map.h b/map/map.h
index 97407cc..91af103 100644
--- a/map/map.h
+++ b/map/map.h
@@ -17,6 +17,7 @@
#ifndef MAP_H
#define MAP_H
+#include <memory>
#include <QObject>
#include <QJsonArray>
#include <QtQml/QQmlContext>
@@ -25,8 +26,6 @@
class MessageEngine;
class Message;
-enum class MessageType;
-
class Map : public QObject
{
Q_OBJECT
@@ -50,7 +49,7 @@ class Map : public QObject
// slots
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
};
#endif // MAP_H
diff --git a/mediaplayer/CMakeLists.txt b/mediaplayer/CMakeLists.txt
index fd7e3f3..75bbca1 100644
--- a/mediaplayer/CMakeLists.txt
+++ b/mediaplayer/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(mediaplayer.h mediaplayermessage.h)
-add_sources(mediaplayer.cpp mediaplayermessage.cpp)
+add_headers(mediaplayer.h)
+add_sources(mediaplayer.cpp)
diff --git a/mediaplayer/mediaplayer.cpp b/mediaplayer/mediaplayer.cpp
index 69b2dea..e723d5d 100644
--- a/mediaplayer/mediaplayer.cpp
+++ b/mediaplayer/mediaplayer.cpp
@@ -16,9 +16,10 @@
#include <QDebug>
-#include "message.h"
-#include "mediaplayermessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
#include "messageengine.h"
+#include "messagefactory.h"
#include "mediaplayer.h"
@@ -89,13 +90,15 @@ void Mediaplayer::updatePlaylist(QVariantMap playlist)
void Mediaplayer::control(QString control, QJsonObject parameter)
{
- MediaplayerMessage *tmsg = new MediaplayerMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+ CallMessage* mpmsg = static_cast<CallMessage*>(msg.get());
parameter.insert("value", control);
- tmsg->createRequest("controls", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ mpmsg->createRequest("mediaplayer", "controls", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
@@ -186,44 +189,54 @@ void Mediaplayer::loop(QString state)
void Mediaplayer::onConnected()
{
QStringListIterator eventIterator(events);
- MediaplayerMessage *tmsg;
while (eventIterator.hasNext()) {
- tmsg = new MediaplayerMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* mpmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- tmsg->createRequest("subscribe", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ mpmsg->createRequest("mediaplayer", "subscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
}
void Mediaplayer::onDisconnected()
{
QStringListIterator eventIterator(events);
- MediaplayerMessage *tmsg;
while (eventIterator.hasNext()) {
- tmsg = new MediaplayerMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* mpmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- tmsg->createRequest("unsubscribe", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ mpmsg->createRequest("mediaplayer", "unsubscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
}
-void Mediaplayer::onMessageReceived(MessageType type, Message *message)
+void Mediaplayer::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (type == MessageType::MediaplayerEventMessage) {
- MediaplayerMessage *tmsg =
- qobject_cast<MediaplayerMessage*>(message);
-
- if (tmsg->isEvent()) {
- if (tmsg->isPlaylistEvent()) {
- updatePlaylist(tmsg->eventData().toVariantMap());
- } else if (tmsg->isMetadataEvent()) {
- QVariantMap map = tmsg->eventData().toVariantMap();
+ if (!msg)
+ return;
+
+ if (msg->isEvent()){
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ QString ename = emsg->eventName();
+ QString eapi = emsg->eventApi();
+ QJsonObject data = emsg->eventData();
+ if (eapi != "mediaplayer")
+ return;
+
+ if (ename == "playlist") {
+ updatePlaylist(data.toVariantMap());
+ } else if (ename == "metadata") {
+ QVariantMap map = data.toVariantMap();
if (map.contains("track")) {
QVariantMap track = map.value("track").toMap();
@@ -247,6 +260,4 @@ void Mediaplayer::onMessageReceived(MessageType type, Message *message)
emit metadataChanged(map);
}
}
- }
- message->deleteLater();
}
diff --git a/mediaplayer/mediaplayer.h b/mediaplayer/mediaplayer.h
index f3930f4..374ab06 100644
--- a/mediaplayer/mediaplayer.h
+++ b/mediaplayer/mediaplayer.h
@@ -17,6 +17,7 @@
#ifndef MEDIAPLAYER_H
#define MEDIAPLAYER_H
+#include <memory>
#include <QObject>
#include <QtQml/QQmlContext>
#include <QtQml/QQmlListProperty>
@@ -24,8 +25,6 @@
class MessageEngine;
class Message;
-enum class MessageType;
-
class Playlist : public QObject
{
Q_OBJECT
@@ -106,7 +105,7 @@ class Mediaplayer : public QObject
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
const QStringList events {
"playlist",
diff --git a/message.cpp b/message.cpp
index 3cd4bb9..1865f14 100644
--- a/message.cpp
+++ b/message.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Konsulko Group
+ * Copyright (C) 2017-2020 Konsulko Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,59 +17,25 @@
#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonValue>
+#include <QWebSocket>
#include "message.h"
-Message::Message()
- : m_init(false), m_event(false), m_reply(false)
-{
-}
-
-bool Message::createRequest(QString api, QString verb, QJsonValue parameter)
-{
- if (!m_request.isEmpty()){
- qWarning("Message instance has already been used. Cannot send another request.");
- return false;
- }
-
- m_request["msgid"] = Call;
- m_request["callid"] = 0;
- m_request["api"] = api;
- m_request["verb"] = verb;
- m_request["parameter"] = parameter;
-
- m_init = true;
-
- return true;
-}
-
-bool Message::fromJson(QByteArray jsonData)
+MessageId Message::isValid(QJsonDocument candidate)
{
- QJsonDocument jdoc(QJsonDocument::fromJson(jsonData));
-
- if (jdoc.isNull()) {
- qWarning("Imported invalid JSON: empty appfw message");
- return false;
- }
-
- return Message::fromJDoc(jdoc);
-}
+ MessageId id = MessageId::Invalid;
-bool Message::fromJDoc(QJsonDocument jdoc)
-{
// Validate message is array
- if (!jdoc.isArray()) {
+ if (!candidate.isArray()) {
qWarning("Invalid appfw message: not an array");
- return false;
+ return id;
}
- QJsonArray msg = jdoc.array();
+ QJsonArray msg = candidate.array();
// Validate array is proper length
if ((msg.size() < 3) || (msg.size() > 4)) {
qWarning("Invalid appfw message: invalid array size");
- return false;
+ return id;
}
// Validate msgid type
@@ -78,75 +44,36 @@ bool Message::fromJDoc(QJsonDocument jdoc)
msgid = msg[0].toDouble();
} else {
qWarning("Invalid appfw message: invalid msgid type");
- return false;
+ return id;
}
// Validate msgid element
- if ((msgid < Call) || (msgid > Event)) {
- qWarning("Invalid appfw message: msgid out of range");
- return false;
- }
-
- // Validate that the payload has a request object
- QJsonObject payload;
- if (msg[2].isObject()) {
- payload = msg[2].toObject();
- } else {
- qWarning("Invalid appfw payload: no JSON object");
- return false;
- }
-
- if ((msgid == RetOk) || (msgid == RetErr)) {
- auto request_iter = payload.find("request");
- auto request = request_iter.value().toObject();
- if (request.empty()) {
- qWarning("Invalid appfw reply message: empty request data");
- return false;
- }
- auto status_iter = request.find("status");
- auto info_iter = request.find("info");
- auto response_iter = payload.find("response");
- auto response = response_iter.value().toObject();
- m_reply_status = status_iter.value().toString();
- m_reply_info = info_iter.value().toString();
- m_reply_data = response;
- m_reply = true;
- } else if (msgid == Event) {
- // If event, save data object
- auto data_iter = payload.find("data");
- m_event_data = data_iter.value().toObject();
+ if ((msgid >= static_cast<double>(MessageId::Call)) && (msgid <= static_cast<double>(MessageId::Event)))
+ id = static_cast<MessageId>(msgid);
- auto event_iter = payload.find("event");
- auto event_string = event_iter.value().toString();
- if (event_string.isEmpty()) {
- qWarning("Invalid appfw event message: empty event name");
- return false;
- }
- QStringList event_strings = event_string.split(QRegExp("/"));
- if (event_strings.size() != 2) {
- qWarning("Invalid appfw event message: malformed event name");
- return false;
- }
- m_event_api = event_strings[0];
- m_event_name = event_strings[1];
- m_event = true;
- }
-
- m_jdoc = jdoc;
- m_init = true;
- return m_init;
+ return id;
}
-QByteArray Message::toJson(QJsonDocument::JsonFormat format)
+Message::Message()
+ : m_init(false)
{
- QJsonArray array;
- array.append(m_request["msgid"].toInt());
- array.append(m_request["callid"].toInt());
- array.append(m_request["api"].toString() + "/" + m_request["verb"].toString());
- array.append(m_request["parameter"].toJsonValue());
+}
- QJsonDocument jdoc;
- jdoc.setArray(array);
+QByteArray Message::serialize(QJsonDocument::JsonFormat format)
+{
+ QByteArray dummy;
+ return dummy;
+ }
- return jdoc.toJson(format).data();
+QByteArray Message::send(QWebSocket& transport, unsigned int id)
+{
+ QByteArray blob;
+ qint64 size = 0;
+ updateCallId(id);
+ if (m_init)
+ blob = serialize().data();
+ if (!blob.isEmpty())
+ size = transport.sendTextMessage(blob);
+
+ return blob;
}
diff --git a/message.h b/message.h
index 4270651..0b5ad64 100644
--- a/message.h
+++ b/message.h
@@ -23,103 +23,44 @@
#include <QJsonDocument>
#include <QJsonObject>
-enum MessageId {
+enum class MessageId {
+ Invalid = 0,
Call = 2,
RetOk = 3,
RetErr = 4,
Event = 5,
};
-enum class MessageType {
- GenericMessage,
- ResponseRequestMessage,
- TelephonyEventMessage,
- WeatherEventMessage,
- MediaplayerEventMessage,
- NetworkEventMessage,
- BluetoothEventMessage,
- PbapEventMessage,
- RadioEventMessage,
- MapEventMessage,
- NavigationEventMessage,
- VoiceEventMessage,
- SignalComposerEventMessage,
- GuiMetadataCapabilityEventMessage,
- HVACEventMessage,
-};
+class QWebSocket;
-class Message : public QObject
+class Message
{
- Q_OBJECT
- Q_ENUM(MessageId)
-
public:
Message();
+ void setAdditionalData(QByteArray data) {};
+ QByteArray send(QWebSocket& transport, unsigned int callid);
- bool fromJson(QByteArray jsonData);
- virtual bool fromJDoc(QJsonDocument jdocData);
- QByteArray toJson(QJsonDocument::JsonFormat format = QJsonDocument::Compact);
- bool createRequest(QString api, QString verb, QJsonValue parameter = "None");
- inline QString eventApi() const
- {
- return m_event_api;
- }
-
- inline QString eventName() const
- {
- return m_event_name;
- }
-
- inline QJsonObject eventData() const
+ inline bool isComplete() const
{
- return m_event_data;
- }
-
- inline QString replyStatus() const
- {
- return m_reply_status;
- }
-
- inline QString replyInfo() const
- {
- return m_reply_info;
- }
-
- inline QJsonObject replyData() const
- {
- return m_reply_data;
- }
-
- inline bool isEvent() const
- {
- return m_event;
- }
-
- inline bool isReply() const
- {
- return m_reply;
+ return m_init;
}
- inline bool isValid() const
+ virtual bool getCallId(unsigned int *id) const
{
- return m_init;
+ return false;
}
- inline void setCallId(qint32 callId) {
- m_request["callid"] = callId;
- }
+ static MessageId isValid(QJsonDocument );
- inline QMap<QString, QVariant> requestData() const
- {
- return m_request;
- }
+ virtual bool isEvent() = 0;
+ virtual bool isReply() = 0;
protected:
- bool m_event, m_init, m_reply;
- QString m_event_api, m_event_name, m_reply_info, m_reply_status, m_reply_uuid;
- QMap<QString, QVariant> m_request;
+ virtual void updateCallId(unsigned int id) {};
+ virtual QByteArray serialize(QJsonDocument::JsonFormat format = QJsonDocument::Compact);
+
+ bool m_init;
QJsonDocument m_jdoc;
- QJsonObject m_event_data, m_reply_data;
};
#endif // MESSAGE_H
diff --git a/messageengine.cpp b/messageengine.cpp
index 6f31d0f..2633545 100644
--- a/messageengine.cpp
+++ b/messageengine.cpp
@@ -14,24 +14,13 @@
* limitations under the License.
*/
+#include <QJsonArray>
+#include <QDebug>
+
#include "message.h"
+#include "messagefactory.h"
#include "messageengine.h"
-#include "bluetoothmessage.h"
-#include "guimetadatamessage.h"
-#include "hvacmessage.h"
-#include "mapmessage.h"
-#include "mediaplayermessage.h"
-#include "navigationmessage.h"
-#include "networkmessage.h"
-#include "pbapmessage.h"
-#include "radiomessage.h"
-#include "responsemessage.h"
-#include "signalcomposermessage.h"
-#include "telephonymessage.h"
-#include "weathermessage.h"
-#include "voicemessage.h"
-#include <QJsonArray>
MessageEngine::MessageEngine(const QUrl &url, QObject *parent) :
QObject(parent),
@@ -44,31 +33,17 @@ MessageEngine::MessageEngine(const QUrl &url, QObject *parent) :
m_websocket.open(url);
}
-unsigned int MessageEngine::requestCallId()
-{
- int callid;
-
- m_mutex.lock();
- callid = ++m_callid;
- m_mutex.unlock();
-
- return callid;
-}
-
-bool MessageEngine::sendMessage(Message *message)
+bool MessageEngine::sendMessage(std::unique_ptr<Message> msg)
{
- if (!message->isValid())
+ if (!msg)
return false;
- auto callid = requestCallId();
- message->setCallId(callid);
-
- QByteArray data = message->toJson().data();
- qint64 size = m_websocket.sendTextMessage(data);
- if (size == 0)
+ unsigned int callid = m_callid++;
+ QByteArray forkeeps = msg->send(m_websocket, callid);
+ if (forkeeps.isEmpty())
return false;
- m_calls.insert(callid, data);
+ m_calls.insert(callid, forkeeps);
return true;
}
@@ -94,83 +69,20 @@ void MessageEngine::onTextMessageReceived(QString jsonStr)
return;
}
- QJsonArray msg = jdoc.array();
- int msgid = msg[0].toInt();
+ MessageId id = Message::isValid(jdoc);
+ if (id == MessageId::Invalid) {
+ qWarning() << "Received unknown message, discarding";
+ return;
+ }
- Message *message;
- MessageType type;
+ std::shared_ptr<Message> message = MessageFactory::getInstance().createInboundMessage(id, jdoc);
- switch (msgid) {
- case RetOk:
- case RetErr: {
- auto callid = msg[1].toString().toInt();
- message = new ResponseMessage(m_calls[callid]);
- type = MessageType::ResponseRequestMessage;
+ unsigned int callid;
+ if (message->isReply() && message->getCallId(&callid)) {
+ message->setAdditionalData(m_calls[callid]);
m_calls.remove(callid);
- break;
- }
- case Event: {
- QStringList api_str_list = msg[1].toString().split(QRegExp("/"));
- QString api = api_str_list[0].toLower();
-
- // FIXME: This should be rewritten using a factory class with a
- // parser parameter to remove API specific handling here
- if (api == "bluetooth-manager") {
- message = new BluetoothMessage;
- type = MessageType::BluetoothEventMessage;
- } else if (api == "bluetooth-pbap") {
- message = new PbapMessage;
- type = MessageType::PbapEventMessage;
- } else if (api == "telephony") {
- message = new TelephonyMessage;
- type = MessageType::TelephonyEventMessage;
- } else if (api == "weather") {
- message = new WeatherMessage;
- type = MessageType::WeatherEventMessage;
- } else if (api == "mediaplayer") {
- message = new MediaplayerMessage;
- type = MessageType::MediaplayerEventMessage;
- } else if (api == "navigation") {
- message = new NavigationMessage;
- type = MessageType::NavigationEventMessage;
- } else if (api == "network-manager") {
- message = new NetworkMessage;
- type = MessageType::NetworkEventMessage;
- } else if (api == "radio") {
- message = new RadioMessage;
- type = MessageType::RadioEventMessage;
- } else if (api == "bluetooth-map") {
- message = new MapMessage;
- type = MessageType::MapEventMessage;
- } else if (api == "vshl-core" ) {
- message = new VoiceMessage;
- type = MessageType::VoiceEventMessage;
- } else if (api == "vshl-capabilities" ) {
- // NOTE: Will need to look at event name to differentiate
- // capabilities if more support (e.g. navigation or
- // local media control) is added.
- message = new GuiMetadataCapabilityMessage;
- type = MessageType::GuiMetadataCapabilityEventMessage;
- } else if (api == "signal-composer") {
- message = new SignalComposerMessage;
- type = MessageType::SignalComposerEventMessage;
- } else if (api == "hvac") {
- message = new HVACMessage;
- type = MessageType::HVACEventMessage;
- } else {
- message = new Message;
- type = MessageType::GenericMessage;
- }
- break;
- }
- default:
- break;
- }
-
- if (message->fromJDoc(jdoc) == false) {
- delete message;
- return;
}
- emit messageReceived(type, message);
+ if (message->isComplete())
+ emit messageReceived(message);
}
diff --git a/messageengine.h b/messageengine.h
index 6b2233f..b682ec5 100644
--- a/messageengine.h
+++ b/messageengine.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Konsulko Group
+ * Copyright (C) 2017-2020 Konsulko Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,8 +17,8 @@
#ifndef MESSAGEENGINE_H
#define MESSAGEENGINE_H
-#include <QMutex>
-#include <QThread>
+#include <memory>
+#include <atomic>
#include <QUrl>
#include <QWebSocket>
@@ -29,13 +29,12 @@ class MessageEngine : public QObject
Q_OBJECT
public:
explicit MessageEngine(const QUrl &url, QObject *parent = Q_NULLPTR);
- bool sendMessage(Message *message);
- unsigned int requestCallId();
+ bool sendMessage(std::unique_ptr<Message> message);
Q_SIGNALS:
void disconnected();
void connected();
- void messageReceived(MessageType type, Message *message);
+ void messageReceived(std::shared_ptr<Message> message);
private Q_SLOTS:
void onConnected();
@@ -46,8 +45,7 @@ class MessageEngine : public QObject
QWebSocket m_websocket;
QMap<qint32, QByteArray> m_calls;
QUrl m_url;
- QMutex m_mutex;
- unsigned int m_callid;
+ std::atomic<unsigned int> m_callid;
};
#endif // MESSAGEENGINE_H
diff --git a/messagefactory.cpp b/messagefactory.cpp
new file mode 100644
index 0000000..6740e25
--- /dev/null
+++ b/messagefactory.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messagefactory.h"
+#include "message.h"
+#include "responsemessage.h"
+#include "eventmessage.h"
+#include "callmessage.h"
+
+std::unique_ptr<Message> MessageFactory::createInboundMessage(MessageId id, QJsonDocument data)
+{
+ std::unique_ptr<Message> msg(nullptr);
+ if ((id == MessageId::RetOk) || (id == MessageId::RetErr))
+ msg.reset(new ResponseMessage(data));
+ else if (id == MessageId::Event)
+ msg.reset(new EventMessage(data));
+ return msg;
+}
+
+std::unique_ptr<Message> MessageFactory::createOutboundMessage(MessageId id)
+{
+ std::unique_ptr<Message> msg(nullptr);
+ if (id == MessageId::Call)
+ msg.reset(new CallMessage());
+ return msg;
+}
diff --git a/messagefactory.h b/messagefactory.h
new file mode 100644
index 0000000..f826483
--- /dev/null
+++ b/messagefactory.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MESSAGEFACTORY_H
+#define MESSAGEFACTORY_H
+
+#include <memory>
+#include <QJsonDocument>
+
+class Message;
+enum class MessageId;
+
+class MessageFactory {
+ public:
+ static MessageFactory& getInstance() {
+ static MessageFactory instance;
+ return instance;
+ }
+ std::unique_ptr<Message> createInboundMessage(MessageId id, QJsonDocument content);
+ std::unique_ptr<Message> createOutboundMessage(MessageId);
+ MessageFactory(MessageFactory const&) = delete;
+ void operator=(MessageFactory const&) = delete;
+
+ private:
+ MessageFactory() = default;
+ ~MessageFactory() = default;
+};
+
+#endif // MESSAGEFACTORY_H
diff --git a/navigation/CMakeLists.txt b/navigation/CMakeLists.txt
index 9bea511..ec76041 100644
--- a/navigation/CMakeLists.txt
+++ b/navigation/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(navigation.h navigationmessage.h)
-add_sources(navigation.cpp navigationmessage.cpp)
+add_headers(navigation.h)
+add_sources(navigation.cpp)
diff --git a/navigation/navigation.cpp b/navigation/navigation.cpp
index ce6b91d..e0078c2 100644
--- a/navigation/navigation.cpp
+++ b/navigation/navigation.cpp
@@ -16,9 +16,9 @@
#include <QDebug>
-#include "message.h"
-#include "navigationmessage.h"
-#include "responsemessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "navigation.h"
@@ -40,21 +40,28 @@ Navigation::~Navigation()
void Navigation::sendWaypoint(double lat, double lon)
{
- NavigationMessage *nmsg = new NavigationMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter, point;
QJsonArray points;
point.insert("latitude", lat);
point.insert("longitude", lon);
points.append(point);
parameter.insert("points", points);
- nmsg->createRequest("broadcast_waypoints", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("navigation", "broadcast_waypoints", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Navigation::broadcastPosition(double lat, double lon, double drc, double dst)
{
- NavigationMessage *nmsg = new NavigationMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("position", "car");
@@ -63,14 +70,17 @@ void Navigation::broadcastPosition(double lat, double lon, double drc, double ds
parameter.insert("direction", drc);
parameter.insert("distance", dst);
- nmsg->createRequest("broadcast_position", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("navigation", "broadcast_position", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Navigation::broadcastRouteInfo(double lat, double lon, double route_lat, double route_lon)
{
- NavigationMessage *nmsg = new NavigationMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("position", "route");
@@ -79,66 +89,75 @@ void Navigation::broadcastRouteInfo(double lat, double lon, double route_lat, do
parameter.insert("route_latitude", route_lat);
parameter.insert("route_longitude", route_lon);
- nmsg->createRequest("broadcast_position", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("navigation", "broadcast_position", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Navigation::broadcastStatus(QString state)
{
- NavigationMessage *nmsg = new NavigationMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("state", state);
- nmsg->createRequest("broadcast_status", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("navigation", "broadcast_status", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Navigation::onConnected()
{
QStringListIterator eventIterator(events);
- NavigationMessage *nmsg;
while (eventIterator.hasNext()) {
- nmsg = new NavigationMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- nmsg->createRequest("subscribe", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("navigation", "subscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
}
void Navigation::onDisconnected()
{
QStringListIterator eventIterator(events);
- NavigationMessage *nmsg;
while (eventIterator.hasNext()) {
- nmsg = new NavigationMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- nmsg->createRequest("unsubscribe", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("navigation", "unsubscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
}
-void Navigation::onMessageReceived(MessageType type, Message *msg)
+void Navigation::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (type == MessageType::NavigationEventMessage) {
- NavigationMessage *tmsg = qobject_cast<NavigationMessage*>(msg);
+ if (!msg)
+ return;
- if (tmsg->isPositionEvent()) {
- emit positionEvent(tmsg->eventData().toVariantMap());
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ if (emsg->eventApi() != "navigation")
+ return;
+
+ if (emsg->eventName() == "position") {
+ emit positionEvent(emsg->eventData().toVariantMap());
}
- if (tmsg->isStatusEvent()) {
- emit statusEvent(tmsg->eventData().toVariantMap());
+ else if (emsg->eventName() == "status") {
+ emit statusEvent(emsg->eventData().toVariantMap());
}
- if (tmsg->isWaypointsEvent()) {
- emit waypointsEvent(tmsg->eventData().toVariantMap());
+ else if (emsg->eventName() == "waypoints") {
+ emit waypointsEvent(emsg->eventData().toVariantMap());
}
}
-
- msg->deleteLater();
}
diff --git a/navigation/navigation.h b/navigation/navigation.h
index c407d0f..87e5636 100644
--- a/navigation/navigation.h
+++ b/navigation/navigation.h
@@ -17,6 +17,7 @@
#ifndef NAVIGATION_H
#define NAVIGATION_H
+#include <memory>
#include <QObject>
#include <QJsonArray>
#include <QtQml/QQmlListProperty>
@@ -24,8 +25,6 @@
class MessageEngine;
class Message;
-enum class MessageType;
-
class Navigation : public QObject
{
Q_OBJECT
@@ -50,7 +49,7 @@ class Navigation : public QObject
MessageEngine *m_mloop;
// slots
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message> msg);
void onConnected();
void onDisconnected();
diff --git a/network/CMakeLists.txt b/network/CMakeLists.txt
index e6d93bd..fcf21ac 100644
--- a/network/CMakeLists.txt
+++ b/network/CMakeLists.txt
@@ -1,8 +1,8 @@
-add_headers(network.h networkmessage.h
+add_headers(network.h
networkadapter.h wifiadapter.h wiredadapter.h
wifinetworkmodel.h wirednetworkmodel.h abstractnetworkmodel.h
connectionprofile.h)
-add_sources(network.cpp networkmessage.cpp
+add_sources(network.cpp
wifiadapter.cpp wiredadapter.cpp
wifinetworkmodel.cpp wirednetworkmodel.cpp abstractnetworkmodel.cpp
connectionprofile.cpp)
diff --git a/network/network.cpp b/network/network.cpp
index b858206..2472279 100644
--- a/network/network.cpp
+++ b/network/network.cpp
@@ -17,9 +17,10 @@
#include <QDebug>
#include <QtQml/QQmlEngine>
-#include "message.h"
-#include "networkmessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
#include "responsemessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "networkadapter.h"
#include "network.h"
@@ -48,38 +49,47 @@ Network::~Network()
void Network::connect(QString service)
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("service", service);
- nmsg->createRequest("connect_service", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "connect_service", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Network::disconnect(QString service)
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("service", service);
- nmsg->createRequest("disconnect_service", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "disconnect_service", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Network::remove(QString service)
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("service", service);
- nmsg->createRequest("remove_service", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "remove_service", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Network::power(bool on, QString type)
@@ -92,21 +102,28 @@ void Network::power(bool on, QString type)
void Network::input(int id, QString passphrase)
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter, fields;
parameter.insert("id", id);
fields.insert("passphrase", passphrase);
parameter.insert("fields", fields);
- nmsg->createRequest("agent_response", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "agent_response", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Network::configureAddress(QString service, QVariantList paramlist)
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter, type, properties;
QJsonArray values = QJsonArray::fromVariantList(paramlist);
@@ -123,14 +140,17 @@ void Network::configureAddress(QString service, QVariantList paramlist)
parameter.insert("properties", type);
parameter.insert("service", service);
- nmsg->createRequest("set_property", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "set_property", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Network::configureNameServer(QString service, QVariantList paramlist)
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter, properties;
QJsonArray values = QJsonArray::fromVariantList(paramlist);
@@ -146,19 +166,21 @@ void Network::configureNameServer(QString service, QVariantList paramlist)
parameter.insert("properties", properties);
parameter.insert("service", service);
- nmsg->createRequest("set_property", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "set_property", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Network::getServices()
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
- nmsg->createRequest("services", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "services", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
AdapterIf* Network::findAdapter(QString type)
@@ -208,38 +230,44 @@ void Network::addServices(QJsonArray services)
void Network::scanServices(QString type)
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("technology", type);
- nmsg->createRequest("scan_services", parameter);
- m_mloop->sendMessage(nmsg);
-
- delete nmsg;
+ nmsg->createRequest("network-manager", "scan_services", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Network::disableTechnology(QString type)
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("technology", type);
- nmsg->createRequest("disable_technology", parameter);
- m_mloop->sendMessage(nmsg);
-
- delete nmsg;
+ nmsg->createRequest("network-manager", "disable_technology", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Network::enableTechnology(QString type)
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("technology", type);
- nmsg->createRequest("enable_technology", parameter);
- m_mloop->sendMessage(nmsg);
-
- delete nmsg;
+ nmsg->createRequest("network-manager", "enable_technology", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Network::parseTechnologies(QJsonArray technologies)
@@ -257,28 +285,38 @@ void Network::parseTechnologies(QJsonArray technologies)
void Network::getTechnologies()
{
- NetworkMessage *nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
- nmsg->createRequest("technologies", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "technologies", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
-void Network::processEvent(NetworkMessage *nmsg)
+void Network::processEvent(std::shared_ptr<Message> msg)
{
- if (nmsg->eventName() == "agent") {
- QJsonObject agent = nmsg->eventData();
- QJsonObject fields = agent.value("fields").toObject();
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ QString ename = emsg->eventName();
+ QString eapi = emsg->eventApi();
+ QJsonObject data = emsg->eventData();
+
+ if (eapi != "network-manager")
+ return;
+
+ if (ename == "agent") {
+ QJsonObject fields = data.value("fields").toObject();
QJsonObject passphrase = fields.value("passphrase").toObject();
QString type = passphrase.value("type").toString();
QString reqmt = passphrase.value("requirement").toString();
if (((type == "psk") || (type == "wep")) && (reqmt == "mandatory")) {
- int id = agent.value("id").toInt();
+ int id = data.value("id").toInt();
emit inputRequest(id);
}
- } else if (nmsg->eventName() == "services") {
- QJsonArray services = nmsg->eventData().value("values").toArray();
+ } else if (ename == "services") {
+ QJsonArray services = data.value("values").toArray();
for (auto value : services) {
QJsonObject service = value.toObject();
QString action = service.value("action").toString();
@@ -288,54 +326,59 @@ void Network::processEvent(NetworkMessage *nmsg)
removeService(service);
}
}
- } else if (nmsg->eventName() == "service_properties") {
- updateServiceProperties(nmsg->eventData());
- } else if (nmsg->eventName() == "technology_properties") {
- QJsonObject technology = nmsg->eventData();
- QJsonObject properties = technology.value("properties").toObject();
- QString type = technology.value("technology").toString();
+ } else if (ename == "service_properties") {
+ updateServiceProperties(data);
+ } else if (ename == "technology_properties") {
+ QJsonObject properties = data.value("properties").toObject();
+ QString type = data.value("technology").toString();
AdapterIf* adapter = findAdapter(type);
if (adapter)
adapter->updateStatus(properties);
}
}
-void Network::processReply(ResponseMessage *rmsg)
+void Network::processReply(std::shared_ptr<Message> msg)
{
- if (rmsg->requestVerb() == "services") {
- addServices(rmsg->replyData().value("values").toArray());
- } else if (rmsg->requestVerb() == "technologies") {
- parseTechnologies(rmsg->replyData().value("values").toArray());
- } else if (rmsg->requestVerb() == "connect_service") {
+ std::shared_ptr<ResponseMessage> rmsg = std::static_pointer_cast<ResponseMessage>(msg);
+ QString verb = rmsg->requestVerb();
+ QJsonObject data = rmsg->replyData();
+
+ if (verb == "services") {
+ addServices(data.value("values").toArray());
+ } else if (verb == "technologies") {
+ parseTechnologies(data.value("values").toArray());
+ } else if (verb == "connect_service") {
if (rmsg->replyStatus() == "failed" && rmsg->replyInfo().contains("invalid-key")) {
- emit invalidPassphrase(rmsg->requestData()["parameter"].toMap()["service"].toString());
+ emit invalidPassphrase(rmsg->requestParameters()["service"].toString());
}
}
}
-void Network::onMessageReceived(MessageType type, Message *msg)
+void Network::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (msg->isEvent() && (type == MessageType::NetworkEventMessage)) {
- processEvent(qobject_cast<NetworkMessage*>(msg));
- } else if (msg->isReply() && (type == MessageType::ResponseRequestMessage)) {
- processReply(qobject_cast<ResponseMessage*>(msg));
- }
+ if (!msg)
+ return;
- msg->deleteLater();
+ if (msg->isEvent())
+ processEvent(msg);
+ else if (msg->isReply())
+ processReply(msg);
}
void Network::onConnected()
{
QStringListIterator eventIterator(events);
- NetworkMessage *nmsg;
while (eventIterator.hasNext()) {
- nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- nmsg->createRequest("subscribe", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "subscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
getTechnologies();
@@ -344,15 +387,16 @@ void Network::onConnected()
void Network::onDisconnected()
{
QStringListIterator eventIterator(events);
- NetworkMessage *nmsg;
while (eventIterator.hasNext()) {
- nmsg = new NetworkMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+ CallMessage *nmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- nmsg->createRequest("unsubscribe", parameter);
- m_mloop->sendMessage(nmsg);
- delete nmsg;
+ nmsg->createRequest("network-manager", "unsubscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
getTechnologies();
diff --git a/network/network.h b/network/network.h
index ebaeb6e..b40b432 100644
--- a/network/network.h
+++ b/network/network.h
@@ -17,6 +17,7 @@
#ifndef NETWORK_H
#define NETWORK_H
+#include <memory>
#include <QObject>
#include <QJsonArray>
#include <QtQml/QQmlContext>
@@ -27,10 +28,6 @@
class MessageEngine;
class Message;
-class NetworkMessage;
-class ResponseMessage;
-
-enum class MessageType;
class Network : public QObject
{
@@ -72,11 +69,11 @@ class Network : public QObject
void enableTechnology(QString type);
void parseTechnologies(QJsonArray technologies);
void getTechnologies();
- void processEvent(NetworkMessage *nmsg);
- void processReply(ResponseMessage *rmsg);
+ void processEvent(std::shared_ptr<Message> msg);
+ void processReply(std::shared_ptr<Message> msg);
// slots
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
void onConnected();
void onDisconnected();
diff --git a/pbap/CMakeLists.txt b/pbap/CMakeLists.txt
index 99edd7d..441280f 100644
--- a/pbap/CMakeLists.txt
+++ b/pbap/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(pbap.h pbapmessage.h)
-add_sources(pbap.cpp pbapmessage.cpp)
+add_headers(pbap.h)
+add_sources(pbap.cpp)
diff --git a/pbap/pbap.cpp b/pbap/pbap.cpp
index 7b7829f..a0b84f4 100644
--- a/pbap/pbap.cpp
+++ b/pbap/pbap.cpp
@@ -19,9 +19,10 @@
#include <QMimeDatabase>
#include <QtQml/QQmlEngine>
-#include "message.h"
-#include "pbapmessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
#include "responsemessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "pbap.h"
@@ -102,50 +103,62 @@ Pbap::~Pbap()
void Pbap::importContacts(int max_entries)
{
- PbapMessage *tmsg = new PbapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* pmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
- tmsg->createRequest("import", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ pmsg->createRequest("bluetooth-pbap", "import", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Pbap::refreshContacts(int max_entries)
{
- PbapMessage *tmsg = new PbapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* pmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
- tmsg->createRequest("contacts", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ pmsg->createRequest("bluetooth-pbap", "contacts", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Pbap::refreshCalls(int max_entries)
{
- PbapMessage *tmsg = new PbapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* pmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("list", "cch");
if (max_entries >= 0)
parameter.insert("max_entries", max_entries);
- tmsg->createRequest("history", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ pmsg->createRequest("bluetooth-pbap", "history", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Pbap::search(QString number)
{
- PbapMessage *tmsg = new PbapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* pmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
if (!number.isEmpty())
parameter.insert("number", number);
parameter.insert("max_entries", 1);
- tmsg->createRequest("search", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ pmsg->createRequest("bluetooth-pbap", "search", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
bool compareContactPtr(QObject *a, QObject *b)
@@ -253,55 +266,71 @@ void Pbap::sendSearchResults(QJsonArray results)
void Pbap::onConnected()
{
QStringListIterator eventIterator(events);
- PbapMessage *tmsg;
while (eventIterator.hasNext()) {
- tmsg = new PbapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* pmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- tmsg->createRequest("subscribe", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ pmsg->createRequest("bluetooth-pbap", "subscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
}
void Pbap::onDisconnected()
{
QStringListIterator eventIterator(events);
- PbapMessage *tmsg;
while (eventIterator.hasNext()) {
- tmsg = new PbapMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* pmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- tmsg->createRequest("unsubscribe", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ pmsg->createRequest("bluetooth-pbap", "unsubscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
}
-void Pbap::onMessageReceived(MessageType type, Message *msg)
+void Pbap::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (msg->isEvent() && type == MessageType::PbapEventMessage) {
- PbapMessage *tmsg = qobject_cast<PbapMessage*>(msg);
-
- if (tmsg->isStatusEvent()) {
- emit statusChanged(tmsg->connected());
- if (tmsg->connected() == true) {
+ if (!msg)
+ return;
+
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ QString ename = emsg->eventName();
+ QString eapi = emsg->eventApi();
+ QVariantMap data = emsg->eventData().toVariantMap();
+
+ if (eapi != "pbap")
+ return;
+
+ bool connected = data.find("connected").value().toBool();
+ if (ename == "status") {
+ emit statusChanged(connected);
+ if (connected)
refreshContacts(-1);
}
- }
- } else if (msg->isReply() && type == MessageType::ResponseRequestMessage) {
- ResponseMessage *tmsg = qobject_cast<ResponseMessage*>(msg);
-
- if (tmsg->requestVerb() == "contacts" || tmsg->requestVerb() == "import") {
- updateContacts(tmsg->replyData().value("vcards").toArray());
- } else if (tmsg->requestVerb() == "history") {
- updateCalls(tmsg->replyData().value("vcards").toArray());
- } else if (tmsg->requestVerb() == "search") {
- sendSearchResults(tmsg->replyData().value("results").toArray());
+ } else if (msg->isReply()) {
+ std::shared_ptr<ResponseMessage> rmsg = std::static_pointer_cast<ResponseMessage>(msg);
+ QString api = rmsg->requestApi();
+ if (api != "pbap")
+ return;
+
+ QString verb = rmsg->requestVerb();
+ QJsonObject data = rmsg->replyData();
+ if (verb == "contacts" || verb == "import") {
+ updateContacts(data.value("vcards").toArray());
+ } else if (verb == "history") {
+ updateCalls(data.value("vcards").toArray());
+ } else if (verb == "search") {
+ sendSearchResults(data.value("results").toArray());
}
}
-
- msg->deleteLater();
}
diff --git a/pbap/pbap.h b/pbap/pbap.h
index a89bf2b..4deb9c6 100644
--- a/pbap/pbap.h
+++ b/pbap/pbap.h
@@ -17,6 +17,7 @@
#ifndef PBAP_H
#define PBAP_H
+#include <memory>
#include <QObject>
#include <QJsonArray>
#include <QtQml/QQmlContext>
@@ -25,8 +26,6 @@
class MessageEngine;
class Message;
-enum class MessageType;
-
class PhoneNumber : public QObject
{
Q_OBJECT
@@ -169,7 +168,7 @@ class Pbap : public QObject
// slots
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
const QStringList events {
"status",
diff --git a/radio/CMakeLists.txt b/radio/CMakeLists.txt
index 46ac12b..a6b8db4 100644
--- a/radio/CMakeLists.txt
+++ b/radio/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(radio.h radiomessage.h)
-add_sources(radio.cpp radiomessage.cpp)
+add_headers(radio.h)
+add_sources(radio.cpp)
diff --git a/radio/radio.cpp b/radio/radio.cpp
index 1627cd7..b7c407c 100644
--- a/radio/radio.cpp
+++ b/radio/radio.cpp
@@ -16,9 +16,10 @@
#include <QDebug>
-#include "message.h"
-#include "radiomessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
#include "responsemessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "radio.h"
@@ -48,18 +49,25 @@ Radio::~Radio()
void Radio::setBand(int band)
{
- RadioMessage *rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("band", band ? "FM": "AM");
- rmsg->createRequest("band", parameter);
- m_mloop->sendMessage(rmsg);
- delete rmsg;
+ rmsg->createRequest("radio", "band", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Radio::setFrequency(int frequency)
{
- RadioMessage *rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
if (m_scanning)
@@ -69,9 +77,8 @@ void Radio::setFrequency(int frequency)
return;
parameter.insert("value", QString::number(frequency));
- rmsg->createRequest("frequency", parameter);
- m_mloop->sendMessage(rmsg);
- delete rmsg;
+ rmsg->createRequest("radio", "frequency", parameter);
+ m_mloop->sendMessage(std::move(msg));
// To improve UI responsiveness, signal the change here immediately
// This fixes visual glitchiness in the slider caused by the frequency
@@ -86,22 +93,27 @@ void Radio::setFrequency(int frequency)
void Radio::start()
{
- RadioMessage *rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
- rmsg->createRequest("start", parameter);
- m_mloop->sendMessage(rmsg);
- delete rmsg;
+ rmsg->createRequest("radio", "start", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Radio::stop()
{
- RadioMessage *rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
- rmsg->createRequest("stop", parameter);
- m_mloop->sendMessage(rmsg);
- delete rmsg;
+ rmsg->createRequest("radio", "stop", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void Radio::scanForward()
@@ -109,16 +121,15 @@ void Radio::scanForward()
if (m_scanning)
return;
- RadioMessage *rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("direction", "forward");
- rmsg->createRequest("scan_start", parameter);
- m_mloop->sendMessage(rmsg);
+ rmsg->createRequest("radio", "scan_start", parameter);
+ m_mloop->sendMessage(std::move(msg));
m_scanning = true;
emit scanningChanged(m_scanning);
-
- delete rmsg;
}
void Radio::scanBackward()
@@ -126,60 +137,70 @@ void Radio::scanBackward()
if (m_scanning)
return;
- RadioMessage *rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("direction", "backward");
- rmsg->createRequest("scan_start", parameter);
- m_mloop->sendMessage(rmsg);
+ rmsg->createRequest("radio", "scan_start", parameter);
+ m_mloop->sendMessage(std::move(msg));
m_scanning = true;
emit scanningChanged(m_scanning);
-
- delete rmsg;
}
void Radio::scanStop()
{
- RadioMessage *rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
- rmsg->createRequest("scan_stop", parameter);
- m_mloop->sendMessage(rmsg);
+ rmsg->createRequest("radio", "scan_stop", parameter);
+ m_mloop->sendMessage(std::move(msg));
m_scanning = false;
emit scanningChanged(m_scanning);
-
- delete rmsg;
}
void Radio::updateFrequencyBandParameters()
{
- RadioMessage *rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("band", m_band ? "FM" : "AM");
- rmsg->createRequest("frequency_range", parameter);
- m_mloop->sendMessage(rmsg);
- delete rmsg;
-
- rmsg = new RadioMessage();
- rmsg->createRequest("frequency_step", parameter);
- m_mloop->sendMessage(rmsg);
- delete rmsg;
+ rmsg->createRequest("radio", "frequency_range", parameter);
+ m_mloop->sendMessage(std::move(msg));
+
+ std::unique_ptr<Message> msg2 = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg2)
+ return;
+
+ rmsg = static_cast<CallMessage*>(msg2.get());
+ rmsg->createRequest("radio", "frequency_step", parameter);
+ m_mloop->sendMessage(std::move(msg2));
}
void Radio::onConnected()
{
QStringListIterator eventIterator(events);
- RadioMessage *rmsg;
while (eventIterator.hasNext()) {
- rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- rmsg->createRequest("subscribe", parameter);
- m_mloop->sendMessage(rmsg);
- delete rmsg;
+ rmsg->createRequest("radio", "subscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
// Trigger initial update of frequency band parameters (min/max/step)
@@ -189,51 +210,63 @@ void Radio::onConnected()
void Radio::onDisconnected()
{
QStringListIterator eventIterator(events);
- RadioMessage *rmsg;
while (eventIterator.hasNext()) {
- rmsg = new RadioMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("value", eventIterator.next());
- rmsg->createRequest("unsubscribe", parameter);
- m_mloop->sendMessage(rmsg);
- delete rmsg;
+ rmsg->createRequest("radio", "unsubscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
}
-void Radio::onMessageReceived(MessageType type, Message *msg)
+void Radio::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (msg->isEvent() && type == MessageType::RadioEventMessage) {
- RadioMessage *rmsg = qobject_cast<RadioMessage*>(msg);
+ if (!msg)
+ return;
- if (rmsg->isFrequencyEvent()) {
- unsigned int frequency = rmsg->eventData().value("value").toInt();
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ QString ename = emsg->eventName();
+ QString eapi = emsg->eventApi();
+ QJsonObject data = emsg->eventData();
+ if (ename == "frequency") {
+ unsigned int frequency = data.value("value").toInt();
m_frequency = frequency;
if (!m_scanning && (m_frequency != frequency)) {
emit frequencyChanged(m_frequency);
}
- } else if (rmsg->isStationFoundEvent()) {
+ } else if (ename == "station_found") {
m_scanning = false;
emit scanningChanged(m_scanning);
- m_frequency = rmsg->eventData().value("value").toInt();
+ m_frequency = data.value("value").toInt();
emit frequencyChanged(m_frequency);
- } else if (rmsg->isStatusEvent()) {
- if (rmsg->eventData().value("value") == QString("playing")) {
+ } else if (ename == "status") {
+ if (data.value("value") == QString("playing")) {
m_playing = true;
emit playingChanged(m_playing);
- } else if (rmsg->eventData().value("value") == QString("stopped")) {
+ } else if (data.value("value") == QString("stopped")) {
m_playing = false;
emit playingChanged(m_playing);
}
}
- } else if (msg->isReply() && type == MessageType::ResponseRequestMessage) {
- ResponseMessage *rmsg = qobject_cast<ResponseMessage*>(msg);
-
- if (rmsg->requestVerb() == "frequency_range") {
- m_minFrequency = rmsg->replyData().value("min").toInt();
+ } else if (msg->isReply()) {
+ std::shared_ptr<ResponseMessage> rmsg = std::static_pointer_cast<ResponseMessage>(msg);
+ QString api = rmsg->requestApi();
+ if (api != "radio")
+ return;
+
+ QString verb = rmsg->requestVerb();
+ QJsonObject data = rmsg->replyData();
+ if (verb == "frequency_range") {
+ m_minFrequency = data.value("min").toInt();
emit minFrequencyChanged(m_minFrequency);
- m_maxFrequency = rmsg->replyData().value("max").toInt();
+ m_maxFrequency = data.value("max").toInt();
emit maxFrequencyChanged(m_maxFrequency);
// Handle start up
@@ -241,10 +274,9 @@ void Radio::onMessageReceived(MessageType type, Message *msg)
m_frequency = m_minFrequency;
emit frequencyChanged(m_frequency);
}
- } else if (rmsg->requestVerb() == "frequency_step") {
- m_frequencyStep = rmsg->replyData().value("step").toInt();
+ } else if (verb == "frequency_step") {
+ m_frequencyStep = data.value("step").toInt();
emit frequencyStepChanged(m_frequencyStep);
}
}
- msg->deleteLater();
}
diff --git a/radio/radio.h b/radio/radio.h
index 9e72a5a..77b78d2 100644
--- a/radio/radio.h
+++ b/radio/radio.h
@@ -17,13 +17,13 @@
#ifndef RADIO_H
#define RADIO_H
+#include <memory>
#include <QObject>
#include <QtQml/QQmlContext>
class MessageEngine;
class Message;
-enum class MessageType;
class Radio : public QObject
{
@@ -90,7 +90,7 @@ class Radio : public QObject
void updateFrequencyBandParameters();
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType type, Message *msg);
+ void onMessageReceived(std::shared_ptr<Message> msg);
const QStringList events {
"frequency",
diff --git a/responsemessage.cpp b/responsemessage.cpp
index 0e2ad5a..96dab97 100644
--- a/responsemessage.cpp
+++ b/responsemessage.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Konsulko Group
+ * Copyright (C) 2018-2020 Konsulko Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,28 +22,105 @@
#include "responsemessage.h"
+//deprecated method call new constructor and setAdditionalData() instead:
ResponseMessage::ResponseMessage(QByteArray request)
{
- QJsonDocument jdoc(QJsonDocument::fromJson(request));
+ QJsonDocument jdoc(QJsonDocument::fromJson(request));
- if (!jdoc.isArray()) {
- qWarning("Invalid appfw message: not an array");
- return;
- }
+ if (!jdoc.isArray()) {
+ qWarning("Invalid appfw message: not an array");
+ return;
+ }
- QJsonArray msg = jdoc.array();
+ QJsonArray msg = jdoc.array();
- if (msg.size() != 4) {
- qWarning("Invalid appfw message: invalid array size");
- return;
- }
+ if (msg.size() != 4) {
+ qWarning("Invalid appfw message: invalid array size");
+ return;
+ }
- QStringList api_str_list = msg[2].toString().split(QRegExp("/"));
+ QStringList api_str_list = msg[2].toString().split(QRegExp("/"));
- m_request["msgid"] = msg.at(0);
- m_request["callid"] = msg.at(1);
- m_request["api"] = api_str_list[0];
- m_request["verb"] = api_str_list[1];
- m_request["parameter"] = msg.at(3);
+ m_request["msgid"] = msg.at(0);
+ m_request["callid"] = msg.at(1);
+ m_request["api"] = api_str_list[0];
+ m_request["verb"] = api_str_list[1];
+ m_request["parameter"] = msg.at(3);
+}
+
+ResponseMessage::ResponseMessage(QJsonDocument content)
+{
+ QJsonArray msg = content.array();
+ if (!msg[2].isObject()) {
+ qWarning("Invalid appfw payload: no JSON object");
+ return;
+ }
+
+ //deserialize:
+ auto callid = msg[1].toString().toInt();
+ QJsonObject payload = msg[2].toObject();
+
+ auto request_iter = payload.find("request");
+ auto request = request_iter.value().toObject();
+ if (request.empty()) {
+ qWarning("Invalid appfw reply message: empty request data");
+ return;
+ }
+
+ auto status_iter = request.find("status");
+ auto info_iter = request.find("info");
+ auto response_iter = payload.find("response");
+ auto response = response_iter.value().toObject();
+ m_reply_status = status_iter.value().toString();
+ m_reply_info = info_iter.value().toString();
+ m_reply_data = response;
+ m_reply_callid = callid;
+ m_init = false; //not complete yet, missing matching request data
+}
+
+bool ResponseMessage::setAdditionalData(QByteArray data)
+{
+ QJsonDocument jdoc(QJsonDocument::fromJson(data));
+ if (!jdoc.isArray()) {
+ qWarning("Invalid data: not an array");
+ return false;
+ }
+
+ QJsonArray content = jdoc.array();
+ if (content.size() != 4) {
+ qWarning("Invalid data: invalid array size");
+ return false;
+ }
+
+ QStringList api_str_list = content[2].toString().split(QRegExp("/"));
+ m_request["msgid"] = content.at(0);
+ m_request["callid"] = content.at(1);
+ m_request["api"] = api_str_list[0];
+ m_request["verb"] = api_str_list[1];
+ m_request["parameter"] = content.at(3);
+ m_init = true;
+ return true;
+}
+
+bool ResponseMessage::copyCallId(unsigned int *id)
+{
+ *id = m_reply_callid;
+ return true;
+}
+
+QByteArray ResponseMessage::serialize(QJsonDocument::JsonFormat format)
+{
+ QJsonArray array;
+ (m_reply_status == "failed")?
+ array.append(static_cast<int>(MessageId::RetErr)) :
+ array.append(static_cast<int>(MessageId::RetOk));
+ array.append(static_cast<int>(m_reply_callid));
+ array.append(m_request["api"].toString() + "/" + m_request["verb"].toString());
+ array.append(m_reply_data);
+
+ QJsonDocument jdoc;
+ jdoc.setArray(array);
+
+ return jdoc.toJson(format).data();
}
diff --git a/responsemessage.h b/responsemessage.h
index dd85150..edad3b1 100644
--- a/responsemessage.h
+++ b/responsemessage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Konsulko Group
+ * Copyright (C) 2018-2020 Konsulko Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,26 +17,69 @@
#ifndef RESPONSEMESSAGE_H
#define RESPONSEMESSAGE_H
-#include <QObject>
#include "message.h"
class ResponseMessage : public Message
{
- Q_OBJECT
- public:
- explicit ResponseMessage(QByteArray request = nullptr);
- inline QString requestVerb() const
- {
- return m_request["verb"].toString();
- }
+ public:
+ //deprecated:
+ explicit ResponseMessage(QByteArray request = nullptr);
- inline QVariantMap requestParameters() const
- {
- return m_request["parameter"].toMap();
- }
+ explicit ResponseMessage(QJsonDocument data);
+
+ inline QString requestApi() const
+ {
+ return m_request["api"].toString();
+ }
+
+ inline QString requestVerb() const
+ {
+ return m_request["verb"].toString();
+ }
+
+ inline QVariantMap requestParameters() const
+ {
+ return m_request["parameter"].toMap();
+ }
+
+ inline QString replyStatus() const
+ {
+ return m_reply_status;
+ }
+
+ inline QString replyInfo() const
+ {
+ return m_reply_info;
+ }
+
+ inline QJsonObject replyData() const
+ {
+ return m_reply_data;
+ }
+
+ bool isEvent() override
+ {
+ return false;
+ }
+
+ bool isReply() override
+ {
+ return true;
+ }
+
+ bool setAdditionalData(QByteArray data);
+ bool copyCallId(unsigned int *id);
+
+ QByteArray serialize(QJsonDocument::JsonFormat format = QJsonDocument::Compact) override;
+
+ private:
+ QString m_reply_info, m_reply_status, m_reply_uuid;
+ unsigned int m_reply_callid;
+ QJsonObject m_reply_data;
+ QMap<QString, QVariant> m_request;
};
#endif // RESPONSEMESSAGE_H
diff --git a/signal-composer/CMakeLists.txt b/signal-composer/CMakeLists.txt
index 18f3a0a..f517d27 100644
--- a/signal-composer/CMakeLists.txt
+++ b/signal-composer/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(signalcomposer.h signalcomposermessage.h)
-add_sources(signalcomposer.cpp signalcomposermessage.cpp)
+add_headers(signalcomposer.h)
+add_sources(signalcomposer.cpp)
diff --git a/signal-composer/signalcomposer.cpp b/signal-composer/signalcomposer.cpp
index 59395f5..1296162 100644
--- a/signal-composer/signalcomposer.cpp
+++ b/signal-composer/signalcomposer.cpp
@@ -16,8 +16,9 @@
#include <QDebug>
-#include "message.h"
-#include "signalcomposermessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "signalcomposer.h"
@@ -40,56 +41,63 @@ SignalComposer::~SignalComposer()
void SignalComposer::onConnected()
{
QStringListIterator eventIterator(events);
- SignalComposerMessage *tmsg;
while (eventIterator.hasNext()) {
- tmsg = new SignalComposerMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* tmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("signal", eventIterator.next());
- tmsg->createRequest("subscribe", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ tmsg->createRequest("signal-composer", "subscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
}
void SignalComposer::onDisconnected()
{
QStringListIterator eventIterator(events);
- SignalComposerMessage *tmsg;
while (eventIterator.hasNext()) {
- tmsg = new SignalComposerMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage* tmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
parameter.insert("signal", eventIterator.next());
- tmsg->createRequest("unsubscribe", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ tmsg->createRequest("signal-composer", "unsubscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
}
-void SignalComposer::onMessageReceived(MessageType type, Message *message)
+void SignalComposer::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (type == MessageType::SignalComposerEventMessage) {
- SignalComposerMessage *tmsg = qobject_cast<SignalComposerMessage*>(message);
+ if (!msg)
+ return;
+
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ if (emsg->eventApi() != "signal-composer")
+ return;
- if (tmsg->isEvent()) {
- QString uid = tmsg->eventData().value("uid").toString();
- QVariant v = tmsg->eventData().value("value").toVariant();
- QString value;
- if(v.canConvert(QMetaType::QString))
- value = v.toString();
- else
- qWarning() << "Unconvertible value type for uid " << uid;
- QString units = tmsg->eventData().value("unit").toString();
- v = tmsg->eventData().value("timestamp").toVariant();
- quint64 timestamp = 0;
- if(v.canConvert(QMetaType::ULongLong))
- timestamp = v.toULongLong();
- else
- qWarning() << "Unconvertible timestamp type for uid " << uid;
+ QJsonObject data = emsg->eventData();
+ QString uid = data.value("uid").toString();
+ QVariant v = data.value("value").toVariant();
+ QString value;
+ if(v.canConvert(QMetaType::QString))
+ value = v.toString();
+ else
+ qWarning() << "Unconvertible value type for uid " << uid;
+ QString units = data.value("unit").toString();
+ v = data.value("timestamp").toVariant();
+ quint64 timestamp = 0;
+ if(v.canConvert(QMetaType::ULongLong))
+ timestamp = v.toULongLong();
+ else
+ qWarning() << "Unconvertible timestamp type for uid " << uid;
- emit signalEvent(uid, value, units, timestamp);
- }
+ emit signalEvent(uid, value, units, timestamp);
}
- message->deleteLater();
}
diff --git a/signal-composer/signalcomposer.h b/signal-composer/signalcomposer.h
index 13d26c6..382b6e9 100644
--- a/signal-composer/signalcomposer.h
+++ b/signal-composer/signalcomposer.h
@@ -17,14 +17,13 @@
#ifndef SIGNALCOMPOSER_H
#define SIGNALCOMPOSER_H
+#include <memory>
#include <QObject>
#include <QJsonArray>
class MessageEngine;
class Message;
-enum class MessageType;
-
class SignalComposer : public QObject
{
Q_OBJECT
@@ -41,7 +40,7 @@ class SignalComposer : public QObject
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
const QStringList events {
"event.vehicle.speed",
diff --git a/telephony/CMakeLists.txt b/telephony/CMakeLists.txt
index 1dfcd63..196ad53 100644
--- a/telephony/CMakeLists.txt
+++ b/telephony/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(telephony.h telephonymessage.h)
-add_sources(telephony.cpp telephonymessage.cpp)
+add_headers(telephony.h)
+add_sources(telephony.cpp)
diff --git a/telephony/telephony.cpp b/telephony/telephony.cpp
index e0fe2bd..0660156 100644
--- a/telephony/telephony.cpp
+++ b/telephony/telephony.cpp
@@ -16,8 +16,9 @@
#include <QDebug>
-#include "message.h"
-#include "telephonymessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "telephony.h"
@@ -41,26 +42,35 @@ Telephony::~Telephony()
void Telephony::dial(QString number)
{
- TelephonyMessage *tmsg = new TelephonyMessage();
- tmsg->createRequest("dial", number);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *tmsg = static_cast<CallMessage*>(msg.get());
+ tmsg->createRequest("telephony", "dial", number);
+ m_mloop->sendMessage(std::move(msg));
}
void Telephony::answer()
{
- TelephonyMessage *tmsg = new TelephonyMessage();
- tmsg->createRequest("answer");
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *tmsg = static_cast<CallMessage*>(msg.get());
+ tmsg->createRequest("telephony", "answer");
+ m_mloop->sendMessage(std::move(msg));
}
void Telephony::hangup()
{
- TelephonyMessage *tmsg = new TelephonyMessage();
- tmsg->createRequest("hangup");
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *tmsg = static_cast<CallMessage*>(msg.get());
+ tmsg->createRequest("telephony", "hangup");
+ m_mloop->sendMessage(std::move(msg));
}
void Telephony::onConnected()
@@ -72,13 +82,15 @@ void Telephony::onConnected()
"terminatedCall",
"online"};
QStringListIterator eventIterator(events);
- TelephonyMessage *tmsg;
while (eventIterator.hasNext()) {
- tmsg = new TelephonyMessage();
- tmsg->createRequest("subscribe", eventIterator.next());
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *tmsg = static_cast<CallMessage*>(msg.get());
+ tmsg->createRequest("telephony", "subscribe", eventIterator.next());
+ m_mloop->sendMessage(std::move(msg));
}
setConnected(true);
@@ -89,28 +101,31 @@ void Telephony::onDisconnected()
setConnected(false);
}
-void Telephony::onMessageReceived(MessageType type, Message *message)
+void Telephony::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (type == MessageType::TelephonyEventMessage) {
- TelephonyMessage *tmsg = qobject_cast<TelephonyMessage*>(message);
-
- if (tmsg->isEvent()) {
- if (tmsg->isCallStateChanged()) {
- setCallState(tmsg->state());
- } else if (tmsg->isDialingCall()) {
- m_colp = tmsg->colp();
+ if (!msg)
+ return;
+
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ if (emsg->eventApi() != "telephony");
+ return;
+ QString ename = emsg->eventName();
+ QJsonObject data = emsg->eventData();
+ if (ename == "callStateChanged") {
+ setCallState(data.find("state").value().toString());
+ } else if (ename == "dialingCall") {
+ m_colp = data.find("colp").value().toString();
setCallState("dialing");
- } else if (tmsg->isIncomingCall()) {
- m_clip = tmsg->clip();
+ } else if (ename == "incomingCall") {
+ m_clip = data.find("clip").value().toString();
setCallState("incoming");
- } else if (tmsg->isTerminatedCall()) {
+ } else if (ename == "terminatedCall") {
setCallState("disconnected");
m_colp = "";
m_clip = "";
- } else if (tmsg->isOnline()) {
- setOnlineState(tmsg->connected());
+ } else if (ename == "online") {
+ setOnlineState(data.find("connected").value().toBool());
}
}
- }
- message->deleteLater();
}
diff --git a/telephony/telephony.h b/telephony/telephony.h
index 097310f..ca1e52a 100644
--- a/telephony/telephony.h
+++ b/telephony/telephony.h
@@ -17,13 +17,12 @@
#ifndef TELEPHONY_H
#define TELEPHONY_H
+#include <memory>
#include <QObject>
class MessageEngine;
class Message;
-enum class MessageType;
-
class Telephony : public QObject
{
Q_OBJECT
@@ -78,7 +77,7 @@ class Telephony : public QObject
QString m_colp;
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
};
#endif // TELEPHONY_H
diff --git a/voice-capabilities/CMakeLists.txt b/voice-capabilities/CMakeLists.txt
index e1a6089..e3c0de7 100644
--- a/voice-capabilities/CMakeLists.txt
+++ b/voice-capabilities/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(guimetadata.h guimetadatamessage.h)
-add_sources(guimetadata.cpp guimetadatamessage.cpp)
+add_headers(guimetadata.h)
+add_sources(guimetadata.cpp)
diff --git a/voice-capabilities/guimetadata.cpp b/voice-capabilities/guimetadata.cpp
index 949cb58..4c597c1 100644
--- a/voice-capabilities/guimetadata.cpp
+++ b/voice-capabilities/guimetadata.cpp
@@ -17,8 +17,9 @@
#include <QDebug>
#include <QJsonArray>
-#include "message.h"
-#include "guimetadatamessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "guimetadata.h"
@@ -308,19 +309,20 @@ bool GuiMetadata::updateWeatherMetadata(QJsonObject &data)
void GuiMetadata::onConnected()
{
- QStringListIterator eventIterator(events);
- GuiMetadataCapabilityMessage *tmsg;
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
- tmsg = new GuiMetadataCapabilityMessage();
+ CallMessage *tmsg = static_cast<CallMessage*>(msg.get());
+ QStringListIterator eventIterator(events);
QJsonObject parameter;
QJsonArray actions;
while (eventIterator.hasNext()) {
actions.append(QJsonValue(eventIterator.next()));
}
parameter.insert("actions", actions);
- tmsg->createRequest("guimetadata/subscribe", parameter);
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ tmsg->createRequest("vshl-capabilities", "guimetadata/subscribe", parameter);
+ m_mloop->sendMessage(std::move(msg));
}
void GuiMetadata::onDisconnected()
@@ -328,18 +330,21 @@ void GuiMetadata::onDisconnected()
// vshl-capabilities currently has no unsubscribe verb...
}
-void GuiMetadata::onMessageReceived(MessageType type, Message *message)
+void GuiMetadata::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (type == MessageType::GuiMetadataCapabilityEventMessage) {
- GuiMetadataCapabilityMessage *tmsg = qobject_cast<GuiMetadataCapabilityMessage*>(message);
- if (tmsg->isEvent()) {
- if (tmsg->isGuiMetadataRenderTemplateEvent()) {
- if(updateMetadata(tmsg->eventData()))
- emit renderTemplate();
- } else if (tmsg->isGuiMetadataClearTemplateEvent()) {
- emit clearTemplate();
- }
+ if (!msg)
+ return;
+
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ if (emsg->eventApi() != "vshl-capabilities");
+ return;
+ QString ename = emsg->eventName();
+ QJsonObject data = emsg->eventData();
+ if ((ename == "render-template") && updateMetadata(data)) {
+ emit renderTemplate();
+ } else if (ename == "clear_template") {
+ emit clearTemplate();
}
}
- message->deleteLater();
}
diff --git a/voice-capabilities/guimetadata.h b/voice-capabilities/guimetadata.h
index ae90cba..f082d52 100644
--- a/voice-capabilities/guimetadata.h
+++ b/voice-capabilities/guimetadata.h
@@ -17,13 +17,13 @@
#ifndef GUIMETADATA_H
#define GUIMETADATA_H
+#include <memory>
#include <QObject>
#include <QtQml/QQmlContext>
class MessageEngine;
class Message;
-enum class MessageType;
class GuiMetadata : public QObject
{
@@ -128,7 +128,7 @@ private:
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
const QStringList events {
"render_template",
diff --git a/voice/CMakeLists.txt b/voice/CMakeLists.txt
index 61b8fe2..6363c3b 100644
--- a/voice/CMakeLists.txt
+++ b/voice/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_headers(voice.h voicemessage.h
+add_headers(voice.h
voiceagentregistry.h voiceagentprofile.h voiceagentmodel.h)
-add_sources(voice.cpp voicemessage.cpp
+add_sources(voice.cpp
voiceagentregistry.cpp voiceagentprofile.cpp voiceagentmodel.cpp)
diff --git a/voice/voice.cpp b/voice/voice.cpp
index 3c93960..5961882 100644
--- a/voice/voice.cpp
+++ b/voice/voice.cpp
@@ -16,9 +16,10 @@
#include <QDebug>
#include <QStringList>
-#include "message.h"
+#include "callmessage.h"
#include "responsemessage.h"
-#include "voicemessage.h"
+#include "eventmessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "voiceagentregistry.h"
#include "voice.h"
@@ -46,12 +47,15 @@ Voice::~Voice()
void Voice::scan()
{
- VoiceMessage *vmsg = new VoiceMessage();
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *vmsg = static_cast<CallMessage*>(msg.get());
QJsonObject parameter;
- vmsg->createRequest("enumerateVoiceAgents", parameter);
- m_loop->sendMessage(vmsg);
- delete vmsg;
+ vmsg->createRequest("vshl-core", "enumerateVoiceAgents", parameter);
+ m_loop->sendMessage(std::move(msg));
}
void Voice::getCBLpair(QString id)
@@ -61,41 +65,50 @@ void Voice::getCBLpair(QString id)
void Voice::subscribeAgentToVshlEvents(QString id)
{
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *vmsg = static_cast<CallMessage*>(msg.get());
QJsonArray events = QJsonArray::fromStringList(vshl_events);
- VoiceMessage *vmsg = new VoiceMessage();
QJsonObject parameter;
parameter.insert("va_id", id);
parameter.insert("events", events);
- vmsg->createRequest("subscribe", parameter);
- m_loop->sendMessage(vmsg);
- delete vmsg;
+ vmsg->createRequest("vshl-core", "subscribe", parameter);
+ m_loop->sendMessage(std::move(msg));
}
void Voice::unsubscribeAgentFromVshlEvents(QString id)
{
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *vmsg = static_cast<CallMessage*>(msg.get());
QJsonArray events = QJsonArray::fromStringList(vshl_events);
- VoiceMessage *vmsg = new VoiceMessage();
QJsonObject parameter;
parameter.insert("va_id", id);
parameter.insert("events", events);
- vmsg->createRequest("unsubscribe", parameter);
- m_loop->sendMessage(vmsg);
- delete vmsg;
+ vmsg->createRequest("vshl-core", "unsubscribe", parameter);
+ m_loop->sendMessage(std::move(msg));
}
void Voice::triggerCBLProcess(QString id)
{
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *vmsg = static_cast<CallMessage*>(msg.get());
QJsonArray events;
- VoiceMessage *vmsg = new VoiceMessage();
QJsonObject parameter;
parameter.insert("va_id", id);
parameter.insert("events", events);
- vmsg->createRequest("subscribeToLoginEvents", parameter);
- m_loop->sendMessage(vmsg);
- delete vmsg;
+ vmsg->createRequest("vshl-core", "subscribeToLoginEvents", parameter);
+ m_loop->sendMessage(std::move(msg));
}
void Voice::parseAgentsList(QJsonArray agents)
@@ -109,14 +122,20 @@ void Voice::parseAgentsList(QJsonArray agents)
-void Voice::processEvent(VoiceMessage *vmsg)
+void Voice::processEvent(std::shared_ptr<Message> msg)
{
- const QString str = vmsg->eventName();
- QJsonObject data = vmsg->eventData();
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ QString eapi = emsg->eventApi();
+
+ if (eapi != "vshl-core")
+ return;
+
+ QString ename = emsg->eventName();
+ QJsonObject data = emsg->eventData();
QString agentId = data.value("va_id").toString();
QString state = data.value("state").toString();
- if (vmsg->isAuthStateEvent()) {
+ if (ename.contains("voice_authstate_event")) {
m_var->setAuthState(
agentId,
static_cast<VoiceAgentRegistry::ServiceAuthState>(
@@ -124,47 +143,48 @@ void Voice::processEvent(VoiceMessage *vmsg)
return;
}
- else if (vmsg->isConnectionStateEvent()) {
+ else if (ename.contains("voice_connectionstate_event")) {
m_var->setConnectionState(
agentId,
static_cast<VoiceAgentRegistry::AgentConnectionState>(
m_var->stringToEnum(state, "AgentConnectionState")));
return;
}
- else if (vmsg->isDialogStateEvent()) {
+ else if (ename.contains("voice_dialogstate_event")) {
m_var->setDialogState(
agentId,
static_cast<VoiceAgentRegistry::VoiceDialogState>(
m_var->stringToEnum(state, "VoiceDialogState")));
return;
}
- else if (vmsg->isCblEvent()) {
+ else if (ename.contains("cbl")) {
QJsonObject payload = data.value("payload").toObject();
QString url = payload.value("url").toString();
QString code = payload.value("code").toString();
- if (str.contains("expired"))
+ if (ename.contains("expired"))
m_var->updateLoginData(agentId, code, url, true);
- else if (str.contains("received")) {
+ else if (ename.contains("received")) {
m_var->updateLoginData(agentId, code, url, false);
} else
qWarning() << "Unknown cbl event";
return;
}
- qWarning() << "Unknown vshl event:" << str;
+ qWarning() << "Unknown vshl event:" << ename;
}
-void Voice::processReply(ResponseMessage *rmsg)
+void Voice::processReply(std::shared_ptr<Message> msg)
{
+ std::shared_ptr<ResponseMessage> rmsg = std::static_pointer_cast<ResponseMessage>(msg);
+ QString verb = rmsg->requestVerb();
+ QJsonObject data = rmsg->replyData();
if (rmsg->replyStatus() == "failed") {
- qWarning() << "Reply Failed received for verb:" << rmsg->requestVerb();
- } else if (rmsg->requestVerb() == "enumerateVoiceAgents") {
- parseAgentsList(rmsg->replyData().value("agents").toArray());
- m_var->setDefaultId(
- rmsg->replyData().value("default").toString());
+ qWarning() << "Reply Failed received for verb:" << verb;
+ } else if (verb == "enumerateVoiceAgents") {
+ parseAgentsList(data.value("agents").toArray());
+ m_var->setDefaultId(data.value("default").toString());
} else
- qDebug() << "discarding reply received for verb:" <<
- rmsg->requestVerb();
+ qDebug() << "discarding reply received for verb:" << verb;
}
void Voice::onConnected()
@@ -180,13 +200,12 @@ void Voice::onDisconnected()
unsubscribeAgentFromVshlEvents(*it);
}
-void Voice::onMessageReceived(MessageType type, Message *msg)
+void Voice::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (msg->isEvent() && type == MessageType::VoiceEventMessage) {
- processEvent(qobject_cast<VoiceMessage*>(msg));
- } else if (msg->isReply() && (type == MessageType::ResponseRequestMessage)) {
- processReply(qobject_cast<ResponseMessage*>(msg));
+ if (msg->isEvent()) {
+ processEvent(msg);
+ } else if (msg->isReply()) {
+ processReply(msg);
} else
- qWarning() << "Received unknown message type:" << static_cast<double>(type);
- msg->deleteLater();
+ qWarning() << "Received invalid inbound message";
}
diff --git a/voice/voice.h b/voice/voice.h
index e3132be..ea0649b 100644
--- a/voice/voice.h
+++ b/voice/voice.h
@@ -17,6 +17,7 @@
#ifndef VOICE_H
#define VOICE_H
+#include <memory>
#include <QObject>
#include <QJsonArray>
#include <QtQml/QQmlContext>
@@ -24,10 +25,6 @@
class VoiceAgentRegistry;
class MessageEngine;
class Message;
-class ResponseMessage;
-class VoiceMessage;
-
-enum class MessageType;
class Voice : public QObject
{
@@ -51,16 +48,16 @@ class Voice : public QObject
void unsubscribeAgentFromVshlEvents(QString id);
void triggerCBLProcess(QString id);
void parseAgentsList(QJsonArray agents);
- void processVshlEvent(VoiceMessage *vmsg);
- void processLoginEvent(VoiceMessage *vmsg);
+ void processVshlEvent(std::shared_ptr<Message> msg);
+ void processLoginEvent(std::shared_ptr<Message> msg);
- void processEvent(VoiceMessage *vmsg);
- void processReply(ResponseMessage *rmsg);
+ void processEvent(std::shared_ptr<Message> emsg);
+ void processReply(std::shared_ptr<Message> rmsg);
// slots
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType type, Message *msg);
+ void onMessageReceived(std::shared_ptr<Message> msg);
const QStringList vshl_events {
"voice_authstate_event",
diff --git a/weather/CMakeLists.txt b/weather/CMakeLists.txt
index 44b4d4d..bd94755 100644
--- a/weather/CMakeLists.txt
+++ b/weather/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_headers(weather.h weathermessage.h)
-add_sources(weather.cpp weathermessage.cpp)
+add_headers(weather.h)
+add_sources(weather.cpp)
diff --git a/weather/weather.cpp b/weather/weather.cpp
index d4992d4..298f32c 100644
--- a/weather/weather.cpp
+++ b/weather/weather.cpp
@@ -17,8 +17,9 @@
#include <QDebug>
#include <QJsonArray>
-#include "message.h"
-#include "weathermessage.h"
+#include "callmessage.h"
+#include "eventmessage.h"
+#include "messagefactory.h"
#include "messageengine.h"
#include "weather.h"
@@ -40,32 +41,41 @@ Weather::~Weather()
void Weather::onConnected()
{
- WeatherMessage *tmsg = new WeatherMessage();
- tmsg->createRequest("subscribe", "weather");
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *tmsg = static_cast<CallMessage*>(msg.get());
+ tmsg->createRequest("weather", "subscribe", "weather");
+ m_mloop->sendMessage(std::move(msg));
}
void Weather::onDisconnected()
{
- WeatherMessage *tmsg = new WeatherMessage();
- tmsg->createRequest("unsubscribe", "weather");
- m_mloop->sendMessage(tmsg);
- delete tmsg;
+ std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
+ if (!msg)
+ return;
+
+ CallMessage *tmsg = static_cast<CallMessage*>(msg.get());
+ tmsg->createRequest("weater", "unsubscribe", "weather");
+ m_mloop->sendMessage(std::move(msg));
}
-void Weather::onMessageReceived(MessageType type, Message *message)
+void Weather::onMessageReceived(std::shared_ptr<Message> msg)
{
- if (type == MessageType::WeatherEventMessage) {
- WeatherMessage *tmsg = qobject_cast<WeatherMessage*>(message);
+ if (!msg)
+ return;
+
+ if (msg->isEvent()) {
+ std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
+ if (emsg->eventApi() != "weather")
+ return;
- if (tmsg->isEvent()) {
- m_temperature = tmsg->temperature();
- m_condition = tmsg->condition();
+ QJsonObject data = emsg->eventData();
+ m_temperature = QString::number(data.value("main").toObject().value("temp").toDouble());
+ m_condition = data.value("weather").toArray().at(0).toObject().value("description").toString();
emit temperatureChanged(m_temperature);
emit conditionChanged(m_condition);
}
- }
- message->deleteLater();
}
diff --git a/weather/weather.h b/weather/weather.h
index 6d33a15..75054d5 100644
--- a/weather/weather.h
+++ b/weather/weather.h
@@ -17,13 +17,12 @@
#ifndef WEATHER_H
#define WEATHER_H
+#include <memory>
#include <QObject>
class MessageEngine;
class Message;
-enum class MessageType;
-
class Weather : public QObject
{
Q_OBJECT
@@ -48,7 +47,7 @@ class Weather : public QObject
void onConnected();
void onDisconnected();
- void onMessageReceived(MessageType, Message*);
+ void onMessageReceived(std::shared_ptr<Message>);
};
#endif // WEATHER_H