Jim Flynn / Mbed OS aws-iot-device-sdk-mbed-c
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers aws_iot_shadow_json.c Source File

aws_iot_shadow_json.c

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