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:
Wed Nov 16 21:38:26 2016 -0800
Revision:
17:fa1bba4c6053
Child:
18:58b667752399
1.0.10

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AzureIoTClient 17:fa1bba4c6053 1 // Copyright (c) Microsoft. All rights reserved.
AzureIoTClient 17:fa1bba4c6053 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
AzureIoTClient 17:fa1bba4c6053 3
AzureIoTClient 17:fa1bba4c6053 4
AzureIoTClient 17:fa1bba4c6053 5 #ifndef SERIALIZER_DEVICE_TWIN_H
AzureIoTClient 17:fa1bba4c6053 6 #define SERIALIZER_DEVICE_TWIN_H
AzureIoTClient 17:fa1bba4c6053 7
AzureIoTClient 17:fa1bba4c6053 8 #include "serializer.h"
AzureIoTClient 17:fa1bba4c6053 9
AzureIoTClient 17:fa1bba4c6053 10 #include "iothub_client.h"
AzureIoTClient 17:fa1bba4c6053 11 #include "iothub_client_ll.h"
AzureIoTClient 17:fa1bba4c6053 12 #include "parson.h"
AzureIoTClient 17:fa1bba4c6053 13 #include "vector.h"
AzureIoTClient 17:fa1bba4c6053 14
AzureIoTClient 17:fa1bba4c6053 15 static void serializer_ingest(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)
AzureIoTClient 17:fa1bba4c6053 16 {
AzureIoTClient 17:fa1bba4c6053 17 /*by convention, userContextCallback is a pointer to a model instance created with CodeFirst_CreateDevice*/
AzureIoTClient 17:fa1bba4c6053 18
AzureIoTClient 17:fa1bba4c6053 19 /*Codes_SRS_SERIALIZERDEVICETWIN_02_001: [ serializer_ingest shall clone the payload into a null terminated string. ]*/
AzureIoTClient 17:fa1bba4c6053 20 char* copyOfPayload = (char*)malloc(size + 1);
AzureIoTClient 17:fa1bba4c6053 21 if (copyOfPayload == NULL)
AzureIoTClient 17:fa1bba4c6053 22 {
AzureIoTClient 17:fa1bba4c6053 23 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 24 LogError("unable to malloc\n");
AzureIoTClient 17:fa1bba4c6053 25 }
AzureIoTClient 17:fa1bba4c6053 26 else
AzureIoTClient 17:fa1bba4c6053 27 {
AzureIoTClient 17:fa1bba4c6053 28 memcpy(copyOfPayload, payLoad, size);
AzureIoTClient 17:fa1bba4c6053 29 copyOfPayload[size] = '\0';
AzureIoTClient 17:fa1bba4c6053 30
AzureIoTClient 17:fa1bba4c6053 31 /*Codes_SRS_SERIALIZERDEVICETWIN_02_002: [ serializer_ingest shall parse the null terminated string into parson data types. ]*/
AzureIoTClient 17:fa1bba4c6053 32 JSON_Value* allJSON = json_parse_string(copyOfPayload);
AzureIoTClient 17:fa1bba4c6053 33 if (allJSON == NULL)
AzureIoTClient 17:fa1bba4c6053 34 {
AzureIoTClient 17:fa1bba4c6053 35 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 36 LogError("failure in json_parse_string");
AzureIoTClient 17:fa1bba4c6053 37 }
AzureIoTClient 17:fa1bba4c6053 38 else
AzureIoTClient 17:fa1bba4c6053 39 {
AzureIoTClient 17:fa1bba4c6053 40 JSON_Object *allObject = json_value_get_object(allJSON);
AzureIoTClient 17:fa1bba4c6053 41 if (allObject == NULL)
AzureIoTClient 17:fa1bba4c6053 42 {
AzureIoTClient 17:fa1bba4c6053 43 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 44 LogError("failure in json_value_get_object");
AzureIoTClient 17:fa1bba4c6053 45 }
AzureIoTClient 17:fa1bba4c6053 46 else
AzureIoTClient 17:fa1bba4c6053 47 {
AzureIoTClient 17:fa1bba4c6053 48 switch (update_state)
AzureIoTClient 17:fa1bba4c6053 49 {
AzureIoTClient 17:fa1bba4c6053 50 /*Codes_SRS_SERIALIZERDEVICETWIN_02_003: [ If update_state is DEVICE_TWIN_UPDATE_COMPLETE then serializer_ingest shall locate "desired" json name. ]*/
AzureIoTClient 17:fa1bba4c6053 51 case DEVICE_TWIN_UPDATE_COMPLETE:
AzureIoTClient 17:fa1bba4c6053 52 {
AzureIoTClient 17:fa1bba4c6053 53 JSON_Object* desired = json_object_get_object(allObject, "desired");
AzureIoTClient 17:fa1bba4c6053 54 if (desired == NULL)
AzureIoTClient 17:fa1bba4c6053 55 {
AzureIoTClient 17:fa1bba4c6053 56 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 57 LogError("failure in json_object_get_object");
AzureIoTClient 17:fa1bba4c6053 58 }
AzureIoTClient 17:fa1bba4c6053 59 else
AzureIoTClient 17:fa1bba4c6053 60 {
AzureIoTClient 17:fa1bba4c6053 61 /*Codes_SRS_SERIALIZERDEVICETWIN_02_004: [ If "desired" contains "$version" then serializer_ingest shall remove it. ]*/
AzureIoTClient 17:fa1bba4c6053 62 (void)json_object_remove(desired, "$version"); //it might not exist
AzureIoTClient 17:fa1bba4c6053 63 JSON_Value* desiredAfterRemove = json_object_get_value(allObject, "desired");
AzureIoTClient 17:fa1bba4c6053 64 if (desiredAfterRemove != NULL)
AzureIoTClient 17:fa1bba4c6053 65 {
AzureIoTClient 17:fa1bba4c6053 66 /*Codes_SRS_SERIALIZERDEVICETWIN_02_005: [ The "desired" value shall be outputed to a null terminated string and serializer_ingest shall call CodeFirst_IngestDesiredProperties. ]*/
AzureIoTClient 17:fa1bba4c6053 67 char* pretty = json_serialize_to_string(desiredAfterRemove);
AzureIoTClient 17:fa1bba4c6053 68 if (pretty == NULL)
AzureIoTClient 17:fa1bba4c6053 69 {
AzureIoTClient 17:fa1bba4c6053 70 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 71 LogError("failure in json_serialize_to_string\n");
AzureIoTClient 17:fa1bba4c6053 72 }
AzureIoTClient 17:fa1bba4c6053 73 else
AzureIoTClient 17:fa1bba4c6053 74 {
AzureIoTClient 17:fa1bba4c6053 75 if (CodeFirst_IngestDesiredProperties(userContextCallback, pretty) != CODEFIRST_OK)
AzureIoTClient 17:fa1bba4c6053 76 {
AzureIoTClient 17:fa1bba4c6053 77 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 78 LogError("failure ingesting desired properties\n");
AzureIoTClient 17:fa1bba4c6053 79 }
AzureIoTClient 17:fa1bba4c6053 80 else
AzureIoTClient 17:fa1bba4c6053 81 {
AzureIoTClient 17:fa1bba4c6053 82 /*all is fine*/
AzureIoTClient 17:fa1bba4c6053 83 }
AzureIoTClient 17:fa1bba4c6053 84 free(pretty);
AzureIoTClient 17:fa1bba4c6053 85 }
AzureIoTClient 17:fa1bba4c6053 86 }
AzureIoTClient 17:fa1bba4c6053 87 }
AzureIoTClient 17:fa1bba4c6053 88 break;
AzureIoTClient 17:fa1bba4c6053 89 }
AzureIoTClient 17:fa1bba4c6053 90 case DEVICE_TWIN_UPDATE_PARTIAL:
AzureIoTClient 17:fa1bba4c6053 91 {
AzureIoTClient 17:fa1bba4c6053 92 /*Codes_SRS_SERIALIZERDEVICETWIN_02_006: [ If update_state is DEVICE_TWIN_UPDATE_PARTIAL then serializer_ingest shall remove "$version" (if it exists). ]*/
AzureIoTClient 17:fa1bba4c6053 93 (void)json_object_remove(allObject, "$version");
AzureIoTClient 17:fa1bba4c6053 94
AzureIoTClient 17:fa1bba4c6053 95 /*Codes_SRS_SERIALIZERDEVICETWIN_02_007: [ The JSON shall be outputed to a null terminated string and serializer_ingest shall call CodeFirst_IngestDesiredProperties. ]*/
AzureIoTClient 17:fa1bba4c6053 96 char* pretty = json_serialize_to_string(allJSON);
AzureIoTClient 17:fa1bba4c6053 97 if (pretty == NULL)
AzureIoTClient 17:fa1bba4c6053 98 {
AzureIoTClient 17:fa1bba4c6053 99 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 100 LogError("failure in json_serialize_to_string\n");
AzureIoTClient 17:fa1bba4c6053 101 }
AzureIoTClient 17:fa1bba4c6053 102 else
AzureIoTClient 17:fa1bba4c6053 103 {
AzureIoTClient 17:fa1bba4c6053 104 if (CodeFirst_IngestDesiredProperties(userContextCallback, pretty) != CODEFIRST_OK)
AzureIoTClient 17:fa1bba4c6053 105 {
AzureIoTClient 17:fa1bba4c6053 106 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 107 LogError("failure ingesting desired properties\n");
AzureIoTClient 17:fa1bba4c6053 108 }
AzureIoTClient 17:fa1bba4c6053 109 else
AzureIoTClient 17:fa1bba4c6053 110 {
AzureIoTClient 17:fa1bba4c6053 111 /*all is fine*/
AzureIoTClient 17:fa1bba4c6053 112 }
AzureIoTClient 17:fa1bba4c6053 113 free(pretty);
AzureIoTClient 17:fa1bba4c6053 114 }
AzureIoTClient 17:fa1bba4c6053 115 break;
AzureIoTClient 17:fa1bba4c6053 116 }
AzureIoTClient 17:fa1bba4c6053 117 default:
AzureIoTClient 17:fa1bba4c6053 118 {
AzureIoTClient 17:fa1bba4c6053 119 LogError("INTERNAL ERROR: unexpected value for update_state=%d\n", (int)update_state);
AzureIoTClient 17:fa1bba4c6053 120 }
AzureIoTClient 17:fa1bba4c6053 121 }
AzureIoTClient 17:fa1bba4c6053 122 }
AzureIoTClient 17:fa1bba4c6053 123 json_value_free(allJSON);
AzureIoTClient 17:fa1bba4c6053 124 }
AzureIoTClient 17:fa1bba4c6053 125 free(copyOfPayload);
AzureIoTClient 17:fa1bba4c6053 126 }
AzureIoTClient 17:fa1bba4c6053 127 }
AzureIoTClient 17:fa1bba4c6053 128
AzureIoTClient 17:fa1bba4c6053 129 /*an enum that sets the type of the handle used to record IoTHubDeviceTwin_Create was called*/
AzureIoTClient 17:fa1bba4c6053 130 #define IOTHUB_CLIENT_HANDLE_TYPE_VALUES \
AzureIoTClient 17:fa1bba4c6053 131 IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE, \
AzureIoTClient 17:fa1bba4c6053 132 IOTHUB_CLIENT_LL_HANDLE_TYPE
AzureIoTClient 17:fa1bba4c6053 133
AzureIoTClient 17:fa1bba4c6053 134 DEFINE_ENUM(IOTHUB_CLIENT_HANDLE_TYPE, IOTHUB_CLIENT_HANDLE_TYPE_VALUES)
AzureIoTClient 17:fa1bba4c6053 135
AzureIoTClient 17:fa1bba4c6053 136 typedef union IOTHUB_CLIENT_HANDLE_VALUE_TAG
AzureIoTClient 17:fa1bba4c6053 137 {
AzureIoTClient 17:fa1bba4c6053 138 IOTHUB_CLIENT_HANDLE iothubClientHandle;
AzureIoTClient 17:fa1bba4c6053 139 IOTHUB_CLIENT_LL_HANDLE iothubClientLLHandle;
AzureIoTClient 17:fa1bba4c6053 140 } IOTHUB_CLIENT_HANDLE_VALUE;
AzureIoTClient 17:fa1bba4c6053 141
AzureIoTClient 17:fa1bba4c6053 142 typedef struct IOTHUB_CLIENT_HANDLE_VARIANT_TAG
AzureIoTClient 17:fa1bba4c6053 143 {
AzureIoTClient 17:fa1bba4c6053 144 IOTHUB_CLIENT_HANDLE_TYPE iothubClientHandleType;
AzureIoTClient 17:fa1bba4c6053 145 IOTHUB_CLIENT_HANDLE_VALUE iothubClientHandleValue;
AzureIoTClient 17:fa1bba4c6053 146 } IOTHUB_CLIENT_HANDLE_VARIANT;
AzureIoTClient 17:fa1bba4c6053 147
AzureIoTClient 17:fa1bba4c6053 148 typedef struct SERIALIZER_DEVICETWIN_PROTOHANDLE_TAG /*it is called "PROTOHANDLE" because it is a primitive type of handle*/
AzureIoTClient 17:fa1bba4c6053 149 {
AzureIoTClient 17:fa1bba4c6053 150 IOTHUB_CLIENT_HANDLE_VARIANT iothubClientHandleVariant;
AzureIoTClient 17:fa1bba4c6053 151 void* deviceAssigned;
AzureIoTClient 17:fa1bba4c6053 152 } SERIALIZER_DEVICETWIN_PROTOHANDLE;
AzureIoTClient 17:fa1bba4c6053 153
AzureIoTClient 17:fa1bba4c6053 154 static VECTOR_HANDLE g_allProtoHandles=NULL; /*contains SERIALIZER_DEVICETWIN_PROTOHANDLE*/
AzureIoTClient 17:fa1bba4c6053 155
AzureIoTClient 17:fa1bba4c6053 156 static int lazilyAddProtohandle(const SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle)
AzureIoTClient 17:fa1bba4c6053 157 {
AzureIoTClient 17:fa1bba4c6053 158 int result;
AzureIoTClient 17:fa1bba4c6053 159 if ((g_allProtoHandles == NULL) && ((g_allProtoHandles = VECTOR_create(sizeof(SERIALIZER_DEVICETWIN_PROTOHANDLE))) == NULL))
AzureIoTClient 17:fa1bba4c6053 160 {
AzureIoTClient 17:fa1bba4c6053 161 LogError("failure in VECTOR_create");
AzureIoTClient 17:fa1bba4c6053 162 result = __LINE__;
AzureIoTClient 17:fa1bba4c6053 163 }
AzureIoTClient 17:fa1bba4c6053 164 else
AzureIoTClient 17:fa1bba4c6053 165 {
AzureIoTClient 17:fa1bba4c6053 166 if (VECTOR_push_back(g_allProtoHandles, protoHandle, 1) != 0)
AzureIoTClient 17:fa1bba4c6053 167 {
AzureIoTClient 17:fa1bba4c6053 168 LogError("failure in VECTOR_push_back");
AzureIoTClient 17:fa1bba4c6053 169 result = __LINE__;
AzureIoTClient 17:fa1bba4c6053 170
AzureIoTClient 17:fa1bba4c6053 171 /*leave it as it was*/
AzureIoTClient 17:fa1bba4c6053 172
AzureIoTClient 17:fa1bba4c6053 173 if (VECTOR_size(g_allProtoHandles) == 0)
AzureIoTClient 17:fa1bba4c6053 174 {
AzureIoTClient 17:fa1bba4c6053 175 VECTOR_destroy(g_allProtoHandles);
AzureIoTClient 17:fa1bba4c6053 176 g_allProtoHandles = NULL;
AzureIoTClient 17:fa1bba4c6053 177 }
AzureIoTClient 17:fa1bba4c6053 178 }
AzureIoTClient 17:fa1bba4c6053 179 else
AzureIoTClient 17:fa1bba4c6053 180 {
AzureIoTClient 17:fa1bba4c6053 181 result = 0;
AzureIoTClient 17:fa1bba4c6053 182 }
AzureIoTClient 17:fa1bba4c6053 183 }
AzureIoTClient 17:fa1bba4c6053 184 return result;
AzureIoTClient 17:fa1bba4c6053 185 }
AzureIoTClient 17:fa1bba4c6053 186
AzureIoTClient 17:fa1bba4c6053 187 static IOTHUB_CLIENT_RESULT Generic_IoTHubClient_SetDeviceTwinCallback(const SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
AzureIoTClient 17:fa1bba4c6053 188 {
AzureIoTClient 17:fa1bba4c6053 189 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 17:fa1bba4c6053 190 /*Codes_SRS_SERIALIZERDEVICETWIN_02_011: [ IoTHubDeviceTwinCreate_Impl shall set the device twin callback. ]*/
AzureIoTClient 17:fa1bba4c6053 191 switch (protoHandle->iothubClientHandleVariant.iothubClientHandleType)
AzureIoTClient 17:fa1bba4c6053 192 {
AzureIoTClient 17:fa1bba4c6053 193 case IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE:
AzureIoTClient 17:fa1bba4c6053 194 {
AzureIoTClient 17:fa1bba4c6053 195 if ((result = IoTHubClient_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, deviceTwinCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 196 {
AzureIoTClient 17:fa1bba4c6053 197 LogError("failure in IoTHubClient_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 198 }
AzureIoTClient 17:fa1bba4c6053 199 break;
AzureIoTClient 17:fa1bba4c6053 200 }
AzureIoTClient 17:fa1bba4c6053 201 case IOTHUB_CLIENT_LL_HANDLE_TYPE:
AzureIoTClient 17:fa1bba4c6053 202 {
AzureIoTClient 17:fa1bba4c6053 203 if ((result =IoTHubClient_LL_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, deviceTwinCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 204 {
AzureIoTClient 17:fa1bba4c6053 205 LogError("failure in IoTHubClient_LL_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 206 }
AzureIoTClient 17:fa1bba4c6053 207 break;
AzureIoTClient 17:fa1bba4c6053 208 }
AzureIoTClient 17:fa1bba4c6053 209 default:
AzureIoTClient 17:fa1bba4c6053 210 {
AzureIoTClient 17:fa1bba4c6053 211 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 17:fa1bba4c6053 212 LogError("INTERNAL ERROR");
AzureIoTClient 17:fa1bba4c6053 213 }
AzureIoTClient 17:fa1bba4c6053 214 }/*switch*/
AzureIoTClient 17:fa1bba4c6053 215 return result;
AzureIoTClient 17:fa1bba4c6053 216 }
AzureIoTClient 17:fa1bba4c6053 217
AzureIoTClient 17:fa1bba4c6053 218 static void* IoTHubDeviceTwinCreate_Impl(const char* name, size_t sizeOfName, SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle)
AzureIoTClient 17:fa1bba4c6053 219 {
AzureIoTClient 17:fa1bba4c6053 220 void* result;
AzureIoTClient 17:fa1bba4c6053 221 /*Codes_SRS_SERIALIZERDEVICETWIN_02_009: [ IoTHubDeviceTwinCreate_Impl shall locate the model and the metadata for name by calling Schema_GetSchemaForModel/Schema_GetMetadata/Schema_GetModelByName. ]*/
AzureIoTClient 17:fa1bba4c6053 222 SCHEMA_HANDLE h = Schema_GetSchemaForModel(name);
AzureIoTClient 17:fa1bba4c6053 223 if (h == NULL)
AzureIoTClient 17:fa1bba4c6053 224 {
AzureIoTClient 17:fa1bba4c6053 225 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 226 LogError("failure in Schema_GetSchemaForModel.");
AzureIoTClient 17:fa1bba4c6053 227 result = NULL;
AzureIoTClient 17:fa1bba4c6053 228 }
AzureIoTClient 17:fa1bba4c6053 229 else
AzureIoTClient 17:fa1bba4c6053 230 {
AzureIoTClient 17:fa1bba4c6053 231 void* metadata = Schema_GetMetadata(h);
AzureIoTClient 17:fa1bba4c6053 232 SCHEMA_MODEL_TYPE_HANDLE modelType = Schema_GetModelByName(h, name);
AzureIoTClient 17:fa1bba4c6053 233 if (modelType == NULL)
AzureIoTClient 17:fa1bba4c6053 234 {
AzureIoTClient 17:fa1bba4c6053 235 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 236 LogError("failure in Schema_GetModelByName");
AzureIoTClient 17:fa1bba4c6053 237 result = NULL;
AzureIoTClient 17:fa1bba4c6053 238 }
AzureIoTClient 17:fa1bba4c6053 239 else
AzureIoTClient 17:fa1bba4c6053 240 {
AzureIoTClient 17:fa1bba4c6053 241 /*Codes_SRS_SERIALIZERDEVICETWIN_02_010: [ IoTHubDeviceTwinCreate_Impl shall call CodeFirst_CreateDevice. ]*/
AzureIoTClient 17:fa1bba4c6053 242 result = CodeFirst_CreateDevice(modelType, (REFLECTED_DATA_FROM_DATAPROVIDER *)metadata, sizeOfName, true);
AzureIoTClient 17:fa1bba4c6053 243 if (result == NULL)
AzureIoTClient 17:fa1bba4c6053 244 {
AzureIoTClient 17:fa1bba4c6053 245 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 246 LogError("failure in CodeFirst_CreateDevice");
AzureIoTClient 17:fa1bba4c6053 247 /*return as is*/
AzureIoTClient 17:fa1bba4c6053 248 }
AzureIoTClient 17:fa1bba4c6053 249 else
AzureIoTClient 17:fa1bba4c6053 250 {
AzureIoTClient 17:fa1bba4c6053 251 protoHandle->deviceAssigned = result;
AzureIoTClient 17:fa1bba4c6053 252 if (Generic_IoTHubClient_SetDeviceTwinCallback(protoHandle, serializer_ingest, result) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 253 {
AzureIoTClient 17:fa1bba4c6053 254 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 255 LogError("failure in Generic_IoTHubClient_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 256 CodeFirst_DestroyDevice(result);
AzureIoTClient 17:fa1bba4c6053 257 result = NULL;
AzureIoTClient 17:fa1bba4c6053 258 }
AzureIoTClient 17:fa1bba4c6053 259 else
AzureIoTClient 17:fa1bba4c6053 260 {
AzureIoTClient 17:fa1bba4c6053 261 /*lazily add the protohandle to the array of tracking handles*/
AzureIoTClient 17:fa1bba4c6053 262
AzureIoTClient 17:fa1bba4c6053 263 /*Codes_SRS_SERIALIZERDEVICETWIN_02_012: [ IoTHubDeviceTwinCreate_Impl shall record the pair of (device, IoTHubClient(_LL)). ]*/
AzureIoTClient 17:fa1bba4c6053 264 if (lazilyAddProtohandle(protoHandle) != 0)
AzureIoTClient 17:fa1bba4c6053 265 {
AzureIoTClient 17:fa1bba4c6053 266 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 267 LogError("unable to add the protohandle to the collection of handles");
AzureIoTClient 17:fa1bba4c6053 268 /*unsubscribe*/
AzureIoTClient 17:fa1bba4c6053 269 if (Generic_IoTHubClient_SetDeviceTwinCallback(protoHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 270 {
AzureIoTClient 17:fa1bba4c6053 271 /*just log the error*/
AzureIoTClient 17:fa1bba4c6053 272 LogError("failure in Generic_IoTHubClient_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 273 }
AzureIoTClient 17:fa1bba4c6053 274 CodeFirst_DestroyDevice(result);
AzureIoTClient 17:fa1bba4c6053 275 result = NULL;
AzureIoTClient 17:fa1bba4c6053 276 }
AzureIoTClient 17:fa1bba4c6053 277 else
AzureIoTClient 17:fa1bba4c6053 278 {
AzureIoTClient 17:fa1bba4c6053 279 /*Codes_SRS_SERIALIZERDEVICETWIN_02_013: [ If all operations complete successfully then IoTHubDeviceTwinCreate_Impl shall succeeds and return a non-NULL value. ]*/
AzureIoTClient 17:fa1bba4c6053 280 /*return as is*/
AzureIoTClient 17:fa1bba4c6053 281 }
AzureIoTClient 17:fa1bba4c6053 282 }
AzureIoTClient 17:fa1bba4c6053 283 }
AzureIoTClient 17:fa1bba4c6053 284 }
AzureIoTClient 17:fa1bba4c6053 285 }
AzureIoTClient 17:fa1bba4c6053 286 return result;
AzureIoTClient 17:fa1bba4c6053 287 }
AzureIoTClient 17:fa1bba4c6053 288
AzureIoTClient 17:fa1bba4c6053 289 static bool protoHandleHasDeviceStartAddress(const void* element, const void* value)
AzureIoTClient 17:fa1bba4c6053 290 {
AzureIoTClient 17:fa1bba4c6053 291 const SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle = (const SERIALIZER_DEVICETWIN_PROTOHANDLE*)element;
AzureIoTClient 17:fa1bba4c6053 292 return protoHandle->deviceAssigned == value;
AzureIoTClient 17:fa1bba4c6053 293 }
AzureIoTClient 17:fa1bba4c6053 294
AzureIoTClient 17:fa1bba4c6053 295 static void IoTHubDeviceTwin_Destroy_Impl(void* model)
AzureIoTClient 17:fa1bba4c6053 296 {
AzureIoTClient 17:fa1bba4c6053 297 /*Codes_SRS_SERIALIZERDEVICETWIN_02_020: [ If model is NULL then IoTHubDeviceTwin_Destroy_Impl shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 298 if (model == NULL)
AzureIoTClient 17:fa1bba4c6053 299 {
AzureIoTClient 17:fa1bba4c6053 300 LogError("invalid argument void* model=%p", model);
AzureIoTClient 17:fa1bba4c6053 301 }
AzureIoTClient 17:fa1bba4c6053 302 else
AzureIoTClient 17:fa1bba4c6053 303 {
AzureIoTClient 17:fa1bba4c6053 304 /*Codes_SRS_SERIALIZERDEVICETWIN_02_015: [ IoTHubDeviceTwin_Destroy_Impl shall locate the saved handle belonging to model. ]*/
AzureIoTClient 17:fa1bba4c6053 305 SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle = (SERIALIZER_DEVICETWIN_PROTOHANDLE*)VECTOR_find_if(g_allProtoHandles, protoHandleHasDeviceStartAddress, model);
AzureIoTClient 17:fa1bba4c6053 306 if (protoHandle == NULL)
AzureIoTClient 17:fa1bba4c6053 307 {
AzureIoTClient 17:fa1bba4c6053 308 LogError("failure in VECTOR_find_if [not found]");
AzureIoTClient 17:fa1bba4c6053 309 }
AzureIoTClient 17:fa1bba4c6053 310 else
AzureIoTClient 17:fa1bba4c6053 311 {
AzureIoTClient 17:fa1bba4c6053 312 /*Codes_SRS_SERIALIZERDEVICETWIN_02_016: [ IoTHubDeviceTwin_Destroy_Impl shall set the devicetwin callback to NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 313 switch (protoHandle->iothubClientHandleVariant.iothubClientHandleType)
AzureIoTClient 17:fa1bba4c6053 314 {
AzureIoTClient 17:fa1bba4c6053 315 case IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE:
AzureIoTClient 17:fa1bba4c6053 316 {
AzureIoTClient 17:fa1bba4c6053 317 if (IoTHubClient_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 318 {
AzureIoTClient 17:fa1bba4c6053 319 LogError("failure in IoTHubClient_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 320 }
AzureIoTClient 17:fa1bba4c6053 321 break;
AzureIoTClient 17:fa1bba4c6053 322 }
AzureIoTClient 17:fa1bba4c6053 323 case IOTHUB_CLIENT_LL_HANDLE_TYPE:
AzureIoTClient 17:fa1bba4c6053 324 {
AzureIoTClient 17:fa1bba4c6053 325 if (IoTHubClient_LL_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 326 {
AzureIoTClient 17:fa1bba4c6053 327 LogError("failure in IoTHubClient_LL_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 328 }
AzureIoTClient 17:fa1bba4c6053 329 break;
AzureIoTClient 17:fa1bba4c6053 330 }
AzureIoTClient 17:fa1bba4c6053 331 default:
AzureIoTClient 17:fa1bba4c6053 332 {
AzureIoTClient 17:fa1bba4c6053 333 LogError("INTERNAL ERROR");
AzureIoTClient 17:fa1bba4c6053 334 }
AzureIoTClient 17:fa1bba4c6053 335 }/*switch*/
AzureIoTClient 17:fa1bba4c6053 336 }
AzureIoTClient 17:fa1bba4c6053 337
AzureIoTClient 17:fa1bba4c6053 338 /*Codes_SRS_SERIALIZERDEVICETWIN_02_017: [ IoTHubDeviceTwin_Destroy_Impl shall call CodeFirst_DestroyDevice. ]*/
AzureIoTClient 17:fa1bba4c6053 339 CodeFirst_DestroyDevice(protoHandle->deviceAssigned);
AzureIoTClient 17:fa1bba4c6053 340
AzureIoTClient 17:fa1bba4c6053 341 /*Codes_SRS_SERIALIZERDEVICETWIN_02_018: [ IoTHubDeviceTwin_Destroy_Impl shall remove the IoTHubClient_Handle and the device handle from the recorded set. ]*/
AzureIoTClient 17:fa1bba4c6053 342 VECTOR_erase(g_allProtoHandles, protoHandle, 1);
AzureIoTClient 17:fa1bba4c6053 343
AzureIoTClient 17:fa1bba4c6053 344 /*Codes_SRS_SERIALIZERDEVICETWIN_02_019: [ If the recorded set of IoTHubClient handles is zero size, then the set shall be destroyed. ]*/
AzureIoTClient 17:fa1bba4c6053 345 if (VECTOR_size(g_allProtoHandles) == 0) /*lazy init means more work @ destroy time*/
AzureIoTClient 17:fa1bba4c6053 346 {
AzureIoTClient 17:fa1bba4c6053 347 VECTOR_destroy(g_allProtoHandles);
AzureIoTClient 17:fa1bba4c6053 348 g_allProtoHandles = NULL;
AzureIoTClient 17:fa1bba4c6053 349 }
AzureIoTClient 17:fa1bba4c6053 350 }
AzureIoTClient 17:fa1bba4c6053 351 }
AzureIoTClient 17:fa1bba4c6053 352
AzureIoTClient 17:fa1bba4c6053 353 #define DECLARE_DEVICETWIN_MODEL(name, ...) \
AzureIoTClient 17:fa1bba4c6053 354 DECLARE_MODEL(name, __VA_ARGS__) \
AzureIoTClient 17:fa1bba4c6053 355 static name* C2(IoTHubDeviceTwin_Create, name)(IOTHUB_CLIENT_HANDLE iotHubClientHandle) \
AzureIoTClient 17:fa1bba4c6053 356 { \
AzureIoTClient 17:fa1bba4c6053 357 SERIALIZER_DEVICETWIN_PROTOHANDLE protoHandle; \
AzureIoTClient 17:fa1bba4c6053 358 protoHandle.iothubClientHandleVariant.iothubClientHandleType = IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE; \
AzureIoTClient 17:fa1bba4c6053 359 protoHandle.iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle = iotHubClientHandle; \
AzureIoTClient 17:fa1bba4c6053 360 return (name*)IoTHubDeviceTwinCreate_Impl(#name, sizeof(name), &protoHandle); \
AzureIoTClient 17:fa1bba4c6053 361 } \
AzureIoTClient 17:fa1bba4c6053 362 \
AzureIoTClient 17:fa1bba4c6053 363 static void C2(IoTHubDeviceTwin_Destroy, name) (name* model) \
AzureIoTClient 17:fa1bba4c6053 364 { \
AzureIoTClient 17:fa1bba4c6053 365 IoTHubDeviceTwin_Destroy_Impl(model); \
AzureIoTClient 17:fa1bba4c6053 366 } \
AzureIoTClient 17:fa1bba4c6053 367 \
AzureIoTClient 17:fa1bba4c6053 368 static name* C2(IoTHubDeviceTwin_LL_Create, name)(IOTHUB_CLIENT_LL_HANDLE iotHubClientLLHandle) \
AzureIoTClient 17:fa1bba4c6053 369 { \
AzureIoTClient 17:fa1bba4c6053 370 SERIALIZER_DEVICETWIN_PROTOHANDLE protoHandle; \
AzureIoTClient 17:fa1bba4c6053 371 protoHandle.iothubClientHandleVariant.iothubClientHandleType = IOTHUB_CLIENT_LL_HANDLE_TYPE; \
AzureIoTClient 17:fa1bba4c6053 372 protoHandle.iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle = iotHubClientLLHandle; \
AzureIoTClient 17:fa1bba4c6053 373 return (name*)IoTHubDeviceTwinCreate_Impl(#name, sizeof(name), &protoHandle); \
AzureIoTClient 17:fa1bba4c6053 374 } \
AzureIoTClient 17:fa1bba4c6053 375 \
AzureIoTClient 17:fa1bba4c6053 376 static void C2(IoTHubDeviceTwin_LL_Destroy, name) (name* model) \
AzureIoTClient 17:fa1bba4c6053 377 { \
AzureIoTClient 17:fa1bba4c6053 378 IoTHubDeviceTwin_Destroy_Impl(model); \
AzureIoTClient 17:fa1bba4c6053 379 } \
AzureIoTClient 17:fa1bba4c6053 380
AzureIoTClient 17:fa1bba4c6053 381 #endif /*SERIALIZER_DEVICE_TWIN_H*/
AzureIoTClient 17:fa1bba4c6053 382
AzureIoTClient 17:fa1bba4c6053 383