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

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?

UserRevisionLine numberNew 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 }