77#include < aws/crt/mqtt/Mqtt5Packets.h>
88#include < aws/iot/Mqtt5Client.h>
99
10+ #include < algorithm>
11+ #include < cstring>
1012#include < thread>
1113
12- #include " ../../utils/CommandLineUtils.h"
13-
1414using namespace Aws ::Crt;
1515
16+ /* --------------------------------- ARGUMENT PARSING ----------------------------------------- */
17+ struct CmdArgs {
18+ String endpoint;
19+ String cert;
20+ String key;
21+ String clientId;
22+ String topic = " test/topic" ;
23+ String message = " Hello from mqtt5 sample" ;
24+ uint32_t count = 5 ;
25+ };
26+
27+ void printHelp () {
28+ printf (" MQTT5 X509 Sample (mTLS)\n " );
29+ printf (" options:\n " );
30+ printf (" --help show this help message and exit\n " );
31+ printf (" required arguments:\n " );
32+ printf (" --endpoint IoT endpoint hostname (default: None)\n " );
33+ printf (
34+ " --cert Path to the certificate file to use during mTLS connection establishment (default: None)\n " );
35+ printf (
36+ " --key Path to the private key file to use during mTLS connection establishment (default: None)\n " );
37+ printf (" optional arguments:\n " );
38+ printf (" --client-id Client ID (default: mqtt5-sample-<uuid>)\n " );
39+ printf (" --ca_file Path to optional CA bundle (PEM) (default: None)\n " );
40+ printf (" --topic Topic (default: test/topic)\n " );
41+ printf (" --message Message payload (default: Hello from mqtt5 sample)\n " );
42+ printf (" --count Messages to publish (0 = infinite) (default: 5)\n " );
43+ }
44+
45+ CmdArgs parseArgs (int argc, char *argv[]) {
46+ CmdArgs args;
47+ for (int i = 1 ; i < argc; i++) {
48+ if (strcmp (argv[i], " --help" ) == 0 ) {
49+ printHelp ();
50+ exit (0 );
51+ }
52+ else if (i < argc - 1 ) {
53+ if (strcmp (argv[i], " --endpoint" ) == 0 ) {
54+ args.endpoint = argv[++i];
55+ }
56+ else if (strcmp (argv[i], " --cert" ) == 0 ) {
57+ args.cert = argv[++i];
58+ }
59+ else if (strcmp (argv[i], " --key" ) == 0 ) {
60+ args.key = argv[++i];
61+ }
62+ else if (strcmp (argv[i], " --client_id" ) == 0 ) {
63+ args.clientId = argv[++i];
64+ }
65+ else if (strcmp (argv[i], " --topic" ) == 0 ) {
66+ args.topic = argv[++i];
67+ }
68+ else if (strcmp (argv[i], " --message" ) == 0 ) {
69+ args.message = argv[++i];
70+ }
71+ else if (strcmp (argv[i], " --count" ) == 0 ) {
72+ args.count = atoi (argv[++i]);
73+ }
74+ else {
75+ fprintf (stderr, " Unknown argument: %s\n " , argv[i]);
76+ printHelp ();
77+ exit (1 );
78+ }
79+ }
80+ }
81+ if (args.endpoint .empty () || args.cert .empty () || args.key .empty ()) {
82+ fprintf (stderr, " Error: --endpoint, --cert, and --key are required\n " );
83+ printHelp ();
84+ exit (1 );
85+ }
86+ if (args.clientId .empty ()) args.clientId = String (" test-" ) + UUID ().ToString ();
87+ return args;
88+ }
89+ /* --------------------------------- ARGUMENT PARSING END ----------------------------------------- */
90+
1691int main (int argc, char *argv[])
1792{
93+ // Parse command line arguments
94+ CmdArgs cmdData = parseArgs (argc, argv);
1895
1996 /* *********************** Setup ****************************/
2097
@@ -26,17 +103,10 @@ int main(int argc, char *argv[])
26103 std::condition_variable receiveSignal;
27104 uint32_t receivedCount = 0 ;
28105
29- /* *
30- * cmdData is the arguments/input from the command line placed into a single struct for
31- * use in this sample. This handles all of the command line parsing, validating, etc.
32- * See the Utils/CommandLineUtils for more information.
33- */
34- Utils::cmdData cmdData = Utils::parseSampleInputPubSub (argc, argv, &apiHandle, " mqtt5-pubsub" );
35-
36106 // Create the MQTT5 builder and populate it with data from cmdData.
37107 auto builder = std::unique_ptr<Aws::Iot::Mqtt5ClientBuilder>(
38108 Aws::Iot::Mqtt5ClientBuilder::NewMqtt5ClientBuilderWithMtlsFromPath (
39- cmdData.input_endpoint , cmdData.input_cert .c_str (), cmdData.input_key .c_str ()));
109+ cmdData.endpoint , cmdData.cert .c_str (), cmdData.key .c_str ()));
40110
41111 // Check if the builder setup correctly.
42112 if (builder == nullptr )
@@ -49,12 +119,8 @@ int main(int argc, char *argv[])
49119 // Setup connection options
50120 std::shared_ptr<Mqtt5::ConnectPacket> connectOptions =
51121 Aws::Crt::MakeShared<Mqtt5::ConnectPacket>(Aws::Crt::DefaultAllocatorImplementation ());
52- connectOptions->WithClientId (cmdData.input_clientId );
122+ connectOptions->WithClientId (cmdData.clientId );
53123 builder->WithConnectOptions (connectOptions);
54- if (cmdData.input_port != 0 )
55- {
56- builder->WithPort (static_cast <uint32_t >(cmdData.input_port ));
57- }
58124
59125 std::promise<bool > connectionPromise;
60126 std::promise<void > stoppedPromise;
@@ -155,7 +221,7 @@ int main(int argc, char *argv[])
155221 subscribeSuccess.set_value (true );
156222 };
157223
158- Mqtt5::Subscription sub1 (cmdData.input_topic , Mqtt5::QOS::AWS_MQTT5_QOS_AT_LEAST_ONCE);
224+ Mqtt5::Subscription sub1 (cmdData.topic , Mqtt5::QOS::AWS_MQTT5_QOS_AT_LEAST_ONCE);
159225 sub1.WithNoLocal (false );
160226 std::shared_ptr<Mqtt5::SubscribePacket> subPacket =
161227 Aws::Crt::MakeShared<Mqtt5::SubscribePacket>(Aws::Crt::DefaultAllocatorImplementation ());
@@ -197,15 +263,15 @@ int main(int argc, char *argv[])
197263 };
198264
199265 uint32_t publishedCount = 0 ;
200- while (publishedCount < cmdData.input_count )
266+ while (publishedCount < cmdData.count )
201267 {
202268 // Add \" to 'JSON-ify' the message
203- String message = " \" " + cmdData.input_message + std::to_string (publishedCount + 1 ).c_str () + " \" " ;
269+ String message = " \" " + cmdData.message + std::to_string (publishedCount + 1 ).c_str () + " \" " ;
204270 ByteCursor payload = ByteCursorFromString (message);
205271
206272 std::shared_ptr<Mqtt5::PublishPacket> publish = Aws::Crt::MakeShared<Mqtt5::PublishPacket>(
207273 Aws::Crt::DefaultAllocatorImplementation (),
208- cmdData.input_topic ,
274+ cmdData.topic ,
209275 payload,
210276 Mqtt5::QOS::AWS_MQTT5_QOS_AT_LEAST_ONCE);
211277 if (client->Publish (publish, onPublishComplete))
@@ -218,14 +284,14 @@ int main(int argc, char *argv[])
218284
219285 {
220286 std::unique_lock<std::mutex> receivedLock (receiveMutex);
221- receiveSignal.wait (receivedLock, [&] { return receivedCount >= cmdData.input_count ; });
287+ receiveSignal.wait (receivedLock, [&] { return receivedCount >= cmdData.count ; });
222288 }
223289
224290 // Unsubscribe from the topic.
225291 std::promise<void > unsubscribeFinishedPromise;
226292 std::shared_ptr<Mqtt5::UnsubscribePacket> unsub =
227293 Aws::Crt::MakeShared<Mqtt5::UnsubscribePacket>(Aws::Crt::DefaultAllocatorImplementation ());
228- unsub->WithTopicFilter (cmdData.input_topic );
294+ unsub->WithTopicFilter (cmdData.topic );
229295 if (!client->Unsubscribe (unsub, [&](int , std::shared_ptr<Mqtt5::UnSubAckPacket>) {
230296 unsubscribeFinishedPromise.set_value ();
231297 }))
0 commit comments