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@36:7d12a5386197, 2018-09-11 (annotated)
- Committer:
- AzureIoTClient
- Date:
- Tue Sep 11 11:14:37 2018 -0700
- Revision:
- 36:7d12a5386197
- Parent:
- 21:6d3dea1abd9c
1.2.9
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> |
Azure.IoT Build | 10:c2aee3965a83 | 5 | #include "azure_c_shared_utility/gballoc.h" |
AzureIoTClient | 0:1f9b2707ec7d | 6 | |
AzureIoTClient | 0:1f9b2707ec7d | 7 | #include <stddef.h> |
AzureIoTClient | 0:1f9b2707ec7d | 8 | #include "schemaserializer.h" |
Azure.IoT Build | 13:16e88f0cfa5f | 9 | #include "azure_c_shared_utility/xlogging.h" |
Azure.IoT Build | 10:c2aee3965a83 | 10 | #include "azure_c_shared_utility/macro_utils.h" |
AzureIoTClient | 0:1f9b2707ec7d | 11 | |
AzureIoTClient | 0:1f9b2707ec7d | 12 | DEFINE_ENUM_STRINGS(SCHEMA_SERIALIZER_RESULT, SCHEMA_SERIALIZER_RESULT_VALUES); |
AzureIoTClient | 0:1f9b2707ec7d | 13 | |
AzureIoTClient | 11:b1327861f5e0 | 14 | #define LOG_SCHEMA_SERIALIZER_ERROR(result) LogError("(result = %s)", ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, (result))) |
AzureIoTClient | 0:1f9b2707ec7d | 15 | |
AzureIoTClient | 0:1f9b2707ec7d | 16 | static const char* ConvertType(const char* sourceType) |
AzureIoTClient | 0:1f9b2707ec7d | 17 | { |
AzureIoTClient | 0:1f9b2707ec7d | 18 | /* Codes_SRS_SCHEMA_SERIALIZER_01_016: ["ascii_char_ptr" shall be translated to "string".] */ |
AzureIoTClient | 0:1f9b2707ec7d | 19 | if (strcmp(sourceType, "ascii_char_ptr") == 0) |
AzureIoTClient | 0:1f9b2707ec7d | 20 | { |
AzureIoTClient | 0:1f9b2707ec7d | 21 | return "string"; |
AzureIoTClient | 0:1f9b2707ec7d | 22 | } |
AzureIoTClient | 0:1f9b2707ec7d | 23 | else |
AzureIoTClient | 0:1f9b2707ec7d | 24 | { |
AzureIoTClient | 0:1f9b2707ec7d | 25 | /* Codes_SRS_SCHEMA_SERIALIZER_01_017: [All other types shall be kept as they are.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 26 | return sourceType; |
AzureIoTClient | 0:1f9b2707ec7d | 27 | } |
AzureIoTClient | 0:1f9b2707ec7d | 28 | } |
AzureIoTClient | 0:1f9b2707ec7d | 29 | |
AzureIoTClient | 0:1f9b2707ec7d | 30 | /* Codes_SRS_SCHEMA_SERIALIZER_01_001: [SchemaSerializer_SerializeCommandMetadata shall serialize a specific model to a string using JSON as format.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 31 | SCHEMA_SERIALIZER_RESULT SchemaSerializer_SerializeCommandMetadata(SCHEMA_MODEL_TYPE_HANDLE modelHandle, STRING_HANDLE schemaText) |
AzureIoTClient | 0:1f9b2707ec7d | 32 | { |
AzureIoTClient | 0:1f9b2707ec7d | 33 | SCHEMA_SERIALIZER_RESULT result; |
AzureIoTClient | 0:1f9b2707ec7d | 34 | |
AzureIoTClient | 0:1f9b2707ec7d | 35 | /* Codes_SRS_SCHEMA_SERIALIZER_01_013: [If the modelHandle argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 36 | if ((modelHandle == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 37 | /* Codes_SRS_SCHEMA_SERIALIZER_01_014: [If the schemaText argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 38 | (schemaText == NULL)) |
AzureIoTClient | 0:1f9b2707ec7d | 39 | { |
AzureIoTClient | 0:1f9b2707ec7d | 40 | result = SCHEMA_SERIALIZER_INVALID_ARG; |
AzureIoTClient | 11:b1327861f5e0 | 41 | LogError("(result = %s), modelHandle = %p, schemaText = %p", ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, result), modelHandle, schemaText); |
AzureIoTClient | 0:1f9b2707ec7d | 42 | } |
AzureIoTClient | 0:1f9b2707ec7d | 43 | else |
AzureIoTClient | 0:1f9b2707ec7d | 44 | { |
AzureIoTClient | 0:1f9b2707ec7d | 45 | size_t commandCount; |
AzureIoTClient | 0:1f9b2707ec7d | 46 | |
AzureIoTClient | 0:1f9b2707ec7d | 47 | /* Codes_SRS_SCHEMA_SERIALIZER_01_002: [Only commands shall be serialized, the properties of a model shall be ignored.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 48 | |
AzureIoTClient | 0:1f9b2707ec7d | 49 | /* Codes_SRS_SCHEMA_SERIALIZER_01_003: [The output JSON shall have an array, where each array element shall represent a command.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 50 | /* 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 | 51 | if ((STRING_concat(schemaText, "[") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 52 | /* 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 | 53 | (Schema_GetModelActionCount(modelHandle, &commandCount) != SCHEMA_OK)) |
AzureIoTClient | 0:1f9b2707ec7d | 54 | { |
AzureIoTClient | 0:1f9b2707ec7d | 55 | /* 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 | 56 | result = SCHEMA_SERIALIZER_ERROR; |
AzureIoTClient | 0:1f9b2707ec7d | 57 | LOG_SCHEMA_SERIALIZER_ERROR(result); |
AzureIoTClient | 0:1f9b2707ec7d | 58 | } |
AzureIoTClient | 0:1f9b2707ec7d | 59 | else |
AzureIoTClient | 0:1f9b2707ec7d | 60 | { |
AzureIoTClient | 0:1f9b2707ec7d | 61 | size_t i; |
AzureIoTClient | 0:1f9b2707ec7d | 62 | |
AzureIoTClient | 0:1f9b2707ec7d | 63 | for (i = 0; i < commandCount; i++) |
AzureIoTClient | 0:1f9b2707ec7d | 64 | { |
AzureIoTClient | 0:1f9b2707ec7d | 65 | SCHEMA_ACTION_HANDLE actionHandle = Schema_GetModelActionByIndex(modelHandle, i); |
AzureIoTClient | 0:1f9b2707ec7d | 66 | const char* commandName; |
AzureIoTClient | 0:1f9b2707ec7d | 67 | size_t argCount; |
AzureIoTClient | 0:1f9b2707ec7d | 68 | size_t j; |
AzureIoTClient | 0:1f9b2707ec7d | 69 | |
AzureIoTClient | 0:1f9b2707ec7d | 70 | /* Codes_SRS_SCHEMA_SERIALIZER_01_005: [Each array element shall be a JSON object.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 71 | if ((actionHandle == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 72 | (STRING_concat(schemaText, "{ \"Name\":\"") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 73 | ((commandName = Schema_GetModelActionName(actionHandle)) == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 74 | (STRING_concat(schemaText, commandName) != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 75 | /* Codes_SRS_SCHEMA_SERIALIZER_01_007: [The object for a command shall also have a "Parameters" member.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 76 | (STRING_concat(schemaText, "\", \"Parameters\":[") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 77 | (Schema_GetModelActionArgumentCount(actionHandle, &argCount) != SCHEMA_OK)) |
AzureIoTClient | 0:1f9b2707ec7d | 78 | { |
AzureIoTClient | 0:1f9b2707ec7d | 79 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 11:b1327861f5e0 | 80 | LogError("Failed encoding action."); |
AzureIoTClient | 0:1f9b2707ec7d | 81 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 82 | } |
AzureIoTClient | 0:1f9b2707ec7d | 83 | else |
AzureIoTClient | 0:1f9b2707ec7d | 84 | { |
AzureIoTClient | 0:1f9b2707ec7d | 85 | for (j = 0; j < argCount; j++) |
AzureIoTClient | 0:1f9b2707ec7d | 86 | { |
AzureIoTClient | 0:1f9b2707ec7d | 87 | /* Codes_SRS_SCHEMA_SERIALIZER_01_008: [The parameters member shall be an array, where each entry is a command parameter.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 88 | SCHEMA_ACTION_ARGUMENT_HANDLE argHandle = Schema_GetModelActionArgumentByIndex(actionHandle, j); |
AzureIoTClient | 0:1f9b2707ec7d | 89 | const char* argName; |
AzureIoTClient | 0:1f9b2707ec7d | 90 | const char* argType; |
AzureIoTClient | 0:1f9b2707ec7d | 91 | |
AzureIoTClient | 0:1f9b2707ec7d | 92 | /* 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 | 93 | if ((argHandle == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 94 | (STRING_concat(schemaText, "{\"Name\":\"") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 95 | ((argName = Schema_GetActionArgumentName(argHandle)) == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 96 | (STRING_concat(schemaText, argName) != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 97 | /* 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 | 98 | (STRING_concat(schemaText, "\",\"Type\":\"") != 0) || |
AzureIoTClient | 0:1f9b2707ec7d | 99 | ((argType = Schema_GetActionArgumentType(argHandle)) == NULL) || |
AzureIoTClient | 0:1f9b2707ec7d | 100 | (STRING_concat(schemaText, ConvertType(argType)) != 0)) |
AzureIoTClient | 0:1f9b2707ec7d | 101 | { |
AzureIoTClient | 0:1f9b2707ec7d | 102 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 11:b1327861f5e0 | 103 | LogError("Failed encoding argument."); |
AzureIoTClient | 0:1f9b2707ec7d | 104 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 105 | } |
AzureIoTClient | 0:1f9b2707ec7d | 106 | else |
AzureIoTClient | 0:1f9b2707ec7d | 107 | { |
AzureIoTClient | 0:1f9b2707ec7d | 108 | if (j + 1 < argCount) |
AzureIoTClient | 0:1f9b2707ec7d | 109 | { |
AzureIoTClient | 0:1f9b2707ec7d | 110 | if (STRING_concat(schemaText, "\"},") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 111 | { |
AzureIoTClient | 0:1f9b2707ec7d | 112 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 11:b1327861f5e0 | 113 | LogError("Failed to concatenate arg end."); |
AzureIoTClient | 0:1f9b2707ec7d | 114 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 115 | } |
AzureIoTClient | 0:1f9b2707ec7d | 116 | } |
AzureIoTClient | 0:1f9b2707ec7d | 117 | else |
AzureIoTClient | 0:1f9b2707ec7d | 118 | { |
AzureIoTClient | 0:1f9b2707ec7d | 119 | if (STRING_concat(schemaText, "\"}") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 120 | { |
AzureIoTClient | 0:1f9b2707ec7d | 121 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 11:b1327861f5e0 | 122 | LogError("Failed to concatenate arg end."); |
AzureIoTClient | 0:1f9b2707ec7d | 123 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 124 | } |
AzureIoTClient | 0:1f9b2707ec7d | 125 | } |
AzureIoTClient | 0:1f9b2707ec7d | 126 | } |
AzureIoTClient | 0:1f9b2707ec7d | 127 | } |
AzureIoTClient | 0:1f9b2707ec7d | 128 | |
AzureIoTClient | 0:1f9b2707ec7d | 129 | if (j < argCount) |
AzureIoTClient | 0:1f9b2707ec7d | 130 | { |
AzureIoTClient | 0:1f9b2707ec7d | 131 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 132 | } |
AzureIoTClient | 0:1f9b2707ec7d | 133 | |
AzureIoTClient | 0:1f9b2707ec7d | 134 | if (i + 1 < commandCount) |
AzureIoTClient | 0:1f9b2707ec7d | 135 | { |
AzureIoTClient | 0:1f9b2707ec7d | 136 | if (STRING_concat(schemaText, "]},") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 137 | { |
AzureIoTClient | 0:1f9b2707ec7d | 138 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 11:b1327861f5e0 | 139 | LogError("Failed to concatenate."); |
AzureIoTClient | 0:1f9b2707ec7d | 140 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 141 | } |
AzureIoTClient | 0:1f9b2707ec7d | 142 | } |
AzureIoTClient | 0:1f9b2707ec7d | 143 | else |
AzureIoTClient | 0:1f9b2707ec7d | 144 | { |
AzureIoTClient | 0:1f9b2707ec7d | 145 | if (STRING_concat(schemaText, "]}") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 146 | { |
AzureIoTClient | 0:1f9b2707ec7d | 147 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 11:b1327861f5e0 | 148 | LogError("Failed to concatenate."); |
AzureIoTClient | 0:1f9b2707ec7d | 149 | break; |
AzureIoTClient | 0:1f9b2707ec7d | 150 | } |
AzureIoTClient | 0:1f9b2707ec7d | 151 | } |
AzureIoTClient | 0:1f9b2707ec7d | 152 | } |
AzureIoTClient | 0:1f9b2707ec7d | 153 | } |
AzureIoTClient | 0:1f9b2707ec7d | 154 | |
AzureIoTClient | 0:1f9b2707ec7d | 155 | if (i < commandCount) |
AzureIoTClient | 0:1f9b2707ec7d | 156 | { |
AzureIoTClient | 0:1f9b2707ec7d | 157 | result = SCHEMA_SERIALIZER_ERROR; |
AzureIoTClient | 0:1f9b2707ec7d | 158 | } |
AzureIoTClient | 0:1f9b2707ec7d | 159 | else if (STRING_concat(schemaText, "]") != 0) |
AzureIoTClient | 0:1f9b2707ec7d | 160 | { |
AzureIoTClient | 0:1f9b2707ec7d | 161 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */ |
AzureIoTClient | 11:b1327861f5e0 | 162 | LogError("Failed to concatenate commands object end."); |
AzureIoTClient | 0:1f9b2707ec7d | 163 | result = SCHEMA_SERIALIZER_ERROR; |
AzureIoTClient | 0:1f9b2707ec7d | 164 | } |
AzureIoTClient | 0:1f9b2707ec7d | 165 | else |
AzureIoTClient | 0:1f9b2707ec7d | 166 | { |
AzureIoTClient | 0:1f9b2707ec7d | 167 | /* Codes_SRS_SCHEMA_SERIALIZER_01_012: [On success SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_OK.] */ |
AzureIoTClient | 0:1f9b2707ec7d | 168 | result = SCHEMA_SERIALIZER_OK; |
AzureIoTClient | 0:1f9b2707ec7d | 169 | } |
AzureIoTClient | 0:1f9b2707ec7d | 170 | } |
AzureIoTClient | 0:1f9b2707ec7d | 171 | } |
AzureIoTClient | 0:1f9b2707ec7d | 172 | |
AzureIoTClient | 0:1f9b2707ec7d | 173 | return result; |
AzureIoTClient | 0:1f9b2707ec7d | 174 | } |