V.06 11/3
Dependencies: FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts
Fork of ATT_AWS_IoT_demo by
aws_iot_shadow_json.cpp
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 00016 #include "aws_iot_shadow_json.h" 00017 00018 #include <string.h> 00019 #include <stdbool.h> 00020 #include <inttypes.h> 00021 #include "aws_iot_json_utils.h" 00022 #include "aws_iot_log.h" 00023 #include "aws_iot_shadow_key.h" 00024 #include "aws_iot_config.h" 00025 00026 extern char mqttClientID[MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES]; 00027 00028 static uint32_t clientTokenNum = 0; 00029 00030 //helper functions 00031 static IoT_Error_t convertDataToString(char *pStringBuffer, size_t maxSizoStringBuffer, JsonPrimitiveType type, 00032 void *pData); 00033 00034 void resetClientTokenSequenceNum(void) { 00035 clientTokenNum = 0; 00036 } 00037 00038 static void emptyJsonWithClientToken(char *pJsonDocument) { 00039 sprintf(pJsonDocument, "{\"clientToken\":\""); 00040 FillWithClientToken(pJsonDocument + strlen(pJsonDocument)); 00041 sprintf(pJsonDocument + strlen(pJsonDocument), "\"}"); 00042 } 00043 00044 void iot_shadow_get_request_json(char *pJsonDocument) { 00045 emptyJsonWithClientToken(pJsonDocument); 00046 } 00047 00048 void iot_shadow_delete_request_json(char *pJsonDocument) { 00049 emptyJsonWithClientToken(pJsonDocument); 00050 } 00051 00052 static inline IoT_Error_t checkReturnValueOfSnPrintf(int32_t snPrintfReturn, size_t maxSizeOfJsonDocument) { 00053 00054 if (snPrintfReturn >= maxSizeOfJsonDocument) { 00055 return SHADOW_JSON_BUFFER_TRUNCATED; 00056 } else if (snPrintfReturn < 0) { 00057 return SHADOW_JSON_ERROR; 00058 } 00059 return NONE_ERROR; 00060 } 00061 00062 IoT_Error_t aws_iot_shadow_init_json_document(char *pJsonDocument, size_t maxSizeOfJsonDocument) { 00063 00064 IoT_Error_t ret_val = NONE_ERROR; 00065 int32_t snPrintfReturn = 0; 00066 00067 if (pJsonDocument == NULL) { 00068 return NULL_VALUE_ERROR; 00069 } 00070 snPrintfReturn = snprintf(pJsonDocument, maxSizeOfJsonDocument, "{\"state\":{"); 00071 00072 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, maxSizeOfJsonDocument); 00073 00074 return ret_val; 00075 00076 } 00077 00078 IoT_Error_t aws_iot_shadow_add_desired(char *pJsonDocument, size_t maxSizeOfJsonDocument, uint8_t count, ...) { 00079 IoT_Error_t ret_val = NONE_ERROR; 00080 int32_t tempSize = 0; 00081 int8_t i; 00082 size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument; 00083 int32_t snPrintfReturn = 0; 00084 va_list pArgs; 00085 va_start(pArgs, count); 00086 jsonStruct_t *pTemporary; 00087 00088 if (pJsonDocument == NULL) { 00089 return NULL_VALUE_ERROR; 00090 } 00091 00092 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); 00093 if(tempSize <= 1){ 00094 return SHADOW_JSON_ERROR; 00095 } 00096 remSizeOfJsonBuffer = tempSize; 00097 00098 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"desired\":{"); 00099 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); 00100 00101 if (ret_val != NONE_ERROR) { 00102 return ret_val; 00103 } 00104 00105 for (i = 0; i < count; i++) { 00106 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); 00107 if(tempSize <= 1){ 00108 return SHADOW_JSON_ERROR; 00109 } 00110 remSizeOfJsonBuffer = tempSize; 00111 pTemporary = va_arg (pArgs, jsonStruct_t *); 00112 if (pTemporary != NULL) { 00113 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"%s\":", 00114 pTemporary->pKey); 00115 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); 00116 if (ret_val != NONE_ERROR) { 00117 return ret_val; 00118 } 00119 if (pTemporary->pKey != NULL && pTemporary->pData != NULL) { 00120 ret_val = convertDataToString(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, 00121 pTemporary->type, pTemporary->pData); 00122 } else { 00123 return NULL_VALUE_ERROR; 00124 } 00125 if (ret_val != NONE_ERROR) { 00126 return ret_val; 00127 } 00128 } else { 00129 return NULL_VALUE_ERROR; 00130 } 00131 } 00132 00133 va_end(pArgs); 00134 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "},"); 00135 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); 00136 return ret_val; 00137 } 00138 00139 IoT_Error_t aws_iot_shadow_add_reported(char *pJsonDocument, size_t maxSizeOfJsonDocument, uint8_t count, ...) { 00140 IoT_Error_t ret_val = NONE_ERROR; 00141 00142 int8_t i; 00143 size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument; 00144 int32_t snPrintfReturn = 0; 00145 int32_t tempSize = 0; 00146 va_list pArgs; 00147 va_start(pArgs, count); 00148 jsonStruct_t *pTemporary; 00149 00150 if (pJsonDocument == NULL) { 00151 return NULL_VALUE_ERROR; 00152 } 00153 00154 00155 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); 00156 if(tempSize <= 1){ 00157 return SHADOW_JSON_ERROR; 00158 } 00159 remSizeOfJsonBuffer = tempSize; 00160 00161 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"reported\":{"); 00162 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); 00163 00164 if (ret_val != NONE_ERROR) { 00165 return ret_val; 00166 } 00167 00168 for (i = 0; i < count; i++) { 00169 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); 00170 if(tempSize <= 1){ 00171 return SHADOW_JSON_ERROR; 00172 } 00173 remSizeOfJsonBuffer = tempSize; 00174 00175 pTemporary = va_arg (pArgs, jsonStruct_t *); 00176 if (pTemporary != NULL) { 00177 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"%s\":", 00178 pTemporary->pKey); 00179 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); 00180 if (ret_val != NONE_ERROR) { 00181 return ret_val; 00182 } 00183 if (pTemporary->pKey != NULL && pTemporary->pData != NULL) { 00184 ret_val = convertDataToString(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, 00185 pTemporary->type, pTemporary->pData); 00186 } else { 00187 return NULL_VALUE_ERROR; 00188 } 00189 if (ret_val != NONE_ERROR) { 00190 return ret_val; 00191 } 00192 } else { 00193 return NULL_VALUE_ERROR; 00194 } 00195 } 00196 00197 va_end(pArgs); 00198 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "},"); 00199 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); 00200 return ret_val; 00201 } 00202 00203 00204 int32_t FillWithClientTokenSize(char *pBufferToBeUpdatedWithClientToken, size_t maxSizeOfJsonDocument) { 00205 int32_t snPrintfReturn; 00206 snPrintfReturn = snprintf(pBufferToBeUpdatedWithClientToken, maxSizeOfJsonDocument, "%s-%d", mqttClientID, 00207 clientTokenNum++); 00208 00209 return snPrintfReturn; 00210 } 00211 00212 IoT_Error_t aws_iot_fill_with_client_token(char *pBufferToBeUpdatedWithClientToken, size_t maxSizeOfJsonDocument){ 00213 00214 int32_t snPrintfRet = 0; 00215 snPrintfRet = FillWithClientTokenSize(pBufferToBeUpdatedWithClientToken, maxSizeOfJsonDocument); 00216 return checkReturnValueOfSnPrintf(snPrintfRet, maxSizeOfJsonDocument); 00217 00218 } 00219 00220 IoT_Error_t aws_iot_finalize_json_document(char *pJsonDocument, size_t maxSizeOfJsonDocument) { 00221 size_t remSizeOfJsonBuffer = maxSizeOfJsonDocument; 00222 int32_t snPrintfReturn = 0; 00223 int32_t tempSize = 0; 00224 IoT_Error_t ret_val = NONE_ERROR; 00225 00226 if (pJsonDocument == NULL) { 00227 return NULL_VALUE_ERROR; 00228 } 00229 00230 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); 00231 if(tempSize <= 1){ 00232 return SHADOW_JSON_ERROR; 00233 } 00234 remSizeOfJsonBuffer = tempSize; 00235 00236 // strlen(ShadowTxBuffer) - 1 is to ensure we remove the last ,(comma) that was added 00237 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument) - 1, remSizeOfJsonBuffer, "}, \"%s\":\"", 00238 SHADOW_CLIENT_TOKEN_STRING); 00239 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); 00240 00241 if (ret_val != NONE_ERROR) { 00242 return ret_val; 00243 } 00244 // refactor this XXX repeated code 00245 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); 00246 if(tempSize <= 1){ 00247 return SHADOW_JSON_ERROR; 00248 } 00249 remSizeOfJsonBuffer = tempSize; 00250 00251 00252 snPrintfReturn = FillWithClientTokenSize(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer); 00253 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); 00254 00255 if (ret_val != NONE_ERROR) { 00256 return ret_val; 00257 } 00258 tempSize = maxSizeOfJsonDocument - strlen(pJsonDocument); 00259 if(tempSize <= 1){ 00260 return SHADOW_JSON_ERROR; 00261 } 00262 remSizeOfJsonBuffer = tempSize; 00263 00264 00265 snPrintfReturn = snprintf(pJsonDocument + strlen(pJsonDocument), remSizeOfJsonBuffer, "\"}"); 00266 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, remSizeOfJsonBuffer); 00267 00268 return ret_val; 00269 } 00270 00271 void FillWithClientToken(char *pBufferToBeUpdatedWithClientToken) { 00272 sprintf(pBufferToBeUpdatedWithClientToken, "%s-%d", mqttClientID, clientTokenNum++); 00273 } 00274 00275 static IoT_Error_t convertDataToString(char *pStringBuffer, size_t maxSizoStringBuffer, JsonPrimitiveType type, 00276 void *pData) { 00277 int32_t snPrintfReturn = 0; 00278 IoT_Error_t ret_val = NONE_ERROR; 00279 00280 if (maxSizoStringBuffer == 0) { 00281 return SHADOW_JSON_ERROR; 00282 } 00283 00284 if (type == SHADOW_JSON_INT32) { 00285 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIi32",", *(int32_t * )(pData)); 00286 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%li,", *(int32_t * )(pData)); 00287 } else if (type == SHADOW_JSON_INT16) { 00288 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIi16",", *(int16_t * )(pData)); 00289 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%i,", *(int16_t * )(pData)); 00290 } else if (type == SHADOW_JSON_INT8) { 00291 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIi8",", *(int8_t * )(pData)); 00292 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%i,", *(int8_t * )(pData)); 00293 } else if (type == SHADOW_JSON_UINT32) { 00294 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIu32",", *(uint32_t * )(pData)); 00295 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%lu,", *(uint32_t * )(pData)); 00296 } else if (type == SHADOW_JSON_UINT16) { 00297 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIu16",", *(uint16_t * )(pData)); 00298 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%u,", *(uint16_t * )(pData)); 00299 } else if (type == SHADOW_JSON_UINT8) { 00300 //snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%"PRIu8",", *(uint8_t * )(pData)); 00301 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%u,", *(uint8_t * )(pData)); 00302 } else if (type == SHADOW_JSON_DOUBLE) { 00303 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%f,", *(double * )(pData)); 00304 } else if (type == SHADOW_JSON_FLOAT) { 00305 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%f,", *(float * )(pData)); 00306 } else if (type == SHADOW_JSON_BOOL) { 00307 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "%s,", *(bool *)(pData)?"true":"false"); 00308 } else if (type == SHADOW_JSON_STRING) { 00309 snPrintfReturn = snprintf(pStringBuffer, maxSizoStringBuffer, "\"%s\",", (char * )(pData)); 00310 } 00311 00312 ret_val = checkReturnValueOfSnPrintf(snPrintfReturn, maxSizoStringBuffer); 00313 00314 return ret_val; 00315 } 00316 static jsmn_parser shadowJsonParser; 00317 static jsmntok_t jsonTokenStruct[MAX_JSON_TOKEN_EXPECTED]; 00318 00319 bool isJsonValidAndParse(const char *pJsonDocument, void *pJsonHandler, int32_t *pTokenCount) { 00320 int32_t tokenCount; 00321 00322 jsmn_init(&shadowJsonParser); 00323 00324 tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct, 00325 sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0])); 00326 00327 if (tokenCount < 0) { 00328 WARN("Failed to parse JSON: %d\n", tokenCount); 00329 return false; 00330 } 00331 00332 /* Assume the top-level element is an object */ 00333 if (tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) { 00334 WARN("Top Level is not an object\n"); 00335 return false; 00336 } 00337 00338 pJsonHandler = (void *) jsonTokenStruct; 00339 *pTokenCount = tokenCount; 00340 00341 return true; 00342 } 00343 00344 static IoT_Error_t UpdateValueIfNoObject(const char *pJsonString, jsonStruct_t *pDataStruct, jsmntok_t token) { 00345 IoT_Error_t ret_val = NONE_ERROR; 00346 if (pDataStruct->type == SHADOW_JSON_BOOL) { 00347 ret_val = parseBooleanValue((bool *)pDataStruct->pData, pJsonString, &token); 00348 } else if (pDataStruct->type == SHADOW_JSON_INT32) { 00349 ret_val = parseInteger32Value((int32_t *)pDataStruct->pData, pJsonString, &token); 00350 } else if (pDataStruct->type == SHADOW_JSON_INT16) { 00351 ret_val = parseInteger16Value((int16_t *)pDataStruct->pData, pJsonString, &token); 00352 } else if (pDataStruct->type == SHADOW_JSON_INT8) { 00353 ret_val = parseInteger8Value((int8_t *)pDataStruct->pData, pJsonString, &token); 00354 } else if (pDataStruct->type == SHADOW_JSON_UINT32) { 00355 ret_val = parseUnsignedInteger32Value((uint32_t *)pDataStruct->pData, pJsonString, &token); 00356 } else if (pDataStruct->type == SHADOW_JSON_UINT16) { 00357 ret_val = parseUnsignedInteger16Value((uint16_t *)pDataStruct->pData, pJsonString, &token); 00358 } else if (pDataStruct->type == SHADOW_JSON_UINT8) { 00359 ret_val = parseUnsignedInteger8Value((uint8_t *)pDataStruct->pData, pJsonString, &token); 00360 } else if (pDataStruct->type == SHADOW_JSON_FLOAT) { 00361 ret_val = parseFloatValue((float *)pDataStruct->pData, pJsonString, &token); 00362 } else if (pDataStruct->type == SHADOW_JSON_DOUBLE) { 00363 ret_val = parseDoubleValue((double *)pDataStruct->pData, pJsonString, &token); 00364 } 00365 00366 return ret_val; 00367 } 00368 00369 bool isJsonKeyMatchingAndUpdateValue(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount, 00370 jsonStruct_t *pDataStruct, uint32_t *pDataLength, int32_t *pDataPosition) { 00371 int32_t i; 00372 00373 jsmntok_t *pJsonTokenStruct; 00374 00375 pJsonTokenStruct = (jsmntok_t *) pJsonHandler; 00376 for (i = 1; i < tokenCount; i++) { 00377 if (jsoneq(pJsonDocument, &(jsonTokenStruct[i]), pDataStruct->pKey) == 0) { 00378 jsmntok_t dataToken = jsonTokenStruct[i + 1]; 00379 uint32_t dataLength = dataToken.end - dataToken.start; 00380 UpdateValueIfNoObject(pJsonDocument, pDataStruct, dataToken); 00381 *pDataPosition = dataToken.start; 00382 *pDataLength = dataLength; 00383 return true; 00384 } 00385 } 00386 return false; 00387 } 00388 00389 bool isReceivedJsonValid(const char *pJsonDocument) { 00390 int32_t tokenCount; 00391 00392 jsmn_init(&shadowJsonParser); 00393 00394 tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct, 00395 sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0])); 00396 00397 if (tokenCount < 0) { 00398 WARN("Failed to parse JSON: %d\n", tokenCount); 00399 return false; 00400 } 00401 00402 /* Assume the top-level element is an object */ 00403 if (tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) { 00404 return false; 00405 } 00406 00407 return true; 00408 } 00409 00410 bool extractClientToken(const char *pJsonDocument, char *pExtractedClientToken) { 00411 bool ret_val = false; 00412 jsmn_init(&shadowJsonParser); 00413 int32_t tokenCount, i; 00414 jsmntok_t ClientJsonToken; 00415 00416 tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct, 00417 sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0])); 00418 00419 if (tokenCount < 0) { 00420 WARN("Failed to parse JSON: %d\n", tokenCount); 00421 return false; 00422 } 00423 00424 /* Assume the top-level element is an object */ 00425 if (tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) { 00426 return false; 00427 } 00428 00429 for (i = 1; i < tokenCount; i++) { 00430 if (jsoneq(pJsonDocument, &jsonTokenStruct[i], SHADOW_CLIENT_TOKEN_STRING) == 0) { 00431 ClientJsonToken = jsonTokenStruct[i + 1]; 00432 uint8_t length = ClientJsonToken.end - ClientJsonToken.start; 00433 strncpy(pExtractedClientToken, pJsonDocument + ClientJsonToken.start, length); 00434 pExtractedClientToken[length] = '\0'; 00435 return true; 00436 } 00437 } 00438 00439 return false; 00440 } 00441 00442 bool extractVersionNumber(const char *pJsonDocument, void *pJsonHandler, int32_t tokenCount, uint32_t *pVersionNumber) { 00443 int32_t i; 00444 jsmntok_t *pJsonTokenStruct; 00445 IoT_Error_t ret_val = NONE_ERROR; 00446 00447 pJsonTokenStruct = (jsmntok_t *) pJsonHandler; 00448 for (i = 1; i < tokenCount; i++) { 00449 if (jsoneq(pJsonDocument, &(jsonTokenStruct[i]), SHADOW_VERSION_STRING) == 0) { 00450 jsmntok_t dataToken = jsonTokenStruct[i + 1]; 00451 uint32_t dataLength = dataToken.end - dataToken.start; 00452 ret_val = parseUnsignedInteger32Value(pVersionNumber, pJsonDocument, &dataToken); 00453 if (ret_val == NONE_ERROR) { 00454 return true; 00455 } 00456 } 00457 } 00458 return false; 00459 } 00460 00461
Generated on Tue Jul 12 2022 14:16:19 by 1.7.2