1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 /**
12  * @file nx_azure_iot_hub_client.h
13  *
14  * @brief Definition for the Azure IoT Hub client.
15  * @remark The IoT Hub MQTT protocol is described at
16  * https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support.
17  *
18  */
19 
20 #ifndef NX_AZURE_IOT_HUB_CLIENT_H
21 #define NX_AZURE_IOT_HUB_CLIENT_H
22 
23 #ifdef __cplusplus
24 extern   "C" {
25 #endif
26 
27 #include "nx_azure_iot.h"
28 #include "azure/iot/az_iot_hub_client.h"
29 
30 /**< Value denoting a message is of "None" type */
31 #define NX_AZURE_IOT_HUB_NONE                                       0x00000000
32 
33 /**< Value denoting a message is of "all" type */
34 #define NX_AZURE_IOT_HUB_ALL_MESSAGE                                0xFFFFFFFF
35 
36 /**< Value denoting a message is a cloud-to-device message */
37 #define NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE                    0x00000001
38 
39 /**< Value denoting a message is a command message */
40 #define NX_AZURE_IOT_HUB_COMMAND                                    0x00000002
41 
42 /**< Value denoting a message is a properties message */
43 #define NX_AZURE_IOT_HUB_PROPERTIES                                 0x00000004
44 
45 /**< Value denoting a message is a writable properties message */
46 #define NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES                        0x00000008
47 
48 /**< Value denoting a message is a reported properties response */
49 #define NX_AZURE_IOT_HUB_REPORTED_PROPERTIES_RESPONSE               0x00000010
50 
51 /* Map the message type.  */
52 #define NX_AZURE_IOT_HUB_DIRECT_METHOD                              NX_AZURE_IOT_HUB_COMMAND
53 #define NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES                     NX_AZURE_IOT_HUB_PROPERTIES
54 #define NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES             NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES
55 #define NX_AZURE_IOT_HUB_DEVICE_TWIN_REPORTED_PROPERTIES_RESPONSE   NX_AZURE_IOT_HUB_REPORTED_PROPERTIES_RESPONSE
56 
57 /* Set the default timeout for DNS query.  */
58 #ifndef NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT
59 #define NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT                         (5 * NX_IP_PERIODIC_RATE)
60 #endif /* NX_AZURE_IOT_HUB_CLIENT_DNS_TIMEOUT */
61 
62 /* Set the default timeout for connection with SAS token authentication in secs.  */
63 #ifndef NX_AZURE_IOT_HUB_CLIENT_TOKEN_CONNECTION_TIMEOUT
64 #ifdef NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY
65 #define NX_AZURE_IOT_HUB_CLIENT_TOKEN_CONNECTION_TIMEOUT            NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY
66 #else
67 #define NX_AZURE_IOT_HUB_CLIENT_TOKEN_CONNECTION_TIMEOUT            (3600)
68 #endif /* NX_AZURE_IOT_HUB_CLIENT_TOKEN_EXPIRY */
69 #endif /* NX_AZURE_IOT_HUB_CLIENT_SAS_CONNECTION_TIMEOUT */
70 
71 #ifndef NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_IN_SEC
72 #define NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_IN_SEC                  (10 * 60)
73 #endif /* NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_IN_SEC */
74 
75 #ifndef NX_AZURE_IOT_HUB_CLIENT_INITIAL_BACKOFF_IN_SEC
76 #define NX_AZURE_IOT_HUB_CLIENT_INITIAL_BACKOFF_IN_SEC              (3)
77 #endif /* NX_AZURE_IOT_HUB_CLIENT_INITIAL_BACKOFF_IN_SEC */
78 
79 #ifndef NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_JITTER_PERCENT
80 #define NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_JITTER_PERCENT          (60)
81 #endif /* NX_AZURE_IOT_HUB_CLIENT_MAX_BACKOFF_JITTER_PERCENT */
82 
83 /* Define Azure IoT Hub Client state.  */
84 /**< The client is not connected */
85 #define NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED                0
86 
87 /**< The client is connecting */
88 #define NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTING                   1
89 
90 /**< The client is connected */
91 #define NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED                    2
92 
93 /* Default TELEMETRY QoS is QoS1 */
94 #ifndef NX_AZURE_IOT_HUB_CLIENT_TELEMETRY_QOS
95 #define NX_AZURE_IOT_HUB_CLIENT_TELEMETRY_QOS                       NX_AZURE_IOT_MQTT_QOS_1
96 #endif /* NX_AZURE_IOT_HUB_CLIENT_TELEMETRY_QOS */
97 
98 #ifndef NX_AZURE_IOT_HUB_CLIENT_MAX_COMPONENT_LIST
99 #define NX_AZURE_IOT_HUB_CLIENT_MAX_COMPONENT_LIST                  (4)
100 #endif /* NX_AZURE_IOT_HUB_CLIENT_MAX_COMPONENT_LIST */
101 
102 /* Forward declration*/
103 struct NX_AZURE_IOT_HUB_CLIENT_STRUCT;
104 
105 typedef struct NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE_STRUCT
106 {
107     NX_PACKET    *message_head;
108     NX_PACKET    *message_tail;
109     VOID        (*message_callback)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr, VOID *args);
110     VOID         *message_callback_args;
111     UINT        (*message_process)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
112                                    NX_PACKET *packet_ptr, ULONG topic_offset, USHORT topic_length);
113     UINT        (*message_enable)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr);
114 } NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE;
115 
116 /**
117  * @brief Azure IoT Hub Client struct
118  *
119  */
120 typedef struct NX_AZURE_IOT_HUB_CLIENT_STRUCT
121 {
122     NX_AZURE_IOT                           *nx_azure_iot_ptr;
123 
124     UINT                                    nx_azure_iot_hub_client_state;
125     NX_AZURE_IOT_THREAD                    *nx_azure_iot_hub_client_thread_suspended;
126     NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE nx_azure_iot_hub_client_c2d_message;
127     NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE nx_azure_iot_hub_client_command_message;
128     NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE nx_azure_iot_hub_client_properties_message;
129     NX_AZURE_IOT_HUB_CLIENT_RECEIVE_MESSAGE nx_azure_iot_hub_client_writable_properties_message;
130     VOID                                  (*nx_azure_iot_hub_client_report_properties_response_callback)(
131                                            struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
132                                            UINT request_id, UINT response_status, ULONG version, VOID *args);
133     VOID                                   *nx_azure_iot_hub_client_report_properties_response_callback_args;
134 
135     VOID                                  (*nx_azure_iot_hub_client_connection_status_callback)(
136                                            struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
137                                            UINT status);
138     VOID                                  (*nx_azure_iot_hub_client_telemetry_ack_callback)(
139                                            struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
140                                            USHORT packet_id);
141     UINT                                  (*nx_azure_iot_hub_client_token_refresh)(
142                                            struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
143                                            ULONG expiry_time_secs, const UCHAR *key, UINT key_len,
144                                            UCHAR *sas_buffer, UINT sas_buffer_len, UINT *sas_length);
145 
146     UINT                                    nx_azure_iot_hub_client_request_id;
147     const UCHAR                            *nx_azure_iot_hub_client_symmetric_key;
148     UINT                                    nx_azure_iot_hub_client_symmetric_key_length;
149     NX_AZURE_IOT_RESOURCE                   nx_azure_iot_hub_client_resource;
150 
151     volatile UCHAR                          nx_azure_iot_hub_client_properties_subscribe_ack;
152     UCHAR                                   reserved[3];
153 
154     az_iot_hub_client                       iot_hub_client_core;
155     UINT                                    nx_azure_iot_hub_client_throttle_count;
156     ULONG                                   nx_azure_iot_hub_client_throttle_end_time;
157     ULONG                                   nx_azure_iot_hub_client_sas_token_expiry_time;
158     az_span                                 nx_azure_iot_hub_client_component_list[NX_AZURE_IOT_HUB_CLIENT_MAX_COMPONENT_LIST];
159     UINT                                  (*nx_azure_iot_hub_client_component_callback[NX_AZURE_IOT_HUB_CLIENT_MAX_COMPONENT_LIST])
160                                                                                       (VOID *json_reader_ptr,
161                                                                                        ULONG version,
162                                                                                        VOID *args);
163     VOID                                   *nx_azure_iot_hub_client_component_callback_args[NX_AZURE_IOT_HUB_CLIENT_MAX_COMPONENT_LIST];
164     VOID                                  (*nx_azure_iot_hub_client_component_properties_process)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
165                                                                                                   NX_PACKET *packet_ptr,
166                                                                                                   UINT message_type);
167 } NX_AZURE_IOT_HUB_CLIENT;
168 
169 
170 /**
171  * @brief Initialize Azure IoT hub instance
172  *
173  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
174  * @param[in] nx_azure_iot_ptr A pointer to a #NX_AZURE_IOT.
175  * @param[in] host_name A `UCHAR` pointer to IoTHub hostname. Must be `NULL` terminated.
176  * @param[in] host_name_length Length of `host_name`. Does not include the `NULL` terminator.
177  * @param[in] device_id A `UCHAR` pointer to the device ID.
178  * @param[in] device_id_length Length of the `device_id`. Does not include the `NULL` terminator.
179  * @param[in] module_id A `UCHAR` pointer to the module ID.
180  * @param[in] module_id_length Length of the `module_id`. Does not include the `NULL` terminator.
181  * @param[in] crypto_array A pointer to an array of `NX_CRYPTO_METHOD`.
182  * @param[in] crypto_array_size Size of `crypto_array`.
183  * @param[in] cipher_map A pointer to an array of `NX_CRYPTO_CIPHERSUITE`.
184  * @param[in] cipher_map_size Size of `cipher_map`.
185  * @param[in] metadata_memory A `UCHAR` pointer to metadata memory buffer.
186  * @param[in] memory_size Size of `metadata_memory`.
187  * @param[in] trusted_certificate A pointer to `NX_SECURE_X509_CERT`, which are the server side certs.
188  * @return A `UINT` with the result of the API.
189  *   @retval #NX_AZURE_IOT_SUCCESS Successfully initialized the Azure IoT hub client.
190  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to initialize the Azure IoT hub client due to invalid parameter.
191  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to initialize the Azure IoT hub client due to SDK core error.
192  */
193 UINT nx_azure_iot_hub_client_initialize(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
194                                         NX_AZURE_IOT *nx_azure_iot_ptr,
195                                         const UCHAR *host_name, UINT host_name_length,
196                                         const UCHAR *device_id, UINT device_id_length,
197                                         const UCHAR *module_id, UINT module_id_length,
198                                         const NX_CRYPTO_METHOD **crypto_array, UINT crypto_array_size,
199                                         const NX_CRYPTO_CIPHERSUITE **cipher_map, UINT cipher_map_size,
200                                         UCHAR *metadata_memory, UINT memory_size,
201                                         NX_SECURE_X509_CERT *trusted_certificate);
202 
203 /**
204  * @brief Deinitialize the Azure IoT Hub instance.
205  *
206  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
207  * @return A `UINT` with the result of the API.
208  *   @retval #NX_AZURE_IOT_SUCCESS Successfully de-initialized the Azure IoT hub client.
209  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to deinitialize the Azure IoT hub client due to invalid parameter.
210  */
211 UINT nx_azure_iot_hub_client_deinitialize(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
212 
213 /**
214  * @brief Add more trusted certificate in the IoT Hub client if needed. It can be called multiple times to set multiple trusted certificates.
215  *
216  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
217  * @param[in] trusted_certificate A pointer to a `NX_SECURE_X509_CERT`, which is the trusted certificate.
218  * @return A `UINT` with the result of the API.
219  *   @retval #NX_AZURE_IOT_SUCCESS Successfully add trusted certificate to Azure IoT Hub Instance.
220  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to add trusted certificate to Azure IoT Hub Instance due to invalid parameter.
221  *   @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to add trusted certificate due to NX_AZURE_IOT_MAX_NUM_OF_TRUSTED_CERTS is too small.
222  */
223 UINT nx_azure_iot_hub_client_trusted_cert_add(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
224                                               NX_SECURE_X509_CERT *trusted_certificate);
225 
226 /**
227  * @brief Set the client certificate in the IoT Hub client. It can be called multiple times to set certificate chain.
228  *
229  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
230  * @param[in] device_certificate A pointer to a `NX_SECURE_X509_CERT`, which is the device certificate.
231  * @return A `UINT` with the result of the API.
232  *   @retval #NX_AZURE_IOT_SUCCESS Successfully set device certificate to Azure IoT Hub Instance.
233  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set device certificate to Azure IoT Hub Instance due to invalid parameter.
234  *   @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to set device certificate due to NX_AZURE_IOT_MAX_NUM_OF_DEVICE_CERTS is too small.
235  */
236 UINT nx_azure_iot_hub_client_device_cert_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
237                                              NX_SECURE_X509_CERT *device_certificate);
238 
239 /**
240  * @brief Set symmetric key in the IoT Hub client.
241  *
242  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
243  * @param[in] symmetric_key A pointer to a symmetric key.
244  * @param[in] symmetric_key_length Length of `symmetric_key`.
245  * @return A `UINT` with the result of the API.
246  *   @retval #NX_AZURE_IOT_SUCCESS Successfully set symmetric key to IoTHub client.
247  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set symmetric key to IoTHub client due to invalid parameter.
248  */
249 UINT nx_azure_iot_hub_client_symmetric_key_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
250                                                const UCHAR *symmetric_key, UINT symmetric_key_length);
251 
252 /**
253  * @brief Set model id in the IoT Hub client to enable PnP.
254  * @note To enable pnp, this routine should be called immediately after nx_azure_iot_hub_client_initialize(),
255          if model id is not set, only normal iothub APIs can be used, if it is set, only pnp APIs can be used.
256  *
257  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
258  * @param[in] model_id_ptr A pointer to a model id.
259  * @param[in] model_id_length Length of `model id`.
260  * @return A `UINT` with the result of the API.
261  *   @retval #NX_AZURE_IOT_SUCCESS Successfully set model id to IoTHub client.
262  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set model id to IoTHub client due to invalid parameter.
263  */
264 UINT nx_azure_iot_hub_client_model_id_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
265                                           const UCHAR *model_id_ptr, UINT model_id_length);
266 
267 /**
268  * @brief Add component name to IoT Hub client.
269  * @note This routine should be called for all the component in the PnP model.
270  *
271  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
272  * @param[in] component_name_ptr A pointer to component, that is part of PnP model.
273  * @param[in] component_name_length Length of the `component_name_ptr`.
274  * @return A `UINT` with the result of the API.
275  *   @retval #NX_AZURE_IOT_SUCCESS Successfully add the component name to the PnP client.
276  *   @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to add the component name due to out of memory.
277  */
278 UINT nx_azure_iot_hub_client_component_add(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
279                                            const UCHAR *component_name_ptr,
280                                            USHORT component_name_length);
281 
282 #ifdef NXD_MQTT_OVER_WEBSOCKET
283 /**
284  * @brief Enable using MQTT over WebSocket to connect to IoTHub.
285  *
286  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
287  * @return A `UINT` with the result of the API.
288  *   @retval #NX_AZURE_IOT_SUCCESS Successful if MQTT over WebSocket is enabled.
289  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to enable C2D message receiving due to invalid parameter.
290  *   @retval NXD_MQTT_NOT_CONNECTED Fail to enable C2D message receiving due to MQTT not connected.
291  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to enable C2D message receiving due to no available packet in pool.
292  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to enable C2D message receiving due to TCP/TLS error.
293  */
294 UINT nx_azure_iot_hub_client_websocket_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
295 #endif /* NXD_MQTT_OVER_WEBSOCKET */
296 
297 /**
298  * @brief Connect to IoT Hub.
299  *
300  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
301  * @param[in] clean_session Can be set to `0` to re-use current session, or `1` to start new session
302  * @param[in] wait_option Number of ticks to wait for internal resources to be available.
303  * @return A `UINT` with the result of the API.
304  *   @retval #NX_AZURE_IOT_SUCCESS Successful if connected to Azure IoT Hub.
305  *   @retval #NX_AZURE_IOT_CONNECTING Successfully started connection but not yet completed.
306  *   @retval #NX_AZURE_IOT_ALREADY_CONNECTED Already connected to Azure IoT Hub.
307  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to connect to Azure IoT Hub due to invalid parameter.
308  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to connect to Azure IoT Hub due to SDK core error.
309  *   @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to connect to Azure IoT Hub due to buffer size is too small.
310  *   @retval NX_DNS_QUERY_FAILED Fail to connect to Azure IoT Hub due to hostname can not be resolved.
311  *   @retval NX_NO_PACKET Fail to connect to Azure IoT Hub due to no available packet in pool.
312  *   @retval NX_INVALID_PARAMETERS Fail to connect to Azure IoT Hub due to invalid parameters.
313  *   @retval NX_SECURE_TLS_INSUFFICIENT_METADATA_SPACE Fail to connect to Azure IoT Hub due to insufficient metadata space.
314  *   @retval NX_SECURE_TLS_UNSUPPORTED_CIPHER Fail to connect to Azure IoT Hub due to unsupported cipher.
315  *   @retval NXD_MQTT_ALREADY_CONNECTED Fail to connect to Azure IoT Hub due to MQTT session is not disconnected.
316  *   @retval NXD_MQTT_CONNECT_FAILURE Fail to connect to Azure IoT Hub due to TCP/TLS connect error.
317  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to connect to Azure IoT Hub due to MQTT connect error.
318  *   @retval NXD_MQTT_ERROR_SERVER_UNAVAILABLE Fail to connect to Azure IoT Hub due to server unavailable.
319  *   @retval NXD_MQTT_ERROR_NOT_AUTHORIZED Fail to connect to Azure IoT Hub due to authentication error.
320  */
321 UINT nx_azure_iot_hub_client_connect(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
322                                      UINT clean_session, UINT wait_option);
323 
324 /**
325  * @brief Disconnect from IoT Hub.
326  *
327  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
328  * @return A `UINT` with the result of the API.
329  *   @retval #NX_AZURE_IOT_SUCCESS Successful if client disconnects.
330  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to disconnect due to invalid parameter.
331  */
332 UINT nx_azure_iot_hub_client_disconnect(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
333 
334 /**
335  * @brief Sets connection status callback function
336  * @details This routine sets the connection status callback. This callback function is
337  *          invoked when IoT Hub status is changed, such as when the client is connected to IoT Hub.
338  *          The different statuses include:
339  *
340  *          - #NX_AZURE_IOT_SUCCESS
341  *          - NX_SECURE_TLS_ALERT_RECEIVED
342  *          - NX_SECURE_TLS_NO_SUPPORTED_CIPHERS
343  *          - NX_SECURE_X509_CHAIN_VERIFY_FAILURE
344  *          - NXD_MQTT_CONNECT_FAILURE
345  *          - NXD_MQTT_ERROR_SERVER_UNAVAILABLE
346  *          - NXD_MQTT_ERROR_NOT_AUTHORIZED
347  *          - NX_AZURE_IOT_DISCONNECTED
348  *
349  *          Setting the callback function to `NULL` disables the callback function.
350  *
351  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
352  * @param[in] connection_status_cb Pointer to a callback function invoked on connection status is changed.
353  * @return A `UINT` with the result of the API.
354  *   @retval #NX_AZURE_IOT_SUCCESS Successful if connection status callback is set.
355  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set connection status callback due to invalid parameter.
356  */
357 UINT nx_azure_iot_hub_client_connection_status_callback_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
358                                                             VOID (*connection_status_cb)(
359                                                                   struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *client_ptr,
360                                                                   UINT status));
361 
362 /**
363  * @brief Sets receive callback function
364  * @details This routine sets the IoT Hub receive callback function. This callback
365  *          function is invoked when a message is received from Azure IoT hub. Setting the
366  *          callback function to `NULL` disables the callback function. Message types can be:
367  *
368  *          - #NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE
369  *          - #NX_AZURE_IOT_HUB_COMMAND / NX_AZURE_IOT_HUB_DIRECT_METHOD
370  *          - #NX_AZURE_IOT_HUB_PROPERTIES / NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES
371  *          - #NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES / NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES
372  *
373  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
374  * @param[in] message_type Message type of callback function.
375  * @param[in] callback_ptr Pointer to a callback function invoked if the specified message type is received.
376  * @param[in] callback_args Pointer to an argument passed to callback function.
377  * @return A `UINT` with the result of the API.
378  *   @retval #NX_AZURE_IOT_SUCCESS Successful if callback function is set.
379  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set receive callback due to invalid parameter.
380  *   @retval #NX_AZURE_IOT_NOT_SUPPORTED Fail to set receive callback due to message_type not supported.
381  */
382 UINT nx_azure_iot_hub_client_receive_callback_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
383                                                   UINT message_type,
384                                                   VOID (*callback_ptr)(
385                                                         NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
386                                                         VOID *args),
387                                                   VOID *callback_args);
388 
389 /**
390  * @brief Creates telemetry message.
391  * @details This routine prepares a packet for sending telemetry data. After the packet is properly created,
392  *          application owns the `NX_PACKET` and can add additional user-defined properties before sending out.
393  *
394  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
395  * @param[out] packet_pptr Returned allocated `NX_PACKET` on success. Caller owns the `NX_PACKET` memory.
396  * @param[in] wait_option Ticks to wait if no packet is available.
397  * @return A `UINT` with the result of the API.
398  *   @retval #NX_AZURE_IOT_SUCCESS Successful if a packet is allocated.
399  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to allocate telemetry message due to invalid parameter.
400  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to allocate telemetry message due to SDK core error.
401  *   @retval NX_NO_PACKET Fail to allocate telemetry message due to no available packet in pool.
402  */
403 UINT nx_azure_iot_hub_client_telemetry_message_create(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
404                                                       NX_PACKET **packet_pptr,
405                                                       UINT wait_option);
406 
407 /**
408  * @brief Deletes telemetry message
409  *
410  * @param[in] packet_ptr The `NX_PACKET` to release.
411  * @return A `UINT` with the result of the API.
412  *   @retval #NX_AZURE_IOT_SUCCESS Successful if a packet is deallocated.
413  */
414 UINT nx_azure_iot_hub_client_telemetry_message_delete(NX_PACKET *packet_ptr);
415 
416 /**
417  * @brief Set component to telemetry message.
418  * @details This routine allows an application to set a component name to a telemetry message
419  *          before it is being sent. The component is stored in the sequence which the routine is being called.
420  *
421  * @param[in] packet_ptr A pointer to telemetry property packet.
422  * @param[in] component_name_ptr A pointer to a component name.
423  * @param[in] component_name_length Length of `component_name_ptr`. Does not include the `NULL` terminator.
424  * @param[in] wait_option Ticks to wait if no packet is available.
425  * @return A `UINT` with the result of the API.
426  *   @retval #NX_AZURE_IOT_SUCCESS Successful if component is set.
427  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set component due to invalid parameter.
428  *   @retval NX_NO_PACKET Fail to set component due to no available packet in pool.
429  */
430 UINT nx_azure_iot_hub_client_telemetry_component_set(NX_PACKET *packet_pptr,
431                                                      const UCHAR *component_name_ptr,
432                                                      USHORT component_name_length,
433                                                      UINT wait_option);
434 
435 /**
436  * @brief Add property to telemetry message
437  * @details This routine allows an application to add user-defined properties to a telemetry message
438  *          before it is being sent. This routine can be called multiple times to add all the properties to
439  *          the message. The properties are stored in the sequence which the routine is being called.
440  *          The property must be added after a telemetry packet is created, and before the telemetry
441  *          message is being sent.
442  *
443  * @param[in] packet_ptr A pointer to telemetry property packet.
444  * @param[in] property_name Pointer to property name.
445  * @param[in] property_name_length Length of property name.
446  * @param[in] property_value Pointer to property value.
447  * @param[in] property_value_length Length of property value.
448  * @param[in] wait_option Ticks to wait if packet needs to be expanded.
449  * @return A `UINT` with the result of the API.
450  *   @retval #NX_AZURE_IOT_SUCCESS Successful if property is added.
451  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to add property due to invalid parameter.
452  *   @retval NX_NO_PACKET Fail to add property due to no available packet in pool.
453  */
454 UINT nx_azure_iot_hub_client_telemetry_property_add(NX_PACKET *packet_ptr,
455                                                     const UCHAR *property_name, USHORT property_name_length,
456                                                     const UCHAR *property_value, USHORT property_value_length,
457                                                     UINT wait_option);
458 
459 /**
460  * @brief Sends telemetry message to IoTHub.
461  * @details This routine sends telemetry to IoTHub, with `packet_ptr` containing all the properties.
462  *          On successful return of this function, ownership of `NX_PACKET` is released.
463  *
464  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
465  * @param[in] packet_ptr A pointer to telemetry property packet.
466  * @param[in] telemetry_data Pointer to telemetry data.
467  * @param[in] data_size Size of telemetry data.
468  * @param[in] wait_option Ticks to wait for message to be sent.
469  * @return A `UINT` with the result of the API.
470  *   @retval #NX_AZURE_IOT_SUCCESS Successful if telemetry message is sent out.
471  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send telemetry message due to invalid parameter.
472  *   @retval #NX_AZURE_IOT_INVALID_PACKET Fail to send telemetry message due to packet is invalid.
473  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to send telemetry message due to no available packet in pool.
474  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to send telemetry message due to TCP/TLS error.
475  *   @retval NX_NO_PACKET Fail to send telemetry message due to no available packet in pool.
476  */
477 UINT nx_azure_iot_hub_client_telemetry_send(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, NX_PACKET *packet_ptr,
478                                             const UCHAR *telemetry_data, UINT data_size, UINT wait_option);
479 
480 /**
481  * @brief Sends telemetry message to IoTHub, and return the packet id.
482  * @details This routine sends telemetry to IoTHub, with `packet_ptr` containing all the properties.
483  *          On successful return of this function, ownership of `NX_PACKET` is released.
484  *
485  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
486  * @param[in] packet_ptr A pointer to telemetry property packet.
487  * @param[in] telemetry_data Pointer to telemetry data.
488  * @param[in] data_size Size of telemetry data.
489  * @param[out] packet_id_ptr Return packet id of telemetry message on success..
490  * @param[in] wait_option Ticks to wait for message to be sent.
491  * @return A `UINT` with the result of the API.
492  *   @retval #NX_AZURE_IOT_SUCCESS Successful if telemetry message is sent out.
493  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send telemetry message due to invalid parameter.
494  *   @retval #NX_AZURE_IOT_INVALID_PACKET Fail to send telemetry message due to packet is invalid.
495  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to send telemetry message due to no available packet in pool.
496  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to send telemetry message due to TCP/TLS error.
497  *   @retval NX_NO_PACKET Fail to send telemetry message due to no available packet in pool.
498  */
499 UINT nx_azure_iot_hub_client_telemetry_send_extended(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, NX_PACKET *packet_ptr,
500                                                      const UCHAR *telemetry_data, UINT data_size, USHORT *packet_id_ptr, UINT wait_option);
501 
502 /**
503  * @brief Sets the telemetry ack callback function.
504  * @details This routine sets the telemetry callback function. This callback function is invoked when a telemetry
505             is sent from device or a telemetry ack is received from Azure IoT hub. Setting the callback function
506  *          to 'NULL' disables the callback function.
507  *
508  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
509  * @param[in] callback_ptr Pointer to a callback function invoked.
510  * @return A `UINT` with the result of the API.
511  *   @retval #NX_AZURE_IOT_SUCCESS Successful if callback function is set.
512  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set callback due to invalid parameter.
513  */
514 UINT nx_azure_iot_hub_client_telemetry_ack_callback_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
515                                                         VOID (*callback_ptr)(
516                                                               NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
517                                                               USHORT packet_id));
518 
519 /**
520  * @brief Enable receiving C2D message from IoTHub.
521  *
522  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
523  * @return A `UINT` with the result of the API.
524  *   @retval #NX_AZURE_IOT_SUCCESS Successful if C2D message receiving is enabled.
525  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to enable C2D message receiving due to invalid parameter.
526  *   @retval NXD_MQTT_NOT_CONNECTED Fail to enable C2D message receiving due to MQTT not connected.
527  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to enable C2D message receiving due to no available packet in pool.
528  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to enable C2D message receiving due to TCP/TLS error.
529  */
530 UINT nx_azure_iot_hub_client_cloud_message_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
531 
532 /**
533  * @brief Disables receiving C2D message from IoTHub
534  *
535  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
536  * @return A `UINT` with the result of the API.
537  *   @retval #NX_AZURE_IOT_SUCCESS Successful if C2D message receiving is disabled.
538  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to disable C2D message receiving due to invalid parameter.
539  *   @retval NXD_MQTT_NOT_CONNECTED Fail to disable C2D message receiving due to MQTT not connected.
540  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to disable C2D message receiving due to no available packet in pool.
541  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to disable C2D message receiving due to TCP/TLS error.
542  */
543 UINT nx_azure_iot_hub_client_cloud_message_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
544 
545 /**
546  * @brief Receives C2D message from IoTHub
547  * @details This routine receives C2D message from IoT Hub. If there are no messages in the receive
548  *          queue, this routine can block.The amount of time it waits for a message is determined
549  *          by the `wait_option` parameter.
550  *
551  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
552  * @param[out] packet_pptr Return a `NX_PACKET` pointer with C2D message on success. Caller owns the `NX_PACKET` memory.
553  * @param[in] wait_option Ticks to wait for message to arrive.
554  * @return A `UINT` with the result of the API.
555  *   @retval #NX_AZURE_IOT_SUCCESS Successful if C2D message is received.
556  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive C2D message due to invalid parameter.
557  *   @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive C2D message due to it is not enabled.
558  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to receive C2D message due to timeout.
559  *   @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive C2D message due to disconnection.
560  */
561 UINT nx_azure_iot_hub_client_cloud_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
562                                                    NX_PACKET **packet_pptr, UINT wait_option);
563 
564 /**
565  * @brief Retrieve the property with given property name in the C2D message.
566  *
567  * @param[in] hub_client_ptr A pointer to a NX_AZURE_IOT_HUB_CLIENT.
568  * @param[in] packet_ptr Pointer to NX_PACKET containing C2D message.
569  * @param[in] property_name A `UCHAR` pointer to property name.
570  * @param[in] property_name_length Length of `property_name`.
571  * @param[out] property_value Pointer to `UCHAR` array that contains property values.
572  * @param[out] property_value_length A `USHORT` pointer to size of `property_value`.
573  * @return A `UINT` with the result of the API.
574  *   @retval #NX_AZURE_IOT_SUCCESS Successful if property is found and copied successfully into user buffer.
575  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to find the property due to invalid parameter.
576  *   @retval #NX_AZURE_IOT_INVALID_PACKET Fail to find the property due to the packet is invalid.
577  *   @retval #NX_AZURE_IOT_NOT_FOUND Property is not found.
578  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to find the property due to parsing error.
579  */
580 UINT nx_azure_iot_hub_client_cloud_message_property_get(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
581                                                         NX_PACKET *packet_ptr, const UCHAR *property_name,
582                                                         USHORT property_name_length, const UCHAR **property_value,
583                                                         USHORT *property_value_length);
584 
585 /**
586  * @brief Enables receiving direct method messages from IoTHub
587  *
588  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
589  * @return
590  *   @retval #NX_AZURE_IOT_SUCCESS Successful if direct method message receiving is enabled.
591  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to enable direct method message receiving due to invalid parameter.
592  *   @retval NXD_MQTT_NOT_CONNECTED Fail to enable direct method message receiving due to MQTT not connected.
593  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to enable direct method message receiving due to no available packet in pool.
594  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to enable direct method message receiving due to TCP/TLS error.
595  */
596 UINT nx_azure_iot_hub_client_direct_method_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
597 
598 /**
599  * @brief Disables receiving direct method messages from IoTHub
600  *
601  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
602  * @return A `UINT` with the result of the API.
603  *   @retval #NX_AZURE_IOT_SUCCESS Successful if direct method message receiving is disabled.
604  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to disable direct method message receiving due to invalid parameter.
605  *   @retval NXD_MQTT_NOT_CONNECTED Fail to disable direct method message receiving due to MQTT not connected.
606  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to disable direct method message receiving due to no available packet in pool.
607  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to disable direct method message receiving due to TCP/TLS error.
608  */
609 UINT nx_azure_iot_hub_client_direct_method_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
610 
611 /**
612  * @brief Receives direct method message from IoTHub
613  * @details This routine receives direct method message from IoT Hub. If there are no
614  *          messages in the receive queue, this routine can block. The amount of time it waits for a
615  *          message is determined by the `wait_option` parameter.
616  *
617  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
618  * @param[out] method_name_pptr Return a pointer to method name on success.
619  * @param[out] method_name_length_ptr Return length of `method_name_pptr` on success.
620  * @param[out] context_pptr Return a pointer to the context pointer on success.
621  * @param[out] context_length_ptr Return length of `context` on success.
622  * @param[out] packet_pptr Return `NX_PACKET` containing the method payload on success. Caller owns the `NX_PACKET` memory.
623  * @param[in] wait_option Ticks to wait for message to arrive.
624  * @return A `UINT` with the result of the API.
625  *   @retval #NX_AZURE_IOT_SUCCESS Successful if direct method message is received.
626  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive direct method message due to invalid parameter.
627  *   @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive direct method message due to it is not enabled.
628  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to receive direct method message due to timeout.
629  *   @retval #NX_AZURE_IOT_INVALID_PACKET Fail to receive direct method message due to invalid packet.
630  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to receive direct method message due to SDK core error.
631  *   @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive direct method message due to disconnect.
632  */
633 UINT nx_azure_iot_hub_client_direct_method_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
634                                                            const UCHAR **method_name_pptr, USHORT *method_name_length_ptr,
635                                                            VOID **context_pptr, USHORT *context_length_ptr,
636                                                            NX_PACKET **packet_pptr, UINT wait_option);
637 
638 /**
639  * @brief Return response to direct method message from IoTHub
640  * @details This routine returns response to the direct method message from IoT Hub.
641  * @note request_id ties the correlation between direct method receive and response.
642  *
643  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
644  * @param[in] status_code Status code for direct method.
645  * @param[in] context_ptr Pointer to context return from nx_azure_iot_hub_client_direct_method_message_receive().
646  * @param[in] context_length Length of context.
647  * @param[in] payload  Pointer to `UCHAR` containing the payload for the direct method response. Payload is in JSON format.
648  * @param[in] payload_length Length of `payload`
649  * @param[in] wait_option Ticks to wait for message to send.
650  * @return A `UINT` with the result of the API.
651  *   @retval #NX_AZURE_IOT_SUCCESS Successful if direct method response is send.
652  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send direct method response due to invalid parameter.
653  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to send direct method response due to SDK core error.
654  *   @retval NX_NO_PACKET Fail send direct method response due to no available packet in pool.
655  */
656 UINT nx_azure_iot_hub_client_direct_method_message_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
657                                                             UINT status_code, VOID *context_ptr,
658                                                             USHORT context_length, const UCHAR *payload,
659                                                             UINT payload_length, UINT wait_option);
660 
661 /**
662  * @brief Enables receiving command messages from IoTHub
663  *
664  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
665  * @return
666  *   @retval #NX_AZURE_IOT_SUCCESS Successful if command message receiving is enabled.
667  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to enable command message receiving due to invalid parameter.
668  *   @retval NXD_MQTT_NOT_CONNECTED Fail to enable command message receiving due to MQTT not connected.
669  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to enable command message receiving due to no available packet in pool.
670  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to enable command message receiving due to TCP/TLS error.
671  */
672 UINT nx_azure_iot_hub_client_command_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
673 
674 /**
675  * @brief Disables receiving command messages from IoTHub
676  *
677  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
678  * @return A `UINT` with the result of the API.
679  *   @retval #NX_AZURE_IOT_SUCCESS Successful if command message receiving is disabled.
680  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to disable command message receiving due to invalid parameter.
681  *   @retval NXD_MQTT_NOT_CONNECTED Fail to disable command message receiving due to MQTT not connected.
682  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to disable command message receiving due to no available packet in pool.
683  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to disable command message receiving due to TCP/TLS error.
684  */
685 UINT nx_azure_iot_hub_client_command_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
686 
687 /**
688  * @brief Receives PnP command message from IoTHub
689  * @details This routine receives command message from IoT Hub. If there are no
690  *          messages in the receive queue, this routine can block. The amount of time it waits for a
691  *          message is determined by the `wait_option` parameter.
692  *
693  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
694  * @param[out] component_name_pptr Return a pointer to PnP component name on success.
695  * @param[out] component_name_length_ptr Return length of `*component_name_pptr` on success.
696  * @param[out] command_name_pptr Return a pointer to command name on success.
697  * @param[out] command_name_length_ptr Return length of `command_name_pptr` on success.
698  * @param[out] context_pptr Return a pointer to the context pointer on success.
699  * @param[out] context_length_ptr Return length of `context` on success.
700  * @param[out] packet_pptr Return `NX_PACKET` containing the command payload on success. Caller owns the `NX_PACKET` memory.
701  * @param[in] wait_option Ticks to wait for message to arrive.
702  * @return A `UINT` with the result of the API.
703  *   @retval #NX_AZURE_IOT_SUCCESS Successful if command message is received.
704  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive command message due to invalid parameter.
705  *   @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive command message due to it is not enabled.
706  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to receive command message due to timeout.
707  *   @retval #NX_AZURE_IOT_INVALID_PACKET Fail to receive command message due to invalid packet.
708  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to receive command message due to SDK core error.
709  *   @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive command message due to disconnect.
710  */
711 UINT nx_azure_iot_hub_client_command_message_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
712                                                      const UCHAR **component_name_pptr, USHORT *component_name_length_ptr,
713                                                      const UCHAR **command_name_pptr, USHORT *command_name_length_ptr,
714                                                      VOID **context_pptr, USHORT *context_length_ptr,
715                                                      NX_PACKET **packet_pptr, UINT wait_option);
716 
717 /**
718  * @brief Return response to PnP command message from IoTHub
719  * @details This routine returns response to the command message from IoT Hub.
720  * @note request_id ties the correlation between command receive and response.
721  *
722  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
723  * @param[in] status_code Status code for command.
724  * @param[in] context_ptr Pointer to context return from nx_azure_iot_hub_client_command_message_receive().
725  * @param[in] context_length Length of context.
726  * @param[in] payload  Pointer to `UCHAR` containing the payload for the command response. Payload is in JSON format.
727  * @param[in] payload_length Length of `payload`
728  * @param[in] wait_option Ticks to wait for message to send.
729  * @return A `UINT` with the result of the API.
730  *   @retval #NX_AZURE_IOT_SUCCESS Successful if command response is send.
731  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send command response due to invalid parameter.
732  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to send command response due to SDK core error.
733  *   @retval NX_NO_PACKET Fail send command response due to no available packet in pool.
734  */
735 UINT nx_azure_iot_hub_client_command_message_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
736                                                       UINT status_code, VOID *context_ptr,
737                                                       USHORT context_length, const UCHAR *payload,
738                                                       UINT payload_length, UINT wait_option);
739 
740 /**
741  * @brief Enables device twin feature
742  * @details This routine enables device twin feature.
743  *
744  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT
745  * @return A `UINT` with the result of the API.
746  *   @retval #NX_AZURE_IOT_SUCCESS Successful if device twin feature is enabled.
747  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to enable device twin feature due to invalid parameter.
748  *   @retval NXD_MQTT_NOT_CONNECTED Fail to enable device twin feature due to MQTT not connected.
749  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to enable device twin feature due to no available packet in pool.
750  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to enable device twin feature due to TCP/TLS error.
751  */
752 UINT nx_azure_iot_hub_client_device_twin_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
753 
754 /**
755  * @brief Disables device twin feature
756  * @details This routine disables device twin feature.
757  *
758  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT
759  * @return A `UINT` with the result of the API.
760  *   @retval #NX_AZURE_IOT_SUCCESS Successful if device twin feature is disabled.
761  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to disable device twin feature due to invalid parameter.
762  *   @retval NXD_MQTT_NOT_CONNECTED Fail to disable device twin feature due to MQTT not connected.
763  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to disable device twin feature due to no available packet in pool.
764  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to disable device twin feature due to TCP/TLS error.
765  */
766 UINT nx_azure_iot_hub_client_device_twin_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
767 
768 /**
769  * @brief Sets reported properties response callback function
770  * @details This routine sets the reponse receive callback function for reported properties. This callback
771  *          function is invoked when a response is received from Azure IoT hub for reported properties and no
772  *          thread is waiting for response. Setting the callback function to `NULL` disables the callback
773  *          function.
774  *
775  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
776  * @param[in] callback_ptr Pointer to a callback function invoked.
777  * @param[in] callback_args Pointer to an argument passed to callback function.
778  * @return A `UINT` with the result of the API.
779  *   @retval #NX_AZURE_IOT_SUCCESS Successful if callback function is set.
780  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set callback due to invalid parameter.
781  */
782 UINT nx_azure_iot_hub_client_reported_properties_response_callback_set(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
783                                                                        VOID (*callback_ptr)(
784                                                                              NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
785                                                                              UINT request_id,
786                                                                              UINT response_status,
787                                                                              ULONG version,
788                                                                              VOID *args),
789                                                                        VOID *callback_args);
790 
791 /* Map old API to new API.  */
792 #define nx_azure_iot_hub_client_report_properties_response_callback_set nx_azure_iot_hub_client_reported_properties_response_callback_set
793 
794 /**
795  * @brief Send device twin reported properties to IoT Hub
796  * @details This routine sends device twin reported properties to IoT Hub.
797  *
798  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
799  * @param[in] message_buffer JSON document containing the reported properties.
800  * @param[in] message_length Length of JSON document.
801  * @param[out] request_id_ptr Request Id assigned to the request.
802  * @param[out] response_status_ptr Status return for successful send of reported properties.
803  * @param[out] version_ptr Version return for successful send of reported properties.
804  * @param[in] wait_option Ticks to wait for message to send.
805  * @return A `UINT` with the result of the API.
806  *   @retval #NX_AZURE_IOT_SUCCESS Successful if device twin reported properties is sent.
807  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send reported properties due to invalid parameter.
808  *   @retval #NX_AZURE_IOT_NOT_ENABLED Fail to send reported properties due to device twin is not enabled.
809  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to send reported properties due to SDK core error.
810  *   @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to send reported properties due to buffer size is too small.
811  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to send reported properties due to no packet available.
812  *   @retval NX_NO_PACKET Fail to send reported properties due to no packet available.
813  *   @retval #NX_AZURE_IOT_DISCONNECTED Fail to send reported properties due to disconnect.
814  */
815 UINT nx_azure_iot_hub_client_device_twin_reported_properties_send(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
816                                                                   const UCHAR *message_buffer, UINT message_length,
817                                                                   UINT *request_id_ptr, UINT *response_status_ptr,
818                                                                   ULONG *version_ptr, UINT wait_option);
819 
820 /**
821  * @brief Request complete device twin properties
822  * @details This routine requests complete device twin properties.
823  *
824  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT
825  * @param[in] wait_option Ticks to wait for sending request.
826  * @return A `UINT` with the result of the API.
827  *   @retval #NX_AZURE_IOT_SUCCESS Successful if device twin properties is requested.
828  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send device twin request due to invalid parameter.
829  *   @retval #NX_AZURE_IOT_NO_SUBSCRIBE_ACK Fail to send device twin request due to no subscribe ack.
830  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to send device twin request due to SDK core error.
831  *   @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to send device twin request due to buffer size is too small.
832  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to send device twin request due to no packet available.
833  *   @retval NX_NO_PACKET Fail to send device twin request due to no packet available.
834  */
835 UINT nx_azure_iot_hub_client_device_twin_properties_request(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
836                                                             UINT wait_option);
837 
838 /**
839  * @brief Receive complete device twin properties
840  * @details This routine receives complete device twin properties.
841  *
842  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT
843  * @param[out] packet_pptr Pointer to #NX_PACKET* that contains complete twin document. Caller owns the `NX_PACKET` memory.
844  * @param[in] wait_option Ticks to wait for message to receive.
845  * @return A `UINT` with the result of the API.
846  *   @retval #NX_AZURE_IOT_SUCCESS Successful if device twin properties is received.
847  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive device twin properties due to invalid parameter.
848  *   @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive device twin properties due to it is not enabled.
849  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to receive device twin properties due to timeout.
850  *   @retval #NX_AZURE_IOT_INVALID_PACKET Fail to receive device twin properties due to invalid packet.
851  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to receive device twin properties due to SDK core error.
852  *   @retval #NX_AZURE_IOT_SERVER_RESPONSE_ERROR Response code from server is not 2xx.
853  *   @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive device twin properties due to disconnect.
854  */
855 UINT nx_azure_iot_hub_client_device_twin_properties_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
856                                                             NX_PACKET **packet_pptr, UINT wait_option);
857 
858 /**
859  * @brief Receive desired properties form IoTHub
860  * @details This routine receives desired properties from IoTHub.
861  *
862  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
863  * @param[out] packet_pptr Pointer to #NX_PACKET* that contains complete twin document. Caller owns the `NX_PACKET` memory.
864  * @param[in] wait_option Ticks to wait for message to receive.
865  * @return A `UINT` with the result of the API.
866  *   @retval #NX_AZURE_IOT_SUCCESS Successful if desired properties is received.
867  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive desired properties due to invalid parameter.
868  *   @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive desired properties due to it is not enabled.
869  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to receive desired properties due to timeout.
870  *   @retval #NX_AZURE_IOT_INVALID_PACKET Fail to receive desired properties due to invalid packet.
871  *   @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive desired properties due to disconnect.
872  */
873 UINT nx_azure_iot_hub_client_device_twin_desired_properties_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
874                                                                     NX_PACKET **packet_pptr, UINT wait_option);
875 
876 /**
877  * @brief Enables properties feature
878  * @details This routine enables property feature.
879  *
880  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT
881  * @return A `UINT` with the result of the API.
882  *   @retval #NX_AZURE_IOT_SUCCESS Successful if property feature is enabled.
883  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to enable property feature due to invalid parameter.
884  *   @retval NXD_MQTT_NOT_CONNECTED Fail to enable property feature due to MQTT not connected.
885  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to enable property feature due to no available packet in pool.
886  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to enable property feature due to TCP/TLS error.
887  */
888 UINT nx_azure_iot_hub_client_properties_enable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
889 
890 /**
891  * @brief Disables properties feature
892  * @details This routine disables property feature.
893  *
894  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT
895  * @return A `UINT` with the result of the API.
896  *   @retval #NX_AZURE_IOT_SUCCESS Successful if property feature is disabled.
897  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to disable property feature due to invalid parameter.
898  *   @retval NXD_MQTT_NOT_CONNECTED Fail to disable property feature due to MQTT not connected.
899  *   @retval NXD_MQTT_PACKET_POOL_FAILURE Fail to disable property feature due to no available packet in pool.
900  *   @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to disable property feature due to TCP/TLS error.
901  */
902 UINT nx_azure_iot_hub_client_properties_disable(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr);
903 
904 /**
905  * @brief Creates reported properties message.
906  *
907  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
908  * @param[out] packet_pptr Return `NX_PACKET` containing the reported properties payload on success.
909  * @param[in] wait_option Ticks to wait for writer creation
910  * @return A `UINT` with the result of the API.
911  *   @retval #NX_AZURE_IOT_SUCCESS Successful if a message writer is created.
912  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to create message writer due to invalid parameter.
913  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to create message writer due to SDK core error.
914  *   @retval NX_NO_PACKET Fail to create message writer due to no available packet in pool.
915  */
916 UINT nx_azure_iot_hub_client_reported_properties_create(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
917                                                         NX_PACKET **packet_pptr,
918                                                         UINT wait_option);
919 
920 /**
921  * @brief Sends reported properties message to IoTHub.
922  * @note The return status of the API indicates if the reported properties is sent out successfully or not,
923  * the response status is used to track if the reported properties is accepted or not by IoT Hub, and the
924  * reponse status is available only when the return status is NX_AZURE_IOT_SUCCESS.
925  *
926  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
927  * @param[in] packet_ptr A pointer to a #NX_PACKET
928  * @param[out] request_id_ptr Request Id assigned to the request.
929  * @param[out] response_status_ptr Status return for successful send of reported properties.
930  * @param[out] version_ptr Version return for successful send of reported properties.
931  * @param[in] wait_option Ticks to wait for message to send.
932  * @return A `UINT` with the result of the API.
933  *   @retval #NX_AZURE_IOT_SUCCESS Successful if reported properties is sent.
934  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to send reported properties due to invalid parameter.
935  *   @retval #NX_AZURE_IOT_NOT_ENABLED Fail to send reported properties due to property is not enabled.
936  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to send reported properties due to SDK core error.
937  *   @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to send reported properties due to buffer size is too small.
938  *   @retval NX_NO_PACKET Fail to send reported properties due to no packet available.
939  *   @retval #NX_AZURE_IOT_DISCONNECTED Fail to send reported properties due to disconnect.
940  */
941 UINT nx_azure_iot_hub_client_reported_properties_send(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
942                                                       NX_PACKET *packet_ptr,
943                                                       UINT *request_id_ptr, UINT *response_status_ptr,
944                                                       ULONG *version_ptr, UINT wait_option);
945 
946 /**
947  * @brief Request complete properties
948  * @details This routine requests complete properties.
949  *
950  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
951  * @param[in] wait_option Ticks to wait for request to send.
952  * @return A `UINT` with the result of the API.
953  *   @retval #NX_AZURE_IOT_SUCCESS Successful if request get all properties is sent.
954  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to request get all properties due to invalid parameter.
955  *   @retval #NX_AZURE_IOT_NO_SUBSCRIBE_ACK Fail to request get all properties due to no subscribe ack.
956  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to request get all properties due to SDK core error.
957  *   @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to request get all properties due to buffer size is too small.
958  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to request get all properties due to no packet available.
959  *   @retval NX_NO_PACKET Fail to request get all properties due to no packet available.
960  */
961 UINT nx_azure_iot_hub_client_properties_request(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
962                                                 UINT wait_option);
963 
964 /**
965  * @brief Receive all the properties
966  * @details This routine receives all the properties.
967  *
968  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
969  * @param[out] packet_pptr Return `NX_PACKET` containing properties payload on success.
970  * @param[in] wait_option Ticks to wait for message to receive.
971  * @return A `UINT` with the result of the API.
972  *   @retval #NX_AZURE_IOT_SUCCESS Successful if all properties is received.
973  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive all properties due to invalid parameter.
974  *   @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive all properties due to it is not enabled.
975  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to receive all properties due to timeout.
976  *   @retval #NX_AZURE_IOT_INVALID_PACKET Fail to receive all properties due to invalid packet.
977  *   @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to receive all properties due to SDK core error.
978  *   @retval #NX_AZURE_IOT_SERVER_RESPONSE_ERROR Response code from server is not 2xx.
979  *   @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive all properties due to disconnect.
980  */
981 UINT nx_azure_iot_hub_client_properties_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
982                                                 NX_PACKET **packet_pptr,
983                                                 UINT wait_option);
984 
985 /**
986  * @brief Receive writable properties form IoTHub
987  * @details This routine receives writable properties from IoTHub.
988  *
989  * @param[in] hub_client_ptr A pointer to a #NX_AZURE_IOT_HUB_CLIENT.
990  * @param[out] packet_pptr A pointer to a #NX_PACKET containing writable properties on success.
991  * @param[in] wait_option Ticks to wait for message to receive.
992  * @return A `UINT` with the result of the API.
993  *   @retval #NX_AZURE_IOT_SUCCESS Successful if writable properties is received.
994  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to receive writable properties due to invalid parameter.
995  *   @retval #NX_AZURE_IOT_NOT_ENABLED Fail to receive writable properties due to it is not enabled.
996  *   @retval #NX_AZURE_IOT_NO_PACKET Fail to receive writable properties due to timeout.
997  *   @retval #NX_AZURE_IOT_INVALID_PACKET Fail to receive writable properties due to invalid packet.
998  *   @retval #NX_AZURE_IOT_DISCONNECTED Fail to receive writable properties due to disconnect.
999  */
1000 UINT nx_azure_iot_hub_client_writable_properties_receive(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr,
1001                                                          NX_PACKET **packet_pptr,
1002                                                          UINT wait_option);
1003 
1004 #ifdef __cplusplus
1005 }
1006 #endif
1007 #endif /* NX_AZURE_IOT_HUB_CLIENT_H */
1008