Azure IoT / serializer

Dependents:   sht15_remote_monitoring f767zi_mqtt remote_monitoring simplesample_amqp ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers iotdevice.c Source File

iotdevice.c

00001 // Copyright (c) Microsoft. All rights reserved.
00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
00003 
00004 #include <stdlib.h>
00005 #include "azure_c_shared_utility/gballoc.h"
00006 
00007 #include <stdbool.h>
00008 #include "iotdevice.h"
00009 #include "datapublisher.h"
00010 #include "commanddecoder.h"
00011 #include "azure_c_shared_utility/crt_abstractions.h"
00012 #include "azure_c_shared_utility/xlogging.h"
00013 
00014 #define LOG_DEVICE_ERROR \
00015     LogError("(result = %s)", ENUM_TO_STRING(DEVICE_RESULT, result))
00016 
00017 
00018 
00019 typedef struct DEVICE_HANDLE_DATA_TAG
00020 {
00021     SCHEMA_MODEL_TYPE_HANDLE model;
00022     DATA_PUBLISHER_HANDLE dataPublisherHandle;
00023     pfDeviceActionCallback deviceActionCallback;
00024     void* callbackUserContext;
00025     pfDeviceMethodCallback deviceMethodCallback;
00026     void* methodCallbackUserContext;
00027 
00028     COMMAND_DECODER_HANDLE commandDecoderHandle;
00029 } DEVICE_HANDLE_DATA;
00030 
00031 DEFINE_ENUM_STRINGS(DEVICE_RESULT, DEVICE_RESULT_VALUES);
00032 
00033 static EXECUTE_COMMAND_RESULT DeviceInvokeAction(void* actionCallbackContext, const char* relativeActionPath, const char* actionName, size_t argCount, const AGENT_DATA_TYPE* args)
00034 {
00035     EXECUTE_COMMAND_RESULT result;
00036 
00037     /*Codes_SRS_DEVICE_02_011: [If the parameter actionCallbackContent passed the callback is NULL then the callback shall return EXECUTE_COMMAND_ERROR.] */
00038     if (actionCallbackContext == NULL)
00039     {
00040         result = EXECUTE_COMMAND_ERROR;
00041         LogError("(Error code = %s)", ENUM_TO_STRING(DEVICE_RESULT, DEVICE_INVALID_ARG));
00042     }
00043     else
00044     {
00045         DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)actionCallbackContext;
00046 
00047         /* Codes_SRS_DEVICE_01_052: [When the action callback passed to CommandDecoder is called, Device shall call the appropriate user callback associated with the device handle.] */
00048         /* Codes_SRS_DEVICE_01_055: [The value passed in callbackUserContext when creating the device shall be passed to the callback as the value for the callbackUserContext argument.] */
00049         result = device->deviceActionCallback((DEVICE_HANDLE)device, device->callbackUserContext, relativeActionPath, actionName, argCount, args);
00050     }
00051 
00052     return result;
00053 }
00054 
00055 static METHODRETURN_HANDLE DeviceInvokeMethod(void* methodCallbackContext, const char* relativeMethodPath, const char* methodName, size_t argCount, const AGENT_DATA_TYPE* args)
00056 {
00057     METHODRETURN_HANDLE result;
00058 
00059     if (methodCallbackContext == NULL)
00060     {
00061         result = NULL;
00062         LogError("(Error code = %s)", ENUM_TO_STRING(DEVICE_RESULT, DEVICE_INVALID_ARG));
00063     }
00064     else
00065     {
00066         DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)methodCallbackContext;
00067 
00068         result = device->deviceMethodCallback((DEVICE_HANDLE)device, device->methodCallbackUserContext, relativeMethodPath, methodName, argCount, args);
00069     }
00070 
00071     return result;
00072 }
00073 
00074 DEVICE_RESULT Device_Create(SCHEMA_MODEL_TYPE_HANDLE modelHandle, pfDeviceActionCallback deviceActionCallback, void* callbackUserContext, pfDeviceMethodCallback methodCallback, void* methodCallbackContext, bool includePropertyPath, DEVICE_HANDLE* deviceHandle)
00075 {
00076     DEVICE_RESULT result;
00077 
00078     /* Codes_SRS_DEVICE_05_014: [If any of the modelHandle, deviceHandle or deviceActionCallback arguments are NULL, Device_Create shall return DEVICE_INVALID_ARG.]*/
00079     if (modelHandle == NULL || deviceHandle == NULL || deviceActionCallback == NULL || methodCallback == NULL || methodCallbackContext == NULL)
00080     {
00081         result = DEVICE_INVALID_ARG;
00082         LOG_DEVICE_ERROR;
00083     }
00084     else
00085     {
00086         DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)malloc(sizeof(DEVICE_HANDLE_DATA));
00087         if (device == NULL)
00088         {
00089             /* Codes_SRS_DEVICE_05_015: [If an error occurs while trying to create the device, Device_Create shall return DEVICE_ERROR.] */
00090             result = DEVICE_ERROR;
00091             LOG_DEVICE_ERROR;
00092         }
00093         else
00094         {
00095             /* Codes_SRS_DEVICE_01_018: [Device_Create shall create a DataPublisher instance by calling DataPublisher_Create.] */
00096             /* Codes_SRS_DEVICE_01_020: [Device_Create shall pass to DataPublisher_Create the FrontDoor instance obtained earlier.] */
00097             /* Codes_SRS_DEVICE_01_004: [DeviceCreate shall pass to DataPublisher_create the includePropertyPath argument.] */
00098             if ((device->dataPublisherHandle = DataPublisher_Create(modelHandle, includePropertyPath)) == NULL)
00099             {
00100                 free(device);
00101 
00102                 /* Codes_SRS_DEVICE_01_019: [If creating the DataPublisher instance fails, Device_Create shall return DEVICE_DATA_PUBLISHER_FAILED.] */
00103                 result = DEVICE_DATA_PUBLISHER_FAILED;
00104                 LOG_DEVICE_ERROR;
00105             }
00106             else
00107             {
00108                 device->model = modelHandle;
00109                 device->deviceActionCallback = deviceActionCallback;
00110                 device->callbackUserContext = callbackUserContext;
00111                 device->deviceMethodCallback = methodCallback;
00112                 device->methodCallbackUserContext = methodCallbackContext;
00113 
00114                 /* Codes_SRS_DEVICE_01_001: [Device_Create shall create a CommandDecoder instance by calling CommandDecoder_Create and passing to it the model handle.] */
00115                 /* Codes_SRS_DEVICE_01_002: [Device_Create shall also pass to CommandDecoder_Create a callback to be invoked when a command is received and a context that shall be the device handle.] */
00116                 if ((device->commandDecoderHandle = CommandDecoder_Create(modelHandle, DeviceInvokeAction, device, DeviceInvokeMethod, device)) == NULL)
00117                 {
00118                     DataPublisher_Destroy(device->dataPublisherHandle);
00119                     free(device);
00120 
00121                     /* Codes_SRS_DEVICE_01_003: [If CommandDecoder_Create fails, Device_Create shall return DEVICE_COMMAND_DECODER_FAILED.] */
00122                     result = DEVICE_COMMAND_DECODER_FAILED;
00123                     LOG_DEVICE_ERROR;
00124                 }
00125                 else
00126                 {
00127                     /* Codes_SRS_DEVICE_03_003: [The DEVICE_HANDLE shall be provided via the deviceHandle out argument.] */
00128                     *deviceHandle = (DEVICE_HANDLE)device;
00129                     /* Codes_SRS_DEVICE_03_004: [Device_Create shall return DEVICE_OK upon success.] */
00130                     result = DEVICE_OK;
00131                 }
00132             }
00133         }
00134     }
00135 
00136     return result;
00137 }
00138 
00139 /* Codes_SRS_DEVICE_03_006: [Device_Destroy shall free all resources associated with a device.] */
00140 void Device_Destroy(DEVICE_HANDLE deviceHandle)
00141 {
00142     /* Codes_SRS_DEVICE_03_007: [Device_Destroy will not do anything if deviceHandle is NULL.] */
00143     if (deviceHandle != NULL)
00144     {
00145         DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)deviceHandle;
00146 
00147         DataPublisher_Destroy(device->dataPublisherHandle);
00148         CommandDecoder_Destroy(device->commandDecoderHandle);
00149 
00150         free(device);
00151     }
00152 }
00153 
00154 TRANSACTION_HANDLE Device_StartTransaction(DEVICE_HANDLE deviceHandle)
00155 {
00156     TRANSACTION_HANDLE result;
00157 
00158     /* Codes_SRS_DEVICE_01_035: [If any argument is NULL, Device_StartTransaction shall return NULL.] */
00159     if (deviceHandle == NULL)
00160     {
00161         result = NULL;
00162         LogError("(Error code = %s)", ENUM_TO_STRING(DEVICE_RESULT, DEVICE_INVALID_ARG));
00163     }
00164     else
00165     {
00166         DEVICE_HANDLE_DATA* deviceInstance = (DEVICE_HANDLE_DATA*)deviceHandle;
00167 
00168         /* Codes_SRS_DEVICE_01_034: [Device_StartTransaction shall invoke DataPublisher_StartTransaction for the DataPublisher handle associated with the deviceHandle argument.] */
00169         /* Codes_SRS_DEVICE_01_043: [On success, Device_StartTransaction shall return a non NULL handle.] */
00170         /* Codes_SRS_DEVICE_01_048: [When DataPublisher_StartTransaction fails, Device_StartTransaction shall return NULL.] */
00171         result = DataPublisher_StartTransaction(deviceInstance->dataPublisherHandle);
00172     }
00173 
00174     return result;
00175 }
00176 
00177 DEVICE_RESULT Device_PublishTransacted(TRANSACTION_HANDLE transactionHandle, const char* propertyPath, const AGENT_DATA_TYPE* data)
00178 {
00179     DEVICE_RESULT result;
00180 
00181     /* Codes_SRS_DEVICE_01_037: [If any argument is NULL, Device_PublishTransacted shall return DEVICE_INVALID_ARG.] */
00182     if (
00183         (transactionHandle == NULL) ||
00184         (propertyPath == NULL) ||
00185         (data == NULL)
00186        )
00187     {
00188         result = DEVICE_INVALID_ARG;
00189         LOG_DEVICE_ERROR;
00190     }
00191     /* Codes_SRS_DEVICE_01_036: [Device_PublishTransacted shall invoke DataPublisher_PublishTransacted.] */
00192     else if (DataPublisher_PublishTransacted(transactionHandle, propertyPath, data) != DATA_PUBLISHER_OK)
00193     {
00194         /* Codes_SRS_DEVICE_01_049: [When DataPublisher_PublishTransacted fails, Device_PublishTransacted shall return DEVICE_DATA_PUBLISHER_FAILED.] */
00195         result = DEVICE_DATA_PUBLISHER_FAILED;
00196         LOG_DEVICE_ERROR;
00197     }
00198     else
00199     {
00200         /* Codes_SRS_DEVICE_01_044: [On success, Device_PublishTransacted shall return DEVICE_OK.] */
00201         result = DEVICE_OK;
00202     }
00203 
00204     return result;
00205 }
00206 
00207 DEVICE_RESULT Device_EndTransaction(TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize)
00208 {
00209     DEVICE_RESULT result;
00210 
00211     /* Codes_SRS_DEVICE_01_039: [If any parameter is NULL, Device_EndTransaction shall return DEVICE_INVALID_ARG.]*/
00212     if (
00213         (transactionHandle == NULL) ||
00214         (destination == NULL) ||
00215         (destinationSize == NULL)
00216         )
00217     {
00218         result = DEVICE_INVALID_ARG;
00219         LOG_DEVICE_ERROR;
00220     }
00221     /* Codes_SRS_DEVICE_01_038: [Device_EndTransaction shall invoke DataPublisher_EndTransaction.] */
00222     else if (DataPublisher_EndTransaction(transactionHandle, destination, destinationSize) != DATA_PUBLISHER_OK)
00223     {
00224         /* Codes_SRS_DEVICE_01_050: [When DataPublisher_EndTransaction fails, Device_EndTransaction shall return DEVICE_DATA_PUBLISHER_FAILED.] */
00225         result = DEVICE_DATA_PUBLISHER_FAILED;
00226         LOG_DEVICE_ERROR;
00227     }
00228     else
00229     {
00230         /* Codes_SRS_DEVICE_01_045: [On success, Device_EndTransaction shall return DEVICE_OK.] */
00231         result = DEVICE_OK;
00232     }
00233 
00234     return result;
00235 }
00236 
00237 DEVICE_RESULT Device_CancelTransaction(TRANSACTION_HANDLE transactionHandle)
00238 {
00239     DEVICE_RESULT result;
00240 
00241     /* Codes_SRS_DEVICE_01_041: [If any argument is NULL, Device_CancelTransaction shall return DEVICE_INVALID_ARG.] */
00242     if (transactionHandle == NULL)
00243     {
00244         result = DEVICE_INVALID_ARG;
00245         LOG_DEVICE_ERROR;
00246     }
00247     /* Codes_SRS_DEVICE_01_040: [Device_CancelTransaction shall invoke DataPublisher_CancelTransaction.] */
00248     else if (DataPublisher_CancelTransaction(transactionHandle) != DATA_PUBLISHER_OK)
00249     {
00250         /* Codes_SRS_DEVICE_01_051: [When DataPublisher_CancelTransaction fails, Device_CancelTransaction shall return DEVICE_DATA_PUBLISHER_FAILED.] */
00251         result = DEVICE_DATA_PUBLISHER_FAILED;
00252         LOG_DEVICE_ERROR;
00253     }
00254     else
00255     {
00256         /* Codes_SRS_DEVICE_01_046: [On success, Device_PublishTransacted shall return DEVICE_OK.] */
00257         result = DEVICE_OK;
00258     }
00259 
00260     return result;
00261 }
00262 
00263 EXECUTE_COMMAND_RESULT Device_ExecuteCommand(DEVICE_HANDLE deviceHandle, const char* command)
00264 {
00265     EXECUTE_COMMAND_RESULT result;
00266     /*Codes_SRS_DEVICE_02_012: [If any parameters are NULL, then Device_ExecuteCommand shall return EXECUTE_COMMAND_ERROR.] */
00267     if (
00268         (deviceHandle == NULL) ||
00269         (command == NULL)
00270         )
00271     {
00272         result = EXECUTE_COMMAND_ERROR;
00273         LogError("invalid parameter (NULL passed to Device_ExecuteCommand DEVICE_HANDLE deviceHandle=%p, const char* command=%p", deviceHandle, command);
00274     }
00275     else
00276     {
00277         /*Codes_SRS_DEVICE_02_013: [Otherwise, Device_ExecuteCommand shall call CommandDecoder_ExecuteCommand and return what CommandDecoder_ExecuteCommand is returning.] */
00278         DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)deviceHandle;
00279         result = CommandDecoder_ExecuteCommand(device->commandDecoderHandle, command);
00280     }
00281     return result;
00282 }
00283 
00284 METHODRETURN_HANDLE Device_ExecuteMethod(DEVICE_HANDLE deviceHandle, const char* methodName, const char* methodPayload)
00285 {
00286     METHODRETURN_HANDLE result;
00287     if (
00288         (deviceHandle == NULL) ||
00289         (methodName == NULL) /*methodPayload can be NULL*/
00290         )
00291     {
00292         result = NULL;
00293         LogError("invalid parameter (NULL passed to Device_ExecuteMethod DEVICE_HANDLE deviceHandle=%p, const char* methodPayload=%p", deviceHandle, methodPayload);
00294     }
00295     else
00296     {
00297         DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)deviceHandle;
00298         result = CommandDecoder_ExecuteMethod(device->commandDecoderHandle, methodName, methodPayload);
00299     }
00300     return result;
00301 }
00302 
00303 REPORTED_PROPERTIES_TRANSACTION_HANDLE Device_CreateTransaction_ReportedProperties(DEVICE_HANDLE deviceHandle)
00304 {
00305     REPORTED_PROPERTIES_TRANSACTION_HANDLE result;
00306 
00307     /*Codes_SRS_DEVICE_02_014: [ If argument deviceHandle is NULL then Device_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
00308     if (deviceHandle == NULL)
00309     {
00310         LogError("invalid argument DEVICE_HANDLE deviceHandle=%p", deviceHandle);
00311         result = NULL;
00312     }
00313     else
00314     {
00315         DEVICE_HANDLE_DATA* deviceInstance = (DEVICE_HANDLE_DATA*)deviceHandle;
00316         /*Codes_SRS_DEVICE_02_015: [ Otherwise, Device_CreateTransaction_ReportedProperties shall call DataPublisher_CreateTransaction_ReportedProperties. ]*/
00317         /*Codes_SRS_DEVICE_02_016: [ If DataPublisher_CreateTransaction_ReportedProperties fails then Device_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
00318         /*Codes_SRS_DEVICE_02_017: [ Otherwise Device_CreateTransaction_ReportedProperties shall succeed and return a non-NULL value. ]*/
00319         result = DataPublisher_CreateTransaction_ReportedProperties(deviceInstance->dataPublisherHandle);
00320         if (result == NULL)
00321         {
00322             LogError("unable to DataPublisher_CreateTransaction_ReportedProperties");
00323             /*return as is*/
00324         }
00325         else
00326         {
00327             /*return as is*/
00328         }
00329     }
00330 
00331     return result;
00332 }
00333 
00334 DEVICE_RESULT Device_PublishTransacted_ReportedProperty(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, const char* reportedPropertyPath, const AGENT_DATA_TYPE* data)
00335 {
00336     DEVICE_RESULT result;
00337     /*Codes_SRS_DEVICE_02_018: [ If argument transactionHandle is NULL then Device_PublishTransacted_ReportedProperty shall fail and return DEVICE_INVALID_ARG. ]*/
00338     /*Codes_SRS_DEVICE_02_019: [ If argument reportedPropertyPath is NULL then Device_PublishTransacted_ReportedProperty shall fail and return DEVICE_INVALID_ARG. ]*/
00339     /*Codes_SRS_DEVICE_02_020: [ If argument data is NULL then Device_PublishTransacted_ReportedProperty shall fail and return DEVICE_INVALID_ARG. ]*/
00340     if (
00341         (transactionHandle == NULL) ||
00342         (reportedPropertyPath == NULL) ||
00343         (data == NULL)
00344         )
00345     {
00346         LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, const char* reportedPropertyPath=%s, const AGENT_DATA_TYPE* data=%p", transactionHandle, reportedPropertyPath, data);
00347         result = DEVICE_INVALID_ARG;
00348     }
00349     else
00350     {
00351         /*Codes_SRS_DEVICE_02_021: [ Device_PublishTransacted_ReportedProperty shall call DataPublisher_PublishTransacted_ReportedProperty. ]*/
00352         DATA_PUBLISHER_RESULT r = DataPublisher_PublishTransacted_ReportedProperty(transactionHandle, reportedPropertyPath, data);
00353         if (r != DATA_PUBLISHER_OK)
00354         {
00355             LogError("unable to DataPublisher_PublishTransacted_ReportedProperty");
00356             /*Codes_SRS_DEVICE_02_022: [ If DataPublisher_PublishTransacted_ReportedProperty fails then Device_PublishTransacted_ReportedProperty shall fail and return DEVICE_DATA_PUBLISHER_FAILED. ]*/
00357             result = DEVICE_DATA_PUBLISHER_FAILED;
00358         }
00359         else
00360         {
00361             /*Codes_SRS_DEVICE_02_023: [ Otherwise, Device_PublishTransacted_ReportedProperty shall succeed and return DEVICE_OK. ]*/
00362             result = DEVICE_OK;
00363         }
00364     }
00365     return result;
00366 }
00367 
00368 DEVICE_RESULT Device_CommitTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize)
00369 {
00370     DEVICE_RESULT result;
00371 
00372     /*Codes_SRS_DEVICE_02_024: [ If argument transactionHandle is NULL then Device_CommitTransaction_ReportedProperties shall fail and return DEVICE_INVALID_ARG. ]*/
00373     /*Codes_SRS_DEVICE_02_025: [ If argument destination is NULL then Device_CommitTransaction_ReportedProperties shall fail and return DEVICE_INVALID_ARG. ]*/
00374     /*Codes_SRS_DEVICE_02_026: [ If argument destinationSize is NULL then Device_CommitTransaction_ReportedProperties shall fail and return DEVICE_INVALID_ARG. ]*/
00375     if (
00376         (transactionHandle == NULL) ||
00377         (destination == NULL) ||
00378         (destinationSize == NULL)
00379         )
00380     {
00381         LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, unsigned char** destination=%p, size_t* destinationSize=%p", transactionHandle, destination, destinationSize);
00382         result = DEVICE_INVALID_ARG;
00383     }
00384     else
00385     {
00386         /*Codes_SRS_DEVICE_02_027: [ Device_CommitTransaction_ReportedProperties shall call DataPublisher_CommitTransaction_ReportedProperties. ]*/
00387         DATA_PUBLISHER_RESULT r = DataPublisher_CommitTransaction_ReportedProperties(transactionHandle, destination, destinationSize);
00388 
00389         /*Codes_SRS_DEVICE_02_028: [ If DataPublisher_CommitTransaction_ReportedProperties fails then Device_CommitTransaction_ReportedProperties shall fail and return DEVICE_DATA_PUBLISHER_FAILED. ]*/
00390         if (r != DATA_PUBLISHER_OK)
00391         {
00392             LogError("unable to DataPublisher_CommitTransaction_ReportedProperties");
00393             result = DEVICE_DATA_PUBLISHER_FAILED;
00394         }
00395         else
00396         {
00397             /*Codes_SRS_DEVICE_02_029: [ Otherwise Device_CommitTransaction_ReportedProperties shall succeed and return DEVICE_OK. ]*/
00398             result = DEVICE_OK;
00399         }
00400     }
00401     return result;
00402 }
00403 
00404 void Device_DestroyTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle)
00405 {
00406     /*Codes_SRS_DEVICE_02_030: [ If argument transactionHandle is NULL then Device_DestroyTransaction_ReportedProperties shall return. ]*/
00407     if (transactionHandle == NULL)
00408     {
00409         LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p", transactionHandle);
00410     }
00411     else
00412     {
00413         /*Codes_SRS_DEVICE_02_031: [ Otherwise Device_DestroyTransaction_ReportedProperties shall free all used resources. ]*/
00414         DataPublisher_DestroyTransaction_ReportedProperties(transactionHandle);
00415     }
00416 }
00417 
00418 DEVICE_RESULT Device_IngestDesiredProperties(void* startAddress, DEVICE_HANDLE deviceHandle, const char* jsonPayload, bool parseDesiredNode)
00419 {
00420     DEVICE_RESULT result;
00421     /*Codes_SRS_DEVICE_02_032: [ If deviceHandle is NULL then Device_IngestDesiredProperties shall fail and return DEVICE_INVALID_ARG. ]*/
00422     /*Codes_SRS_DEVICE_02_033: [ If jsonPayload is NULL then Device_IngestDesiredProperties shall fail and return DEVICE_INVALID_ARG. ]*/
00423     /*Codes_SRS_DEVICE_02_037: [ If startAddress is NULL then Device_IngestDesiredProperties shall fail and return DEVICE_INVALID_ARG. ]*/
00424     if (
00425         (deviceHandle == NULL) ||
00426         (jsonPayload == NULL) ||
00427         (startAddress == NULL)
00428         )
00429     {
00430         LogError("invalid argument void* startAddress=%p, DEVICE_HANDLE deviceHandle=%p, const char* jsonPayload=%p\n", startAddress, deviceHandle, jsonPayload);
00431         result = DEVICE_INVALID_ARG;
00432     }
00433     else
00434     {
00435         /*Codes_SRS_DEVICE_02_034: [ Device_IngestDesiredProperties shall call CommandDecoder_IngestDesiredProperties. ]*/
00436         DEVICE_HANDLE_DATA* device = (DEVICE_HANDLE_DATA*)deviceHandle;
00437         if (CommandDecoder_IngestDesiredProperties(startAddress, device->commandDecoderHandle, jsonPayload, parseDesiredNode) != EXECUTE_COMMAND_SUCCESS)
00438         {
00439             /*Codes_SRS_DEVICE_02_035: [ If any failure happens then Device_IngestDesiredProperties shall fail and return DEVICE_ERROR. ]*/
00440             LogError("failure in CommandDecoder_IngestDesiredProperties");
00441             result = DEVICE_ERROR;
00442         }
00443         else
00444         {
00445             /*Codes_SRS_DEVICE_02_036: [ Otherwise, Device_IngestDesiredProperties shall succeed and return DEVICE_OK. ]*/
00446             result = DEVICE_OK;
00447         }
00448     }
00449     return result;
00450 }