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 #include <stdio.h>
12 #include <setjmp.h>
13 #include <cmocka.h>  /* macros: https://api.cmocka.org/group__cmocka__asserts.html */
14 
15 #include "nx_api.h"
16 #include "nx_azure_iot_hub_client.h"
17 #include "nx_azure_iot_cert.h"
18 #include "nx_azure_iot_ciphersuites.h"
19 #include "nx_azure_iot_provisioning_client.h"
20 
21 
22 #define DEMO_DHCP_DISABLE
23 #define DEMO_IPV4_ADDRESS         IP_ADDRESS(192, 168, 100, 33)
24 #define DEMO_IPV4_MASK            0xFFFFFF00UL
25 #define DEMO_GATEWAY_ADDRESS      IP_ADDRESS(192, 168, 100, 1)
26 #define DEMO_DNS_SERVER_ADDRESS   IP_ADDRESS(192, 168, 100, 1)
27 #define NETWORK_DRIVER            _nx_ram_network_driver
28 
29 /* Include main.c in the test case since we need to disable DHCP in this test. */
30 #include "main.c"
31 
32 
33 #define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s)
34 
35 #ifndef DEMO_CLOUD_STACK_SIZE
36 #define DEMO_CLOUD_STACK_SIZE   2048
37 #endif /* DEMO_CLOUD_STACK_SIZE */
38 
39 #ifndef DEMO_CLOUD_THREAD_PRIORITY
40 #define DEMO_CLOUD_THREAD_PRIORITY  (4)
41 #endif /* DEMO_CLOUD_THREAD_PRIORITY */
42 
43 static NX_AZURE_IOT iot;
44 static NX_AZURE_IOT_HUB_CLIENT iot_client;
45 static NX_AZURE_IOT_PROVISIONING_CLIENT iot_prov_client;
46 static NX_SECURE_X509_CERT root_ca_cert;
47 static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE];
48 static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)];
49 static NX_PACKET *allocated_packets[256];
50 static UCHAR large_property_name[2048];
51 static ULONG small_pool_stack[1024 >> 2];
52 static NX_PACKET_POOL small_pool;
53 extern int g_argc;
54 extern char **g_argv;
55 
56 CHAR *expected_topic = "";
57 CHAR *expected_message = "";
58 
demo_entry(NX_IP * ip_ptr,NX_PACKET_POOL * pool_ptr,NX_DNS * dns_ptr,UINT (* unix_time_callback)(ULONG * unix_time))59 VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time))
60 {
61 CHAR *host_name = "host_name";
62 CHAR *device_id = "device_id";
63 CHAR *module_id = "module_id";
64 CHAR *endpoint = "host_name";
65 CHAR *id_scope = "id_scope";
66 CHAR *reg_id = "reg_id";
67 NX_SECURE_X509_CERT device_certificate;
68 
69     assert_int_equal(nx_packet_pool_create(&small_pool, "Small Packet Pool", 4,
70                                            (UCHAR *)small_pool_stack , sizeof(small_pool_stack)),
71                      NX_AZURE_IOT_SUCCESS);
72 
73     /* Initialize root certificate.  */
74     assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size,
75                                                            NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE),
76                      NX_AZURE_IOT_SUCCESS);
77 
78     assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack,
79                                          sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
80                      NX_AZURE_IOT_SUCCESS);
81 
82     /* Initialize IoT hub client.  */
83     assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
84                                                         STRING_UNSIGNED_ARGS(host_name),
85                                                         STRING_UNSIGNED_ARGS(device_id),
86                                                         STRING_UNSIGNED_ARGS(""),
87                                                         _nx_azure_iot_tls_supported_crypto,
88                                                         _nx_azure_iot_tls_supported_crypto_size,
89                                                         _nx_azure_iot_tls_ciphersuite_map,
90                                                         _nx_azure_iot_tls_ciphersuite_map_size,
91                                                         metadata_buffer, sizeof(metadata_buffer),
92                                                         &root_ca_cert),
93                      NX_AZURE_IOT_SUCCESS);
94 
95     /* FAIL: hub_client_ptr is NULL. */
96     assert_int_not_equal(nx_azure_iot_hub_client_device_cert_set(NX_NULL, &device_certificate),
97                          NX_AZURE_IOT_SUCCESS);
98 
99     /* FAIL: device_certificate is NULL. */
100     assert_int_not_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, NX_NULL),
101                          NX_AZURE_IOT_SUCCESS);
102 
103     /* SUCCESS: set device certificate. */
104     assert_int_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, &device_certificate),
105                      NX_AZURE_IOT_SUCCESS);
106 
107 #if NX_AZURE_IOT_MAX_NUM_OF_DEVICE_CERTS > 1
108     /* SUCCESS: set device certificate again. */
109     assert_int_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, &device_certificate),
110                      NX_AZURE_IOT_SUCCESS);
111 #endif
112 
113     /* FAIL: no entry for device cert. */
114     assert_int_not_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, &device_certificate),
115                          NX_AZURE_IOT_SUCCESS);
116 
117     /* SUCCESS: connected. */
118     assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, 20 * NX_IP_PERIODIC_RATE),
119                      NX_AZURE_IOT_SUCCESS);
120 
121     /* Deinitialize IoT hub client.  */
122     assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client),
123                      NX_AZURE_IOT_SUCCESS);
124 
125 
126     /* Initialize provisioning client.  */
127     assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot,
128                                                                  endpoint, sizeof(endpoint) - 1,
129                                                                  id_scope, sizeof(id_scope) - 1,
130                                                                  reg_id, sizeof(reg_id) - 1,
131                                                                  _nx_azure_iot_tls_supported_crypto,
132                                                                  _nx_azure_iot_tls_supported_crypto_size,
133                                                                  _nx_azure_iot_tls_ciphersuite_map,
134                                                                  _nx_azure_iot_tls_ciphersuite_map_size,
135                                                                  metadata_buffer, sizeof(metadata_buffer),
136                                                                  &root_ca_cert),
137                      NX_AZURE_IOT_SUCCESS);
138 
139     /* FAIL: prov_client_ptr is NULL. */
140     assert_int_not_equal(nx_azure_iot_provisioning_client_device_cert_set(NX_NULL, &device_certificate),
141                          NX_AZURE_IOT_SUCCESS);
142 
143     /* FAIL: device_certificate is NULL. */
144     assert_int_not_equal(nx_azure_iot_provisioning_client_device_cert_set(&iot_prov_client, NX_NULL),
145                          NX_AZURE_IOT_SUCCESS);
146 
147     /* SUCCESS: set device certificate. */
148     assert_int_equal(nx_azure_iot_provisioning_client_device_cert_set(&iot_prov_client, &device_certificate),
149                      NX_AZURE_IOT_SUCCESS);
150 
151     /* SUCCESS: pending. */
152     assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0),
153                      NX_AZURE_IOT_PENDING);
154 
155     tx_thread_sleep(NX_IP_PERIODIC_RATE);
156 
157     /* Deinitialize IoT provisioning client.  */
158     assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client),
159                      NX_AZURE_IOT_SUCCESS);
160 
161 
162     /* SUCCESS: iot is deleted. */
163     assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS);
164 }
165 
__wrap__nxde_dns_host_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name,NXD_ADDRESS * host_address_ptr,ULONG wait_option,UINT lookup_type)166 UINT  __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr,
167                                         ULONG wait_option, UINT lookup_type)
168 {
169     printf("HIJACKED: %s\n", __func__);
170     host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1);
171     return(NXD_MQTT_SUCCESS);
172 }
173 
__wrap__nxde_mqtt_client_login_set(NXD_MQTT_CLIENT * client_ptr,CHAR * username,UINT username_length,CHAR * password,UINT password_length)174 UINT __wrap__nxde_mqtt_client_login_set(NXD_MQTT_CLIENT *client_ptr,
175                                         CHAR *username, UINT username_length, CHAR *password, UINT password_length)
176 {
177     printf("HIJACKED: %s\n", __func__);
178     assert_null(password);
179     return(NXD_MQTT_SUCCESS);
180 }
181 
__wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT * client_ptr,NXD_ADDRESS * server_ip,UINT server_port,UINT (* tls_setup)(NXD_MQTT_CLIENT * client_ptr,NX_SECURE_TLS_SESSION *,NX_SECURE_X509_CERT *,NX_SECURE_X509_CERT *),UINT keepalive,UINT clean_session,ULONG wait_option)182 UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port,
183                                              UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *,
184                                                                NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *),
185                                              UINT keepalive, UINT clean_session, ULONG wait_option)
186 {
187     printf("HIJACKED: %s\n", __func__);
188     client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED;
189     return(NXD_MQTT_SUCCESS);
190 }
191 
__wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT * client_ptr)192 UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr)
193 {
194     printf("HIJACKED: %s\n", __func__);
195     client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE;
196     return(NXD_MQTT_SUCCESS);
197 }
198 
__wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT * nx_azure_iot_ptr)199 UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr)
200 {
201     printf("HIJACKED: %s\n", __func__);
202     return(NX_AZURE_IOT_SUCCESS);
203 }
204 
__wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT * nx_azure_iot_ptr)205 UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr)
206 {
207     printf("HIJACKED: %s\n", __func__);
208     return(NX_AZURE_IOT_SUCCESS);
209 }