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 #include <stdio.h>
13 
14 #include "nx_api.h"
15 #include "nx_azure_iot_hub_client.h"
16 #include "nx_azure_iot_provisioning_client.h"
17 
18 /* These are sample files, user can build their own certificate and ciphersuites.  */
19 #include "nx_azure_iot_cert.h"
20 #include "nx_azure_iot_ciphersuites.h"
21 #include "sample_config.h"
22 
23 /* Define Azure RTOS TLS info.  */
24 static NX_SECURE_X509_CERT root_ca_cert;
25 static NX_SECURE_X509_CERT root_ca_cert_2;
26 static NX_SECURE_X509_CERT root_ca_cert_3;
27 static UCHAR nx_azure_iot_tls_metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE];
28 static ULONG nx_azure_iot_thread_stack[NX_AZURE_IOT_STACK_SIZE / sizeof(ULONG)];
29 
30 /* Define the prototypes for AZ IoT.  */
31 static NX_AZURE_IOT                                 nx_azure_iot;
32 
33 /* Generally, IoTHub Client and DPS Client do not run at the same time, user can use union as below to
34    share the memory between IoTHub Client and DPS Client.
35 
36    NOTE: If user can not make sure sharing memory is safe, IoTHub Client and DPS Client must be defined seperately.  */
37 typedef union SAMPLE_CLIENT_UNION
38 {
39     NX_AZURE_IOT_HUB_CLIENT                         iothub_client;
40 
41 #ifdef ENABLE_DPS_SAMPLE
42     NX_AZURE_IOT_PROVISIONING_CLIENT                prov_client;
43 #endif /* ENABLE_DPS_SAMPLE */
44 
45 } SAMPLE_CLIENT;
46 
47 static SAMPLE_CLIENT                                client;
48 
49 #define iothub_client client.iothub_client
50 #ifdef ENABLE_DPS_SAMPLE
51 #define prov_client client.prov_client
52 #endif /* ENABLE_DPS_SAMPLE */
53 
54 static volatile UINT sample_connection_status = NX_AZURE_IOT_NOT_INITIALIZED;
55 static volatile UINT sample_properties_request_sent = NX_FALSE;
56 
57 /* Using X509 certificate authenticate to connect to IoT Hub,
58    set the device certificate as your device.  */
59 #if (USE_DEVICE_CERTIFICATE == 1)
60 extern const UCHAR sample_device_cert_ptr[];
61 extern const UINT sample_device_cert_len;
62 extern const UCHAR sample_device_private_key_ptr[];
63 extern const UINT sample_device_private_key_len;
64 NX_SECURE_X509_CERT device_certificate;
65 #endif /* USE_DEVICE_CERTIFICATE */
66 
67 /* Define buffer for IoTHub info.  */
68 #ifdef ENABLE_DPS_SAMPLE
69 static UCHAR sample_iothub_hostname[SAMPLE_MAX_BUFFER];
70 static UCHAR sample_iothub_device_id[SAMPLE_MAX_BUFFER];
71 #endif /* ENABLE_DPS_SAMPLE */
72 
73 /* Define sample threads.  */
74 #ifndef DISABLE_TELEMETRY_SAMPLE
75 static TX_THREAD sample_telemetry_thread;
76 static ULONG sample_telemetry_thread_stack[SAMPLE_STACK_SIZE / sizeof(ULONG)];
77 #endif /* DISABLE_TELEMETRY_SAMPLE */
78 
79 #ifndef DISABLE_C2D_SAMPLE
80 static TX_THREAD sample_c2d_thread;
81 static ULONG sample_c2d_thread_stack[SAMPLE_STACK_SIZE / sizeof(ULONG)];
82 #endif /* DISABLE_C2D_SAMPLE */
83 
84 #if !defined(DISABLE_TELEMETRY_SAMPLE) || !defined(DISABLE_C2D_SAMPLE)
85 /* Define sample properties.  */
86 static const CHAR *sample_properties[MAX_PROPERTY_COUNT][2] = {{"propertyA", "valueA"},
87                                                                {"propertyB", "valueB"}};
88 #endif /* !defined(DISABLE_TELEMETRY_SAMPLE) && !defined(DISABLE_C2D_SAMPLE) */
89 
90 #ifndef DISABLE_DIRECT_METHOD_SAMPLE
91 static CHAR method_response_payload[] = "{\"status\": \"OK\"}";
92 static TX_THREAD sample_direct_method_thread;
93 static ULONG sample_direct_method_thread_stack[SAMPLE_STACK_SIZE / sizeof(ULONG)];
94 #endif /* DISABLE_DIRECT_METHOD_SAMPLE */
95 
96 #ifndef DISABLE_DEVICE_TWIN_SAMPLE
97 static CHAR fixed_reported_properties[] = "{\"sample_report\": \"OK\"}";
98 static TX_THREAD sample_device_twin_thread;
99 static ULONG sample_device_twin_thread_stack[SAMPLE_STACK_SIZE / sizeof(ULONG)];
100 #endif /* DISABLE_DEVICE_TWIN_SAMPLE */
101 
102 void sample_entry(NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr, NX_DNS *dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time));
103 #ifdef ENABLE_DPS_SAMPLE
104 static UINT sample_dps_entry(UCHAR **iothub_hostname, UINT *iothub_hostname_length,
105                              UCHAR **iothub_device_id, UINT *iothub_device_id_length);
106 #endif /* ENABLE_DPS_SAMPLE */
107 #ifndef DISABLE_TELEMETRY_SAMPLE
108 static void sample_telemetry_thread_entry(ULONG parameter);
109 #endif /* DISABLE_TELEMETRY_SAMPLE */
110 
111 #ifndef DISABLE_C2D_SAMPLE
112 static void sample_c2d_thread_entry(ULONG parameter);
113 #endif /* DISABLE_C2D_SAMPLE */
114 
115 #ifndef DISABLE_DIRECT_METHOD_SAMPLE
116 static void sample_direct_method_thread_entry(ULONG parameter);
117 #endif /* DISABLE_DIRECT_METHOD_SAMPLE */
118 
119 #ifndef DISABLE_DEVICE_TWIN_SAMPLE
120 static void sample_device_twin_thread_entry(ULONG parameter);
121 #endif /* DISABLE_DEVICE_TWIN_SAMPLE */
122 
123 /* Include the connection monitor function from sample_azure_iot_embedded_sdk_connect.c.  */
124 extern VOID sample_connection_monitor(NX_IP *ip_ptr, NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, UINT connection_status,
125                                       UINT (*iothub_init)(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr));
126 
printf_packet(NX_PACKET * packet_ptr)127 static VOID printf_packet(NX_PACKET *packet_ptr)
128 {
129     while (packet_ptr != NX_NULL)
130     {
131         printf("%.*s", (INT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr),
132                (CHAR *)packet_ptr -> nx_packet_prepend_ptr);
133         packet_ptr = packet_ptr -> nx_packet_next;
134     }
135 }
136 
connection_status_callback(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,UINT status)137 static VOID connection_status_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT status)
138 {
139     NX_PARAMETER_NOT_USED(hub_client_ptr);
140     if (status)
141     {
142         printf("Disconnected from IoTHub!: error code = 0x%08x\r\n", status);
143     }
144     else
145     {
146         printf("Connected to IoTHub.\r\n");
147     }
148 
149     sample_connection_status = status;
150 }
151 
sample_initialize_iothub(NX_AZURE_IOT_HUB_CLIENT * iothub_client_ptr)152 static UINT sample_initialize_iothub(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr)
153 {
154 UINT status;
155 #ifdef ENABLE_DPS_SAMPLE
156 UCHAR *iothub_hostname = NX_NULL;
157 UCHAR *iothub_device_id = NX_NULL;
158 UINT iothub_hostname_length = 0;
159 UINT iothub_device_id_length = 0;
160 #else
161 UCHAR *iothub_hostname = (UCHAR *)HOST_NAME;
162 UCHAR *iothub_device_id = (UCHAR *)DEVICE_ID;
163 UINT iothub_hostname_length = sizeof(HOST_NAME) - 1;
164 UINT iothub_device_id_length = sizeof(DEVICE_ID) - 1;
165 #endif /* ENABLE_DPS_SAMPLE */
166 
167 #ifdef ENABLE_DPS_SAMPLE
168 
169     /* Run DPS.  */
170     if ((status = sample_dps_entry(&iothub_hostname, &iothub_hostname_length,
171                                    &iothub_device_id, &iothub_device_id_length)))
172     {
173         printf("Failed on sample_dps_entry!: error code = 0x%08x\r\n", status);
174         return(status);
175     }
176 #endif /* ENABLE_DPS_SAMPLE */
177 
178     printf("IoTHub Host Name: %.*s; Device ID: %.*s.\r\n",
179            iothub_hostname_length, iothub_hostname, iothub_device_id_length, iothub_device_id);
180 
181     /* Initialize IoTHub client.  */
182     if ((status = nx_azure_iot_hub_client_initialize(iothub_client_ptr, &nx_azure_iot,
183                                                      iothub_hostname, iothub_hostname_length,
184                                                      iothub_device_id, iothub_device_id_length,
185                                                      (UCHAR *)MODULE_ID, sizeof(MODULE_ID) - 1,
186                                                      _nx_azure_iot_tls_supported_crypto,
187                                                      _nx_azure_iot_tls_supported_crypto_size,
188                                                      _nx_azure_iot_tls_ciphersuite_map,
189                                                      _nx_azure_iot_tls_ciphersuite_map_size,
190                                                      nx_azure_iot_tls_metadata_buffer,
191                                                      sizeof(nx_azure_iot_tls_metadata_buffer),
192                                                      &root_ca_cert)))
193     {
194         printf("Failed on nx_azure_iot_hub_client_initialize!: error code = 0x%08x\r\n", status);
195         return(status);
196     }
197 
198     /* Add more CA certificates.  */
199     if ((status = nx_azure_iot_hub_client_trusted_cert_add(iothub_client_ptr, &root_ca_cert_2)))
200     {
201         printf("Failed on nx_azure_iot_hub_client_trusted_cert_add!: error code = 0x%08x\r\n", status);
202     }
203     else if ((status = nx_azure_iot_hub_client_trusted_cert_add(iothub_client_ptr, &root_ca_cert_3)))
204     {
205         printf("Failed on nx_azure_iot_hub_client_trusted_cert_add!: error code = 0x%08x\r\n", status);
206     }
207 
208 #if (USE_DEVICE_CERTIFICATE == 1)
209 
210     /* Initialize the device certificate.  */
211     else if ((status = nx_secure_x509_certificate_initialize(&device_certificate,
212                                                              (UCHAR *)sample_device_cert_ptr, (USHORT)sample_device_cert_len,
213                                                              NX_NULL, 0,
214                                                              (UCHAR *)sample_device_private_key_ptr, (USHORT)sample_device_private_key_len,
215                                                              DEVICE_KEY_TYPE)))
216     {
217         printf("Failed on nx_secure_x509_certificate_initialize!: error code = 0x%08x\r\n", status);
218     }
219 
220     /* Set device certificate.  */
221     else if ((status = nx_azure_iot_hub_client_device_cert_set(iothub_client_ptr, &device_certificate)))
222     {
223         printf("Failed on nx_azure_iot_hub_client_device_cert_set!: error code = 0x%08x\r\n", status);
224     }
225 #else
226 
227     /* Set symmetric key.  */
228     else if ((status = nx_azure_iot_hub_client_symmetric_key_set(iothub_client_ptr,
229                                                                  (UCHAR *)DEVICE_SYMMETRIC_KEY,
230                                                                  sizeof(DEVICE_SYMMETRIC_KEY) - 1)))
231     {
232         printf("Failed on nx_azure_iot_hub_client_symmetric_key_set!\r\n");
233     }
234 #endif /* USE_DEVICE_CERTIFICATE */
235 
236 #ifdef NXD_MQTT_OVER_WEBSOCKET
237 
238     /* Enable MQTT over WebSocket to connect to IoT Hub  */
239     else if ((status = nx_azure_iot_hub_client_websocket_enable(iothub_client_ptr)))
240     {
241         printf("Failed on nx_azure_iot_hub_client_websocket_enable!\r\n");
242     }
243 #endif /* NXD_MQTT_OVER_WEBSOCKET */
244 
245     /* Set connection status callback.  */
246     else if ((status = nx_azure_iot_hub_client_connection_status_callback_set(iothub_client_ptr,
247                                                                               connection_status_callback)))
248     {
249         printf("Failed on connection_status_callback!\r\n");
250     }
251 #ifndef DISABLE_C2D_SAMPLE
252     else if ((status = nx_azure_iot_hub_client_cloud_message_enable(iothub_client_ptr)))
253     {
254         printf("C2D receive enable failed!: error code = 0x%08x\r\n", status);
255     }
256 #endif /* DISABLE_C2D_SAMPLE */
257 #ifndef DISABLE_DIRECT_METHOD_SAMPLE
258     else if ((status = nx_azure_iot_hub_client_direct_method_enable(iothub_client_ptr)))
259     {
260         printf("Direct method receive enable failed!: error code = 0x%08x\r\n", status);
261     }
262 #endif /* DISABLE_DIRECT_METHOD_SAMPLE */
263 #ifndef DISABLE_DEVICE_TWIN_SAMPLE
264     else if ((status = nx_azure_iot_hub_client_device_twin_enable(iothub_client_ptr)))
265     {
266         printf("device twin enabled failed!: error code = 0x%08x\r\n", status);
267     }
268 #endif /* DISABLE_DEVICE_TWIN_SAMPLE */
269 
270     if (status)
271     {
272         nx_azure_iot_hub_client_deinitialize(iothub_client_ptr);
273     }
274 
275     return(status);
276 }
277 
log_callback(az_log_classification classification,UCHAR * msg,UINT msg_len)278 static void log_callback(az_log_classification classification, UCHAR *msg, UINT msg_len)
279 {
280     if (classification == AZ_LOG_IOT_AZURERTOS)
281     {
282         printf("%.*s", msg_len, (CHAR *)msg);
283     }
284 }
285 
sample_entry(NX_IP * ip_ptr,NX_PACKET_POOL * pool_ptr,NX_DNS * dns_ptr,UINT (* unix_time_callback)(ULONG * unix_time))286 void sample_entry(NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr, NX_DNS *dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time))
287 {
288 UINT status = 0;
289 UINT loop = NX_TRUE;
290 
291     nx_azure_iot_log_init(log_callback);
292 
293     /* Create Azure IoT handler.  */
294     if ((status = nx_azure_iot_create(&nx_azure_iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr,
295                                       nx_azure_iot_thread_stack, sizeof(nx_azure_iot_thread_stack),
296                                       NX_AZURE_IOT_THREAD_PRIORITY, unix_time_callback)))
297     {
298         printf("Failed on nx_azure_iot_create!: error code = 0x%08x\r\n", status);
299         return;
300     }
301 
302     /* Initialize CA certificates.  */
303     if ((status = nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert,
304                                                         (USHORT)_nx_azure_iot_root_cert_size,
305                                                         NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE)))
306     {
307         printf("Failed to initialize ROOT CA certificate!: error code = 0x%08x\r\n", status);
308         nx_azure_iot_delete(&nx_azure_iot);
309         return;
310     }
311 
312     if ((status = nx_secure_x509_certificate_initialize(&root_ca_cert_2, (UCHAR *)_nx_azure_iot_root_cert_2,
313                                                         (USHORT)_nx_azure_iot_root_cert_size_2,
314                                                         NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE)))
315     {
316         printf("Failed to initialize ROOT CA certificate!: error code = 0x%08x\r\n", status);
317         nx_azure_iot_delete(&nx_azure_iot);
318         return;
319     }
320 
321     if ((status = nx_secure_x509_certificate_initialize(&root_ca_cert_3, (UCHAR *)_nx_azure_iot_root_cert_3,
322                                                         (USHORT)_nx_azure_iot_root_cert_size_3,
323                                                         NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE)))
324     {
325         printf("Failed to initialize ROOT CA certificate!: error code = 0x%08x\r\n", status);
326         nx_azure_iot_delete(&nx_azure_iot);
327         return;
328     }
329 
330     if ((status = sample_initialize_iothub(&iothub_client)))
331     {
332         printf("Failed to initialize iothub client: error code = 0x%08x\r\n", status);
333         sample_connection_status = NX_AZURE_IOT_NOT_INITIALIZED;
334     }
335     else if ((sample_connection_status = nx_azure_iot_hub_client_connect(&iothub_client, NX_TRUE, NX_WAIT_FOREVER)))
336     {
337         printf("Failed on nx_azure_iot_hub_client_connect!\r\n");
338     }
339 
340 #ifndef DISABLE_TELEMETRY_SAMPLE
341 
342     /* Create Telemetry sample thread.  */
343     if ((status = tx_thread_create(&sample_telemetry_thread, "Sample Telemetry Thread",
344                                    sample_telemetry_thread_entry, 0,
345                                    (UCHAR *)sample_telemetry_thread_stack, SAMPLE_STACK_SIZE,
346                                    SAMPLE_THREAD_PRIORITY, SAMPLE_THREAD_PRIORITY,
347                                    1, TX_AUTO_START)))
348     {
349         printf("Failed to create telemetry sample thread!: error code = 0x%08x\r\n", status);
350     }
351 #endif /* DISABLE_TELEMETRY_SAMPLE */
352 
353 #ifndef DISABLE_C2D_SAMPLE
354 
355     /* Create C2D sample thread.  */
356     if ((status = tx_thread_create(&sample_c2d_thread, "Sample C2D Thread",
357                                    sample_c2d_thread_entry, 0,
358                                    (UCHAR *)sample_c2d_thread_stack, SAMPLE_STACK_SIZE,
359                                    SAMPLE_THREAD_PRIORITY, SAMPLE_THREAD_PRIORITY,
360                                    1, TX_AUTO_START)))
361     {
362         printf("Failed to create c2d sample thread!: error code = 0x%08x\r\n", status);
363     }
364 #endif /* DISABLE_C2D_SAMPLE */
365 
366 #ifndef DISABLE_DIRECT_METHOD_SAMPLE
367 
368     /* Create Direct Method sample thread.  */
369     if ((status = tx_thread_create(&sample_direct_method_thread, "Sample Direct Method Thread",
370                                    sample_direct_method_thread_entry, 0,
371                                    (UCHAR *)sample_direct_method_thread_stack, SAMPLE_STACK_SIZE,
372                                    SAMPLE_THREAD_PRIORITY, SAMPLE_THREAD_PRIORITY,
373                                    1, TX_AUTO_START)))
374     {
375         printf("Failed to create direct method sample thread!: error code = 0x%08x\r\n", status);
376     }
377 #endif /* DISABLE_DIRECT_METHOD_SAMPLE */
378 
379 #ifndef DISABLE_DEVICE_TWIN_SAMPLE
380 
381     /* Create Device twin sample thread.  */
382     if ((status = tx_thread_create(&sample_device_twin_thread, "Sample Device Twin Thread",
383                                    sample_device_twin_thread_entry, 0,
384                                    (UCHAR *)sample_device_twin_thread_stack, SAMPLE_STACK_SIZE,
385                                    SAMPLE_THREAD_PRIORITY, SAMPLE_THREAD_PRIORITY,
386                                    1, TX_AUTO_START)))
387     {
388         printf("Failed to create device twin sample thread!: error code = 0x%08x\r\n", status);
389     }
390 #endif /* DISABLE_DEVICE_TWIN_SAMPLE */
391 
392     while (loop)
393     {
394 
395         /* Connection monitor.  */
396         sample_connection_monitor(ip_ptr, &iothub_client, sample_connection_status, sample_initialize_iothub);
397 
398         tx_thread_sleep(NX_IP_PERIODIC_RATE);
399     }
400 
401     /* Cleanup.  */
402     nx_azure_iot_hub_client_deinitialize(&iothub_client);
403     nx_azure_iot_delete(&nx_azure_iot);
404 }
405 
406 #ifdef ENABLE_DPS_SAMPLE
sample_dps_entry(UCHAR ** iothub_hostname,UINT * iothub_hostname_length,UCHAR ** iothub_device_id,UINT * iothub_device_id_length)407 static UINT sample_dps_entry(UCHAR **iothub_hostname, UINT *iothub_hostname_length,
408                              UCHAR **iothub_device_id, UINT *iothub_device_id_length)
409 {
410 UINT status;
411 
412     printf("Start Provisioning Client...\r\n");
413 
414     /* Initialize IoT provisioning client.  */
415     if ((status = nx_azure_iot_provisioning_client_initialize(&prov_client, &nx_azure_iot,
416                                                               (UCHAR *)ENDPOINT, sizeof(ENDPOINT) - 1,
417                                                               (UCHAR *)ID_SCOPE, sizeof(ID_SCOPE) - 1,
418                                                               (UCHAR *)REGISTRATION_ID, sizeof(REGISTRATION_ID) - 1,
419                                                               _nx_azure_iot_tls_supported_crypto,
420                                                               _nx_azure_iot_tls_supported_crypto_size,
421                                                               _nx_azure_iot_tls_ciphersuite_map,
422                                                               _nx_azure_iot_tls_ciphersuite_map_size,
423                                                               nx_azure_iot_tls_metadata_buffer,
424                                                               sizeof(nx_azure_iot_tls_metadata_buffer),
425                                                               &root_ca_cert)))
426     {
427         printf("Failed on nx_azure_iot_provisioning_client_initialize!: error code = 0x%08x\r\n", status);
428         return(status);
429     }
430 
431     /* Initialize length of hostname and device ID.  */
432     *iothub_hostname_length = sizeof(sample_iothub_hostname);
433     *iothub_device_id_length = sizeof(sample_iothub_device_id);
434 
435     /* Add more CA certificates.  */
436     if ((status = nx_azure_iot_provisioning_client_trusted_cert_add(&prov_client, &root_ca_cert_2)))
437     {
438         printf("Failed on nx_azure_iot_provisioning_client_trusted_cert_add!: error code = 0x%08x\r\n", status);
439     }
440     else if ((status = nx_azure_iot_provisioning_client_trusted_cert_add(&prov_client, &root_ca_cert_3)))
441     {
442         printf("Failed on nx_azure_iot_provisioning_client_trusted_cert_add!: error code = 0x%08x\r\n", status);
443     }
444 
445 #if (USE_DEVICE_CERTIFICATE == 1)
446 
447     /* Initialize the device certificate.  */
448     else if ((status = nx_secure_x509_certificate_initialize(&device_certificate, (UCHAR *)sample_device_cert_ptr, (USHORT)sample_device_cert_len, NX_NULL, 0,
449                                                              (UCHAR *)sample_device_private_key_ptr, (USHORT)sample_device_private_key_len, DEVICE_KEY_TYPE)))
450     {
451         printf("Failed on nx_secure_x509_certificate_initialize!: error code = 0x%08x\r\n", status);
452     }
453 
454     /* Set device certificate.  */
455     else if ((status = nx_azure_iot_provisioning_client_device_cert_set(&prov_client, &device_certificate)))
456     {
457         printf("Failed on nx_azure_iot_provisioning_client_device_cert_set!: error code = 0x%08x\r\n", status);
458     }
459 #else
460 
461     /* Set symmetric key.  */
462     else if ((status = nx_azure_iot_provisioning_client_symmetric_key_set(&prov_client, (UCHAR *)DEVICE_SYMMETRIC_KEY,
463                                                                           sizeof(DEVICE_SYMMETRIC_KEY) - 1)))
464     {
465         printf("Failed on nx_azure_iot_hub_client_symmetric_key_set!: error code = 0x%08x\r\n", status);
466     }
467 #endif /* USE_DEVICE_CERTIFICATE */
468 
469 #ifdef NXD_MQTT_OVER_WEBSOCKET
470 
471     /* Enable MQTT over WebSocket.  */
472     else if ((status = nx_azure_iot_provisioning_client_websocket_enable(&prov_client)))
473     {
474         printf("Failed on nx_azure_iot_provisioning_client_websocket_enable!\r\n");
475     }
476 #endif /* NXD_MQTT_OVER_WEBSOCKET */
477 
478     /* Register device */
479     else if ((status = nx_azure_iot_provisioning_client_register(&prov_client, NX_WAIT_FOREVER)))
480     {
481         printf("Failed on nx_azure_iot_provisioning_client_register!: error code = 0x%08x\r\n", status);
482     }
483 
484     /* Get Device info */
485     else if ((status = nx_azure_iot_provisioning_client_iothub_device_info_get(&prov_client,
486                                                                                sample_iothub_hostname, iothub_hostname_length,
487                                                                                sample_iothub_device_id, iothub_device_id_length)))
488     {
489         printf("Failed on nx_azure_iot_provisioning_client_iothub_device_info_get!: error code = 0x%08x\r\n", status);
490     }
491     else
492     {
493         *iothub_hostname = sample_iothub_hostname;
494         *iothub_device_id = sample_iothub_device_id;
495         printf("Registered Device Successfully.\r\n");
496     }
497 
498     /* Destroy Provisioning Client.  */
499     nx_azure_iot_provisioning_client_deinitialize(&prov_client);
500 
501     return(status);
502 }
503 #endif /* ENABLE_DPS_SAMPLE */
504 
505 #ifndef DISABLE_TELEMETRY_SAMPLE
sample_telemetry_thread_entry(ULONG parameter)506 void sample_telemetry_thread_entry(ULONG parameter)
507 {
508 UINT i = 0;
509 UINT status = 0;
510 CHAR buffer[30];
511 UINT buffer_length;
512 UCHAR loop = NX_TRUE;
513 NX_PACKET *packet_ptr;
514 
515     NX_PARAMETER_NOT_USED(parameter);
516 
517     /* Loop to send telemetry message.  */
518     while (loop)
519     {
520         if (sample_connection_status != NX_SUCCESS)
521         {
522             tx_thread_sleep(NX_IP_PERIODIC_RATE);
523             continue;
524         }
525 
526         /* Create a telemetry message packet.  */
527         if ((status = nx_azure_iot_hub_client_telemetry_message_create(&iothub_client, &packet_ptr, NX_WAIT_FOREVER)))
528         {
529             printf("Telemetry message create failed!: error code = 0x%08x\r\n", status);
530             continue;
531         }
532 
533         /* Add properties to telemetry message.  */
534         for (int index = 0; index < MAX_PROPERTY_COUNT; index++)
535         {
536             if ((status =
537                     nx_azure_iot_hub_client_telemetry_property_add(packet_ptr,
538                                                                    (UCHAR *)sample_properties[index][0],
539                                                                    (USHORT)strlen(sample_properties[index][0]),
540                                                                    (UCHAR *)sample_properties[index][1],
541                                                                    (USHORT)strlen(sample_properties[index][1]),
542                                                                    NX_WAIT_FOREVER)))
543             {
544                 printf("Telemetry property add failed!: error code = 0x%08x\r\n", status);
545                 break;
546             }
547         }
548 
549         if (status)
550         {
551             nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
552             continue;
553         }
554 
555         buffer_length = (UINT)snprintf(buffer, sizeof(buffer), "{\"Message ID\":%u}", i++);
556         if (nx_azure_iot_hub_client_telemetry_send(&iothub_client, packet_ptr,
557                                                    (UCHAR *)buffer, buffer_length, NX_WAIT_FOREVER))
558         {
559             printf("Telemetry message send failed!: error code = 0x%08x\r\n", status);
560             nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr);
561             continue;
562         }
563         printf("Telemetry message send: %s.\r\n", buffer);
564 
565         tx_thread_sleep(5 * NX_IP_PERIODIC_RATE);
566     }
567 }
568 #endif /* DISABLE_TELEMETRY_SAMPLE */
569 
570 #ifndef DISABLE_C2D_SAMPLE
sample_c2d_thread_entry(ULONG parameter)571 void sample_c2d_thread_entry(ULONG parameter)
572 {
573 UCHAR loop = NX_TRUE;
574 NX_PACKET *packet_ptr;
575 UINT status = 0;
576 USHORT property_buf_size;
577 const UCHAR *property_buf;
578 
579     NX_PARAMETER_NOT_USED(parameter);
580 
581     /* Loop to receive c2d message.  */
582     while (loop)
583     {
584         if (sample_connection_status != NX_SUCCESS)
585         {
586             tx_thread_sleep(NX_IP_PERIODIC_RATE);
587             continue;
588         }
589 
590         if ((status = nx_azure_iot_hub_client_cloud_message_receive(&iothub_client, &packet_ptr, NX_WAIT_FOREVER)))
591         {
592             printf("C2D receive failed!: error code = 0x%08x\r\n", status);
593             continue;
594         }
595 
596         if ((status = nx_azure_iot_hub_client_cloud_message_property_get(&iothub_client, packet_ptr,
597                                                                          (UCHAR *)sample_properties[0][0],
598                                                                          (USHORT)strlen(sample_properties[0][0]),
599                                                                          &property_buf, &property_buf_size)) == NX_AZURE_IOT_SUCCESS)
600         {
601             printf("Receive property: %s = %.*s\r\n", sample_properties[0][0],
602                    (INT)property_buf_size, property_buf);
603         }
604 
605         printf("Receive message: ");
606         printf_packet(packet_ptr);
607         printf("\r\n");
608 
609         nx_packet_release(packet_ptr);
610     }
611 }
612 #endif /* DISABLE_C2D_SAMPLE */
613 
614 #ifndef DISABLE_DIRECT_METHOD_SAMPLE
sample_direct_method_thread_entry(ULONG parameter)615 void sample_direct_method_thread_entry(ULONG parameter)
616 {
617 UCHAR loop = NX_TRUE;
618 NX_PACKET *packet_ptr;
619 UINT status = 0;
620 USHORT method_name_length;
621 const UCHAR *method_name_ptr;
622 USHORT context_length;
623 VOID *context_ptr;
624 
625     NX_PARAMETER_NOT_USED(parameter);
626 
627     /* Loop to receive direct method message.  */
628     while (loop)
629     {
630         if (sample_connection_status != NX_SUCCESS)
631         {
632             tx_thread_sleep(NX_IP_PERIODIC_RATE);
633             continue;
634         }
635 
636         if ((status = nx_azure_iot_hub_client_direct_method_message_receive(&iothub_client,
637                                                                             &method_name_ptr, &method_name_length,
638                                                                             &context_ptr, &context_length,
639                                                                             &packet_ptr, NX_WAIT_FOREVER)))
640         {
641             printf("Direct method receive failed!: error code = 0x%08x\r\n", status);
642             continue;
643         }
644 
645         printf("Receive method call: %.*s, with payload:", (INT)method_name_length, (CHAR *)method_name_ptr);
646         printf_packet(packet_ptr);
647         printf("\r\n");
648 
649         if ((status = nx_azure_iot_hub_client_direct_method_message_response(&iothub_client, 200 /* method status */,
650                                                                              context_ptr, context_length,
651                                                                              (UCHAR *)method_response_payload, sizeof(method_response_payload) - 1,
652                                                                              NX_WAIT_FOREVER)))
653         {
654             printf("Direct method response failed!: error code = 0x%08x\r\n", status);
655             nx_packet_release(packet_ptr);
656             continue;
657         }
658 
659         nx_packet_release(packet_ptr);
660     }
661 }
662 #endif /* DISABLE_DIRECT_METHOD_SAMPLE */
663 
664 #ifndef DISABLE_DEVICE_TWIN_SAMPLE
sample_device_twin_thread_entry(ULONG parameter)665 void sample_device_twin_thread_entry(ULONG parameter)
666 {
667 UCHAR loop = NX_TRUE;
668 NX_PACKET *packet_ptr;
669 UINT status = 0;
670 UINT response_status;
671 UINT request_id;
672 ULONG reported_property_version;
673 
674     NX_PARAMETER_NOT_USED(parameter);
675 
676     /* Loop to receive device twin message.  */
677     while (loop)
678     {
679         if (sample_connection_status != NX_SUCCESS)
680         {
681             tx_thread_sleep(NX_IP_PERIODIC_RATE);
682             continue;
683         }
684 
685         /* Only one properties request.  */
686         if (sample_properties_request_sent == NX_FALSE)
687         {
688             if ((status = nx_azure_iot_hub_client_device_twin_properties_request(&iothub_client, NX_WAIT_FOREVER)))
689             {
690                 printf("device twin document request failed!: error code = 0x%08x\r\n", status);
691                 continue;
692             }
693 
694             if ((status = nx_azure_iot_hub_client_device_twin_properties_receive(&iothub_client, &packet_ptr, NX_WAIT_FOREVER)))
695             {
696                 printf("device twin document receive failed!: error code = 0x%08x\r\n", status);
697                 continue;
698             }
699 
700             printf("Receive twin properties :");
701             printf_packet(packet_ptr);
702             printf("\r\n");
703             nx_packet_release(packet_ptr);
704             sample_properties_request_sent = NX_TRUE;
705         }
706 
707         if ((status = nx_azure_iot_hub_client_device_twin_desired_properties_receive(&iothub_client, &packet_ptr,
708                                                                                      NX_WAIT_FOREVER)))
709         {
710             printf("Receive desired property receive failed!: error code = 0x%08x\r\n", status);
711             continue;
712         }
713 
714         printf("Receive desired property call: ");
715         printf_packet(packet_ptr);
716         printf("\r\n");
717         nx_packet_release(packet_ptr);
718 
719         if ((status = nx_azure_iot_hub_client_device_twin_reported_properties_send(&iothub_client,
720                                                                                    (UCHAR *)fixed_reported_properties, sizeof(fixed_reported_properties) - 1,
721                                                                                    &request_id, &response_status,
722                                                                                    &reported_property_version,
723                                                                                    NX_WAIT_FOREVER)))
724         {
725             printf("Device twin reported properties failed!: error code = 0x%08x\r\n", status);
726             continue;
727         }
728 
729         if ((response_status < 200) || (response_status >= 300))
730         {
731             printf("device twin report properties failed with code : %d\r\n", response_status);
732         }
733     }
734 }
735 #endif /* DISABLE_DEVICE_TWIN_SAMPLE */
736