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:
26:7c0e6f86d034
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>
AzureIoTClient 17:fa1bba4c6053 5 #include <stdarg.h>
Azure.IoT Build 10:c2aee3965a83 6 #include "azure_c_shared_utility/gballoc.h"
AzureIoTClient 0:1f9b2707ec7d 7
AzureIoTClient 0:1f9b2707ec7d 8 #include "codefirst.h"
Azure.IoT Build 10:c2aee3965a83 9 #include "azure_c_shared_utility/macro_utils.h"
Azure.IoT Build 10:c2aee3965a83 10 #include "azure_c_shared_utility/crt_abstractions.h"
Azure.IoT Build 13:16e88f0cfa5f 11 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 0:1f9b2707ec7d 12 #include <stddef.h>
Azure.IoT Build 10:c2aee3965a83 13 #include "azure_c_shared_utility/crt_abstractions.h"
AzureIoTClient 0:1f9b2707ec7d 14 #include "iotdevice.h"
AzureIoTClient 0:1f9b2707ec7d 15
AzureIoTClient 17:fa1bba4c6053 16 DEFINE_ENUM_STRINGS(CODEFIRST_RESULT, CODEFIRST_RESULT_VALUES)
AzureIoTClient 0:1f9b2707ec7d 17 DEFINE_ENUM_STRINGS(EXECUTE_COMMAND_RESULT, EXECUTE_COMMAND_RESULT_VALUES)
AzureIoTClient 0:1f9b2707ec7d 18
AzureIoTClient 0:1f9b2707ec7d 19 #define LOG_CODEFIRST_ERROR \
AzureIoTClient 11:b1327861f5e0 20 LogError("(result = %s)", ENUM_TO_STRING(CODEFIRST_RESULT, result))
AzureIoTClient 0:1f9b2707ec7d 21
AzureIoTClient 0:1f9b2707ec7d 22 typedef struct DEVICE_HEADER_DATA_TAG
AzureIoTClient 0:1f9b2707ec7d 23 {
AzureIoTClient 0:1f9b2707ec7d 24 DEVICE_HANDLE DeviceHandle;
AzureIoTClient 0:1f9b2707ec7d 25 const REFLECTED_DATA_FROM_DATAPROVIDER* ReflectedData;
AzureIoTClient 0:1f9b2707ec7d 26 SCHEMA_MODEL_TYPE_HANDLE ModelHandle;
AzureIoTClient 0:1f9b2707ec7d 27 size_t DataSize;
AzureIoTClient 0:1f9b2707ec7d 28 unsigned char* data;
AzureIoTClient 0:1f9b2707ec7d 29 } DEVICE_HEADER_DATA;
AzureIoTClient 0:1f9b2707ec7d 30
AzureIoTClient 0:1f9b2707ec7d 31 #define COUNT_OF(A) (sizeof(A) / sizeof((A)[0]))
AzureIoTClient 0:1f9b2707ec7d 32
AzureIoTClient 17:fa1bba4c6053 33 /*design considerations for lazy init of CodeFirst:
AzureIoTClient 17:fa1bba4c6053 34 There are 2 main states: either CodeFirst is in an initialized state, or it is not initialized.
AzureIoTClient 17:fa1bba4c6053 35 The initialized state means there's a g_OverrideSchemaNamespace set (even when it is set to NULL).
AzureIoTClient 17:fa1bba4c6053 36 The uninitialized state means g_OverrideSchemaNamespace is not set.
AzureIoTClient 17:fa1bba4c6053 37
AzureIoTClient 17:fa1bba4c6053 38 To switch to Init state, either call CodeFirst_Init (that sets g_OverrideSchemaNamespace to something)
AzureIoTClient 17:fa1bba4c6053 39 or call directly an API (that will set automatically g_OverrideSchemaNamespace to NULL).
AzureIoTClient 17:fa1bba4c6053 40
AzureIoTClient 17:fa1bba4c6053 41 To switch to NOT INIT state, depending on the method used to initialize:
AzureIoTClient 36:7d12a5386197 42 - if CodeFirst_Init was called, then only by a call to CodeFirst_Deinit the switch will take place
AzureIoTClient 17:fa1bba4c6053 43 (note how in this case g_OverrideSchemaNamespace survives destruction of all devices).
AzureIoTClient 36:7d12a5386197 44 - if the init has been done "lazily" by an API call then the module returns to uninitialized state
AzureIoTClient 17:fa1bba4c6053 45 when the number of devices reaches zero.
AzureIoTClient 17:fa1bba4c6053 46
AzureIoTClient 17:fa1bba4c6053 47 +-----------------------------+
AzureIoTClient 17:fa1bba4c6053 48 Start +---------------->| |
AzureIoTClient 17:fa1bba4c6053 49 | NOT INIT |
AzureIoTClient 17:fa1bba4c6053 50 +---------------->| |
AzureIoTClient 17:fa1bba4c6053 51 | +------------+----------------+
AzureIoTClient 17:fa1bba4c6053 52 | |
AzureIoTClient 17:fa1bba4c6053 53 | |
AzureIoTClient 17:fa1bba4c6053 54 | | _Init | APIs
AzureIoTClient 17:fa1bba4c6053 55 | |
AzureIoTClient 17:fa1bba4c6053 56 | v
AzureIoTClient 17:fa1bba4c6053 57 | +---------------------------------------------------+
AzureIoTClient 17:fa1bba4c6053 58 | | Init State |
AzureIoTClient 17:fa1bba4c6053 59 | | +-----------------+ +-----------------+ |
AzureIoTClient 17:fa1bba4c6053 60 | | | | | | |
AzureIoTClient 17:fa1bba4c6053 61 | | | init by _Init | | init by API | |
AzureIoTClient 17:fa1bba4c6053 62 | | +------+----------+ +---------+-------+ |
AzureIoTClient 17:fa1bba4c6053 63 | | | | |
AzureIoTClient 17:fa1bba4c6053 64 | | |_DeInit | nDevices==0 |
AzureIoTClient 17:fa1bba4c6053 65 | | | | |
AzureIoTClient 17:fa1bba4c6053 66 | +--------v----------------+-----------v-------------+
AzureIoTClient 17:fa1bba4c6053 67 | |
AzureIoTClient 17:fa1bba4c6053 68 +-------------------------------+
AzureIoTClient 17:fa1bba4c6053 69
AzureIoTClient 17:fa1bba4c6053 70 */
AzureIoTClient 17:fa1bba4c6053 71
AzureIoTClient 17:fa1bba4c6053 72
AzureIoTClient 17:fa1bba4c6053 73 #define CODEFIRST_STATE_VALUES \
AzureIoTClient 17:fa1bba4c6053 74 CODEFIRST_STATE_NOT_INIT, \
AzureIoTClient 17:fa1bba4c6053 75 CODEFIRST_STATE_INIT_BY_INIT, \
AzureIoTClient 36:7d12a5386197 76 CODEFIRST_STATE_INIT_BY_API
AzureIoTClient 17:fa1bba4c6053 77
AzureIoTClient 17:fa1bba4c6053 78 DEFINE_ENUM(CODEFIRST_STATE, CODEFIRST_STATE_VALUES)
AzureIoTClient 0:1f9b2707ec7d 79
AzureIoTClient 0:1f9b2707ec7d 80 static CODEFIRST_STATE g_state = CODEFIRST_STATE_NOT_INIT;
AzureIoTClient 0:1f9b2707ec7d 81 static const char* g_OverrideSchemaNamespace;
AzureIoTClient 0:1f9b2707ec7d 82 static size_t g_DeviceCount = 0;
AzureIoTClient 0:1f9b2707ec7d 83 static DEVICE_HEADER_DATA** g_Devices = NULL;
AzureIoTClient 0:1f9b2707ec7d 84
AzureIoTClient 17:fa1bba4c6053 85 static void deinitializeDesiredProperties(SCHEMA_MODEL_TYPE_HANDLE model, void* destination)
AzureIoTClient 17:fa1bba4c6053 86 {
AzureIoTClient 17:fa1bba4c6053 87 size_t nDesiredProperties;
AzureIoTClient 17:fa1bba4c6053 88 if (Schema_GetModelDesiredPropertyCount(model, &nDesiredProperties) != SCHEMA_OK)
AzureIoTClient 17:fa1bba4c6053 89 {
AzureIoTClient 17:fa1bba4c6053 90 LogError("unexpected error in Schema_GetModelDesiredPropertyCount");
AzureIoTClient 17:fa1bba4c6053 91 }
AzureIoTClient 17:fa1bba4c6053 92 else
AzureIoTClient 17:fa1bba4c6053 93 {
AzureIoTClient 17:fa1bba4c6053 94 size_t nProcessedDesiredProperties = 0;
AzureIoTClient 17:fa1bba4c6053 95 for (size_t i = 0;i < nDesiredProperties;i++)
AzureIoTClient 17:fa1bba4c6053 96 {
AzureIoTClient 17:fa1bba4c6053 97 SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle = Schema_GetModelDesiredPropertyByIndex(model, i);
AzureIoTClient 17:fa1bba4c6053 98 if (desiredPropertyHandle == NULL)
AzureIoTClient 17:fa1bba4c6053 99 {
AzureIoTClient 17:fa1bba4c6053 100 LogError("unexpected error in Schema_GetModelDesiredPropertyByIndex");
AzureIoTClient 17:fa1bba4c6053 101 i = nDesiredProperties;
AzureIoTClient 17:fa1bba4c6053 102 }
AzureIoTClient 17:fa1bba4c6053 103 else
AzureIoTClient 17:fa1bba4c6053 104 {
AzureIoTClient 17:fa1bba4c6053 105 pfDesiredPropertyDeinitialize desiredPropertyDeinitialize = Schema_GetModelDesiredProperty_pfDesiredPropertyDeinitialize(desiredPropertyHandle);
AzureIoTClient 17:fa1bba4c6053 106 if (desiredPropertyDeinitialize == NULL)
AzureIoTClient 17:fa1bba4c6053 107 {
AzureIoTClient 17:fa1bba4c6053 108 LogError("unexpected error in Schema_GetModelDesiredProperty_pfDesiredPropertyDeinitialize");
AzureIoTClient 17:fa1bba4c6053 109 i = nDesiredProperties;
AzureIoTClient 17:fa1bba4c6053 110 }
AzureIoTClient 17:fa1bba4c6053 111 else
AzureIoTClient 17:fa1bba4c6053 112 {
AzureIoTClient 17:fa1bba4c6053 113 size_t offset = Schema_GetModelDesiredProperty_offset(desiredPropertyHandle);
AzureIoTClient 17:fa1bba4c6053 114 desiredPropertyDeinitialize((char*)destination + offset);
AzureIoTClient 17:fa1bba4c6053 115 nProcessedDesiredProperties++;
AzureIoTClient 17:fa1bba4c6053 116 }
AzureIoTClient 17:fa1bba4c6053 117 }
AzureIoTClient 17:fa1bba4c6053 118 }
AzureIoTClient 17:fa1bba4c6053 119
AzureIoTClient 17:fa1bba4c6053 120 if (nDesiredProperties == nProcessedDesiredProperties)
AzureIoTClient 17:fa1bba4c6053 121 {
AzureIoTClient 17:fa1bba4c6053 122 /*recursively go in the model and initialize the other fields*/
AzureIoTClient 17:fa1bba4c6053 123 size_t nModelInModel;
AzureIoTClient 17:fa1bba4c6053 124 if (Schema_GetModelModelCount(model, &nModelInModel) != SCHEMA_OK)
AzureIoTClient 17:fa1bba4c6053 125 {
AzureIoTClient 17:fa1bba4c6053 126 LogError("unexpected error in Schema_GetModelModelCount");
AzureIoTClient 17:fa1bba4c6053 127 }
AzureIoTClient 17:fa1bba4c6053 128 else
AzureIoTClient 17:fa1bba4c6053 129 {
AzureIoTClient 17:fa1bba4c6053 130 size_t nProcessedModelInModel = 0;
AzureIoTClient 17:fa1bba4c6053 131 for (size_t i = 0; i < nModelInModel;i++)
AzureIoTClient 17:fa1bba4c6053 132 {
AzureIoTClient 17:fa1bba4c6053 133 SCHEMA_MODEL_TYPE_HANDLE modelInModel = Schema_GetModelModelyByIndex(model, i);
AzureIoTClient 17:fa1bba4c6053 134 if (modelInModel == NULL)
AzureIoTClient 17:fa1bba4c6053 135 {
AzureIoTClient 17:fa1bba4c6053 136 LogError("unexpected failure in Schema_GetModelModelyByIndex");
AzureIoTClient 17:fa1bba4c6053 137 i = nModelInModel;
AzureIoTClient 17:fa1bba4c6053 138 }
AzureIoTClient 17:fa1bba4c6053 139 else
AzureIoTClient 17:fa1bba4c6053 140 {
AzureIoTClient 17:fa1bba4c6053 141 size_t offset = Schema_GetModelModelByIndex_Offset(model, i);
AzureIoTClient 17:fa1bba4c6053 142 deinitializeDesiredProperties(modelInModel, (char*)destination + offset);
AzureIoTClient 17:fa1bba4c6053 143 nProcessedModelInModel++;
AzureIoTClient 17:fa1bba4c6053 144 }
AzureIoTClient 17:fa1bba4c6053 145 }
AzureIoTClient 17:fa1bba4c6053 146
AzureIoTClient 17:fa1bba4c6053 147 if (nProcessedModelInModel == nModelInModel)
AzureIoTClient 17:fa1bba4c6053 148 {
AzureIoTClient 17:fa1bba4c6053 149 /*all is fine... */
AzureIoTClient 17:fa1bba4c6053 150 }
AzureIoTClient 17:fa1bba4c6053 151 }
AzureIoTClient 17:fa1bba4c6053 152 }
AzureIoTClient 17:fa1bba4c6053 153 }
AzureIoTClient 17:fa1bba4c6053 154 }
AzureIoTClient 17:fa1bba4c6053 155
AzureIoTClient 0:1f9b2707ec7d 156 static void DestroyDevice(DEVICE_HEADER_DATA* deviceHeader)
AzureIoTClient 0:1f9b2707ec7d 157 {
AzureIoTClient 0:1f9b2707ec7d 158 /* Codes_SRS_CODEFIRST_99_085:[CodeFirst_DestroyDevice shall free all resources associated with a device.] */
AzureIoTClient 0:1f9b2707ec7d 159 /* Codes_SRS_CODEFIRST_99_087:[In order to release the device handle, CodeFirst_DestroyDevice shall call Device_Destroy.] */
AzureIoTClient 36:7d12a5386197 160
AzureIoTClient 0:1f9b2707ec7d 161 Device_Destroy(deviceHeader->DeviceHandle);
AzureIoTClient 0:1f9b2707ec7d 162 free(deviceHeader->data);
AzureIoTClient 0:1f9b2707ec7d 163 free(deviceHeader);
AzureIoTClient 0:1f9b2707ec7d 164 }
AzureIoTClient 0:1f9b2707ec7d 165
AzureIoTClient 0:1f9b2707ec7d 166 static CODEFIRST_RESULT buildStructTypes(SCHEMA_HANDLE schemaHandle, const REFLECTED_DATA_FROM_DATAPROVIDER* reflectedData)
AzureIoTClient 0:1f9b2707ec7d 167 {
AzureIoTClient 0:1f9b2707ec7d 168 CODEFIRST_RESULT result = CODEFIRST_OK;
AzureIoTClient 0:1f9b2707ec7d 169
AzureIoTClient 0:1f9b2707ec7d 170 const REFLECTED_SOMETHING* something;
AzureIoTClient 0:1f9b2707ec7d 171 for (something = reflectedData->reflectedData; something != NULL; something = something->next)
AzureIoTClient 0:1f9b2707ec7d 172 {
AzureIoTClient 0:1f9b2707ec7d 173 if (something->type == REFLECTION_STRUCT_TYPE)
AzureIoTClient 0:1f9b2707ec7d 174 {
AzureIoTClient 0:1f9b2707ec7d 175 SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle;
AzureIoTClient 0:1f9b2707ec7d 176 structTypeHandle = Schema_CreateStructType(schemaHandle, something->what.structure.name);
AzureIoTClient 0:1f9b2707ec7d 177
AzureIoTClient 0:1f9b2707ec7d 178 if (structTypeHandle == NULL)
AzureIoTClient 0:1f9b2707ec7d 179 {
AzureIoTClient 0:1f9b2707ec7d 180 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 181 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 11:b1327861f5e0 182 LogError("create struct failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 183 break;
AzureIoTClient 0:1f9b2707ec7d 184 }
AzureIoTClient 0:1f9b2707ec7d 185 else
AzureIoTClient 0:1f9b2707ec7d 186 {
AzureIoTClient 0:1f9b2707ec7d 187 const REFLECTED_SOMETHING* maybeField;
AzureIoTClient 0:1f9b2707ec7d 188 /*look for the field... */
AzureIoTClient 0:1f9b2707ec7d 189 for (maybeField = reflectedData->reflectedData; maybeField != NULL; maybeField = maybeField->next)
AzureIoTClient 0:1f9b2707ec7d 190 {
AzureIoTClient 0:1f9b2707ec7d 191 if (maybeField->type == REFLECTION_FIELD_TYPE)
AzureIoTClient 0:1f9b2707ec7d 192 {
AzureIoTClient 0:1f9b2707ec7d 193 if (strcmp(maybeField->what.field.structName, something->what.structure.name) == 0)
AzureIoTClient 0:1f9b2707ec7d 194 {
AzureIoTClient 0:1f9b2707ec7d 195 if (Schema_AddStructTypeProperty(structTypeHandle, maybeField->what.field.fieldName, maybeField->what.field.fieldType) != SCHEMA_OK)
AzureIoTClient 0:1f9b2707ec7d 196 {
AzureIoTClient 0:1f9b2707ec7d 197 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 198 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 11:b1327861f5e0 199 LogError("add struct property failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 200 break;
AzureIoTClient 0:1f9b2707ec7d 201 }
AzureIoTClient 0:1f9b2707ec7d 202 }
AzureIoTClient 0:1f9b2707ec7d 203 }
AzureIoTClient 0:1f9b2707ec7d 204 }
AzureIoTClient 0:1f9b2707ec7d 205 }
AzureIoTClient 0:1f9b2707ec7d 206 }
AzureIoTClient 0:1f9b2707ec7d 207 }
AzureIoTClient 0:1f9b2707ec7d 208
AzureIoTClient 0:1f9b2707ec7d 209 return result;
AzureIoTClient 0:1f9b2707ec7d 210 }
AzureIoTClient 0:1f9b2707ec7d 211
AzureIoTClient 0:1f9b2707ec7d 212 static CODEFIRST_RESULT buildModel(SCHEMA_HANDLE schemaHandle, const REFLECTED_DATA_FROM_DATAPROVIDER* reflectedData, const REFLECTED_SOMETHING* modelReflectedData)
AzureIoTClient 0:1f9b2707ec7d 213 {
AzureIoTClient 0:1f9b2707ec7d 214 CODEFIRST_RESULT result = CODEFIRST_OK;
AzureIoTClient 0:1f9b2707ec7d 215 const REFLECTED_SOMETHING* something;
AzureIoTClient 0:1f9b2707ec7d 216 SCHEMA_MODEL_TYPE_HANDLE modelTypeHandle;
AzureIoTClient 0:1f9b2707ec7d 217
AzureIoTClient 0:1f9b2707ec7d 218 modelTypeHandle = Schema_GetModelByName(schemaHandle, modelReflectedData->what.model.name);
AzureIoTClient 0:1f9b2707ec7d 219 if (modelTypeHandle == NULL)
AzureIoTClient 0:1f9b2707ec7d 220 {
AzureIoTClient 0:1f9b2707ec7d 221 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 222 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 0:1f9b2707ec7d 223 LogError("cannot get model %s %s", modelReflectedData->what.model.name, ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 224 goto out;
AzureIoTClient 0:1f9b2707ec7d 225 }
AzureIoTClient 0:1f9b2707ec7d 226
AzureIoTClient 0:1f9b2707ec7d 227 for (something = reflectedData->reflectedData; something != NULL; something = something->next)
AzureIoTClient 0:1f9b2707ec7d 228 {
AzureIoTClient 0:1f9b2707ec7d 229 /* looking for all elements that belong to a model: properties and actions */
AzureIoTClient 0:1f9b2707ec7d 230 if ((something->type == REFLECTION_PROPERTY_TYPE) &&
AzureIoTClient 0:1f9b2707ec7d 231 (strcmp(something->what.property.modelName, modelReflectedData->what.model.name) == 0))
AzureIoTClient 0:1f9b2707ec7d 232 {
AzureIoTClient 0:1f9b2707ec7d 233 SCHEMA_MODEL_TYPE_HANDLE childModelHande = Schema_GetModelByName(schemaHandle, something->what.property.type);
AzureIoTClient 0:1f9b2707ec7d 234
AzureIoTClient 0:1f9b2707ec7d 235 /* if this is a model type use the appropriate APIs for it */
AzureIoTClient 0:1f9b2707ec7d 236 if (childModelHande != NULL)
AzureIoTClient 0:1f9b2707ec7d 237 {
AzureIoTClient 17:fa1bba4c6053 238 if (Schema_AddModelModel(modelTypeHandle, something->what.property.name, childModelHande, something->what.property.offset, NULL) != SCHEMA_OK)
AzureIoTClient 0:1f9b2707ec7d 239 {
AzureIoTClient 0:1f9b2707ec7d 240 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 241 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 0:1f9b2707ec7d 242 LogError("add model failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 243 goto out;
AzureIoTClient 0:1f9b2707ec7d 244 }
AzureIoTClient 0:1f9b2707ec7d 245 }
AzureIoTClient 0:1f9b2707ec7d 246 else
AzureIoTClient 0:1f9b2707ec7d 247 {
AzureIoTClient 0:1f9b2707ec7d 248 if (Schema_AddModelProperty(modelTypeHandle, something->what.property.name, something->what.property.type) != SCHEMA_OK)
AzureIoTClient 0:1f9b2707ec7d 249 {
AzureIoTClient 0:1f9b2707ec7d 250 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 251 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 0:1f9b2707ec7d 252 LogError("add property failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 253 goto out;
AzureIoTClient 0:1f9b2707ec7d 254 }
AzureIoTClient 0:1f9b2707ec7d 255 }
AzureIoTClient 0:1f9b2707ec7d 256 }
AzureIoTClient 0:1f9b2707ec7d 257
AzureIoTClient 17:fa1bba4c6053 258 if ((something->type == REFLECTION_REPORTED_PROPERTY_TYPE) &&
AzureIoTClient 17:fa1bba4c6053 259 (strcmp(something->what.reportedProperty.modelName, modelReflectedData->what.model.name) == 0))
AzureIoTClient 17:fa1bba4c6053 260 {
AzureIoTClient 17:fa1bba4c6053 261 SCHEMA_MODEL_TYPE_HANDLE childModelHande = Schema_GetModelByName(schemaHandle, something->what.reportedProperty.type);
AzureIoTClient 17:fa1bba4c6053 262
AzureIoTClient 17:fa1bba4c6053 263 /* if this is a model type use the appropriate APIs for it */
AzureIoTClient 17:fa1bba4c6053 264 if (childModelHande != NULL)
AzureIoTClient 17:fa1bba4c6053 265 {
AzureIoTClient 17:fa1bba4c6053 266 if (Schema_AddModelModel(modelTypeHandle, something->what.reportedProperty.name, childModelHande, something->what.reportedProperty.offset, NULL) != SCHEMA_OK)
AzureIoTClient 17:fa1bba4c6053 267 {
AzureIoTClient 17:fa1bba4c6053 268 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 17:fa1bba4c6053 269 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 17:fa1bba4c6053 270 LogError("add model failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 17:fa1bba4c6053 271 goto out;
AzureIoTClient 17:fa1bba4c6053 272 }
AzureIoTClient 17:fa1bba4c6053 273 }
AzureIoTClient 17:fa1bba4c6053 274 else
AzureIoTClient 17:fa1bba4c6053 275 {
AzureIoTClient 17:fa1bba4c6053 276 if (Schema_AddModelReportedProperty(modelTypeHandle, something->what.reportedProperty.name, something->what.reportedProperty.type) != SCHEMA_OK)
AzureIoTClient 17:fa1bba4c6053 277 {
AzureIoTClient 17:fa1bba4c6053 278 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 17:fa1bba4c6053 279 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 17:fa1bba4c6053 280 LogError("add reported property failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 17:fa1bba4c6053 281 goto out;
AzureIoTClient 17:fa1bba4c6053 282 }
AzureIoTClient 17:fa1bba4c6053 283 }
AzureIoTClient 17:fa1bba4c6053 284 }
AzureIoTClient 17:fa1bba4c6053 285
AzureIoTClient 17:fa1bba4c6053 286 if ((something->type == REFLECTION_DESIRED_PROPERTY_TYPE) &&
AzureIoTClient 17:fa1bba4c6053 287 (strcmp(something->what.desiredProperty.modelName, modelReflectedData->what.model.name) == 0))
AzureIoTClient 17:fa1bba4c6053 288 {
AzureIoTClient 17:fa1bba4c6053 289 SCHEMA_MODEL_TYPE_HANDLE childModelHande = Schema_GetModelByName(schemaHandle, something->what.desiredProperty.type);
AzureIoTClient 17:fa1bba4c6053 290
AzureIoTClient 17:fa1bba4c6053 291 /* if this is a model type use the appropriate APIs for it */
AzureIoTClient 17:fa1bba4c6053 292 if (childModelHande != NULL)
AzureIoTClient 17:fa1bba4c6053 293 {
AzureIoTClient 17:fa1bba4c6053 294 if (Schema_AddModelModel(modelTypeHandle, something->what.desiredProperty.name, childModelHande, something->what.desiredProperty.offset, something->what.desiredProperty.onDesiredProperty) != SCHEMA_OK)
AzureIoTClient 17:fa1bba4c6053 295 {
AzureIoTClient 17:fa1bba4c6053 296 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 17:fa1bba4c6053 297 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 17:fa1bba4c6053 298 LogError("add model failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 17:fa1bba4c6053 299 goto out;
AzureIoTClient 17:fa1bba4c6053 300 }
AzureIoTClient 17:fa1bba4c6053 301 }
AzureIoTClient 17:fa1bba4c6053 302 else
AzureIoTClient 17:fa1bba4c6053 303 {
AzureIoTClient 36:7d12a5386197 304 if (Schema_AddModelDesiredProperty(modelTypeHandle,
AzureIoTClient 36:7d12a5386197 305 something->what.desiredProperty.name,
AzureIoTClient 36:7d12a5386197 306 something->what.desiredProperty.type,
AzureIoTClient 36:7d12a5386197 307 something->what.desiredProperty.FromAGENT_DATA_TYPE,
AzureIoTClient 36:7d12a5386197 308 something->what.desiredProperty.desiredPropertInitialize,
AzureIoTClient 36:7d12a5386197 309 something->what.desiredProperty.desiredPropertDeinitialize,
AzureIoTClient 36:7d12a5386197 310 something->what.desiredProperty.offset,
AzureIoTClient 17:fa1bba4c6053 311 something->what.desiredProperty.onDesiredProperty) != SCHEMA_OK)
AzureIoTClient 17:fa1bba4c6053 312 {
AzureIoTClient 17:fa1bba4c6053 313 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 17:fa1bba4c6053 314 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 17:fa1bba4c6053 315 LogError("add desired property failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 17:fa1bba4c6053 316 goto out;
AzureIoTClient 17:fa1bba4c6053 317 }
AzureIoTClient 17:fa1bba4c6053 318 }
AzureIoTClient 17:fa1bba4c6053 319 }
AzureIoTClient 17:fa1bba4c6053 320
AzureIoTClient 0:1f9b2707ec7d 321 if ((something->type == REFLECTION_ACTION_TYPE) &&
AzureIoTClient 0:1f9b2707ec7d 322 (strcmp(something->what.action.modelName, modelReflectedData->what.model.name) == 0))
AzureIoTClient 0:1f9b2707ec7d 323 {
AzureIoTClient 0:1f9b2707ec7d 324 SCHEMA_ACTION_HANDLE actionHandle;
AzureIoTClient 0:1f9b2707ec7d 325 size_t i;
AzureIoTClient 0:1f9b2707ec7d 326
AzureIoTClient 0:1f9b2707ec7d 327 if ((actionHandle = Schema_CreateModelAction(modelTypeHandle, something->what.action.name)) == NULL)
AzureIoTClient 0:1f9b2707ec7d 328 {
AzureIoTClient 0:1f9b2707ec7d 329 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 330 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 0:1f9b2707ec7d 331 LogError("add model action failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 332 goto out;
AzureIoTClient 0:1f9b2707ec7d 333 }
AzureIoTClient 0:1f9b2707ec7d 334
AzureIoTClient 0:1f9b2707ec7d 335 for (i = 0; i < something->what.action.nArguments; i++)
AzureIoTClient 0:1f9b2707ec7d 336 {
AzureIoTClient 0:1f9b2707ec7d 337 if (Schema_AddModelActionArgument(actionHandle, something->what.action.arguments[i].name, something->what.action.arguments[i].type) != SCHEMA_OK)
AzureIoTClient 0:1f9b2707ec7d 338 {
AzureIoTClient 0:1f9b2707ec7d 339 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 340 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 0:1f9b2707ec7d 341 LogError("add model action argument failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 342 goto out;
AzureIoTClient 0:1f9b2707ec7d 343 }
AzureIoTClient 0:1f9b2707ec7d 344 }
AzureIoTClient 0:1f9b2707ec7d 345 }
Azure.IoT.Build 18:58b667752399 346
Azure.IoT.Build 18:58b667752399 347 if ((something->type == REFLECTION_METHOD_TYPE) &&
Azure.IoT.Build 18:58b667752399 348 (strcmp(something->what.method.modelName, modelReflectedData->what.model.name) == 0))
Azure.IoT.Build 18:58b667752399 349 {
Azure.IoT.Build 18:58b667752399 350 SCHEMA_METHOD_HANDLE methodHandle;
Azure.IoT.Build 18:58b667752399 351 size_t i;
Azure.IoT.Build 18:58b667752399 352
Azure.IoT.Build 18:58b667752399 353 if ((methodHandle = Schema_CreateModelMethod(modelTypeHandle, something->what.method.name)) == NULL)
Azure.IoT.Build 18:58b667752399 354 {
Azure.IoT.Build 18:58b667752399 355 /*Codes_SRS_CODEFIRST_99_076: [ If any Schema APIs fail, CodeFirst_RegisterSchema shall return NULL. ]*/
Azure.IoT.Build 18:58b667752399 356 result = CODEFIRST_SCHEMA_ERROR;
Azure.IoT.Build 18:58b667752399 357 LogError("add model method failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
Azure.IoT.Build 18:58b667752399 358 goto out;
Azure.IoT.Build 18:58b667752399 359 }
Azure.IoT.Build 18:58b667752399 360
Azure.IoT.Build 18:58b667752399 361 for (i = 0; i < something->what.method.nArguments; i++)
Azure.IoT.Build 18:58b667752399 362 {
Azure.IoT.Build 18:58b667752399 363 if (Schema_AddModelMethodArgument(methodHandle, something->what.method.arguments[i].name, something->what.method.arguments[i].type) != SCHEMA_OK)
Azure.IoT.Build 18:58b667752399 364 {
Azure.IoT.Build 18:58b667752399 365 /*Codes_SRS_CODEFIRST_99_076: [ If any Schema APIs fail, CodeFirst_RegisterSchema shall return NULL. ]*/
Azure.IoT.Build 18:58b667752399 366 result = CODEFIRST_SCHEMA_ERROR;
Azure.IoT.Build 18:58b667752399 367 LogError("add model method argument failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
Azure.IoT.Build 18:58b667752399 368 goto out;
Azure.IoT.Build 18:58b667752399 369 }
Azure.IoT.Build 18:58b667752399 370 }
Azure.IoT.Build 18:58b667752399 371 }
AzureIoTClient 0:1f9b2707ec7d 372 }
AzureIoTClient 0:1f9b2707ec7d 373
AzureIoTClient 0:1f9b2707ec7d 374 out:
AzureIoTClient 0:1f9b2707ec7d 375 return result;
AzureIoTClient 0:1f9b2707ec7d 376 }
AzureIoTClient 0:1f9b2707ec7d 377
AzureIoTClient 0:1f9b2707ec7d 378 static CODEFIRST_RESULT buildModelTypes(SCHEMA_HANDLE schemaHandle, const REFLECTED_DATA_FROM_DATAPROVIDER* reflectedData)
AzureIoTClient 0:1f9b2707ec7d 379 {
AzureIoTClient 0:1f9b2707ec7d 380 CODEFIRST_RESULT result = CODEFIRST_OK;
AzureIoTClient 0:1f9b2707ec7d 381 const REFLECTED_SOMETHING* something;
AzureIoTClient 0:1f9b2707ec7d 382
AzureIoTClient 0:1f9b2707ec7d 383 /* first have a pass and add all the model types */
AzureIoTClient 0:1f9b2707ec7d 384 for (something = reflectedData->reflectedData; something != NULL; something = something->next)
AzureIoTClient 0:1f9b2707ec7d 385 {
AzureIoTClient 0:1f9b2707ec7d 386 if (something->type == REFLECTION_MODEL_TYPE)
AzureIoTClient 0:1f9b2707ec7d 387 {
AzureIoTClient 0:1f9b2707ec7d 388 if (Schema_CreateModelType(schemaHandle, something->what.model.name) == NULL)
AzureIoTClient 0:1f9b2707ec7d 389 {
AzureIoTClient 0:1f9b2707ec7d 390 /*Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CODEFIRST_SCHEMA_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 391 result = CODEFIRST_SCHEMA_ERROR;
AzureIoTClient 17:fa1bba4c6053 392 LogError("create model failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 393 goto out;
AzureIoTClient 0:1f9b2707ec7d 394 }
AzureIoTClient 0:1f9b2707ec7d 395 }
AzureIoTClient 0:1f9b2707ec7d 396 }
AzureIoTClient 0:1f9b2707ec7d 397
AzureIoTClient 0:1f9b2707ec7d 398 for (something = reflectedData->reflectedData; something != NULL; something = something->next)
AzureIoTClient 0:1f9b2707ec7d 399 {
AzureIoTClient 0:1f9b2707ec7d 400 if (something->type == REFLECTION_MODEL_TYPE)
AzureIoTClient 0:1f9b2707ec7d 401 {
AzureIoTClient 0:1f9b2707ec7d 402 result = buildModel(schemaHandle, reflectedData, something);
AzureIoTClient 0:1f9b2707ec7d 403 if (result != CODEFIRST_OK)
AzureIoTClient 0:1f9b2707ec7d 404 {
AzureIoTClient 0:1f9b2707ec7d 405 break;
AzureIoTClient 0:1f9b2707ec7d 406 }
AzureIoTClient 0:1f9b2707ec7d 407 }
AzureIoTClient 0:1f9b2707ec7d 408 }
AzureIoTClient 0:1f9b2707ec7d 409
AzureIoTClient 0:1f9b2707ec7d 410 out:
AzureIoTClient 0:1f9b2707ec7d 411 return result;
AzureIoTClient 0:1f9b2707ec7d 412 }
AzureIoTClient 0:1f9b2707ec7d 413
AzureIoTClient 17:fa1bba4c6053 414 static CODEFIRST_RESULT CodeFirst_Init_impl(const char* overrideSchemaNamespace, bool calledFromCodeFirst_Init)
AzureIoTClient 0:1f9b2707ec7d 415 {
AzureIoTClient 0:1f9b2707ec7d 416 /*shall build the default EntityContainer*/
AzureIoTClient 0:1f9b2707ec7d 417 CODEFIRST_RESULT result;
AzureIoTClient 0:1f9b2707ec7d 418
AzureIoTClient 0:1f9b2707ec7d 419 if (g_state != CODEFIRST_STATE_NOT_INIT)
AzureIoTClient 0:1f9b2707ec7d 420 {
AzureIoTClient 0:1f9b2707ec7d 421 /*Codes_SRS_CODEFIRST_99_003:[ If the module is already initialized, the initialization shall fail and the return value shall be CODEFIRST_ALREADY_INIT.]*/
AzureIoTClient 0:1f9b2707ec7d 422 result = CODEFIRST_ALREADY_INIT;
AzureIoTClient 17:fa1bba4c6053 423 if(calledFromCodeFirst_Init) /*do not log this error when APIs attempt lazy init*/
AzureIoTClient 17:fa1bba4c6053 424 {
AzureIoTClient 17:fa1bba4c6053 425 LogError("CodeFirst was already init %s", ENUM_TO_STRING(CODEFIRST_RESULT, result));
AzureIoTClient 17:fa1bba4c6053 426 }
AzureIoTClient 0:1f9b2707ec7d 427 }
AzureIoTClient 0:1f9b2707ec7d 428 else
AzureIoTClient 0:1f9b2707ec7d 429 {
AzureIoTClient 0:1f9b2707ec7d 430 g_DeviceCount = 0;
AzureIoTClient 0:1f9b2707ec7d 431 g_OverrideSchemaNamespace = overrideSchemaNamespace;
AzureIoTClient 0:1f9b2707ec7d 432 g_Devices = NULL;
AzureIoTClient 0:1f9b2707ec7d 433
AzureIoTClient 0:1f9b2707ec7d 434 /*Codes_SRS_CODEFIRST_99_002:[ CodeFirst_Init shall initialize the CodeFirst module. If initialization is successful, it shall return CODEFIRST_OK.]*/
AzureIoTClient 17:fa1bba4c6053 435 g_state = calledFromCodeFirst_Init? CODEFIRST_STATE_INIT_BY_INIT: CODEFIRST_STATE_INIT_BY_API;
AzureIoTClient 0:1f9b2707ec7d 436 result = CODEFIRST_OK;
AzureIoTClient 0:1f9b2707ec7d 437 }
AzureIoTClient 17:fa1bba4c6053 438 return result;
AzureIoTClient 17:fa1bba4c6053 439 }
AzureIoTClient 0:1f9b2707ec7d 440
AzureIoTClient 17:fa1bba4c6053 441 /*Codes_SRS_CODEFIRST_99_002:[ CodeFirst_Init shall initialize the CodeFirst module. If initialization is successful, it shall return CODEFIRST_OK.]*/
AzureIoTClient 17:fa1bba4c6053 442 CODEFIRST_RESULT CodeFirst_Init(const char* overrideSchemaNamespace)
AzureIoTClient 17:fa1bba4c6053 443 {
AzureIoTClient 17:fa1bba4c6053 444 return CodeFirst_Init_impl(overrideSchemaNamespace, true);
AzureIoTClient 0:1f9b2707ec7d 445 }
AzureIoTClient 0:1f9b2707ec7d 446
AzureIoTClient 0:1f9b2707ec7d 447 void CodeFirst_Deinit(void)
AzureIoTClient 0:1f9b2707ec7d 448 {
AzureIoTClient 0:1f9b2707ec7d 449 /*Codes_SRS_CODEFIRST_99_006:[If the module is not previously initialed, CodeFirst_Deinit shall do nothing.]*/
AzureIoTClient 17:fa1bba4c6053 450 if (g_state != CODEFIRST_STATE_INIT_BY_INIT)
AzureIoTClient 0:1f9b2707ec7d 451 {
AzureIoTClient 17:fa1bba4c6053 452 LogError("CodeFirst_Deinit called when CodeFirst was not initialized by CodeFirst_Init");
AzureIoTClient 0:1f9b2707ec7d 453 }
AzureIoTClient 0:1f9b2707ec7d 454 else
AzureIoTClient 0:1f9b2707ec7d 455 {
AzureIoTClient 0:1f9b2707ec7d 456 size_t i;
AzureIoTClient 0:1f9b2707ec7d 457
AzureIoTClient 0:1f9b2707ec7d 458 /*Codes_SRS_CODEFIRST_99_005:[ CodeFirst_Deinit shall deinitialize the module, freeing all the resources and placing the module in an uninitialized state.]*/
AzureIoTClient 0:1f9b2707ec7d 459 for (i = 0; i < g_DeviceCount; i++)
AzureIoTClient 0:1f9b2707ec7d 460 {
AzureIoTClient 0:1f9b2707ec7d 461 DestroyDevice(g_Devices[i]);
AzureIoTClient 0:1f9b2707ec7d 462 }
AzureIoTClient 0:1f9b2707ec7d 463
AzureIoTClient 0:1f9b2707ec7d 464 free(g_Devices);
AzureIoTClient 0:1f9b2707ec7d 465 g_Devices = NULL;
AzureIoTClient 0:1f9b2707ec7d 466 g_DeviceCount = 0;
AzureIoTClient 0:1f9b2707ec7d 467
AzureIoTClient 0:1f9b2707ec7d 468 g_state = CODEFIRST_STATE_NOT_INIT;
AzureIoTClient 0:1f9b2707ec7d 469 }
AzureIoTClient 0:1f9b2707ec7d 470 }
AzureIoTClient 0:1f9b2707ec7d 471
AzureIoTClient 0:1f9b2707ec7d 472 static const REFLECTED_SOMETHING* FindModelInCodeFirstMetadata(const REFLECTED_SOMETHING* reflectedData, const char* modelName)
AzureIoTClient 0:1f9b2707ec7d 473 {
AzureIoTClient 0:1f9b2707ec7d 474 const REFLECTED_SOMETHING* result;
AzureIoTClient 0:1f9b2707ec7d 475
AzureIoTClient 0:1f9b2707ec7d 476 for (result = reflectedData; result != NULL; result = result->next)
AzureIoTClient 0:1f9b2707ec7d 477 {
AzureIoTClient 0:1f9b2707ec7d 478 if ((result->type == REFLECTION_MODEL_TYPE) &&
AzureIoTClient 0:1f9b2707ec7d 479 (strcmp(result->what.model.name, modelName) == 0))
AzureIoTClient 0:1f9b2707ec7d 480 {
AzureIoTClient 0:1f9b2707ec7d 481 /* found model type */
AzureIoTClient 0:1f9b2707ec7d 482 break;
AzureIoTClient 0:1f9b2707ec7d 483 }
AzureIoTClient 0:1f9b2707ec7d 484 }
AzureIoTClient 0:1f9b2707ec7d 485
AzureIoTClient 0:1f9b2707ec7d 486 return result;
AzureIoTClient 0:1f9b2707ec7d 487 }
AzureIoTClient 0:1f9b2707ec7d 488
AzureIoTClient 0:1f9b2707ec7d 489 static const REFLECTED_SOMETHING* FindChildModelInCodeFirstMetadata(const REFLECTED_SOMETHING* reflectedData, const REFLECTED_SOMETHING* startModel, const char* relativePath, size_t* offset)
AzureIoTClient 0:1f9b2707ec7d 490 {
AzureIoTClient 0:1f9b2707ec7d 491 const REFLECTED_SOMETHING* result = startModel;
AzureIoTClient 0:1f9b2707ec7d 492 *offset = 0;
AzureIoTClient 0:1f9b2707ec7d 493
AzureIoTClient 0:1f9b2707ec7d 494 /* Codes_SRS_CODEFIRST_99_139:[If the relativeActionPath is empty then the action shall be looked up in the device model.] */
AzureIoTClient 0:1f9b2707ec7d 495 while ((*relativePath != 0) && (result != NULL))
AzureIoTClient 0:1f9b2707ec7d 496 {
AzureIoTClient 0:1f9b2707ec7d 497 /* Codes_SRS_CODEFIRST_99_142:[The relativeActionPath argument shall be in the format "childModel1/childModel2/.../childModelN".] */
AzureIoTClient 0:1f9b2707ec7d 498 const REFLECTED_SOMETHING* childModelProperty;
AzureIoTClient 0:1f9b2707ec7d 499 size_t propertyNameLength;
AzureIoTClient 0:1f9b2707ec7d 500 const char* slashPos = strchr(relativePath, '/');
AzureIoTClient 0:1f9b2707ec7d 501 if (slashPos == NULL)
AzureIoTClient 0:1f9b2707ec7d 502 {
AzureIoTClient 0:1f9b2707ec7d 503 slashPos = &relativePath[strlen(relativePath)];
AzureIoTClient 0:1f9b2707ec7d 504 }
AzureIoTClient 0:1f9b2707ec7d 505
AzureIoTClient 0:1f9b2707ec7d 506 propertyNameLength = slashPos - relativePath;
AzureIoTClient 0:1f9b2707ec7d 507
AzureIoTClient 0:1f9b2707ec7d 508 for (childModelProperty = reflectedData; childModelProperty != NULL; childModelProperty = childModelProperty->next)
AzureIoTClient 0:1f9b2707ec7d 509 {
AzureIoTClient 0:1f9b2707ec7d 510 if ((childModelProperty->type == REFLECTION_PROPERTY_TYPE) &&
AzureIoTClient 0:1f9b2707ec7d 511 (strcmp(childModelProperty->what.property.modelName, result->what.model.name) == 0) &&
AzureIoTClient 0:1f9b2707ec7d 512 (strncmp(childModelProperty->what.property.name, relativePath, propertyNameLength) == 0) &&
AzureIoTClient 0:1f9b2707ec7d 513 (strlen(childModelProperty->what.property.name) == propertyNameLength))
AzureIoTClient 0:1f9b2707ec7d 514 {
AzureIoTClient 0:1f9b2707ec7d 515 /* property found, now let's find the model */
AzureIoTClient 0:1f9b2707ec7d 516 /* Codes_SRS_CODEFIRST_99_140:[CodeFirst_InvokeAction shall pass to the action wrapper that it calls a pointer to the model where the action is defined.] */
AzureIoTClient 0:1f9b2707ec7d 517 *offset += childModelProperty->what.property.offset;
AzureIoTClient 0:1f9b2707ec7d 518 break;
AzureIoTClient 0:1f9b2707ec7d 519 }
AzureIoTClient 0:1f9b2707ec7d 520 }
AzureIoTClient 0:1f9b2707ec7d 521
AzureIoTClient 0:1f9b2707ec7d 522 if (childModelProperty == NULL)
AzureIoTClient 0:1f9b2707ec7d 523 {
AzureIoTClient 0:1f9b2707ec7d 524 /* not found */
AzureIoTClient 0:1f9b2707ec7d 525 result = NULL;
AzureIoTClient 0:1f9b2707ec7d 526 }
AzureIoTClient 0:1f9b2707ec7d 527 else
AzureIoTClient 0:1f9b2707ec7d 528 {
AzureIoTClient 0:1f9b2707ec7d 529 result = FindModelInCodeFirstMetadata(reflectedData, childModelProperty->what.property.type);
AzureIoTClient 0:1f9b2707ec7d 530 }
AzureIoTClient 0:1f9b2707ec7d 531
AzureIoTClient 0:1f9b2707ec7d 532 relativePath = slashPos;
AzureIoTClient 0:1f9b2707ec7d 533 }
AzureIoTClient 0:1f9b2707ec7d 534
AzureIoTClient 0:1f9b2707ec7d 535 return result;
AzureIoTClient 0:1f9b2707ec7d 536 }
AzureIoTClient 0:1f9b2707ec7d 537
AzureIoTClient 17:fa1bba4c6053 538 EXECUTE_COMMAND_RESULT CodeFirst_InvokeAction(DEVICE_HANDLE deviceHandle, void* callbackUserContext, const char* relativeActionPath, const char* actionName, size_t parameterCount, const AGENT_DATA_TYPE* parameterValues)
AzureIoTClient 0:1f9b2707ec7d 539 {
AzureIoTClient 0:1f9b2707ec7d 540 EXECUTE_COMMAND_RESULT result;
AzureIoTClient 0:1f9b2707ec7d 541 DEVICE_HEADER_DATA* deviceHeader = (DEVICE_HEADER_DATA*)callbackUserContext;
AzureIoTClient 0:1f9b2707ec7d 542
AzureIoTClient 0:1f9b2707ec7d 543 /*Codes_SRS_CODEFIRST_99_068:[ If the function is called before CodeFirst is initialized then EXECUTE_COMMAND_ERROR shall be returned.] */
AzureIoTClient 17:fa1bba4c6053 544 if (g_state == CODEFIRST_STATE_NOT_INIT)
AzureIoTClient 0:1f9b2707ec7d 545 {
AzureIoTClient 0:1f9b2707ec7d 546 result = EXECUTE_COMMAND_ERROR;
AzureIoTClient 11:b1327861f5e0 547 LogError("CodeFirst_InvokeAction called before init has an error %s ", ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 548 }
AzureIoTClient 0:1f9b2707ec7d 549 /*Codes_SRS_CODEFIRST_99_066:[ If actionName, relativeActionPath or deviceHandle is NULL then EXECUTE_COMMAND_ERROR shall be returned*/
AzureIoTClient 0:1f9b2707ec7d 550 else if ((actionName == NULL) ||
AzureIoTClient 0:1f9b2707ec7d 551 (deviceHandle == NULL) ||
AzureIoTClient 0:1f9b2707ec7d 552 (relativeActionPath == NULL))
AzureIoTClient 0:1f9b2707ec7d 553 {
AzureIoTClient 0:1f9b2707ec7d 554 result = EXECUTE_COMMAND_ERROR;
AzureIoTClient 11:b1327861f5e0 555 LogError("action Name is NULL %s ", ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 556 }
AzureIoTClient 0:1f9b2707ec7d 557 /*Codes_SRS_CODEFIRST_99_067:[ If parameterCount is greater than zero and parameterValues is NULL then EXECUTE_COMMAND_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 558 else if ((parameterCount > 0) && (parameterValues == NULL))
AzureIoTClient 0:1f9b2707ec7d 559 {
AzureIoTClient 0:1f9b2707ec7d 560 result = EXECUTE_COMMAND_ERROR;
AzureIoTClient 11:b1327861f5e0 561 LogError("parameterValues error %s ", ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 562 }
AzureIoTClient 0:1f9b2707ec7d 563 else
AzureIoTClient 0:1f9b2707ec7d 564 {
AzureIoTClient 0:1f9b2707ec7d 565 const REFLECTED_SOMETHING* something;
AzureIoTClient 0:1f9b2707ec7d 566 const REFLECTED_SOMETHING* childModel;
AzureIoTClient 0:1f9b2707ec7d 567 const char* modelName;
AzureIoTClient 0:1f9b2707ec7d 568 size_t offset;
AzureIoTClient 0:1f9b2707ec7d 569
AzureIoTClient 0:1f9b2707ec7d 570 modelName = Schema_GetModelName(deviceHeader->ModelHandle);
AzureIoTClient 0:1f9b2707ec7d 571
AzureIoTClient 0:1f9b2707ec7d 572 if (((childModel = FindModelInCodeFirstMetadata(deviceHeader->ReflectedData->reflectedData, modelName)) == NULL) ||
AzureIoTClient 0:1f9b2707ec7d 573 /* Codes_SRS_CODEFIRST_99_138:[The relativeActionPath argument shall be used by CodeFirst_InvokeAction to find the child model where the action is declared.] */
AzureIoTClient 0:1f9b2707ec7d 574 ((childModel = FindChildModelInCodeFirstMetadata(deviceHeader->ReflectedData->reflectedData, childModel, relativeActionPath, &offset)) == NULL))
AzureIoTClient 0:1f9b2707ec7d 575 {
AzureIoTClient 0:1f9b2707ec7d 576 /*Codes_SRS_CODEFIRST_99_141:[If a child model specified in the relativeActionPath argument cannot be found by CodeFirst_InvokeAction, it shall return EXECUTE_COMMAND_ERROR.] */
AzureIoTClient 0:1f9b2707ec7d 577 result = EXECUTE_COMMAND_ERROR;
AzureIoTClient 11:b1327861f5e0 578 LogError("action %s was not found %s ", actionName, ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 579 }
AzureIoTClient 0:1f9b2707ec7d 580 else
AzureIoTClient 0:1f9b2707ec7d 581 {
AzureIoTClient 0:1f9b2707ec7d 582 /* Codes_SRS_CODEFIRST_99_062:[ When CodeFirst_InvokeAction is called it shall look through the codefirst metadata associated with a specific device for a previously declared action (function) named actionName.]*/
AzureIoTClient 0:1f9b2707ec7d 583 /* Codes_SRS_CODEFIRST_99_078:[If such a function is not found then the function shall return EXECUTE_COMMAND_ERROR.]*/
AzureIoTClient 0:1f9b2707ec7d 584 result = EXECUTE_COMMAND_ERROR;
AzureIoTClient 0:1f9b2707ec7d 585 for (something = deviceHeader->ReflectedData->reflectedData; something != NULL; something = something->next)
AzureIoTClient 0:1f9b2707ec7d 586 {
AzureIoTClient 0:1f9b2707ec7d 587 if ((something->type == REFLECTION_ACTION_TYPE) &&
AzureIoTClient 0:1f9b2707ec7d 588 (strcmp(actionName, something->what.action.name) == 0) &&
AzureIoTClient 0:1f9b2707ec7d 589 (strcmp(childModel->what.model.name, something->what.action.modelName) == 0))
AzureIoTClient 0:1f9b2707ec7d 590 {
AzureIoTClient 0:1f9b2707ec7d 591 /*Codes_SRS_CODEFIRST_99_063:[ If the function is found, then CodeFirst shall call the wrapper of the found function inside the data provider. The wrapper is linked in the reflected data to the function name. The wrapper shall be called with the same arguments as CodeFirst_InvokeAction has been called.]*/
AzureIoTClient 0:1f9b2707ec7d 592 /*Codes_SRS_CODEFIRST_99_064:[ If the wrapper call succeeds then CODEFIRST_OK shall be returned. ]*/
AzureIoTClient 0:1f9b2707ec7d 593 /*Codes_SRS_CODEFIRST_99_065:[ For all the other return values CODEFIRST_ACTION_EXECUTION_ERROR shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 594 /* Codes_SRS_CODEFIRST_99_140:[CodeFirst_InvokeAction shall pass to the action wrapper that it calls a pointer to the model where the action is defined.] */
AzureIoTClient 0:1f9b2707ec7d 595 /*Codes_SRS_CODEFIRST_02_013: [The wrapper's return value shall be returned.]*/
AzureIoTClient 0:1f9b2707ec7d 596 result = something->what.action.wrapper(deviceHeader->data + offset, parameterCount, parameterValues);
AzureIoTClient 0:1f9b2707ec7d 597 break;
AzureIoTClient 0:1f9b2707ec7d 598 }
AzureIoTClient 0:1f9b2707ec7d 599 }
AzureIoTClient 0:1f9b2707ec7d 600 }
AzureIoTClient 0:1f9b2707ec7d 601 }
AzureIoTClient 0:1f9b2707ec7d 602
AzureIoTClient 0:1f9b2707ec7d 603 if (result == EXECUTE_COMMAND_ERROR)
AzureIoTClient 0:1f9b2707ec7d 604 {
AzureIoTClient 11:b1327861f5e0 605 LogError(" %s ", ENUM_TO_STRING(EXECUTE_COMMAND_RESULT, result));
AzureIoTClient 0:1f9b2707ec7d 606 }
AzureIoTClient 0:1f9b2707ec7d 607 return result;
AzureIoTClient 0:1f9b2707ec7d 608 }
AzureIoTClient 0:1f9b2707ec7d 609
Azure.IoT.Build 18:58b667752399 610 METHODRETURN_HANDLE CodeFirst_InvokeMethod(DEVICE_HANDLE deviceHandle, void* callbackUserContext, const char* relativeMethodPath, const char* methodName, size_t parameterCount, const AGENT_DATA_TYPE* parameterValues)
Azure.IoT.Build 18:58b667752399 611 {
Azure.IoT.Build 18:58b667752399 612 METHODRETURN_HANDLE result;
Azure.IoT.Build 18:58b667752399 613 DEVICE_HEADER_DATA* deviceHeader = (DEVICE_HEADER_DATA*)callbackUserContext;
Azure.IoT.Build 18:58b667752399 614
Azure.IoT.Build 18:58b667752399 615 if (g_state == CODEFIRST_STATE_NOT_INIT)
Azure.IoT.Build 18:58b667752399 616 {
Azure.IoT.Build 18:58b667752399 617 result = NULL;
Azure.IoT.Build 18:58b667752399 618 LogError("CodeFirst_InvokeMethod called before CodeFirst_Init");
Azure.IoT.Build 18:58b667752399 619 }
Azure.IoT.Build 18:58b667752399 620 else if ((methodName == NULL) ||
Azure.IoT.Build 18:58b667752399 621 (deviceHandle == NULL) ||
Azure.IoT.Build 18:58b667752399 622 (relativeMethodPath == NULL))
Azure.IoT.Build 18:58b667752399 623 {
Azure.IoT.Build 18:58b667752399 624 result = NULL;
Azure.IoT.Build 18:58b667752399 625 LogError("invalid args: DEVICE_HANDLE deviceHandle=%p, void* callbackUserContext=%p, const char* relativeMethodPath=%p, const char* methodName=%p, size_t parameterCount=%zu, const AGENT_DATA_TYPE* parameterValues=%p",
Azure.IoT.Build 18:58b667752399 626 deviceHandle, callbackUserContext, relativeMethodPath, methodName, parameterCount, parameterValues);
Azure.IoT.Build 18:58b667752399 627 }
Azure.IoT.Build 18:58b667752399 628 else if ((parameterCount > 0) && (parameterValues == NULL))
Azure.IoT.Build 18:58b667752399 629 {
Azure.IoT.Build 18:58b667752399 630 result = NULL;
Azure.IoT.Build 18:58b667752399 631 LogError("parameterValues error ");
Azure.IoT.Build 18:58b667752399 632 }
Azure.IoT.Build 18:58b667752399 633 else
Azure.IoT.Build 18:58b667752399 634 {
Azure.IoT.Build 18:58b667752399 635 const REFLECTED_SOMETHING* something;
Azure.IoT.Build 18:58b667752399 636 const REFLECTED_SOMETHING* childModel;
Azure.IoT.Build 18:58b667752399 637 const char* modelName;
Azure.IoT.Build 18:58b667752399 638 size_t offset;
Azure.IoT.Build 18:58b667752399 639
Azure.IoT.Build 18:58b667752399 640 modelName = Schema_GetModelName(deviceHeader->ModelHandle);
Azure.IoT.Build 18:58b667752399 641
Azure.IoT.Build 18:58b667752399 642 if (((childModel = FindModelInCodeFirstMetadata(deviceHeader->ReflectedData->reflectedData, modelName)) == NULL) ||
Azure.IoT.Build 18:58b667752399 643 ((childModel = FindChildModelInCodeFirstMetadata(deviceHeader->ReflectedData->reflectedData, childModel, relativeMethodPath, &offset)) == NULL))
Azure.IoT.Build 18:58b667752399 644 {
Azure.IoT.Build 18:58b667752399 645 result = NULL;
Azure.IoT.Build 18:58b667752399 646 LogError("method %s was not found", methodName);
Azure.IoT.Build 18:58b667752399 647 }
Azure.IoT.Build 18:58b667752399 648 else
Azure.IoT.Build 18:58b667752399 649 {
Azure.IoT.Build 18:58b667752399 650 result = NULL;
Azure.IoT.Build 18:58b667752399 651 for (something = deviceHeader->ReflectedData->reflectedData; something != NULL; something = something->next)
Azure.IoT.Build 18:58b667752399 652 {
Azure.IoT.Build 18:58b667752399 653 if ((something->type == REFLECTION_METHOD_TYPE) &&
Azure.IoT.Build 18:58b667752399 654 (strcmp(methodName, something->what.method.name) == 0) &&
Azure.IoT.Build 18:58b667752399 655 (strcmp(childModel->what.model.name, something->what.method.modelName) == 0))
Azure.IoT.Build 18:58b667752399 656 {
Azure.IoT.Build 18:58b667752399 657 break; /*found...*/
Azure.IoT.Build 18:58b667752399 658 }
Azure.IoT.Build 18:58b667752399 659 }
Azure.IoT.Build 18:58b667752399 660
Azure.IoT.Build 18:58b667752399 661 if (something == NULL)
Azure.IoT.Build 18:58b667752399 662 {
Azure.IoT.Build 18:58b667752399 663 LogError("method \"%s\" not found", methodName);
Azure.IoT.Build 18:58b667752399 664 result = NULL;
Azure.IoT.Build 18:58b667752399 665 }
Azure.IoT.Build 18:58b667752399 666 else
Azure.IoT.Build 18:58b667752399 667 {
Azure.IoT.Build 18:58b667752399 668 result = something->what.method.wrapper(deviceHeader->data + offset, parameterCount, parameterValues);
Azure.IoT.Build 18:58b667752399 669 if (result == NULL)
Azure.IoT.Build 18:58b667752399 670 {
Azure.IoT.Build 18:58b667752399 671 LogError("method \"%s\" execution error (returned NULL)", methodName);
Azure.IoT.Build 18:58b667752399 672 }
Azure.IoT.Build 18:58b667752399 673 }
Azure.IoT.Build 18:58b667752399 674 }
Azure.IoT.Build 18:58b667752399 675 }
Azure.IoT.Build 18:58b667752399 676 return result;
Azure.IoT.Build 18:58b667752399 677 }
Azure.IoT.Build 18:58b667752399 678
Azure.IoT.Build 18:58b667752399 679
AzureIoTClient 0:1f9b2707ec7d 680 /* Codes_SRS_CODEFIRST_99_002:[ CodeFirst_RegisterSchema shall create the schema information and give it to the Schema module for one schema, identified by the metadata argument. On success, it shall return a handle to the schema.] */
AzureIoTClient 0:1f9b2707ec7d 681 SCHEMA_HANDLE CodeFirst_RegisterSchema(const char* schemaNamespace, const REFLECTED_DATA_FROM_DATAPROVIDER* metadata)
AzureIoTClient 0:1f9b2707ec7d 682 {
AzureIoTClient 0:1f9b2707ec7d 683 SCHEMA_HANDLE result;
AzureIoTClient 17:fa1bba4c6053 684 /*Codes_SRS_CODEFIRST_02_048: [ If schemaNamespace is NULL then CodeFirst_RegisterSchema shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 685 /*Codes_SRS_CODEFIRST_02_049: [ If metadata is NULL then CodeFirst_RegisterSchema shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 686 if (
AzureIoTClient 17:fa1bba4c6053 687 (schemaNamespace == NULL) ||
AzureIoTClient 17:fa1bba4c6053 688 (metadata == NULL)
AzureIoTClient 17:fa1bba4c6053 689 )
AzureIoTClient 0:1f9b2707ec7d 690 {
AzureIoTClient 17:fa1bba4c6053 691 LogError("invalid arg const char* schemaNamespace=%p, const REFLECTED_DATA_FROM_DATAPROVIDER* metadata=%p", schemaNamespace, metadata);
AzureIoTClient 17:fa1bba4c6053 692 result = NULL;
AzureIoTClient 0:1f9b2707ec7d 693 }
AzureIoTClient 17:fa1bba4c6053 694 else
AzureIoTClient 0:1f9b2707ec7d 695 {
AzureIoTClient 17:fa1bba4c6053 696 if (g_OverrideSchemaNamespace != NULL)
AzureIoTClient 0:1f9b2707ec7d 697 {
AzureIoTClient 17:fa1bba4c6053 698 schemaNamespace = g_OverrideSchemaNamespace;
AzureIoTClient 0:1f9b2707ec7d 699 }
AzureIoTClient 17:fa1bba4c6053 700
AzureIoTClient 17:fa1bba4c6053 701 /* Codes_SRS_CODEFIRST_99_121:[If the schema has already been registered, CodeFirst_RegisterSchema shall return its handle.] */
AzureIoTClient 17:fa1bba4c6053 702 result = Schema_GetSchemaByNamespace(schemaNamespace);
AzureIoTClient 17:fa1bba4c6053 703 if (result == NULL)
AzureIoTClient 0:1f9b2707ec7d 704 {
AzureIoTClient 17:fa1bba4c6053 705 if ((result = Schema_Create(schemaNamespace, (void*)metadata)) == NULL)
AzureIoTClient 0:1f9b2707ec7d 706 {
AzureIoTClient 17:fa1bba4c6053 707 /* Codes_SRS_CODEFIRST_99_076:[If any Schema APIs fail, CodeFirst_RegisterSchema shall return NULL.] */
AzureIoTClient 0:1f9b2707ec7d 708 result = NULL;
AzureIoTClient 17:fa1bba4c6053 709 LogError("schema init failed %s", ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_SCHEMA_ERROR));
AzureIoTClient 0:1f9b2707ec7d 710 }
AzureIoTClient 0:1f9b2707ec7d 711 else
AzureIoTClient 0:1f9b2707ec7d 712 {
AzureIoTClient 17:fa1bba4c6053 713 if ((buildStructTypes(result, metadata) != CODEFIRST_OK) ||
AzureIoTClient 17:fa1bba4c6053 714 (buildModelTypes(result, metadata) != CODEFIRST_OK))
AzureIoTClient 17:fa1bba4c6053 715 {
AzureIoTClient 17:fa1bba4c6053 716 Schema_Destroy(result);
AzureIoTClient 17:fa1bba4c6053 717 result = NULL;
AzureIoTClient 17:fa1bba4c6053 718 }
AzureIoTClient 17:fa1bba4c6053 719 else
AzureIoTClient 17:fa1bba4c6053 720 {
AzureIoTClient 17:fa1bba4c6053 721 /* do nothing, everything is OK */
AzureIoTClient 17:fa1bba4c6053 722 }
AzureIoTClient 0:1f9b2707ec7d 723 }
AzureIoTClient 0:1f9b2707ec7d 724 }
AzureIoTClient 0:1f9b2707ec7d 725 }
AzureIoTClient 0:1f9b2707ec7d 726
AzureIoTClient 0:1f9b2707ec7d 727 return result;
AzureIoTClient 0:1f9b2707ec7d 728 }
AzureIoTClient 0:1f9b2707ec7d 729
AzureIoTClient 0:1f9b2707ec7d 730 AGENT_DATA_TYPE_TYPE CodeFirst_GetPrimitiveType(const char* typeName)
AzureIoTClient 0:1f9b2707ec7d 731 {
Azure.IoT Build 7:5176a13270bb 732 #ifndef NO_FLOATS
AzureIoTClient 0:1f9b2707ec7d 733 if (strcmp(typeName, "double") == 0)
AzureIoTClient 0:1f9b2707ec7d 734 {
AzureIoTClient 0:1f9b2707ec7d 735 return EDM_DOUBLE_TYPE;
AzureIoTClient 0:1f9b2707ec7d 736 }
AzureIoTClient 0:1f9b2707ec7d 737 else if (strcmp(typeName, "float") == 0)
AzureIoTClient 0:1f9b2707ec7d 738 {
AzureIoTClient 0:1f9b2707ec7d 739 return EDM_SINGLE_TYPE;
AzureIoTClient 0:1f9b2707ec7d 740 }
AzureIoTClient 36:7d12a5386197 741 else
AzureIoTClient 6:36cc37b1dbc9 742 #endif
AzureIoTClient 6:36cc37b1dbc9 743 if (strcmp(typeName, "int") == 0)
AzureIoTClient 0:1f9b2707ec7d 744 {
AzureIoTClient 0:1f9b2707ec7d 745 return EDM_INT32_TYPE;
AzureIoTClient 0:1f9b2707ec7d 746 }
AzureIoTClient 0:1f9b2707ec7d 747 else if (strcmp(typeName, "long") == 0)
AzureIoTClient 0:1f9b2707ec7d 748 {
AzureIoTClient 0:1f9b2707ec7d 749 return EDM_INT64_TYPE;
AzureIoTClient 0:1f9b2707ec7d 750 }
AzureIoTClient 0:1f9b2707ec7d 751 else if (strcmp(typeName, "int8_t") == 0)
AzureIoTClient 0:1f9b2707ec7d 752 {
AzureIoTClient 0:1f9b2707ec7d 753 return EDM_SBYTE_TYPE;
AzureIoTClient 0:1f9b2707ec7d 754 }
AzureIoTClient 0:1f9b2707ec7d 755 else if (strcmp(typeName, "uint8_t") == 0)
AzureIoTClient 0:1f9b2707ec7d 756 {
AzureIoTClient 0:1f9b2707ec7d 757 return EDM_BYTE_TYPE;
AzureIoTClient 0:1f9b2707ec7d 758 }
AzureIoTClient 0:1f9b2707ec7d 759 else if (strcmp(typeName, "int16_t") == 0)
AzureIoTClient 0:1f9b2707ec7d 760 {
AzureIoTClient 0:1f9b2707ec7d 761 return EDM_INT16_TYPE;
AzureIoTClient 0:1f9b2707ec7d 762 }
AzureIoTClient 0:1f9b2707ec7d 763 else if (strcmp(typeName, "int32_t") == 0)
AzureIoTClient 0:1f9b2707ec7d 764 {
AzureIoTClient 0:1f9b2707ec7d 765 return EDM_INT32_TYPE;
AzureIoTClient 0:1f9b2707ec7d 766 }
AzureIoTClient 0:1f9b2707ec7d 767 else if (strcmp(typeName, "int64_t") == 0)
AzureIoTClient 0:1f9b2707ec7d 768 {
AzureIoTClient 0:1f9b2707ec7d 769 return EDM_INT64_TYPE;
AzureIoTClient 0:1f9b2707ec7d 770 }
AzureIoTClient 0:1f9b2707ec7d 771 else if (
AzureIoTClient 0:1f9b2707ec7d 772 (strcmp(typeName, "_Bool") == 0) ||
AzureIoTClient 0:1f9b2707ec7d 773 (strcmp(typeName, "bool") == 0)
AzureIoTClient 0:1f9b2707ec7d 774 )
AzureIoTClient 0:1f9b2707ec7d 775 {
AzureIoTClient 0:1f9b2707ec7d 776 return EDM_BOOLEAN_TYPE;
AzureIoTClient 0:1f9b2707ec7d 777 }
AzureIoTClient 0:1f9b2707ec7d 778 else if (strcmp(typeName, "ascii_char_ptr") == 0)
AzureIoTClient 0:1f9b2707ec7d 779 {
AzureIoTClient 0:1f9b2707ec7d 780 return EDM_STRING_TYPE;
AzureIoTClient 0:1f9b2707ec7d 781 }
AzureIoTClient 0:1f9b2707ec7d 782 else if (strcmp(typeName, "ascii_char_ptr_no_quotes") == 0)
AzureIoTClient 0:1f9b2707ec7d 783 {
AzureIoTClient 0:1f9b2707ec7d 784 return EDM_STRING_NO_QUOTES_TYPE;
AzureIoTClient 0:1f9b2707ec7d 785 }
AzureIoTClient 0:1f9b2707ec7d 786 else if (strcmp(typeName, "EDM_DATE_TIME_OFFSET") == 0)
AzureIoTClient 0:1f9b2707ec7d 787 {
AzureIoTClient 0:1f9b2707ec7d 788 return EDM_DATE_TIME_OFFSET_TYPE;
AzureIoTClient 0:1f9b2707ec7d 789 }
AzureIoTClient 0:1f9b2707ec7d 790 else if (strcmp(typeName, "EDM_GUID") == 0)
AzureIoTClient 0:1f9b2707ec7d 791 {
AzureIoTClient 0:1f9b2707ec7d 792 return EDM_GUID_TYPE;
AzureIoTClient 0:1f9b2707ec7d 793 }
AzureIoTClient 0:1f9b2707ec7d 794 else if (strcmp(typeName, "EDM_BINARY") == 0)
AzureIoTClient 0:1f9b2707ec7d 795 {
AzureIoTClient 0:1f9b2707ec7d 796 return EDM_BINARY_TYPE;
AzureIoTClient 0:1f9b2707ec7d 797 }
AzureIoTClient 0:1f9b2707ec7d 798 else
AzureIoTClient 0:1f9b2707ec7d 799 {
AzureIoTClient 0:1f9b2707ec7d 800 return EDM_NO_TYPE;
AzureIoTClient 0:1f9b2707ec7d 801 }
AzureIoTClient 0:1f9b2707ec7d 802 }
AzureIoTClient 0:1f9b2707ec7d 803
AzureIoTClient 17:fa1bba4c6053 804 static void initializeDesiredProperties(SCHEMA_MODEL_TYPE_HANDLE model, void* destination)
AzureIoTClient 17:fa1bba4c6053 805 {
AzureIoTClient 17:fa1bba4c6053 806 /*this function assumes that at the address given by destination there is an instance of a model*/
AzureIoTClient 17:fa1bba4c6053 807 /*some constituents of the model need to be initialized - ascii_char_ptr for example should be set to NULL*/
AzureIoTClient 17:fa1bba4c6053 808
AzureIoTClient 17:fa1bba4c6053 809 size_t nDesiredProperties;
AzureIoTClient 17:fa1bba4c6053 810 if (Schema_GetModelDesiredPropertyCount(model, &nDesiredProperties) != SCHEMA_OK)
AzureIoTClient 17:fa1bba4c6053 811 {
AzureIoTClient 17:fa1bba4c6053 812 LogError("unexpected error in Schema_GetModelDesiredPropertyCount");
AzureIoTClient 17:fa1bba4c6053 813 }
AzureIoTClient 17:fa1bba4c6053 814 else
AzureIoTClient 17:fa1bba4c6053 815 {
AzureIoTClient 17:fa1bba4c6053 816 size_t nProcessedDesiredProperties = 0;
AzureIoTClient 17:fa1bba4c6053 817 for (size_t i = 0;i < nDesiredProperties;i++)
AzureIoTClient 17:fa1bba4c6053 818 {
AzureIoTClient 17:fa1bba4c6053 819 SCHEMA_DESIRED_PROPERTY_HANDLE desiredPropertyHandle = Schema_GetModelDesiredPropertyByIndex(model, i);
AzureIoTClient 17:fa1bba4c6053 820 if (desiredPropertyHandle == NULL)
AzureIoTClient 17:fa1bba4c6053 821 {
AzureIoTClient 17:fa1bba4c6053 822 LogError("unexpected error in Schema_GetModelDesiredPropertyByIndex");
AzureIoTClient 17:fa1bba4c6053 823 i = nDesiredProperties;
AzureIoTClient 17:fa1bba4c6053 824 }
AzureIoTClient 17:fa1bba4c6053 825 else
AzureIoTClient 17:fa1bba4c6053 826 {
AzureIoTClient 17:fa1bba4c6053 827 pfDesiredPropertyInitialize desiredPropertyInitialize = Schema_GetModelDesiredProperty_pfDesiredPropertyInitialize(desiredPropertyHandle);
AzureIoTClient 17:fa1bba4c6053 828 if (desiredPropertyInitialize == NULL)
AzureIoTClient 17:fa1bba4c6053 829 {
AzureIoTClient 17:fa1bba4c6053 830 LogError("unexpected error in Schema_GetModelDesiredProperty_pfDesiredPropertyInitialize");
AzureIoTClient 17:fa1bba4c6053 831 i = nDesiredProperties;
AzureIoTClient 17:fa1bba4c6053 832 }
AzureIoTClient 17:fa1bba4c6053 833 else
AzureIoTClient 17:fa1bba4c6053 834 {
AzureIoTClient 17:fa1bba4c6053 835 /*Codes_SRS_CODEFIRST_02_036: [ CodeFirst_CreateDevice shall initialize all the desired properties to their default values. ]*/
AzureIoTClient 17:fa1bba4c6053 836 size_t offset = Schema_GetModelDesiredProperty_offset(desiredPropertyHandle);
AzureIoTClient 17:fa1bba4c6053 837 desiredPropertyInitialize((char*)destination + offset);
AzureIoTClient 17:fa1bba4c6053 838 nProcessedDesiredProperties++;
AzureIoTClient 17:fa1bba4c6053 839 }
AzureIoTClient 17:fa1bba4c6053 840 }
AzureIoTClient 17:fa1bba4c6053 841 }
AzureIoTClient 17:fa1bba4c6053 842
AzureIoTClient 17:fa1bba4c6053 843 if (nDesiredProperties == nProcessedDesiredProperties)
AzureIoTClient 17:fa1bba4c6053 844 {
AzureIoTClient 17:fa1bba4c6053 845 /*recursively go in the model and initialize the other fields*/
AzureIoTClient 17:fa1bba4c6053 846 size_t nModelInModel;
AzureIoTClient 17:fa1bba4c6053 847 if (Schema_GetModelModelCount(model, &nModelInModel) != SCHEMA_OK)
AzureIoTClient 17:fa1bba4c6053 848 {
AzureIoTClient 17:fa1bba4c6053 849 LogError("unexpected error in Schema_GetModelModelCount");
AzureIoTClient 17:fa1bba4c6053 850 }
AzureIoTClient 17:fa1bba4c6053 851 else
AzureIoTClient 17:fa1bba4c6053 852 {
AzureIoTClient 17:fa1bba4c6053 853 size_t nProcessedModelInModel = 0;
AzureIoTClient 17:fa1bba4c6053 854 for (size_t i = 0; i < nModelInModel;i++)
AzureIoTClient 17:fa1bba4c6053 855 {
AzureIoTClient 17:fa1bba4c6053 856 SCHEMA_MODEL_TYPE_HANDLE modelInModel = Schema_GetModelModelyByIndex(model, i);
AzureIoTClient 17:fa1bba4c6053 857 if (modelInModel == NULL)
AzureIoTClient 17:fa1bba4c6053 858 {
AzureIoTClient 17:fa1bba4c6053 859 LogError("unexpected failure in Schema_GetModelModelyByIndex");
AzureIoTClient 17:fa1bba4c6053 860 i = nModelInModel;
AzureIoTClient 17:fa1bba4c6053 861 }
AzureIoTClient 17:fa1bba4c6053 862 else
AzureIoTClient 17:fa1bba4c6053 863 {
AzureIoTClient 17:fa1bba4c6053 864 size_t offset = Schema_GetModelModelByIndex_Offset(model, i);
AzureIoTClient 17:fa1bba4c6053 865 initializeDesiredProperties(modelInModel, (char*)destination + offset);
AzureIoTClient 17:fa1bba4c6053 866 nProcessedModelInModel++;
AzureIoTClient 17:fa1bba4c6053 867 }
AzureIoTClient 17:fa1bba4c6053 868 }
AzureIoTClient 17:fa1bba4c6053 869
AzureIoTClient 17:fa1bba4c6053 870 if (nProcessedModelInModel == nModelInModel)
AzureIoTClient 17:fa1bba4c6053 871 {
AzureIoTClient 17:fa1bba4c6053 872 /*all is fine... */
AzureIoTClient 17:fa1bba4c6053 873 }
AzureIoTClient 17:fa1bba4c6053 874 }
AzureIoTClient 17:fa1bba4c6053 875 }
AzureIoTClient 17:fa1bba4c6053 876 }
AzureIoTClient 17:fa1bba4c6053 877 }
AzureIoTClient 17:fa1bba4c6053 878
AzureIoTClient 0:1f9b2707ec7d 879 /* Codes_SRS_CODEFIRST_99_079:[CodeFirst_CreateDevice shall create a device and allocate a memory block that should hold the device data.] */
AzureIoTClient 0:1f9b2707ec7d 880 void* CodeFirst_CreateDevice(SCHEMA_MODEL_TYPE_HANDLE model, const REFLECTED_DATA_FROM_DATAPROVIDER* metadata, size_t dataSize, bool includePropertyPath)
AzureIoTClient 0:1f9b2707ec7d 881 {
AzureIoTClient 0:1f9b2707ec7d 882 void* result;
AzureIoTClient 0:1f9b2707ec7d 883 DEVICE_HEADER_DATA* deviceHeader;
AzureIoTClient 0:1f9b2707ec7d 884
AzureIoTClient 0:1f9b2707ec7d 885 /* Codes_SRS_CODEFIRST_99_080:[If CodeFirst_CreateDevice is invoked with a NULL model, it shall return NULL.]*/
AzureIoTClient 22:422d94bd3c18 886 if (model == NULL)
AzureIoTClient 0:1f9b2707ec7d 887 {
AzureIoTClient 0:1f9b2707ec7d 888 result = NULL;
AzureIoTClient 11:b1327861f5e0 889 LogError(" %s ", ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_INVALID_ARG));
AzureIoTClient 0:1f9b2707ec7d 890 }
AzureIoTClient 0:1f9b2707ec7d 891 else
AzureIoTClient 0:1f9b2707ec7d 892 {
AzureIoTClient 17:fa1bba4c6053 893 /*Codes_SRS_CODEFIRST_02_037: [ CodeFirst_CreateDevice shall call CodeFirst_Init, passing NULL for overrideSchemaNamespace. ]*/
AzureIoTClient 17:fa1bba4c6053 894 (void)CodeFirst_Init_impl(NULL, false); /*lazy init*/
AzureIoTClient 36:7d12a5386197 895
AzureIoTClient 17:fa1bba4c6053 896 if ((deviceHeader = (DEVICE_HEADER_DATA*)malloc(sizeof(DEVICE_HEADER_DATA))) == NULL)
AzureIoTClient 0:1f9b2707ec7d 897 {
AzureIoTClient 17:fa1bba4c6053 898 /* Codes_SRS_CODEFIRST_99_102:[On any other errors, Device_Create shall return NULL.] */
AzureIoTClient 0:1f9b2707ec7d 899 result = NULL;
AzureIoTClient 11:b1327861f5e0 900 LogError(" %s ", ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_ERROR));
AzureIoTClient 0:1f9b2707ec7d 901 }
AzureIoTClient 17:fa1bba4c6053 902 /* Codes_SRS_CODEFIRST_99_081:[CodeFirst_CreateDevice shall use Device_Create to create a device handle.] */
Azure.IoT.Build 18:58b667752399 903 /* Codes_SRS_CODEFIRST_99_082: [ CodeFirst_CreateDevice shall pass to Device_Create the function CodeFirst_InvokeAction, action callback argument and the CodeFirst_InvokeMethod ] */
AzureIoTClient 0:1f9b2707ec7d 904 else
AzureIoTClient 0:1f9b2707ec7d 905 {
AzureIoTClient 17:fa1bba4c6053 906 if ((deviceHeader->data = malloc(dataSize)) == NULL)
AzureIoTClient 0:1f9b2707ec7d 907 {
AzureIoTClient 0:1f9b2707ec7d 908 free(deviceHeader);
AzureIoTClient 17:fa1bba4c6053 909 deviceHeader = NULL;
AzureIoTClient 0:1f9b2707ec7d 910 result = NULL;
AzureIoTClient 11:b1327861f5e0 911 LogError(" %s ", ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_ERROR));
AzureIoTClient 0:1f9b2707ec7d 912 }
AzureIoTClient 0:1f9b2707ec7d 913 else
AzureIoTClient 0:1f9b2707ec7d 914 {
AzureIoTClient 17:fa1bba4c6053 915 DEVICE_HEADER_DATA** newDevices;
AzureIoTClient 17:fa1bba4c6053 916
AzureIoTClient 17:fa1bba4c6053 917 initializeDesiredProperties(model, deviceHeader->data);
AzureIoTClient 17:fa1bba4c6053 918
AzureIoTClient 36:7d12a5386197 919 if (Device_Create(model, CodeFirst_InvokeAction, deviceHeader, CodeFirst_InvokeMethod, deviceHeader,
AzureIoTClient 17:fa1bba4c6053 920 includePropertyPath, &deviceHeader->DeviceHandle) != DEVICE_OK)
AzureIoTClient 17:fa1bba4c6053 921 {
AzureIoTClient 17:fa1bba4c6053 922 free(deviceHeader->data);
AzureIoTClient 17:fa1bba4c6053 923 free(deviceHeader);
AzureIoTClient 17:fa1bba4c6053 924
AzureIoTClient 17:fa1bba4c6053 925 /* Codes_SRS_CODEFIRST_99_084:[If Device_Create fails, CodeFirst_CreateDevice shall return NULL.] */
AzureIoTClient 17:fa1bba4c6053 926 result = NULL;
AzureIoTClient 17:fa1bba4c6053 927 LogError(" %s ", ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_DEVICE_FAILED));
AzureIoTClient 17:fa1bba4c6053 928 }
AzureIoTClient 17:fa1bba4c6053 929 else if ((newDevices = (DEVICE_HEADER_DATA**)realloc(g_Devices, sizeof(DEVICE_HEADER_DATA*) * (g_DeviceCount + 1))) == NULL)
AzureIoTClient 0:1f9b2707ec7d 930 {
AzureIoTClient 0:1f9b2707ec7d 931 Device_Destroy(deviceHeader->DeviceHandle);
AzureIoTClient 0:1f9b2707ec7d 932 free(deviceHeader->data);
AzureIoTClient 0:1f9b2707ec7d 933 free(deviceHeader);
AzureIoTClient 0:1f9b2707ec7d 934
AzureIoTClient 0:1f9b2707ec7d 935 /* Codes_SRS_CODEFIRST_99_102:[On any other errors, Device_Create shall return NULL.] */
AzureIoTClient 0:1f9b2707ec7d 936 result = NULL;
AzureIoTClient 17:fa1bba4c6053 937 LogError(" %s ", ENUM_TO_STRING(CODEFIRST_RESULT, CODEFIRST_ERROR));
AzureIoTClient 0:1f9b2707ec7d 938 }
AzureIoTClient 0:1f9b2707ec7d 939 else
AzureIoTClient 0:1f9b2707ec7d 940 {
AzureIoTClient 17:fa1bba4c6053 941 SCHEMA_RESULT schemaResult;
AzureIoTClient 17:fa1bba4c6053 942 deviceHeader->ReflectedData = metadata;
AzureIoTClient 17:fa1bba4c6053 943 deviceHeader->DataSize = dataSize;
AzureIoTClient 17:fa1bba4c6053 944 deviceHeader->ModelHandle = model;
AzureIoTClient 17:fa1bba4c6053 945 schemaResult = Schema_AddDeviceRef(model);
AzureIoTClient 17:fa1bba4c6053 946 if (schemaResult != SCHEMA_OK)
AzureIoTClient 17:fa1bba4c6053 947 {
AzureIoTClient 17:fa1bba4c6053 948 Device_Destroy(deviceHeader->DeviceHandle);
AzureIoTClient 36:7d12a5386197 949 free(newDevices);
AzureIoTClient 17:fa1bba4c6053 950 free(deviceHeader->data);
AzureIoTClient 17:fa1bba4c6053 951 free(deviceHeader);
AzureIoTClient 0:1f9b2707ec7d 952
AzureIoTClient 17:fa1bba4c6053 953 /* Codes_SRS_CODEFIRST_99_102:[On any other errors, Device_Create shall return NULL.] */
AzureIoTClient 17:fa1bba4c6053 954 result = NULL;
AzureIoTClient 17:fa1bba4c6053 955 }
AzureIoTClient 17:fa1bba4c6053 956 else
AzureIoTClient 17:fa1bba4c6053 957 {
AzureIoTClient 17:fa1bba4c6053 958 g_Devices = newDevices;
AzureIoTClient 17:fa1bba4c6053 959 g_Devices[g_DeviceCount] = deviceHeader;
AzureIoTClient 17:fa1bba4c6053 960 g_DeviceCount++;
AzureIoTClient 17:fa1bba4c6053 961
AzureIoTClient 17:fa1bba4c6053 962 /* Codes_SRS_CODEFIRST_99_101:[On success, CodeFirst_CreateDevice shall return a non NULL pointer to the device data.] */
AzureIoTClient 17:fa1bba4c6053 963 result = deviceHeader->data;
AzureIoTClient 17:fa1bba4c6053 964 }
AzureIoTClient 0:1f9b2707ec7d 965 }
AzureIoTClient 0:1f9b2707ec7d 966 }
AzureIoTClient 0:1f9b2707ec7d 967 }
AzureIoTClient 36:7d12a5386197 968
AzureIoTClient 0:1f9b2707ec7d 969 }
AzureIoTClient 0:1f9b2707ec7d 970
AzureIoTClient 0:1f9b2707ec7d 971 return result;
AzureIoTClient 0:1f9b2707ec7d 972 }
AzureIoTClient 0:1f9b2707ec7d 973
AzureIoTClient 0:1f9b2707ec7d 974 void CodeFirst_DestroyDevice(void* device)
AzureIoTClient 0:1f9b2707ec7d 975 {
AzureIoTClient 0:1f9b2707ec7d 976 /* Codes_SRS_CODEFIRST_99_086:[If the argument is NULL, CodeFirst_DestroyDevice shall do nothing.] */
AzureIoTClient 0:1f9b2707ec7d 977 if (device != NULL)
AzureIoTClient 0:1f9b2707ec7d 978 {
AzureIoTClient 0:1f9b2707ec7d 979 size_t i;
AzureIoTClient 0:1f9b2707ec7d 980
AzureIoTClient 0:1f9b2707ec7d 981 for (i = 0; i < g_DeviceCount; i++)
AzureIoTClient 0:1f9b2707ec7d 982 {
AzureIoTClient 0:1f9b2707ec7d 983 if (g_Devices[i]->data == device)
AzureIoTClient 0:1f9b2707ec7d 984 {
AzureIoTClient 17:fa1bba4c6053 985 deinitializeDesiredProperties(g_Devices[i]->ModelHandle, g_Devices[i]->data);
AzureIoTClient 0:1f9b2707ec7d 986 Schema_ReleaseDeviceRef(g_Devices[i]->ModelHandle);
AzureIoTClient 0:1f9b2707ec7d 987
AzureIoTClient 0:1f9b2707ec7d 988 // Delete the Created Schema if all the devices are unassociated
AzureIoTClient 0:1f9b2707ec7d 989 Schema_DestroyIfUnused(g_Devices[i]->ModelHandle);
AzureIoTClient 0:1f9b2707ec7d 990
AzureIoTClient 0:1f9b2707ec7d 991 DestroyDevice(g_Devices[i]);
AzureIoTClient 22:422d94bd3c18 992 (void)memcpy(&g_Devices[i], &g_Devices[i + 1], (g_DeviceCount - i - 1) * sizeof(DEVICE_HEADER_DATA*));
AzureIoTClient 0:1f9b2707ec7d 993 g_DeviceCount--;
AzureIoTClient 0:1f9b2707ec7d 994 break;
AzureIoTClient 0:1f9b2707ec7d 995 }
AzureIoTClient 0:1f9b2707ec7d 996 }
AzureIoTClient 17:fa1bba4c6053 997
AzureIoTClient 17:fa1bba4c6053 998 /*Codes_SRS_CODEFIRST_02_039: [ If the current device count is zero then CodeFirst_DestroyDevice shall deallocate all other used resources. ]*/
AzureIoTClient 17:fa1bba4c6053 999 if ((g_state == CODEFIRST_STATE_INIT_BY_API) && (g_DeviceCount == 0))
AzureIoTClient 17:fa1bba4c6053 1000 {
AzureIoTClient 17:fa1bba4c6053 1001 free(g_Devices);
AzureIoTClient 17:fa1bba4c6053 1002 g_Devices = NULL;
AzureIoTClient 17:fa1bba4c6053 1003 g_state = CODEFIRST_STATE_NOT_INIT;
AzureIoTClient 17:fa1bba4c6053 1004 }
AzureIoTClient 0:1f9b2707ec7d 1005 }
AzureIoTClient 0:1f9b2707ec7d 1006 }
AzureIoTClient 0:1f9b2707ec7d 1007
AzureIoTClient 0:1f9b2707ec7d 1008 static DEVICE_HEADER_DATA* FindDevice(void* value)
AzureIoTClient 0:1f9b2707ec7d 1009 {
AzureIoTClient 0:1f9b2707ec7d 1010 size_t i;
AzureIoTClient 0:1f9b2707ec7d 1011 DEVICE_HEADER_DATA* result = NULL;
AzureIoTClient 0:1f9b2707ec7d 1012
AzureIoTClient 0:1f9b2707ec7d 1013 for (i = 0; i < g_DeviceCount; i++)
AzureIoTClient 0:1f9b2707ec7d 1014 {
AzureIoTClient 0:1f9b2707ec7d 1015 if ((g_Devices[i]->data <= (unsigned char*)value) &&
AzureIoTClient 0:1f9b2707ec7d 1016 (g_Devices[i]->data + g_Devices[i]->DataSize > (unsigned char*)value))
AzureIoTClient 0:1f9b2707ec7d 1017 {
AzureIoTClient 0:1f9b2707ec7d 1018 result = g_Devices[i];
AzureIoTClient 0:1f9b2707ec7d 1019 break;
AzureIoTClient 0:1f9b2707ec7d 1020 }
AzureIoTClient 0:1f9b2707ec7d 1021 }
AzureIoTClient 0:1f9b2707ec7d 1022
AzureIoTClient 0:1f9b2707ec7d 1023 return result;
AzureIoTClient 0:1f9b2707ec7d 1024 }
AzureIoTClient 0:1f9b2707ec7d 1025
AzureIoTClient 0:1f9b2707ec7d 1026 static const REFLECTED_SOMETHING* FindValue(DEVICE_HEADER_DATA* deviceHeader, void* value, const char* modelName, size_t startOffset, STRING_HANDLE valuePath)
AzureIoTClient 0:1f9b2707ec7d 1027 {
AzureIoTClient 0:1f9b2707ec7d 1028 const REFLECTED_SOMETHING* result;
AzureIoTClient 0:1f9b2707ec7d 1029 size_t valueOffset = (size_t)((unsigned char*)value - (unsigned char*)deviceHeader->data) - startOffset;
AzureIoTClient 0:1f9b2707ec7d 1030
AzureIoTClient 0:1f9b2707ec7d 1031 for (result = deviceHeader->ReflectedData->reflectedData; result != NULL; result = result->next)
AzureIoTClient 0:1f9b2707ec7d 1032 {
AzureIoTClient 0:1f9b2707ec7d 1033 if (result->type == REFLECTION_PROPERTY_TYPE &&
AzureIoTClient 0:1f9b2707ec7d 1034 (strcmp(result->what.property.modelName, modelName) == 0) &&
AzureIoTClient 0:1f9b2707ec7d 1035 (result->what.property.offset <= valueOffset) &&
AzureIoTClient 0:1f9b2707ec7d 1036 (result->what.property.offset + result->what.property.size > valueOffset))
AzureIoTClient 0:1f9b2707ec7d 1037 {
AzureIoTClient 0:1f9b2707ec7d 1038 if (startOffset != 0)
AzureIoTClient 0:1f9b2707ec7d 1039 {
AzureIoTClient 0:1f9b2707ec7d 1040 STRING_concat(valuePath, "/");
AzureIoTClient 0:1f9b2707ec7d 1041 }
AzureIoTClient 0:1f9b2707ec7d 1042
AzureIoTClient 0:1f9b2707ec7d 1043 STRING_concat(valuePath, result->what.property.name);
AzureIoTClient 0:1f9b2707ec7d 1044 break;
AzureIoTClient 0:1f9b2707ec7d 1045 }
AzureIoTClient 0:1f9b2707ec7d 1046 }
AzureIoTClient 0:1f9b2707ec7d 1047
AzureIoTClient 0:1f9b2707ec7d 1048 if (result != NULL)
AzureIoTClient 0:1f9b2707ec7d 1049 {
AzureIoTClient 0:1f9b2707ec7d 1050 /* Codes_SRS_CODEFIRST_99_133:[CodeFirst_SendAsync shall allow sending of properties that are part of a child model.] */
AzureIoTClient 0:1f9b2707ec7d 1051 if (result->what.property.offset < valueOffset)
AzureIoTClient 0:1f9b2707ec7d 1052 {
AzureIoTClient 0:1f9b2707ec7d 1053 /* find recursively the property in the inner model, if there is one */
AzureIoTClient 0:1f9b2707ec7d 1054 result = FindValue(deviceHeader, value, result->what.property.type, startOffset + result->what.property.offset, valuePath);
AzureIoTClient 0:1f9b2707ec7d 1055 }
AzureIoTClient 0:1f9b2707ec7d 1056 }
AzureIoTClient 0:1f9b2707ec7d 1057
AzureIoTClient 0:1f9b2707ec7d 1058 return result;
AzureIoTClient 0:1f9b2707ec7d 1059 }
AzureIoTClient 0:1f9b2707ec7d 1060
AzureIoTClient 17:fa1bba4c6053 1061 static const REFLECTED_SOMETHING* FindReportedProperty(DEVICE_HEADER_DATA* deviceHeader, void* value, const char* modelName, size_t startOffset, STRING_HANDLE valuePath)
AzureIoTClient 17:fa1bba4c6053 1062 {
AzureIoTClient 17:fa1bba4c6053 1063 const REFLECTED_SOMETHING* result;
AzureIoTClient 17:fa1bba4c6053 1064 size_t valueOffset = (size_t)((unsigned char*)value - (unsigned char*)deviceHeader->data) - startOffset;
AzureIoTClient 17:fa1bba4c6053 1065
AzureIoTClient 17:fa1bba4c6053 1066 for (result = deviceHeader->ReflectedData->reflectedData; result != NULL; result = result->next)
AzureIoTClient 17:fa1bba4c6053 1067 {
AzureIoTClient 17:fa1bba4c6053 1068 if (result->type == REFLECTION_REPORTED_PROPERTY_TYPE &&
AzureIoTClient 17:fa1bba4c6053 1069 (strcmp(result->what.reportedProperty.modelName, modelName) == 0) &&
AzureIoTClient 17:fa1bba4c6053 1070 (result->what.reportedProperty.offset <= valueOffset) &&
AzureIoTClient 17:fa1bba4c6053 1071 (result->what.reportedProperty.offset + result->what.reportedProperty.size > valueOffset))
AzureIoTClient 17:fa1bba4c6053 1072 {
AzureIoTClient 17:fa1bba4c6053 1073 if (startOffset != 0)
AzureIoTClient 17:fa1bba4c6053 1074 {
AzureIoTClient 17:fa1bba4c6053 1075 if (STRING_concat(valuePath, "/") != 0)
AzureIoTClient 17:fa1bba4c6053 1076 {
AzureIoTClient 17:fa1bba4c6053 1077 LogError("unable to STRING_concat");
AzureIoTClient 17:fa1bba4c6053 1078 result = NULL;
AzureIoTClient 17:fa1bba4c6053 1079 break;
AzureIoTClient 17:fa1bba4c6053 1080 }
AzureIoTClient 17:fa1bba4c6053 1081 }
AzureIoTClient 17:fa1bba4c6053 1082
AzureIoTClient 17:fa1bba4c6053 1083 if (STRING_concat(valuePath, result->what.reportedProperty.name) != 0)
AzureIoTClient 17:fa1bba4c6053 1084 {
AzureIoTClient 17:fa1bba4c6053 1085 LogError("unable to STRING_concat");
AzureIoTClient 17:fa1bba4c6053 1086 result = NULL;
AzureIoTClient 17:fa1bba4c6053 1087 break;
AzureIoTClient 17:fa1bba4c6053 1088 }
AzureIoTClient 17:fa1bba4c6053 1089 break;
AzureIoTClient 17:fa1bba4c6053 1090 }
AzureIoTClient 17:fa1bba4c6053 1091 }
AzureIoTClient 17:fa1bba4c6053 1092
AzureIoTClient 17:fa1bba4c6053 1093 if (result != NULL)
AzureIoTClient 17:fa1bba4c6053 1094 {
AzureIoTClient 17:fa1bba4c6053 1095 /* Codes_SRS_CODEFIRST_99_133:[CodeFirst_SendAsync shall allow sending of properties that are part of a child model.] */
AzureIoTClient 17:fa1bba4c6053 1096 if (result->what.reportedProperty.offset < valueOffset)
AzureIoTClient 17:fa1bba4c6053 1097 {
AzureIoTClient 17:fa1bba4c6053 1098 /* find recursively the property in the inner model, if there is one */
AzureIoTClient 17:fa1bba4c6053 1099 result = FindReportedProperty(deviceHeader, value, result->what.reportedProperty.type, startOffset + result->what.reportedProperty.offset, valuePath);
AzureIoTClient 17:fa1bba4c6053 1100 }
AzureIoTClient 17:fa1bba4c6053 1101 }
AzureIoTClient 17:fa1bba4c6053 1102
AzureIoTClient 17:fa1bba4c6053 1103 return result;
AzureIoTClient 17:fa1bba4c6053 1104 }
AzureIoTClient 17:fa1bba4c6053 1105
AzureIoTClient 0:1f9b2707ec7d 1106 /* Codes_SRS_CODEFIRST_99_130:[If a pointer to the beginning of a device block is passed to CodeFirst_SendAsync instead of a pointer to a property, CodeFirst_SendAsync shall send all the properties that belong to that device.] */
AzureIoTClient 0:1f9b2707ec7d 1107 /* Codes_SRS_CODEFIRST_99_131:[The properties shall be given to Device as one transaction, as if they were all passed as individual arguments to Code_First.] */
AzureIoTClient 0:1f9b2707ec7d 1108 static CODEFIRST_RESULT SendAllDeviceProperties(DEVICE_HEADER_DATA* deviceHeader, TRANSACTION_HANDLE transaction)
AzureIoTClient 0:1f9b2707ec7d 1109 {
AzureIoTClient 0:1f9b2707ec7d 1110 const char* modelName = Schema_GetModelName(deviceHeader->ModelHandle);
AzureIoTClient 0:1f9b2707ec7d 1111 const REFLECTED_SOMETHING* something;
AzureIoTClient 0:1f9b2707ec7d 1112 unsigned char* deviceAddress = (unsigned char*)deviceHeader->data;
AzureIoTClient 0:1f9b2707ec7d 1113 CODEFIRST_RESULT result = CODEFIRST_OK;
AzureIoTClient 0:1f9b2707ec7d 1114
AzureIoTClient 0:1f9b2707ec7d 1115 for (something = deviceHeader->ReflectedData->reflectedData; something != NULL; something = something->next)
AzureIoTClient 0:1f9b2707ec7d 1116 {
AzureIoTClient 0:1f9b2707ec7d 1117 if ((something->type == REFLECTION_PROPERTY_TYPE) &&
AzureIoTClient 0:1f9b2707ec7d 1118 (strcmp(something->what.property.modelName, modelName) == 0))
AzureIoTClient 0:1f9b2707ec7d 1119 {
AzureIoTClient 0:1f9b2707ec7d 1120 AGENT_DATA_TYPE agentDataType;
AzureIoTClient 0:1f9b2707ec7d 1121
AzureIoTClient 0:1f9b2707ec7d 1122 /* Codes_SRS_CODEFIRST_99_097:[For each value marshalling to AGENT_DATA_TYPE shall be performed.] */
AzureIoTClient 0:1f9b2707ec7d 1123 /* Codes_SRS_CODEFIRST_99_098:[The marshalling shall be done by calling the Create_AGENT_DATA_TYPE_from_Ptr function associated with the property.] */
AzureIoTClient 0:1f9b2707ec7d 1124 if (something->what.property.Create_AGENT_DATA_TYPE_from_Ptr(deviceAddress + something->what.property.offset, &agentDataType) != AGENT_DATA_TYPES_OK)
AzureIoTClient 0:1f9b2707ec7d 1125 {
AzureIoTClient 0:1f9b2707ec7d 1126 /* Codes_SRS_CODEFIRST_99_099:[If Create_AGENT_DATA_TYPE_from_Ptr fails, CodeFirst_SendAsync shall return CODEFIRST_AGENT_DATA_TYPE_ERROR.] */
AzureIoTClient 0:1f9b2707ec7d 1127 result = CODEFIRST_AGENT_DATA_TYPE_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1128 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1129 break;
AzureIoTClient 0:1f9b2707ec7d 1130 }
AzureIoTClient 0:1f9b2707ec7d 1131 else
AzureIoTClient 0:1f9b2707ec7d 1132 {
AzureIoTClient 0:1f9b2707ec7d 1133 /* Codes_SRS_CODEFIRST_99_092:[CodeFirst shall publish each value by using Device_PublishTransacted.] */
AzureIoTClient 0:1f9b2707ec7d 1134 if (Device_PublishTransacted(transaction, something->what.property.name, &agentDataType) != DEVICE_OK)
AzureIoTClient 0:1f9b2707ec7d 1135 {
AzureIoTClient 0:1f9b2707ec7d 1136 Destroy_AGENT_DATA_TYPE(&agentDataType);
AzureIoTClient 0:1f9b2707ec7d 1137
AzureIoTClient 0:1f9b2707ec7d 1138 /* Codes_SRS_CODEFIRST_99_094:[If any Device API fail, CodeFirst_SendAsync shall return CODEFIRST_DEVICE_PUBLISH_FAILED.] */
AzureIoTClient 0:1f9b2707ec7d 1139 result = CODEFIRST_DEVICE_PUBLISH_FAILED;
AzureIoTClient 0:1f9b2707ec7d 1140 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1141 break;
AzureIoTClient 0:1f9b2707ec7d 1142 }
AzureIoTClient 0:1f9b2707ec7d 1143
AzureIoTClient 0:1f9b2707ec7d 1144 Destroy_AGENT_DATA_TYPE(&agentDataType);
AzureIoTClient 0:1f9b2707ec7d 1145 }
AzureIoTClient 0:1f9b2707ec7d 1146 }
AzureIoTClient 0:1f9b2707ec7d 1147 }
AzureIoTClient 0:1f9b2707ec7d 1148
AzureIoTClient 0:1f9b2707ec7d 1149 return result;
AzureIoTClient 0:1f9b2707ec7d 1150 }
AzureIoTClient 0:1f9b2707ec7d 1151
AzureIoTClient 17:fa1bba4c6053 1152 static CODEFIRST_RESULT SendAllDeviceReportedProperties(DEVICE_HEADER_DATA* deviceHeader, REPORTED_PROPERTIES_TRANSACTION_HANDLE transaction)
AzureIoTClient 17:fa1bba4c6053 1153 {
AzureIoTClient 17:fa1bba4c6053 1154 const char* modelName = Schema_GetModelName(deviceHeader->ModelHandle);
AzureIoTClient 17:fa1bba4c6053 1155 const REFLECTED_SOMETHING* something;
AzureIoTClient 17:fa1bba4c6053 1156 unsigned char* deviceAddress = (unsigned char*)deviceHeader->data;
AzureIoTClient 17:fa1bba4c6053 1157 CODEFIRST_RESULT result = CODEFIRST_OK;
AzureIoTClient 17:fa1bba4c6053 1158
AzureIoTClient 17:fa1bba4c6053 1159 for (something = deviceHeader->ReflectedData->reflectedData; something != NULL; something = something->next)
AzureIoTClient 17:fa1bba4c6053 1160 {
AzureIoTClient 17:fa1bba4c6053 1161 if ((something->type == REFLECTION_REPORTED_PROPERTY_TYPE) &&
AzureIoTClient 17:fa1bba4c6053 1162 (strcmp(something->what.reportedProperty.modelName, modelName) == 0))
AzureIoTClient 17:fa1bba4c6053 1163 {
AzureIoTClient 17:fa1bba4c6053 1164 AGENT_DATA_TYPE agentDataType;
AzureIoTClient 17:fa1bba4c6053 1165
AzureIoTClient 17:fa1bba4c6053 1166 if (something->what.reportedProperty.Create_AGENT_DATA_TYPE_from_Ptr(deviceAddress + something->what.reportedProperty.offset, &agentDataType) != AGENT_DATA_TYPES_OK)
AzureIoTClient 17:fa1bba4c6053 1167 {
AzureIoTClient 17:fa1bba4c6053 1168 result = CODEFIRST_AGENT_DATA_TYPE_ERROR;
AzureIoTClient 17:fa1bba4c6053 1169 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1170 break;
AzureIoTClient 17:fa1bba4c6053 1171 }
AzureIoTClient 17:fa1bba4c6053 1172 else
AzureIoTClient 17:fa1bba4c6053 1173 {
AzureIoTClient 17:fa1bba4c6053 1174 if (Device_PublishTransacted_ReportedProperty(transaction, something->what.reportedProperty.name, &agentDataType) != DEVICE_OK)
AzureIoTClient 17:fa1bba4c6053 1175 {
AzureIoTClient 17:fa1bba4c6053 1176 Destroy_AGENT_DATA_TYPE(&agentDataType);
AzureIoTClient 17:fa1bba4c6053 1177 result = CODEFIRST_DEVICE_PUBLISH_FAILED;
AzureIoTClient 17:fa1bba4c6053 1178 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1179 break;
AzureIoTClient 17:fa1bba4c6053 1180 }
AzureIoTClient 17:fa1bba4c6053 1181
AzureIoTClient 17:fa1bba4c6053 1182 Destroy_AGENT_DATA_TYPE(&agentDataType);
AzureIoTClient 17:fa1bba4c6053 1183 }
AzureIoTClient 17:fa1bba4c6053 1184 }
AzureIoTClient 17:fa1bba4c6053 1185 }
AzureIoTClient 17:fa1bba4c6053 1186
AzureIoTClient 17:fa1bba4c6053 1187 return result;
AzureIoTClient 17:fa1bba4c6053 1188 }
AzureIoTClient 17:fa1bba4c6053 1189
AzureIoTClient 17:fa1bba4c6053 1190
AzureIoTClient 0:1f9b2707ec7d 1191 /* Codes_SRS_CODEFIRST_99_088:[CodeFirst_SendAsync shall send to the Device module a set of properties, a destination and a destinationSize.]*/
AzureIoTClient 0:1f9b2707ec7d 1192 CODEFIRST_RESULT CodeFirst_SendAsync(unsigned char** destination, size_t* destinationSize, size_t numProperties, ...)
AzureIoTClient 0:1f9b2707ec7d 1193 {
AzureIoTClient 0:1f9b2707ec7d 1194 CODEFIRST_RESULT result;
AzureIoTClient 0:1f9b2707ec7d 1195 va_list ap;
AzureIoTClient 0:1f9b2707ec7d 1196
AzureIoTClient 0:1f9b2707ec7d 1197 if (
AzureIoTClient 36:7d12a5386197 1198 (numProperties == 0) ||
AzureIoTClient 36:7d12a5386197 1199 (destination == NULL) ||
AzureIoTClient 0:1f9b2707ec7d 1200 (destinationSize == NULL)
AzureIoTClient 0:1f9b2707ec7d 1201 )
AzureIoTClient 0:1f9b2707ec7d 1202 {
AzureIoTClient 0:1f9b2707ec7d 1203 /* Codes_SRS_CODEFIRST_04_002: [If CodeFirst_SendAsync receives destination or destinationSize NULL, CodeFirst_SendAsync shall return Invalid Argument.]*/
AzureIoTClient 0:1f9b2707ec7d 1204 /* Codes_SRS_CODEFIRST_99_103:[If CodeFirst_SendAsync is called with numProperties being zero, CODEFIRST_INVALID_ARG shall be returned.] */
AzureIoTClient 0:1f9b2707ec7d 1205 result = CODEFIRST_INVALID_ARG;
AzureIoTClient 0:1f9b2707ec7d 1206 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1207 }
AzureIoTClient 0:1f9b2707ec7d 1208 else
AzureIoTClient 0:1f9b2707ec7d 1209 {
AzureIoTClient 17:fa1bba4c6053 1210 /*Codes_SRS_CODEFIRST_02_040: [ CodeFirst_SendAsync shall call CodeFirst_Init, passing NULL for overrideSchemaNamespace. ]*/
AzureIoTClient 17:fa1bba4c6053 1211 (void)CodeFirst_Init_impl(NULL, false); /*lazy init*/
AzureIoTClient 36:7d12a5386197 1212
AzureIoTClient 0:1f9b2707ec7d 1213 DEVICE_HEADER_DATA* deviceHeader = NULL;
AzureIoTClient 0:1f9b2707ec7d 1214 size_t i;
AzureIoTClient 0:1f9b2707ec7d 1215 TRANSACTION_HANDLE transaction = NULL;
AzureIoTClient 0:1f9b2707ec7d 1216 result = CODEFIRST_OK;
AzureIoTClient 0:1f9b2707ec7d 1217
AzureIoTClient 0:1f9b2707ec7d 1218 /* Codes_SRS_CODEFIRST_99_105:[The properties are passed as pointers to the memory locations where the data exists in the device block allocated by CodeFirst_CreateDevice.] */
AzureIoTClient 0:1f9b2707ec7d 1219 va_start(ap, numProperties);
AzureIoTClient 0:1f9b2707ec7d 1220
AzureIoTClient 0:1f9b2707ec7d 1221 /* Codes_SRS_CODEFIRST_99_089:[The numProperties argument shall indicate how many properties are to be sent.] */
AzureIoTClient 0:1f9b2707ec7d 1222 for (i = 0; i < numProperties; i++)
AzureIoTClient 0:1f9b2707ec7d 1223 {
AzureIoTClient 0:1f9b2707ec7d 1224 void* value = (void*)va_arg(ap, void*);
AzureIoTClient 0:1f9b2707ec7d 1225
AzureIoTClient 0:1f9b2707ec7d 1226 /* Codes_SRS_CODEFIRST_99_095:[For each value passed to it, CodeFirst_SendAsync shall look up to which device the value belongs.] */
AzureIoTClient 0:1f9b2707ec7d 1227 DEVICE_HEADER_DATA* currentValueDeviceHeader = FindDevice(value);
AzureIoTClient 0:1f9b2707ec7d 1228 if (currentValueDeviceHeader == NULL)
AzureIoTClient 0:1f9b2707ec7d 1229 {
AzureIoTClient 0:1f9b2707ec7d 1230 /* Codes_SRS_CODEFIRST_99_104:[If a property cannot be associated with a device, CodeFirst_SendAsync shall return CODEFIRST_INVALID_ARG.] */
AzureIoTClient 0:1f9b2707ec7d 1231 result = CODEFIRST_INVALID_ARG;
AzureIoTClient 0:1f9b2707ec7d 1232 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1233 break;
AzureIoTClient 0:1f9b2707ec7d 1234 }
AzureIoTClient 0:1f9b2707ec7d 1235 else if ((deviceHeader != NULL) &&
AzureIoTClient 0:1f9b2707ec7d 1236 (currentValueDeviceHeader != deviceHeader))
AzureIoTClient 0:1f9b2707ec7d 1237 {
AzureIoTClient 0:1f9b2707ec7d 1238 /* Codes_SRS_CODEFIRST_99_096:[All values have to belong to the same device, otherwise CodeFirst_SendAsync shall return CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR.] */
AzureIoTClient 0:1f9b2707ec7d 1239 result = CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1240 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1241 break;
AzureIoTClient 0:1f9b2707ec7d 1242 }
AzureIoTClient 0:1f9b2707ec7d 1243 /* Codes_SRS_CODEFIRST_99_090:[All the properties shall be sent together by using the transacted APIs of the device.] */
AzureIoTClient 0:1f9b2707ec7d 1244 /* Codes_SRS_CODEFIRST_99_091:[CodeFirst_SendAsync shall start a transaction by calling Device_StartTransaction.] */
AzureIoTClient 0:1f9b2707ec7d 1245 else if ((deviceHeader == NULL) &&
AzureIoTClient 0:1f9b2707ec7d 1246 ((transaction = Device_StartTransaction(currentValueDeviceHeader->DeviceHandle)) == NULL))
AzureIoTClient 0:1f9b2707ec7d 1247 {
AzureIoTClient 0:1f9b2707ec7d 1248 /* Codes_SRS_CODEFIRST_99_094:[If any Device API fail, CodeFirst_SendAsync shall return CODEFIRST_DEVICE_PUBLISH_FAILED.] */
AzureIoTClient 0:1f9b2707ec7d 1249 result = CODEFIRST_DEVICE_PUBLISH_FAILED;
AzureIoTClient 0:1f9b2707ec7d 1250 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1251 break;
AzureIoTClient 0:1f9b2707ec7d 1252 }
AzureIoTClient 0:1f9b2707ec7d 1253 else
AzureIoTClient 0:1f9b2707ec7d 1254 {
AzureIoTClient 0:1f9b2707ec7d 1255 deviceHeader = currentValueDeviceHeader;
AzureIoTClient 0:1f9b2707ec7d 1256
AzureIoTClient 0:1f9b2707ec7d 1257 if (value == ((unsigned char*)deviceHeader->data))
AzureIoTClient 0:1f9b2707ec7d 1258 {
AzureIoTClient 0:1f9b2707ec7d 1259 /* we got a full device, send all its state data */
AzureIoTClient 0:1f9b2707ec7d 1260 result = SendAllDeviceProperties(deviceHeader, transaction);
AzureIoTClient 0:1f9b2707ec7d 1261 if (result != CODEFIRST_OK)
AzureIoTClient 0:1f9b2707ec7d 1262 {
AzureIoTClient 0:1f9b2707ec7d 1263 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1264 break;
AzureIoTClient 0:1f9b2707ec7d 1265 }
AzureIoTClient 0:1f9b2707ec7d 1266 }
AzureIoTClient 0:1f9b2707ec7d 1267 else
AzureIoTClient 0:1f9b2707ec7d 1268 {
AzureIoTClient 0:1f9b2707ec7d 1269 const REFLECTED_SOMETHING* propertyReflectedData;
AzureIoTClient 0:1f9b2707ec7d 1270 const char* modelName;
AzureIoTClient 0:1f9b2707ec7d 1271 STRING_HANDLE valuePath;
AzureIoTClient 0:1f9b2707ec7d 1272
AzureIoTClient 0:1f9b2707ec7d 1273 if ((valuePath = STRING_new()) == NULL)
AzureIoTClient 0:1f9b2707ec7d 1274 {
AzureIoTClient 0:1f9b2707ec7d 1275 /* Codes_SRS_CODEFIRST_99_134:[If CodeFirst_Notify fails for any other reason it shall return CODEFIRST_ERROR.] */
AzureIoTClient 0:1f9b2707ec7d 1276 result = CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1277 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1278 break;
AzureIoTClient 0:1f9b2707ec7d 1279 }
AzureIoTClient 0:1f9b2707ec7d 1280 else
AzureIoTClient 0:1f9b2707ec7d 1281 {
AzureIoTClient 0:1f9b2707ec7d 1282 if ((modelName = Schema_GetModelName(deviceHeader->ModelHandle)) == NULL)
AzureIoTClient 0:1f9b2707ec7d 1283 {
AzureIoTClient 0:1f9b2707ec7d 1284 /* Codes_SRS_CODEFIRST_99_134:[If CodeFirst_Notify fails for any other reason it shall return CODEFIRST_ERROR.] */
AzureIoTClient 0:1f9b2707ec7d 1285 result = CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1286 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1287 STRING_delete(valuePath);
AzureIoTClient 0:1f9b2707ec7d 1288 break;
AzureIoTClient 0:1f9b2707ec7d 1289 }
AzureIoTClient 0:1f9b2707ec7d 1290 else if ((propertyReflectedData = FindValue(deviceHeader, value, modelName, 0, valuePath)) == NULL)
AzureIoTClient 0:1f9b2707ec7d 1291 {
AzureIoTClient 0:1f9b2707ec7d 1292 /* Codes_SRS_CODEFIRST_99_104:[If a property cannot be associated with a device, CodeFirst_SendAsync shall return CODEFIRST_INVALID_ARG.] */
AzureIoTClient 0:1f9b2707ec7d 1293 result = CODEFIRST_INVALID_ARG;
AzureIoTClient 0:1f9b2707ec7d 1294 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1295 STRING_delete(valuePath);
AzureIoTClient 0:1f9b2707ec7d 1296 break;
AzureIoTClient 0:1f9b2707ec7d 1297 }
AzureIoTClient 0:1f9b2707ec7d 1298 else
AzureIoTClient 0:1f9b2707ec7d 1299 {
AzureIoTClient 0:1f9b2707ec7d 1300 AGENT_DATA_TYPE agentDataType;
AzureIoTClient 0:1f9b2707ec7d 1301
AzureIoTClient 0:1f9b2707ec7d 1302 /* Codes_SRS_CODEFIRST_99_097:[For each value marshalling to AGENT_DATA_TYPE shall be performed.] */
AzureIoTClient 0:1f9b2707ec7d 1303 /* Codes_SRS_CODEFIRST_99_098:[The marshalling shall be done by calling the Create_AGENT_DATA_TYPE_from_Ptr function associated with the property.] */
AzureIoTClient 0:1f9b2707ec7d 1304 if (propertyReflectedData->what.property.Create_AGENT_DATA_TYPE_from_Ptr(value, &agentDataType) != AGENT_DATA_TYPES_OK)
AzureIoTClient 0:1f9b2707ec7d 1305 {
AzureIoTClient 0:1f9b2707ec7d 1306 /* Codes_SRS_CODEFIRST_99_099:[If Create_AGENT_DATA_TYPE_from_Ptr fails, CodeFirst_SendAsync shall return CODEFIRST_AGENT_DATA_TYPE_ERROR.] */
AzureIoTClient 0:1f9b2707ec7d 1307 result = CODEFIRST_AGENT_DATA_TYPE_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1308 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1309 STRING_delete(valuePath);
AzureIoTClient 0:1f9b2707ec7d 1310 break;
AzureIoTClient 0:1f9b2707ec7d 1311 }
AzureIoTClient 0:1f9b2707ec7d 1312 else
AzureIoTClient 0:1f9b2707ec7d 1313 {
AzureIoTClient 0:1f9b2707ec7d 1314 /* Codes_SRS_CODEFIRST_99_092:[CodeFirst shall publish each value by using Device_PublishTransacted.] */
AzureIoTClient 0:1f9b2707ec7d 1315 /* Codes_SRS_CODEFIRST_99_136:[CodeFirst_SendAsync shall build the full path for each property and then pass it to Device_PublishTransacted.] */
AzureIoTClient 0:1f9b2707ec7d 1316 if (Device_PublishTransacted(transaction, STRING_c_str(valuePath), &agentDataType) != DEVICE_OK)
AzureIoTClient 0:1f9b2707ec7d 1317 {
AzureIoTClient 0:1f9b2707ec7d 1318 Destroy_AGENT_DATA_TYPE(&agentDataType);
AzureIoTClient 0:1f9b2707ec7d 1319
AzureIoTClient 0:1f9b2707ec7d 1320 /* Codes_SRS_CODEFIRST_99_094:[If any Device API fail, CodeFirst_SendAsync shall return CODEFIRST_DEVICE_PUBLISH_FAILED.] */
AzureIoTClient 0:1f9b2707ec7d 1321 result = CODEFIRST_DEVICE_PUBLISH_FAILED;
AzureIoTClient 0:1f9b2707ec7d 1322 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1323 STRING_delete(valuePath);
AzureIoTClient 0:1f9b2707ec7d 1324 break;
AzureIoTClient 0:1f9b2707ec7d 1325 }
AzureIoTClient 0:1f9b2707ec7d 1326 else
AzureIoTClient 0:1f9b2707ec7d 1327 {
AzureIoTClient 0:1f9b2707ec7d 1328 STRING_delete(valuePath); /*anyway*/
AzureIoTClient 0:1f9b2707ec7d 1329 }
AzureIoTClient 0:1f9b2707ec7d 1330
AzureIoTClient 0:1f9b2707ec7d 1331 Destroy_AGENT_DATA_TYPE(&agentDataType);
AzureIoTClient 0:1f9b2707ec7d 1332 }
AzureIoTClient 0:1f9b2707ec7d 1333 }
AzureIoTClient 0:1f9b2707ec7d 1334 }
AzureIoTClient 0:1f9b2707ec7d 1335 }
AzureIoTClient 0:1f9b2707ec7d 1336 }
AzureIoTClient 0:1f9b2707ec7d 1337 }
AzureIoTClient 0:1f9b2707ec7d 1338
AzureIoTClient 0:1f9b2707ec7d 1339 if (i < numProperties)
AzureIoTClient 0:1f9b2707ec7d 1340 {
AzureIoTClient 0:1f9b2707ec7d 1341 if (transaction != NULL)
AzureIoTClient 0:1f9b2707ec7d 1342 {
AzureIoTClient 0:1f9b2707ec7d 1343 (void)Device_CancelTransaction(transaction);
AzureIoTClient 0:1f9b2707ec7d 1344 }
AzureIoTClient 0:1f9b2707ec7d 1345 }
AzureIoTClient 0:1f9b2707ec7d 1346 /* Codes_SRS_CODEFIRST_99_093:[After all values have been published, Device_EndTransaction shall be called.] */
AzureIoTClient 0:1f9b2707ec7d 1347 else if (Device_EndTransaction(transaction, destination, destinationSize) != DEVICE_OK)
AzureIoTClient 0:1f9b2707ec7d 1348 {
AzureIoTClient 0:1f9b2707ec7d 1349 /* Codes_SRS_CODEFIRST_99_094:[If any Device API fail, CodeFirst_SendAsync shall return CODEFIRST_DEVICE_PUBLISH_FAILED.] */
AzureIoTClient 0:1f9b2707ec7d 1350 result = CODEFIRST_DEVICE_PUBLISH_FAILED;
AzureIoTClient 0:1f9b2707ec7d 1351 LOG_CODEFIRST_ERROR;
AzureIoTClient 0:1f9b2707ec7d 1352 }
AzureIoTClient 0:1f9b2707ec7d 1353 else
AzureIoTClient 0:1f9b2707ec7d 1354 {
AzureIoTClient 0:1f9b2707ec7d 1355 /* Codes_SRS_CODEFIRST_99_117:[On success, CodeFirst_SendAsync shall return CODEFIRST_OK.] */
AzureIoTClient 0:1f9b2707ec7d 1356 result = CODEFIRST_OK;
AzureIoTClient 0:1f9b2707ec7d 1357 }
AzureIoTClient 0:1f9b2707ec7d 1358
AzureIoTClient 0:1f9b2707ec7d 1359 va_end(ap);
AzureIoTClient 36:7d12a5386197 1360
AzureIoTClient 0:1f9b2707ec7d 1361 }
AzureIoTClient 0:1f9b2707ec7d 1362
AzureIoTClient 0:1f9b2707ec7d 1363 return result;
AzureIoTClient 0:1f9b2707ec7d 1364 }
AzureIoTClient 0:1f9b2707ec7d 1365
AzureIoTClient 17:fa1bba4c6053 1366 CODEFIRST_RESULT CodeFirst_SendAsyncReported(unsigned char** destination, size_t* destinationSize, size_t numReportedProperties, ...)
AzureIoTClient 17:fa1bba4c6053 1367 {
AzureIoTClient 17:fa1bba4c6053 1368 CODEFIRST_RESULT result;
AzureIoTClient 17:fa1bba4c6053 1369 if ((destination == NULL) || (destinationSize == NULL) || numReportedProperties == 0)
AzureIoTClient 17:fa1bba4c6053 1370 {
AzureIoTClient 17:fa1bba4c6053 1371 /*Codes_SRS_CODEFIRST_02_018: [ If parameter destination, destinationSize or any of the values passed through va_args is NULL then CodeFirst_SendAsyncReported shall fail and return CODEFIRST_INVALID_ARG. ]*/
AzureIoTClient 17:fa1bba4c6053 1372 LogError("invalid argument unsigned char** destination=%p, size_t* destinationSize=%p, size_t numReportedProperties=%zu", destination, destinationSize, numReportedProperties);
AzureIoTClient 17:fa1bba4c6053 1373 result = CODEFIRST_INVALID_ARG;
AzureIoTClient 17:fa1bba4c6053 1374 }
AzureIoTClient 17:fa1bba4c6053 1375 else
AzureIoTClient 17:fa1bba4c6053 1376 {
AzureIoTClient 17:fa1bba4c6053 1377 /*Codes_SRS_CODEFIRST_02_046: [ CodeFirst_SendAsyncReported shall call CodeFirst_Init, passing NULL for overrideSchemaNamespace. ]*/
AzureIoTClient 17:fa1bba4c6053 1378 (void)CodeFirst_Init_impl(NULL, false);/*lazy init*/
AzureIoTClient 36:7d12a5386197 1379
AzureIoTClient 17:fa1bba4c6053 1380 DEVICE_HEADER_DATA* deviceHeader = NULL;
AzureIoTClient 17:fa1bba4c6053 1381 size_t i;
AzureIoTClient 17:fa1bba4c6053 1382 REPORTED_PROPERTIES_TRANSACTION_HANDLE transaction = NULL;
AzureIoTClient 17:fa1bba4c6053 1383 va_list ap;
AzureIoTClient 17:fa1bba4c6053 1384 result = CODEFIRST_ACTION_EXECUTION_ERROR; /*this initialization squelches a false warning about result not being initialized*/
AzureIoTClient 17:fa1bba4c6053 1385
AzureIoTClient 17:fa1bba4c6053 1386 va_start(ap, numReportedProperties);
AzureIoTClient 17:fa1bba4c6053 1387
AzureIoTClient 17:fa1bba4c6053 1388 for (i = 0; i < numReportedProperties; i++)
AzureIoTClient 17:fa1bba4c6053 1389 {
AzureIoTClient 17:fa1bba4c6053 1390 void* value = (void*)va_arg(ap, void*);
AzureIoTClient 17:fa1bba4c6053 1391 /*Codes_SRS_CODEFIRST_02_018: [ If parameter destination, destinationSize or any of the values passed through va_args is NULL then CodeFirst_SendAsyncReported shall fail and return CODEFIRST_INVALID_ARG. ]*/
AzureIoTClient 17:fa1bba4c6053 1392 if (value == NULL)
AzureIoTClient 17:fa1bba4c6053 1393 {
AzureIoTClient 17:fa1bba4c6053 1394 LogError("argument number %zu passed through variable arguments is NULL", i);
AzureIoTClient 17:fa1bba4c6053 1395 result = CODEFIRST_INVALID_ARG;
AzureIoTClient 17:fa1bba4c6053 1396 break;
AzureIoTClient 17:fa1bba4c6053 1397 }
AzureIoTClient 17:fa1bba4c6053 1398 else
AzureIoTClient 17:fa1bba4c6053 1399 {
AzureIoTClient 17:fa1bba4c6053 1400 DEVICE_HEADER_DATA* currentValueDeviceHeader = FindDevice(value);
AzureIoTClient 17:fa1bba4c6053 1401 if (currentValueDeviceHeader == NULL)
AzureIoTClient 17:fa1bba4c6053 1402 {
AzureIoTClient 17:fa1bba4c6053 1403 result = CODEFIRST_INVALID_ARG;
AzureIoTClient 17:fa1bba4c6053 1404 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1405 break;
AzureIoTClient 17:fa1bba4c6053 1406 }
AzureIoTClient 17:fa1bba4c6053 1407 /*Codes_SRS_CODEFIRST_02_019: [ If values passed through va_args do not belong to the same device then CodeFirst_SendAsyncReported shall fail and return CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR. ]*/
AzureIoTClient 17:fa1bba4c6053 1408 else if ((deviceHeader != NULL) &&
AzureIoTClient 17:fa1bba4c6053 1409 (currentValueDeviceHeader != deviceHeader))
AzureIoTClient 17:fa1bba4c6053 1410 {
AzureIoTClient 17:fa1bba4c6053 1411 result = CODEFIRST_VALUES_FROM_DIFFERENT_DEVICES_ERROR;
AzureIoTClient 17:fa1bba4c6053 1412 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1413 break;
AzureIoTClient 17:fa1bba4c6053 1414 }
AzureIoTClient 17:fa1bba4c6053 1415 /*Codes_SRS_CODEFIRST_02_022: [ CodeFirst_SendAsyncReported shall start a transaction by calling Device_CreateTransaction_ReportedProperties. ]*/
AzureIoTClient 17:fa1bba4c6053 1416 else if ((deviceHeader == NULL) &&
AzureIoTClient 17:fa1bba4c6053 1417 ((transaction = Device_CreateTransaction_ReportedProperties(currentValueDeviceHeader->DeviceHandle)) == NULL))
AzureIoTClient 17:fa1bba4c6053 1418 {
AzureIoTClient 17:fa1bba4c6053 1419 result = CODEFIRST_DEVICE_PUBLISH_FAILED;
AzureIoTClient 17:fa1bba4c6053 1420 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1421 break;
AzureIoTClient 17:fa1bba4c6053 1422 }
AzureIoTClient 17:fa1bba4c6053 1423 else
AzureIoTClient 17:fa1bba4c6053 1424 {
AzureIoTClient 17:fa1bba4c6053 1425 deviceHeader = currentValueDeviceHeader;
AzureIoTClient 17:fa1bba4c6053 1426 if (value == ((unsigned char*)deviceHeader->data))
AzureIoTClient 17:fa1bba4c6053 1427 {
AzureIoTClient 17:fa1bba4c6053 1428 /*Codes_SRS_CODEFIRST_02_021: [ If the value passed through va_args is a complete model instance, then CodeFirst_SendAsyncReported shall send all the reported properties of that device. ]*/
AzureIoTClient 17:fa1bba4c6053 1429 result = SendAllDeviceReportedProperties(deviceHeader, transaction);
AzureIoTClient 17:fa1bba4c6053 1430 if (result != CODEFIRST_OK)
AzureIoTClient 17:fa1bba4c6053 1431 {
AzureIoTClient 17:fa1bba4c6053 1432 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1433 break;
AzureIoTClient 17:fa1bba4c6053 1434 }
AzureIoTClient 17:fa1bba4c6053 1435 }
AzureIoTClient 17:fa1bba4c6053 1436 else
AzureIoTClient 17:fa1bba4c6053 1437 {
AzureIoTClient 17:fa1bba4c6053 1438 /*Codes_SRS_CODEFIRST_02_020: [ If values passed through va_args are not all of type REFLECTED_REPORTED_PROPERTY then CodeFirst_SendAsyncReported shall fail and return CODEFIRST_INVALID_ARG. ]*/
AzureIoTClient 17:fa1bba4c6053 1439 const REFLECTED_SOMETHING* propertyReflectedData;
AzureIoTClient 17:fa1bba4c6053 1440 const char* modelName;
AzureIoTClient 17:fa1bba4c6053 1441
AzureIoTClient 17:fa1bba4c6053 1442 STRING_HANDLE valuePath;
AzureIoTClient 17:fa1bba4c6053 1443 if ((valuePath = STRING_new()) == NULL)
AzureIoTClient 17:fa1bba4c6053 1444 {
AzureIoTClient 17:fa1bba4c6053 1445 result = CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1446 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1447 break;
AzureIoTClient 17:fa1bba4c6053 1448 }
AzureIoTClient 17:fa1bba4c6053 1449 else
AzureIoTClient 17:fa1bba4c6053 1450 {
AzureIoTClient 17:fa1bba4c6053 1451 modelName = Schema_GetModelName(deviceHeader->ModelHandle);
AzureIoTClient 17:fa1bba4c6053 1452
AzureIoTClient 17:fa1bba4c6053 1453 /*Codes_SRS_CODEFIRST_02_025: [ CodeFirst_SendAsyncReported shall compute for every AGENT_DATA_TYPE the valuePath. ]*/
AzureIoTClient 17:fa1bba4c6053 1454 if ((propertyReflectedData = FindReportedProperty(deviceHeader, value, modelName, 0, valuePath)) == NULL)
AzureIoTClient 17:fa1bba4c6053 1455 {
AzureIoTClient 17:fa1bba4c6053 1456 result = CODEFIRST_INVALID_ARG;
AzureIoTClient 17:fa1bba4c6053 1457 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1458 STRING_delete(valuePath);
AzureIoTClient 17:fa1bba4c6053 1459 break;
AzureIoTClient 17:fa1bba4c6053 1460 }
AzureIoTClient 17:fa1bba4c6053 1461 else
AzureIoTClient 17:fa1bba4c6053 1462 {
AzureIoTClient 17:fa1bba4c6053 1463 AGENT_DATA_TYPE agentDataType;
AzureIoTClient 17:fa1bba4c6053 1464 /*Codes_SRS_CODEFIRST_02_023: [ CodeFirst_SendAsyncReported shall convert all REPORTED_PROPERTY model components to AGENT_DATA_TYPE. ]*/
AzureIoTClient 17:fa1bba4c6053 1465 if (propertyReflectedData->what.reportedProperty.Create_AGENT_DATA_TYPE_from_Ptr(value, &agentDataType) != AGENT_DATA_TYPES_OK)
AzureIoTClient 17:fa1bba4c6053 1466 {
AzureIoTClient 17:fa1bba4c6053 1467 result = CODEFIRST_AGENT_DATA_TYPE_ERROR;
AzureIoTClient 17:fa1bba4c6053 1468 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1469 STRING_delete(valuePath);
AzureIoTClient 17:fa1bba4c6053 1470 break;
AzureIoTClient 17:fa1bba4c6053 1471 }
AzureIoTClient 17:fa1bba4c6053 1472 else
AzureIoTClient 17:fa1bba4c6053 1473 {
AzureIoTClient 17:fa1bba4c6053 1474 /*Codes_SRS_CODEFIRST_02_024: [ CodeFirst_SendAsyncReported shall call Device_PublishTransacted_ReportedProperty for every AGENT_DATA_TYPE converted from REPORTED_PROPERTY. ]*/
AzureIoTClient 17:fa1bba4c6053 1475 if (Device_PublishTransacted_ReportedProperty(transaction, STRING_c_str(valuePath), &agentDataType) != DEVICE_OK)
AzureIoTClient 17:fa1bba4c6053 1476 {
AzureIoTClient 17:fa1bba4c6053 1477 Destroy_AGENT_DATA_TYPE(&agentDataType);
AzureIoTClient 17:fa1bba4c6053 1478 result = CODEFIRST_DEVICE_PUBLISH_FAILED;
AzureIoTClient 17:fa1bba4c6053 1479 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1480 STRING_delete(valuePath);
AzureIoTClient 17:fa1bba4c6053 1481 break;
AzureIoTClient 17:fa1bba4c6053 1482 }
AzureIoTClient 17:fa1bba4c6053 1483 else
AzureIoTClient 17:fa1bba4c6053 1484 {
AzureIoTClient 17:fa1bba4c6053 1485 STRING_delete(valuePath);
AzureIoTClient 17:fa1bba4c6053 1486 }
AzureIoTClient 17:fa1bba4c6053 1487 Destroy_AGENT_DATA_TYPE(&agentDataType);
AzureIoTClient 17:fa1bba4c6053 1488 }
AzureIoTClient 17:fa1bba4c6053 1489 }
AzureIoTClient 17:fa1bba4c6053 1490 }
AzureIoTClient 17:fa1bba4c6053 1491 }
AzureIoTClient 17:fa1bba4c6053 1492 }
AzureIoTClient 17:fa1bba4c6053 1493 }
AzureIoTClient 17:fa1bba4c6053 1494 }
AzureIoTClient 17:fa1bba4c6053 1495
AzureIoTClient 17:fa1bba4c6053 1496 /*Codes_SRS_CODEFIRST_02_027: [ If any error occurs, CodeFirst_SendAsyncReported shall fail and return CODEFIRST_ERROR. ]*/
AzureIoTClient 17:fa1bba4c6053 1497 if (i < numReportedProperties)
AzureIoTClient 17:fa1bba4c6053 1498 {
AzureIoTClient 17:fa1bba4c6053 1499 if (transaction != NULL)
AzureIoTClient 17:fa1bba4c6053 1500 {
AzureIoTClient 17:fa1bba4c6053 1501 Device_DestroyTransaction_ReportedProperties(transaction);
AzureIoTClient 17:fa1bba4c6053 1502 }
AzureIoTClient 17:fa1bba4c6053 1503 }
AzureIoTClient 17:fa1bba4c6053 1504 /*Codes_SRS_CODEFIRST_02_026: [ CodeFirst_SendAsyncReported shall call Device_CommitTransaction_ReportedProperties to commit the transaction. ]*/
AzureIoTClient 17:fa1bba4c6053 1505 else
AzureIoTClient 17:fa1bba4c6053 1506 {
AzureIoTClient 17:fa1bba4c6053 1507 if (Device_CommitTransaction_ReportedProperties(transaction, destination, destinationSize) != DEVICE_OK)
AzureIoTClient 17:fa1bba4c6053 1508 {
AzureIoTClient 17:fa1bba4c6053 1509 result = CODEFIRST_DEVICE_PUBLISH_FAILED;
AzureIoTClient 17:fa1bba4c6053 1510 LOG_CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1511 }
AzureIoTClient 17:fa1bba4c6053 1512 else
AzureIoTClient 17:fa1bba4c6053 1513 {
AzureIoTClient 17:fa1bba4c6053 1514 /*Codes_SRS_CODEFIRST_02_028: [ CodeFirst_SendAsyncReported shall return CODEFIRST_OK when it succeeds. ]*/
AzureIoTClient 17:fa1bba4c6053 1515 result = CODEFIRST_OK;
AzureIoTClient 17:fa1bba4c6053 1516 }
AzureIoTClient 17:fa1bba4c6053 1517
AzureIoTClient 17:fa1bba4c6053 1518 /*Codes_SRS_CODEFIRST_02_029: [ CodeFirst_SendAsyncReported shall call Device_DestroyTransaction_ReportedProperties to destroy the transaction. ]*/
AzureIoTClient 17:fa1bba4c6053 1519 Device_DestroyTransaction_ReportedProperties(transaction);
AzureIoTClient 17:fa1bba4c6053 1520 }
AzureIoTClient 17:fa1bba4c6053 1521
AzureIoTClient 17:fa1bba4c6053 1522 va_end(ap);
AzureIoTClient 17:fa1bba4c6053 1523 }
AzureIoTClient 17:fa1bba4c6053 1524 return result;
AzureIoTClient 17:fa1bba4c6053 1525 }
AzureIoTClient 17:fa1bba4c6053 1526
AzureIoTClient 0:1f9b2707ec7d 1527 EXECUTE_COMMAND_RESULT CodeFirst_ExecuteCommand(void* device, const char* command)
AzureIoTClient 0:1f9b2707ec7d 1528 {
AzureIoTClient 0:1f9b2707ec7d 1529 EXECUTE_COMMAND_RESULT result;
AzureIoTClient 0:1f9b2707ec7d 1530 /*Codes_SRS_CODEFIRST_02_014: [If parameter device or command is NULL then CodeFirst_ExecuteCommand shall return EXECUTE_COMMAND_ERROR.] */
AzureIoTClient 0:1f9b2707ec7d 1531 if (
AzureIoTClient 0:1f9b2707ec7d 1532 (device == NULL) ||
AzureIoTClient 0:1f9b2707ec7d 1533 (command == NULL)
AzureIoTClient 0:1f9b2707ec7d 1534 )
AzureIoTClient 0:1f9b2707ec7d 1535 {
AzureIoTClient 0:1f9b2707ec7d 1536 result = EXECUTE_COMMAND_ERROR;
AzureIoTClient 11:b1327861f5e0 1537 LogError("invalid argument (NULL) passed to CodeFirst_ExecuteCommand void* device = %p, const char* command = %p", device, command);
AzureIoTClient 0:1f9b2707ec7d 1538 }
AzureIoTClient 0:1f9b2707ec7d 1539 else
AzureIoTClient 0:1f9b2707ec7d 1540 {
AzureIoTClient 0:1f9b2707ec7d 1541 /*Codes_SRS_CODEFIRST_02_015: [CodeFirst_ExecuteCommand shall find the device.]*/
AzureIoTClient 0:1f9b2707ec7d 1542 DEVICE_HEADER_DATA* deviceHeader = FindDevice(device);
AzureIoTClient 0:1f9b2707ec7d 1543 if(deviceHeader == NULL)
AzureIoTClient 0:1f9b2707ec7d 1544 {
AzureIoTClient 0:1f9b2707ec7d 1545 /*Codes_SRS_CODEFIRST_02_016: [If finding the device fails, then CodeFirst_ExecuteCommand shall return EXECUTE_COMMAND_ERROR.]*/
AzureIoTClient 0:1f9b2707ec7d 1546 result = EXECUTE_COMMAND_ERROR;
AzureIoTClient 11:b1327861f5e0 1547 LogError("unable to find the device given by address %p", device);
AzureIoTClient 0:1f9b2707ec7d 1548 }
AzureIoTClient 0:1f9b2707ec7d 1549 else
AzureIoTClient 0:1f9b2707ec7d 1550 {
AzureIoTClient 0:1f9b2707ec7d 1551 /*Codes_SRS_CODEFIRST_02_017: [Otherwise CodeFirst_ExecuteCommand shall call Device_ExecuteCommand and return what Device_ExecuteCommand is returning.] */
AzureIoTClient 0:1f9b2707ec7d 1552 result = Device_ExecuteCommand(deviceHeader->DeviceHandle, command);
AzureIoTClient 0:1f9b2707ec7d 1553 }
AzureIoTClient 0:1f9b2707ec7d 1554 }
AzureIoTClient 0:1f9b2707ec7d 1555 return result;
AzureIoTClient 17:fa1bba4c6053 1556 }
AzureIoTClient 17:fa1bba4c6053 1557
Azure.IoT.Build 18:58b667752399 1558 METHODRETURN_HANDLE CodeFirst_ExecuteMethod(void* device, const char* methodName, const char* methodPayload)
Azure.IoT.Build 18:58b667752399 1559 {
Azure.IoT.Build 18:58b667752399 1560 METHODRETURN_HANDLE result;
Azure.IoT.Build 18:58b667752399 1561 if (
Azure.IoT.Build 18:58b667752399 1562 (device == NULL) ||
Azure.IoT.Build 18:58b667752399 1563 (methodName== NULL) /*methodPayload can be NULL*/
Azure.IoT.Build 18:58b667752399 1564 )
Azure.IoT.Build 18:58b667752399 1565 {
Azure.IoT.Build 18:58b667752399 1566 result = NULL;
Azure.IoT.Build 18:58b667752399 1567 LogError("invalid argument (NULL) passed to CodeFirst_ExecuteMethod void* device = %p, const char* methodName = %p", device, methodName);
Azure.IoT.Build 18:58b667752399 1568 }
Azure.IoT.Build 18:58b667752399 1569 else
Azure.IoT.Build 18:58b667752399 1570 {
Azure.IoT.Build 18:58b667752399 1571 DEVICE_HEADER_DATA* deviceHeader = FindDevice(device);
Azure.IoT.Build 18:58b667752399 1572 if (deviceHeader == NULL)
Azure.IoT.Build 18:58b667752399 1573 {
Azure.IoT.Build 18:58b667752399 1574 result = NULL;
Azure.IoT.Build 18:58b667752399 1575 LogError("unable to find the device given by address %p", device);
Azure.IoT.Build 18:58b667752399 1576 }
Azure.IoT.Build 18:58b667752399 1577 else
Azure.IoT.Build 18:58b667752399 1578 {
Azure.IoT.Build 18:58b667752399 1579 result = Device_ExecuteMethod(deviceHeader->DeviceHandle, methodName, methodPayload);
Azure.IoT.Build 18:58b667752399 1580 }
Azure.IoT.Build 18:58b667752399 1581 }
Azure.IoT.Build 18:58b667752399 1582 return result;
Azure.IoT.Build 18:58b667752399 1583 }
Azure.IoT.Build 18:58b667752399 1584
AzureIoTClient 26:7c0e6f86d034 1585 CODEFIRST_RESULT CodeFirst_IngestDesiredProperties(void* device, const char* jsonPayload, bool parseDesiredNode)
AzureIoTClient 17:fa1bba4c6053 1586 {
AzureIoTClient 17:fa1bba4c6053 1587 CODEFIRST_RESULT result;
AzureIoTClient 17:fa1bba4c6053 1588 /*Codes_SRS_CODEFIRST_02_030: [ If argument device is NULL then CodeFirst_IngestDesiredProperties shall fail and return CODEFIRST_INVALID_ARG. ]*/
AzureIoTClient 26:7c0e6f86d034 1589 /*Codes_SRS_CODEFIRST_02_031: [ If argument jsonPayload is NULL then CodeFirst_IngestDesiredProperties shall fail and return CODEFIRST_INVALID_ARG. ]*/
AzureIoTClient 17:fa1bba4c6053 1590 if (
AzureIoTClient 17:fa1bba4c6053 1591 (device == NULL) ||
AzureIoTClient 26:7c0e6f86d034 1592 (jsonPayload == NULL)
AzureIoTClient 17:fa1bba4c6053 1593 )
AzureIoTClient 17:fa1bba4c6053 1594 {
AzureIoTClient 26:7c0e6f86d034 1595 LogError("invalid argument void* device=%p, const char* jsonPayload=%p", device, jsonPayload);
AzureIoTClient 17:fa1bba4c6053 1596 result = CODEFIRST_INVALID_ARG;
AzureIoTClient 17:fa1bba4c6053 1597 }
AzureIoTClient 17:fa1bba4c6053 1598 else
AzureIoTClient 17:fa1bba4c6053 1599 {
AzureIoTClient 17:fa1bba4c6053 1600 /*Codes_SRS_CODEFIRST_02_032: [ CodeFirst_IngestDesiredProperties shall locate the device associated with device. ]*/
AzureIoTClient 17:fa1bba4c6053 1601 DEVICE_HEADER_DATA* deviceHeader = FindDevice(device);
AzureIoTClient 17:fa1bba4c6053 1602 if (deviceHeader == NULL)
AzureIoTClient 17:fa1bba4c6053 1603 {
AzureIoTClient 17:fa1bba4c6053 1604 /*Codes_SRS_CODEFIRST_02_034: [ If there is any failure, then CodeFirst_IngestDesiredProperties shall fail and return CODEFIRST_ERROR. ]*/
AzureIoTClient 17:fa1bba4c6053 1605 LogError("unable to find a device having this memory address %p", device);
AzureIoTClient 17:fa1bba4c6053 1606 result = CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1607 }
AzureIoTClient 17:fa1bba4c6053 1608 else
AzureIoTClient 17:fa1bba4c6053 1609 {
AzureIoTClient 17:fa1bba4c6053 1610 /*Codes_SRS_CODEFIRST_02_033: [ CodeFirst_IngestDesiredProperties shall call Device_IngestDesiredProperties. ]*/
AzureIoTClient 26:7c0e6f86d034 1611 if (Device_IngestDesiredProperties(device, deviceHeader->DeviceHandle, jsonPayload, parseDesiredNode) != DEVICE_OK)
AzureIoTClient 17:fa1bba4c6053 1612 {
AzureIoTClient 17:fa1bba4c6053 1613 LogError("failure in Device_IngestDesiredProperties");
AzureIoTClient 22:422d94bd3c18 1614 result = CODEFIRST_ERROR;
AzureIoTClient 17:fa1bba4c6053 1615 }
AzureIoTClient 17:fa1bba4c6053 1616 else
AzureIoTClient 17:fa1bba4c6053 1617 {
AzureIoTClient 17:fa1bba4c6053 1618 /*Codes_SRS_CODEFIRST_02_035: [ Otherwise, CodeFirst_IngestDesiredProperties shall return CODEFIRST_OK. ]*/
AzureIoTClient 17:fa1bba4c6053 1619 result = CODEFIRST_OK;
AzureIoTClient 17:fa1bba4c6053 1620 }
AzureIoTClient 17:fa1bba4c6053 1621 }
AzureIoTClient 17:fa1bba4c6053 1622 }
AzureIoTClient 17:fa1bba4c6053 1623 return result;
AzureIoTClient 17:fa1bba4c6053 1624 }
AzureIoTClient 17:fa1bba4c6053 1625
AzureIoTClient 17:fa1bba4c6053 1626