Jim Flynn / Mbed OS aws-iot-device-sdk-mbed-c
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers subscribe_publish_library_sample.c Source File

subscribe_publish_library_sample.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License").
00005  * You may not use this file except in compliance with the License.
00006  * A copy of the License is located at
00007  *
00008  *  http://aws.amazon.com/apache2.0
00009  *
00010  * or in the "license" file accompanying this file. This file is distributed
00011  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
00012  * express or implied. See the License for the specific language governing
00013  * permissions and limitations under the License.
00014  */
00015 
00016 /**
00017  * @file subscribe_publish_library_sample.c
00018  * @brief simple MQTT publish and subscribe on the same topic using the SDK as a library
00019  *
00020  * This example takes the parameters from the aws_iot_config.h file and establishes a connection to the AWS IoT MQTT Platform.
00021  * It subscribes and publishes to the same topic - "sdkTest/sub"
00022  *
00023  * If all the certs are correct, you should see the messages received by the application in a loop.
00024  *
00025  * The application takes in the certificate path, host name , port and the number of times the publish should happen.
00026  *
00027  */
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <ctype.h>
00031 #include <unistd.h>
00032 #include <limits.h>
00033 #include <string.h>
00034 
00035 #include "aws_iot_config.h"
00036 #include "aws_iot_log.h"
00037 #include "aws_iot_version.h"
00038 #include "aws_iot_mqtt_client_interface.h"
00039 
00040 #define HOST_ADDRESS_SIZE 255
00041 
00042 /**
00043  * @brief Default cert location
00044  */
00045 char certDirectory[PATH_MAX + 1] = "../../../certs";
00046 
00047 /**
00048  * @brief Default MQTT HOST URL is pulled from the aws_iot_config.h
00049  */
00050 char HostAddress[HOST_ADDRESS_SIZE] = AWS_IOT_MQTT_HOST;
00051 
00052 /**
00053  * @brief Default MQTT port is pulled from the aws_iot_config.h
00054  */
00055 uint32_t port = AWS_IOT_MQTT_PORT;
00056 
00057 /**
00058  * @brief This parameter will avoid infinite loop of publish and exit the program after certain number of publishes
00059  */
00060 uint32_t publishCount = 0;
00061 
00062 void iot_subscribe_callback_handler(AWS_IoT_Client *pClient, char *topicName, uint16_t topicNameLen,
00063                                     IoT_Publish_Message_Params *params, void *pData) {
00064     IOT_UNUSED(pData);
00065     IOT_UNUSED(pClient);
00066     IOT_INFO("Subscribe callback");
00067     IOT_INFO("%.*s\t%.*s", topicNameLen, topicName, (int) params->payloadLen, (char *) params->payload);
00068 }
00069 
00070 void disconnectCallbackHandler(AWS_IoT_Client *pClient, void *data) {
00071     IOT_WARN("MQTT Disconnect");
00072     IoT_Error_t rc = FAILURE;
00073 
00074     if(NULL == pClient) {
00075         return;
00076     }
00077 
00078     IOT_UNUSED(data);
00079 
00080     if(aws_iot_is_autoreconnect_enabled(pClient)) {
00081         IOT_INFO("Auto Reconnect is enabled, Reconnecting attempt will start now");
00082     } else {
00083         IOT_WARN("Auto Reconnect not enabled. Starting manual reconnect...");
00084         rc = aws_iot_mqtt_attempt_reconnect(pClient);
00085         if(NETWORK_RECONNECTED == rc) {
00086             IOT_WARN("Manual Reconnect Successful");
00087         } else {
00088             IOT_WARN("Manual Reconnect Failed - %d", rc);
00089         }
00090     }
00091 }
00092 
00093 void parseInputArgsForConnectParams(int argc, char **argv) {
00094     int opt;
00095 
00096     while(-1 != (opt = getopt(argc, argv, "h:p:c:x:"))) {
00097         switch(opt) {
00098             case 'h':
00099                 strncpy(HostAddress, optarg, HOST_ADDRESS_SIZE);
00100                 IOT_DEBUG("Host %s", optarg);
00101                 break;
00102             case 'p':
00103                 port = atoi(optarg);
00104                 IOT_DEBUG("arg %s", optarg);
00105                 break;
00106             case 'c':
00107                 strncpy(certDirectory, optarg, PATH_MAX + 1);
00108                 IOT_DEBUG("cert root directory %s", optarg);
00109                 break;
00110             case 'x':
00111                 publishCount = atoi(optarg);
00112                 IOT_DEBUG("publish %s times\n", optarg);
00113                 break;
00114             case '?':
00115                 if(optopt == 'c') {
00116                     IOT_ERROR("Option -%c requires an argument.", optopt);
00117                 } else if(isprint(optopt)) {
00118                     IOT_WARN("Unknown option `-%c'.", optopt);
00119                 } else {
00120                     IOT_WARN("Unknown option character `\\x%x'.", optopt);
00121                 }
00122                 break;
00123             default:
00124                 IOT_ERROR("Error in command line argument parsing");
00125                 break;
00126         }
00127     }
00128 
00129 }
00130 
00131 int main(int argc, char **argv) {
00132     bool infinitePublishFlag = true;
00133 
00134     char rootCA[PATH_MAX + 1];
00135     char clientCRT[PATH_MAX + 1];
00136     char clientKey[PATH_MAX + 1];
00137     char CurrentWD[PATH_MAX + 1];
00138     char cPayload[100];
00139 
00140     int32_t i = 0;
00141 
00142     IoT_Error_t rc = FAILURE;
00143 
00144     AWS_IoT_Client client;
00145     IoT_Client_Init_Params mqttInitParams = iotClientInitParamsDefault;
00146     IoT_Client_Connect_Params connectParams = iotClientConnectParamsDefault;
00147 
00148     IoT_Publish_Message_Params paramsQOS0;
00149     IoT_Publish_Message_Params paramsQOS1;
00150 
00151     parseInputArgsForConnectParams(argc, argv);
00152 
00153     IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
00154 
00155     getcwd(CurrentWD, sizeof(CurrentWD));
00156     snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME);
00157     snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME);
00158     snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME);
00159 
00160     IOT_DEBUG("rootCA %s", rootCA);
00161     IOT_DEBUG("clientCRT %s", clientCRT);
00162     IOT_DEBUG("clientKey %s", clientKey);
00163     mqttInitParams.enableAutoReconnect = false; // We enable this later below
00164     mqttInitParams.pHostURL = HostAddress;
00165     mqttInitParams.port = port;
00166     mqttInitParams.pRootCALocation = rootCA;
00167     mqttInitParams.pDeviceCertLocation = clientCRT;
00168     mqttInitParams.pDevicePrivateKeyLocation = clientKey;
00169     mqttInitParams.mqttCommandTimeout_ms = 20000;
00170     mqttInitParams.tlsHandshakeTimeout_ms = 5000;
00171     mqttInitParams.isSSLHostnameVerify = true;
00172     mqttInitParams.disconnectHandler = disconnectCallbackHandler;
00173     mqttInitParams.disconnectHandlerData = NULL;
00174 
00175     rc = aws_iot_mqtt_init(&client, &mqttInitParams);
00176     if(SUCCESS != rc) {
00177         IOT_ERROR("aws_iot_mqtt_init returned error : %d ", rc);
00178         return rc;
00179     }
00180 
00181     connectParams.keepAliveIntervalInSec = 600;
00182     connectParams.isCleanSession = true;
00183     connectParams.MQTTVersion = MQTT_3_1_1;
00184     connectParams.pClientID = AWS_IOT_MQTT_CLIENT_ID;
00185     connectParams.clientIDLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID);
00186     connectParams.isWillMsgPresent = false;
00187 
00188     IOT_INFO("Connecting...");
00189     rc = aws_iot_mqtt_connect(&client, &connectParams);
00190     if(SUCCESS != rc) {
00191         IOT_ERROR("Error(%d) connecting to %s:%d", rc, mqttInitParams.pHostURL, mqttInitParams.port);
00192         return rc;
00193     }
00194     /*
00195      * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
00196      *  #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
00197      *  #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
00198      */
00199     rc = aws_iot_mqtt_autoreconnect_set_status(&client, true);
00200     if(SUCCESS != rc) {
00201         IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc);
00202         return rc;
00203     }
00204 
00205     IOT_INFO("Subscribing...");
00206     rc = aws_iot_mqtt_subscribe(&client, "sdkTest/sub", 11, QOS0, iot_subscribe_callback_handler, NULL);
00207     if(SUCCESS != rc) {
00208         IOT_ERROR("Error subscribing : %d ", rc);
00209         return rc;
00210     }
00211 
00212     sprintf(cPayload, "%s : %d ", "hello from SDK", i);
00213 
00214     paramsQOS0.qos = QOS0;
00215     paramsQOS0.payload = (void *) cPayload;
00216     paramsQOS0.isRetained = 0;
00217 
00218     paramsQOS1.qos = QOS1;
00219     paramsQOS1.payload = (void *) cPayload;
00220     paramsQOS1.isRetained = 0;
00221 
00222     if(publishCount != 0) {
00223         infinitePublishFlag = false;
00224     }
00225 
00226     while((NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc)
00227           && (publishCount > 0 || infinitePublishFlag)) {
00228 
00229         //Max time the yield function will wait for read messages
00230         rc = aws_iot_mqtt_yield(&client, 100);
00231         if(NETWORK_ATTEMPTING_RECONNECT == rc) {
00232             // If the client is attempting to reconnect we will skip the rest of the loop.
00233             continue;
00234         }
00235 
00236         IOT_INFO("-->sleep");
00237         sleep(1);
00238         sprintf(cPayload, "%s : %d ", "hello from SDK QOS0", i++);
00239         paramsQOS0.payloadLen = strlen(cPayload);
00240         rc = aws_iot_mqtt_publish(&client, "sdkTest/sub", 11, &paramsQOS0);
00241         if(publishCount > 0) {
00242             publishCount--;
00243         }
00244 
00245         sprintf(cPayload, "%s : %d ", "hello from SDK QOS1", i++);
00246         paramsQOS1.payloadLen = strlen(cPayload);
00247         rc = aws_iot_mqtt_publish(&client, "sdkTest/sub", 11, &paramsQOS1);
00248         if (rc == MQTT_REQUEST_TIMEOUT_ERROR) {
00249             IOT_WARN("QOS1 publish ack not received.\n");
00250             rc = SUCCESS;
00251         }
00252         if(publishCount > 0) {
00253             publishCount--;
00254         }
00255     }
00256 
00257     if(SUCCESS != rc) {
00258         IOT_ERROR("An error occurred in the loop.\n");
00259     } else {
00260         IOT_INFO("Publish done\n");
00261     }
00262 
00263     return rc;
00264 }