diff --git a/source/SharedCrtResourceManager.cpp b/source/SharedCrtResourceManager.cpp index 115a1863..2945e90c 100644 --- a/source/SharedCrtResourceManager.cpp +++ b/source/SharedCrtResourceManager.cpp @@ -455,13 +455,29 @@ int SharedCrtResourceManager::establishConnection(const PlainConfig &config) connection->OnConnectionInterrupted = move(OnConnectionInterrupted); connection->OnConnectionResumed = move(OnConnectionResumed); + if (config.lastWillTopic.has_value() && config.lastWillMessage.has_value()) { + Aws::Crt::ByteBuf payload = Aws::Crt::ByteBufFromCString(config.lastWillMessage->c_str()); + connection->SetWill(config.lastWillTopic->c_str(), Aws::Crt::Mqtt::QOS::AWS_MQTT_QOS_AT_LEAST_ONCE, false, payload); + } + LOGM_INFO(TAG, "Establishing MQTT connection with client id %s...", config.thingName->c_str()); if (!connection->SetReconnectTimeout(15, 240)) { LOG_ERROR(TAG, "Device Client is not able to set reconnection settings. Device Client will retry again."); return RETRY; } - if (!connection->Connect(config.thingName->c_str(), false)) + + int keepAliveTimeSecs = 0; + if (config.connectKeepAlive.has_value()) { + keepAliveTimeSecs = *config.connectKeepAlive; + } + + int pingTimeoutMs = 0; + if (config.connectTimeout.has_value()) { + pingTimeoutMs = *config.connectTimeout; + } + + if (!connection->Connect(config.thingName->c_str(), false, keepAliveTimeSecs, pingTimeoutMs)) { LOGM_ERROR(TAG, "MQTT Connection failed with error: %s", ErrorDebugString(connection->LastError())); return RETRY; diff --git a/source/config/Config.cpp b/source/config/Config.cpp index a053176a..60887b3f 100644 --- a/source/config/Config.cpp +++ b/source/config/Config.cpp @@ -62,6 +62,10 @@ constexpr char PlainConfig::JSON_KEY_FLEET_PROVISIONING[]; constexpr char PlainConfig::JSON_KEY_RUNTIME_CONFIG[]; constexpr char PlainConfig::JSON_KEY_SAMPLES[]; constexpr char PlainConfig::JSON_KEY_PUB_SUB[]; +constexpr char PlainConfig::JSON_KEY_LAST_WILL_TOPIC[]; +constexpr char PlainConfig::JSON_KEY_LAST_WILL_MESSAGE[]; +constexpr char PlainConfig::JSON_KEY_CONNECT_TIMEOUT[]; +constexpr char PlainConfig::JSON_KEY_CONNECT_KEEPALIVE[]; constexpr char PlainConfig::JSON_KEY_SAMPLE_SHADOW[]; constexpr char PlainConfig::JSON_KEY_CONFIG_SHADOW[]; constexpr char PlainConfig::JSON_KEY_SECURE_ELEMENT[]; @@ -208,6 +212,30 @@ bool PlainConfig::LoadFromJson(const Crt::JsonView &json) } } + jsonKey = JSON_KEY_LAST_WILL_TOPIC; + if (json.ValueExists(jsonKey)) + { + lastWillTopic = json.GetString(jsonKey).c_str(); + } + + jsonKey = JSON_KEY_LAST_WILL_MESSAGE; + if (json.ValueExists(jsonKey)) + { + lastWillMessage = json.GetString(jsonKey).c_str(); + } + + jsonKey = JSON_KEY_CONNECT_TIMEOUT; + if (json.ValueExists(jsonKey)) + { + connectTimeout = json.GetInteger(jsonKey); + } + + jsonKey = JSON_KEY_CONNECT_KEEPALIVE; + if (json.ValueExists(jsonKey)) + { + connectKeepAlive = json.GetInteger(jsonKey); + } + jsonKey = JSON_KEY_SAMPLE_SHADOW; if (json.ValueExists(jsonKey)) { @@ -436,6 +464,22 @@ void PlainConfig::SerializeToObject(Crt::JsonObject &object) const { object.WithString(JSON_KEY_THING_NAME, thingName->c_str()); } + if (lastWillTopic.has_value() && lastWillTopic->c_str()) + { + object.WithString(JSON_KEY_LAST_WILL_TOPIC, lastWillTopic->c_str()); + } + if (lastWillMessage.has_value() && lastWillMessage->c_str()) + { + object.WithString(JSON_KEY_LAST_WILL_MESSAGE, lastWillMessage->c_str()); + } + if (connectTimeout.has_value() && connectTimeout) + { + object.WithInteger(JSON_KEY_CONNECT_TIMEOUT, *connectTimeout); + } + if (connectKeepAlive.has_value() && connectKeepAlive) + { + object.WithInteger(JSON_KEY_CONNECT_KEEPALIVE, *connectKeepAlive); + } Crt::JsonObject loggingObject; logConfig.SerializeToObject(loggingObject); diff --git a/source/config/Config.h b/source/config/Config.h index 965f2b3e..fb067061 100644 --- a/source/config/Config.h +++ b/source/config/Config.h @@ -94,6 +94,12 @@ namespace Aws static constexpr char JSON_KEY_SAMPLES[] = "samples"; static constexpr char JSON_KEY_PUB_SUB[] = "pub-sub"; + static constexpr char JSON_KEY_LAST_WILL_TOPIC[] = "last-will-topic"; + static constexpr char JSON_KEY_LAST_WILL_MESSAGE[] = "last-will-message"; + + static constexpr char JSON_KEY_CONNECT_TIMEOUT[] = "connect-timeout"; + static constexpr char JSON_KEY_CONNECT_KEEPALIVE[] = "keep-alive"; + static constexpr char JSON_KEY_SAMPLE_SHADOW[] = "sample-shadow"; static constexpr char JSON_KEY_CONFIG_SHADOW[] = "config-shadow"; static constexpr char JSON_KEY_SENSOR_PUBLISH[] = "sensor-publish"; @@ -107,6 +113,10 @@ namespace Aws Aws::Crt::Optional key; Aws::Crt::Optional rootCa; Aws::Crt::Optional thingName; + Aws::Crt::Optional lastWillTopic; + Aws::Crt::Optional lastWillMessage; + Aws::Crt::Optional connectTimeout; + Aws::Crt::Optional connectKeepAlive; std::string lockFilePath{DEFAULT_LOCK_FILE_PATH};