test

Committer:
peyo
Date:
Wed Apr 12 14:07:09 2017 +0200
Revision:
0:cd5404401c2f
first commit

Who changed what in which revision?

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