Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
shadow_console_echo.c
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 #include <stdio.h> 00016 #include <stdlib.h> 00017 #include <string.h> 00018 #include <ctype.h> 00019 #include <unistd.h> 00020 #include <limits.h> 00021 00022 #include "aws_iot_config.h" 00023 #include "aws_iot_log.h" 00024 #include "aws_iot_version.h" 00025 #include "aws_iot_mqtt_client_interface.h" 00026 #include "aws_iot_shadow_interface.h" 00027 00028 /** 00029 * @file shadow_console_echo.c 00030 * @brief Echo received Delta message 00031 * 00032 * This application will echo the message received in delta, as reported. 00033 * for example: 00034 * Received Delta message 00035 * { 00036 * "state": { 00037 * "switch": "on" 00038 * } 00039 * } 00040 * This delta message means the desired switch position has changed to "on" 00041 * 00042 * This application will take this delta message and publish it back as the reported message from the device. 00043 * { 00044 * "state": { 00045 * "reported": { 00046 * "switch": "on" 00047 * } 00048 * } 00049 * } 00050 * 00051 * This update message will remove the delta that was created. If this message was not removed then the AWS IoT Thing Shadow is going to always have a delta and keep sending delta any time an update is applied to the Shadow 00052 * This example will not use any of the json builder/helper functions provided in the aws_iot_shadow_json_data.h. 00053 * @note Ensure the buffer sizes in aws_iot_config.h are big enough to receive the delta message. The delta message will also contain the metadata with the timestamps 00054 */ 00055 00056 char certDirectory[PATH_MAX + 1] = "../../../certs"; 00057 #define HOST_ADDRESS_SIZE 255 00058 char HostAddress[HOST_ADDRESS_SIZE] = AWS_IOT_MQTT_HOST; 00059 uint32_t port = AWS_IOT_MQTT_PORT; 00060 bool messageArrivedOnDelta = false; 00061 00062 /* 00063 * @note The delta message is always sent on the "state" key in the json 00064 * @note Any time messages are bigger than AWS_IOT_MQTT_RX_BUF_LEN the underlying MQTT library will ignore it. The maximum size of the message that can be received is limited to the AWS_IOT_MQTT_RX_BUF_LEN 00065 */ 00066 char stringToEchoDelta[SHADOW_MAX_SIZE_OF_RX_BUFFER]; 00067 00068 // Helper functions 00069 void parseInputArgsForConnectParams(int argc, char** argv); 00070 00071 // Shadow Callback for receiving the delta 00072 void DeltaCallback(const char *pJsonValueBuffer, uint32_t valueLength, jsonStruct_t *pJsonStruct_t); 00073 00074 void UpdateStatusCallback(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status, 00075 const char *pReceivedJsonDocument, void *pContextData); 00076 00077 int main(int argc, char** argv) { 00078 IoT_Error_t rc = SUCCESS; 00079 int32_t i = 0; 00080 00081 char rootCA[PATH_MAX + 1]; 00082 char clientCRT[PATH_MAX + 1]; 00083 char clientKey[PATH_MAX + 1]; 00084 char CurrentWD[PATH_MAX + 1]; 00085 00086 IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG); 00087 00088 getcwd(CurrentWD, sizeof(CurrentWD)); 00089 snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME); 00090 snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME); 00091 snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME); 00092 00093 IOT_DEBUG("rootCA %s", rootCA); 00094 IOT_DEBUG("clientCRT %s", clientCRT); 00095 IOT_DEBUG("clientKey %s", clientKey); 00096 00097 parseInputArgsForConnectParams(argc, argv); 00098 00099 // initialize the mqtt client 00100 AWS_IoT_Client mqttClient; 00101 00102 ShadowInitParameters_t sp = ShadowInitParametersDefault; 00103 sp.pHost = AWS_IOT_MQTT_HOST; 00104 sp.port = AWS_IOT_MQTT_PORT; 00105 sp.pClientCRT = clientCRT; 00106 sp.pClientKey = clientKey; 00107 sp.pRootCA = rootCA; 00108 sp.enableAutoReconnect = false; 00109 sp.disconnectHandler = NULL; 00110 00111 IOT_INFO("Shadow Init"); 00112 rc = aws_iot_shadow_init(&mqttClient, &sp); 00113 if (SUCCESS != rc) { 00114 IOT_ERROR("Shadow Connection Error"); 00115 return rc; 00116 } 00117 00118 ShadowConnectParameters_t scp = ShadowConnectParametersDefault; 00119 scp.pMyThingName = AWS_IOT_MY_THING_NAME; 00120 scp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID; 00121 scp.mqttClientIdLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID); 00122 00123 IOT_INFO("Shadow Connect"); 00124 rc = aws_iot_shadow_connect(&mqttClient, &scp); 00125 if (SUCCESS != rc) { 00126 IOT_ERROR("Shadow Connection Error"); 00127 return rc; 00128 } 00129 00130 /* 00131 * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h 00132 * #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL 00133 * #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL 00134 */ 00135 rc = aws_iot_shadow_set_autoreconnect_status(&mqttClient, true); 00136 if(SUCCESS != rc){ 00137 IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc); 00138 return rc; 00139 } 00140 00141 jsonStruct_t deltaObject; 00142 deltaObject.pData = stringToEchoDelta; 00143 deltaObject.dataLength = SHADOW_MAX_SIZE_OF_RX_BUFFER; 00144 deltaObject.pKey = "state"; 00145 deltaObject.type = SHADOW_JSON_OBJECT; 00146 deltaObject.cb = DeltaCallback; 00147 00148 /* 00149 * Register the jsonStruct object 00150 */ 00151 rc = aws_iot_shadow_register_delta(&mqttClient, &deltaObject); 00152 00153 // Now wait in the loop to receive any message sent from the console 00154 while (NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc) { 00155 /* 00156 * Lets check for the incoming messages for 200 ms. 00157 */ 00158 rc = aws_iot_shadow_yield(&mqttClient, 200); 00159 00160 if (NETWORK_ATTEMPTING_RECONNECT == rc) { 00161 sleep(1); 00162 // If the client is attempting to reconnect we will skip the rest of the loop. 00163 continue; 00164 } 00165 00166 if (messageArrivedOnDelta) { 00167 IOT_INFO("\nSending delta message back %s\n", stringToEchoDelta); 00168 rc = aws_iot_shadow_update(&mqttClient, AWS_IOT_MY_THING_NAME, stringToEchoDelta, UpdateStatusCallback, NULL, 2, true); 00169 messageArrivedOnDelta = false; 00170 } 00171 00172 // sleep for some time in seconds 00173 sleep(1); 00174 } 00175 00176 if (SUCCESS != rc) { 00177 IOT_ERROR("An error occurred in the loop %d", rc); 00178 } 00179 00180 IOT_INFO("Disconnecting"); 00181 rc = aws_iot_shadow_disconnect(&mqttClient); 00182 00183 if (SUCCESS != rc) { 00184 IOT_ERROR("Disconnect error %d", rc); 00185 } 00186 00187 return rc; 00188 } 00189 /** 00190 * @brief This function builds a full Shadow expected JSON document by putting the data in the reported section 00191 * 00192 * @param pJsonDocument Buffer to be filled up with the JSON data 00193 * @param maxSizeOfJsonDocument maximum size of the buffer that could be used to fill 00194 * @param pReceivedDeltaData This is the data that will be embedded in the reported section of the JSON document 00195 * @param lengthDelta Length of the data 00196 */ 00197 bool buildJSONForReported(char *pJsonDocument, size_t maxSizeOfJsonDocument, const char *pReceivedDeltaData, uint32_t lengthDelta) { 00198 int32_t ret; 00199 00200 if (NULL == pJsonDocument) { 00201 return false; 00202 } 00203 00204 char tempClientTokenBuffer[MAX_SIZE_CLIENT_TOKEN_CLIENT_SEQUENCE]; 00205 00206 if(aws_iot_fill_with_client_token(tempClientTokenBuffer, MAX_SIZE_CLIENT_TOKEN_CLIENT_SEQUENCE) != SUCCESS){ 00207 return false; 00208 } 00209 00210 ret = snprintf(pJsonDocument, maxSizeOfJsonDocument, "{\"state\":{\"reported\":%.*s}, \"clientToken\":\"%s\"}", lengthDelta, pReceivedDeltaData, tempClientTokenBuffer); 00211 00212 if (ret >= maxSizeOfJsonDocument || ret < 0) { 00213 return false; 00214 } 00215 00216 return true; 00217 } 00218 00219 void parseInputArgsForConnectParams(int argc, char** argv) { 00220 int opt; 00221 00222 while (-1 != (opt = getopt(argc, argv, "h:p:c:"))) { 00223 switch (opt) { 00224 case 'h': 00225 strncpy(HostAddress, optarg, HOST_ADDRESS_SIZE); 00226 IOT_DEBUG("Host %s", optarg); 00227 break; 00228 case 'p': 00229 port = atoi(optarg); 00230 IOT_DEBUG("arg %s", optarg); 00231 break; 00232 case 'c': 00233 strncpy(certDirectory, optarg, PATH_MAX + 1); 00234 IOT_DEBUG("cert root directory %s", optarg); 00235 break; 00236 case '?': 00237 if (optopt == 'c') { 00238 IOT_ERROR("Option -%c requires an argument.", optopt); 00239 } else if (isprint(optopt)) { 00240 IOT_WARN("Unknown option `-%c'.", optopt); 00241 } else { 00242 IOT_WARN("Unknown option character `\\x%x'.", optopt); 00243 } 00244 break; 00245 default: 00246 IOT_ERROR("ERROR in command line argument parsing"); 00247 break; 00248 } 00249 } 00250 00251 } 00252 00253 00254 void DeltaCallback(const char *pJsonValueBuffer, uint32_t valueLength, jsonStruct_t *pJsonStruct_t) { 00255 IOT_UNUSED(pJsonStruct_t); 00256 00257 IOT_DEBUG("Received Delta message %.*s", valueLength, pJsonValueBuffer); 00258 00259 if (buildJSONForReported(stringToEchoDelta, SHADOW_MAX_SIZE_OF_RX_BUFFER, pJsonValueBuffer, valueLength)) { 00260 messageArrivedOnDelta = true; 00261 } 00262 } 00263 00264 void UpdateStatusCallback(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status, 00265 const char *pReceivedJsonDocument, void *pContextData) { 00266 IOT_UNUSED(pThingName); 00267 IOT_UNUSED(action); 00268 IOT_UNUSED(pReceivedJsonDocument); 00269 IOT_UNUSED(pContextData); 00270 00271 if(SHADOW_ACK_TIMEOUT == status) { 00272 IOT_INFO("Update Timeout--"); 00273 } else if(SHADOW_ACK_REJECTED == status) { 00274 IOT_INFO("Update RejectedXX"); 00275 } else if(SHADOW_ACK_ACCEPTED == status) { 00276 IOT_INFO("Update Accepted !!"); 00277 } 00278 }
Generated on Tue Jul 12 2022 19:02:38 by
1.7.2