iothub_client/inc/iothub_client_properties.h (56 lines of code) (raw):
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
/** @file iothub_client_properties.h
* @brief APIs that serialize and deserialize properties modeled with DTDLv2.
*
* @details IoT Plug and Play devices are defined using the DTDLv2 modeling language described
* at https://github.com/Azure/opendigitaltwins-dtdl/blob/master/DTDL/v2/dtdlv2.md.
*
* Azure IoT Hub defines a set of conventions for parsing and creating DTDLv2
* properties that can be sent between Azure IoT Hub and devices connected to the Hub.
*
* The format is JSON based. It is possible to manually serialize and deserialize
* this payload following the documented convention. These APIs make this process easier.
* When serializing a property to be sent to IoT Hub, your application provides a C structure and
* the API returns a byte stream to be sent.
*
* When receiving properties from IoT Hub, the deserialization API converts a raw stream
* into an easier to process C structure with the JSON parsed out.
*
* These APIs do not invoke any network I/O. To actually send and receive data, these APIs
* will typically be paired with a corresponding IoT Hub device or module client.
*
* Pseudocode to demonstrate the relationship for serializing properties and clients:
* // Converts C structure into serialized stream.
* IOTHUB_CLIENT_PROPERTY_REPORTED reportedProps = { ... }; // Specific to your application
* IoTHubClient_Properties_Serializer_CreateReported(&reportedProps, &serializedByteStream);
* // Send the data
* IoTHubDeviceClient_LL_SendPropertiesAsync(deviceHandle, serializedByteStream);
*
* Pseudocode to demonstrate the relationship for deserializing properties and clients:
* // Request all device properties from IoT Hub
* IoTHubDeviceClient_LL_GetPropertiesAsync(deviceHandle, &yourAppCallback);
* // Time passes as request is processed...
* // ...
* // Your application's IOTHUB_CLIENT_PROPERTIES_RECEIVED_CALLBACK is eventually invoked.
* // Your application then will setup the deserializer handle based on the data from the network.
* // rawDataFromIoTHub below corresponds to data your IOTHUB_CLIENT_PROPERTIES_RECEIVED_CALLBACK
* // receives.
*
* void yourAppCallback(rawDataFromIoTHub, ...) // your IOTHUB_CLIENT_PROPERTIES_RECEIVED_CALLBACK implementation
* {
* // Create handle used in deserialization process below
* IoTHubClient_Properties_Deserializer_Create(rawDataFromIoTHub, &deserializationHandle)
*
* // Enumerate each received property. deserializedProperty will be of type
* // IOTHUB_CLIENT_PROPERTY_PARSED and is much easier to process than raw JSON.
* while (IoTHubClient_Properties_Deserializer_GetNext(&deserializationHandle, &deserializedProperty))
* {
* // Application processes deserializedProperty according to modeling rules
* // ...
* // Free memory allocated by IoTHubClient_Properties_Deserializer_GetNext
* IoTHubClient_Properties_DeserializerProperty_Destroy(&deserializedProperty);
* }
* // Free memory allocated by IoTHubClient_Properties_Deserializer_Create
* IoTHubClient_Properties_Deserializer_Destroy(deserializationHandle);
* }
*/
#ifndef IOTHUB_CLIENT_PROPERTIES_H
#define IOTHUB_CLIENT_PROPERTIES_H
#include "umock_c/umock_c_prod.h"
#include <stddef.h>
#include "iothub_client_core_common.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @brief Current version of @p IOTHUB_CLIENT_PROPERTY_REPORTED structure. */
#define IOTHUB_CLIENT_PROPERTY_REPORTED_STRUCT_VERSION_1 1
/** @brief This struct defines properties reported from the client. This corresponds to what DTDLv2 calls a
* "read-only property." This structure is filled out by the application and can be serialized into
* a payload for IoT Hub via @p IoTHubClient_Properties_Serializer_CreateReported(). */
typedef struct IOTHUB_CLIENT_PROPERTY_REPORTED_TAG {
/** @brief Version of the structure. Currently must be IOTHUB_CLIENT_PROPERTY_REPORTED_STRUCT_VERSION_1. */
int structVersion;
/** @brief Name of the property. */
const char* name;
/** @brief Value of the property. This must be legal JSON. Strings need to be escaped by the application, e.g. reported.value="\"MyValue\""; */
const char* value;
} IOTHUB_CLIENT_PROPERTY_REPORTED;
/** @brief Current version of @p IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE structure. */
#define IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE_STRUCT_VERSION_1 1
/** @brief This struct represents the response to a writable property that the client will return.
* This structure is filled out by the application and can be serialized into a payload for IoT Hub via
* @p IoTHubClient_Properties_Serializer_CreateWritableResponse(). */
typedef struct IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE_TAG {
/** @brief Version of the structure. Currently must be IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE_STRUCT_VERSION_1. */
int structVersion;
/** @brief Name of the property. */
const char* name;
/** @brief Value of the property. This must be legal JSON. Strings need to be escaped by the application, e.g. writeableResponse.value="\"MyValue\""; */
const char* value;
/** @brief Result of the requested operation. This maps to an HTTP status code. */
int result;
/** @brief Acknowledgement version. This corresponds to the version of the writable properties being responded to. */
/** @details If using @p IoTHubClient_Properties_Deserializer_Create() to deserialize initial property request
* from IoT Hub, just set this field to what was returned by @p IoTHubClient_Properties_Deserializer_GetVersion(). */
int ackVersion;
/** @brief Optional friendly description of the operation. May be NULL. */
const char* description;
} IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE;
/** @brief Enumeration that indicates whether a given property from the service was originally reported from the client
(and hence the client application sees what the last reported value IoT Hub has)
or whether this is a writable property that the service is requesting configuration for.
*/
#define IOTHUB_CLIENT_PROPERTY_TYPE_VALUES \
IOTHUB_CLIENT_PROPERTY_TYPE_REPORTED_FROM_CLIENT, \
IOTHUB_CLIENT_PROPERTY_TYPE_WRITABLE
MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_PROPERTY_TYPE, IOTHUB_CLIENT_PROPERTY_TYPE_VALUES);
/* @brief Enumeration that indicates whether the JSON value of a deserialized property
* is a null-terminated string or binary. Currently only STRING values are supported.
*/
#define IOTHUB_CLIENT_PROPERTY_VALUE_TYPE_VALUES \
IOTHUB_CLIENT_PROPERTY_VALUE_STRING
MU_DEFINE_ENUM_WITHOUT_INVALID(IOTHUB_CLIENT_PROPERTY_VALUE_TYPE, IOTHUB_CLIENT_PROPERTY_VALUE_TYPE_VALUES);
/** @brief Current version of @p #IOTHUB_CLIENT_PROPERTY_PARSED structure. */
#define IOTHUB_CLIENT_PROPERTY_PARSED_STRUCT_VERSION_1 1
/** @brief This struct represents a property from IoT Hub.
It is generated by IoTHubClient_Deserialize_Properties() while deserializing a property payload. */
typedef struct IOTHUB_CLIENT_PROPERTY_PARSED_TAG {
/** @brief Version of the structure. Currently must be IOTHUB_CLIENT_PROPERTY_PARSED_STRUCT_VERSION_1. */
int structVersion;
/** @brief Whether this is a property the client reported (and we're seeing what IoT Hub last received from
the client) or whether it's a writable property request from the client. */
IOTHUB_CLIENT_PROPERTY_TYPE propertyType;
/** @brief Name of the component. Optional; may be NULL for the root component. */
const char* componentName;
/** @brief Name of the property. */
const char* name;
/** @brief Whether the value is passed as a string or non-null terminated length. */
/** @description Applications can safely assume that this will always be IOTHUB_CLIENT_PROPERTY_VALUE_STRING.
* Additional types may be added in the future but they will never be the default.
*/
IOTHUB_CLIENT_PROPERTY_VALUE_TYPE valueType;
/** @brief Value of the property. Currently this is only set to str. */
union {
const char* str;
} value;
/** @brief Number of bytes in valueLength. Does not include null-terminator if IOTHUB_CLIENT_PROPERTY_VALUE_STRING
* is set. */
size_t valueLength;
} IOTHUB_CLIENT_PROPERTY_PARSED;
/**
* @brief Serializes reported properties into the required format for sending to IoT Hub.
*
* @param[in] properties Pointer to IOTHUB_CLIENT_PROPERTY_REPORTED to be serialized.
* @param[in] numProperties Number of elements contained in @p properties.
* @param[in] componentName Optional component name these properties are part of. May be NULL for default
* component.
* @param[out] serializedProperties Serialized output of @p properties for sending to IoT Hub.
* The application must release this memory using
* @p IoTHubClient_Properties_Serializer_Destroy().
* Note: This is NOT a null-terminated string.
* @param[out] serializedPropertiesLength Length of serializedProperties.
*
* @remarks Applications can also manually construct the payload based on the convention rules. This API is an easier
* to use alternative, so the application can use the more convenient IOTHUB_CLIENT_PROPERTY_REPORTED
* structure instead of raw serialization.
*
* This API does not perform any network I/O. It only translates IOTHUB_CLIENT_PROPERTY_REPORTED into a byte
* array. Applications should use APIs such as @p IoTHubDeviceClient_LL_SendPropertiesAsync() to send the
* serialized data.
*
* @return IOTHUB_CLIENT_OK upon success or an error code upon failure.
*/
MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_Properties_Serializer_CreateReported, const IOTHUB_CLIENT_PROPERTY_REPORTED*, properties, size_t, numProperties, const char*, componentName, unsigned char**, serializedProperties, size_t*, serializedPropertiesLength);
/**
* @brief Serializes the response to writable properties into bytes for sending to IoT Hub.
*
* @param[in] properties Pointer to #IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE to be serialized.
* @param[in] numProperties Number of elements contained in @p properties.
* @param[in] componentName Optional component name these properties are part of. May be NULL for
* default component.
* @param[out] serializedProperties Serialized output of @p properties for sending to IoT Hub.
The application must release this memory using
@p IoTHubClient_Properties_Serializer_Destroy().
* Note: This is NOT a null-terminated string.
* @param[out] serializedPropertiesLength Length of serializedProperties.
*
* @remarks Applications typically will invoke this API when processing a property from service
* (IOTHUB_CLIENT_PROPERTIES_RECEIVED_CALLBACK) to indicate whether properties have been accepted or rejected
* by the client. For example, if the service requested DesiredTemp=50, then the application could fill out
* the fields in an #IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE structure indicating whether the request can be
* processed or whether there was a failure.
*
* Applications can also manually construct the payload based on the convention rules. This API is an easier
* to use alternative, so the application can use the more convenient #IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE
* structure instead of raw serialization.
*
* This API does not perform any network I/O. It only translates #IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE into
* a byte array. Applications should use APIs such as @p IoTHubDeviceClient_LL_SendPropertiesAsync() to send the
* serialized data.
*
* @return IOTHUB_CLIENT_OK upon success or an error code upon failure.
*/
MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_Properties_Serializer_CreateWritableResponse, const IOTHUB_CLIENT_PROPERTY_WRITABLE_RESPONSE*, properties, size_t, numProperties, const char*, componentName, unsigned char**, serializedProperties, size_t*, serializedPropertiesLength);
/**
* @brief Frees serialized properties that were initially allocated with IoTHubClient_Properties_Serializer_CreateReported()
* or IoTHubClient_Properties_Serializer_CreateWritableResponse().
*
* @param[in] serializedProperties Properties to free.
*/
MOCKABLE_FUNCTION(, void, IoTHubClient_Properties_Serializer_Destroy, unsigned char*, serializedProperties);
/**
* @brief Handle used during deserialization of IoT Plug and Play properties.
*/
typedef struct IOTHUB_CLIENT_PROPERTIES_DESERIALIZER_TAG* IOTHUB_CLIENT_PROPERTIES_DESERIALIZER_HANDLE;
/**
* @brief Setup a deserialization handle to parse through Plug and Play properties received from IoT Hub.
*
* @param[in] payloadType Whether the payload is a full set of properties or only a set of updated
* writable properties.
* @param[in] payload Payload containing properties from Azure IoT that is to be deserialized.
* @param[in] payloadLength Length of @p payload.
* @param[out] propertiesDeserializerHandle Returned handle used for subsequent iteration calls.
*
* @remarks Applications typically will invoke this API in their IOTHUB_CLIENT_PROPERTIES_RECEIVED_CALLBACK
* implementation. Many of the parameters this function takes should come directly from the
* IOTHUB_CLIENT_PROPERTIES_RECEIVED_CALLBACK itself.
*
* Applications must call @p IoTHubClient_Properties_Deserializer_Destroy() to free @p
* propertiesDeserializerHandle on completion.
*
* @return IOTHUB_CLIENT_OK upon success or an error code upon failure.
*/
MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_Properties_Deserializer_Create, IOTHUB_CLIENT_PROPERTY_PAYLOAD_TYPE, payloadType, const unsigned char*, payload, size_t, payloadLength, IOTHUB_CLIENT_PROPERTIES_DESERIALIZER_HANDLE*, propertiesDeserializerHandle);
/**
* @brief Retrieves the version associated with the properties payload.
*
* @param[in] propertiesDeserializerHandle Deserialization handle returned by @p IoTHubClient_Properties_Deserializer_Create().
* @param[out] propertiesVersion Version of the writable properties received. This is used when acknowledging a
* writable property update.
*
* @return IOTHUB_CLIENT_OK upon success or an error code upon failure.
*/
MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_Properties_Deserializer_GetVersion, IOTHUB_CLIENT_PROPERTIES_DESERIALIZER_HANDLE, propertiesDeserializerHandle, int*, propertiesVersion);
/**
* @brief Gets the next property during iteration.
*
* @param[in] propertiesDeserializerHandle Deserialization handle returned by @p IoTHubClient_Properties_Deserializer_Create().
* @param[out] property @p #IOTHUB_CLIENT_PROPERTY_PARSED containing a deserialized representation
* of the properties.
* @param[out] propertySpecified Returned value indicating whether a property was found or not. If false, this
* indicates all components have been iterated over.
*
* @remarks Applications must call @p IoTHubClient_Properties_DeserializerProperty_Destroy() to free the @p property returned by this call.
* The property structure becomes invalid after @p IoTHubClient_Properties_DeserializerProperty_Destroy() has been called.
*
* @return IOTHUB_CLIENT_OK upon success or an error code upon failure.
*/
MOCKABLE_FUNCTION(, IOTHUB_CLIENT_RESULT, IoTHubClient_Properties_Deserializer_GetNext, IOTHUB_CLIENT_PROPERTIES_DESERIALIZER_HANDLE, propertiesDeserializerHandle, IOTHUB_CLIENT_PROPERTY_PARSED*, property, bool*, propertySpecified);
/**
* @brief Frees memory allocated by IoTHubClient_Properties_Deserializer_GetNext().
*
* @param property @p #IOTHUB_CLIENT_PROPERTY_PARSED initially allocated by @p IoTHubClient_Properties_Deserializer_Create()
* to be freed.
*
*/
MOCKABLE_FUNCTION(, void, IoTHubClient_Properties_DeserializerProperty_Destroy, IOTHUB_CLIENT_PROPERTY_PARSED*, property);
/**
* @brief Frees memory allocated by IoTHubClient_Properties_Deserializer_Create().
*
* @param propertiesDeserializerHandle @p #IOTHUB_CLIENT_PROPERTIES_DESERIALIZER_HANDLE initially allocated by @p
* IoTHubClient_Properties_Deserializer_Create() to be freed.
*
* @remarks After an application calls @p IoTHubClient_Properties_Deserializer_Destroy(), any previous
* @p #IOTHUB_CLIENT_PROPERTY_PARSED structures that were retrieved via
* @p IoTHubClient_Properties_Deserializer_GetNext() become invalid.
*/
MOCKABLE_FUNCTION(, void, IoTHubClient_Properties_Deserializer_Destroy, IOTHUB_CLIENT_PROPERTIES_DESERIALIZER_HANDLE, propertiesDeserializerHandle);
#ifdef __cplusplus
}
#endif
#endif /* IOTHUB_CLIENT_PROPERTIES_H */