source/include/azure_iot_hub_client.h (197 lines of code) (raw):

/* Copyright (c) Microsoft Corporation. * Licensed under the MIT License. */ /** * @file azure_iot_hub_client.h * * @brief The middleware IoT Hub Client used to connect a device to Azure IoT Hub. * * @note You MUST NOT use any symbols (macros, functions, structures, enums, etc.) * prefixed with an underscore ('_') directly in your application code. These symbols * are part of Azure SDK's internal implementation; we do not document these symbols * and they are subject to change in future versions of the SDK which would break your code. * */ #ifndef AZURE_IOT_HUB_CLIENT_H #define AZURE_IOT_HUB_CLIENT_H #include "azure_iot.h" #include "azure_iot_message.h" #include "azure_iot_result.h" #include "azure_iot_mqtt_port.h" #include "azure_iot_transport_interface.h" /* Azure SDK for Embedded C includes */ #include "azure/az_core.h" #include "azure/iot/az_iot_common.h" #include "azure/iot/az_iot_hub_client.h" #include "azure/core/_az_cfg_prefix.h" /** * @brief Total number of features which could be subscribed to. */ #define azureiothubSUBSCRIBE_FEATURE_COUNT ( 3 ) /** * @brief Macro which should be used to create an array of #AzureIoTHubClientComponent_t */ #define azureiothubCREATE_COMPONENT( x ) ( AzureIoTHubClientComponent_t ) AZ_SPAN_LITERAL_FROM_STR( x ) /* Forward declaration for Azure IoT Hub Client */ typedef struct AzureIoTHubClient AzureIoTHubClient_t; /** * @brief Type for Azure IoT Plug and Play component. The list of component names can be set * as an option for the Azure IoT Hub Client */ typedef az_span AzureIoTHubClientComponent_t; /** * @brief MQTT quality of service values used for messages. */ typedef enum AzureIoTHubMessageQoS { eAzureIoTHubMessageQoS0 = 0, /** Delivery at most once. */ eAzureIoTHubMessageQoS1 = 1 /** Delivery at least once. */ } AzureIoTHubMessageQoS_t; /** * @brief Enumeration to dictate Azure IoT message types. */ typedef enum AzureIoTHubMessageType { eAzureIoTHubCloudToDeviceMessage = 1, /**< The message is a cloud message. */ eAzureIoTHubCommandMessage, /**< The message is a command message. */ eAzureIoTHubPropertiesRequestedMessage, /**< The message is a response from a property request (payload contains the property document). */ eAzureIoTHubPropertiesReportedResponseMessage, /**< The message is a reported property status response. */ eAzureIoTHubPropertiesWritablePropertyMessage, /**< The message is a writable property message (incoming from the service). */ } AzureIoTHubMessageType_t; /** * @brief Status codes for Azure IoT Hub responses. */ typedef enum AzureIoTHubMessageStatus { /* Default, unset value */ eAzureIoTStatusUnknown = 0, /* Service success codes */ eAzureIoTStatusOk = 200, eAzureIoTStatusAccepted = 202, eAzureIoTStatusNoContent = 204, /* Service error codes */ eAzureIoTStatusBadRequest = 400, eAzureIoTStatusUnauthorized = 401, eAzureIoTStatusForbidden = 403, eAzureIoTStatusNotFound = 404, eAzureIoTStatusNotAllowed = 405, eAzureIoTStatusNotConflict = 409, eAzureIoTStatusPreconditionFailed = 412, eAzureIoTStatusRequestTooLarge = 413, eAzureIoTStatusUnsupportedType = 415, eAzureIoTStatusThrottled = 429, eAzureIoTStatusClientClosed = 499, eAzureIoTStatusServerError = 500, eAzureIoTStatusBadGateway = 502, eAzureIoTStatusServiceUnavailable = 503, eAzureIoTStatusTimeout = 504, } AzureIoTHubMessageStatus_t; /** * @brief IoT Hub Cloud Message Request struct. */ typedef struct AzureIoTHubClientCloudToDeviceMessageRequest { const void * pvMessagePayload; /**< The pointer to the message payload. */ uint32_t ulPayloadLength; /**< The length of the message payload. */ AzureIoTMessageProperties_t xProperties; /**< The bag of properties received with the message. */ } AzureIoTHubClientCloudToDeviceMessageRequest_t; /** * @brief IoT Hub Command Request struct. */ typedef struct AzureIoTHubClientCommandRequest { const void * pvMessagePayload; /**< The pointer to the message payload. */ uint32_t ulPayloadLength; /**< The length of the message payload. */ const uint8_t * pucRequestID; /**< The pointer to the request ID. */ uint16_t usRequestIDLength; /**< The length of the request ID. */ const uint8_t * pucComponentName; /**< The name of the component associate with this command. */ uint16_t usComponentNameLength; /**< The length of the component name. */ const uint8_t * pucCommandName; /**< The name of the command to invoke. */ uint16_t usCommandNameLength; /**< The length of the command name. */ } AzureIoTHubClientCommandRequest_t; /** * @brief IoT Hub Properties Response struct. */ typedef struct AzureIoTHubClientPropertiesResponse { AzureIoTHubMessageType_t xMessageType; /**< The type of message received. */ const void * pvMessagePayload; /**< The pointer to the message payload. */ uint32_t ulPayloadLength; /**< The length of the message payload. */ uint32_t ulRequestID; /**< The request ID for the property response. */ AzureIoTHubMessageStatus_t xMessageStatus; /**< The operation status. */ } AzureIoTHubClientPropertiesResponse_t; /** * @brief Cloud message callback to be invoked when a cloud message is received in the call to AzureIoTHubClient_ProcessLoop(). * * @param[in] pxMessage The #AzureIoTHubClientCloudToDeviceMessageRequest_t associated with the message. * @param[in] pvContext The context passed back to the caller. */ typedef void ( * AzureIoTHubClientCloudToDeviceMessageCallback_t ) ( AzureIoTHubClientCloudToDeviceMessageRequest_t * pxMessage, void * pvContext ); /** * @brief Command callback to be invoked when a command request is received in the call to AzureIoTHubClient_ProcessLoop(). * * @param[in] pxMessage The #AzureIoTHubClientCommandRequest_t associated with the message. * @param[in] pvContext The context passed back to the caller. * */ typedef void ( * AzureIoTHubClientCommandCallback_t ) ( AzureIoTHubClientCommandRequest_t * pxMessage, void * pvContext ); /** * @brief Properties callback to be invoked when a property message is received in the call to AzureIoTHubClient_ProcessLoop(). * * @param[in] pxMessage The #AzureIoTHubClientPropertiesResponse_t associated with the message. * @param[in] pvContext The context passed back to the caller. */ typedef void ( * AzureIoTHubClientPropertiesCallback_t ) ( AzureIoTHubClientPropertiesResponse_t * pxMessage, void * pvContext ); /** * @brief Receive context to be used internally for the processing of messages. * * @warning Used internally. */ typedef struct AzureIoTHubClientReceiveContext { struct { uint16_t usState; uint16_t usMqttSubPacketID; uint32_t ( * pxProcessFunction )( struct AzureIoTHubClientReceiveContext * pxContext, AzureIoTHubClient_t * pxAzureIoTHubClient, void * pvPublishInfo ); void * pvCallbackContext; union { AzureIoTHubClientCloudToDeviceMessageCallback_t xCloudToDeviceMessageCallback; AzureIoTHubClientCommandCallback_t xCommandCallback; AzureIoTHubClientPropertiesCallback_t xPropertiesCallback; } callbacks; } _internal; /**< @brief Internal to the SDK */ } AzureIoTHubClientReceiveContext_t; /** * @brief Callback to send notification that puback was received for specific packet ID. * * @param[in] ulTelemetryPacketID The packet id for the telemetry message which was received. You may use this to match * messages with the optional packet id parameter in AzureIoTHubClient_SendTelemetry(). */ typedef void (* AzureIoTTelemetryAckCallback_t)( uint16_t ulTelemetryPacketID ); /** * @brief Options list for the hub client. */ typedef struct AzureIoTHubClientOptions { const uint8_t * pucModuleID; /**< The optional module ID to use for this device. */ uint32_t ulModuleIDLength; /**< The length of the module ID. */ const uint8_t * pucModelID; /**< The Azure Digital Twin Definition Language model ID used to * identify the capabilities of this device based on the Digital Twin document. */ uint32_t ulModelIDLength; /**< The length of the model ID. */ AzureIoTHubClientComponent_t * pxComponentList; /**< The list of component names to use for the device. */ uint32_t ulComponentListLength; /**< The number of components in the list. */ const uint8_t * pucUserAgent; /**< The user agent to use for this device. */ uint32_t ulUserAgentLength; /**< The length of the user agent. */ AzureIoTTelemetryAckCallback_t xTelemetryCallback; /**< The callback to invoke to notify user a puback was received for QOS 1. * Can be NULL if user does not want to be notified.*/ } AzureIoTHubClientOptions_t; /** * @struct AzureIoTHubClient_t * @brief Azure IoT Hub Client used to manage connections and features for Azure IoT Hub. */ struct AzureIoTHubClient { struct { AzureIoTMQTT_t xMQTTContext; uint8_t * pucWorkingBuffer; uint32_t ulWorkingBufferLength; az_iot_hub_client xAzureIoTHubClientCore; const uint8_t * pucHostname; uint16_t ulHostnameLength; const uint8_t * pucDeviceID; uint16_t ulDeviceIDLength; const uint8_t * pucSymmetricKey; uint32_t ulSymmetricKeyLength; uint32_t ( * pxTokenRefresh )( AzureIoTHubClient_t * pxAzureIoTHubClient, uint64_t ullExpiryTimeSecs, const uint8_t * ucKey, uint32_t ulKeyLen, uint8_t * pucSASBuffer, uint32_t ulSasBufferLen, uint32_t * pulSaSLength ); AzureIoTGetHMACFunc_t xHMACFunction; AzureIoTGetCurrentTimeFunc_t xTimeFunction; AzureIoTTelemetryAckCallback_t xTelemetryCallback; uint32_t ulCurrentPropertyRequestID; AzureIoTHubClientReceiveContext_t xReceiveContext[ azureiothubSUBSCRIBE_FEATURE_COUNT ]; } _internal; /**< @brief Internal to the SDK */ }; /** * @brief Initialize the Azure IoT Hub Options with default values. * * @param[out] pxHubClientOptions The #AzureIoTHubClientOptions_t instance to set with default values. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_OptionsInit( AzureIoTHubClientOptions_t * pxHubClientOptions ); /** * @brief Initialize the Azure IoT Hub Client. * * @param[out] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] pucHostname The IoT Hub Hostname. * @param[in] ulHostnameLength The length of the IoT Hub Hostname. * @param[in] pucDeviceID The device ID. If the ID contains any of the following characters, they must * be percent-encoded as follows: * - `/` : `%2F` * - `%` : `%25` * - `#` : `%23` * - `&` : `%26` * @param[in] ulDeviceIDLength The length of the device ID. * @param[in] pxHubClientOptions The #AzureIoTHubClientOptions_t for the IoT Hub client instance. * @param[in] pucBuffer The static buffer to use for middleware operations and MQTT messages until AzureIoTHubClient_Deinit is called. * @param[in] ulBufferLength The length of the \p pucBuffer. * @param[in] xGetTimeFunction A function pointer to a function which gives the current epoch time. * @param[in] pxTransportInterface The #AzureIoTTransportInterface_t to use for the MQTT library. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_Init( AzureIoTHubClient_t * pxAzureIoTHubClient, const uint8_t * pucHostname, uint16_t ulHostnameLength, const uint8_t * pucDeviceID, uint16_t ulDeviceIDLength, AzureIoTHubClientOptions_t * pxHubClientOptions, uint8_t * pucBuffer, uint32_t ulBufferLength, AzureIoTGetCurrentTimeFunc_t xGetTimeFunction, const AzureIoTTransportInterface_t * pxTransportInterface ); /** * @brief Deinitialize the Azure IoT Hub Client. * * @param pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. */ void AzureIoTHubClient_Deinit( AzureIoTHubClient_t * pxAzureIoTHubClient ); /** * @brief Set the symmetric key to use for authentication. * * @note If using X509 authentication, this is not needed and should not be used. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] pucSymmetricKey The symmetric key to use for the connection. * @param[in] ulSymmetricKeyLength The length of the \p pucSymmetricKey. * @param[in] xHMACFunction The #AzureIoTGetHMACFunc_t function pointer to a function which computes the HMAC256 over a set of bytes. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_SetSymmetricKey( AzureIoTHubClient_t * pxAzureIoTHubClient, const uint8_t * pucSymmetricKey, uint32_t ulSymmetricKeyLength, AzureIoTGetHMACFunc_t xHMACFunction ); /** * @brief Connect via MQTT to the IoT Hub endpoint. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] xCleanSession A boolean dictating whether to connect with a clean session or not. * @param[in] pxOutSessionPresent Whether a previous session was present. * Only relevant if not establishing a clean session. * @param[in] ulTimeoutMilliseconds The maximum time in milliseconds to wait for a CONNACK. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_Connect( AzureIoTHubClient_t * pxAzureIoTHubClient, bool xCleanSession, bool * pxOutSessionPresent, uint32_t ulTimeoutMilliseconds ); /** * @brief Disconnect from the IoT Hub endpoint. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_Disconnect( AzureIoTHubClient_t * pxAzureIoTHubClient ); /** * @brief Send telemetry data to IoT Hub. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] pucTelemetryData The pointer to the buffer of telemetry data. * @param[in] ulTelemetryDataLength The length of the buffer to send as telemetry. * @param[in] pxProperties The property bag to send with the message. * @param[in] xQOS The QOS to use for the telemetry. Only QOS `0` and `1` are supported. * @param[out] pusTelemetryPacketID The packet id for the sent telemetry. * Can be notified of PUBACK for QOS 1 using the #AzureIoTHubClientOptions_t `xTelemetryCallback` option. * If xQOS is `eAzureIoTHubMessageQoS0` this value will not be sent on return. * Can be `NULL`. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_SendTelemetry( AzureIoTHubClient_t * pxAzureIoTHubClient, const uint8_t * pucTelemetryData, uint32_t ulTelemetryDataLength, AzureIoTMessageProperties_t * pxProperties, AzureIoTHubMessageQoS_t xQOS, uint16_t * pusTelemetryPacketID ); /** * @brief Receive any incoming MQTT messages from and manage the MQTT connection to IoT Hub. * * @note This API will receive any messages sent to the device and manage the connection such as sending * `PING` messages. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] ulTimeoutMilliseconds Minimum time (in milliseconds) for the loop to run. If `0` is passed, it will only run once. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_ProcessLoop( AzureIoTHubClient_t * pxAzureIoTHubClient, uint32_t ulTimeoutMilliseconds ); /** * @brief Subscribe to cloud to device messages. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] xCloudToDeviceMessageCallback The #AzureIoTHubClientCloudToDeviceMessageCallback_t to invoke when a CloudToDevice messages arrive. * @param[in] prvCallbackContext A pointer to a context to pass to the callback. * @param[in] ulTimeoutMilliseconds Timeout in milliseconds for subscribe operation to complete. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_SubscribeCloudToDeviceMessage( AzureIoTHubClient_t * pxAzureIoTHubClient, AzureIoTHubClientCloudToDeviceMessageCallback_t xCloudToDeviceMessageCallback, void * prvCallbackContext, uint32_t ulTimeoutMilliseconds ); /** * @brief Unsubscribe from cloud to device messages. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_UnsubscribeCloudToDeviceMessage( AzureIoTHubClient_t * pxAzureIoTHubClient ); /** * @brief Subscribe to Azure IoT Hub Direct Methods. * @remark Azure IoT Direct methods may also be referred to as Commands. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] xCommandCallback The #AzureIoTHubClientCommandCallback_t to invoke when command messages arrive. * @param[in] prvCallbackContext A pointer to a context to pass to the callback. * @param[in] ulTimeoutMilliseconds Timeout in milliseconds for Subscribe operation to complete. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_SubscribeCommand( AzureIoTHubClient_t * pxAzureIoTHubClient, AzureIoTHubClientCommandCallback_t xCommandCallback, void * prvCallbackContext, uint32_t ulTimeoutMilliseconds ); /** * @brief Unsubscribe from Azure IoT Hub Direct Methods. * @remark Azure IoT Direct methods may also be referred to as Commands. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_UnsubscribeCommand( AzureIoTHubClient_t * pxAzureIoTHubClient ); /** * @brief Send a response to a received command message. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] pxMessage The pointer to the #AzureIoTHubClientCommandRequest_t to which a response is being sent. * @param[in] ulStatus A code that indicates the result of the command, as defined by the user. * @param[in] pucCommandPayload __[nullable]__ An optional command response payload. * @param[in] ulCommandPayloadLength The length of the command response payload. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_SendCommandResponse( AzureIoTHubClient_t * pxAzureIoTHubClient, const AzureIoTHubClientCommandRequest_t * pxMessage, uint32_t ulStatus, const uint8_t * pucCommandPayload, uint32_t ulCommandPayloadLength ); /** * @brief Subscribe to device properties. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] xPropertiesCallback The #AzureIoTHubClientPropertiesCallback_t to invoke when device property messages arrive. * @param[in] prvCallbackContext A pointer to a context to pass to the callback. * @param[in] ulTimeoutMilliseconds Timeout in milliseconds for Subscribe operation to complete. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_SubscribeProperties( AzureIoTHubClient_t * pxAzureIoTHubClient, AzureIoTHubClientPropertiesCallback_t xPropertiesCallback, void * prvCallbackContext, uint32_t ulTimeoutMilliseconds ); /** * @brief Unsubscribe from device properties. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_UnsubscribeProperties( AzureIoTHubClient_t * pxAzureIoTHubClient ); /** * @brief Send reported device properties to Azure IoT Hub. * * @note AzureIoTHubClient_SubscribeProperties() must be called before calling this function. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @param[in] pucReportedPayload The payload of properly formatted, reported properties. * @param[in] ulReportedPayloadLength The length of the reported property payload. * @param[out] pulRequestID Pointer to request ID used to send the reported property. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_SendPropertiesReported( AzureIoTHubClient_t * pxAzureIoTHubClient, const uint8_t * pucReportedPayload, uint32_t ulReportedPayloadLength, uint32_t * pulRequestID ); /** * @brief Request to get the device property document. * * @note AzureIoTHubClient_SubscribeProperties() must be called before calling this function. * * The response to the request will be returned via the #AzureIoTHubClientPropertiesCallback_t which was passed * in the AzureIoTHubClient_SubscribeProperties() call. The type of message will be #eAzureIoTHubPropertiesRequestedMessage * and the payload (on success) will be the property document. * * @param[in] pxAzureIoTHubClient The #AzureIoTHubClient_t * to use for this call. * @return An #AzureIoTResult_t with the result of the operation. */ AzureIoTResult_t AzureIoTHubClient_RequestPropertiesAsync( AzureIoTHubClient_t * pxAzureIoTHubClient ); #include "azure/core/_az_cfg_suffix.h" #endif /* AZURE_IOT_HUB_CLIENT_H */