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:
34:87d7cd4169c6
1.2.9

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 23:078ea26cffcd 13 #include "azure_c_shared_utility/optimize_size.h"
AzureIoTClient 22:422d94bd3c18 14 #include "azure_c_shared_utility/vector.h"
Azure.IoT.Build 18:58b667752399 15 #include "methodreturn.h"
AzureIoTClient 17:fa1bba4c6053 16
AzureIoTClient 17:fa1bba4c6053 17 static void serializer_ingest(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)
AzureIoTClient 17:fa1bba4c6053 18 {
AzureIoTClient 17:fa1bba4c6053 19 /*by convention, userContextCallback is a pointer to a model instance created with CodeFirst_CreateDevice*/
AzureIoTClient 17:fa1bba4c6053 20
AzureIoTClient 17:fa1bba4c6053 21 /*Codes_SRS_SERIALIZERDEVICETWIN_02_001: [ serializer_ingest shall clone the payload into a null terminated string. ]*/
AzureIoTClient 17:fa1bba4c6053 22 char* copyOfPayload = (char*)malloc(size + 1);
AzureIoTClient 17:fa1bba4c6053 23 if (copyOfPayload == NULL)
AzureIoTClient 17:fa1bba4c6053 24 {
AzureIoTClient 17:fa1bba4c6053 25 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 26 LogError("unable to malloc\n");
AzureIoTClient 17:fa1bba4c6053 27 }
AzureIoTClient 17:fa1bba4c6053 28 else
AzureIoTClient 17:fa1bba4c6053 29 {
AzureIoTClient 22:422d94bd3c18 30 (void)memcpy(copyOfPayload, payLoad, size);
AzureIoTClient 17:fa1bba4c6053 31 copyOfPayload[size] = '\0';
AzureIoTClient 17:fa1bba4c6053 32
AzureIoTClient 26:7c0e6f86d034 33 bool parseDesiredNode = (update_state == DEVICE_TWIN_UPDATE_COMPLETE);
AzureIoTClient 26:7c0e6f86d034 34
AzureIoTClient 26:7c0e6f86d034 35 if (CodeFirst_IngestDesiredProperties(userContextCallback, copyOfPayload, parseDesiredNode) != CODEFIRST_OK)
AzureIoTClient 17:fa1bba4c6053 36 {
AzureIoTClient 17:fa1bba4c6053 37 /*Codes_SRS_SERIALIZERDEVICETWIN_02_008: [ If any of the above operations fail, then serializer_ingest shall return. ]*/
AzureIoTClient 26:7c0e6f86d034 38 LogError("failure ingesting desired properties\n");
AzureIoTClient 17:fa1bba4c6053 39 }
AzureIoTClient 17:fa1bba4c6053 40 else
AzureIoTClient 17:fa1bba4c6053 41 {
AzureIoTClient 26:7c0e6f86d034 42 /*all is fine*/
AzureIoTClient 17:fa1bba4c6053 43 }
AzureIoTClient 36:7d12a5386197 44
AzureIoTClient 17:fa1bba4c6053 45 free(copyOfPayload);
AzureIoTClient 17:fa1bba4c6053 46 }
AzureIoTClient 17:fa1bba4c6053 47 }
AzureIoTClient 17:fa1bba4c6053 48
Azure.IoT.Build 18:58b667752399 49 /*both LL and convenience layer can be served by the same callback*/
Azure.IoT.Build 18:58b667752399 50 static int deviceMethodCallback(const char* method_name, const unsigned char* payload, size_t size, unsigned char** response, size_t* resp_size, void* userContextCallback)
Azure.IoT.Build 18:58b667752399 51 {
Azure.IoT.Build 18:58b667752399 52 int result;
Azure.IoT.Build 18:58b667752399 53 /*Codes_SRS_SERIALIZERDEVICETWIN_02_021: [ deviceMethodCallback shall transform payload and size into a null terminated string. ]*/
Azure.IoT.Build 18:58b667752399 54 char* payloadZeroTerminated = (char*)malloc(size + 1);
Azure.IoT.Build 18:58b667752399 55 if (payloadZeroTerminated == NULL)
Azure.IoT.Build 18:58b667752399 56 {
Azure.IoT.Build 18:58b667752399 57 LogError("failure in malloc");
Azure.IoT.Build 18:58b667752399 58 /*Codes_SRS_SERIALIZERDEVICETWIN_02_026: [ If any failure occurs in the above operations, then deviceMethodCallback shall fail, return 500, set *response to NULL and '*resp_size` to 0. ]*/
Azure.IoT.Build 18:58b667752399 59 *response = NULL;
Azure.IoT.Build 18:58b667752399 60 *resp_size = 0;
Azure.IoT.Build 18:58b667752399 61 result = 500;
Azure.IoT.Build 18:58b667752399 62 }
Azure.IoT.Build 18:58b667752399 63 else
Azure.IoT.Build 18:58b667752399 64 {
AzureIoTClient 22:422d94bd3c18 65 (void)memcpy(payloadZeroTerminated, payload, size);
Azure.IoT.Build 18:58b667752399 66 payloadZeroTerminated[size] = '\0';
Azure.IoT.Build 18:58b667752399 67
Azure.IoT.Build 18:58b667752399 68 /*Codes_SRS_SERIALIZERDEVICETWIN_02_022: [ deviceMethodCallback shall call EXECUTE_METHOD passing the userContextCallback, method_name and the null terminated string build before. ]*/
Azure.IoT.Build 18:58b667752399 69 METHODRETURN_HANDLE mr = EXECUTE_METHOD(userContextCallback, method_name, payloadZeroTerminated);
AzureIoTClient 36:7d12a5386197 70
Azure.IoT.Build 18:58b667752399 71 if (mr == NULL)
Azure.IoT.Build 18:58b667752399 72 {
Azure.IoT.Build 18:58b667752399 73 LogError("failure in EXECUTE_METHOD");
Azure.IoT.Build 18:58b667752399 74 /*Codes_SRS_SERIALIZERDEVICETWIN_02_026: [ If any failure occurs in the above operations, then deviceMethodCallback shall fail, return 500, set *response to NULL and '*resp_size` to 0. ]*/
Azure.IoT.Build 18:58b667752399 75 *response = NULL;
Azure.IoT.Build 18:58b667752399 76 *resp_size = 0;
Azure.IoT.Build 18:58b667752399 77 result = 500;
Azure.IoT.Build 18:58b667752399 78 }
Azure.IoT.Build 18:58b667752399 79 else
Azure.IoT.Build 18:58b667752399 80 {
Azure.IoT.Build 18:58b667752399 81 /*Codes_SRS_SERIALIZERDEVICETWIN_02_023: [ deviceMethodCallback shall get the MethodReturn_Data and shall copy the response JSON value into a new byte array. ]*/
Azure.IoT.Build 18:58b667752399 82 const METHODRETURN_DATA* data = MethodReturn_GetReturn(mr);
Azure.IoT.Build 18:58b667752399 83
Azure.IoT.Build 18:58b667752399 84 /*Codes_SRS_SERIALIZERDEVICETWIN_02_025: [ deviceMethodCallback returns the statusCode from the user. ]*/
Azure.IoT.Build 18:58b667752399 85 result = data->statusCode;
Azure.IoT.Build 18:58b667752399 86
Azure.IoT.Build 18:58b667752399 87 if (data->jsonValue == NULL)
Azure.IoT.Build 18:58b667752399 88 {
Azure.IoT.Build 18:58b667752399 89 *resp_size = 0;
Azure.IoT.Build 18:58b667752399 90 *response = NULL;
Azure.IoT.Build 18:58b667752399 91 }
Azure.IoT.Build 18:58b667752399 92 else
Azure.IoT.Build 18:58b667752399 93 {
Azure.IoT.Build 18:58b667752399 94 *resp_size = strlen(data->jsonValue);
Azure.IoT.Build 18:58b667752399 95 *response = (unsigned char*)malloc(*resp_size);
Azure.IoT.Build 18:58b667752399 96 if (*response == NULL)
Azure.IoT.Build 18:58b667752399 97 {
Azure.IoT.Build 18:58b667752399 98 LogError("failure in malloc");
Azure.IoT.Build 18:58b667752399 99 /*Codes_SRS_SERIALIZERDEVICETWIN_02_026: [ If any failure occurs in the above operations, then deviceMethodCallback shall fail, return 500, set *response to NULL and '*resp_size` to 0. ]*/
Azure.IoT.Build 18:58b667752399 100 *response = NULL;
Azure.IoT.Build 18:58b667752399 101 *resp_size = 0;
Azure.IoT.Build 18:58b667752399 102 result = 500;
Azure.IoT.Build 18:58b667752399 103 }
Azure.IoT.Build 18:58b667752399 104 else
Azure.IoT.Build 18:58b667752399 105 {
Azure.IoT.Build 18:58b667752399 106 /*Codes_SRS_SERIALIZERDEVICETWIN_02_024: [ deviceMethodCallback shall set *response to this new byte array, *resp_size to the size of the array. ]*/
AzureIoTClient 22:422d94bd3c18 107 (void)memcpy(*response, data->jsonValue, *resp_size);
Azure.IoT.Build 18:58b667752399 108 }
Azure.IoT.Build 18:58b667752399 109 }
Azure.IoT.Build 18:58b667752399 110 MethodReturn_Destroy(mr);
Azure.IoT.Build 18:58b667752399 111 }
Azure.IoT.Build 18:58b667752399 112 free(payloadZeroTerminated);
Azure.IoT.Build 18:58b667752399 113 }
Azure.IoT.Build 18:58b667752399 114 return result;
Azure.IoT.Build 18:58b667752399 115 }
Azure.IoT.Build 18:58b667752399 116
AzureIoTClient 17:fa1bba4c6053 117 /*an enum that sets the type of the handle used to record IoTHubDeviceTwin_Create was called*/
AzureIoTClient 17:fa1bba4c6053 118 #define IOTHUB_CLIENT_HANDLE_TYPE_VALUES \
AzureIoTClient 17:fa1bba4c6053 119 IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE, \
AzureIoTClient 17:fa1bba4c6053 120 IOTHUB_CLIENT_LL_HANDLE_TYPE
AzureIoTClient 17:fa1bba4c6053 121
AzureIoTClient 17:fa1bba4c6053 122 DEFINE_ENUM(IOTHUB_CLIENT_HANDLE_TYPE, IOTHUB_CLIENT_HANDLE_TYPE_VALUES)
AzureIoTClient 17:fa1bba4c6053 123
AzureIoTClient 17:fa1bba4c6053 124 typedef union IOTHUB_CLIENT_HANDLE_VALUE_TAG
AzureIoTClient 17:fa1bba4c6053 125 {
AzureIoTClient 17:fa1bba4c6053 126 IOTHUB_CLIENT_HANDLE iothubClientHandle;
AzureIoTClient 17:fa1bba4c6053 127 IOTHUB_CLIENT_LL_HANDLE iothubClientLLHandle;
AzureIoTClient 17:fa1bba4c6053 128 } IOTHUB_CLIENT_HANDLE_VALUE;
AzureIoTClient 17:fa1bba4c6053 129
AzureIoTClient 17:fa1bba4c6053 130 typedef struct IOTHUB_CLIENT_HANDLE_VARIANT_TAG
AzureIoTClient 17:fa1bba4c6053 131 {
AzureIoTClient 17:fa1bba4c6053 132 IOTHUB_CLIENT_HANDLE_TYPE iothubClientHandleType;
AzureIoTClient 17:fa1bba4c6053 133 IOTHUB_CLIENT_HANDLE_VALUE iothubClientHandleValue;
AzureIoTClient 17:fa1bba4c6053 134 } IOTHUB_CLIENT_HANDLE_VARIANT;
AzureIoTClient 17:fa1bba4c6053 135
AzureIoTClient 17:fa1bba4c6053 136 typedef struct SERIALIZER_DEVICETWIN_PROTOHANDLE_TAG /*it is called "PROTOHANDLE" because it is a primitive type of handle*/
AzureIoTClient 17:fa1bba4c6053 137 {
AzureIoTClient 17:fa1bba4c6053 138 IOTHUB_CLIENT_HANDLE_VARIANT iothubClientHandleVariant;
AzureIoTClient 17:fa1bba4c6053 139 void* deviceAssigned;
AzureIoTClient 17:fa1bba4c6053 140 } SERIALIZER_DEVICETWIN_PROTOHANDLE;
AzureIoTClient 36:7d12a5386197 141
AzureIoTClient 17:fa1bba4c6053 142 static VECTOR_HANDLE g_allProtoHandles=NULL; /*contains SERIALIZER_DEVICETWIN_PROTOHANDLE*/
AzureIoTClient 17:fa1bba4c6053 143
AzureIoTClient 17:fa1bba4c6053 144 static int lazilyAddProtohandle(const SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle)
AzureIoTClient 17:fa1bba4c6053 145 {
AzureIoTClient 17:fa1bba4c6053 146 int result;
AzureIoTClient 17:fa1bba4c6053 147 if ((g_allProtoHandles == NULL) && ((g_allProtoHandles = VECTOR_create(sizeof(SERIALIZER_DEVICETWIN_PROTOHANDLE))) == NULL))
AzureIoTClient 17:fa1bba4c6053 148 {
AzureIoTClient 17:fa1bba4c6053 149 LogError("failure in VECTOR_create");
AzureIoTClient 23:078ea26cffcd 150 result = __FAILURE__;
AzureIoTClient 17:fa1bba4c6053 151 }
AzureIoTClient 17:fa1bba4c6053 152 else
AzureIoTClient 17:fa1bba4c6053 153 {
AzureIoTClient 17:fa1bba4c6053 154 if (VECTOR_push_back(g_allProtoHandles, protoHandle, 1) != 0)
AzureIoTClient 17:fa1bba4c6053 155 {
AzureIoTClient 17:fa1bba4c6053 156 LogError("failure in VECTOR_push_back");
AzureIoTClient 23:078ea26cffcd 157 result = __FAILURE__;
AzureIoTClient 17:fa1bba4c6053 158
AzureIoTClient 17:fa1bba4c6053 159 /*leave it as it was*/
AzureIoTClient 17:fa1bba4c6053 160
AzureIoTClient 17:fa1bba4c6053 161 if (VECTOR_size(g_allProtoHandles) == 0)
AzureIoTClient 17:fa1bba4c6053 162 {
AzureIoTClient 17:fa1bba4c6053 163 VECTOR_destroy(g_allProtoHandles);
AzureIoTClient 17:fa1bba4c6053 164 g_allProtoHandles = NULL;
AzureIoTClient 17:fa1bba4c6053 165 }
AzureIoTClient 17:fa1bba4c6053 166 }
AzureIoTClient 17:fa1bba4c6053 167 else
AzureIoTClient 17:fa1bba4c6053 168 {
AzureIoTClient 17:fa1bba4c6053 169 result = 0;
AzureIoTClient 17:fa1bba4c6053 170 }
AzureIoTClient 17:fa1bba4c6053 171 }
AzureIoTClient 17:fa1bba4c6053 172 return result;
AzureIoTClient 17:fa1bba4c6053 173 }
AzureIoTClient 17:fa1bba4c6053 174
Azure.IoT.Build 18:58b667752399 175 static IOTHUB_CLIENT_RESULT Generic_IoTHubClient_SetCallbacks(const SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
AzureIoTClient 17:fa1bba4c6053 176 {
AzureIoTClient 17:fa1bba4c6053 177 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 17:fa1bba4c6053 178 /*Codes_SRS_SERIALIZERDEVICETWIN_02_011: [ IoTHubDeviceTwinCreate_Impl shall set the device twin callback. ]*/
AzureIoTClient 17:fa1bba4c6053 179 switch (protoHandle->iothubClientHandleVariant.iothubClientHandleType)
AzureIoTClient 17:fa1bba4c6053 180 {
AzureIoTClient 17:fa1bba4c6053 181 case IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE:
AzureIoTClient 17:fa1bba4c6053 182 {
AzureIoTClient 17:fa1bba4c6053 183 if ((result = IoTHubClient_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, deviceTwinCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 184 {
AzureIoTClient 17:fa1bba4c6053 185 LogError("failure in IoTHubClient_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 186 }
Azure.IoT.Build 18:58b667752399 187 else
Azure.IoT.Build 18:58b667752399 188 {
Azure.IoT.Build 18:58b667752399 189 /*Codes_SRS_SERIALIZERDEVICETWIN_02_027: [ IoTHubDeviceTwinCreate_Impl shall set the device method callback ]*/
Azure.IoT.Build 18:58b667752399 190 if ((result = IoTHubClient_SetDeviceMethodCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, deviceMethodCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
Azure.IoT.Build 18:58b667752399 191 {
Azure.IoT.Build 18:58b667752399 192 (void)IoTHubClient_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, NULL, NULL);
Azure.IoT.Build 18:58b667752399 193 LogError("failure in IoTHubClient_SetDeviceMethodCallback");
Azure.IoT.Build 18:58b667752399 194 }
Azure.IoT.Build 18:58b667752399 195 }
AzureIoTClient 17:fa1bba4c6053 196 break;
AzureIoTClient 17:fa1bba4c6053 197 }
AzureIoTClient 17:fa1bba4c6053 198 case IOTHUB_CLIENT_LL_HANDLE_TYPE:
AzureIoTClient 17:fa1bba4c6053 199 {
AzureIoTClient 17:fa1bba4c6053 200 if ((result =IoTHubClient_LL_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, deviceTwinCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 201 {
AzureIoTClient 17:fa1bba4c6053 202 LogError("failure in IoTHubClient_LL_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 203 }
Azure.IoT.Build 18:58b667752399 204 else
Azure.IoT.Build 18:58b667752399 205 {
Azure.IoT.Build 18:58b667752399 206 /*Codes_SRS_SERIALIZERDEVICETWIN_02_027: [ IoTHubDeviceTwinCreate_Impl shall set the device method callback ]*/
Azure.IoT.Build 18:58b667752399 207 if ((result = IoTHubClient_LL_SetDeviceMethodCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, deviceMethodCallback, userContextCallback)) != IOTHUB_CLIENT_OK)
Azure.IoT.Build 18:58b667752399 208 {
Azure.IoT.Build 18:58b667752399 209 (void)IoTHubClient_LL_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, NULL, NULL);
Azure.IoT.Build 18:58b667752399 210 LogError("failure in IoTHubClient_SetDeviceMethodCallback");
Azure.IoT.Build 18:58b667752399 211 }
Azure.IoT.Build 18:58b667752399 212 }
AzureIoTClient 17:fa1bba4c6053 213 break;
AzureIoTClient 17:fa1bba4c6053 214 }
AzureIoTClient 17:fa1bba4c6053 215 default:
AzureIoTClient 17:fa1bba4c6053 216 {
AzureIoTClient 17:fa1bba4c6053 217 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 17:fa1bba4c6053 218 LogError("INTERNAL ERROR");
AzureIoTClient 17:fa1bba4c6053 219 }
AzureIoTClient 17:fa1bba4c6053 220 }/*switch*/
AzureIoTClient 17:fa1bba4c6053 221 return result;
AzureIoTClient 17:fa1bba4c6053 222 }
AzureIoTClient 17:fa1bba4c6053 223
AzureIoTClient 17:fa1bba4c6053 224 static void* IoTHubDeviceTwinCreate_Impl(const char* name, size_t sizeOfName, SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle)
AzureIoTClient 17:fa1bba4c6053 225 {
AzureIoTClient 17:fa1bba4c6053 226 void* result;
AzureIoTClient 17:fa1bba4c6053 227 /*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 228 SCHEMA_HANDLE h = Schema_GetSchemaForModel(name);
AzureIoTClient 17:fa1bba4c6053 229 if (h == NULL)
AzureIoTClient 17:fa1bba4c6053 230 {
AzureIoTClient 17:fa1bba4c6053 231 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 232 LogError("failure in Schema_GetSchemaForModel.");
AzureIoTClient 17:fa1bba4c6053 233 result = NULL;
AzureIoTClient 17:fa1bba4c6053 234 }
AzureIoTClient 17:fa1bba4c6053 235 else
AzureIoTClient 17:fa1bba4c6053 236 {
AzureIoTClient 17:fa1bba4c6053 237 void* metadata = Schema_GetMetadata(h);
AzureIoTClient 17:fa1bba4c6053 238 SCHEMA_MODEL_TYPE_HANDLE modelType = Schema_GetModelByName(h, name);
AzureIoTClient 17:fa1bba4c6053 239 if (modelType == NULL)
AzureIoTClient 17:fa1bba4c6053 240 {
AzureIoTClient 17:fa1bba4c6053 241 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 242 LogError("failure in Schema_GetModelByName");
AzureIoTClient 17:fa1bba4c6053 243 result = NULL;
AzureIoTClient 17:fa1bba4c6053 244 }
AzureIoTClient 17:fa1bba4c6053 245 else
AzureIoTClient 17:fa1bba4c6053 246 {
AzureIoTClient 17:fa1bba4c6053 247 /*Codes_SRS_SERIALIZERDEVICETWIN_02_010: [ IoTHubDeviceTwinCreate_Impl shall call CodeFirst_CreateDevice. ]*/
AzureIoTClient 17:fa1bba4c6053 248 result = CodeFirst_CreateDevice(modelType, (REFLECTED_DATA_FROM_DATAPROVIDER *)metadata, sizeOfName, true);
AzureIoTClient 17:fa1bba4c6053 249 if (result == NULL)
AzureIoTClient 17:fa1bba4c6053 250 {
AzureIoTClient 17:fa1bba4c6053 251 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 252 LogError("failure in CodeFirst_CreateDevice");
AzureIoTClient 17:fa1bba4c6053 253 /*return as is*/
AzureIoTClient 17:fa1bba4c6053 254 }
AzureIoTClient 17:fa1bba4c6053 255 else
AzureIoTClient 17:fa1bba4c6053 256 {
AzureIoTClient 17:fa1bba4c6053 257 protoHandle->deviceAssigned = result;
Azure.IoT.Build 18:58b667752399 258 if (Generic_IoTHubClient_SetCallbacks(protoHandle, serializer_ingest, result) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 259 {
AzureIoTClient 17:fa1bba4c6053 260 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
Azure.IoT.Build 18:58b667752399 261 LogError("failure in Generic_IoTHubClient_SetCallbacks");
AzureIoTClient 17:fa1bba4c6053 262 CodeFirst_DestroyDevice(result);
AzureIoTClient 17:fa1bba4c6053 263 result = NULL;
AzureIoTClient 17:fa1bba4c6053 264 }
AzureIoTClient 17:fa1bba4c6053 265 else
AzureIoTClient 17:fa1bba4c6053 266 {
AzureIoTClient 17:fa1bba4c6053 267 /*lazily add the protohandle to the array of tracking handles*/
AzureIoTClient 17:fa1bba4c6053 268
AzureIoTClient 17:fa1bba4c6053 269 /*Codes_SRS_SERIALIZERDEVICETWIN_02_012: [ IoTHubDeviceTwinCreate_Impl shall record the pair of (device, IoTHubClient(_LL)). ]*/
AzureIoTClient 17:fa1bba4c6053 270 if (lazilyAddProtohandle(protoHandle) != 0)
AzureIoTClient 17:fa1bba4c6053 271 {
AzureIoTClient 17:fa1bba4c6053 272 /*Codes_SRS_SERIALIZERDEVICETWIN_02_014: [ Otherwise, IoTHubDeviceTwinCreate_Impl shall fail and return NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 273 LogError("unable to add the protohandle to the collection of handles");
AzureIoTClient 17:fa1bba4c6053 274 /*unsubscribe*/
Azure.IoT.Build 18:58b667752399 275 if (Generic_IoTHubClient_SetCallbacks(protoHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 276 {
AzureIoTClient 17:fa1bba4c6053 277 /*just log the error*/
Azure.IoT.Build 18:58b667752399 278 LogError("failure in Generic_IoTHubClient_SetCallbacks");
AzureIoTClient 17:fa1bba4c6053 279 }
AzureIoTClient 17:fa1bba4c6053 280 CodeFirst_DestroyDevice(result);
AzureIoTClient 17:fa1bba4c6053 281 result = NULL;
AzureIoTClient 17:fa1bba4c6053 282 }
AzureIoTClient 17:fa1bba4c6053 283 else
AzureIoTClient 17:fa1bba4c6053 284 {
AzureIoTClient 17:fa1bba4c6053 285 /*Codes_SRS_SERIALIZERDEVICETWIN_02_013: [ If all operations complete successfully then IoTHubDeviceTwinCreate_Impl shall succeeds and return a non-NULL value. ]*/
AzureIoTClient 17:fa1bba4c6053 286 /*return as is*/
AzureIoTClient 17:fa1bba4c6053 287 }
AzureIoTClient 17:fa1bba4c6053 288 }
AzureIoTClient 17:fa1bba4c6053 289 }
AzureIoTClient 17:fa1bba4c6053 290 }
AzureIoTClient 17:fa1bba4c6053 291 }
AzureIoTClient 17:fa1bba4c6053 292 return result;
AzureIoTClient 17:fa1bba4c6053 293 }
AzureIoTClient 17:fa1bba4c6053 294
AzureIoTClient 17:fa1bba4c6053 295 static bool protoHandleHasDeviceStartAddress(const void* element, const void* value)
AzureIoTClient 17:fa1bba4c6053 296 {
AzureIoTClient 17:fa1bba4c6053 297 const SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle = (const SERIALIZER_DEVICETWIN_PROTOHANDLE*)element;
AzureIoTClient 17:fa1bba4c6053 298 return protoHandle->deviceAssigned == value;
AzureIoTClient 17:fa1bba4c6053 299 }
AzureIoTClient 17:fa1bba4c6053 300
AzureIoTClient 17:fa1bba4c6053 301 static void IoTHubDeviceTwin_Destroy_Impl(void* model)
AzureIoTClient 17:fa1bba4c6053 302 {
AzureIoTClient 17:fa1bba4c6053 303 /*Codes_SRS_SERIALIZERDEVICETWIN_02_020: [ If model is NULL then IoTHubDeviceTwin_Destroy_Impl shall return. ]*/
AzureIoTClient 17:fa1bba4c6053 304 if (model == NULL)
AzureIoTClient 17:fa1bba4c6053 305 {
AzureIoTClient 17:fa1bba4c6053 306 LogError("invalid argument void* model=%p", model);
AzureIoTClient 17:fa1bba4c6053 307 }
AzureIoTClient 17:fa1bba4c6053 308 else
AzureIoTClient 17:fa1bba4c6053 309 {
AzureIoTClient 17:fa1bba4c6053 310 /*Codes_SRS_SERIALIZERDEVICETWIN_02_015: [ IoTHubDeviceTwin_Destroy_Impl shall locate the saved handle belonging to model. ]*/
AzureIoTClient 17:fa1bba4c6053 311 SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle = (SERIALIZER_DEVICETWIN_PROTOHANDLE*)VECTOR_find_if(g_allProtoHandles, protoHandleHasDeviceStartAddress, model);
AzureIoTClient 17:fa1bba4c6053 312 if (protoHandle == NULL)
AzureIoTClient 17:fa1bba4c6053 313 {
AzureIoTClient 17:fa1bba4c6053 314 LogError("failure in VECTOR_find_if [not found]");
AzureIoTClient 17:fa1bba4c6053 315 }
AzureIoTClient 17:fa1bba4c6053 316 else
AzureIoTClient 17:fa1bba4c6053 317 {
AzureIoTClient 17:fa1bba4c6053 318 /*Codes_SRS_SERIALIZERDEVICETWIN_02_016: [ IoTHubDeviceTwin_Destroy_Impl shall set the devicetwin callback to NULL. ]*/
AzureIoTClient 17:fa1bba4c6053 319 switch (protoHandle->iothubClientHandleVariant.iothubClientHandleType)
AzureIoTClient 17:fa1bba4c6053 320 {
AzureIoTClient 17:fa1bba4c6053 321 case IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE:
AzureIoTClient 17:fa1bba4c6053 322 {
AzureIoTClient 17:fa1bba4c6053 323 if (IoTHubClient_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 324 {
AzureIoTClient 17:fa1bba4c6053 325 LogError("failure in IoTHubClient_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 326 }
Azure.IoT.Build 18:58b667752399 327 /*Codes_SRS_SERIALIZERDEVICETWIN_02_028: [ IoTHubDeviceTwin_Destroy_Impl shall set the method callback to NULL. ]*/
Azure.IoT.Build 18:58b667752399 328 if (IoTHubClient_SetDeviceMethodCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
Azure.IoT.Build 18:58b667752399 329 {
Azure.IoT.Build 18:58b667752399 330 LogError("failure in IoTHubClient_SetDeviceMethodCallback");
Azure.IoT.Build 18:58b667752399 331 }
AzureIoTClient 17:fa1bba4c6053 332 break;
AzureIoTClient 17:fa1bba4c6053 333 }
AzureIoTClient 17:fa1bba4c6053 334 case IOTHUB_CLIENT_LL_HANDLE_TYPE:
AzureIoTClient 17:fa1bba4c6053 335 {
AzureIoTClient 17:fa1bba4c6053 336 if (IoTHubClient_LL_SetDeviceTwinCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
AzureIoTClient 17:fa1bba4c6053 337 {
AzureIoTClient 17:fa1bba4c6053 338 LogError("failure in IoTHubClient_LL_SetDeviceTwinCallback");
AzureIoTClient 17:fa1bba4c6053 339 }
Azure.IoT.Build 18:58b667752399 340 /*Codes_SRS_SERIALIZERDEVICETWIN_02_028: [ IoTHubDeviceTwin_Destroy_Impl shall set the method callback to NULL. ]*/
Azure.IoT.Build 18:58b667752399 341 if (IoTHubClient_LL_SetDeviceMethodCallback(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, NULL, NULL) != IOTHUB_CLIENT_OK)
Azure.IoT.Build 18:58b667752399 342 {
Azure.IoT.Build 18:58b667752399 343 LogError("failure in IoTHubClient_LL_SetDeviceMethodCallback");
Azure.IoT.Build 18:58b667752399 344 }
AzureIoTClient 17:fa1bba4c6053 345 break;
AzureIoTClient 17:fa1bba4c6053 346 }
AzureIoTClient 17:fa1bba4c6053 347 default:
AzureIoTClient 17:fa1bba4c6053 348 {
AzureIoTClient 17:fa1bba4c6053 349 LogError("INTERNAL ERROR");
AzureIoTClient 17:fa1bba4c6053 350 }
AzureIoTClient 17:fa1bba4c6053 351 }/*switch*/
AzureIoTClient 34:87d7cd4169c6 352
AzureIoTClient 34:87d7cd4169c6 353 /*Codes_SRS_SERIALIZERDEVICETWIN_02_017: [ IoTHubDeviceTwin_Destroy_Impl shall call CodeFirst_DestroyDevice. ]*/
AzureIoTClient 34:87d7cd4169c6 354 CodeFirst_DestroyDevice(protoHandle->deviceAssigned);
AzureIoTClient 17:fa1bba4c6053 355
AzureIoTClient 34:87d7cd4169c6 356 /*Codes_SRS_SERIALIZERDEVICETWIN_02_018: [ IoTHubDeviceTwin_Destroy_Impl shall remove the IoTHubClient_Handle and the device handle from the recorded set. ]*/
AzureIoTClient 34:87d7cd4169c6 357 VECTOR_erase(g_allProtoHandles, protoHandle, 1);
AzureIoTClient 34:87d7cd4169c6 358 }
AzureIoTClient 17:fa1bba4c6053 359
AzureIoTClient 17:fa1bba4c6053 360 /*Codes_SRS_SERIALIZERDEVICETWIN_02_019: [ If the recorded set of IoTHubClient handles is zero size, then the set shall be destroyed. ]*/
AzureIoTClient 17:fa1bba4c6053 361 if (VECTOR_size(g_allProtoHandles) == 0) /*lazy init means more work @ destroy time*/
AzureIoTClient 17:fa1bba4c6053 362 {
AzureIoTClient 17:fa1bba4c6053 363 VECTOR_destroy(g_allProtoHandles);
AzureIoTClient 17:fa1bba4c6053 364 g_allProtoHandles = NULL;
AzureIoTClient 17:fa1bba4c6053 365 }
AzureIoTClient 17:fa1bba4c6053 366 }
AzureIoTClient 17:fa1bba4c6053 367 }
AzureIoTClient 17:fa1bba4c6053 368
Azure.IoT.Build 18:58b667752399 369 /*the below function sends the reported state of a model previously created by IoTHubDeviceTwin_Create*/
Azure.IoT.Build 18:58b667752399 370 /*this function serves both the _LL and the convenience layer because of protohandles*/
Azure.IoT.Build 18:58b667752399 371 static IOTHUB_CLIENT_RESULT IoTHubDeviceTwin_SendReportedState_Impl(void* model, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK deviceTwinCallback, void* context)
Azure.IoT.Build 18:58b667752399 372 {
Azure.IoT.Build 18:58b667752399 373 unsigned char*buffer;
Azure.IoT.Build 18:58b667752399 374 size_t bufferSize;
Azure.IoT.Build 18:58b667752399 375
Azure.IoT.Build 18:58b667752399 376 IOTHUB_CLIENT_RESULT result;
Azure.IoT.Build 18:58b667752399 377
Azure.IoT.Build 18:58b667752399 378 if (SERIALIZE_REPORTED_PROPERTIES_FROM_POINTERS(&buffer, &bufferSize, model) != CODEFIRST_OK)
Azure.IoT.Build 18:58b667752399 379 {
Azure.IoT.Build 18:58b667752399 380 LogError("Failed serializing reported state");
Azure.IoT.Build 18:58b667752399 381 result = IOTHUB_CLIENT_ERROR;
Azure.IoT.Build 18:58b667752399 382 }
Azure.IoT.Build 18:58b667752399 383 else
Azure.IoT.Build 18:58b667752399 384 {
Azure.IoT.Build 18:58b667752399 385 SERIALIZER_DEVICETWIN_PROTOHANDLE* protoHandle = (SERIALIZER_DEVICETWIN_PROTOHANDLE*)VECTOR_find_if(g_allProtoHandles, protoHandleHasDeviceStartAddress, model);
Azure.IoT.Build 18:58b667752399 386 if (protoHandle == NULL)
Azure.IoT.Build 18:58b667752399 387 {
Azure.IoT.Build 18:58b667752399 388 LogError("failure in VECTOR_find_if [not found]");
Azure.IoT.Build 18:58b667752399 389 result = IOTHUB_CLIENT_ERROR;
Azure.IoT.Build 18:58b667752399 390 }
Azure.IoT.Build 18:58b667752399 391 else
Azure.IoT.Build 18:58b667752399 392 {
Azure.IoT.Build 18:58b667752399 393 switch (protoHandle->iothubClientHandleVariant.iothubClientHandleType)
Azure.IoT.Build 18:58b667752399 394 {
Azure.IoT.Build 18:58b667752399 395 case IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE:
Azure.IoT.Build 18:58b667752399 396 {
Azure.IoT.Build 18:58b667752399 397 if (IoTHubClient_SendReportedState(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle, buffer, bufferSize, deviceTwinCallback, context) != IOTHUB_CLIENT_OK)
Azure.IoT.Build 18:58b667752399 398 {
Azure.IoT.Build 18:58b667752399 399 LogError("Failure sending data");
Azure.IoT.Build 18:58b667752399 400 result = IOTHUB_CLIENT_ERROR;
Azure.IoT.Build 18:58b667752399 401 }
Azure.IoT.Build 18:58b667752399 402 else
Azure.IoT.Build 18:58b667752399 403 {
Azure.IoT.Build 18:58b667752399 404 result = IOTHUB_CLIENT_OK;
Azure.IoT.Build 18:58b667752399 405 }
Azure.IoT.Build 18:58b667752399 406 break;
Azure.IoT.Build 18:58b667752399 407 }
Azure.IoT.Build 18:58b667752399 408 case IOTHUB_CLIENT_LL_HANDLE_TYPE:
Azure.IoT.Build 18:58b667752399 409 {
Azure.IoT.Build 18:58b667752399 410 if (IoTHubClient_LL_SendReportedState(protoHandle->iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle, buffer, bufferSize, deviceTwinCallback, context) != IOTHUB_CLIENT_OK)
Azure.IoT.Build 18:58b667752399 411 {
Azure.IoT.Build 18:58b667752399 412 LogError("Failure sending data");
Azure.IoT.Build 18:58b667752399 413 result = IOTHUB_CLIENT_ERROR;
Azure.IoT.Build 18:58b667752399 414 }
Azure.IoT.Build 18:58b667752399 415 else
Azure.IoT.Build 18:58b667752399 416 {
Azure.IoT.Build 18:58b667752399 417 result = IOTHUB_CLIENT_OK;
Azure.IoT.Build 18:58b667752399 418 }
Azure.IoT.Build 18:58b667752399 419 break;
Azure.IoT.Build 18:58b667752399 420 }
Azure.IoT.Build 18:58b667752399 421 default:
Azure.IoT.Build 18:58b667752399 422 {
Azure.IoT.Build 18:58b667752399 423 LogError("INTERNAL ERROR: unexpected value for enum (%d)", (int)protoHandle->iothubClientHandleVariant.iothubClientHandleType);
Azure.IoT.Build 18:58b667752399 424 result = IOTHUB_CLIENT_ERROR;
Azure.IoT.Build 18:58b667752399 425 break;
Azure.IoT.Build 18:58b667752399 426 }
Azure.IoT.Build 18:58b667752399 427 }
Azure.IoT.Build 18:58b667752399 428 }
Azure.IoT.Build 18:58b667752399 429 free(buffer);
Azure.IoT.Build 18:58b667752399 430 }
Azure.IoT.Build 18:58b667752399 431 return result;
Azure.IoT.Build 18:58b667752399 432 }
Azure.IoT.Build 18:58b667752399 433
AzureIoTClient 17:fa1bba4c6053 434 #define DECLARE_DEVICETWIN_MODEL(name, ...) \
AzureIoTClient 17:fa1bba4c6053 435 DECLARE_MODEL(name, __VA_ARGS__) \
AzureIoTClient 17:fa1bba4c6053 436 static name* C2(IoTHubDeviceTwin_Create, name)(IOTHUB_CLIENT_HANDLE iotHubClientHandle) \
AzureIoTClient 17:fa1bba4c6053 437 { \
AzureIoTClient 17:fa1bba4c6053 438 SERIALIZER_DEVICETWIN_PROTOHANDLE protoHandle; \
AzureIoTClient 17:fa1bba4c6053 439 protoHandle.iothubClientHandleVariant.iothubClientHandleType = IOTHUB_CLIENT_CONVENIENCE_HANDLE_TYPE; \
AzureIoTClient 17:fa1bba4c6053 440 protoHandle.iothubClientHandleVariant.iothubClientHandleValue.iothubClientHandle = iotHubClientHandle; \
AzureIoTClient 17:fa1bba4c6053 441 return (name*)IoTHubDeviceTwinCreate_Impl(#name, sizeof(name), &protoHandle); \
AzureIoTClient 17:fa1bba4c6053 442 } \
AzureIoTClient 17:fa1bba4c6053 443 \
AzureIoTClient 17:fa1bba4c6053 444 static void C2(IoTHubDeviceTwin_Destroy, name) (name* model) \
AzureIoTClient 17:fa1bba4c6053 445 { \
AzureIoTClient 17:fa1bba4c6053 446 IoTHubDeviceTwin_Destroy_Impl(model); \
AzureIoTClient 17:fa1bba4c6053 447 } \
AzureIoTClient 17:fa1bba4c6053 448 \
AzureIoTClient 17:fa1bba4c6053 449 static name* C2(IoTHubDeviceTwin_LL_Create, name)(IOTHUB_CLIENT_LL_HANDLE iotHubClientLLHandle) \
AzureIoTClient 17:fa1bba4c6053 450 { \
AzureIoTClient 17:fa1bba4c6053 451 SERIALIZER_DEVICETWIN_PROTOHANDLE protoHandle; \
AzureIoTClient 17:fa1bba4c6053 452 protoHandle.iothubClientHandleVariant.iothubClientHandleType = IOTHUB_CLIENT_LL_HANDLE_TYPE; \
AzureIoTClient 17:fa1bba4c6053 453 protoHandle.iothubClientHandleVariant.iothubClientHandleValue.iothubClientLLHandle = iotHubClientLLHandle; \
AzureIoTClient 17:fa1bba4c6053 454 return (name*)IoTHubDeviceTwinCreate_Impl(#name, sizeof(name), &protoHandle); \
AzureIoTClient 17:fa1bba4c6053 455 } \
AzureIoTClient 17:fa1bba4c6053 456 \
AzureIoTClient 17:fa1bba4c6053 457 static void C2(IoTHubDeviceTwin_LL_Destroy, name) (name* model) \
AzureIoTClient 17:fa1bba4c6053 458 { \
AzureIoTClient 17:fa1bba4c6053 459 IoTHubDeviceTwin_Destroy_Impl(model); \
AzureIoTClient 17:fa1bba4c6053 460 } \
Azure.IoT.Build 18:58b667752399 461 static IOTHUB_CLIENT_RESULT C2(IoTHubDeviceTwin_LL_SendReportedState, name) (name* model, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK deviceTwinCallback, void* context) \
Azure.IoT.Build 18:58b667752399 462 { \
Azure.IoT.Build 18:58b667752399 463 return IoTHubDeviceTwin_SendReportedState_Impl(model, deviceTwinCallback, context); \
Azure.IoT.Build 18:58b667752399 464 } \
Azure.IoT.Build 18:58b667752399 465 static IOTHUB_CLIENT_RESULT C2(IoTHubDeviceTwin_SendReportedState, name) (name* model, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK deviceTwinCallback, void* context) \
Azure.IoT.Build 18:58b667752399 466 { \
Azure.IoT.Build 18:58b667752399 467 return IoTHubDeviceTwin_SendReportedState_Impl(model, deviceTwinCallback, context); \
Azure.IoT.Build 18:58b667752399 468 } \
AzureIoTClient 17:fa1bba4c6053 469
AzureIoTClient 17:fa1bba4c6053 470 #endif /*SERIALIZER_DEVICE_TWIN_H*/
AzureIoTClient 17:fa1bba4c6053 471
AzureIoTClient 17:fa1bba4c6053 472