add API to check if cloud is connected

This commit is contained in:
Michael Zanetti 2017-11-21 12:02:53 +01:00
parent 61c20e2001
commit 33095f4dbe
8 changed files with 89 additions and 12 deletions

View File

@ -40,9 +40,6 @@ DisconnectCallbackContextData::~DisconnectCallbackContextData() {}
AWSConnector::AWSConnector(QObject *parent) : QObject(parent)
{
connect(this, &AWSConnector::connected, this, &AWSConnector::onConnected, Qt::QueuedConnection);
connect(this, &AWSConnector::disconnected, this, &AWSConnector::onDisconnected, Qt::QueuedConnection);
// Enable some AWS logging (does not regard our logging categories)
// std::shared_ptr<awsiotsdk::util::Logging::ConsoleLogSystem> p_log_system =
// std::make_shared<awsiotsdk::util::Logging::ConsoleLogSystem>(awsiotsdk::util::Logging::LogLevel::Info);
@ -61,6 +58,7 @@ AWSConnector::~AWSConnector()
void AWSConnector::connect2AWS(const QString &endpoint, const QString &clientId, const QString &clientName, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile)
{
m_shouldReconnect = true;
m_currentEndpoint = endpoint;
m_caFile = caFile;
m_clientCertFile = clientCertFile;
@ -97,7 +95,7 @@ void AWSConnector::doConnect()
m_connectingFuture = QtConcurrent::run([&]() {
ResponseCode rc = m_client->Connect(std::chrono::milliseconds(3000), true, mqtt::Version::MQTT_3_1_1, std::chrono::seconds(60), Utf8String::Create(m_clientId.toStdString()), nullptr, nullptr, nullptr);
if (rc == ResponseCode::MQTT_CONNACK_CONNECTION_ACCEPTED) {
emit connected();
staticMetaObject.invokeMethod(this, "onConnected", Qt::QueuedConnection);
} else {
qCWarning(dcAWS) << "Error connecting to AWS. Response code:" << QString::fromStdString(ResponseHelper::ToString(rc));
m_client.reset();
@ -181,10 +179,12 @@ void AWSConnector::onPairingsRetrieved(const QVariantList &pairings)
subscribe(topics);
m_setupInProgress = false;
emit connected();
}
void AWSConnector::disconnectAWS()
{
m_shouldReconnect = false;
if (isConnected()) {
m_client->Disconnect(std::chrono::seconds(2));
}
@ -229,6 +229,9 @@ quint16 AWSConnector::publish(const QString &topic, const QVariantMap &message)
void AWSConnector::onDisconnected()
{
qCDebug(dcAWS) << "AWS disconnected.";
emit disconnected();
bool needReRegistering = false;
if (m_setupInProgress) {
qCWarning(dcAWS()) << "Setup process interrupted by disconnect.";
@ -244,16 +247,17 @@ void AWSConnector::onDisconnected()
qCWarning(dcAWS()) << "Connection dropped 5 times in a row within a minute.";
needReRegistering = true;
}
return;
}
if (needReRegistering) {
qCDebug(dcAWS) << "Trying to reregister the device in the cloud";
storeRegisteredFlag(false);
doConnect();
}
qCDebug(dcAWS) << "AWS disconnected. (should reconnect on it's own)";
if (m_shouldReconnect) {
qCDebug(dcAWS()) << "Reconnecting to AWS...";
doConnect();
}
}
void AWSConnector::setName()
@ -409,7 +413,7 @@ ResponseCode AWSConnector::onDisconnectedCallback(util::String mqtt_client_id, s
{
Q_UNUSED(mqtt_client_id)
AWSConnector* connector = dynamic_cast<DisconnectContext*>(p_app_handler_data.get())->c;
emit connector->disconnected();
connector->staticMetaObject.invokeMethod(connector, "onDisconnected", Qt::QueuedConnection);
return ResponseCode::SUCCESS;
}

View File

@ -101,6 +101,7 @@ private:
QString m_clientName;
QFuture<void> m_connectingFuture;
bool m_isCleanSession = true;
bool m_shouldReconnect = false;
quint8 m_transactionId = 0;
QString m_createDeviceId;

View File

@ -29,6 +29,8 @@ CloudManager::CloudManager(NetworkManager *networkManager, QObject *parent) : QO
m_awsConnector = new AWSConnector(this);
connect(m_awsConnector, &AWSConnector::devicePaired, this, &CloudManager::onPairingFinished);
connect(m_awsConnector, &AWSConnector::webRtcHandshakeMessageReceived, this, &CloudManager::onAWSWebRtcHandshakeMessageReceived);
connect(m_awsConnector, &AWSConnector::connected, this, &CloudManager::awsConnected);
connect(m_awsConnector, &AWSConnector::disconnected, this, &CloudManager::awsDisconnected);
m_janusConnector = new JanusConnector(this);
connect(m_janusConnector, &JanusConnector::webRtcHandshakeMessageReceived, this, &CloudManager::onJanusWebRtcHandshakeMessageReceived);
@ -113,6 +115,11 @@ void CloudManager::setEnabled(bool enabled)
}
}
bool CloudManager::connected() const
{
return m_awsConnector->isConnected();
}
void CloudManager::pairDevice(const QString &idToken, const QString &userId)
{
m_awsConnector->pairDevice(idToken, userId);
@ -157,3 +164,13 @@ void CloudManager::onJanusWebRtcHandshakeMessageReceived(const QString &transact
{
m_awsConnector->sendWebRtcHandshakeMessage(transactionId, data);
}
void CloudManager::awsConnected()
{
emit connectedChanged(true);
}
void CloudManager::awsDisconnected()
{
emit connectedChanged(false);
}

View File

@ -45,12 +45,15 @@ public:
bool enabled() const;
void setEnabled(bool enabled);
bool connected() const;
void pairDevice(const QString &idToken, const QString &userId);
bool keepAlive(const QString &sessionId);
signals:
void connectedChanged(bool connected);
void pairingReply(QString cognitoUserId, int status, const QString &message);
private:
@ -61,6 +64,8 @@ private slots:
void onPairingFinished(const QString &cognitoUserId, int errorCode, const QString &message);
void onAWSWebRtcHandshakeMessageReceived(const QString &transactionId, const QVariantMap &data);
void onJanusWebRtcHandshakeMessageReceived(const QString &transactionId, const QVariantMap &data);
void awsConnected();
void awsDisconnected();
private:
QTimer m_reconnectTimer;

View File

@ -141,7 +141,7 @@ JsonRPCServer::JsonRPCServer(const QSslConfiguration &sslConfiguration, QObject
setReturns("RemoveToken", returns);
params.clear(); returns.clear();
setDescription("SetupRemoteAccess", "Setup the remote connection by providing AWS token information");
setDescription("SetupRemoteAccess", "Setup the remote connection by providing AWS token information. This requires the cloud to be connected.");
params.insert("idToken", JsonTypes::basicTypeToString(JsonTypes::String));
params.insert("userId", JsonTypes::basicTypeToString(JsonTypes::String));
setParams("SetupRemoteAccess", params);
@ -149,6 +149,12 @@ JsonRPCServer::JsonRPCServer(const QSslConfiguration &sslConfiguration, QObject
returns.insert("message", JsonTypes::basicTypeToString(JsonTypes::String));
setReturns("SetupRemoteAccess", returns);
params.clear(); returns.clear();
setDescription("IsCloudConnected", "Check whether the cloud is currently connected.");
setParams("IsCloudConnected", params);
returns.insert("connected", JsonTypes::basicTypeToString(JsonTypes::Bool));
setReturns("IsCloudConnected", returns);
params.clear(); returns.clear();
setDescription("KeepAlive", "Keep alive a remote connection. The sessionId is the MQTT topic which has been used to establish the session. It will return false if no ongoing session with the given ID can be found.");
params.insert("sessionId", JsonTypes::basicTypeToString(JsonTypes::String));
@ -156,6 +162,12 @@ JsonRPCServer::JsonRPCServer(const QSslConfiguration &sslConfiguration, QObject
returns.insert("success", JsonTypes::basicTypeToString(JsonTypes::Bool));
setReturns("KeepAlive", returns);
// Notifications
params.clear(); returns.clear();
setDescription("CloudConnectedChanged", "Emitted whenever the cloud connection status changes.");
params.insert("connected", JsonTypes::basicTypeToString(JsonTypes::Bool));
setParams("CloudConnectedChanged", params);
QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection);
}
@ -281,6 +293,15 @@ JsonReply *JsonRPCServer::SetupRemoteAccess(const QVariantMap &params)
return reply;
}
JsonReply *JsonRPCServer::IsCloudConnected(const QVariantMap &params)
{
Q_UNUSED(params)
bool connected = GuhCore::instance()->cloudManager()->connected();
QVariantMap data;
data.insert("connected", connected);
return createReply(data);
}
JsonReply *JsonRPCServer::KeepAlive(const QVariantMap &params)
{
QString sessionId = params.value("sessionId").toString();
@ -385,6 +406,7 @@ void JsonRPCServer::setup()
registerHandler(new NetworkManagerHandler(this));
connect(GuhCore::instance()->cloudManager(), &CloudManager::pairingReply, this, &JsonRPCServer::pairingFinished);
connect(GuhCore::instance()->cloudManager(), &CloudManager::connectedChanged, this, &JsonRPCServer::onCloudConnectedChanged);
}
void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &data)
@ -533,6 +555,13 @@ void JsonRPCServer::pairingFinished(QString cognitoUserId, int status, const QSt
reply->finished();
}
void JsonRPCServer::onCloudConnectedChanged(bool connected)
{
QVariantMap params;
params.insert("connected", connected);
emit CloudConnectedChanged(params);
}
void JsonRPCServer::registerHandler(JsonHandler *handler)
{
m_handlers.insert(handler->name(), handler);

View File

@ -57,14 +57,20 @@ public:
Q_INVOKABLE JsonReply *Tokens(const QVariantMap &params) const;
Q_INVOKABLE JsonReply *RemoveToken(const QVariantMap &params);
Q_INVOKABLE JsonReply *SetupRemoteAccess(const QVariantMap &params);
Q_INVOKABLE JsonReply *IsCloudConnected(const QVariantMap &params);
Q_INVOKABLE JsonReply *KeepAlive(const QVariantMap &params);
QHash<QString, JsonHandler *> handlers() const;
signals:
void CloudConnectedChanged(const QVariantMap &map);
// Internal
public:
void registerTransportInterface(TransportInterface *interface, bool authenticationRequired);
void unregisterTransportInterface(TransportInterface *interface);
private:
QHash<QString, JsonHandler *> handlers() const;
void sendResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QVariantMap &params = QVariantMap());
void sendErrorResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QString &error);
void sendUnauthorizedResponse(TransportInterface *interface, const QUuid &clientId, int commandId, const QString &error);
@ -83,6 +89,7 @@ private slots:
void asyncReplyFinished();
void pairingFinished(QString cognitoUserId, int status, const QString &message);
void onCloudConnectedChanged(bool connected);
private:
QMap<TransportInterface*, bool> m_interfaces;

View File

@ -449,6 +449,14 @@
"types": "Object"
}
},
"JSONRPC.IsCloudConnected": {
"description": "Check whether the cloud is currently connected.",
"params": {
},
"returns": {
"connected": "Bool"
}
},
"JSONRPC.KeepAlive": {
"description": "Keep alive a remote connection. The sessionId is the MQTT topic which has been used to establish the session. It will return false if no ongoing session with the given ID can be found.",
"params": {
@ -477,7 +485,7 @@
}
},
"JSONRPC.SetupRemoteAccess": {
"description": "Setup the remote connection by providing AWS token information",
"description": "Setup the remote connection by providing AWS token information. This requires the cloud to be connected.",
"params": {
"idToken": "String",
"userId": "String"
@ -830,6 +838,12 @@
"event": "$ref:Event"
}
},
"JSONRPC.CloudConnectedChanged": {
"description": "Emitted whenever the cloud connection status changes.",
"params": {
"connected": "Bool"
}
},
"Logging.LogDatabaseUpdated": {
"description": "Emitted whenever the database was updated. The database will be updated when a log entry was deleted. A log entry will be deleted when the corresponding device or a rule will be removed, or when the oldest entry of the database was deleted to keep to database in the size limits.",
"params": {

View File

@ -102,7 +102,7 @@ void TestVersioning::apiChangeBumpsVersion()
p.waitForFinished();
QByteArray apiDiff = p.readAll();
qDebug() << "API Differences:" << endl << apiDiff;
qDebug() << "API Differences:" << endl << qUtf8Printable(apiDiff);
if (oldVersion == newVersionStripped && oldApi != newApi) {
QVERIFY2(false, "JSONRPC API has changed but version is still the same. You need to bump the API version.");