From 6bf060ae7d96ca4be363630840554bf2ddd99216 Mon Sep 17 00:00:00 2001 From: Igor Abdrakhimov Date: Wed, 11 Sep 2024 11:30:41 -0700 Subject: [PATCH 1/3] Fix race conditions in samples and service tests (#748) --- .../mqtt5_basic_report/main.cpp | 18 +- .../fleet_provisioning/main.cpp | 2 +- .../mqtt5_fleet_provisioning/main.cpp | 12 +- samples/jobs/mqtt5_job_execution/main.cpp | 6 +- samples/mqtt5/mqtt5_pubsub/main.cpp | 8 +- .../mqtt5/mqtt5_shared_subscription/main.cpp | 6 +- .../secure_tunneling/secure_tunnel/main.cpp | 4 + samples/shadow/mqtt5_shadow_sync/main.cpp | 7 +- servicetests/tests/FleetProvisioning/main.cpp | 763 +++++++++--------- 9 files changed, 417 insertions(+), 409 deletions(-) diff --git a/samples/device_defender/mqtt5_basic_report/main.cpp b/samples/device_defender/mqtt5_basic_report/main.cpp index 61f2bf522..6bbddf391 100644 --- a/samples/device_defender/mqtt5_basic_report/main.cpp +++ b/samples/device_defender/mqtt5_basic_report/main.cpp @@ -73,8 +73,19 @@ int main(int argc, char *argv[]) Utils::cmdData cmdData = Utils::parseSampleInputDeviceDefender(argc, argv, &apiHandle); // Create the MQTT builder and populate it with data from cmdData. - auto clientConfigBuilder = Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( - cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str()); + auto clientConfigBuilder = std::unique_ptr( + Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( + cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str())); + if (clientConfigBuilder == nullptr) + { + fprintf( + stdout, + "Failed to setup MQTT5 client builder with error code %d: %s", + LastError(), + ErrorDebugString(LastError())); + return -1; + } + if (cmdData.input_ca != "") { clientConfigBuilder->WithCertificateAuthority(cmdData.input_ca.c_str()); @@ -119,9 +130,6 @@ int main(int argc, char *argv[]) // Create Mqtt5Client std::shared_ptr client = clientConfigBuilder->Build(); - // Clean up the builder - delete clientConfigBuilder; - if (client == nullptr) { fprintf( diff --git a/samples/fleet_provisioning/fleet_provisioning/main.cpp b/samples/fleet_provisioning/fleet_provisioning/main.cpp index 02b307f7e..cc1f5bcaf 100644 --- a/samples/fleet_provisioning/fleet_provisioning/main.cpp +++ b/samples/fleet_provisioning/fleet_provisioning/main.cpp @@ -426,7 +426,7 @@ int main(int argc, char *argv[]) { /************************ Setup ****************************/ - // Do the global initialization for the API + // Do the global initialization for the API ApiHandle apiHandle; /** diff --git a/samples/fleet_provisioning/mqtt5_fleet_provisioning/main.cpp b/samples/fleet_provisioning/mqtt5_fleet_provisioning/main.cpp index 3ea7ef274..f065fcfd8 100644 --- a/samples/fleet_provisioning/mqtt5_fleet_provisioning/main.cpp +++ b/samples/fleet_provisioning/mqtt5_fleet_provisioning/main.cpp @@ -79,11 +79,12 @@ struct RegisterThingContext /** * Create MQTT5 client. */ -std::shared_ptr createMqtt5Client(Mqtt5ClientContext &ctx, const Utils::cmdData &cmdData) +std::shared_ptr createMqtt5Client(const Utils::cmdData &cmdData, Mqtt5ClientContext &ctx) { // Create the MQTT5 builder and populate it with data from cmdData. - Aws::Iot::Mqtt5ClientBuilder *builder = Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( - cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str()); + auto builder = std::unique_ptr( + Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( + cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str())); // Check if the builder setup correctly. if (builder == nullptr) @@ -128,7 +129,6 @@ std::shared_ptr createMqtt5Client(Mqtt5ClientConte // Create Mqtt5Client std::shared_ptr client = builder->Build(); - delete builder; return client; } @@ -418,7 +418,7 @@ int main(int argc, char *argv[]) { /************************ Setup ****************************/ - // Do the global initialization for the API + // Do the global initialization for the API ApiHandle apiHandle; /** @@ -429,7 +429,7 @@ int main(int argc, char *argv[]) Utils::cmdData cmdData = Utils::parseSampleInputFleetProvisioning(argc, argv, &apiHandle); Mqtt5ClientContext mqtt5ClientContext; - auto client = createMqtt5Client(mqtt5ClientContext, cmdData); + auto client = createMqtt5Client(cmdData, mqtt5ClientContext); /************************ Run the sample ****************************/ diff --git a/samples/jobs/mqtt5_job_execution/main.cpp b/samples/jobs/mqtt5_job_execution/main.cpp index 65e91d520..d3e3dbcd8 100644 --- a/samples/jobs/mqtt5_job_execution/main.cpp +++ b/samples/jobs/mqtt5_job_execution/main.cpp @@ -57,8 +57,9 @@ int main(int argc, char *argv[]) Utils::cmdData cmdData = Utils::parseSampleInputJobs(argc, argv, &apiHandle); // Create the MQTT5 builder and populate it with data from cmdData. - Aws::Iot::Mqtt5ClientBuilder *builder = Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( - cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str()); + auto builder = std::unique_ptr( + Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( + cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str())); // Check if the builder setup correctly. if (builder == nullptr) @@ -101,7 +102,6 @@ int main(int argc, char *argv[]) // Create Mqtt5Client std::shared_ptr client = builder->Build(); - delete builder; /************************ Run the sample ****************************/ fprintf(stdout, "Connecting...\n"); diff --git a/samples/mqtt5/mqtt5_pubsub/main.cpp b/samples/mqtt5/mqtt5_pubsub/main.cpp index 9f65cae4e..479146c5a 100644 --- a/samples/mqtt5/mqtt5_pubsub/main.cpp +++ b/samples/mqtt5/mqtt5_pubsub/main.cpp @@ -34,8 +34,9 @@ int main(int argc, char *argv[]) Utils::cmdData cmdData = Utils::parseSampleInputPubSub(argc, argv, &apiHandle, "mqtt5-pubsub"); // Create the MQTT5 builder and populate it with data from cmdData. - Aws::Iot::Mqtt5ClientBuilder *builder = Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( - cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str()); + auto builder = std::unique_ptr( + Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( + cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str())); // Check if the builder setup correctly. if (builder == nullptr) @@ -107,9 +108,6 @@ int main(int argc, char *argv[]) // Create Mqtt5Client std::shared_ptr client = builder->Build(); - // Clean up the builder - delete builder; - if (client == nullptr) { fprintf( diff --git a/samples/mqtt5/mqtt5_shared_subscription/main.cpp b/samples/mqtt5/mqtt5_shared_subscription/main.cpp index 998792ae9..6f8085699 100644 --- a/samples/mqtt5/mqtt5_shared_subscription/main.cpp +++ b/samples/mqtt5/mqtt5_shared_subscription/main.cpp @@ -45,8 +45,9 @@ class sample_mqtt5_client std::shared_ptr result = std::make_shared(); result->name = input_clientName; - Aws::Iot::Mqtt5ClientBuilder *builder = Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( - input_endpoint, input_cert.c_str(), input_key.c_str()); + auto builder = std::unique_ptr( + Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( + input_endpoint, input_cert.c_str(), input_key.c_str())); if (builder == nullptr) { return nullptr; @@ -136,7 +137,6 @@ class sample_mqtt5_client }); result->client = builder->Build(); - delete builder; return result; } }; diff --git a/samples/secure_tunneling/secure_tunnel/main.cpp b/samples/secure_tunneling/secure_tunnel/main.cpp index 4f39c3c10..cbae47690 100644 --- a/samples/secure_tunneling/secure_tunnel/main.cpp +++ b/samples/secure_tunneling/secure_tunnel/main.cpp @@ -133,6 +133,7 @@ int main(int argc, char *argv[]) * In a real world application you probably don't want to enforce synchronous behavior * but this is a sample console application, so we'll just do that with a condition variable. */ + std::promise clientConnectedPromise; std::promise clientStoppedPromise; // service id storage for use in sample @@ -285,6 +286,7 @@ int main(int argc, char *argv[]) fprintf(stdout, "Sending Stream Start request\n"); secureTunnel->SendStreamStart(); } + clientConnectedPromise.set_value(); } }); @@ -345,6 +347,8 @@ int main(int argc, char *argv[]) exit(-1); } + clientConnectedPromise.get_future().wait_for(std::chrono::seconds(5)); + /* * In Destination mode the Secure Tunnel Client will remain open and echo messages that come in. * In Source mode the Secure Tunnel Client will send 4 messages and then disconnect and terminate. diff --git a/samples/shadow/mqtt5_shadow_sync/main.cpp b/samples/shadow/mqtt5_shadow_sync/main.cpp index 12bc00353..b55b1d1cf 100644 --- a/samples/shadow/mqtt5_shadow_sync/main.cpp +++ b/samples/shadow/mqtt5_shadow_sync/main.cpp @@ -104,9 +104,9 @@ int main(int argc, char *argv[]) Utils::cmdData cmdData = Utils::parseSampleInputShadow(argc, argv, &apiHandle); // Create the MQTT5 builder and populate it with data from cmdData. - Aws::Iot::Mqtt5ClientBuilder *builder = Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( - cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str()); - + auto builder = std::unique_ptr( + Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( + cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str())); // Check if the builder setup correctly. if (builder == nullptr) { @@ -148,7 +148,6 @@ int main(int argc, char *argv[]) // Create Mqtt5Client std::shared_ptr client = builder->Build(); - delete builder; /************************ Run the sample ****************************/ fprintf(stdout, "Connecting...\n"); diff --git a/servicetests/tests/FleetProvisioning/main.cpp b/servicetests/tests/FleetProvisioning/main.cpp index ff4c042aa..f99bd17e7 100644 --- a/servicetests/tests/FleetProvisioning/main.cpp +++ b/servicetests/tests/FleetProvisioning/main.cpp @@ -2,11 +2,9 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ + #include #include -#include -#include - #include #include #include @@ -23,515 +21,500 @@ #include #include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include #include "../../../samples/utils/CommandLineUtils.h" using namespace Aws::Crt; using namespace Aws::Iotidentity; -static std::promise gotResponse; - -static std::string getFileData(std::string const &fileName) +static String getFileData(const String &fileName) { - std::ifstream ifs(fileName); + std::ifstream ifs(fileName.c_str()); std::string str; getline(ifs, str, (char)ifs.eof()); - return str; + return str.c_str(); } -std::shared_ptr build_mqtt3_client( - Utils::cmdData &cmdData, - std::shared_ptr &connection, - std::promise &connectionCompletedPromise, - std::promise &connectionClosedPromise) +/** + * Auxiliary structure for holding data used by MQTT3 connection. + */ +struct Mqtt3ConnectionContext { - Aws::Iot::MqttClientConnectionConfigBuilder clientConfigBuilder; - // Create the MQTT builder and populate it with data from cmdData. - clientConfigBuilder = - Aws::Iot::MqttClientConnectionConfigBuilder(cmdData.input_cert.c_str(), cmdData.input_key.c_str()); - clientConfigBuilder.WithEndpoint(cmdData.input_endpoint); - if (cmdData.input_ca != "") + std::promise connectionCompletedPromise; + std::promise connectionClosedPromise; +}; + +/** + * Auxiliary structure for holding data used by MQTT5 connection. + */ +struct Mqtt5ClientContext +{ + std::promise connectionPromise; + std::promise stoppedPromise; + std::promise disconnectPromise; + std::promise subscribeSuccess; +}; + +/** + * Auxiliary structure for holding data used when creating a certificate. + */ +struct CreateCertificateContext +{ + std::promise pubAckPromise; + std::promise acceptedSubAckPromise; + std::promise rejectedSubAckPromise; + std::promise tokenPromise; +}; + +/** + * Auxiliary structure for holding data used when registering a thing. + */ +struct RegisterThingContext +{ + std::promise pubAckPromise; + std::promise acceptedSubAckPromise; + std::promise rejectedSubAckPromise; + std::promise thingCreatedPromise; +}; + +/** + * Create MQTT5 client. + */ +std::shared_ptr createMqtt5Client(const Utils::cmdData &cmdData, Mqtt5ClientContext &ctx) +{ + // Create the MQTT5 builder and populate it with data from cmdData. + auto builder = std::unique_ptr( + Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( + cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str())); + + // Check if the builder setup correctly. + if (builder == nullptr) { - clientConfigBuilder.WithCertificateAuthority(cmdData.input_ca.c_str()); + printf( + "Failed to setup mqtt5 client builder with error code %d: %s", LastError(), ErrorDebugString(LastError())); + return nullptr; } - // Create the MQTT connection from the MQTT builder - auto clientConfig = clientConfigBuilder.Build(); - if (!clientConfig) + // Setup connection options + std::shared_ptr connectOptions = std::make_shared(); + connectOptions->WithClientId(cmdData.input_clientId); + builder->WithConnectOptions(connectOptions); + if (cmdData.input_port != 0) { + builder->WithPort(static_cast(cmdData.input_port)); + } + + // Setup lifecycle callbacks + builder->WithClientConnectionSuccessCallback([&ctx](const Mqtt5::OnConnectionSuccessEventData &eventData) { fprintf( - stderr, - "Client Configuration initialization failed with error %s\n", - Aws::Crt::ErrorDebugString(clientConfig.LastError())); - exit(-1); + stdout, + "Mqtt5 Client connection succeed, clientid: %s.\n", + eventData.negotiatedSettings->getClientId().c_str()); + ctx.connectionPromise.set_value(true); + }); + builder->WithClientConnectionFailureCallback([&ctx](const Mqtt5::OnConnectionFailureEventData &eventData) { + fprintf(stdout, "Mqtt5 Client connection failed with error: %s.\n", aws_error_debug_str(eventData.errorCode)); + ctx.connectionPromise.set_value(false); + }); + builder->WithClientStoppedCallback([&ctx](const Mqtt5::OnStoppedEventData &) { + fprintf(stdout, "Mqtt5 Client stopped.\n"); + ctx.stoppedPromise.set_value(); + }); + builder->WithClientAttemptingConnectCallback([](const Mqtt5::OnAttemptingConnectEventData &) { + fprintf(stdout, "Mqtt5 Client attempting connection...\n"); + }); + builder->WithClientDisconnectionCallback([&ctx](const Mqtt5::OnDisconnectionEventData &eventData) { + fprintf(stdout, "Mqtt5 Client disconnection with reason: %s.\n", aws_error_debug_str(eventData.errorCode)); + ctx.disconnectPromise.set_value(); + }); + + // Create Mqtt5Client + auto client = builder->Build(); + + fprintf(stdout, "Connecting...\n"); + if (!client->Start()) + { + fprintf(stderr, "MQTT5 Connection failed to start"); + return nullptr; } - Aws::Iot::MqttClient client3 = Aws::Iot::MqttClient(); - connection = client3.NewConnection(clientConfig); - if (!*connection) + if (!ctx.connectionPromise.get_future().get()) { - fprintf( - stderr, - "MQTT Connection Creation failed with error %s\n", - Aws::Crt::ErrorDebugString(connection->LastError())); - exit(-1); + return nullptr; } + return client; +} + +/** + * Create MQTT3 connection. + */ +std::shared_ptr createMqtt3Connection(const Utils::cmdData &cmdData, Mqtt3ConnectionContext &ctx) +{ + /** + * In a real world application you probably don't want to enforce synchronous behavior + * but this is a sample console application, so we'll just do that with a promise. + */ + // Invoked when a MQTT connect has completed or failed - auto onConnectionCompleted = [&](Mqtt::MqttConnection &, int errorCode, Mqtt::ReturnCode returnCode, bool) { + auto onConnectionCompleted = [&ctx](Mqtt::MqttConnection &, int errorCode, Mqtt::ReturnCode returnCode, bool) { if (errorCode) { fprintf(stdout, "Connection failed with error %s\n", ErrorDebugString(errorCode)); - connectionCompletedPromise.set_value(false); + ctx.connectionCompletedPromise.set_value(false); } else { fprintf(stdout, "Connection completed with return code %d\n", returnCode); - connectionCompletedPromise.set_value(true); + ctx.connectionCompletedPromise.set_value(true); } }; // Invoked when a disconnect has been completed - auto onDisconnect = [&](Mqtt::MqttConnection & /*conn*/) { + auto onDisconnect = [&ctx](Mqtt::MqttConnection & /*conn*/) { { fprintf(stdout, "Disconnect completed\n"); - connectionClosedPromise.set_value(); + ctx.connectionClosedPromise.set_value(); } }; - connection->OnConnectionCompleted = std::move(onConnectionCompleted); - connection->OnDisconnect = std::move(onDisconnect); - - if (!connection->Connect(cmdData.input_clientId.c_str(), true, 0)) + // Create the MQTT builder and populate it with data from cmdData. + auto clientConfigBuilder = + Aws::Iot::MqttClientConnectionConfigBuilder(cmdData.input_cert.c_str(), cmdData.input_key.c_str()); + clientConfigBuilder.WithEndpoint(cmdData.input_endpoint); + if (cmdData.input_ca != "") { - fprintf(stderr, "MQTT Connection failed with error %s\n", ErrorDebugString(connection->LastError())); - exit(-1); + clientConfigBuilder.WithCertificateAuthority(cmdData.input_ca.c_str()); } - return std::make_shared(connection); -} -std::shared_ptr build_mqtt5_client( - Utils::cmdData &cmdData, - std::shared_ptr &client5, - std::promise &connectionCompletedPromise, - std::promise &connectionClosedPromise) -{ - std::shared_ptr builder( - Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath( - cmdData.input_endpoint, cmdData.input_cert.c_str(), cmdData.input_key.c_str())); - - // Check if the builder setup correctly. - if (builder == nullptr) + // Create the MQTT connection from the MQTT builder + auto clientConfig = clientConfigBuilder.Build(); + if (!clientConfig) { - printf( - "Failed to setup mqtt5 client builder with error code %d: %s", LastError(), ErrorDebugString(LastError())); + fprintf( + stderr, + "Client Configuration initialization failed with error %s\n", + Aws::Crt::ErrorDebugString(clientConfig.LastError())); return nullptr; } - // Create the MQTT5 builder and populate it with data from cmdData. - // Setup connection options - std::shared_ptr connectOptions = std::make_shared(); - connectOptions->WithClientId(cmdData.input_clientId); - builder->WithConnectOptions(connectOptions); - if (cmdData.input_port != 0) + Aws::Iot::MqttClient client = Aws::Iot::MqttClient(); + auto connection = client.NewConnection(clientConfig); + if (!*connection) { - builder->WithPort(static_cast(cmdData.input_port)); + fprintf( + stderr, + "MQTT Connection Creation failed with error %s\n", + Aws::Crt::ErrorDebugString(connection->LastError())); + return nullptr; } - // Setup lifecycle callbacks - builder->WithClientConnectionSuccessCallback( - [&connectionCompletedPromise](const Mqtt5::OnConnectionSuccessEventData &eventData) { - fprintf( - stdout, - "Mqtt5 Client connection succeed, clientid: %s.\n", - eventData.negotiatedSettings->getClientId().c_str()); - connectionCompletedPromise.set_value(true); - }); - builder->WithClientConnectionFailureCallback([&connectionCompletedPromise]( - const Mqtt5::OnConnectionFailureEventData &eventData) { - fprintf(stdout, "Mqtt5 Client connection failed with error: %s.\n", aws_error_debug_str(eventData.errorCode)); - connectionCompletedPromise.set_value(false); - }); - builder->WithClientStoppedCallback([&connectionClosedPromise](const Mqtt5::OnStoppedEventData &) { - fprintf(stdout, "Mqtt5 Client stopped.\n"); - connectionClosedPromise.set_value(); - }); - client5 = builder->Build(); - if (client5 == nullptr) + connection->OnConnectionCompleted = std::move(onConnectionCompleted); + connection->OnDisconnect = std::move(onDisconnect); + + fprintf(stdout, "Connecting...\n"); + if (!connection->Connect(cmdData.input_clientId.c_str(), true, 0)) { - fprintf( - stdout, "Failed to Init Mqtt5Client with error code %d: %s.\n", LastError(), ErrorDebugString(LastError())); - exit(-1); + fprintf(stderr, "MQTT Connection failed with error %s\n", ErrorDebugString(connection->LastError())); + return nullptr; } - if (!client5->Start()) + if (!ctx.connectionCompletedPromise.get_future().get()) { - fprintf(stderr, "MQTT5 Connection failed to start"); - exit(-1); + return nullptr; } - return std::make_shared(client5); + + return connection; } -void SubscribeToRegisterThing(String input_templateName, std::shared_ptr iotIdentityClient) +/** + * Keys-and-Certificate workflow. + * + * @note Subscriptions created here will be active even after the function completes. So, all variables accessed in the + * callbacks must be alive for the whole duration of the identityClient's lifetime. An instance of + * CreateCertificateContext is used to store variables used by the callbacks. + */ +void createKeysAndCertificate(const std::shared_ptr &identityClient, CreateCertificateContext &ctx) { - std::promise onSubAckPromise; - std::promise registerRejectedCompletedPromise; - std::promise registerAcceptedCompletedPromise; - - auto onRegisterThingAccepted = [&](RegisterThingResponse *response, int ioErr) { - if (ioErr) + auto onKeysPublishPubAck = [&ctx](int ioErr) { + if (ioErr != AWS_OP_SUCCESS) { - fprintf(stderr, "Error: onSuback callback error %d\n", ioErr); + fprintf(stderr, "Error publishing to CreateKeysAndCertificate: %s\n", ErrorDebugString(ioErr)); exit(-1); } - if (response) + ctx.pubAckPromise.set_value(); + }; + + auto onKeysAcceptedSubAck = [&ctx](int ioErr) { + if (ioErr != AWS_OP_SUCCESS) { - fprintf(stdout, "Register thing: %s\n", response->ThingName.value().c_str()); + fprintf(stderr, "Error subscribing to CreateKeysAndCertificate accepted: %s\n", ErrorDebugString(ioErr)); + exit(-1); } + ctx.acceptedSubAckPromise.set_value(); }; - RegisterThingSubscriptionRequest registerThingSubscriptionRequest; - registerThingSubscriptionRequest.TemplateName = input_templateName; - - auto onRegisterAcceptedSubAck = [&](int ioErr) { + auto onKeysRejectedSubAck = [&ctx](int ioErr) { if (ioErr != AWS_OP_SUCCESS) { - fprintf(stderr, "Error subscribing to RegisterThing accepted: %s\n", ErrorDebugString(ioErr)); + fprintf(stderr, "Error subscribing to CreateKeysAndCertificate rejected: %s\n", ErrorDebugString(ioErr)); exit(-1); } - registerAcceptedCompletedPromise.set_value(); + ctx.rejectedSubAckPromise.set_value(); }; - iotIdentityClient->SubscribeToRegisterThingAccepted( - registerThingSubscriptionRequest, - AWS_MQTT_QOS_AT_LEAST_ONCE, - onRegisterThingAccepted, - onRegisterAcceptedSubAck); - - auto rejectedHandler = [&](ErrorResponse *error, int ioErr) { - if (ioErr) + auto onKeysAccepted = [&ctx](CreateKeysAndCertificateResponse *response, int ioErr) { + if (ioErr == AWS_OP_SUCCESS) { - fprintf(stderr, "Error: rejectedHandler callback error %d\n", ioErr); - exit(-1); + fprintf(stdout, "CreateKeysAndCertificateResponse certificateId: %s.\n", response->CertificateId->c_str()); + ctx.tokenPromise.set_value(*response->CertificateOwnershipToken); } else + { + fprintf(stderr, "Error on subscription: %s.\n", ErrorDebugString(ioErr)); + exit(-1); + } + }; + + auto onKeysRejected = [](ErrorResponse *error, int ioErr) { + if (ioErr == AWS_OP_SUCCESS) { fprintf( stdout, - "RegisterThing failed with statusCode %d, errorMessage %s and errorCode %s.", + "CreateKeysAndCertificate failed with statusCode %d, errorMessage %s and errorCode %s.", *error->StatusCode, error->ErrorMessage->c_str(), error->ErrorCode->c_str()); + exit(-1); } - }; - auto onRegisterRejectedSubAck = [&](int ioErr) { - if (ioErr != AWS_OP_SUCCESS) + else { - fprintf(stderr, "Error subscribing to RegisterThing rejected: %s\n", ErrorDebugString(ioErr)); + fprintf(stderr, "Error on subscription: %s.\n", ErrorDebugString(ioErr)); exit(-1); } - registerRejectedCompletedPromise.set_value(); }; - iotIdentityClient->SubscribeToRegisterThingRejected( - registerThingSubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, rejectedHandler, onRegisterRejectedSubAck); - - registerAcceptedCompletedPromise.get_future().wait(); - registerRejectedCompletedPromise.get_future().wait(); -} -void createKeysAndCertificateWorkflow( - String &input_templateName, - String &input_templateParameters, - std::shared_ptr iotIdentityClient) -{ - std::promise onSubAckPromise; + fprintf(stdout, "Subscribing to CreateKeysAndCertificate Accepted and Rejected topics\n"); + CreateKeysAndCertificateSubscriptionRequest keySubscriptionRequest; + identityClient->SubscribeToCreateKeysAndCertificateAccepted( + keySubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onKeysAccepted, onKeysAcceptedSubAck); + identityClient->SubscribeToCreateKeysAndCertificateRejected( + keySubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onKeysRejected, onKeysRejectedSubAck); - std::promise keysPublishCompletedPromise; - std::promise keysAcceptedCompletedPromise; - std::promise keysRejectedCompletedPromise; + // Wait for the subscriptions to the accept and reject keys-and-certificate topics to be established. + ctx.acceptedSubAckPromise.get_future().wait(); + ctx.rejectedSubAckPromise.get_future().wait(); - std::promise registerPublishCompletedPromise; - std::promise registerAcceptedCompletedPromise; - - CreateKeysAndCertificateResponse *createKeysAndCertificateResponse = nullptr; - String token; + // Now, when we subscribed to the keys and certificate topics, we can make a request for a certificate. + fprintf(stdout, "Publishing to CreateKeysAndCertificate topic\n"); + CreateKeysAndCertificateRequest createKeysAndCertificateRequest; + identityClient->PublishCreateKeysAndCertificate( + createKeysAndCertificateRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onKeysPublishPubAck); + ctx.pubAckPromise.get_future().wait(); +} - auto acceptedHandler = [&createKeysAndCertificateResponse, - &token](CreateKeysAndCertificateResponse *response, int ioErr) { - fprintf(stderr, "acceptedhandler is called\n"); - if (ioErr) +/** + * Certificate-from-CSR workflow. + * + * @note Subscriptions created here will be active even after the function completes. So, all variables accessed in the + * callbacks must be alive for the whole duration of the identityClient's lifetime. An instance of + * CreateCertificateContext is used to store variables used by the callbacks. + */ +void createCertificateFromCsr( + const std::shared_ptr &identityClient, + CreateCertificateContext &ctx, + const String &csrFile) +{ + auto onCsrPublishPubAck = [&ctx](int ioErr) { + if (ioErr != AWS_OP_SUCCESS) { - fprintf(stderr, "Error: acceptedHandler callback error %d\n", ioErr); + fprintf(stderr, "Error publishing to CreateCertificateFromCsr: %s\n", ErrorDebugString(ioErr)); exit(-1); } - if (response) + ctx.pubAckPromise.set_value(); + }; + + auto onCsrAcceptedSubAck = [&ctx](int ioErr) { + if (ioErr != AWS_OP_SUCCESS) { - if (createKeysAndCertificateResponse == nullptr) - { - createKeysAndCertificateResponse = response; - token = *response->CertificateOwnershipToken; - } + fprintf(stderr, "Error subscribing to CreateCertificateFromCsr accepted: %s\n", ErrorDebugString(ioErr)); + exit(-1); } - gotResponse.set_value(); + ctx.acceptedSubAckPromise.set_value(); }; - auto onKeysAcceptedSubAck = [&](int ioErr) { + auto onCsrRejectedSubAck = [&ctx](int ioErr) { if (ioErr != AWS_OP_SUCCESS) { - fprintf(stderr, "Error subscribing to CreateKeysAndCertificate accepted: %s\n", ErrorDebugString(ioErr)); + fprintf(stderr, "Error subscribing to CreateCertificateFromCsr rejected: %s\n", ErrorDebugString(ioErr)); exit(-1); } - - keysAcceptedCompletedPromise.set_value(); + ctx.rejectedSubAckPromise.set_value(); }; - CreateKeysAndCertificateSubscriptionRequest createKeysAndCertificateSubscriptionRequest; - iotIdentityClient->SubscribeToCreateKeysAndCertificateAccepted( - createKeysAndCertificateSubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, acceptedHandler, onKeysAcceptedSubAck); - - auto rejectedHandler = [&](Aws::Iotidentity::ErrorResponse *error, int ioErr) { - if (ioErr == AWS_OP_ERR) + auto onCsrAccepted = [&ctx](CreateCertificateFromCsrResponse *response, int ioErr) { + if (ioErr == AWS_OP_SUCCESS) { - fprintf(stderr, "Error: rejectedHandler callback error %s\n", ErrorDebugString(ioErr)); + fprintf(stdout, "CreateCertificateFromCsrResponse certificateId: %s.\n", response->CertificateId->c_str()); + ctx.tokenPromise.set_value(*response->CertificateOwnershipToken); + } + else + { + fprintf(stderr, "Error on subscription: %s.\n", ErrorDebugString(ioErr)); exit(-1); } - if (error) + }; + + auto onCsrRejected = [](ErrorResponse *error, int ioErr) { + if (ioErr == AWS_OP_SUCCESS) { fprintf( stdout, - "CreateKeysAndCertificate failed with statusCode %d, errorMessage %s and errorCode %s.", + "CreateCertificateFromCsr failed with statusCode %d, errorMessage %s and errorCode %s.", *error->StatusCode, error->ErrorMessage->c_str(), error->ErrorCode->c_str()); - } - exit(-1); - }; - - auto onKeysRejectedSubAck = [&](int ioErr) { - if (ioErr != AWS_OP_SUCCESS) - { - fprintf(stderr, "Error subscribing to CreateKeysAndCertificate rejected: %s\n", ErrorDebugString(ioErr)); exit(-1); } - keysRejectedCompletedPromise.set_value(); - }; - iotIdentityClient->SubscribeToCreateKeysAndCertificateRejected( - createKeysAndCertificateSubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, rejectedHandler, onKeysRejectedSubAck); - - auto onKeysPublishSubAck = [&](int ioErr) { - if (ioErr != AWS_OP_SUCCESS) + else { - fprintf(stderr, "Error publishing to CreateKeysAndCertificate: %s\n", ErrorDebugString(ioErr)); + fprintf(stderr, "Error on subscription: %s.\n", ErrorDebugString(ioErr)); exit(-1); } - - keysPublishCompletedPromise.set_value(); }; - CreateKeysAndCertificateRequest createKeysAndCertificateRequest; - iotIdentityClient->PublishCreateKeysAndCertificate( - createKeysAndCertificateRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onKeysPublishSubAck); - - SubscribeToRegisterThing(input_templateName, iotIdentityClient); - std::this_thread::sleep_for(std::chrono::seconds(1)); - - // Verify the response is good - if (createKeysAndCertificateResponse == nullptr) - { - fprintf(stderr, "Error: 1 createKeysAndCertificateResponse is null\n"); - exit(-1); - } - // reset gotResponse future - gotResponse = std::promise(); + // CreateCertificateFromCsr workflow + fprintf(stdout, "Subscribing to CreateCertificateFromCsr Accepted and Rejected topics\n"); + CreateCertificateFromCsrSubscriptionRequest csrSubscriptionRequest; + identityClient->SubscribeToCreateCertificateFromCsrAccepted( + csrSubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onCsrAccepted, onCsrAcceptedSubAck); - RegisterThingRequest registerThingRequest; - registerThingRequest.TemplateName = input_templateName; + identityClient->SubscribeToCreateCertificateFromCsrRejected( + csrSubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onCsrRejected, onCsrRejectedSubAck); - if (!input_templateParameters.empty()) - { - const Aws::Crt::String jsonValue = input_templateParameters; - Aws::Crt::JsonObject value(jsonValue); - Map pm = value.View().GetAllObjects(); - Aws::Crt::Map params = Aws::Crt::Map(); + // Wait for the subscriptions to the accept and reject certificates topics to be established. + ctx.acceptedSubAckPromise.get_future().wait(); + ctx.rejectedSubAckPromise.get_future().wait(); - for (const auto &x : pm) - { - params.emplace(x.first, x.second.AsString()); - } - registerThingRequest.Parameters = params; - } - registerThingRequest.CertificateOwnershipToken = token; + // Now, when we subscribed to the certificates topics, we can make a request for a certificate. + fprintf(stdout, "Publishing to CreateCertificateFromCsr topic\n"); + CreateCertificateFromCsrRequest createCertificateFromCsrRequest; + createCertificateFromCsrRequest.CertificateSigningRequest = csrFile; + identityClient->PublishCreateCertificateFromCsr( + createCertificateFromCsrRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onCsrPublishPubAck); + ctx.pubAckPromise.get_future().wait(); +} - auto onRegisterPublishSubAck = [&](int ioErr) { +/** + * Provision an AWS IoT thing using a pre-defined template. + */ +void registerThing( + const std::shared_ptr &identityClient, + RegisterThingContext &ctx, + const Utils::cmdData &cmdData, + const String &token) +{ + auto onRegisterAcceptedSubAck = [&ctx](int ioErr) { if (ioErr != AWS_OP_SUCCESS) { - fprintf(stderr, "Error publishing to RegisterThing: %s\n", ErrorDebugString(ioErr)); + fprintf(stderr, "Error subscribing to RegisterThing accepted: %s\n", ErrorDebugString(ioErr)); exit(-1); } - - registerPublishCompletedPromise.set_value(); + ctx.acceptedSubAckPromise.set_value(); }; - iotIdentityClient->PublishRegisterThing(registerThingRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onRegisterPublishSubAck); - std::this_thread::sleep_for(std::chrono::seconds(1)); - - keysPublishCompletedPromise.get_future().wait(); - keysAcceptedCompletedPromise.get_future().wait(); - keysRejectedCompletedPromise.get_future().wait(); - registerPublishCompletedPromise.get_future().wait(); -} -void createCertificateFromCsrWorkflow( - String input_templateName, - String input_templateParameters, - String input_csrPath, - std::shared_ptr iotIdentityClient) -{ - std::promise keysPublishCompletedPromise; - std::promise keysAcceptedCompletedPromise; - std::promise keysRejectedCompletedPromise; - - std::promise registerPublishCompletedPromise; - std::promise registerAcceptedCompletedPromise; - CreateCertificateFromCsrResponse *createCertificateFromCsrResponse = nullptr; - String token; - - gotResponse = std::promise(); - - auto onCreateCertificateFromCsrResponseAccepted = [&createCertificateFromCsrResponse, - &token](CreateCertificateFromCsrResponse *response, int ioErr) { - if (ioErr) + auto onRegisterRejectedSubAck = [&ctx](int ioErr) { + if (ioErr != AWS_OP_SUCCESS) { - fprintf(stderr, "Error: onCreateCertificateFromCsrResponseAccepted callback error %d\n", ioErr); + fprintf(stderr, "Error subscribing to RegisterThing rejected: %s\n", ErrorDebugString(ioErr)); exit(-1); } - if (response != nullptr) - { - if (createCertificateFromCsrResponse == nullptr) - { - createCertificateFromCsrResponse = response; - token = *response->CertificateOwnershipToken; - } - } - gotResponse.set_value(); + ctx.rejectedSubAckPromise.set_value(); }; - auto onSubAck = [&](int ioErr) { - if (ioErr) + auto onRegisterAccepted = [&ctx](RegisterThingResponse *response, int ioErr) { + if (ioErr == AWS_OP_SUCCESS) { - fprintf(stderr, "Error: onSubAck callback error %d\n", ioErr); - exit(-1); + fprintf(stdout, "RegisterThingResponse ThingName: %s.\n", response->ThingName->c_str()); + ctx.thingCreatedPromise.set_value(); } - keysAcceptedCompletedPromise.set_value(); - }; - - CreateCertificateFromCsrSubscriptionRequest createCertificateFromCsrSubscriptionRequest; - iotIdentityClient->SubscribeToCreateCertificateFromCsrAccepted( - createCertificateFromCsrSubscriptionRequest, - AWS_MQTT_QOS_AT_LEAST_ONCE, - onCreateCertificateFromCsrResponseAccepted, - onSubAck); - - auto onRejectedCsr = [&](ErrorResponse *response, int ioErr) { - (void)response; - if (ioErr) + else { - fprintf(stderr, "Error: onSubAck callback error %d\n", ioErr); + fprintf(stderr, "Error on subscription: %s.\n", ErrorDebugString(ioErr)); exit(-1); } - exit(1); }; - auto onKeysRejectedSubAck = [&](int ioErr) { - if (ioErr != AWS_OP_SUCCESS) + auto onRegisterRejected = [](ErrorResponse *error, int ioErr) { + if (ioErr == AWS_OP_SUCCESS) { - fprintf(stderr, "Error subscribing to CreateKeysAndCertificate rejected: %s\n", ErrorDebugString(ioErr)); + fprintf( + stdout, + "RegisterThing failed with statusCode %d, errorMessage %s and errorCode %s.", + *error->StatusCode, + error->ErrorMessage->c_str(), + error->ErrorCode->c_str()); + } + else + { + fprintf(stderr, "Error on subscription: %s.\n", ErrorDebugString(ioErr)); exit(-1); } - keysRejectedCompletedPromise.set_value(); }; - iotIdentityClient->SubscribeToCreateCertificateFromCsrRejected( - createCertificateFromCsrSubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onRejectedCsr, onKeysRejectedSubAck); - - auto onKeysPublishSubAck = [&](int ioErr) { + auto onRegisterPublishPubAck = [&ctx](int ioErr) { if (ioErr != AWS_OP_SUCCESS) { - fprintf(stderr, "Error publishing to CreateKeysAndCertificate: %s\n", ErrorDebugString(ioErr)); + fprintf(stderr, "Error publishing to RegisterThing: %s\n", ErrorDebugString(ioErr)); exit(-1); } - keysPublishCompletedPromise.set_value(); + ctx.pubAckPromise.set_value(); }; - std::string csrContents = getFileData(input_csrPath.c_str()); - CreateCertificateFromCsrRequest createCertificateFromCsrRequest; - createCertificateFromCsrRequest.CertificateSigningRequest = csrContents.c_str(); + fprintf(stdout, "Subscribing to RegisterThing Accepted and Rejected topics\n"); + RegisterThingSubscriptionRequest registerSubscriptionRequest; + registerSubscriptionRequest.TemplateName = cmdData.input_templateName; - iotIdentityClient->PublishCreateCertificateFromCsr( - createCertificateFromCsrRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onKeysPublishSubAck); + identityClient->SubscribeToRegisterThingAccepted( + registerSubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onRegisterAccepted, onRegisterAcceptedSubAck); - // Subscribes to the register thing accepted and rejected topics - SubscribeToRegisterThing(input_templateName, iotIdentityClient); - std::this_thread::sleep_for(std::chrono::seconds(1)); + identityClient->SubscribeToRegisterThingRejected( + registerSubscriptionRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onRegisterRejected, onRegisterRejectedSubAck); - // Verify the response is good - if (createCertificateFromCsrResponse == nullptr) - { - fprintf(stderr, "Error: 1 createCertificateFromCsrResponse is null\n"); - exit(-1); - } - // reset gotResponse future - gotResponse = std::promise(); + // Wait for the subscriptions to the accept and reject RegisterThing topics to be established. + ctx.acceptedSubAckPromise.get_future().wait(); + ctx.rejectedSubAckPromise.get_future().wait(); + fprintf(stdout, "Publishing to RegisterThing topic\n"); RegisterThingRequest registerThingRequest; - registerThingRequest.CertificateOwnershipToken = token; - registerThingRequest.TemplateName = input_templateName; + registerThingRequest.TemplateName = cmdData.input_templateName; - if (!input_templateParameters.empty()) - { - const Aws::Crt::String jsonValue = input_templateParameters; - Aws::Crt::JsonObject value(jsonValue); - Map pm = value.View().GetAllObjects(); - Aws::Crt::Map params = Aws::Crt::Map(); + const Aws::Crt::String jsonValue = cmdData.input_templateParameters; + Aws::Crt::JsonObject value(jsonValue); + Map pm = value.View().GetAllObjects(); + Aws::Crt::Map params = Aws::Crt::Map(); - for (const auto &x : pm) - { - params.emplace(x.first, x.second.AsString()); - } - registerThingRequest.Parameters = params; + for (const auto &x : pm) + { + params.emplace(x.first, x.second.AsString()); } - auto onRegisterPublishSubAck = [&](int ioErr) { - if (ioErr != AWS_OP_SUCCESS) - { - fprintf(stderr, "Error publishing to RegisterThing: %s\n", ErrorDebugString(ioErr)); - exit(-1); - } - - registerPublishCompletedPromise.set_value(); - }; - iotIdentityClient->PublishRegisterThing(registerThingRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onRegisterPublishSubAck); + registerThingRequest.Parameters = params; + // NOTE: In a real application creating multiple certificates you'll probably need to protect token var with + // a critical section. This sample makes only one request for a certificate, so no data race is possible. + registerThingRequest.CertificateOwnershipToken = token; - std::this_thread::sleep_for(std::chrono::seconds(1)); + identityClient->PublishRegisterThing(registerThingRequest, AWS_MQTT_QOS_AT_LEAST_ONCE, onRegisterPublishPubAck); + ctx.pubAckPromise.get_future().wait(); - keysPublishCompletedPromise.get_future().wait(); - keysAcceptedCompletedPromise.get_future().wait(); - keysRejectedCompletedPromise.get_future().wait(); - registerPublishCompletedPromise.get_future().wait(); + // Wait for registering a thing to succeed. + ctx.thingCreatedPromise.get_future().wait(); } int main(int argc, char *argv[]) { + /************************ Setup ****************************/ + // Do the global initialization for the API ApiHandle apiHandle; @@ -542,62 +525,78 @@ int main(int argc, char *argv[]) */ Utils::cmdData cmdData = Utils::parseSampleInputFleetProvisioning(argc, argv, &apiHandle); - /** - * In a real world application you probably don't want to enforce synchronous behavior - * but this is a sample console application, so we'll just do that with a condition variable. - */ - std::promise connectionCompletedPromise; - std::promise connectionClosedPromise; - std::shared_ptr connection = nullptr; - std::shared_ptr client5 = nullptr; - std::shared_ptr iotIdentityClient = nullptr; + Mqtt5ClientContext mqtt5ClientContext; + std::shared_ptr mqtt5Client; + + Mqtt3ConnectionContext mqtt3ConnectionContext; + std::shared_ptr mqtt3Connection; + + std::shared_ptr identityClient; if (cmdData.input_mqtt_version == 5UL) { - iotIdentityClient = build_mqtt5_client(cmdData, client5, connectionCompletedPromise, connectionClosedPromise); + mqtt5Client = createMqtt5Client(cmdData, mqtt5ClientContext); + if (!mqtt5Client) + { + fprintf(stderr, "MQTT5 Connection failed to start"); + return -1; + } + identityClient = std::make_shared(mqtt5Client); } else if (cmdData.input_mqtt_version == 3UL) { - iotIdentityClient = - build_mqtt3_client(cmdData, connection, connectionCompletedPromise, connectionClosedPromise); + mqtt3Connection = createMqtt3Connection(cmdData, mqtt3ConnectionContext); + if (!mqtt3Connection) + { + fprintf(stderr, "MQTT3 Connection failed to start"); + return -1; + } + identityClient = std::make_shared(mqtt3Connection); } else { fprintf(stderr, "MQTT Version not supported\n"); - exit(-1); + return -1; } - if (connectionCompletedPromise.get_future().get()) + + /************************ Run the sample ****************************/ + + // Create fleet provisioning client. + + // Create certificate. + CreateCertificateContext certificateContext; + if (cmdData.input_csrPath != "") { - if (cmdData.input_csrPath.empty()) - { - createKeysAndCertificateWorkflow( - cmdData.input_templateName, cmdData.input_templateParameters, iotIdentityClient); - } - else - { - createCertificateFromCsrWorkflow( - cmdData.input_templateName, cmdData.input_templateParameters, cmdData.input_csrPath, iotIdentityClient); - } + auto csrFile = getFileData(cmdData.input_csrPath); + createCertificateFromCsr(identityClient, certificateContext, csrFile); + } + else + { + createKeysAndCertificate(identityClient, certificateContext); } - // Wait just a little bit to let the console print - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + // Wait for a certificate token to be obtained. + auto token = certificateContext.tokenPromise.get_future().get(); + + // After certificate is obtained, it's time to register a thing. + RegisterThingContext registerThingContext; + registerThing(identityClient, registerThingContext, cmdData, token); + + // Disconnect if (cmdData.input_mqtt_version == 5UL) { - // Disconnect - if (client5->Stop() == true) + if (mqtt5Client->Stop()) { - connectionClosedPromise.get_future().wait(); + mqtt5ClientContext.stoppedPromise.get_future().wait(); } } - else - { // mqtt3 - - // Disconnect - if (connection->Disconnect() == true) + else if (cmdData.input_mqtt_version == 3UL) + { + if (mqtt3Connection->Disconnect()) { - connectionClosedPromise.get_future().wait(); + mqtt3ConnectionContext.connectionClosedPromise.get_future().wait(); } } + return 0; } From dc12eb50456dff52e017bd30dac68be52f251ba4 Mon Sep 17 00:00:00 2001 From: Steve Kim <86316075+sbSteveK@users.noreply.github.com> Date: Mon, 14 Oct 2024 13:06:21 -0700 Subject: [PATCH 2/3] move mac-only tls info to main README (#754) --- README.md | 9 +++++++++ documents/FAQ.md | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 17b330a98..3156fb39c 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ __Jump To:__ * [Supported Architectures](#supported-architectures) * [Installation](#installation) * [Samples](./samples) +* [Mac-Only TLS Behavior](#mac-only-tls-behavior) * [Getting Help](#getting-help) * [FAQ](./documents/FAQ.md) * [API Docs](https://aws.github.io/aws-iot-device-sdk-cpp-v2/) @@ -108,6 +109,14 @@ existing `libcrypto`, instead of building its own copy. [Samples README](./samples) +### Mac-Only TLS Behavior + +Please note that on Mac, once a private key is used with a certificate, that certificate-key pair is imported into the Mac Keychain. All subsequent uses of that certificate will use the stored private key and ignore anything passed in programmatically. Beginning in v1.7.3, when a stored private key from the Keychain is used, the following will be logged at the "info" log level: + +``` +static: certificate has an existing certificate-key pair that was previously imported into the Keychain. Using key from Keychain instead of the one provided. +``` + ## Getting Help The best way to interact with our team is through GitHub. You can open a [discussion](https://github.com/aws/aws-iot-device-sdk-cpp-v2/discussions) for guidance questions or an [issue](https://github.com/aws/aws-iot-device-sdk-cpp-v2/issues/new/choose) for bug reports, or feature requests. You may also find help on community resources such as [StackOverFlow](https://stackoverflow.com/questions/tagged/aws-iot) with the tag [#aws-iot](https://stackoverflow.com/questions/tagged/aws-iot) or if you have a support plan with [AWS Support](https://aws.amazon.com/premiumsupport/), you can also create a new support case. diff --git a/documents/FAQ.md b/documents/FAQ.md index ccd0f7045..67d529789 100644 --- a/documents/FAQ.md +++ b/documents/FAQ.md @@ -8,7 +8,6 @@ * [Detecting connection loss (tldr use keepAliveTimeSecs and pingTimeoutMs)](#connection-loss) * [How to use a Pre-Built aws-crt-cpp (Most useful for development of this package)](#prebuilt-aws-crt-cpp) * [I am experiencing deadlocks](#i-am-experiencing-deadlocks) -* [Mac-Only TLS Behavior](#mac-only-tls-behavior) * [How do debug in VSCode?](#how-do-debug-in-vscode) * [What certificates do I need?](#what-certificates-do-i-need) * [I still have more questions about this sdk?](#i-still-have-more-questions-about-this-sdk) @@ -82,14 +81,6 @@ cmake --build . --target install You MUST NOT perform blocking operations on any callback, or you will cause a deadlock. For example: in the on_publish_received callback, do not send a publish, and then wait for the future to complete within the callback. The Client cannot do work until your callback returns, so the thread will be stuck. -### Mac-Only TLS Behavior - -Please note that on Mac, once a private key is used with a certificate, that certificate-key pair is imported into the Mac Keychain. All subsequent uses of that certificate will use the stored private key and ignore anything passed in programmatically. Beginning in v1.7.3, when a stored private key from the Keychain is used, the following will be logged at the "info" log level: - -``` -static: certificate has an existing certificate-key pair that was previously imported into the Keychain. Using key from Keychain instead of the one provided. -``` - ### How do debug in VSCode? Here is an example launch.json file to run the pubsub sample From 8a0a23e645ef6d46fc78f555553b490f293a1c1c Mon Sep 17 00:00:00 2001 From: Bret Ambrose Date: Mon, 28 Oct 2024 08:55:11 -0700 Subject: [PATCH 3/3] Update submodules and cmake versions (#755) Co-authored-by: Bret Ambrose --- CMakeLists.txt | 2 +- README.md | 2 +- crt/aws-c-iot | 2 +- crt/aws-crt-cpp | 2 +- deviceadvisor/tests/mqtt_connect/CMakeLists.txt | 2 +- deviceadvisor/tests/mqtt_publish/CMakeLists.txt | 2 +- deviceadvisor/tests/mqtt_subscribe/CMakeLists.txt | 2 +- deviceadvisor/tests/shadow_update/CMakeLists.txt | 2 +- devicedefender/CMakeLists.txt | 2 +- discovery/CMakeLists.txt | 2 +- eventstream_rpc/CMakeLists.txt | 2 +- greengrass_ipc/CMakeLists.txt | 2 +- identity/CMakeLists.txt | 2 +- iotdevicecommon/CMakeLists.txt | 2 +- jobs/CMakeLists.txt | 2 +- samples/CMakeLists.txt | 2 +- samples/device_defender/basic_report/CMakeLists.txt | 2 +- samples/device_defender/mqtt5_basic_report/CMakeLists.txt | 2 +- samples/fleet_provisioning/fleet_provisioning/CMakeLists.txt | 2 +- .../fleet_provisioning/mqtt5_fleet_provisioning/CMakeLists.txt | 2 +- samples/greengrass/basic_discovery/CMakeLists.txt | 2 +- samples/greengrass/ipc/CMakeLists.txt | 2 +- samples/jobs/job_execution/CMakeLists.txt | 2 +- samples/jobs/mqtt5_job_execution/CMakeLists.txt | 2 +- samples/mqtt/basic_connect/CMakeLists.txt | 2 +- samples/mqtt/cognito_connect/CMakeLists.txt | 2 +- samples/mqtt/custom_authorizer_connect/CMakeLists.txt | 2 +- samples/mqtt/pkcs11_connect/CMakeLists.txt | 2 +- samples/mqtt/pkcs12_connect/CMakeLists.txt | 2 +- samples/mqtt/websocket_connect/CMakeLists.txt | 2 +- samples/mqtt/windows_cert_connect/CMakeLists.txt | 2 +- samples/mqtt/x509_credentials_provider_connect/CMakeLists.txt | 2 +- samples/mqtt5/mqtt5_pubsub/CMakeLists.txt | 2 +- samples/mqtt5/mqtt5_shared_subscription/CMakeLists.txt | 2 +- samples/pub_sub/basic_pub_sub/CMakeLists.txt | 2 +- samples/pub_sub/cycle_pub_sub/CMakeLists.txt | 2 +- samples/secure_tunneling/secure_tunnel/CMakeLists.txt | 2 +- samples/secure_tunneling/tunnel_notification/CMakeLists.txt | 2 +- samples/shadow/mqtt5_shadow_sync/CMakeLists.txt | 2 +- samples/shadow/shadow_sync/CMakeLists.txt | 2 +- secure_tunneling/CMakeLists.txt | 2 +- secure_tunneling/tests/CMakeLists.txt | 1 - servicetests/tests/FleetProvisioning/CMakeLists.txt | 2 +- servicetests/tests/JobsExecution/CMakeLists.txt | 2 +- servicetests/tests/ShadowUpdate/CMakeLists.txt | 2 +- shadow/CMakeLists.txt | 2 +- 46 files changed, 45 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f5c133aa..b9e38de0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(AwsGetVersion) diff --git a/README.md b/README.md index 3156fb39c..d85047010 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ __Jump To:__ ### Minimum Requirements * C++ 11 or higher * Clang 3.9+ or GCC 4.8+ or MSVC 2015+ -* CMake 3.1+ +* CMake 3.9+ [Step-by-step instructions](./documents/PREREQUISITES.md) diff --git a/crt/aws-c-iot b/crt/aws-c-iot index b3fe01586..aab341f10 160000 --- a/crt/aws-c-iot +++ b/crt/aws-c-iot @@ -1 +1 @@ -Subproject commit b3fe015865d7ead9fe7c9df8f8c6b38c37a51f00 +Subproject commit aab341f10bfd1e99da5202b8712b547443698e36 diff --git a/crt/aws-crt-cpp b/crt/aws-crt-cpp index 17e30acb7..fbd5310be 160000 --- a/crt/aws-crt-cpp +++ b/crt/aws-crt-cpp @@ -1 +1 @@ -Subproject commit 17e30acb7d6338a7b180c0cd522de0b4c51ceadd +Subproject commit fbd5310be54cc853807c06e85a9290560fc8f986 diff --git a/deviceadvisor/tests/mqtt_connect/CMakeLists.txt b/deviceadvisor/tests/mqtt_connect/CMakeLists.txt index 528562934..903b1dd7d 100644 --- a/deviceadvisor/tests/mqtt_connect/CMakeLists.txt +++ b/deviceadvisor/tests/mqtt_connect/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(mqtt_connect CXX) diff --git a/deviceadvisor/tests/mqtt_publish/CMakeLists.txt b/deviceadvisor/tests/mqtt_publish/CMakeLists.txt index 34e7a56ed..2013ee1f2 100644 --- a/deviceadvisor/tests/mqtt_publish/CMakeLists.txt +++ b/deviceadvisor/tests/mqtt_publish/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(mqtt_publish CXX) diff --git a/deviceadvisor/tests/mqtt_subscribe/CMakeLists.txt b/deviceadvisor/tests/mqtt_subscribe/CMakeLists.txt index 2bdaa4f14..dbb8290a1 100644 --- a/deviceadvisor/tests/mqtt_subscribe/CMakeLists.txt +++ b/deviceadvisor/tests/mqtt_subscribe/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(mqtt_subscribe CXX) diff --git a/deviceadvisor/tests/shadow_update/CMakeLists.txt b/deviceadvisor/tests/shadow_update/CMakeLists.txt index dd7e853d4..409358b21 100644 --- a/deviceadvisor/tests/shadow_update/CMakeLists.txt +++ b/deviceadvisor/tests/shadow_update/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(shadow_update CXX) diff --git a/devicedefender/CMakeLists.txt b/devicedefender/CMakeLists.txt index 4040ca76f..4104c6b3b 100644 --- a/devicedefender/CMakeLists.txt +++ b/devicedefender/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(IotDeviceDefender-cpp LANGUAGES CXX) diff --git a/discovery/CMakeLists.txt b/discovery/CMakeLists.txt index 58e364e36..d592212ff 100644 --- a/discovery/CMakeLists.txt +++ b/discovery/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(Discovery-cpp LANGUAGES CXX) if (DEFINED SIMPLE_VERSION) diff --git a/eventstream_rpc/CMakeLists.txt b/eventstream_rpc/CMakeLists.txt index 5e5aa13b6..9904496d3 100644 --- a/eventstream_rpc/CMakeLists.txt +++ b/eventstream_rpc/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(EventstreamRpc-cpp LANGUAGES CXX) if (DEFINED SIMPLE_VERSION) diff --git a/greengrass_ipc/CMakeLists.txt b/greengrass_ipc/CMakeLists.txt index 1e66deb48..911650ec9 100644 --- a/greengrass_ipc/CMakeLists.txt +++ b/greengrass_ipc/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(GreengrassIpc-cpp LANGUAGES CXX) if (DEFINED SIMPLE_VERSION) diff --git a/identity/CMakeLists.txt b/identity/CMakeLists.txt index e843c0ff5..6a29bfaaf 100644 --- a/identity/CMakeLists.txt +++ b/identity/CMakeLists.txt @@ -1,6 +1,6 @@ # This file is generated -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(IotIdentity-cpp LANGUAGES CXX) if (DEFINED SIMPLE_VERSION) diff --git a/iotdevicecommon/CMakeLists.txt b/iotdevicecommon/CMakeLists.txt index 05fbcb0c8..a4fb4e0fc 100644 --- a/iotdevicecommon/CMakeLists.txt +++ b/iotdevicecommon/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(IotDeviceCommon-cpp LANGUAGES CXX) if (DEFINED SIMPLE_VERSION) diff --git a/jobs/CMakeLists.txt b/jobs/CMakeLists.txt index b1d054924..79b62ea0e 100644 --- a/jobs/CMakeLists.txt +++ b/jobs/CMakeLists.txt @@ -1,6 +1,6 @@ # This file is generated -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(IotJobs-cpp LANGUAGES CXX) if (DEFINED SIMPLE_VERSION) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 312dce978..600180149 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(aws-iot-device-sdk-cpp-v2-samples) diff --git a/samples/device_defender/basic_report/CMakeLists.txt b/samples/device_defender/basic_report/CMakeLists.txt index a973fcb4b..0e54da9d3 100644 --- a/samples/device_defender/basic_report/CMakeLists.txt +++ b/samples/device_defender/basic_report/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(basic-report CXX) diff --git a/samples/device_defender/mqtt5_basic_report/CMakeLists.txt b/samples/device_defender/mqtt5_basic_report/CMakeLists.txt index ecb8ef996..f7f87ccb0 100644 --- a/samples/device_defender/mqtt5_basic_report/CMakeLists.txt +++ b/samples/device_defender/mqtt5_basic_report/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(mqtt5-basic-report CXX) diff --git a/samples/fleet_provisioning/fleet_provisioning/CMakeLists.txt b/samples/fleet_provisioning/fleet_provisioning/CMakeLists.txt index 52b9fb458..71b470d6d 100644 --- a/samples/fleet_provisioning/fleet_provisioning/CMakeLists.txt +++ b/samples/fleet_provisioning/fleet_provisioning/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(fleet-provisioning CXX) diff --git a/samples/fleet_provisioning/mqtt5_fleet_provisioning/CMakeLists.txt b/samples/fleet_provisioning/mqtt5_fleet_provisioning/CMakeLists.txt index b13a3f34d..644023257 100644 --- a/samples/fleet_provisioning/mqtt5_fleet_provisioning/CMakeLists.txt +++ b/samples/fleet_provisioning/mqtt5_fleet_provisioning/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(mqtt5-fleet-provisioning CXX) diff --git a/samples/greengrass/basic_discovery/CMakeLists.txt b/samples/greengrass/basic_discovery/CMakeLists.txt index 05bdb5a6d..b565c8d50 100644 --- a/samples/greengrass/basic_discovery/CMakeLists.txt +++ b/samples/greengrass/basic_discovery/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(basic-discovery CXX) diff --git a/samples/greengrass/ipc/CMakeLists.txt b/samples/greengrass/ipc/CMakeLists.txt index 646a7868f..e7b96c8e0 100644 --- a/samples/greengrass/ipc/CMakeLists.txt +++ b/samples/greengrass/ipc/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(greengrass-ipc CXX) diff --git a/samples/jobs/job_execution/CMakeLists.txt b/samples/jobs/job_execution/CMakeLists.txt index a0ce228b7..c0009043c 100644 --- a/samples/jobs/job_execution/CMakeLists.txt +++ b/samples/jobs/job_execution/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(job-execution CXX) diff --git a/samples/jobs/mqtt5_job_execution/CMakeLists.txt b/samples/jobs/mqtt5_job_execution/CMakeLists.txt index 0affcba5c..ec06a6d41 100644 --- a/samples/jobs/mqtt5_job_execution/CMakeLists.txt +++ b/samples/jobs/mqtt5_job_execution/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(mqtt5-job-execution CXX) diff --git a/samples/mqtt/basic_connect/CMakeLists.txt b/samples/mqtt/basic_connect/CMakeLists.txt index f80d0d512..0174831a0 100644 --- a/samples/mqtt/basic_connect/CMakeLists.txt +++ b/samples/mqtt/basic_connect/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(basic-connect CXX) diff --git a/samples/mqtt/cognito_connect/CMakeLists.txt b/samples/mqtt/cognito_connect/CMakeLists.txt index 4e5f2a8b0..394ebe1c4 100644 --- a/samples/mqtt/cognito_connect/CMakeLists.txt +++ b/samples/mqtt/cognito_connect/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(cognito-connect CXX) diff --git a/samples/mqtt/custom_authorizer_connect/CMakeLists.txt b/samples/mqtt/custom_authorizer_connect/CMakeLists.txt index 4a758056b..266c53351 100644 --- a/samples/mqtt/custom_authorizer_connect/CMakeLists.txt +++ b/samples/mqtt/custom_authorizer_connect/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(custom-authorizer-connect CXX) diff --git a/samples/mqtt/pkcs11_connect/CMakeLists.txt b/samples/mqtt/pkcs11_connect/CMakeLists.txt index e1f3c5d4e..e512589f0 100644 --- a/samples/mqtt/pkcs11_connect/CMakeLists.txt +++ b/samples/mqtt/pkcs11_connect/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(pkcs11-connect CXX) diff --git a/samples/mqtt/pkcs12_connect/CMakeLists.txt b/samples/mqtt/pkcs12_connect/CMakeLists.txt index b257f8b37..43c996fad 100644 --- a/samples/mqtt/pkcs12_connect/CMakeLists.txt +++ b/samples/mqtt/pkcs12_connect/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(pkcs12-connect CXX) diff --git a/samples/mqtt/websocket_connect/CMakeLists.txt b/samples/mqtt/websocket_connect/CMakeLists.txt index 9b99fc7c2..7d7253569 100644 --- a/samples/mqtt/websocket_connect/CMakeLists.txt +++ b/samples/mqtt/websocket_connect/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(websocket-connect CXX) diff --git a/samples/mqtt/windows_cert_connect/CMakeLists.txt b/samples/mqtt/windows_cert_connect/CMakeLists.txt index 551a5dcc1..4448aa28d 100644 --- a/samples/mqtt/windows_cert_connect/CMakeLists.txt +++ b/samples/mqtt/windows_cert_connect/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(windows-cert-connect CXX) diff --git a/samples/mqtt/x509_credentials_provider_connect/CMakeLists.txt b/samples/mqtt/x509_credentials_provider_connect/CMakeLists.txt index da58e6d30..48b55ab3b 100644 --- a/samples/mqtt/x509_credentials_provider_connect/CMakeLists.txt +++ b/samples/mqtt/x509_credentials_provider_connect/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(x509-credentials-provider-connect CXX) diff --git a/samples/mqtt5/mqtt5_pubsub/CMakeLists.txt b/samples/mqtt5/mqtt5_pubsub/CMakeLists.txt index b2d6ddafa..5435c3f58 100644 --- a/samples/mqtt5/mqtt5_pubsub/CMakeLists.txt +++ b/samples/mqtt5/mqtt5_pubsub/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(mqtt5_pubsub CXX) diff --git a/samples/mqtt5/mqtt5_shared_subscription/CMakeLists.txt b/samples/mqtt5/mqtt5_shared_subscription/CMakeLists.txt index b366a1618..eae2822d9 100644 --- a/samples/mqtt5/mqtt5_shared_subscription/CMakeLists.txt +++ b/samples/mqtt5/mqtt5_shared_subscription/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(mqtt5_shared_subscription CXX) diff --git a/samples/pub_sub/basic_pub_sub/CMakeLists.txt b/samples/pub_sub/basic_pub_sub/CMakeLists.txt index c50d4227f..21e471903 100644 --- a/samples/pub_sub/basic_pub_sub/CMakeLists.txt +++ b/samples/pub_sub/basic_pub_sub/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(basic-pub-sub CXX) diff --git a/samples/pub_sub/cycle_pub_sub/CMakeLists.txt b/samples/pub_sub/cycle_pub_sub/CMakeLists.txt index 9b11689e2..947aaa0a5 100644 --- a/samples/pub_sub/cycle_pub_sub/CMakeLists.txt +++ b/samples/pub_sub/cycle_pub_sub/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(cycle-pub-sub CXX) diff --git a/samples/secure_tunneling/secure_tunnel/CMakeLists.txt b/samples/secure_tunneling/secure_tunnel/CMakeLists.txt index 489c0a4b8..41ef2c4f3 100644 --- a/samples/secure_tunneling/secure_tunnel/CMakeLists.txt +++ b/samples/secure_tunneling/secure_tunnel/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(secure-tunnel CXX) diff --git a/samples/secure_tunneling/tunnel_notification/CMakeLists.txt b/samples/secure_tunneling/tunnel_notification/CMakeLists.txt index fd25af565..69388d69e 100644 --- a/samples/secure_tunneling/tunnel_notification/CMakeLists.txt +++ b/samples/secure_tunneling/tunnel_notification/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(tunnel-notification CXX) diff --git a/samples/shadow/mqtt5_shadow_sync/CMakeLists.txt b/samples/shadow/mqtt5_shadow_sync/CMakeLists.txt index 34e17996f..3dc9c1f07 100644 --- a/samples/shadow/mqtt5_shadow_sync/CMakeLists.txt +++ b/samples/shadow/mqtt5_shadow_sync/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(mqtt5-shadow-sync CXX) diff --git a/samples/shadow/shadow_sync/CMakeLists.txt b/samples/shadow/shadow_sync/CMakeLists.txt index 45c4e76eb..cf2270af4 100644 --- a/samples/shadow/shadow_sync/CMakeLists.txt +++ b/samples/shadow/shadow_sync/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(shadow-sync CXX) diff --git a/secure_tunneling/CMakeLists.txt b/secure_tunneling/CMakeLists.txt index 224b767c6..3a5cb08e6 100644 --- a/secure_tunneling/CMakeLists.txt +++ b/secure_tunneling/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(IotSecureTunneling-cpp LANGUAGES CXX) if (DEFINED SIMPLE_VERSION) diff --git a/secure_tunneling/tests/CMakeLists.txt b/secure_tunneling/tests/CMakeLists.txt index c4ddfecc6..de0cc2592 100644 --- a/secure_tunneling/tests/CMakeLists.txt +++ b/secure_tunneling/tests/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.1) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(secure_tunnel_test CXX) diff --git a/servicetests/tests/FleetProvisioning/CMakeLists.txt b/servicetests/tests/FleetProvisioning/CMakeLists.txt index efcb43bdc..b6a778f9d 100644 --- a/servicetests/tests/FleetProvisioning/CMakeLists.txt +++ b/servicetests/tests/FleetProvisioning/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(fleet_provisioning CXX) diff --git a/servicetests/tests/JobsExecution/CMakeLists.txt b/servicetests/tests/JobsExecution/CMakeLists.txt index 70577d337..77dc0b6e1 100644 --- a/servicetests/tests/JobsExecution/CMakeLists.txt +++ b/servicetests/tests/JobsExecution/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(job-execution CXX) diff --git a/servicetests/tests/ShadowUpdate/CMakeLists.txt b/servicetests/tests/ShadowUpdate/CMakeLists.txt index 3e10518c6..567781ffe 100644 --- a/servicetests/tests/ShadowUpdate/CMakeLists.txt +++ b/servicetests/tests/ShadowUpdate/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) # note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12 project(shadow-update CXX) diff --git a/shadow/CMakeLists.txt b/shadow/CMakeLists.txt index 771a462a8..837c79fc2 100644 --- a/shadow/CMakeLists.txt +++ b/shadow/CMakeLists.txt @@ -1,6 +1,6 @@ # This file is generated -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) project(IotShadow-cpp LANGUAGES CXX) if (DEFINED SIMPLE_VERSION)