From c040a71cdb0c9ae1a86b9499e8c3af3492378269 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Wed, 4 Oct 2017 17:39:57 +0200 Subject: [PATCH] some more work for latest api changes --- libguh-core/awsconnector.cpp | 84 +++++++++++++++++++++++------------- libguh-core/awsconnector.h | 10 +++-- libguh-core/cloudmanager.cpp | 11 ++++- libguh-core/cloudmanager.h | 2 + libguh-core/guhcore.cpp | 1 + 5 files changed, 72 insertions(+), 36 deletions(-) diff --git a/libguh-core/awsconnector.cpp b/libguh-core/awsconnector.cpp index 3eeb4cc9..9ecc0330 100644 --- a/libguh-core/awsconnector.cpp +++ b/libguh-core/awsconnector.cpp @@ -42,7 +42,7 @@ AWSConnector::~AWSConnector() { } -void AWSConnector::connect2AWS(const QString &endpoint, const QString &clientId, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile) +void AWSConnector::connect2AWS(const QString &endpoint, const QString &clientId, const QString &clientName, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile) { m_networkConnection = std::shared_ptr(new MbedTLSConnection( endpoint.toStdString(), @@ -59,6 +59,7 @@ void AWSConnector::connect2AWS(const QString &endpoint, const QString &clientId, m_client->SetDisconnectCallbackPtr(&onDisconnected, std::shared_ptr(this)); m_client->SetAutoReconnectEnabled(true); m_clientId = clientId; + m_clientName = clientName; qCDebug(dcAWS()) << "Connecting to AWS with ID:" << m_clientId << "endpoint:" << endpoint; m_connectingFuture = QtConcurrent::run([&]() { @@ -121,25 +122,10 @@ quint16 AWSConnector::publish(const QString &topic, const QVariantMap &message) return packetId; } -void AWSConnector::subscribe(const QStringList &topics) -{ - m_subscribedTopics.append(topics); - - if (!isConnected()) { - qCDebug(dcAWS()) << "Can't subscribe to AWS: Not connected. Subscription will happen upon next connection."; - return; - } - doSubscribe(topics); -} - void AWSConnector::onConnected() { qCDebug(dcAWS()) << "AWS connected"; registerDevice(); - retrievePairedDeviceInfo(); - if (!m_subscribedTopics.isEmpty()) { - doSubscribe(m_subscribedTopics); - } } void AWSConnector::retrievePairedDeviceInfo() @@ -147,7 +133,8 @@ void AWSConnector::retrievePairedDeviceInfo() QVariantMap params; params.insert("timestamp", QDateTime::currentMSecsSinceEpoch()); params.insert("id", ++m_transactionId); - publish(QString("%1/pair/list").arg(m_clientId), params); + params.insert("command", "getUsers"); + publish(QString("%1/device/users").arg(m_clientId), params); } void AWSConnector::registerDevice() @@ -157,19 +144,23 @@ void AWSConnector::registerDevice() // call we need to subscribe to a topic every device can subscribe to. If we'd use our deviceId, a potential // black hat could snoop in all the devices we register on the system. So in case someone actually does that // let's give him meaningless IDs instead of real device ids. - QString tmpId = QUuid::createUuid().toString().remove(QRegExp("[{}]*")); + m_createDeviceId = QUuid::createUuid().toString().remove(QRegExp("[{}]*")); // first subscribe to this tmp id topic - subscribe({QString("create/device/%1").arg(tmpId)}); - - // and register ourselves - QVariantMap params; - params.insert("id", tmpId); - params.insert("UUID", m_clientId); - publish("create/device", params); + m_createDeviceSubscriptionId = subscribe({QString("create/device/%1").arg(m_createDeviceId)}); } -void AWSConnector::doSubscribe(const QStringList &topics) +void AWSConnector::setName() +{ + QVariantMap params; + params.insert("id", ++m_transactionId); + params.insert("timestamp", QDateTime::currentSecsSinceEpoch()); + params.insert("command", "postName"); + params.insert("name", m_clientName); + publish(QString("%1/device/name").arg(m_clientId), params); +} + +quint16 AWSConnector::subscribe(const QStringList &topics) { util::Vector> subscription_list; foreach (const QString &topic, topics) { @@ -181,7 +172,9 @@ void AWSConnector::doSubscribe(const QStringList &topics) uint16_t packetId; ResponseCode res = m_client->SubscribeAsync(subscription_list, subscribeCallback, packetId); qCDebug(dcAWSTraffic()) << "subscribe call queued with status:" << QString::fromStdString(ResponseHelper::ToString(res)) << packetId; + qWarning() << "'''" << s_requestMap.count(); s_requestMap.insert(packetId, this); + return packetId; } void AWSConnector::publishCallback(uint16_t actionId, ResponseCode rc) @@ -203,7 +196,27 @@ void AWSConnector::publishCallback(uint16_t actionId, ResponseCode rc) void AWSConnector::subscribeCallback(uint16_t actionId, ResponseCode rc) { - qCDebug(dcAWS()) << "subscribed to topic" << actionId << QString::fromStdString(ResponseHelper::ToString(rc)); + if (rc != ResponseCode::SUCCESS) { + qCWarning(dcAWS()) << "Error subscribing to" << actionId << QString::fromStdString(ResponseHelper::ToString(rc)); + return; + } + + AWSConnector *connector = s_requestMap.take(actionId); + if (!connector) { + qCWarning(dcAWS()) << "received a subscribe callback but don't have a request id for it."; + return; + } + + if (actionId == connector->m_createDeviceSubscriptionId) { + qCDebug(dcAWS()) << "subscribed to create/device/response"; + QVariantMap params; + params.insert("id", connector->m_createDeviceId); + params.insert("UUID", connector->m_clientId); + connector->publish("create/device", params); + return; + } + + qCDebug(dcAWS()) << "Subscribe callback for action" << actionId; } ResponseCode AWSConnector::onSubscriptionReceivedCallback(util::String topic_name, util::String payload, std::shared_ptr p_app_handler_data) @@ -220,12 +233,19 @@ ResponseCode AWSConnector::onSubscriptionReceivedCallback(util::String topic_nam if (topic.startsWith("create/device/")) { int statusCode = jsonDoc.toVariant().toMap().value("result").toMap().value("code").toInt(); if (statusCode != 200) { - qCWarning(dcAWS()) << "Error registering device in the cloud. AWS connetion will not work."; + qCWarning(dcAWS()) << "Error registering device in the cloud. AWS connetion will not work:" << statusCode; return ResponseCode::SUCCESS; } qCDebug(dcAWS()) << "Device registered in cloud"; - connector->subscribe({QString("%1/pair/response").arg(connector->m_clientId), - QString("%1/pair/list/response").arg(connector->m_clientId)}); + + QStringList subscriptions; + subscriptions.append(QString("%1/pair/response").arg(connector->m_clientId)); + subscriptions.append(QString("%1/device/users/response").arg(connector->m_clientId)); + connector->subscribe(subscriptions); + + connector->retrievePairedDeviceInfo(); + connector->setName(); + } else if (topic == QString("%1/pair/response").arg(connector->m_clientId)) { int statusCode = jsonDoc.toVariant().toMap().value("status").toInt(); int id = jsonDoc.toVariant().toMap().value("id").toInt(); @@ -237,13 +257,15 @@ ResponseCode AWSConnector::onSubscriptionReceivedCallback(util::String topic_nam } else { qCWarning(dcAWS()) << "Received a pairing response for a transaction we didn't start"; } - } else if (topic == QString("%1/pair/list/response").arg(connector->m_clientId)) { + } else if (topic == QString("%1/device/users/response").arg(connector->m_clientId)) { qCDebug(dcAWS) << "have device pairings:" << jsonDoc.toVariant().toMap().value("pairings").toList(); QStringList topics; foreach (const QVariant &pairing, jsonDoc.toVariant().toMap().value("pairings").toList()) { topics << QString("eu-west-1:%1/listeningPeer/#").arg(pairing.toMap().value("cognitoIdIdentityId").toString()); } connector->subscribe(topics); + } else if (topic == QString("%1/device/name/response").arg(connector->m_clientId)) { + qCDebug(dcAWS) << "Set device name in cloud with status:" << jsonDoc.toVariant().toMap().value("status").toInt(); } else if (topic.contains("listeningPeer") && !topic.contains("reply")) { static QStringList dupes; QString id = jsonDoc.toVariant().toMap().value("id").toString(); diff --git a/libguh-core/awsconnector.h b/libguh-core/awsconnector.h index 79dfa7e7..2b7c78cd 100644 --- a/libguh-core/awsconnector.h +++ b/libguh-core/awsconnector.h @@ -35,7 +35,7 @@ public: explicit AWSConnector(QObject *parent = 0); ~AWSConnector(); - void connect2AWS(const QString &endpoint, const QString &clientId, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile); + void connect2AWS(const QString &endpoint, const QString &clientId, const QString &clientName, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile); void disconnectAWS(); bool isConnected() const; @@ -52,11 +52,11 @@ private slots: void onConnected(); void retrievePairedDeviceInfo(); void registerDevice(); + void setName(); private: quint16 publish(const QString &topic, const QVariantMap &message); - void subscribe(const QStringList &topics); - void doSubscribe(const QStringList &topcis); + quint16 subscribe(const QStringList &topics); static void publishCallback(uint16_t actionId, awsiotsdk::ResponseCode rc); static void subscribeCallback(uint16_t actionId, awsiotsdk::ResponseCode rc); static awsiotsdk::ResponseCode onSubscriptionReceivedCallback(awsiotsdk::util::String topic_name, awsiotsdk::util::String payload, @@ -69,10 +69,12 @@ private: std::shared_ptr m_client; QString m_clientId; + QString m_clientName; QFuture m_connectingFuture; - QStringList m_subscribedTopics; int m_transactionId = 0; + QString m_createDeviceId; + int m_createDeviceSubscriptionId = 0; QHash m_pairingRequests; static QHash s_requestMap; diff --git a/libguh-core/cloudmanager.cpp b/libguh-core/cloudmanager.cpp index d0d15925..dd366207 100644 --- a/libguh-core/cloudmanager.cpp +++ b/libguh-core/cloudmanager.cpp @@ -46,6 +46,11 @@ void CloudManager::setDeviceId(const QUuid &deviceId) m_deviceId = deviceId; } +void CloudManager::setDeviceName(const QString &name) +{ + m_deviceName = name; +} + void CloudManager::setClientCertificates(const QString &caCertificate, const QString &clientCertificate, const QString &clientCertificateKey) { m_caCertificate = caCertificate; @@ -66,7 +71,10 @@ void CloudManager::setEnabled(bool enabled) qCWarning(dcCloud()) << "Don't have a unique device ID."; missingConfig = true; } - + if (m_deviceName.isEmpty()) { + qCWarning(dcCloud()) << "Don't have a device name set"; + missingConfig = true; + } if (m_serverUrl.isEmpty()) { qCWarning(dcCloud()) << "Cloud server URL not set."; missingConfig = true; @@ -105,6 +113,7 @@ void CloudManager::connect2aws() m_awsConnector->connect2AWS(m_serverUrl, "1e10fb7e-d9d9-4145-88dd-2d3caf623c18", // micha's test id (needs micha's test certs) - remove that before merging // m_deviceId.toString().remove(QRegExp("[{}]*")), + m_deviceName, m_caCertificate, m_clientCertificate, m_clientCertificateKey diff --git a/libguh-core/cloudmanager.h b/libguh-core/cloudmanager.h index 2228fddc..04cea56e 100644 --- a/libguh-core/cloudmanager.h +++ b/libguh-core/cloudmanager.h @@ -39,6 +39,7 @@ public: void setServerUrl(const QString &serverUrl); void setDeviceId(const QUuid &deviceId); + void setDeviceName(const QString &name); void setClientCertificates(const QString &caCertificate, const QString &clientCertificate, const QString &clientCertificateKey); bool enabled() const; @@ -67,6 +68,7 @@ private: QString m_serverUrl; QUuid m_deviceId; + QString m_deviceName; QString m_caCertificate; QString m_clientCertificate; QString m_clientCertificateKey; diff --git a/libguh-core/guhcore.cpp b/libguh-core/guhcore.cpp index ee2a21a5..acf6d334 100644 --- a/libguh-core/guhcore.cpp +++ b/libguh-core/guhcore.cpp @@ -448,6 +448,7 @@ void GuhCore::init() { m_cloudManager = new CloudManager(m_networkManager, this); m_cloudManager->setDeviceId(m_configuration->serverUuid()); + m_cloudManager->setDeviceName(m_configuration->serverName()); m_cloudManager->setServerUrl(m_configuration->cloudServerUrl()); m_cloudManager->setClientCertificates(m_configuration->cloudCertificateCA(), m_configuration->cloudCertificate(), m_configuration->cloudCertificateKey()); if (!m_configuration->cloudServerUrl().isEmpty()) {