diff --git a/libnymea-core/awsconnector.cpp b/libnymea-core/awsconnector.cpp index 9dcaca9a..0fa1ff8c 100644 --- a/libnymea-core/awsconnector.cpp +++ b/libnymea-core/awsconnector.cpp @@ -217,6 +217,8 @@ void AWSConnector::onPairingsRetrieved(const QVariantMap &pairings) m_setupInProgress = false; emit connected(); + + requestTURNCredentials(); } void AWSConnector::disconnectAWS() @@ -284,6 +286,10 @@ void AWSConnector::requestTURNCredentials() emit turnCredentialsReceived(QVariantMap()); return; } + if (!m_cachedTURNCredentials.first.isEmpty() && QDateTime::currentDateTime().secsTo(m_cachedTURNCredentials.second) > 0) { + emit turnCredentialsReceived(m_cachedTURNCredentials.first); + return; + } qCDebug(dcAWS()) << "Requesting TURN credentials"; QVariantMap params; params.insert("id", QUuid::createUuid()); @@ -344,6 +350,19 @@ void AWSConnector::onDisconnected() } } +void AWSConnector::onTurnCredentialsReceived(const QVariantMap &turnCredentials) +{ + qCDebug(dcAWS()) << "Dynamic TURN credentials received"; + + m_cachedTURNCredentials.first = turnCredentials; + m_cachedTURNCredentials.second = QDateTime::currentDateTime().addSecs(turnCredentials.value("ttl").toInt()); + emit turnCredentialsReceived(turnCredentials); + + // refresh the cache + QTimer::singleShot((turnCredentials.value("ttl").toInt() - 10) * 1000, this, &AWSConnector::requestTURNCredentials); + qCDebug(dcAWS()) << "Refreshing TURN credentials in" << (turnCredentials.value("ttl").toInt() - 10) << "seconds."; +} + void AWSConnector::setName() { QVariantMap params; @@ -513,8 +532,7 @@ ResponseCode AWSConnector::onSubscriptionReceivedCallback(util::String topic_nam qCWarning(dcAWS()) << "Error retrieving TURN credentials:" << turnCreds.value("result").toMap().value("code").toInt() << turnCreds.value("result").toMap().value("message").toString(); return ResponseCode::SUCCESS; } - qCDebug(dcAWS()) << "Dynamic TURN credentials received"; - emit connector->turnCredentialsReceived(turnCreds.value("turnCredentials").toMap()); + connector->staticMetaObject.invokeMethod(connector, "onTurnCredentialsReceived", Qt::QueuedConnection, Q_ARG(QVariantMap, turnCreds.value("turnCredentials").toMap())); } else { qCWarning(dcAWS()) << "Unhandled subscription received!" << topic << QString::fromStdString(payload); } diff --git a/libnymea-core/awsconnector.h b/libnymea-core/awsconnector.h index 6bda1fcf..84ec7149 100644 --- a/libnymea-core/awsconnector.h +++ b/libnymea-core/awsconnector.h @@ -79,6 +79,7 @@ private slots: void onPairingsRetrieved(const QVariantMap &pairings); void setName(); void onDisconnected(); + void onTurnCredentialsReceived(const QVariantMap &turnCredentials); private: class SubscriptionContext: public awsiotsdk::mqtt::SubscriptionHandlerContextData @@ -132,6 +133,7 @@ private: int m_reconnectCounter = 0; QDateTime m_lastConnectionDrop; QStringList m_subscriptionCache; + QPair m_cachedTURNCredentials; std::shared_ptr m_subscriptionContextData; std::shared_ptr m_disconnectContextData; diff --git a/libnymea-core/janusconnector.cpp b/libnymea-core/janusconnector.cpp index 8fdecea5..f3947bc5 100644 --- a/libnymea-core/janusconnector.cpp +++ b/libnymea-core/janusconnector.cpp @@ -38,7 +38,7 @@ JanusConnector::JanusConnector(QObject *parent) : QObject(parent) // When Janus crashes it will leave the socket in a very broken state which causes QLocalSocket to spin the CPU // So let's use a rather short heartbeat to send ping messages and clean things up in case they are not acked. - m_pingTimer.setInterval(1000); + m_pingTimer.setInterval(5000); connect(&m_pingTimer, &QTimer::timeout, this, &JanusConnector::heartbeat); m_turnCredentialsServer = new QTcpServer(this); @@ -177,7 +177,7 @@ void JanusConnector::setTurnCredentials(const QVariantMap &turnCredentials) while (!m_pendingTurnCredentialRequests.isEmpty()) { QJsonDocument jsonDoc = QJsonDocument::fromVariant(turnCredentials); QByteArray content = jsonDoc.toJson(QJsonDocument::Compact); - qCDebug(dcJanus()) << "Providing TURN credentials to Janus."; + qCDebug(dcJanus()) << "Providing TURN credentials to Janus." << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented)); QTcpSocket* socket = m_pendingTurnCredentialRequests.takeFirst(); QByteArray reply = QByteArray("HTTP/1.1 200 Ok\r\n"); reply.append("Content-Type: application/json\r\n"); diff --git a/libnymea/devicemanager.cpp b/libnymea/devicemanager.cpp index 6f81c21e..6cad4d4a 100644 --- a/libnymea/devicemanager.cpp +++ b/libnymea/devicemanager.cpp @@ -1370,7 +1370,7 @@ void DeviceManager::onAutoDevicesAppeared(const DeviceClassId &deviceClassId, co { DeviceClass deviceClass = findDeviceClass(deviceClassId); if (!deviceClass.isValid()) { - qCWarning(dcDeviceManager()) << "Auto device appeared for an unknown DeviceClass. Ignoring..."; + qCWarning(dcDeviceManager()) << "Ignoring auto device appeared for an unknown DeviceClass" << deviceClassId; return; }