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