Demo application for using the AT&T IoT Starter Kit Powered by AWS.

Dependencies:   SDFileSystem

Fork of ATT_AWS_IoT_demo by Anthony Phillips

IoT Starter Kit Powered by AWS Demo

This program demonstrates the AT&T IoT Starter Kit sending data directly into AWS IoT. It's explained and used in the Getting Started with the IoT Starter Kit Powered by AWS on starterkit.att.com.

What's required

  • AT&T IoT LTE Add-on (also known as the Cellular Shield)
  • NXP K64F - for programming
  • microSD card - used to store your AWS security credentials
  • AWS account
  • Python, locally installed

If you don't already have an IoT Starter Kit, you can purchase a kit here. The IoT Starter Kit Powered by AWS includes the LTE cellular shield, K64F, and a microSD card.

Committer:
rfinn
Date:
Tue Feb 07 16:18:57 2017 +0000
Revision:
27:2f486c766854
Parent:
15:6f2798e45099
changed SDFileSystem library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ampembeng 15:6f2798e45099 1 /*
ampembeng 15:6f2798e45099 2 * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
ampembeng 15:6f2798e45099 3 *
ampembeng 15:6f2798e45099 4 * Licensed under the Apache License, Version 2.0 (the "License").
ampembeng 15:6f2798e45099 5 * You may not use this file except in compliance with the License.
ampembeng 15:6f2798e45099 6 * A copy of the License is located at
ampembeng 15:6f2798e45099 7 *
ampembeng 15:6f2798e45099 8 * http://aws.amazon.com/apache2.0
ampembeng 15:6f2798e45099 9 *
ampembeng 15:6f2798e45099 10 * or in the "license" file accompanying this file. This file is distributed
ampembeng 15:6f2798e45099 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
ampembeng 15:6f2798e45099 12 * express or implied. See the License for the specific language governing
ampembeng 15:6f2798e45099 13 * permissions and limitations under the License.
ampembeng 15:6f2798e45099 14 */
ampembeng 15:6f2798e45099 15
ampembeng 15:6f2798e45099 16 #include "aws_iot_shadow_json.h"
ampembeng 15:6f2798e45099 17
ampembeng 15:6f2798e45099 18 #include <string.h>
ampembeng 15:6f2798e45099 19 #include <stdbool.h>
ampembeng 15:6f2798e45099 20 #include <inttypes.h>
ampembeng 15:6f2798e45099 21 #include "aws_iot_json_utils.h"
ampembeng 15:6f2798e45099 22 #include "aws_iot_log.h"
ampembeng 15:6f2798e45099 23 #include "aws_iot_shadow_key.h"
ampembeng 15:6f2798e45099 24 #include "aws_iot_config.h"
ampembeng 15:6f2798e45099 25
ampembeng 15:6f2798e45099 26 extern char mqttClientID[MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES];
ampembeng 15:6f2798e45099 27
ampembeng 15:6f2798e45099 28 static uint32_t clientTokenNum = 0;
ampembeng 15:6f2798e45099 29
ampembeng 15:6f2798e45099 30 //helper functions
ampembeng 15:6f2798e45099 31 static IoT_Error_t convertDataToString(char *pStringBuffer, size_t maxSizoStringBuffer, JsonPrimitiveType type,
ampembeng 15:6f2798e45099 32 void *pData);
ampembeng 15:6f2798e45099 33
ampembeng 15:6f2798e45099 34 void resetClientTokenSequenceNum(void) {
ampembeng 15:6f2798e45099 35 clientTokenNum = 0;
ampembeng 15:6f2798e45099 36 }
ampembeng 15:6f2798e45099 37
ampembeng 15:6f2798e45099 38 static void emptyJsonWithClientToken(char *pJsonDocument) {
ampembeng 15:6f2798e45099 39 sprintf(pJsonDocument, "{\"clientToken\":\"");
ampembeng 15:6f2798e45099 40 FillWithClientToken(pJsonDocument + strlen(pJsonDocument));
ampembeng 15:6f2798e45099 41 sprintf(pJsonDocument + strlen(pJsonDocument), "\"}");
ampembeng 15:6f2798e45099 42 }
ampembeng 15:6f2798e45099 43
ampembeng 15:6f2798e45099 44 void iot_shadow_get_request_json(char *pJsonDocument) {
ampembeng 15:6f2798e45099 45 emptyJsonWithClientToken(pJsonDocument);
ampembeng 15:6f2798e45099 46 }
ampembeng 15:6f2798e45099 47
ampembeng 15:6f2798e45099 48 void iot_shadow_delete_request_json(char *pJsonDocument) {
ampembeng 15:6f2798e45099 49 emptyJsonWithClientToken(pJsonDocument);
ampembeng 15:6f2798e45099 50 }
ampembeng 15:6f2798e45099 51
ampembeng 15:6f2798e45099 52 static inline IoT_Error_t checkReturnValueOfSnPrintf(int32_t snPrintfReturn, size_t maxSizeOfJsonDocument) {
ampembeng 15:6f2798e45099 53
ampembeng 15:6f2798e45099 54 if (snPrintfReturn >= maxSizeOfJsonDocument) {
ampembeng 15:6f2798e45099 55 return SHADOW_JSON_BUFFER_TRUNCATED;
ampembeng 15:6f2798e45099 56 } else if (snPrintfReturn < 0) {
ampembeng 15:6f2798e45099 57 return SHADOW_JSON_ERROR;
ampembeng 15:6f2798e45099 58 }
ampembeng 15:6f2798e45099 59 return NONE_ERROR;
ampembeng 15:6f2798e45099 60 }
ampembeng 15:6f2798e45099 61
ampembeng 15:6f2798e45099 62 IoT_Error_t aws_iot_shadow_init_json_document(char *pJsonDocument, size_t maxSizeOfJsonDocument) {
ampembeng 15:6f2798e45099 63
ampembeng 15:6f2798e45099 64 IoT_Error_t ret_val = NONE_ERROR;
ampembeng 15:6f2798e45099 65 int32_t snPrintfReturn = 0;
ampembeng 15:6f2798e45099 66
ampembeng 15:6f2798e45099 67 if (pJsonDocument == NULL) {
ampembeng 15:6f2798e45099 68 return NULL_VALUE_ERROR;
ampembeng 15:6f2798e45099 69 }
ampembeng 15:6f2798e45099 70 snPrintfReturn = snprintf(pJsonDocument, maxSizeOfJsonDocument, "{\"state\":{");
ampembeng 15:6f2798e45099 71
ampembeng 15:6f2798e45099 72 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, maxSizeOfJsonDocument);
ampembeng 15:6f2798e45099 73
ampembeng 15:6f2798e45099 74 return ret_val;
ampembeng 15:6f2798e45099 75
ampembeng 15:6f2798e45099 76 }
ampembeng 15:6f2798e45099 77
ampembeng 15:6f2798e45099 78 IoT_Error_t aws_iot_shadow_add_desired(char *pJsonDocument, size_t maxSizeOfJsonDocument, uint8_t count, ...) {
ampembeng 15:6f2798e45099 79 IoT_Error_t ret_val = NONE_ERROR;
ampembeng 15:6f2798e45099 80 int32_t tempSize = 0;
ampembeng 15:6f2798e45099 81 int8_t i;
ampembeng 15:6f2798e45099 82 size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument;
ampembeng 15:6f2798e45099 83 int32_t snPrintfReturn = 0;
ampembeng 15:6f2798e45099 84 va_list pArgs;
ampembeng 15:6f2798e45099 85 va_start(pArgs, count);
ampembeng 15:6f2798e45099 86 jsonStruct_t *pTemporary;
ampembeng 15:6f2798e45099 87
ampembeng 15:6f2798e45099 88 if (pJsonDocument == NULL) {
ampembeng 15:6f2798e45099 89 return NULL_VALUE_ERROR;
ampembeng 15:6f2798e45099 90 }
ampembeng 15:6f2798e45099 91
ampembeng 15:6f2798e45099 92 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
ampembeng 15:6f2798e45099 93 if(tempSize <= 1){
ampembeng 15:6f2798e45099 94 return SHADOW_JSON_ERROR;
ampembeng 15:6f2798e45099 95 }
ampembeng 15:6f2798e45099 96 remSizeOfJsonBuffer = tempSize;
ampembeng 15:6f2798e45099 97
ampembeng 15:6f2798e45099 98 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"desired\":{");
ampembeng 15:6f2798e45099 99 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 100
ampembeng 15:6f2798e45099 101 if (ret_val != NONE_ERROR) {
ampembeng 15:6f2798e45099 102 return ret_val;
ampembeng 15:6f2798e45099 103 }
ampembeng 15:6f2798e45099 104
ampembeng 15:6f2798e45099 105 for (i = 0; i < count; i++) {
ampembeng 15:6f2798e45099 106 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
ampembeng 15:6f2798e45099 107 if(tempSize <= 1){
ampembeng 15:6f2798e45099 108 return SHADOW_JSON_ERROR;
ampembeng 15:6f2798e45099 109 }
ampembeng 15:6f2798e45099 110 remSizeOfJsonBuffer = tempSize;
ampembeng 15:6f2798e45099 111 pTemporary = va_arg (pArgs, jsonStruct_t *);
ampembeng 15:6f2798e45099 112 if (pTemporary != NULL) {
ampembeng 15:6f2798e45099 113 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"%s\":",
ampembeng 15:6f2798e45099 114 pTemporary->pKey);
ampembeng 15:6f2798e45099 115 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 116 if (ret_val != NONE_ERROR) {
ampembeng 15:6f2798e45099 117 return ret_val;
ampembeng 15:6f2798e45099 118 }
ampembeng 15:6f2798e45099 119 if (pTemporary->pKey != NULL && pTemporary->pData != NULL) {
ampembeng 15:6f2798e45099 120 ret_val = convertDataToString(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer,
ampembeng 15:6f2798e45099 121 pTemporary->type, pTemporary->pData);
ampembeng 15:6f2798e45099 122 } else {
ampembeng 15:6f2798e45099 123 return NULL_VALUE_ERROR;
ampembeng 15:6f2798e45099 124 }
ampembeng 15:6f2798e45099 125 if (ret_val != NONE_ERROR) {
ampembeng 15:6f2798e45099 126 return ret_val;
ampembeng 15:6f2798e45099 127 }
ampembeng 15:6f2798e45099 128 } else {
ampembeng 15:6f2798e45099 129 return NULL_VALUE_ERROR;
ampembeng 15:6f2798e45099 130 }
ampembeng 15:6f2798e45099 131 }
ampembeng 15:6f2798e45099 132
ampembeng 15:6f2798e45099 133 va_end(pArgs);
ampembeng 15:6f2798e45099 134 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "},");
ampembeng 15:6f2798e45099 135 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 136 return ret_val;
ampembeng 15:6f2798e45099 137 }
ampembeng 15:6f2798e45099 138
ampembeng 15:6f2798e45099 139 IoT_Error_t aws_iot_shadow_add_reported(char *pJsonDocument, size_t maxSizeOfJsonDocument, uint8_t count, ...) {
ampembeng 15:6f2798e45099 140 IoT_Error_t ret_val = NONE_ERROR;
ampembeng 15:6f2798e45099 141
ampembeng 15:6f2798e45099 142 int8_t i;
ampembeng 15:6f2798e45099 143 size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument;
ampembeng 15:6f2798e45099 144 int32_t snPrintfReturn = 0;
ampembeng 15:6f2798e45099 145 int32_t tempSize = 0;
ampembeng 15:6f2798e45099 146 va_list pArgs;
ampembeng 15:6f2798e45099 147 va_start(pArgs, count);
ampembeng 15:6f2798e45099 148 jsonStruct_t *pTemporary;
ampembeng 15:6f2798e45099 149
ampembeng 15:6f2798e45099 150 if (pJsonDocument == NULL) {
ampembeng 15:6f2798e45099 151 return NULL_VALUE_ERROR;
ampembeng 15:6f2798e45099 152 }
ampembeng 15:6f2798e45099 153
ampembeng 15:6f2798e45099 154
ampembeng 15:6f2798e45099 155 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
ampembeng 15:6f2798e45099 156 if(tempSize <= 1){
ampembeng 15:6f2798e45099 157 return SHADOW_JSON_ERROR;
ampembeng 15:6f2798e45099 158 }
ampembeng 15:6f2798e45099 159 remSizeOfJsonBuffer = tempSize;
ampembeng 15:6f2798e45099 160
ampembeng 15:6f2798e45099 161 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"reported\":{");
ampembeng 15:6f2798e45099 162 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 163
ampembeng 15:6f2798e45099 164 if (ret_val != NONE_ERROR) {
ampembeng 15:6f2798e45099 165 return ret_val;
ampembeng 15:6f2798e45099 166 }
ampembeng 15:6f2798e45099 167
ampembeng 15:6f2798e45099 168 for (i = 0; i < count; i++) {
ampembeng 15:6f2798e45099 169 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
ampembeng 15:6f2798e45099 170 if(tempSize <= 1){
ampembeng 15:6f2798e45099 171 return SHADOW_JSON_ERROR;
ampembeng 15:6f2798e45099 172 }
ampembeng 15:6f2798e45099 173 remSizeOfJsonBuffer = tempSize;
ampembeng 15:6f2798e45099 174
ampembeng 15:6f2798e45099 175 pTemporary = va_arg (pArgs, jsonStruct_t *);
ampembeng 15:6f2798e45099 176 if (pTemporary != NULL) {
ampembeng 15:6f2798e45099 177 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"%s\":",
ampembeng 15:6f2798e45099 178 pTemporary->pKey);
ampembeng 15:6f2798e45099 179 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 180 if (ret_val != NONE_ERROR) {
ampembeng 15:6f2798e45099 181 return ret_val;
ampembeng 15:6f2798e45099 182 }
ampembeng 15:6f2798e45099 183 if (pTemporary->pKey != NULL && pTemporary->pData != NULL) {
ampembeng 15:6f2798e45099 184 ret_val = convertDataToString(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer,
ampembeng 15:6f2798e45099 185 pTemporary->type, pTemporary->pData);
ampembeng 15:6f2798e45099 186 } else {
ampembeng 15:6f2798e45099 187 return NULL_VALUE_ERROR;
ampembeng 15:6f2798e45099 188 }
ampembeng 15:6f2798e45099 189 if (ret_val != NONE_ERROR) {
ampembeng 15:6f2798e45099 190 return ret_val;
ampembeng 15:6f2798e45099 191 }
ampembeng 15:6f2798e45099 192 } else {
ampembeng 15:6f2798e45099 193 return NULL_VALUE_ERROR;
ampembeng 15:6f2798e45099 194 }
ampembeng 15:6f2798e45099 195 }
ampembeng 15:6f2798e45099 196
ampembeng 15:6f2798e45099 197 va_end(pArgs);
ampembeng 15:6f2798e45099 198 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "},");
ampembeng 15:6f2798e45099 199 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 200 return ret_val;
ampembeng 15:6f2798e45099 201 }
ampembeng 15:6f2798e45099 202
ampembeng 15:6f2798e45099 203
ampembeng 15:6f2798e45099 204 int32_t FillWithClientTokenSize(char *pBufferToBeUpdatedWithClientToken, size_t maxSizeOfJsonDocument) {
ampembeng 15:6f2798e45099 205 int32_t snPrintfReturn;
ampembeng 15:6f2798e45099 206 snPrintfReturn = snprintf(pBufferToBeUpdatedWithClientToken, maxSizeOfJsonDocument, "%s-%d", mqttClientID,
ampembeng 15:6f2798e45099 207 clientTokenNum++);
ampembeng 15:6f2798e45099 208
ampembeng 15:6f2798e45099 209 return snPrintfReturn;
ampembeng 15:6f2798e45099 210 }
ampembeng 15:6f2798e45099 211
ampembeng 15:6f2798e45099 212 IoT_Error_t aws_iot_fill_with_client_token(char *pBufferToBeUpdatedWithClientToken, size_t maxSizeOfJsonDocument){
ampembeng 15:6f2798e45099 213
ampembeng 15:6f2798e45099 214 int32_t snPrintfRet = 0;
ampembeng 15:6f2798e45099 215 snPrintfRet = FillWithClientTokenSize(pBufferToBeUpdatedWithClientToken, maxSizeOfJsonDocument);
ampembeng 15:6f2798e45099 216 return checkReturnValueOfSnPrintf(snPrintfRet, maxSizeOfJsonDocument);
ampembeng 15:6f2798e45099 217
ampembeng 15:6f2798e45099 218 }
ampembeng 15:6f2798e45099 219
ampembeng 15:6f2798e45099 220 IoT_Error_t aws_iot_finalize_json_document(char *pJsonDocument, size_t maxSizeOfJsonDocument) {
ampembeng 15:6f2798e45099 221 size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument;
ampembeng 15:6f2798e45099 222 int32_t snPrintfReturn = 0;
ampembeng 15:6f2798e45099 223 int32_t tempSize = 0;
ampembeng 15:6f2798e45099 224 IoT_Error_t ret_val = NONE_ERROR;
ampembeng 15:6f2798e45099 225
ampembeng 15:6f2798e45099 226 if (pJsonDocument == NULL) {
ampembeng 15:6f2798e45099 227 return NULL_VALUE_ERROR;
ampembeng 15:6f2798e45099 228 }
ampembeng 15:6f2798e45099 229
ampembeng 15:6f2798e45099 230 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
ampembeng 15:6f2798e45099 231 if(tempSize <= 1){
ampembeng 15:6f2798e45099 232 return SHADOW_JSON_ERROR;
ampembeng 15:6f2798e45099 233 }
ampembeng 15:6f2798e45099 234 remSizeOfJsonBuffer = tempSize;
ampembeng 15:6f2798e45099 235
ampembeng 15:6f2798e45099 236 // strlen(ShadowTxBuffer) - 1 is to ensure we remove the last ,(comma) that was added
ampembeng 15:6f2798e45099 237 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "}, \"%s\":\"",
ampembeng 15:6f2798e45099 238 SHADOW_CLIENT_TOKEN_STRING);
ampembeng 15:6f2798e45099 239 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 240
ampembeng 15:6f2798e45099 241 if (ret_val != NONE_ERROR) {
ampembeng 15:6f2798e45099 242 return ret_val;
ampembeng 15:6f2798e45099 243 }
ampembeng 15:6f2798e45099 244 // refactor this XXX repeated code
ampembeng 15:6f2798e45099 245 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
ampembeng 15:6f2798e45099 246 if(tempSize <= 1){
ampembeng 15:6f2798e45099 247 return SHADOW_JSON_ERROR;
ampembeng 15:6f2798e45099 248 }
ampembeng 15:6f2798e45099 249 remSizeOfJsonBuffer = tempSize;
ampembeng 15:6f2798e45099 250
ampembeng 15:6f2798e45099 251
ampembeng 15:6f2798e45099 252 snPrintfReturn = FillWithClientTokenSize(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 253 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 254
ampembeng 15:6f2798e45099 255 if (ret_val != NONE_ERROR) {
ampembeng 15:6f2798e45099 256 return ret_val;
ampembeng 15:6f2798e45099 257 }
ampembeng 15:6f2798e45099 258 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
ampembeng 15:6f2798e45099 259 if(tempSize <= 1){
ampembeng 15:6f2798e45099 260 return SHADOW_JSON_ERROR;
ampembeng 15:6f2798e45099 261 }
ampembeng 15:6f2798e45099 262 remSizeOfJsonBuffer = tempSize;
ampembeng 15:6f2798e45099 263
ampembeng 15:6f2798e45099 264
ampembeng 15:6f2798e45099 265 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"}");
ampembeng 15:6f2798e45099 266 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
ampembeng 15:6f2798e45099 267
ampembeng 15:6f2798e45099 268 return ret_val;
ampembeng 15:6f2798e45099 269 }
ampembeng 15:6f2798e45099 270
ampembeng 15:6f2798e45099 271 void FillWithClientToken(char *pBufferToBeUpdatedWithClientToken) {
ampembeng 15:6f2798e45099 272 sprintf(pBufferToBeUpdatedWithClientToken, "%s-%d", mqttClientID, clientTokenNum++);
ampembeng 15:6f2798e45099 273 }
ampembeng 15:6f2798e45099 274
ampembeng 15:6f2798e45099 275 static IoT_Error_t convertDataToString(char *pStringBuffer, size_t maxSizoStringBuffer, JsonPrimitiveType type,
ampembeng 15:6f2798e45099 276 void *pData) {
ampembeng 15:6f2798e45099 277 int32_t snPrintfReturn = 0;
ampembeng 15:6f2798e45099 278 IoT_Error_t ret_val = NONE_ERROR;
ampembeng 15:6f2798e45099 279
ampembeng 15:6f2798e45099 280 if (maxSizoStringBuffer == 0) {
ampembeng 15:6f2798e45099 281 return SHADOW_JSON_ERROR;
ampembeng 15:6f2798e45099 282 }
ampembeng 15:6f2798e45099 283
ampembeng 15:6f2798e45099 284 if (type == SHADOW_JSON_INT32) {
ampembeng 15:6f2798e45099 285 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIi32",", *(int32_t * )(pData));
ampembeng 15:6f2798e45099 286 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%li,", *(int32_t * )(pData));
ampembeng 15:6f2798e45099 287 } else if (type == SHADOW_JSON_INT16) {
ampembeng 15:6f2798e45099 288 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIi16",", *(int16_t * )(pData));
ampembeng 15:6f2798e45099 289 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%i,", *(int16_t * )(pData));
ampembeng 15:6f2798e45099 290 } else if (type == SHADOW_JSON_INT8) {
ampembeng 15:6f2798e45099 291 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIi8",", *(int8_t * )(pData));
ampembeng 15:6f2798e45099 292 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%i,", *(int8_t * )(pData));
ampembeng 15:6f2798e45099 293 } else if (type == SHADOW_JSON_UINT32) {
ampembeng 15:6f2798e45099 294 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIu32",", *(uint32_t * )(pData));
ampembeng 15:6f2798e45099 295 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%lu,", *(uint32_t * )(pData));
ampembeng 15:6f2798e45099 296 } else if (type == SHADOW_JSON_UINT16) {
ampembeng 15:6f2798e45099 297 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIu16",", *(uint16_t * )(pData));
ampembeng 15:6f2798e45099 298 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%u,", *(uint16_t * )(pData));
ampembeng 15:6f2798e45099 299 } else if (type == SHADOW_JSON_UINT8) {
ampembeng 15:6f2798e45099 300 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIu8",", *(uint8_t * )(pData));
ampembeng 15:6f2798e45099 301 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%u,", *(uint8_t * )(pData));
ampembeng 15:6f2798e45099 302 } else if (type == SHADOW_JSON_DOUBLE) {
ampembeng 15:6f2798e45099 303 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%f,", *(double * )(pData));
ampembeng 15:6f2798e45099 304 } else if (type == SHADOW_JSON_FLOAT) {
ampembeng 15:6f2798e45099 305 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%f,", *(float * )(pData));
ampembeng 15:6f2798e45099 306 } else if (type == SHADOW_JSON_BOOL) {
ampembeng 15:6f2798e45099 307 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%s,", *(bool *)(pData)?"true":"false");
ampembeng 15:6f2798e45099 308 } else if (type == SHADOW_JSON_STRING) {
ampembeng 15:6f2798e45099 309 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "\"%s\",", (char * )(pData));
ampembeng 15:6f2798e45099 310 }
ampembeng 15:6f2798e45099 311
ampembeng 15:6f2798e45099 312 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, maxSizoStringBuffer);
ampembeng 15:6f2798e45099 313
ampembeng 15:6f2798e45099 314 return ret_val;
ampembeng 15:6f2798e45099 315 }
ampembeng 15:6f2798e45099 316 static jsmn_parser shadowJsonParser;
ampembeng 15:6f2798e45099 317 static jsmntok_t jsonTokenStruct[MAX_JSON_TOKEN_EXPECTED];
ampembeng 15:6f2798e45099 318
ampembeng 15:6f2798e45099 319 bool isJsonValidAndParse(const char *pJsonDocument, void *pJsonHandler, int32_t *pTokenCount) {
ampembeng 15:6f2798e45099 320 int32_t tokenCount;
ampembeng 15:6f2798e45099 321
ampembeng 15:6f2798e45099 322 jsmn_init(&shadowJsonParser);
ampembeng 15:6f2798e45099 323
ampembeng 15:6f2798e45099 324 tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct,
ampembeng 15:6f2798e45099 325 sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0]));
ampembeng 15:6f2798e45099 326
ampembeng 15:6f2798e45099 327 if (tokenCount < 0) {
ampembeng 15:6f2798e45099 328 WARN("Failed to parse JSON: %d\n", tokenCount);
ampembeng 15:6f2798e45099 329 return false;
ampembeng 15:6f2798e45099 330 }
ampembeng 15:6f2798e45099 331
ampembeng 15:6f2798e45099 332 /* Assume the top-level element is an object */
ampembeng 15:6f2798e45099 333 if (tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) {
ampembeng 15:6f2798e45099 334 WARN("Top Level is not an object\n");
ampembeng 15:6f2798e45099 335 return false;
ampembeng 15:6f2798e45099 336 }
ampembeng 15:6f2798e45099 337
ampembeng 15:6f2798e45099 338 pJsonHandler = (void *) jsonTokenStruct;
ampembeng 15:6f2798e45099 339 *pTokenCount = tokenCount;
ampembeng 15:6f2798e45099 340
ampembeng 15:6f2798e45099 341 return true;
ampembeng 15:6f2798e45099 342 }
ampembeng 15:6f2798e45099 343
ampembeng 15:6f2798e45099 344 static IoT_Error_t UpdateValueIfNoObject(const char *pJsonString, jsonStruct_t *pDataStruct, jsmntok_t token) {
ampembeng 15:6f2798e45099 345 IoT_Error_t ret_val = NONE_ERROR;
ampembeng 15:6f2798e45099 346 if (pDataStruct->type == SHADOW_JSON_BOOL) {
ampembeng 15:6f2798e45099 347 ret_val = parseBooleanValue((bool *)pDataStruct->pData, pJsonString, &token);
ampembeng 15:6f2798e45099 348 } else if (pDataStruct->type == SHADOW_JSON_INT32) {
ampembeng 15:6f2798e45099 349 ret_val = parseInteger32Value((int32_t *)pDataStruct->pData, pJsonString, &token);
ampembeng 15:6f2798e45099 350 } else if (pDataStruct->type == SHADOW_JSON_INT16) {
ampembeng 15:6f2798e45099 351 ret_val = parseInteger16Value((int16_t *)pDataStruct->pData, pJsonString, &token);
ampembeng 15:6f2798e45099 352 } else if (pDataStruct->type == SHADOW_JSON_INT8) {
ampembeng 15:6f2798e45099 353 ret_val = parseInteger8Value((int8_t *)pDataStruct->pData, pJsonString, &token);
ampembeng 15:6f2798e45099 354 } else if (pDataStruct->type == SHADOW_JSON_UINT32) {
ampembeng 15:6f2798e45099 355 ret_val = parseUnsignedInteger32Value((uint32_t *)pDataStruct->pData, pJsonString, &token);
ampembeng 15:6f2798e45099 356 } else if (pDataStruct->type == SHADOW_JSON_UINT16) {
ampembeng 15:6f2798e45099 357 ret_val = parseUnsignedInteger16Value((uint16_t *)pDataStruct->pData, pJsonString, &token);
ampembeng 15:6f2798e45099 358 } else if (pDataStruct->type == SHADOW_JSON_UINT8) {
ampembeng 15:6f2798e45099 359 ret_val = parseUnsignedInteger8Value((uint8_t *)pDataStruct->pData, pJsonString, &token);
ampembeng 15:6f2798e45099 360 } else if (pDataStruct->type == SHADOW_JSON_FLOAT) {
ampembeng 15:6f2798e45099 361 ret_val = parseFloatValue((float *)pDataStruct->pData, pJsonString, &token);
ampembeng 15:6f2798e45099 362 } else if (pDataStruct->type == SHADOW_JSON_DOUBLE) {
ampembeng 15:6f2798e45099 363 ret_val = parseDoubleValue((double *)pDataStruct->pData, pJsonString, &token);
ampembeng 15:6f2798e45099 364 }
ampembeng 15:6f2798e45099 365
ampembeng 15:6f2798e45099 366 return ret_val;
ampembeng 15:6f2798e45099 367 }
ampembeng 15:6f2798e45099 368
ampembeng 15:6f2798e45099 369 bool isJsonKeyMatchingAndUpdateValue(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount,
ampembeng 15:6f2798e45099 370 jsonStruct_t *pDataStruct, uint32_t *pDataLength, int32_t *pDataPosition) {
ampembeng 15:6f2798e45099 371 int32_t i;
ampembeng 15:6f2798e45099 372
ampembeng 15:6f2798e45099 373 jsmntok_t *pJsonTokenStruct;
ampembeng 15:6f2798e45099 374
ampembeng 15:6f2798e45099 375 pJsonTokenStruct = (jsmntok_t *) pJsonHandler;
ampembeng 15:6f2798e45099 376 for (i = 1; i < tokenCount; i++) {
ampembeng 15:6f2798e45099 377 if (jsoneq(pJsonDocument, &(jsonTokenStruct[i]), pDataStruct->pKey) == 0) {
ampembeng 15:6f2798e45099 378 jsmntok_t dataToken = jsonTokenStruct[i + 1];
ampembeng 15:6f2798e45099 379 uint32_t dataLength = dataToken.end - dataToken.start;
ampembeng 15:6f2798e45099 380 UpdateValueIfNoObject(pJsonDocument, pDataStruct, dataToken);
ampembeng 15:6f2798e45099 381 *pDataPosition = dataToken.start;
ampembeng 15:6f2798e45099 382 *pDataLength = dataLength;
ampembeng 15:6f2798e45099 383 return true;
ampembeng 15:6f2798e45099 384 }
ampembeng 15:6f2798e45099 385 }
ampembeng 15:6f2798e45099 386 return false;
ampembeng 15:6f2798e45099 387 }
ampembeng 15:6f2798e45099 388
ampembeng 15:6f2798e45099 389 bool isReceivedJsonValid(const char *pJsonDocument) {
ampembeng 15:6f2798e45099 390 int32_t tokenCount;
ampembeng 15:6f2798e45099 391
ampembeng 15:6f2798e45099 392 jsmn_init(&shadowJsonParser);
ampembeng 15:6f2798e45099 393
ampembeng 15:6f2798e45099 394 tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct,
ampembeng 15:6f2798e45099 395 sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0]));
ampembeng 15:6f2798e45099 396
ampembeng 15:6f2798e45099 397 if (tokenCount < 0) {
ampembeng 15:6f2798e45099 398 WARN("Failed to parse JSON: %d\n", tokenCount);
ampembeng 15:6f2798e45099 399 return false;
ampembeng 15:6f2798e45099 400 }
ampembeng 15:6f2798e45099 401
ampembeng 15:6f2798e45099 402 /* Assume the top-level element is an object */
ampembeng 15:6f2798e45099 403 if (tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) {
ampembeng 15:6f2798e45099 404 return false;
ampembeng 15:6f2798e45099 405 }
ampembeng 15:6f2798e45099 406
ampembeng 15:6f2798e45099 407 return true;
ampembeng 15:6f2798e45099 408 }
ampembeng 15:6f2798e45099 409
ampembeng 15:6f2798e45099 410 bool extractClientToken(const char *pJsonDocument, char *pExtractedClientToken) {
ampembeng 15:6f2798e45099 411 bool ret_val = false;
ampembeng 15:6f2798e45099 412 jsmn_init(&shadowJsonParser);
ampembeng 15:6f2798e45099 413 int32_t tokenCount, i;
ampembeng 15:6f2798e45099 414 jsmntok_t ClientJsonToken;
ampembeng 15:6f2798e45099 415
ampembeng 15:6f2798e45099 416 tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct,
ampembeng 15:6f2798e45099 417 sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0]));
ampembeng 15:6f2798e45099 418
ampembeng 15:6f2798e45099 419 if (tokenCount < 0) {
ampembeng 15:6f2798e45099 420 WARN("Failed to parse JSON: %d\n", tokenCount);
ampembeng 15:6f2798e45099 421 return false;
ampembeng 15:6f2798e45099 422 }
ampembeng 15:6f2798e45099 423
ampembeng 15:6f2798e45099 424 /* Assume the top-level element is an object */
ampembeng 15:6f2798e45099 425 if (tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) {
ampembeng 15:6f2798e45099 426 return false;
ampembeng 15:6f2798e45099 427 }
ampembeng 15:6f2798e45099 428
ampembeng 15:6f2798e45099 429 for (i = 1; i < tokenCount; i++) {
ampembeng 15:6f2798e45099 430 if (jsoneq(pJsonDocument, &jsonTokenStruct[i], SHADOW_CLIENT_TOKEN_STRING) == 0) {
ampembeng 15:6f2798e45099 431 ClientJsonToken = jsonTokenStruct[i + 1];
ampembeng 15:6f2798e45099 432 uint8_t length = ClientJsonToken.end - ClientJsonToken.start;
ampembeng 15:6f2798e45099 433 strncpy(pExtractedClientToken, pJsonDocument + ClientJsonToken.start, length);
ampembeng 15:6f2798e45099 434 pExtractedClientToken[length] = '\0';
ampembeng 15:6f2798e45099 435 return true;
ampembeng 15:6f2798e45099 436 }
ampembeng 15:6f2798e45099 437 }
ampembeng 15:6f2798e45099 438
ampembeng 15:6f2798e45099 439 return false;
ampembeng 15:6f2798e45099 440 }
ampembeng 15:6f2798e45099 441
ampembeng 15:6f2798e45099 442 bool extractVersionNumber(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount, uint32_t *pVersionNumber) {
ampembeng 15:6f2798e45099 443 int32_t i;
ampembeng 15:6f2798e45099 444 jsmntok_t *pJsonTokenStruct;
ampembeng 15:6f2798e45099 445 IoT_Error_t ret_val = NONE_ERROR;
ampembeng 15:6f2798e45099 446
ampembeng 15:6f2798e45099 447 pJsonTokenStruct = (jsmntok_t *) pJsonHandler;
ampembeng 15:6f2798e45099 448 for (i = 1; i < tokenCount; i++) {
ampembeng 15:6f2798e45099 449 if (jsoneq(pJsonDocument, &(jsonTokenStruct[i]), SHADOW_VERSION_STRING) == 0) {
ampembeng 15:6f2798e45099 450 jsmntok_t dataToken = jsonTokenStruct[i + 1];
ampembeng 15:6f2798e45099 451 uint32_t dataLength = dataToken.end - dataToken.start;
ampembeng 15:6f2798e45099 452 ret_val = parseUnsignedInteger32Value(pVersionNumber, pJsonDocument, &dataToken);
ampembeng 15:6f2798e45099 453 if (ret_val == NONE_ERROR) {
ampembeng 15:6f2798e45099 454 return true;
ampembeng 15:6f2798e45099 455 }
ampembeng 15:6f2798e45099 456 }
ampembeng 15:6f2798e45099 457 }
ampembeng 15:6f2798e45099 458 return false;
ampembeng 15:6f2798e45099 459 }
ampembeng 15:6f2798e45099 460
ampembeng 15:6f2798e45099 461