Jim Flynn
/
aws-iot-device-sdk-mbed-c
Changes to enabled on-line compiler
examples/subscribe_publish_sample/subscribe_publish_sample.cpp@0:082731ede69f, 2018-05-30 (annotated)
- Committer:
- JMF
- Date:
- Wed May 30 20:59:51 2018 +0000
- Revision:
- 0:082731ede69f
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JMF | 0:082731ede69f | 1 | /* |
JMF | 0:082731ede69f | 2 | * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
JMF | 0:082731ede69f | 3 | * |
JMF | 0:082731ede69f | 4 | * Licensed under the Apache License, Version 2.0 (the "License"). |
JMF | 0:082731ede69f | 5 | * You may not use this file except in compliance with the License. |
JMF | 0:082731ede69f | 6 | * A copy of the License is located at |
JMF | 0:082731ede69f | 7 | * |
JMF | 0:082731ede69f | 8 | * http://aws.amazon.com/apache2.0 |
JMF | 0:082731ede69f | 9 | * |
JMF | 0:082731ede69f | 10 | * or in the "license" file accompanying this file. This file is distributed |
JMF | 0:082731ede69f | 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
JMF | 0:082731ede69f | 12 | * express or implied. See the License for the specific language governing |
JMF | 0:082731ede69f | 13 | * permissions and limitations under the License. |
JMF | 0:082731ede69f | 14 | */ |
JMF | 0:082731ede69f | 15 | |
JMF | 0:082731ede69f | 16 | /** |
JMF | 0:082731ede69f | 17 | * @file subscribe_publish_sample.c |
JMF | 0:082731ede69f | 18 | * @brief simple MQTT publish and subscribe on the same topic |
JMF | 0:082731ede69f | 19 | * |
JMF | 0:082731ede69f | 20 | * This example takes the parameters from the aws_iot_config.h file and establishes a connection to the AWS IoT MQTT Platform. |
JMF | 0:082731ede69f | 21 | * It subscribes and publishes to the same topic - "sdkTest/sub" |
JMF | 0:082731ede69f | 22 | * |
JMF | 0:082731ede69f | 23 | * If all the certs are correct, you should see the messages received by the application in a loop. |
JMF | 0:082731ede69f | 24 | * |
JMF | 0:082731ede69f | 25 | * The application takes in the certificate path, host name , port and the number of times the publish should happen. |
JMF | 0:082731ede69f | 26 | * |
JMF | 0:082731ede69f | 27 | */ |
JMF | 0:082731ede69f | 28 | #include <stdio.h> |
JMF | 0:082731ede69f | 29 | #include <stdlib.h> |
JMF | 0:082731ede69f | 30 | #include <ctype.h> |
JMF | 0:082731ede69f | 31 | #include <limits.h> |
JMF | 0:082731ede69f | 32 | #include <string.h> |
JMF | 0:082731ede69f | 33 | |
JMF | 0:082731ede69f | 34 | #include "aws_iot_config.h" |
JMF | 0:082731ede69f | 35 | #include "aws_iot_log.h" |
JMF | 0:082731ede69f | 36 | #include "aws_iot_version.h" |
JMF | 0:082731ede69f | 37 | #include "aws_iot_mqtt_client_interface.h" |
JMF | 0:082731ede69f | 38 | |
JMF | 0:082731ede69f | 39 | #include "easy-connect.h" |
JMF | 0:082731ede69f | 40 | #include "WNC14A2AInterface.h" |
JMF | 0:082731ede69f | 41 | |
JMF | 0:082731ede69f | 42 | #define HOST_ADDRESS_SIZE 255 |
JMF | 0:082731ede69f | 43 | |
JMF | 0:082731ede69f | 44 | Thread aws_subscribe_publish(osPriorityNormal, 16*1024, NULL); |
JMF | 0:082731ede69f | 45 | void aws_subscribe_publish_task(void); |
JMF | 0:082731ede69f | 46 | |
JMF | 0:082731ede69f | 47 | /** |
JMF | 0:082731ede69f | 48 | * @brief Default cert location |
JMF | 0:082731ede69f | 49 | */ |
JMF | 0:082731ede69f | 50 | char certDirectory[PATH_MAX + 1] = "../../../certs"; |
JMF | 0:082731ede69f | 51 | |
JMF | 0:082731ede69f | 52 | /** |
JMF | 0:082731ede69f | 53 | * @brief Default MQTT HOST URL is pulled from the aws_iot_config.h |
JMF | 0:082731ede69f | 54 | */ |
JMF | 0:082731ede69f | 55 | char HostAddress[HOST_ADDRESS_SIZE] = AWS_IOT_MQTT_HOST; |
JMF | 0:082731ede69f | 56 | |
JMF | 0:082731ede69f | 57 | /** |
JMF | 0:082731ede69f | 58 | * @brief Default MQTT port is pulled from the aws_iot_config.h |
JMF | 0:082731ede69f | 59 | */ |
JMF | 0:082731ede69f | 60 | uint32_t port = AWS_IOT_MQTT_PORT; |
JMF | 0:082731ede69f | 61 | |
JMF | 0:082731ede69f | 62 | /** |
JMF | 0:082731ede69f | 63 | * @brief This parameter will avoid infinite loop of publish and exit the program after certain number of publishes |
JMF | 0:082731ede69f | 64 | */ |
JMF | 0:082731ede69f | 65 | uint32_t publishCount = 0; |
JMF | 0:082731ede69f | 66 | |
JMF | 0:082731ede69f | 67 | void iot_subscribe_callback_handler(AWS_IoT_Client *pClient, char *topicName, uint16_t topicNameLen, |
JMF | 0:082731ede69f | 68 | IoT_Publish_Message_Params *params, void *pData) { |
JMF | 0:082731ede69f | 69 | IOT_UNUSED(pData); |
JMF | 0:082731ede69f | 70 | IOT_UNUSED(pClient); |
JMF | 0:082731ede69f | 71 | IOT_INFO("Subscribe callback"); |
JMF | 0:082731ede69f | 72 | IOT_INFO("%.*s\t%.*s", topicNameLen, topicName, (int) params->payloadLen, (char *) params->payload); |
JMF | 0:082731ede69f | 73 | } |
JMF | 0:082731ede69f | 74 | |
JMF | 0:082731ede69f | 75 | void disconnectCallbackHandler(AWS_IoT_Client *pClient, void *data) { |
JMF | 0:082731ede69f | 76 | IOT_WARN("MQTT Disconnect"); |
JMF | 0:082731ede69f | 77 | IoT_Error_t rc = FAILURE; |
JMF | 0:082731ede69f | 78 | |
JMF | 0:082731ede69f | 79 | if(NULL == pClient) { |
JMF | 0:082731ede69f | 80 | return; |
JMF | 0:082731ede69f | 81 | } |
JMF | 0:082731ede69f | 82 | |
JMF | 0:082731ede69f | 83 | IOT_UNUSED(data); |
JMF | 0:082731ede69f | 84 | |
JMF | 0:082731ede69f | 85 | if(aws_iot_is_autoreconnect_enabled(pClient)) { |
JMF | 0:082731ede69f | 86 | IOT_INFO("Auto Reconnect is enabled, Reconnecting attempt will start now"); |
JMF | 0:082731ede69f | 87 | } else { |
JMF | 0:082731ede69f | 88 | IOT_WARN("Auto Reconnect not enabled. Starting manual reconnect..."); |
JMF | 0:082731ede69f | 89 | rc = aws_iot_mqtt_attempt_reconnect(pClient); |
JMF | 0:082731ede69f | 90 | if(NETWORK_RECONNECTED == rc) { |
JMF | 0:082731ede69f | 91 | IOT_WARN("Manual Reconnect Successful"); |
JMF | 0:082731ede69f | 92 | } else { |
JMF | 0:082731ede69f | 93 | IOT_WARN("Manual Reconnect Failed - %d", rc); |
JMF | 0:082731ede69f | 94 | } |
JMF | 0:082731ede69f | 95 | } |
JMF | 0:082731ede69f | 96 | } |
JMF | 0:082731ede69f | 97 | |
JMF | 0:082731ede69f | 98 | |
JMF | 0:082731ede69f | 99 | int main() |
JMF | 0:082731ede69f | 100 | { |
JMF | 0:082731ede69f | 101 | printf("AWS %s Example.\n",__FILE__); |
JMF | 0:082731ede69f | 102 | IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG); |
JMF | 0:082731ede69f | 103 | |
JMF | 0:082731ede69f | 104 | aws_subscribe_publish.start(aws_subscribe_publish_task); |
JMF | 0:082731ede69f | 105 | aws_subscribe_publish.join(); |
JMF | 0:082731ede69f | 106 | printf(" - - - - - - - ALL DONE - - - - - - - \n"); |
JMF | 0:082731ede69f | 107 | } |
JMF | 0:082731ede69f | 108 | |
JMF | 0:082731ede69f | 109 | void aws_subscribe_publish_task() |
JMF | 0:082731ede69f | 110 | { |
JMF | 0:082731ede69f | 111 | bool infinitePublishFlag = true; |
JMF | 0:082731ede69f | 112 | |
JMF | 0:082731ede69f | 113 | char rootCA[PATH_MAX + 1]; |
JMF | 0:082731ede69f | 114 | char clientCRT[PATH_MAX + 1]; |
JMF | 0:082731ede69f | 115 | char clientKey[PATH_MAX + 1]; |
JMF | 0:082731ede69f | 116 | char CurrentWD[PATH_MAX + 1]; |
JMF | 0:082731ede69f | 117 | char cPayload[100]; |
JMF | 0:082731ede69f | 118 | |
JMF | 0:082731ede69f | 119 | int32_t i = 0; |
JMF | 0:082731ede69f | 120 | |
JMF | 0:082731ede69f | 121 | IoT_Error_t rc = FAILURE; |
JMF | 0:082731ede69f | 122 | |
JMF | 0:082731ede69f | 123 | AWS_IoT_Client client; |
JMF | 0:082731ede69f | 124 | IoT_Client_Init_Params mqttInitParams = iotClientInitParamsDefault; |
JMF | 0:082731ede69f | 125 | IoT_Client_Connect_Params connectParams = iotClientConnectParamsDefault; |
JMF | 0:082731ede69f | 126 | |
JMF | 0:082731ede69f | 127 | IoT_Publish_Message_Params paramsQOS0; |
JMF | 0:082731ede69f | 128 | IoT_Publish_Message_Params paramsQOS1; |
JMF | 0:082731ede69f | 129 | |
JMF | 0:082731ede69f | 130 | IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG); |
JMF | 0:082731ede69f | 131 | |
JMF | 0:082731ede69f | 132 | snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME); |
JMF | 0:082731ede69f | 133 | snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME); |
JMF | 0:082731ede69f | 134 | snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME); |
JMF | 0:082731ede69f | 135 | |
JMF | 0:082731ede69f | 136 | IOT_DEBUG("rootCA %s", rootCA); |
JMF | 0:082731ede69f | 137 | IOT_DEBUG("clientCRT %s", clientCRT); |
JMF | 0:082731ede69f | 138 | IOT_DEBUG("clientKey %s", clientKey); |
JMF | 0:082731ede69f | 139 | mqttInitParams.enableAutoReconnect = false; // We enable this later below |
JMF | 0:082731ede69f | 140 | mqttInitParams.pHostURL = HostAddress; |
JMF | 0:082731ede69f | 141 | mqttInitParams.port = port; |
JMF | 0:082731ede69f | 142 | mqttInitParams.pRootCALocation = rootCA; |
JMF | 0:082731ede69f | 143 | mqttInitParams.pDeviceCertLocation = clientCRT; |
JMF | 0:082731ede69f | 144 | mqttInitParams.pDevicePrivateKeyLocation = clientKey; |
JMF | 0:082731ede69f | 145 | mqttInitParams.mqttCommandTimeout_ms = 20000; |
JMF | 0:082731ede69f | 146 | mqttInitParams.tlsHandshakeTimeout_ms = 5000; |
JMF | 0:082731ede69f | 147 | mqttInitParams.isSSLHostnameVerify = true; |
JMF | 0:082731ede69f | 148 | mqttInitParams.disconnectHandler = disconnectCallbackHandler; |
JMF | 0:082731ede69f | 149 | mqttInitParams.disconnectHandlerData = NULL; |
JMF | 0:082731ede69f | 150 | |
JMF | 0:082731ede69f | 151 | rc = aws_iot_mqtt_init(&client, &mqttInitParams); |
JMF | 0:082731ede69f | 152 | if(SUCCESS != rc) { |
JMF | 0:082731ede69f | 153 | IOT_ERROR("aws_iot_mqtt_init returned error : %d ", rc); |
JMF | 0:082731ede69f | 154 | return; |
JMF | 0:082731ede69f | 155 | } |
JMF | 0:082731ede69f | 156 | |
JMF | 0:082731ede69f | 157 | connectParams.keepAliveIntervalInSec = 600; |
JMF | 0:082731ede69f | 158 | connectParams.isCleanSession = true; |
JMF | 0:082731ede69f | 159 | connectParams.MQTTVersion = MQTT_3_1_1; |
JMF | 0:082731ede69f | 160 | connectParams.pClientID = AWS_IOT_MQTT_CLIENT_ID; |
JMF | 0:082731ede69f | 161 | connectParams.clientIDLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID); |
JMF | 0:082731ede69f | 162 | connectParams.isWillMsgPresent = false; |
JMF | 0:082731ede69f | 163 | |
JMF | 0:082731ede69f | 164 | IOT_INFO("Connecting..."); |
JMF | 0:082731ede69f | 165 | rc = aws_iot_mqtt_connect(&client, &connectParams); |
JMF | 0:082731ede69f | 166 | if(SUCCESS != rc) { |
JMF | 0:082731ede69f | 167 | IOT_ERROR("Error(%d) connecting to %s:%d", rc, mqttInitParams.pHostURL, mqttInitParams.port); |
JMF | 0:082731ede69f | 168 | return; |
JMF | 0:082731ede69f | 169 | } |
JMF | 0:082731ede69f | 170 | /* |
JMF | 0:082731ede69f | 171 | * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h |
JMF | 0:082731ede69f | 172 | * #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL |
JMF | 0:082731ede69f | 173 | * #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL |
JMF | 0:082731ede69f | 174 | */ |
JMF | 0:082731ede69f | 175 | rc = aws_iot_mqtt_autoreconnect_set_status(&client, true); |
JMF | 0:082731ede69f | 176 | if(SUCCESS != rc) { |
JMF | 0:082731ede69f | 177 | IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc); |
JMF | 0:082731ede69f | 178 | return; |
JMF | 0:082731ede69f | 179 | } |
JMF | 0:082731ede69f | 180 | |
JMF | 0:082731ede69f | 181 | IOT_INFO("Subscribing..."); |
JMF | 0:082731ede69f | 182 | rc = aws_iot_mqtt_subscribe(&client, "sdkTest/sub", 11, QOS0, iot_subscribe_callback_handler, NULL); |
JMF | 0:082731ede69f | 183 | if(SUCCESS != rc) { |
JMF | 0:082731ede69f | 184 | IOT_ERROR("Error subscribing : %d ", rc); |
JMF | 0:082731ede69f | 185 | return; |
JMF | 0:082731ede69f | 186 | } |
JMF | 0:082731ede69f | 187 | |
JMF | 0:082731ede69f | 188 | sprintf(cPayload, "%s : %ld ", "hello from SDK", i); |
JMF | 0:082731ede69f | 189 | |
JMF | 0:082731ede69f | 190 | paramsQOS0.qos = QOS0; |
JMF | 0:082731ede69f | 191 | paramsQOS0.payload = (void *) cPayload; |
JMF | 0:082731ede69f | 192 | paramsQOS0.isRetained = 0; |
JMF | 0:082731ede69f | 193 | |
JMF | 0:082731ede69f | 194 | paramsQOS1.qos = QOS1; |
JMF | 0:082731ede69f | 195 | paramsQOS1.payload = (void *) cPayload; |
JMF | 0:082731ede69f | 196 | paramsQOS1.isRetained = 0; |
JMF | 0:082731ede69f | 197 | |
JMF | 0:082731ede69f | 198 | if(publishCount != 0) { |
JMF | 0:082731ede69f | 199 | infinitePublishFlag = false; |
JMF | 0:082731ede69f | 200 | } |
JMF | 0:082731ede69f | 201 | |
JMF | 0:082731ede69f | 202 | while((NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc) |
JMF | 0:082731ede69f | 203 | && (publishCount > 0 || infinitePublishFlag)) { |
JMF | 0:082731ede69f | 204 | |
JMF | 0:082731ede69f | 205 | //Max time the yield function will wait for read messages |
JMF | 0:082731ede69f | 206 | rc = aws_iot_mqtt_yield(&client, 100); |
JMF | 0:082731ede69f | 207 | if(NETWORK_ATTEMPTING_RECONNECT == rc) { |
JMF | 0:082731ede69f | 208 | // If the client is attempting to reconnect we will skip the rest of the loop. |
JMF | 0:082731ede69f | 209 | continue; |
JMF | 0:082731ede69f | 210 | } |
JMF | 0:082731ede69f | 211 | |
JMF | 0:082731ede69f | 212 | IOT_INFO("-->sleep"); |
JMF | 0:082731ede69f | 213 | wait(1); |
JMF | 0:082731ede69f | 214 | sprintf(cPayload, "%s : %ld ", "hello from SDK QOS0", i++); |
JMF | 0:082731ede69f | 215 | paramsQOS0.payloadLen = strlen(cPayload); |
JMF | 0:082731ede69f | 216 | rc = aws_iot_mqtt_publish(&client, "sdkTest/sub", 11, ¶msQOS0); |
JMF | 0:082731ede69f | 217 | if(publishCount > 0) { |
JMF | 0:082731ede69f | 218 | publishCount--; |
JMF | 0:082731ede69f | 219 | } |
JMF | 0:082731ede69f | 220 | |
JMF | 0:082731ede69f | 221 | if(publishCount == 0 && !infinitePublishFlag) { |
JMF | 0:082731ede69f | 222 | break; |
JMF | 0:082731ede69f | 223 | } |
JMF | 0:082731ede69f | 224 | |
JMF | 0:082731ede69f | 225 | sprintf(cPayload, "%s : %ld ", "hello from SDK QOS1", i++); |
JMF | 0:082731ede69f | 226 | paramsQOS1.payloadLen = strlen(cPayload); |
JMF | 0:082731ede69f | 227 | rc = aws_iot_mqtt_publish(&client, "sdkTest/sub", 11, ¶msQOS1); |
JMF | 0:082731ede69f | 228 | if (rc == MQTT_REQUEST_TIMEOUT_ERROR) { |
JMF | 0:082731ede69f | 229 | IOT_WARN("QOS1 publish ack not received.\n"); |
JMF | 0:082731ede69f | 230 | rc = SUCCESS; |
JMF | 0:082731ede69f | 231 | } |
JMF | 0:082731ede69f | 232 | if(publishCount > 0) { |
JMF | 0:082731ede69f | 233 | publishCount--; |
JMF | 0:082731ede69f | 234 | } |
JMF | 0:082731ede69f | 235 | } |
JMF | 0:082731ede69f | 236 | |
JMF | 0:082731ede69f | 237 | // Wait for all the messages to be received |
JMF | 0:082731ede69f | 238 | aws_iot_mqtt_yield(&client, 100); |
JMF | 0:082731ede69f | 239 | |
JMF | 0:082731ede69f | 240 | if(SUCCESS != rc) { |
JMF | 0:082731ede69f | 241 | IOT_ERROR("An error occurred in the loop.\n"); |
JMF | 0:082731ede69f | 242 | } else { |
JMF | 0:082731ede69f | 243 | IOT_INFO("Publish done\n"); |
JMF | 0:082731ede69f | 244 | } |
JMF | 0:082731ede69f | 245 | |
JMF | 0:082731ede69f | 246 | return; |
JMF | 0:082731ede69f | 247 | } |
JMF | 0:082731ede69f | 248 | |
JMF | 0:082731ede69f | 249 |