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
13 #include "nx_api.h"
14 #include "nx_azure_iot_hub_client.h"
15 #include "nx_azure_iot_cert.h"
16 #include "nx_azure_iot_ciphersuites.h"
17
18
19 #define DEMO_DHCP_DISABLE
20 #define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33)
21 #define DEMO_IPV4_MASK 0xFFFFFF00UL
22 #define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1)
23 #define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1)
24 #define NETWORK_DRIVER _nx_ram_network_driver
25
26 /* Include main.c in the test case since we need to disable DHCP in this test. */
27 #include "main.c"
28
29
30 #define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s)
31
32 #ifndef DEMO_CLOUD_STACK_SIZE
33 #define DEMO_CLOUD_STACK_SIZE 2048
34 #endif /* DEMO_CLOUD_STACK_SIZE */
35
36 #ifndef DEMO_CLOUD_THREAD_PRIORITY
37 #define DEMO_CLOUD_THREAD_PRIORITY (4)
38 #endif /* DEMO_CLOUD_THREAD_PRIORITY */
39
40 UINT __wrap__nxde_mqtt_client_delete(NXD_MQTT_CLIENT *client_ptr);
41 UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr,
42 VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr,
43 UINT message_count));
44
45 static NX_AZURE_IOT iot;
46 static NX_AZURE_IOT_HUB_CLIENT iot_client;
47 static NX_AZURE_IOT_HUB_CLIENT iot_clients[3];
48 static NX_SECURE_X509_CERT root_ca_cert;
49 static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE];
50 static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)];
51 extern int g_argc;
52 extern char **g_argv;
53 extern NX_AZURE_IOT *_nx_azure_iot_created_ptr;
54
demo_entry(NX_IP * ip_ptr,NX_PACKET_POOL * pool_ptr,NX_DNS * dns_ptr,UINT (* unix_time_callback)(ULONG * unix_time))55 VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time))
56 {
57 CHAR *host_name = "host_name";
58 CHAR *device_id = "device_id";
59 CHAR *module_id = "module_id";
60 CHAR *symmetric_key = "symmetric_key";
61 UINT i;
62
63 /* Initialize root certificate. */
64 assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size,
65 NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE),
66 NX_AZURE_IOT_SUCCESS);
67
68 /*********** Test nx_azure_iot_create() ***********/
69 /* FAIL: NX_AZURE_IOT pointer is null. */
70 assert_int_not_equal(nx_azure_iot_create(NX_NULL, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack,
71 sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
72 NX_AZURE_IOT_SUCCESS);
73
74 /* FAIL: NX_IP pointer is null. */
75 assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", NX_NULL, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack,
76 sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
77 NX_AZURE_IOT_SUCCESS);
78
79 /* FAIL: NX_PACKET_POOL pointer is null. */
80 assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, NX_NULL, dns_ptr, (UCHAR *)demo_cloud_thread_stack,
81 sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
82 NX_AZURE_IOT_SUCCESS);
83
84 /* FAIL: NX_DNS pointer is null. */
85 assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, NX_NULL, (UCHAR *)demo_cloud_thread_stack,
86 sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
87 NX_AZURE_IOT_SUCCESS);
88
89 /* FAIL: stack pointer is null. */
90 assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, NX_NULL,
91 sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
92 NX_AZURE_IOT_SUCCESS);
93
94 /* FAIL: stack size is 0. */
95 assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack,
96 0, DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
97 NX_AZURE_IOT_SUCCESS);
98
99 /* SUCCESS: all parameters are valid. */
100 assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack,
101 sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
102 NX_AZURE_IOT_SUCCESS);
103
104 /*********** Test nx_azure_iot_delete() ***********/
105 /* FAIL: NX_AZURE_IOT pointer is null. */
106 assert_int_not_equal(nx_azure_iot_delete(NX_NULL), NX_AZURE_IOT_SUCCESS);
107
108 /* FAIL: nx_cloud_delete fail. */
109 /* Manually set nx_cloud_modules_count to none zero. */
110 iot.nx_azure_iot_cloud.nx_cloud_modules_count++;
111 assert_int_not_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS);
112 iot.nx_azure_iot_cloud.nx_cloud_modules_count--;
113
114 /* SUCCESS: iot is created. */
115 assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS);
116
117
118 /*********** Test nx_azure_iot_hub_client_initialize() ***********/
119 assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack,
120 sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
121 NX_AZURE_IOT_SUCCESS);
122
123 /* FAIL: NX_AZURE_IOT pointer is null. */
124 assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, NX_NULL,
125 STRING_UNSIGNED_ARGS(host_name),
126 STRING_UNSIGNED_ARGS(device_id),
127 STRING_UNSIGNED_ARGS(module_id),
128 _nx_azure_iot_tls_supported_crypto,
129 _nx_azure_iot_tls_supported_crypto_size,
130 _nx_azure_iot_tls_ciphersuite_map,
131 _nx_azure_iot_tls_ciphersuite_map_size,
132 metadata_buffer, sizeof(metadata_buffer),
133 &root_ca_cert),
134 NX_AZURE_IOT_SUCCESS);
135
136 /* FAIL: NX_AZURE_IOT_HUB_CLIENT pointer is null. */
137 assert_int_not_equal(nx_azure_iot_hub_client_initialize(NX_NULL, &iot,
138 STRING_UNSIGNED_ARGS(host_name),
139 STRING_UNSIGNED_ARGS(device_id),
140 STRING_UNSIGNED_ARGS(module_id),
141 _nx_azure_iot_tls_supported_crypto,
142 _nx_azure_iot_tls_supported_crypto_size,
143 _nx_azure_iot_tls_ciphersuite_map,
144 _nx_azure_iot_tls_ciphersuite_map_size,
145 metadata_buffer, sizeof(metadata_buffer),
146 &root_ca_cert),
147 NX_AZURE_IOT_SUCCESS);
148
149 /* FAIL: host_name pointer is null. */
150 assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
151 NX_NULL, 0,
152 STRING_UNSIGNED_ARGS(device_id),
153 STRING_UNSIGNED_ARGS(module_id),
154 _nx_azure_iot_tls_supported_crypto,
155 _nx_azure_iot_tls_supported_crypto_size,
156 _nx_azure_iot_tls_ciphersuite_map,
157 _nx_azure_iot_tls_ciphersuite_map_size,
158 metadata_buffer, sizeof(metadata_buffer),
159 &root_ca_cert),
160 NX_AZURE_IOT_SUCCESS);
161
162 /* FAIL: device_id pointer is null. */
163 assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
164 STRING_UNSIGNED_ARGS(host_name),
165 NX_NULL, 0,
166 STRING_UNSIGNED_ARGS(module_id),
167 _nx_azure_iot_tls_supported_crypto,
168 _nx_azure_iot_tls_supported_crypto_size,
169 _nx_azure_iot_tls_ciphersuite_map,
170 _nx_azure_iot_tls_ciphersuite_map_size,
171 metadata_buffer, sizeof(metadata_buffer),
172 &root_ca_cert),
173 NX_AZURE_IOT_SUCCESS);
174
175 /* FAIL: host_name_length is 0. */
176 assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
177 "", 0,
178 STRING_UNSIGNED_ARGS(device_id),
179 STRING_UNSIGNED_ARGS(module_id),
180 _nx_azure_iot_tls_supported_crypto,
181 _nx_azure_iot_tls_supported_crypto_size,
182 _nx_azure_iot_tls_ciphersuite_map,
183 _nx_azure_iot_tls_ciphersuite_map_size,
184 metadata_buffer, sizeof(metadata_buffer),
185 &root_ca_cert),
186 NX_AZURE_IOT_SUCCESS);
187
188 /* FAIL: device_id_length is 0. */
189 assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
190 STRING_UNSIGNED_ARGS(host_name),
191 "", 0,
192 STRING_UNSIGNED_ARGS(module_id),
193 _nx_azure_iot_tls_supported_crypto,
194 _nx_azure_iot_tls_supported_crypto_size,
195 _nx_azure_iot_tls_ciphersuite_map,
196 _nx_azure_iot_tls_ciphersuite_map_size,
197 metadata_buffer, sizeof(metadata_buffer),
198 &root_ca_cert),
199 NX_AZURE_IOT_SUCCESS);
200
201 /* FAIL: invalidate cloud_id manually. */
202 iot.nx_azure_iot_cloud.nx_cloud_id = 0;
203 assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
204 STRING_UNSIGNED_ARGS(host_name),
205 STRING_UNSIGNED_ARGS(device_id),
206 STRING_UNSIGNED_ARGS(module_id),
207 _nx_azure_iot_tls_supported_crypto,
208 _nx_azure_iot_tls_supported_crypto_size,
209 _nx_azure_iot_tls_ciphersuite_map,
210 _nx_azure_iot_tls_ciphersuite_map_size,
211 metadata_buffer, sizeof(metadata_buffer),
212 &root_ca_cert),
213 NX_AZURE_IOT_SUCCESS);
214 iot.nx_azure_iot_cloud.nx_cloud_id = NX_CLOUD_ID;
215
216 /* FAIL: nxd_mqtt_client_receive_notify_set will fail by hijacked function. */
217 will_return(__wrap__nxde_mqtt_client_receive_notify_set, NXD_MQTT_INVALID_PARAMETER);
218 will_return(__wrap__nxde_mqtt_client_delete, NXD_MQTT_SUCCESS);
219 assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
220 STRING_UNSIGNED_ARGS(host_name),
221 STRING_UNSIGNED_ARGS(device_id),
222 STRING_UNSIGNED_ARGS(module_id),
223 _nx_azure_iot_tls_supported_crypto,
224 _nx_azure_iot_tls_supported_crypto_size,
225 _nx_azure_iot_tls_ciphersuite_map,
226 _nx_azure_iot_tls_ciphersuite_map_size,
227 metadata_buffer, sizeof(metadata_buffer),
228 &root_ca_cert),
229 NX_AZURE_IOT_SUCCESS);
230
231 /* SUCCESS: all parameters are valid. */
232 will_return_always(__wrap__nxde_mqtt_client_receive_notify_set, NXD_MQTT_SUCCESS);
233 will_return(__wrap__nxde_mqtt_client_delete, NXD_MQTT_SUCCESS);
234 assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
235 STRING_UNSIGNED_ARGS(host_name),
236 STRING_UNSIGNED_ARGS(device_id),
237 STRING_UNSIGNED_ARGS(module_id),
238 _nx_azure_iot_tls_supported_crypto,
239 _nx_azure_iot_tls_supported_crypto_size,
240 _nx_azure_iot_tls_ciphersuite_map,
241 _nx_azure_iot_tls_ciphersuite_map_size,
242 metadata_buffer, sizeof(metadata_buffer),
243 &root_ca_cert),
244 NX_AZURE_IOT_SUCCESS);
245 assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client),
246 NX_AZURE_IOT_SUCCESS);
247
248 /* SUCCESS: all parameters are valid and module_id pointer is null. */
249 assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
250 STRING_UNSIGNED_ARGS(host_name),
251 STRING_UNSIGNED_ARGS(device_id),
252 NX_NULL, 0,
253 _nx_azure_iot_tls_supported_crypto,
254 _nx_azure_iot_tls_supported_crypto_size,
255 _nx_azure_iot_tls_ciphersuite_map,
256 _nx_azure_iot_tls_ciphersuite_map_size,
257 metadata_buffer, sizeof(metadata_buffer),
258 &root_ca_cert),
259 NX_AZURE_IOT_SUCCESS);
260 will_return(__wrap__nxde_mqtt_client_delete, NXD_MQTT_SUCCESS);
261 assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client),
262 NX_AZURE_IOT_SUCCESS);
263
264 /* SUCCESS: all parameters are valid and module_id pointer is null. */
265 assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
266 STRING_UNSIGNED_ARGS(host_name),
267 STRING_UNSIGNED_ARGS(device_id),
268 NX_NULL, 0,
269 _nx_azure_iot_tls_supported_crypto,
270 _nx_azure_iot_tls_supported_crypto_size,
271 _nx_azure_iot_tls_ciphersuite_map,
272 _nx_azure_iot_tls_ciphersuite_map_size,
273 metadata_buffer, sizeof(metadata_buffer),
274 &root_ca_cert),
275 NX_AZURE_IOT_SUCCESS);
276
277
278 /*********** Test nx_azure_iot_hub_client_deinitialize() ***********/
279 /* FAIL: NX_AZURE_IOT_HUB_CLIENT pointer is null. */
280 assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(NX_NULL),
281 NX_AZURE_IOT_SUCCESS);
282
283 /* FAIL: iot_client is not deleted yet. */
284 assert_int_not_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS);
285
286 /* FAIL: nxd_mqtt_client_delete will fail by hijacked function. */
287 will_return(__wrap__nxde_mqtt_client_delete, NXD_MQTT_INVALID_PARAMETER);
288 assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(&iot_client),
289 NX_AZURE_IOT_SUCCESS);
290
291 /* SUCCESS: iot_client is created. */
292 will_return_always(__wrap__nxde_mqtt_client_delete, NXD_MQTT_SUCCESS);
293 assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client),
294 NX_AZURE_IOT_SUCCESS);
295
296 /* FAIL: iot_client is already deleted. */
297 assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(&iot_client),
298 NX_AZURE_IOT_SUCCESS);
299
300
301 /*********** Test multiple nx_azure_iot_hub_client_initialize()/deinitialize() ***********/
302 for (i = 0; i < sizeof(iot_clients) / sizeof(NX_AZURE_IOT_HUB_CLIENT); i++)
303 {
304 assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_clients[i], &iot,
305 STRING_UNSIGNED_ARGS(host_name),
306 STRING_UNSIGNED_ARGS(device_id),
307 NX_NULL, 0,
308 _nx_azure_iot_tls_supported_crypto,
309 _nx_azure_iot_tls_supported_crypto_size,
310 _nx_azure_iot_tls_ciphersuite_map,
311 _nx_azure_iot_tls_ciphersuite_map_size,
312 metadata_buffer, sizeof(metadata_buffer),
313 &root_ca_cert),
314 NX_AZURE_IOT_SUCCESS);
315 }
316
317 /* Manually remove the header of nx_azure_iot_hub_client_list_header. */
318 /* FAIL: this one removed from nx_azure_iot_hub_client_list_header. */
319 _nx_azure_iot_created_ptr -> nx_azure_iot_resource_list_header = _nx_azure_iot_created_ptr -> nx_azure_iot_resource_list_header -> resource_next;
320 assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(&iot_clients[sizeof(iot_clients) / sizeof(NX_AZURE_IOT_HUB_CLIENT) - 1]),
321 NX_AZURE_IOT_SUCCESS);
322
323 for (i = 0; i < sizeof(iot_clients) / sizeof(NX_AZURE_IOT_HUB_CLIENT) - 1; i++)
324 {
325 assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_clients[i]),
326 NX_AZURE_IOT_SUCCESS);
327 }
328
329
330 /* SUCCESS: iot is created. */
331 assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS);
332
333 /* Check if all the packet are released */
334 assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr -> nx_packet_pool_total);
335 }
336
337 UINT __real__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr,
338 VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr,
339 UINT message_count));
__wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT * client_ptr,VOID (* receive_notify)(NXD_MQTT_CLIENT * client_ptr,UINT message_count))340 UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr,
341 VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr,
342 UINT message_count))
343 {
344 if ((UINT)mock() != NXD_MQTT_SUCCESS)
345 {
346 printf("HIJACKED: %s\n", __func__);
347 return(NXD_MQTT_INVALID_PARAMETER);
348 }
349 return(__real__nxde_mqtt_client_receive_notify_set(client_ptr, receive_notify));
350 }
351
352 UINT __real__nxde_mqtt_client_delete(NXD_MQTT_CLIENT *client_ptr);
__wrap__nxde_mqtt_client_delete(NXD_MQTT_CLIENT * client_ptr)353 UINT __wrap__nxde_mqtt_client_delete(NXD_MQTT_CLIENT *client_ptr)
354 {
355 if ((UINT)mock() != NXD_MQTT_SUCCESS)
356 {
357 printf("HIJACKED: %s\n", __func__);
358 return(NXD_MQTT_INVALID_PARAMETER);
359 }
360 return(__real__nxde_mqtt_client_delete(client_ptr));
361 }
362