A modelling and serializer library for Microsoft Azure IoTHub client applications
Dependents: sht15_remote_monitoring f767zi_mqtt remote_monitoring simplesample_amqp ... more
This library implements a serializer library to be used in projects involving Microsoft Azure IoT Hub connectivity. The code is replicated from https://github.com/Azure/azure-iot-sdks
schemaserializer.c@10:c2aee3965a83, 2016-04-08 (annotated)
- Committer:
- Azure.IoT Build
- Date:
- Fri Apr 08 13:25:09 2016 -0700
- Revision:
- 10:c2aee3965a83
- Parent:
- 0:1f9b2707ec7d
- Child:
- 11:b1327861f5e0
1.0.4
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AzureIoTClient | 0:1f9b2707ec7d | 1 | // Copyright (c) Microsoft. All rights reserved. |
AzureIoTClient | 0:1f9b2707ec7d | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
AzureIoTClient | 0:1f9b2707ec7d | 3 | |
AzureIoTClient | 0:1f9b2707ec7d | 4 | #include <stdlib.h> |
AzureIoTClient | 0:1f9b2707ec7d | 5 | #ifdef _CRTDBG_MAP_ALLOC |
AzureIoTClient | 0:1f9b2707ec7d | 6 | #include <crtdbg.h> |
AzureIoTClient | 0:1f9b2707ec7d | 7 | #endif |
Azure.IoT Build | 10:c2aee3965a83 | 8 | #include "azure_c_shared_utility/gballoc.h" |
AzureIoTClient | 0:1f9b2707ec7d | 9 | |
AzureIoTClient | 0:1f9b2707ec7d | 10 | #include <stddef.h> |
AzureIoTClient | 0:1f9b2707ec7d | 11 | #include "schemaserializer.h" |
Azure.IoT Build | 10:c2aee3965a83 | 12 | #include "azure_c_shared_utility/iot_logging.h" |
Azure.IoT Build | 10:c2aee3965a83 | 13 | #include "azure_c_shared_utility/macro_utils.h" |
AzureIoTClient | 0:1f9b2707ec7d | 14 | |
AzureIoTClient | 0:1f9b2707ec7d | 15 | DEFINE_ENUM_STRINGS(SCHEMA_SERIALIZER_RESULT, SCHEMA_SERIALIZER_RESULT_VALUES); |
AzureIoTClient | 0:1f9b2707ec7d | 16 | |
AzureIoTClient | 0:1f9b2707ec7d | 17 | #define LOG_SCHEMA_SERIALIZER_ERROR(result) LogError("(result = %s)\r\n", ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, (result))) |
AzureIoTClient | 0:1f9b2707ec7d | 18 | |
AzureIoTClient | 0:1f9b2707ec7d | 19 | static const char* ConvertType(const char* sourceType) |
AzureIoTClient | 0:1f9b2707ec7d | 20 | { |
AzureIoTClient | 0:1f9b2707ec7d | 21 | /* Codes_SRS_SCHEMA_SERIALIZER_01_016: ["ascii_char_ptr" shall be translated to "string".] */ |
AzureIoTClient | 0:1f9b2707ec7d | 22 | if (strcmp(sourceType, "ascii_char_ptr") == 0) |
AzureIoTClient | 0:1f9b2707ec7d | 23 | { |
AzureIoTClient | 0:1f9b2707ec7d | 24 | return "string"; |
AzureIoTClient | 0:1f9b2707ec7d | 25 | } |
AzureIoTClient | 0:1f9b2707ec7d | 26 | else |
AzureIoTClient | 0:1f9b2707ec7d | 27 | { |
AzureIoTClient | 0:1f9b2707ec7d | 28 | /* Codes_SRS_SCHEMA_SERIALIZER_01_017: [All other types shall be kept as they are.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 29 | return sourceType; |
AzureIoTClient | 0:1f9b2707ec7d | 30 | } |
AzureIoTClient | 0:1f9b2707ec7d | 31 | } |
AzureIoTClient | 0:1f9b2707ec7d | 32 | |
AzureIoTClient | 0:1f9b2707ec7d | 33 | /* Codes_SRS_SCHEMA_SERIALIZER_01_001: [SchemaSerializer_SerializeCommandMetadata shall serialize a specific model to a string using JSON as format.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 34 | SCHEMA_SERIALIZER_RESULT SchemaSerializer_SerializeCommandMetadata(SCHEMA_MODEL_TYPE_HANDLE modelHandle, STRING_HANDLE schemaText) |
AzureIoTClient | 0:1f9b2707ec7d | 35 | { |
AzureIoTClient | 0:1f9b2707ec7d | 36 | SCHEMA_SERIALIZER_RESULT result; |
AzureIoTClient | 0:1f9b2707ec7d | 37 | |
AzureIoTClient | 0:1f9b2707ec7d | 38 | /* Codes_SRS_SCHEMA_SERIALIZER_01_013: [If the modelHandle argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 39 | if ((modelHandle == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 40 | /* Codes_SRS_SCHEMA_SERIALIZER_01_014: [If the schemaText argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 41 | (schemaText == NULL)) |
AzureIoTClient | 0:1f9b2707ec7d | 42 | { |
AzureIoTClient | 0:1f9b2707ec7d | 43 | result = SCHEMA_SERIALIZER_INVALID_ARG; |
AzureIoTClient | 0:1f9b2707ec7d | 44 | LogError("(result = %s), modelHandle = %p, schemaText = %p\r\n", ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, result), modelHandle, schemaText); |
AzureIoTClient | 0:1f9b2707ec7d | 45 | } |
AzureIoTClient | 0:1f9b2707ec7d | 46 | else |
AzureIoTClient | 0:1f9b2707ec7d | 47 | { |
AzureIoTClient | 0:1f9b2707ec7d | 48 | size_t commandCount; |
AzureIoTClient | 0:1f9b2707ec7d | 49 | |
AzureIoTClient | 0:1f9b2707ec7d | 50 | /* Codes_SRS_SCHEMA_SERIALIZER_01_002: [Only commands shall be serialized, the properties of a model shall be ignored.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 51 | |
AzureIoTClient | 0:1f9b2707ec7d | 52 | /* Codes_SRS_SCHEMA_SERIALIZER_01_003: [The output JSON shall have an array, where each array element shall represent a command.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 53 | /* Codes_SRS_SCHEMA_SERIALIZER_01_011: [The JSON text shall be built into the string indicated by the schemaText argument by using String APIs.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 54 | if ((STRING_concat(schemaText, "[") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 55 | /* Codes_SRS_SCHEMA_SERIALIZER_01_006: [The object for a command shall have a member named Name, whose value shall be the command name as obtained by using Schema APIs.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 56 | (Schema_GetModelActionCount(modelHandle, &commandCount) != SCHEMA_OK)) |
AzureIoTClient | 0:1f9b2707ec7d | 57 | { |
AzureIoTClient | 0:1f9b2707ec7d | 58 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 59 | result = SCHEMA_SERIALIZER_ERROR; |
AzureIoTClient | 0:1f9b2707ec7d | 60 | LOG_SCHEMA_SERIALIZER_ERROR(result); |
AzureIoTClient | 0:1f9b2707ec7d | 61 | } |
AzureIoTClient | 0:1f9b2707ec7d | 62 | else |
AzureIoTClient | 0:1f9b2707ec7d | 63 | { |
AzureIoTClient | 0:1f9b2707ec7d | 64 | size_t i; |
AzureIoTClient | 0:1f9b2707ec7d | 65 | |
AzureIoTClient | 0:1f9b2707ec7d | 66 | for (i = 0; i < commandCount; i++) |
AzureIoTClient | 0:1f9b2707ec7d | 67 | { |
AzureIoTClient | 0:1f9b2707ec7d | 68 | SCHEMA_ACTION_HANDLE actionHandle = Schema_GetModelActionByIndex(modelHandle, i); |
AzureIoTClient | 0:1f9b2707ec7d | 69 | const char* commandName; |
AzureIoTClient | 0:1f9b2707ec7d | 70 | size_t argCount; |
AzureIoTClient | 0:1f9b2707ec7d | 71 | size_t j; |
AzureIoTClient | 0:1f9b2707ec7d | 72 | |
AzureIoTClient | 0:1f9b2707ec7d | 73 | /* Codes_SRS_SCHEMA_SERIALIZER_01_005: [Each array element shall be a JSON object.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 74 | if ((actionHandle == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 75 | (STRING_concat(schemaText, "{ \"Name\":\"") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 76 | ((commandName = Schema_GetModelActionName(actionHandle)) == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 77 | (STRING_concat(schemaText, commandName) != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 78 | /* Codes_SRS_SCHEMA_SERIALIZER_01_007: [The object for a command shall also have a "Parameters" member.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 79 | (STRING_concat(schemaText, "\", \"Parameters\":[") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 80 | (Schema_GetModelActionArgumentCount(actionHandle, &argCount) != SCHEMA_OK)) |
AzureIoTClient | 0:1f9b2707ec7d | 81 | { |
AzureIoTClient | 0:1f9b2707ec7d | 82 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 83 | LogError("Failed encoding action.\r\n"); |
AzureIoTClient | 0:1f9b2707ec7d | 84 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 85 | } |
AzureIoTClient | 0:1f9b2707ec7d | 86 | else |
AzureIoTClient | 0:1f9b2707ec7d | 87 | { |
AzureIoTClient | 0:1f9b2707ec7d | 88 | for (j = 0; j < argCount; j++) |
AzureIoTClient | 0:1f9b2707ec7d | 89 | { |
AzureIoTClient | 0:1f9b2707ec7d | 90 | /* Codes_SRS_SCHEMA_SERIALIZER_01_008: [The parameters member shall be an array, where each entry is a command parameter.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 91 | SCHEMA_ACTION_ARGUMENT_HANDLE argHandle = Schema_GetModelActionArgumentByIndex(actionHandle, j); |
AzureIoTClient | 0:1f9b2707ec7d | 92 | const char* argName; |
AzureIoTClient | 0:1f9b2707ec7d | 93 | const char* argType; |
AzureIoTClient | 0:1f9b2707ec7d | 94 | |
AzureIoTClient | 0:1f9b2707ec7d | 95 | /* Codes_SRS_SCHEMA_SERIALIZER_01_009: [Each command parameter shall have a member named "Name", that should have as value the command argument name as obtained by using Schema APIs.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 96 | if ((argHandle == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 97 | (STRING_concat(schemaText, "{\"Name\":\"") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 98 | ((argName = Schema_GetActionArgumentName(argHandle)) == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 99 | (STRING_concat(schemaText, argName) != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 100 | /* Codes_SRS_SCHEMA_SERIALIZER_01_010: [Each command parameter shall have a member named "Type", that should have as value the command argument type as obtained by using Schema APIs.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 101 | (STRING_concat(schemaText, "\",\"Type\":\"") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 102 | ((argType = Schema_GetActionArgumentType(argHandle)) == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 103 | (STRING_concat(schemaText, ConvertType(argType)) != 0)) |
AzureIoTClient | 0:1f9b2707ec7d | 104 | { |
AzureIoTClient | 0:1f9b2707ec7d | 105 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 106 | LogError("Failed encoding argument.\r\n"); |
AzureIoTClient | 0:1f9b2707ec7d | 107 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 108 | } |
AzureIoTClient | 0:1f9b2707ec7d | 109 | else |
AzureIoTClient | 0:1f9b2707ec7d | 110 | { |
AzureIoTClient | 0:1f9b2707ec7d | 111 | if (j + 1 < argCount) |
AzureIoTClient | 0:1f9b2707ec7d | 112 | { |
AzureIoTClient | 0:1f9b2707ec7d | 113 | if (STRING_concat(schemaText, "\"},") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 114 | { |
AzureIoTClient | 0:1f9b2707ec7d | 115 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 116 | LogError("Failed to concatenate arg end.\r\n"); |
AzureIoTClient | 0:1f9b2707ec7d | 117 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 118 | } |
AzureIoTClient | 0:1f9b2707ec7d | 119 | } |
AzureIoTClient | 0:1f9b2707ec7d | 120 | else |
AzureIoTClient | 0:1f9b2707ec7d | 121 | { |
AzureIoTClient | 0:1f9b2707ec7d | 122 | if (STRING_concat(schemaText, "\"}") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 123 | { |
AzureIoTClient | 0:1f9b2707ec7d | 124 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 125 | LogError("Failed to concatenate arg end.\r\n"); |
AzureIoTClient | 0:1f9b2707ec7d | 126 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 127 | } |
AzureIoTClient | 0:1f9b2707ec7d | 128 | } |
AzureIoTClient | 0:1f9b2707ec7d | 129 | } |
AzureIoTClient | 0:1f9b2707ec7d | 130 | } |
AzureIoTClient | 0:1f9b2707ec7d | 131 | |
AzureIoTClient | 0:1f9b2707ec7d | 132 | if (j < argCount) |
AzureIoTClient | 0:1f9b2707ec7d | 133 | { |
AzureIoTClient | 0:1f9b2707ec7d | 134 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 135 | } |
AzureIoTClient | 0:1f9b2707ec7d | 136 | |
AzureIoTClient | 0:1f9b2707ec7d | 137 | if (i + 1 < commandCount) |
AzureIoTClient | 0:1f9b2707ec7d | 138 | { |
AzureIoTClient | 0:1f9b2707ec7d | 139 | if (STRING_concat(schemaText, "]},") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 140 | { |
AzureIoTClient | 0:1f9b2707ec7d | 141 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 142 | LogError("Failed to concatenate.\r\n"); |
AzureIoTClient | 0:1f9b2707ec7d | 143 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 144 | } |
AzureIoTClient | 0:1f9b2707ec7d | 145 | } |
AzureIoTClient | 0:1f9b2707ec7d | 146 | else |
AzureIoTClient | 0:1f9b2707ec7d | 147 | { |
AzureIoTClient | 0:1f9b2707ec7d | 148 | if (STRING_concat(schemaText, "]}") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 149 | { |
AzureIoTClient | 0:1f9b2707ec7d | 150 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 151 | LogError("Failed to concatenate.\r\n"); |
AzureIoTClient | 0:1f9b2707ec7d | 152 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 153 | } |
AzureIoTClient | 0:1f9b2707ec7d | 154 | } |
AzureIoTClient | 0:1f9b2707ec7d | 155 | } |
AzureIoTClient | 0:1f9b2707ec7d | 156 | } |
AzureIoTClient | 0:1f9b2707ec7d | 157 | |
AzureIoTClient | 0:1f9b2707ec7d | 158 | if (i < commandCount) |
AzureIoTClient | 0:1f9b2707ec7d | 159 | { |
AzureIoTClient | 0:1f9b2707ec7d | 160 | result = SCHEMA_SERIALIZER_ERROR; |
AzureIoTClient | 0:1f9b2707ec7d | 161 | } |
AzureIoTClient | 0:1f9b2707ec7d | 162 | else if (STRING_concat(schemaText, "]") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 163 | { |
AzureIoTClient | 0:1f9b2707ec7d | 164 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 165 | LogError("Failed to concatenate commands object end.\r\n"); |
AzureIoTClient | 0:1f9b2707ec7d | 166 | result = SCHEMA_SERIALIZER_ERROR; |
AzureIoTClient | 0:1f9b2707ec7d | 167 | } |
AzureIoTClient | 0:1f9b2707ec7d | 168 | else |
AzureIoTClient | 0:1f9b2707ec7d | 169 | { |
AzureIoTClient | 0:1f9b2707ec7d | 170 | /* Codes_SRS_SCHEMA_SERIALIZER_01_012: [On success SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_OK.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 171 | result = SCHEMA_SERIALIZER_OK; |
AzureIoTClient | 0:1f9b2707ec7d | 172 | } |
AzureIoTClient | 0:1f9b2707ec7d | 173 | } |
AzureIoTClient | 0:1f9b2707ec7d | 174 | } |
AzureIoTClient | 0:1f9b2707ec7d | 175 | |
AzureIoTClient | 0:1f9b2707ec7d | 176 | return result; |
AzureIoTClient | 0:1f9b2707ec7d | 177 | } |