Changes to enabled on-line compiler

Committer:
JMF
Date:
Wed May 30 20:59:51 2018 +0000
Revision:
0:082731ede69f
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew 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 aws_iot_shadow_json.c
JMF 0:082731ede69f 18 * @brief Shadow client JSON parsing API definitions
JMF 0:082731ede69f 19 */
JMF 0:082731ede69f 20
JMF 0:082731ede69f 21 #ifdef __cplusplus
JMF 0:082731ede69f 22 extern "C" {
JMF 0:082731ede69f 23 #endif
JMF 0:082731ede69f 24
JMF 0:082731ede69f 25 #include "aws_iot_shadow_json.h"
JMF 0:082731ede69f 26
JMF 0:082731ede69f 27 #include <string.h>
JMF 0:082731ede69f 28 #include <stdbool.h>
JMF 0:082731ede69f 29
JMF 0:082731ede69f 30 #include "aws_iot_json_utils.h"
JMF 0:082731ede69f 31 #include "aws_iot_log.h"
JMF 0:082731ede69f 32 #include "aws_iot_shadow_key.h"
JMF 0:082731ede69f 33 #include "aws_iot_config.h"
JMF 0:082731ede69f 34
JMF 0:082731ede69f 35 extern char mqttClientID[MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES];
JMF 0:082731ede69f 36 #define AWS_IOT_SHADOW_CLIENT_TOKEN_KEY "{\"clientToken\":\""
JMF 0:082731ede69f 37 static uint32_t clientTokenNum = 0;
JMF 0:082731ede69f 38
JMF 0:082731ede69f 39 //helper functions
JMF 0:082731ede69f 40 static IoT_Error_t convertDataToString(char *pStringBuffer, size_t maxSizoStringBuffer, JsonPrimitiveType type,
JMF 0:082731ede69f 41 void *pData);
JMF 0:082731ede69f 42
JMF 0:082731ede69f 43 void resetClientTokenSequenceNum(void) {
JMF 0:082731ede69f 44 clientTokenNum = 0;
JMF 0:082731ede69f 45 }
JMF 0:082731ede69f 46
JMF 0:082731ede69f 47 static IoT_Error_t emptyJsonWithClientToken(char *pBuffer, size_t bufferSize) {
JMF 0:082731ede69f 48
JMF 0:082731ede69f 49 IoT_Error_t rc = AWS_SUCCESS;
JMF 0:082731ede69f 50 size_t dataLenInBuffer = 0;
JMF 0:082731ede69f 51
JMF 0:082731ede69f 52 if(pBuffer != NULL)
JMF 0:082731ede69f 53 {
JMF 0:082731ede69f 54 dataLenInBuffer = (size_t)snprintf(pBuffer, bufferSize, AWS_IOT_SHADOW_CLIENT_TOKEN_KEY);
JMF 0:082731ede69f 55 }else
JMF 0:082731ede69f 56 {
JMF 0:082731ede69f 57 IOT_ERROR("NULL buffer in emptyJsonWithClientToken\n");
JMF 0:082731ede69f 58 rc = FAILURE;
JMF 0:082731ede69f 59 }
JMF 0:082731ede69f 60
JMF 0:082731ede69f 61 if(rc == AWS_SUCCESS)
JMF 0:082731ede69f 62 {
JMF 0:082731ede69f 63 if ( dataLenInBuffer < bufferSize )
JMF 0:082731ede69f 64 {
JMF 0:082731ede69f 65 dataLenInBuffer += (size_t)snprintf(pBuffer + dataLenInBuffer, bufferSize - dataLenInBuffer, "%s-%d", mqttClientID, ( int )clientTokenNum++);
JMF 0:082731ede69f 66 }
JMF 0:082731ede69f 67 else
JMF 0:082731ede69f 68 {
JMF 0:082731ede69f 69 rc = FAILURE;
JMF 0:082731ede69f 70 IOT_ERROR("Supplied buffer too small to create JSON file\n");
JMF 0:082731ede69f 71 }
JMF 0:082731ede69f 72 }
JMF 0:082731ede69f 73
JMF 0:082731ede69f 74 if(rc == AWS_SUCCESS)
JMF 0:082731ede69f 75 {
JMF 0:082731ede69f 76 if ( dataLenInBuffer < bufferSize )
JMF 0:082731ede69f 77 {
JMF 0:082731ede69f 78 dataLenInBuffer += (size_t)snprintf( pBuffer + dataLenInBuffer, bufferSize - dataLenInBuffer, "\"}" );
JMF 0:082731ede69f 79 if ( dataLenInBuffer > bufferSize )
JMF 0:082731ede69f 80 {
JMF 0:082731ede69f 81 rc = FAILURE;
JMF 0:082731ede69f 82 IOT_ERROR( "Supplied buffer too small to create JSON file\n" );
JMF 0:082731ede69f 83 }
JMF 0:082731ede69f 84 }
JMF 0:082731ede69f 85 else
JMF 0:082731ede69f 86 {
JMF 0:082731ede69f 87 rc = FAILURE;
JMF 0:082731ede69f 88 IOT_ERROR( "Supplied buffer too small to create JSON file\n" );
JMF 0:082731ede69f 89 }
JMF 0:082731ede69f 90 }
JMF 0:082731ede69f 91
JMF 0:082731ede69f 92 FUNC_EXIT_RC(rc);
JMF 0:082731ede69f 93 }
JMF 0:082731ede69f 94
JMF 0:082731ede69f 95 IoT_Error_t aws_iot_shadow_internal_get_request_json(char *pBuffer, size_t bufferSize) {
JMF 0:082731ede69f 96 return emptyJsonWithClientToken( pBuffer, bufferSize);
JMF 0:082731ede69f 97 }
JMF 0:082731ede69f 98
JMF 0:082731ede69f 99 IoT_Error_t aws_iot_shadow_internal_delete_request_json(char *pBuffer, size_t bufferSize ) {
JMF 0:082731ede69f 100 return emptyJsonWithClientToken( pBuffer, bufferSize);
JMF 0:082731ede69f 101 }
JMF 0:082731ede69f 102
JMF 0:082731ede69f 103 static inline IoT_Error_t checkReturnValueOfSnPrintf(int32_t snPrintfReturn, size_t maxSizeOfJsonDocument) {
JMF 0:082731ede69f 104 if(snPrintfReturn < 0) {
JMF 0:082731ede69f 105 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 106 } else if((size_t) snPrintfReturn >= maxSizeOfJsonDocument) {
JMF 0:082731ede69f 107 return SHADOW_JSON_BUFFER_TRUNCATED;
JMF 0:082731ede69f 108 }
JMF 0:082731ede69f 109 return AWS_SUCCESS;
JMF 0:082731ede69f 110 }
JMF 0:082731ede69f 111
JMF 0:082731ede69f 112 IoT_Error_t aws_iot_shadow_init_json_document(char *pJsonDocument, size_t maxSizeOfJsonDocument) {
JMF 0:082731ede69f 113
JMF 0:082731ede69f 114 IoT_Error_t ret_val = AWS_SUCCESS;
JMF 0:082731ede69f 115 int32_t snPrintfReturn = 0;
JMF 0:082731ede69f 116
JMF 0:082731ede69f 117 if(pJsonDocument == NULL) {
JMF 0:082731ede69f 118 return NULL_VALUE_ERROR;
JMF 0:082731ede69f 119 }
JMF 0:082731ede69f 120 snPrintfReturn = snprintf(pJsonDocument, maxSizeOfJsonDocument, "{\"state\":{");
JMF 0:082731ede69f 121
JMF 0:082731ede69f 122 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, maxSizeOfJsonDocument);
JMF 0:082731ede69f 123
JMF 0:082731ede69f 124 return ret_val;
JMF 0:082731ede69f 125
JMF 0:082731ede69f 126 }
JMF 0:082731ede69f 127
JMF 0:082731ede69f 128 IoT_Error_t aws_iot_shadow_add_desired(char *pJsonDocument, size_t maxSizeOfJsonDocument, uint8_t count, ...) {
JMF 0:082731ede69f 129 IoT_Error_t ret_val = AWS_SUCCESS;
JMF 0:082731ede69f 130 size_t tempSize = 0;
JMF 0:082731ede69f 131 int8_t i;
JMF 0:082731ede69f 132 size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument;
JMF 0:082731ede69f 133 int32_t snPrintfReturn = 0;
JMF 0:082731ede69f 134 va_list pArgs;
JMF 0:082731ede69f 135 jsonStruct_t *pTemporary = NULL;
JMF 0:082731ede69f 136 va_start(pArgs, count);
JMF 0:082731ede69f 137
JMF 0:082731ede69f 138 if(pJsonDocument == NULL) {
JMF 0:082731ede69f 139 va_end(pArgs);
JMF 0:082731ede69f 140 return NULL_VALUE_ERROR;
JMF 0:082731ede69f 141 }
JMF 0:082731ede69f 142
JMF 0:082731ede69f 143 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
JMF 0:082731ede69f 144 if(tempSize <= 1) {
JMF 0:082731ede69f 145 va_end(pArgs);
JMF 0:082731ede69f 146 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 147 }
JMF 0:082731ede69f 148 remSizeOfJsonBuffer = tempSize;
JMF 0:082731ede69f 149
JMF 0:082731ede69f 150 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"desired\":{");
JMF 0:082731ede69f 151 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
JMF 0:082731ede69f 152
JMF 0:082731ede69f 153 if(ret_val != AWS_SUCCESS) {
JMF 0:082731ede69f 154 va_end(pArgs);
JMF 0:082731ede69f 155 return ret_val;
JMF 0:082731ede69f 156 }
JMF 0:082731ede69f 157
JMF 0:082731ede69f 158 for(i = 0; i < count; i++) {
JMF 0:082731ede69f 159 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
JMF 0:082731ede69f 160 if(tempSize <= 1) {
JMF 0:082731ede69f 161 va_end(pArgs);
JMF 0:082731ede69f 162 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 163 }
JMF 0:082731ede69f 164 remSizeOfJsonBuffer = tempSize;
JMF 0:082731ede69f 165 pTemporary = va_arg (pArgs, jsonStruct_t *);
JMF 0:082731ede69f 166 if(pTemporary != NULL) {
JMF 0:082731ede69f 167 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"%s\":",
JMF 0:082731ede69f 168 pTemporary->pKey);
JMF 0:082731ede69f 169 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
JMF 0:082731ede69f 170 if(ret_val != AWS_SUCCESS) {
JMF 0:082731ede69f 171 va_end(pArgs);
JMF 0:082731ede69f 172 return ret_val;
JMF 0:082731ede69f 173 }
JMF 0:082731ede69f 174 if(pTemporary->pKey != NULL && pTemporary->pData != NULL) {
JMF 0:082731ede69f 175 ret_val = convertDataToString(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer,
JMF 0:082731ede69f 176 pTemporary->type, pTemporary->pData);
JMF 0:082731ede69f 177 } else {
JMF 0:082731ede69f 178 va_end(pArgs);
JMF 0:082731ede69f 179 return NULL_VALUE_ERROR;
JMF 0:082731ede69f 180 }
JMF 0:082731ede69f 181 if(ret_val != AWS_SUCCESS) {
JMF 0:082731ede69f 182 va_end(pArgs);
JMF 0:082731ede69f 183 return ret_val;
JMF 0:082731ede69f 184 }
JMF 0:082731ede69f 185 } else {
JMF 0:082731ede69f 186 va_end(pArgs);
JMF 0:082731ede69f 187 return NULL_VALUE_ERROR;
JMF 0:082731ede69f 188 }
JMF 0:082731ede69f 189 }
JMF 0:082731ede69f 190
JMF 0:082731ede69f 191 va_end(pArgs);
JMF 0:082731ede69f 192 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "},");
JMF 0:082731ede69f 193 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
JMF 0:082731ede69f 194 return ret_val;
JMF 0:082731ede69f 195 }
JMF 0:082731ede69f 196
JMF 0:082731ede69f 197 IoT_Error_t aws_iot_shadow_add_reported(char *pJsonDocument, size_t maxSizeOfJsonDocument, uint8_t count, ...) {
JMF 0:082731ede69f 198 IoT_Error_t ret_val = AWS_SUCCESS;
JMF 0:082731ede69f 199
JMF 0:082731ede69f 200 int8_t i;
JMF 0:082731ede69f 201 size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument;
JMF 0:082731ede69f 202 int32_t snPrintfReturn = 0;
JMF 0:082731ede69f 203 size_t tempSize = 0;
JMF 0:082731ede69f 204 jsonStruct_t *pTemporary;
JMF 0:082731ede69f 205 va_list pArgs;
JMF 0:082731ede69f 206 va_start(pArgs, count);
JMF 0:082731ede69f 207
JMF 0:082731ede69f 208 if(pJsonDocument == NULL) {
JMF 0:082731ede69f 209 va_end(pArgs);
JMF 0:082731ede69f 210 return NULL_VALUE_ERROR;
JMF 0:082731ede69f 211 }
JMF 0:082731ede69f 212
JMF 0:082731ede69f 213
JMF 0:082731ede69f 214 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
JMF 0:082731ede69f 215 if(tempSize <= 1) {
JMF 0:082731ede69f 216 va_end(pArgs);
JMF 0:082731ede69f 217 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 218 }
JMF 0:082731ede69f 219 remSizeOfJsonBuffer = tempSize;
JMF 0:082731ede69f 220
JMF 0:082731ede69f 221 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"reported\":{");
JMF 0:082731ede69f 222 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
JMF 0:082731ede69f 223
JMF 0:082731ede69f 224 if(ret_val != AWS_SUCCESS) {
JMF 0:082731ede69f 225 va_end(pArgs);
JMF 0:082731ede69f 226 return ret_val;
JMF 0:082731ede69f 227 }
JMF 0:082731ede69f 228
JMF 0:082731ede69f 229 for(i = 0; i < count; i++) {
JMF 0:082731ede69f 230 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
JMF 0:082731ede69f 231 if(tempSize <= 1) {
JMF 0:082731ede69f 232 va_end(pArgs);
JMF 0:082731ede69f 233 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 234 }
JMF 0:082731ede69f 235 remSizeOfJsonBuffer = tempSize;
JMF 0:082731ede69f 236
JMF 0:082731ede69f 237 pTemporary = va_arg (pArgs, jsonStruct_t *);
JMF 0:082731ede69f 238 if(pTemporary != NULL) {
JMF 0:082731ede69f 239 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"%s\":",
JMF 0:082731ede69f 240 pTemporary->pKey);
JMF 0:082731ede69f 241 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
JMF 0:082731ede69f 242 if(ret_val != AWS_SUCCESS) {
JMF 0:082731ede69f 243 va_end(pArgs);
JMF 0:082731ede69f 244 return ret_val;
JMF 0:082731ede69f 245 }
JMF 0:082731ede69f 246 if(pTemporary->pKey != NULL && pTemporary->pData != NULL) {
JMF 0:082731ede69f 247 ret_val = convertDataToString(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer,
JMF 0:082731ede69f 248 pTemporary->type, pTemporary->pData);
JMF 0:082731ede69f 249 } else {
JMF 0:082731ede69f 250 va_end(pArgs);
JMF 0:082731ede69f 251 return NULL_VALUE_ERROR;
JMF 0:082731ede69f 252 }
JMF 0:082731ede69f 253 if(ret_val != AWS_SUCCESS) {
JMF 0:082731ede69f 254 va_end(pArgs);
JMF 0:082731ede69f 255 return ret_val;
JMF 0:082731ede69f 256 }
JMF 0:082731ede69f 257 } else {
JMF 0:082731ede69f 258 va_end(pArgs);
JMF 0:082731ede69f 259 return NULL_VALUE_ERROR;
JMF 0:082731ede69f 260 }
JMF 0:082731ede69f 261 }
JMF 0:082731ede69f 262
JMF 0:082731ede69f 263 va_end(pArgs);
JMF 0:082731ede69f 264 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "},");
JMF 0:082731ede69f 265 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
JMF 0:082731ede69f 266 return ret_val;
JMF 0:082731ede69f 267 }
JMF 0:082731ede69f 268
JMF 0:082731ede69f 269
JMF 0:082731ede69f 270 int32_t FillWithClientTokenSize(char *pBufferToBeUpdatedWithClientToken, size_t maxSizeOfJsonDocument) {
JMF 0:082731ede69f 271 int32_t snPrintfReturn;
JMF 0:082731ede69f 272 snPrintfReturn = snprintf(pBufferToBeUpdatedWithClientToken, maxSizeOfJsonDocument, "%s-%d", mqttClientID,
JMF 0:082731ede69f 273 (int) clientTokenNum++);
JMF 0:082731ede69f 274
JMF 0:082731ede69f 275 return snPrintfReturn;
JMF 0:082731ede69f 276 }
JMF 0:082731ede69f 277
JMF 0:082731ede69f 278 IoT_Error_t aws_iot_fill_with_client_token(char *pBufferToBeUpdatedWithClientToken, size_t maxSizeOfJsonDocument) {
JMF 0:082731ede69f 279
JMF 0:082731ede69f 280 int32_t snPrintfRet = 0;
JMF 0:082731ede69f 281 snPrintfRet = FillWithClientTokenSize(pBufferToBeUpdatedWithClientToken, maxSizeOfJsonDocument);
JMF 0:082731ede69f 282 return checkReturnValueOfSnPrintf(snPrintfRet, maxSizeOfJsonDocument);
JMF 0:082731ede69f 283
JMF 0:082731ede69f 284 }
JMF 0:082731ede69f 285
JMF 0:082731ede69f 286 IoT_Error_t aws_iot_finalize_json_document(char *pJsonDocument, size_t maxSizeOfJsonDocument) {
JMF 0:082731ede69f 287 size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument;
JMF 0:082731ede69f 288 int32_t snPrintfReturn = 0;
JMF 0:082731ede69f 289 size_t tempSize = 0;
JMF 0:082731ede69f 290 IoT_Error_t ret_val = AWS_SUCCESS;
JMF 0:082731ede69f 291
JMF 0:082731ede69f 292 if(pJsonDocument == NULL) {
JMF 0:082731ede69f 293 return NULL_VALUE_ERROR;
JMF 0:082731ede69f 294 }
JMF 0:082731ede69f 295
JMF 0:082731ede69f 296 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
JMF 0:082731ede69f 297 if(tempSize <= 1) {
JMF 0:082731ede69f 298 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 299 }
JMF 0:082731ede69f 300 remSizeOfJsonBuffer = tempSize;
JMF 0:082731ede69f 301
JMF 0:082731ede69f 302 // strlen(ShadowTxBuffer) - 1 is to ensure we remove the last ,(comma) that was added
JMF 0:082731ede69f 303 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "}, \"%s\":\"",
JMF 0:082731ede69f 304 SHADOW_CLIENT_TOKEN_STRING);
JMF 0:082731ede69f 305 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
JMF 0:082731ede69f 306
JMF 0:082731ede69f 307 if(ret_val != AWS_SUCCESS) {
JMF 0:082731ede69f 308 return ret_val;
JMF 0:082731ede69f 309 }
JMF 0:082731ede69f 310 // refactor this XXX repeated code
JMF 0:082731ede69f 311 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
JMF 0:082731ede69f 312 if(tempSize <= 1) {
JMF 0:082731ede69f 313 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 314 }
JMF 0:082731ede69f 315 remSizeOfJsonBuffer = tempSize;
JMF 0:082731ede69f 316
JMF 0:082731ede69f 317
JMF 0:082731ede69f 318 snPrintfReturn = FillWithClientTokenSize(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer);
JMF 0:082731ede69f 319 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
JMF 0:082731ede69f 320
JMF 0:082731ede69f 321 if(ret_val != AWS_SUCCESS) {
JMF 0:082731ede69f 322 return ret_val;
JMF 0:082731ede69f 323 }
JMF 0:082731ede69f 324 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument);
JMF 0:082731ede69f 325 if(tempSize <= 1) {
JMF 0:082731ede69f 326 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 327 }
JMF 0:082731ede69f 328 remSizeOfJsonBuffer = tempSize;
JMF 0:082731ede69f 329
JMF 0:082731ede69f 330
JMF 0:082731ede69f 331 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"}");
JMF 0:082731ede69f 332 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer);
JMF 0:082731ede69f 333
JMF 0:082731ede69f 334 return ret_val;
JMF 0:082731ede69f 335 }
JMF 0:082731ede69f 336
JMF 0:082731ede69f 337 static IoT_Error_t convertDataToString(char *pStringBuffer, size_t maxSizoStringBuffer, JsonPrimitiveType type,
JMF 0:082731ede69f 338 void *pData) {
JMF 0:082731ede69f 339 int32_t snPrintfReturn = 0;
JMF 0:082731ede69f 340 IoT_Error_t ret_val = AWS_SUCCESS;
JMF 0:082731ede69f 341
JMF 0:082731ede69f 342 if(maxSizoStringBuffer == 0) {
JMF 0:082731ede69f 343 return SHADOW_JSON_ERROR;
JMF 0:082731ede69f 344 }
JMF 0:082731ede69f 345
JMF 0:082731ede69f 346 if(type == SHADOW_JSON_INT32) {
JMF 0:082731ede69f 347 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%li,", *(int32_t *) (pData));
JMF 0:082731ede69f 348 } else if(type == SHADOW_JSON_INT16) {
JMF 0:082731ede69f 349 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%hi,", *(int16_t *) (pData));
JMF 0:082731ede69f 350 } else if(type == SHADOW_JSON_INT8) {
JMF 0:082731ede69f 351 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%hhi,", *(int8_t *) (pData));
JMF 0:082731ede69f 352 } else if(type == SHADOW_JSON_UINT32) {
JMF 0:082731ede69f 353 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%lu,", *(uint32_t *) (pData));
JMF 0:082731ede69f 354 } else if(type == SHADOW_JSON_UINT16) {
JMF 0:082731ede69f 355 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%hu,", *(uint16_t *) (pData));
JMF 0:082731ede69f 356 } else if(type == SHADOW_JSON_UINT8) {
JMF 0:082731ede69f 357 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%hhu,", *(uint8_t *) (pData));
JMF 0:082731ede69f 358 } else if(type == SHADOW_JSON_DOUBLE) {
JMF 0:082731ede69f 359 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%f,", *(double *) (pData));
JMF 0:082731ede69f 360 } else if(type == SHADOW_JSON_FLOAT) {
JMF 0:082731ede69f 361 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%f,", *(float *) (pData));
JMF 0:082731ede69f 362 } else if(type == SHADOW_JSON_BOOL) {
JMF 0:082731ede69f 363 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%s,", *(bool *) (pData) ? "true" : "false");
JMF 0:082731ede69f 364 } else if(type == SHADOW_JSON_STRING) {
JMF 0:082731ede69f 365 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "\"%s\",", (char *) (pData));
JMF 0:082731ede69f 366 } else if(type == SHADOW_JSON_OBJECT) {
JMF 0:082731ede69f 367 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%s,", (char *) (pData));
JMF 0:082731ede69f 368 }
JMF 0:082731ede69f 369
JMF 0:082731ede69f 370
JMF 0:082731ede69f 371 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, maxSizoStringBuffer);
JMF 0:082731ede69f 372
JMF 0:082731ede69f 373 return ret_val;
JMF 0:082731ede69f 374 }
JMF 0:082731ede69f 375
JMF 0:082731ede69f 376 static jsmn_parser shadowJsonParser;
JMF 0:082731ede69f 377 static jsmntok_t jsonTokenStruct[MAX_JSON_TOKEN_EXPECTED];
JMF 0:082731ede69f 378
JMF 0:082731ede69f 379 bool isJsonValidAndParse(const char *pJsonDocument, size_t jsonSize, void *pJsonHandler, int32_t *pTokenCount) {
JMF 0:082731ede69f 380 int32_t tokenCount;
JMF 0:082731ede69f 381
JMF 0:082731ede69f 382 IOT_UNUSED(pJsonHandler);
JMF 0:082731ede69f 383
JMF 0:082731ede69f 384 jsmn_init(&shadowJsonParser);
JMF 0:082731ede69f 385
JMF 0:082731ede69f 386 tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, jsonSize, jsonTokenStruct,
JMF 0:082731ede69f 387 sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0]));
JMF 0:082731ede69f 388
JMF 0:082731ede69f 389 if(tokenCount < 0) {
JMF 0:082731ede69f 390 IOT_WARN("Failed to parse JSON: %ld\n", tokenCount);
JMF 0:082731ede69f 391 return false;
JMF 0:082731ede69f 392 }
JMF 0:082731ede69f 393
JMF 0:082731ede69f 394 /* Assume the top-level element is an object */
JMF 0:082731ede69f 395 if(tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) {
JMF 0:082731ede69f 396 IOT_WARN("Top Level is not an object\n");
JMF 0:082731ede69f 397 return false;
JMF 0:082731ede69f 398 }
JMF 0:082731ede69f 399
JMF 0:082731ede69f 400 *pTokenCount = tokenCount;
JMF 0:082731ede69f 401
JMF 0:082731ede69f 402 return true;
JMF 0:082731ede69f 403 }
JMF 0:082731ede69f 404
JMF 0:082731ede69f 405 static IoT_Error_t UpdateValueIfNoObject(const char *pJsonString, jsonStruct_t *pDataStruct, jsmntok_t token) {
JMF 0:082731ede69f 406 IoT_Error_t ret_val = SHADOW_JSON_ERROR;
JMF 0:082731ede69f 407 if(pDataStruct->type == SHADOW_JSON_BOOL && pDataStruct->dataLength >= sizeof(bool)) {
JMF 0:082731ede69f 408 ret_val = parseBooleanValue((bool *) pDataStruct->pData, pJsonString, &token);
JMF 0:082731ede69f 409 } else if(pDataStruct->type == SHADOW_JSON_INT32 && pDataStruct->dataLength >= sizeof(int32_t)) {
JMF 0:082731ede69f 410 ret_val = parseInteger32Value((int32_t *) pDataStruct->pData, pJsonString, &token);
JMF 0:082731ede69f 411 } else if(pDataStruct->type == SHADOW_JSON_INT16 && pDataStruct->dataLength >= sizeof(int16_t)) {
JMF 0:082731ede69f 412 ret_val = parseInteger16Value((int16_t *) pDataStruct->pData, pJsonString, &token);
JMF 0:082731ede69f 413 } else if(pDataStruct->type == SHADOW_JSON_INT8 && pDataStruct->dataLength >= sizeof(int8_t)) {
JMF 0:082731ede69f 414 ret_val = parseInteger8Value((int8_t *) pDataStruct->pData, pJsonString, &token);
JMF 0:082731ede69f 415 } else if(pDataStruct->type == SHADOW_JSON_UINT32 && pDataStruct->dataLength >= sizeof(uint32_t)) {
JMF 0:082731ede69f 416 ret_val = parseUnsignedInteger32Value((uint32_t *) pDataStruct->pData, pJsonString, &token);
JMF 0:082731ede69f 417 } else if(pDataStruct->type == SHADOW_JSON_UINT16 && pDataStruct->dataLength >= sizeof(uint16_t)) {
JMF 0:082731ede69f 418 ret_val = parseUnsignedInteger16Value((uint16_t *) pDataStruct->pData, pJsonString, &token);
JMF 0:082731ede69f 419 } else if(pDataStruct->type == SHADOW_JSON_UINT8 && pDataStruct->dataLength >= sizeof(uint8_t)) {
JMF 0:082731ede69f 420 ret_val = parseUnsignedInteger8Value((uint8_t *) pDataStruct->pData, pJsonString, &token);
JMF 0:082731ede69f 421 } else if(pDataStruct->type == SHADOW_JSON_FLOAT && pDataStruct->dataLength >= sizeof(float)) {
JMF 0:082731ede69f 422 ret_val = parseFloatValue((float *) pDataStruct->pData, pJsonString, &token);
JMF 0:082731ede69f 423 } else if(pDataStruct->type == SHADOW_JSON_DOUBLE && pDataStruct->dataLength >= sizeof(double)) {
JMF 0:082731ede69f 424 ret_val = parseDoubleValue((double *) pDataStruct->pData, pJsonString, &token);
JMF 0:082731ede69f 425 } else if(pDataStruct->type == SHADOW_JSON_STRING) {
JMF 0:082731ede69f 426 ret_val = parseStringValue((char *) pDataStruct->pData, pDataStruct->dataLength, pJsonString, &token);
JMF 0:082731ede69f 427 }
JMF 0:082731ede69f 428
JMF 0:082731ede69f 429 return ret_val;
JMF 0:082731ede69f 430 }
JMF 0:082731ede69f 431
JMF 0:082731ede69f 432 bool isJsonKeyMatchingAndUpdateValue(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount,
JMF 0:082731ede69f 433 jsonStruct_t *pDataStruct, uint32_t *pDataLength, int32_t *pDataPosition) {
JMF 0:082731ede69f 434 int32_t i;
JMF 0:082731ede69f 435 uint32_t dataLength;
JMF 0:082731ede69f 436 jsmntok_t dataToken;
JMF 0:082731ede69f 437
JMF 0:082731ede69f 438 IOT_UNUSED(pJsonHandler);
JMF 0:082731ede69f 439
JMF 0:082731ede69f 440 for(i = 1; i < tokenCount; i++) {
JMF 0:082731ede69f 441 if(jsoneq(pJsonDocument, &(jsonTokenStruct[i]), pDataStruct->pKey) == 0) {
JMF 0:082731ede69f 442 dataToken = jsonTokenStruct[i + 1];
JMF 0:082731ede69f 443 dataLength = (uint32_t) (dataToken.end - dataToken.start);
JMF 0:082731ede69f 444 UpdateValueIfNoObject(pJsonDocument, pDataStruct, dataToken);
JMF 0:082731ede69f 445 *pDataPosition = dataToken.start;
JMF 0:082731ede69f 446 *pDataLength = dataLength;
JMF 0:082731ede69f 447 return true;
JMF 0:082731ede69f 448 } else if(jsoneq(pJsonDocument, &(jsonTokenStruct[i]), "metadata") == 0) {
JMF 0:082731ede69f 449 return false;
JMF 0:082731ede69f 450 }
JMF 0:082731ede69f 451 }
JMF 0:082731ede69f 452 return false;
JMF 0:082731ede69f 453 }
JMF 0:082731ede69f 454
JMF 0:082731ede69f 455 bool isReceivedJsonValid(const char *pJsonDocument, size_t jsonSize ) {
JMF 0:082731ede69f 456 int32_t tokenCount;
JMF 0:082731ede69f 457
JMF 0:082731ede69f 458 jsmn_init(&shadowJsonParser);
JMF 0:082731ede69f 459
JMF 0:082731ede69f 460 tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, jsonSize, jsonTokenStruct,
JMF 0:082731ede69f 461 sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0]));
JMF 0:082731ede69f 462
JMF 0:082731ede69f 463 if(tokenCount < 0) {
JMF 0:082731ede69f 464 IOT_WARN("Failed to parse JSON: %ld\n", tokenCount);
JMF 0:082731ede69f 465 return false;
JMF 0:082731ede69f 466 }
JMF 0:082731ede69f 467
JMF 0:082731ede69f 468 /* Assume the top-level element is an object */
JMF 0:082731ede69f 469 if(tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) {
JMF 0:082731ede69f 470 return false;
JMF 0:082731ede69f 471 }
JMF 0:082731ede69f 472
JMF 0:082731ede69f 473 return true;
JMF 0:082731ede69f 474 }
JMF 0:082731ede69f 475
JMF 0:082731ede69f 476 bool extractClientToken(const char *pJsonDocument, size_t jsonSize, char *pExtractedClientToken, size_t clientTokenSize) {
JMF 0:082731ede69f 477 int32_t tokenCount, i;
JMF 0:082731ede69f 478 size_t length;
JMF 0:082731ede69f 479 jsmntok_t ClientJsonToken;
JMF 0:082731ede69f 480 jsmn_init(&shadowJsonParser);
JMF 0:082731ede69f 481
JMF 0:082731ede69f 482 tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, jsonSize, jsonTokenStruct,
JMF 0:082731ede69f 483 sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0]));
JMF 0:082731ede69f 484
JMF 0:082731ede69f 485 if(tokenCount < 0) {
JMF 0:082731ede69f 486 IOT_WARN("Failed to parse JSON: %ld\n", tokenCount);
JMF 0:082731ede69f 487 return false;
JMF 0:082731ede69f 488 }
JMF 0:082731ede69f 489
JMF 0:082731ede69f 490 /* Assume the top-level element is an object */
JMF 0:082731ede69f 491 if(tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) {
JMF 0:082731ede69f 492 return false;
JMF 0:082731ede69f 493 }
JMF 0:082731ede69f 494
JMF 0:082731ede69f 495 for(i = 1; i < tokenCount; i++) {
JMF 0:082731ede69f 496 if(jsoneq(pJsonDocument, &jsonTokenStruct[i], SHADOW_CLIENT_TOKEN_STRING) == 0) {
JMF 0:082731ede69f 497 ClientJsonToken = jsonTokenStruct[i + 1];
JMF 0:082731ede69f 498 length = (uint8_t) (ClientJsonToken.end - ClientJsonToken.start);
JMF 0:082731ede69f 499 if (clientTokenSize >= length + 1)
JMF 0:082731ede69f 500 {
JMF 0:082731ede69f 501 strncpy( pExtractedClientToken, pJsonDocument + ClientJsonToken.start, length);
JMF 0:082731ede69f 502 pExtractedClientToken[length] = '\0';
JMF 0:082731ede69f 503 return true;
JMF 0:082731ede69f 504 }else{
JMF 0:082731ede69f 505 IOT_WARN( "Token size %zu too small for string %zu \n", clientTokenSize, length);
JMF 0:082731ede69f 506 return false;
JMF 0:082731ede69f 507 }
JMF 0:082731ede69f 508 }
JMF 0:082731ede69f 509 }
JMF 0:082731ede69f 510
JMF 0:082731ede69f 511 return false;
JMF 0:082731ede69f 512 }
JMF 0:082731ede69f 513
JMF 0:082731ede69f 514 bool extractVersionNumber(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount, uint32_t *pVersionNumber) {
JMF 0:082731ede69f 515 int32_t i;
JMF 0:082731ede69f 516 IoT_Error_t ret_val = AWS_SUCCESS;
JMF 0:082731ede69f 517
JMF 0:082731ede69f 518 IOT_UNUSED(pJsonHandler);
JMF 0:082731ede69f 519
JMF 0:082731ede69f 520 for(i = 1; i < tokenCount; i++) {
JMF 0:082731ede69f 521 if(jsoneq(pJsonDocument, &(jsonTokenStruct[i]), SHADOW_VERSION_STRING) == 0) {
JMF 0:082731ede69f 522 ret_val = parseUnsignedInteger32Value(pVersionNumber, pJsonDocument, &jsonTokenStruct[i + 1]);
JMF 0:082731ede69f 523 if(ret_val == AWS_SUCCESS) {
JMF 0:082731ede69f 524 return true;
JMF 0:082731ede69f 525 }
JMF 0:082731ede69f 526 }
JMF 0:082731ede69f 527 }
JMF 0:082731ede69f 528 return false;
JMF 0:082731ede69f 529 }
JMF 0:082731ede69f 530
JMF 0:082731ede69f 531 #ifdef __cplusplus
JMF 0:082731ede69f 532 }
JMF 0:082731ede69f 533 #endif
JMF 0:082731ede69f 534