1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 /**
13  * @file nx_azure_iot_provisioning_client.h
14  *
15  * @brief Definition for the Azure Device Provisioning client.
16  * @remark The Device Provisioning MQTT protocol is described at
17  * https://docs.microsoft.com/en-us/azure/iot-dps/iot-dps-mqtt-support.
18  *
19  */
20 
21 #ifndef NX_AZURE_IOT_PROVISIONING_CLIENT_H
22 #define NX_AZURE_IOT_PROVISIONING_CLIENT_H
23 
24 #ifdef __cplusplus
25 extern   "C" {
26 #endif
27 
28 #include "azure/iot/az_iot_provisioning_client.h"
29 #include "nx_azure_iot.h"
30 #include "nx_api.h"
31 #include "nxd_mqtt_client.h"
32 
33 /* Define the MAX status size. */
34 #ifndef NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_STATUS_ID_SIZE
35 #define NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_STATUS_ID_SIZE        30
36 #endif /* NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_STATUS_ID_SIZE */
37 
38 /* Define the MAX deviceID size. */
39 #ifndef NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_ID_BUFFER_SIZE
40 #define NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_ID_BUFFER_SIZE        100
41 #endif /* NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_ID_BUFFER_SIZE */
42 
43 /* Define the MAX IoT Hub Endpoint size. */
44 #ifndef NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_HUB_SIZE
45 #define NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_HUB_SIZE              100
46 #endif /* NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_HUB_SIZE */
47 
48 /* Define the MAX operation Id of provisioning service. */
49 #ifndef NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_REQ_OP_ID_SIZE
50 #define NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_REQ_OP_ID_SIZE        100
51 #endif /* NX_AZURE_IOT_PROVISIONING_CLIENT_MAX_REQ_OP_ID_SIZE */
52 
53 /* Set the default token expiry in secs.  */
54 #ifndef NX_AZURE_IOT_PROVISIONING_CLIENT_TOKEN_EXPIRY
55 #define NX_AZURE_IOT_PROVISIONING_CLIENT_TOKEN_EXPIRY              (3600)
56 #endif /* NX_AZURE_IOT_PROVISIONING_CLIENT_TOKEN_EXPIRY */
57 
58 /* Set the default timeout for DNS query.  */
59 #ifndef NX_AZURE_IOT_PROVISIONING_CLIENT_DNS_TIMEOUT
60 #define NX_AZURE_IOT_PROVISIONING_CLIENT_DNS_TIMEOUT               (5 * NX_IP_PERIODIC_RATE)
61 #endif /* NX_AZURE_IOT_PROVISIONING_CLIENT_DNS_TIMEOUT */
62 
63 typedef struct NX_AZURE_IOT_PROVISIONING_DEVICE_RESPONSE_STRUCT
64 {
65     az_iot_provisioning_client_register_response    register_response;
66     NX_PACKET                                      *packet_ptr;
67 } NX_AZURE_IOT_PROVISIONING_RESPONSE;
68 
69 typedef struct NX_AZURE_IOT_PROVISIONING_THREAD_STRUCT
70 {
71     TX_THREAD                                      *thread_ptr;
72     struct NX_AZURE_IOT_PROVISIONING_THREAD_STRUCT *thread_next;
73 } NX_AZURE_IOT_PROVISIONING_THREAD;
74 
75 /**
76  * @brief Azure IoT Provisining Client struct
77  *
78  */
79 typedef struct NX_AZURE_IOT_PROVISIONING_CLIENT_STRUCT
80 {
81     NX_AZURE_IOT                           *nx_azure_iot_ptr;
82 
83     UINT                                    nx_azure_iot_provisioning_client_state;
84     NX_AZURE_IOT_PROVISIONING_THREAD       *nx_azure_iot_provisioning_client_thread_suspended;
85 
86     UINT                                    nx_azure_iot_provisioning_client_req_timeout;
87     NX_PACKET                              *nx_azure_iot_provisioning_client_last_response;
88     UINT                                    nx_azure_iot_provisioning_client_request_id;
89     UINT                                    nx_azure_iot_provisioning_client_result;
90     NX_AZURE_IOT_PROVISIONING_RESPONSE      nx_azure_iot_provisioning_client_response;
91     VOID                                  (*nx_azure_iot_provisioning_client_on_complete_callback)(
92                                            struct NX_AZURE_IOT_PROVISIONING_CLIENT_STRUCT *prov_client_ptr,
93                                            UINT status);
94 
95     const UCHAR                            *nx_azure_iot_provisioning_client_endpoint;
96     UINT                                    nx_azure_iot_provisioning_client_endpoint_length;
97     const UCHAR                            *nx_azure_iot_provisioning_client_id_scope;
98     UINT                                    nx_azure_iot_provisioning_client_id_scope_length;
99     const UCHAR                            *nx_azure_iot_provisioning_client_registration_payload;
100     UINT                                    nx_azure_iot_provisioning_client_registration_payload_length;
101     const UCHAR                            *nx_azure_iot_provisioning_client_registration_id;
102     UINT                                    nx_azure_iot_provisioning_client_registration_id_length;
103     const UCHAR                            *nx_azure_iot_provisioning_client_symmetric_key;
104     UINT                                    nx_azure_iot_provisioning_client_symmetric_key_length;
105     UCHAR                                  *nx_azure_iot_provisioning_client_sas_token;
106     UINT                                    nx_azure_iot_provisioning_client_sas_token_buff_size;
107 
108     NX_AZURE_IOT_RESOURCE                   nx_azure_iot_provisioning_client_resource;
109     az_iot_provisioning_client              nx_azure_iot_provisioning_client_core;
110 } NX_AZURE_IOT_PROVISIONING_CLIENT;
111 
112 
113 /**
114  * @brief Initialize Azure IoT Provisioning instance
115  * @details This routine initializes the device to the IoT provisioning service.
116  *
117  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
118  * @param[in] nx_azure_iot_ptr A pointer to a #NX_AZURE_IOT.
119  * @param[in] endpoint A `UCHAR` pointer to IoT Provisioning endpoint. Must be `NULL` terminated.
120  * @param[in] endpoint_length Length of `endpoint`. Does not include the `NULL` terminator.
121  * @param[in] id_scope A `UCHAR` pointer to ID Scope.
122  * @param[in] id_scope_length Length of the `id_scope`. Does not include the `NULL` terminator.
123  * @param[in] registration_id A `UCHAR` pointer to registration ID.
124  * @param[in] registration_id_length Length of `registration_id`. Does not include the `NULL` terminator.
125  * @param[in] crypto_array A pointer to `NX_CRYPTO_METHOD`.
126  * @param[in] crypto_array_size Size of `crypto_array`.
127  * @param[in] cipher_map A pointer to `NX_CRYPTO_CIPHERSUITE`.
128  * @param[in] cipher_map_size Size of `cipher_map`.
129  * @param[in] metadata_memory A `UCHAR` pointer to metadata memory buffer.
130  * @param[in] memory_size Size of metadata buffer.
131  * @param[in] trusted_certificate A pointer to `NX_SECURE_X509_CERT`, which are the server side certs.
132  * @return A `UINT` with the result of the API.
133  *  @retval #NX_AZURE_IOT_SUCCESS Successfully initialized to Azure IoT Provisioning Client.
134  *  @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to initialize the Azure IoT Provisioning Client due to invalid parameter.
135  *  @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to initialize the Azure IoT Provisioning Client due to SDK core error.
136  *  @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to initialize the Azure IoT Provisioning Client due to buffer size is too small.
137  */
138 UINT nx_azure_iot_provisioning_client_initialize(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr,
139                                                  NX_AZURE_IOT *nx_azure_iot_ptr,
140                                                  const UCHAR *endpoint, UINT endpoint_length,
141                                                  const UCHAR *id_scope, UINT id_scope_length,
142                                                  const UCHAR *registration_id, UINT registration_id_length,
143                                                  const NX_CRYPTO_METHOD **crypto_array, UINT crypto_array_size,
144                                                  const NX_CRYPTO_CIPHERSUITE **cipher_map, UINT cipher_map_size,
145                                                  UCHAR *metadata_memory, UINT memory_size,
146                                                  NX_SECURE_X509_CERT *trusted_certificate);
147 
148 /**
149  * @brief Cleanup the Azure IoT Provisioning Client.
150  * @details This routine de-initializes the Azure IoT Provisioning Client.
151  *
152  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
153  * @return A `UINT` with the result of the API.
154  *  @retval #NX_AZURE_IOT_SUCCESS Successfully cleaned up AZ IoT Provisioning Client Instance.
155  *  @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to deinitialize the AZ IoT Provisioning Client Instance due to invalid parameter.
156  *  @retval #NX_AZURE_IOT_NOT_FOUND Fail to deinitialize the AZ IoT Provisioning Client Instance due to resource not found.
157  */
158 UINT nx_azure_iot_provisioning_client_deinitialize(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr);
159 
160 /**
161  * @brief Add more trusted certificate in the IoT Provisioning client if needed. It can be called multiple times to set certificate chain.
162  *
163  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
164  * @param[in] trusted_certificate A pointer to a `NX_SECURE_X509_CERT`, which is the trusted certificate.
165  * @return A `UINT` with the result of the API.
166  *  @retval #NX_AZURE_IOT_SUCCESS Successfully add trusted certificate to AZ IoT Provisioning Client Instance.
167  *  @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to add trusted certificate to AZ IoT Provisioning Client Instance due to invalid parameter.
168  *  @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.
169  */
170 UINT nx_azure_iot_provisioning_client_trusted_cert_add(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr,
171                                                        NX_SECURE_X509_CERT *trusted_certificate);
172 
173 /**
174  * @brief Set client certificate.
175  * @details This routine sets the device certificate. It can be called multiple times to set certificate chain.
176  *
177  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
178  * @param[in] x509_cert A pointer to a `NX_SECURE_X509_CERT` client cert.
179  * @return A `UINT` with the result of the API.
180  *  @retval #NX_AZURE_IOT_SUCCESS Successfully set device certs to AZ IoT Provisioning Client Instance.
181  *  @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set device certs to AZ IoT Provisioning Client Instance due to invalid parameter.
182  *  @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.
183  */
184 UINT nx_azure_iot_provisioning_client_device_cert_set(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr,
185                                                       NX_SECURE_X509_CERT *x509_cert);
186 
187 /**
188  * @brief Set symmetric key
189  * @details This routine sets symmetric key.
190  *
191  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
192  * @param[in] symmetric_key A UCHAR pointer to a symmetric key.
193  * @param[in] symmetric_key_length Length of symmetric key.
194  * @return A `UINT` with the result of the API.
195  *  @retval #NX_AZURE_IOT_SUCCESS Successfully set symmetric key to the IoT Provisioning client.
196  *  @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set symmetric key to AZ IoT Provisioning Client Instance due to invalid parameter.
197  */
198 UINT nx_azure_iot_provisioning_client_symmetric_key_set(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr,
199                                                         const UCHAR *symmetric_key, UINT symmetric_key_length);
200 
201 #ifdef NXD_MQTT_OVER_WEBSOCKET
202 /**
203  * @brief Enable using MQTT over WebSocket to register device to Azure IoT Provisioning service.
204  *
205  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
206  * @return A `UINT` with the result of the API.
207  *   @retval #NX_AZURE_IOT_SUCCESS Successful if MQTT over WebSocket is enabled.
208  *   @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to enable MQTT over WebSocket due to invalid parameter.
209  */
210 UINT nx_azure_iot_provisioning_client_websocket_enable(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr);
211 #endif /* NXD_MQTT_OVER_WEBSOCKET */
212 
213 /**
214  * @brief Register device to Azure IoT Provisioning service.
215  * @details This routine registers device to Azure IoT Provisioning service.
216  *
217  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
218  * @param[in] wait_option Number of ticks to block for device registration.
219  * @return A `UINT` with the result of the API.
220  *  @retval #NX_AZURE_IOT_SUCCESS Successfully register device to AZ IoT Provisioning.
221  *  @retval #NX_AZURE_IOT_PENDING Successfully started registration of device but not yet completed.
222  *  @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to register device to AZ IoT Provisioning due to invalid parameter.
223  *  @retval #NX_AZURE_IOT_SDK_CORE_ERROR Fail to register device to AZ IoT Provisioning due to SDK core error.
224  *  @retval #NX_AZURE_IOT_SERVER_RESPONSE_ERROR Fail to register device to AZ IoT Provisioning due to error response from server.
225  *  @retval #NX_AZURE_IOT_DISCONNECTED Fail to register device to AZ IoT Provisioning due to disconnection.
226  *  @retval NX_DNS_QUERY_FAILED Fail to register device to AZ IoT Provisioning due to hostname can not be resolved.
227  *  @retval NX_NO_PACKET Fail to register device to AZ IoT Provisioning due to no available packet in pool.
228  *  @retval NX_INVALID_PARAMETERS Fail to register device to AZ IoT Provisioning due to invalid parameters.
229  *  @retval NX_SECURE_TLS_INSUFFICIENT_METADATA_SPACE Fail to register device to AZ IoT Provisioning due to insufficient metadata space.
230  *  @retval NX_SECURE_TLS_UNSUPPORTED_CIPHER Fail to register device to AZ IoT Provisioning due to unsupported cipher.
231  *  @retval NXD_MQTT_ALREADY_CONNECTED Fail to register device to AZ IoT Provisioning due to MQTT session is not disconnected.
232  *  @retval NXD_MQTT_CONNECT_FAILURE Fail to register device to AZ IoT Provisioning due to TCP/TLS connect error.
233  *  @retval NXD_MQTT_COMMUNICATION_FAILURE Fail to register device to AZ IoT Provisioning due to MQTT connect error.
234  *  @retval NXD_MQTT_ERROR_SERVER_UNAVAILABLE Fail to register device to AZ IoT Provisioning due to server unavailable.
235  *  @retval NXD_MQTT_ERROR_NOT_AUTHORIZED Fail to register device to AZ IoT Provisioning due to authentication error.
236  */
237 UINT nx_azure_iot_provisioning_client_register(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr, UINT wait_option);
238 
239 /**
240  * @brief Set registration completion callback
241  * @details This routine sets the callback for registration completion.
242  *
243  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
244  * @param[in] on_complete_callback Registration completion callback.
245  * @return A `UINT` with the result of the API.
246  *  @retval #NX_AZURE_IOT_SUCCESS Successful register completion callback.
247  *  @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to register completion callback due to invalid parameter.
248  */
249 UINT nx_azure_iot_provisioning_client_completion_callback_set(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr,
250                                                               VOID (*on_complete_callback)(
251                                                                     struct NX_AZURE_IOT_PROVISIONING_CLIENT_STRUCT *client_ptr,
252                                                                     UINT status));
253 
254 /**
255  * @brief Set registration payload
256  * @details This routine sets registration payload, which is JSON object.
257  *
258  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
259  * @param[in] payload_ptr A pointer to registration payload.
260  * @param[in] payload_length Length of `payload`. Does not include the `NULL` terminator.
261  * @return A `UINT` with the result of the API.
262  *  @retval #NX_AZURE_IOT_SUCCESS Successfully set registration payload to Azure IoT Provisioning Client.
263  *  @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to set registration payload Azure IoT Provisioning Client due to invalid parameter.
264  */
265 UINT nx_azure_iot_provisioning_client_registration_payload_set(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr,
266                                                                const UCHAR *payload_ptr, UINT payload_length);
267 
268 /**
269  * @brief Get IoTHub device info into user supplied buffer.
270  * @details This routine gets the device id and puts it into a user supplied buffer.
271  *
272  * @param[in] prov_client_ptr A pointer to a #NX_AZURE_IOT_PROVISIONING_CLIENT.
273  * @param[out] iothub_hostname Buffer pointer that will contain IoTHub hostname.
274  * @param[in/out] iothub_hostname_len Pointer to UINT that contains size of buffer supplied. On successful return,
275  *               it contains bytes copied to the buffer.
276  * @param[out] device_id Buffer pointer that will contain IoTHub deviceId.
277  * @param[in/out] device_id_len Pointer to UINT that contains size of buffer supplied, once successfully return it contains bytes copied to buffer.
278  * @return A `UINT` with the result of the API.
279  *  @retval #NX_AZURE_IOT_SUCCESS The device info is successfully retrieved to user supplied buffers.
280  *  @retval #NX_AZURE_IOT_INVALID_PARAMETER Fail to retrieve device info due to invalid parameter.
281  *  @retval #NX_AZURE_IOT_WRONG_STATE Fail to retrieve device info due to wrong state.
282  *  @retval #NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE Fail to retrieve device info due to buffer size is too small.
283  */
284 UINT nx_azure_iot_provisioning_client_iothub_device_info_get(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr,
285                                                              UCHAR *iothub_hostname, UINT *iothub_hostname_len,
286                                                              UCHAR *device_id, UINT *device_id_len);
287 
288 #ifdef __cplusplus
289 }
290 #endif
291 #endif /* NX_AZURE_IOT_PROVISIONING_CLIENT_H */
292