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
20
21 #define DEMO_DHCP_DISABLE
22 #define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33)
23 #define DEMO_IPV4_MASK 0xFFFFFF00UL
24 #define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1)
25 #define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1)
26 #define NETWORK_DRIVER _nx_ram_network_driver
27
28 /* Include main.c in the test case since we need to disable DHCP in this test. */
29 #include "main.c"
30
31 #define C2D_TOPIC "devices/device_id/messages/devicebound/"
32
33 #define CALLBACK_ARGS 0x12345678
34
35 #define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s)
36
37 #ifndef DEMO_CLOUD_STACK_SIZE
38 #define DEMO_CLOUD_STACK_SIZE 2048
39 #endif /* DEMO_CLOUD_STACK_SIZE */
40
41 #ifndef DEMO_CLOUD_THREAD_PRIORITY
42 #define DEMO_CLOUD_THREAD_PRIORITY (4)
43 #endif /* DEMO_CLOUD_THREAD_PRIORITY */
44
45 #ifndef MAXIMUM_PROPERTY_LENGTH
46 #define MAXIMUM_PROPERTY_LENGTH 1400 /* packet size */
47 #endif /* MAXIMUM_PROPERTY_LENGTH */
48
49 #ifndef MAXIMUM_PAYLOAD_LENGTH
50 #define MAXIMUM_PAYLOAD_LENGTH 10240
51 #endif /* MAXIMUM_PAYLOAD_LENGTH */
52
53 #define MQTT_CLIENT_GET(c) ((c) -> nx_azure_iot_hub_client_resource.resource_mqtt)
54 #define TX_MUTEX_GET(c) ((c) -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr)
55
56 typedef struct
57 {
58 UCHAR *name;
59 ULONG name_length;
60 UCHAR *value;
61 ULONG value_length;
62 } PROPERTY;
63
64 #define PROPERTY_INIT(name, value) {(name), sizeof(name) - 1, (value), sizeof(value) - 1}
65
66 static VOID initialize_data();
67 static VOID property_payload_test(UINT packet_offset);
68 static VOID callback_test();
69 static VOID invalid_packet_test();
70 static VOID wait_timeout_test();
71 static VOID no_receiver_test();
72 static VOID construct_c2d_packet(NX_PACKET **packet_pptr, PROPERTY *properties, UINT property_count,
73 UCHAR *message_payload_ptr, ULONG message_payload_length,
74 UINT packet_offset);
75 static VOID c2d_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *args);
76 extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message,
77 UINT length, ULONG wait_option);
78 extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr,
79 UCHAR control_header, UINT length, UINT wait_option);
80
81 static NX_AZURE_IOT iot;
82 static NX_AZURE_IOT_HUB_CLIENT iot_client;
83 static NX_SECURE_X509_CERT root_ca_cert;
84 static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE];
85 static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)];
86 static UCHAR property_name[MAXIMUM_PROPERTY_LENGTH];
87 static UCHAR property_value[MAXIMUM_PROPERTY_LENGTH];
88 static UCHAR message_payload[MAXIMUM_PAYLOAD_LENGTH];
89 static UCHAR result_buffer[MAXIMUM_PAYLOAD_LENGTH];
90 static VOID (*test_receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL;
91
demo_entry(NX_IP * ip_ptr,NX_PACKET_POOL * pool_ptr,NX_DNS * dns_ptr,UINT (* unix_time_callback)(ULONG * unix_time))92 VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time))
93 {
94 CHAR *host_name = "host_name";
95 CHAR *device_id = "device_id";
96 CHAR *module_id = "module_id";
97 CHAR *symmetric_key = "symmetric_key";
98 ULONG pool_ptr_available_packet;
99
100 /* Initialize root certificate. */
101 assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size,
102 NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE),
103 NX_AZURE_IOT_SUCCESS);
104
105 assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack,
106 sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback),
107 NX_AZURE_IOT_SUCCESS);
108
109 /* Record number of available packet before test */
110 pool_ptr_available_packet = pool_ptr -> nx_packet_pool_available;
111
112 assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot,
113 STRING_UNSIGNED_ARGS(host_name),
114 STRING_UNSIGNED_ARGS(device_id),
115 STRING_UNSIGNED_ARGS(""),
116 _nx_azure_iot_tls_supported_crypto,
117 _nx_azure_iot_tls_supported_crypto_size,
118 _nx_azure_iot_tls_ciphersuite_map,
119 _nx_azure_iot_tls_ciphersuite_map_size,
120 metadata_buffer, sizeof(metadata_buffer),
121 &root_ca_cert),
122 NX_AZURE_IOT_SUCCESS);
123
124 assert_int_equal(nx_azure_iot_hub_client_cloud_message_enable(&iot_client),
125 NX_AZURE_IOT_SUCCESS);
126
127 will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS);
128 /* Connect IoTHub client */
129 assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, NX_WAIT_FOREVER),
130 NX_AZURE_IOT_SUCCESS);
131
132 /* Perform actual tests. */
133 initialize_data();
134 property_payload_test(0);
135 property_payload_test(1000);
136 callback_test();
137 invalid_packet_test();
138 wait_timeout_test();
139 no_receiver_test();
140
141
142 will_return(__wrap__nxde_mqtt_client_unsubscribe, NX_AZURE_IOT_SUCCESS);
143 assert_int_equal(nx_azure_iot_hub_client_cloud_message_disable(&iot_client),
144 NX_AZURE_IOT_SUCCESS);
145
146 assert_int_equal(nx_azure_iot_hub_client_disconnect(&iot_client),
147 NX_AZURE_IOT_SUCCESS);
148
149 assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client),
150 NX_AZURE_IOT_SUCCESS);
151
152 /* Check if all the packet are released */
153 assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr_available_packet);
154
155 assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS);
156 }
157
initialize_data()158 static VOID initialize_data()
159 {
160 UINT i;
161
162 for (i = 0; i < MAXIMUM_PROPERTY_LENGTH; i++)
163 {
164 property_name[i] = (NX_RAND() % 26) + 'a';
165 property_value[i] = (NX_RAND() % 26) + 'a';
166 }
167
168 for (i = 0; i < sizeof(message_payload); i++)
169 {
170 message_payload[i] = (NX_RAND() % 26) + 'a';
171 }
172 }
173
construct_c2d_packet(NX_PACKET ** packet_pptr,PROPERTY * properties,UINT property_count,UCHAR * message_payload_ptr,ULONG message_payload_length,UINT packet_offset)174 static VOID construct_c2d_packet(NX_PACKET **packet_pptr, PROPERTY *properties, UINT property_count,
175 UCHAR *message_payload_ptr, ULONG message_payload_length, UINT packet_offset)
176 {
177 NX_PACKET *packet_ptr;
178 ULONG topic_length = sizeof(C2D_TOPIC) - 1;
179 ULONG total_length;
180 UCHAR bytes[2];
181 UINT i;
182
183 assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, packet_offset, NX_NO_WAIT),
184 NX_AZURE_IOT_SUCCESS);
185
186 for (i = 0; i < property_count; i++)
187 {
188 topic_length += properties[i].name_length + properties[i].value_length + 2; /* '=' and '&' */
189 }
190
191 if (property_count)
192 {
193 topic_length--; /* Reduce by one since last '&' is not needed. */
194 }
195 total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field
196 and two bytes for packet id. */
197
198 /* Set fixed header. */
199 assert_int_equal(_nxd_mqtt_client_set_fixed_header(&(MQTT_CLIENT_GET(&iot_client)), packet_ptr,
200 (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1),
201 total_length, NX_NO_WAIT),
202 NX_AZURE_IOT_SUCCESS);
203
204 /* Set topic length. */
205 bytes[0] = (topic_length >> 8) & 0xFF;
206 bytes[1] = topic_length & 0xFF;
207 assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes),
208 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
209 NX_AZURE_IOT_SUCCESS);
210
211 /* Set topic. */
212 assert_int_equal(nx_packet_data_append(packet_ptr, C2D_TOPIC, sizeof(C2D_TOPIC) - 1,
213 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
214 NX_AZURE_IOT_SUCCESS);
215 for (i = 0; i < property_count; i++)
216 {
217 if (i != 0)
218 {
219 assert_int_equal(nx_packet_data_append(packet_ptr, "&", 1,
220 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
221 NX_AZURE_IOT_SUCCESS);
222 }
223 assert_int_equal(nx_packet_data_append(packet_ptr, properties[i].name, properties[i].name_length,
224 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
225 NX_AZURE_IOT_SUCCESS);
226 assert_int_equal(nx_packet_data_append(packet_ptr, "=", 1,
227 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
228 NX_AZURE_IOT_SUCCESS);
229 assert_int_equal(nx_packet_data_append(packet_ptr, properties[i].value, properties[i].value_length,
230 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
231 NX_AZURE_IOT_SUCCESS);
232 }
233
234 /* Set packet ID. The value does not matter. */
235 assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes),
236 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
237 NX_AZURE_IOT_SUCCESS);
238
239 /* Set message payload. */
240 if (message_payload_length > 0)
241 {
242 assert_int_equal(nx_packet_data_append(packet_ptr, message_payload_ptr, message_payload_length,
243 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
244 NX_AZURE_IOT_SUCCESS);
245 }
246
247 *packet_pptr = packet_ptr;
248 }
249
property_payload_test(UINT packet_offset)250 static VOID property_payload_test(UINT packet_offset)
251 {
252 NX_PACKET *packet_ptr;
253 ULONG bytes_copied;
254 USHORT result_size;
255 const UCHAR *result;
256 PROPERTY property = {property_name, 10, property_value, 10};
257 ULONG message_payload_length;
258 ULONG *length;
259 ULONG loop;
260 UINT i;
261
262 for (i = 0; i < 3; i++)
263 {
264 if (i == 0)
265 {
266
267 /* First round, length of property name is variable. */
268 loop = MAXIMUM_PROPERTY_LENGTH;
269 length = &property.name_length;
270 property.value_length = 10;
271 message_payload_length = 10;
272 }
273 else if (i == 1)
274 {
275
276 /* Second round, length of property value is variable. */
277 loop = MAXIMUM_PROPERTY_LENGTH;
278 length = &property.value_length;
279 property.name_length = 10;
280 message_payload_length = 10;
281 }
282 else
283 {
284
285 /* Third round, length of message is variable. */
286 loop = MAXIMUM_PAYLOAD_LENGTH; /* It is supported when message is spanned in multiple packets. */
287 length = &message_payload_length;
288 property.name_length = 10;
289 property.value_length = 10;
290 }
291 for (*length = 0; *length < loop; (*length)++)
292 {
293 if ((i < 2) && (*length == 0))
294 {
295
296 /* Skip length 0 for property. */
297 continue;
298 }
299
300 construct_c2d_packet(&packet_ptr, &property, 1, message_payload, message_payload_length, packet_offset);
301
302 /* Simulate callback from MQTT layer. */
303 MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr;
304 MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1;
305 tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER);
306 test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1);
307 tx_mutex_put(TX_MUTEX_GET(&iot_client));
308
309 assert_int_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT),
310 NX_AZURE_IOT_SUCCESS);
311
312 /* Validate property. */
313 memset(result_buffer, property.value_length, 0);
314 assert_int_equal(nx_azure_iot_hub_client_cloud_message_property_get(&iot_client, packet_ptr,
315 property.name, property.name_length,
316 &result, &result_size),
317 NX_AZURE_IOT_SUCCESS);
318 assert_int_equal(property.value_length, result_size);
319 assert_memory_equal(property.value, result, result_size);
320
321 /* Validate payload. */
322 memset(result_buffer, message_payload_length, 0);
323 assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer,
324 sizeof(result_buffer), &bytes_copied),
325 NX_AZURE_IOT_SUCCESS);
326 assert_int_equal(message_payload_length, bytes_copied);
327 assert_memory_equal(message_payload, result_buffer, bytes_copied);
328
329 nx_packet_release(packet_ptr);
330 }
331 }
332 }
333
334 static UINT (*c2d_message_process)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr,
335 NX_PACKET *packet_ptr, ULONG topic_offset, USHORT topic_length);
336
callback_test()337 static VOID callback_test()
338 {
339 ULONG arg = CALLBACK_ARGS;
340 NX_PACKET *packet_ptr;
341 ULONG bytes_copied;
342 ULONG message_payload_length = 10;
343 UINT c2d_control_flag;
344
345 /* Expected fail: NX_AZURE_IOT_HUB_CLIENT is NULL. */
346 assert_int_not_equal(nx_azure_iot_hub_client_receive_callback_set(NX_NULL,
347 NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE,
348 c2d_callback,
349 &arg),
350 NX_AZURE_IOT_SUCCESS);
351
352 /* Expected fail: unknown message type. */
353 assert_int_not_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client,
354 0xFFFFFFFF,
355 c2d_callback,
356 &arg),
357 NX_AZURE_IOT_SUCCESS);
358
359 /* Expect c2d_callback to be called once. */
360 expect_function_calls(c2d_callback, 1);
361
362 /* Set callback function. */
363 assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client,
364 NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE,
365 c2d_callback,
366 &arg),
367 NX_AZURE_IOT_SUCCESS);
368
369 /* Put C2D packet to MQTT receive queue. */
370 construct_c2d_packet(&packet_ptr, NX_NULL, 0, message_payload, message_payload_length, 0);
371 MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr;
372 MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1;
373
374 /* Expected callback function to be set. */
375 assert_ptr_not_equal(test_receive_notify, NX_NULL);
376
377 /* Simulate callback from MQTT layer. */
378 tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER);
379 test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1);
380 tx_mutex_put(TX_MUTEX_GET(&iot_client));
381
382 /* Expected fail: NX_AZURE_IOT_HUB_CLIENT is NULL. */
383 assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(NX_NULL, &packet_ptr, NX_NO_WAIT),
384 NX_AZURE_IOT_SUCCESS);
385
386 /* Expected fail: packet pointer is NULL. */
387 assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, NX_NULL, NX_NO_WAIT),
388 NX_AZURE_IOT_SUCCESS);
389
390 /* Expected fail: packet pointer is NULL. */
391 assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, NX_NULL, NX_NO_WAIT),
392 NX_AZURE_IOT_SUCCESS);
393
394 /* Expected fail: message_process is NULL. */
395 c2d_message_process = iot_client.nx_azure_iot_hub_client_c2d_message.message_process;
396 iot_client.nx_azure_iot_hub_client_c2d_message.message_process = NX_NULL;
397 assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT),
398 NX_AZURE_IOT_SUCCESS);
399 iot_client.nx_azure_iot_hub_client_c2d_message.message_process = c2d_message_process;
400
401 /* Receive packet by API. */
402 assert_int_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT),
403 NX_AZURE_IOT_SUCCESS);
404
405 /* Validate payload. */
406 memset(result_buffer, message_payload_length, 0);
407 assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer,
408 sizeof(result_buffer), &bytes_copied),
409 NX_AZURE_IOT_SUCCESS);
410 assert_int_equal(message_payload_length, bytes_copied);
411 assert_memory_equal(message_payload, result_buffer, bytes_copied);
412 nx_packet_release(packet_ptr);
413
414 /* Expected fail: no packet available. */
415 assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT),
416 NX_AZURE_IOT_SUCCESS);
417
418 /* Clear C2D callback function. */
419 assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client,
420 NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE,
421 NX_NULL,
422 NX_NULL),
423 NX_AZURE_IOT_SUCCESS);
424 }
425
invalid_packet_test()426 static VOID invalid_packet_test()
427 {
428 NX_PACKET *packet_ptr;
429 UCHAR bytes[2] = {0, 0};
430
431 assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT),
432 NX_AZURE_IOT_SUCCESS);
433 assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes),
434 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
435 NX_AZURE_IOT_SUCCESS);
436
437 /* Put invalid packet to MQTT receive queue. */
438 MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr;
439 MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1;
440
441 /* Simulate callback from MQTT layer. */
442 tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER);
443 test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1);
444 tx_mutex_put(TX_MUTEX_GET(&iot_client));
445
446 /* Expected fail: no packet available. */
447 assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT),
448 NX_AZURE_IOT_SUCCESS);
449
450
451 assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT),
452 NX_AZURE_IOT_SUCCESS);
453 assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes),
454 iot.nx_azure_iot_pool_ptr, NX_NO_WAIT),
455 NX_AZURE_IOT_SUCCESS);
456
457 /* Put invalid packet to receive header. */
458 iot_client.nx_azure_iot_hub_client_c2d_message.message_head = packet_ptr;
459
460 /* Expected fail: no packet available. */
461 assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT),
462 NX_AZURE_IOT_SUCCESS);
463 }
464
wait_timeout_test()465 static VOID wait_timeout_test()
466 {
467 NX_PACKET *packet_ptr;
468 ULONG message_payload_length = 10;
469
470 /* Expect fail: no packet available. */
471 assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, 1),
472 NX_AZURE_IOT_SUCCESS);
473
474 /* Put C2D packet to MQTT receive queue. */
475 construct_c2d_packet(&packet_ptr, NX_NULL, 0, message_payload, message_payload_length, 0);
476 MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr;
477 MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1;
478
479 /* Simulate callback from MQTT layer. */
480 tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER);
481 test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1);
482 tx_mutex_put(TX_MUTEX_GET(&iot_client));
483
484 /* Receive packet by API. */
485 assert_int_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT),
486 NX_AZURE_IOT_SUCCESS);
487 nx_packet_release(packet_ptr);
488 }
489
no_receiver_test()490 static VOID no_receiver_test()
491 {
492 NX_PACKET *packet_ptr;
493 ULONG message_payload_length = 10;
494
495 /* Put C2D packet to MQTT receive queue. */
496 construct_c2d_packet(&packet_ptr, NX_NULL, 0, message_payload, message_payload_length, 0);
497 MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr;
498 MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1;
499
500 /* Simulate callback from MQTT layer. */
501 tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER);
502 test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1);
503 tx_mutex_put(TX_MUTEX_GET(&iot_client));
504
505 /* No one will receive this packet. Packet leak will be checked at last step of test. */
506 }
507
c2d_callback(NX_AZURE_IOT_HUB_CLIENT * hub_client_ptr,VOID * args)508 static VOID c2d_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *args)
509 {
510 function_called();
511 assert_ptr_equal(hub_client_ptr, &iot_client);
512 assert_int_equal(*(ULONG *)args, CALLBACK_ARGS);
513 }
514
__wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT * client_ptr,VOID (* receive_notify)(NXD_MQTT_CLIENT * client_ptr,UINT message_count))515 UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr,
516 VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count))
517 {
518 printf("HIJACKED: %s\n", __func__);
519 test_receive_notify = receive_notify;
520 return(NX_AZURE_IOT_SUCCESS);
521 }
522
__wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT * client_ptr,UINT op,CHAR * topic_name,UINT topic_name_length,USHORT * packet_id_ptr,UINT QoS)523 UINT __wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT *client_ptr, UINT op,
524 CHAR *topic_name, UINT topic_name_length,
525 USHORT *packet_id_ptr, UINT QoS)
526 {
527 printf("HIJACKED: %s\n", __func__);
528 return((UINT)mock());
529 }
530
__wrap__nxde_mqtt_client_unsubscribe(NXD_MQTT_CLIENT * client_ptr,CHAR * topic_name,UINT topic_name_length,UINT QoS)531 UINT __wrap__nxde_mqtt_client_unsubscribe(NXD_MQTT_CLIENT *client_ptr, CHAR *topic_name,
532 UINT topic_name_length, UINT QoS)
533 {
534 printf("HIJACKED: %s\n", __func__);
535 return((UINT)mock());
536 }
537
__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)538 UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port,
539 UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *,
540 NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *),
541 UINT keepalive, UINT clean_session, ULONG wait_option)
542 {
543 printf("HIJACKED: %s\n", __func__);
544
545 tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread));
546 client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED;
547 client_ptr -> nxd_mqtt_client_packet_identifier = 1;
548 client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID;
549 client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE;
550 client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket;
551 client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4;
552 client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED;
553
554 return(NXD_MQTT_SUCCESS);
555 }
556
__wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT * client_ptr)557 UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr)
558 {
559 printf("HIJACKED: %s\n", __func__);
560 client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE;
561 client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED;
562 return(NXD_MQTT_SUCCESS);
563 }
564
__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)565 UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr,
566 ULONG wait_option, UINT lookup_type)
567 {
568 printf("HIJACKED: %s\n", __func__);
569 host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1);
570 return(NX_DNS_SUCCESS);
571 }
572
__wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT * nx_azure_iot_ptr)573 UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr)
574 {
575 printf("HIJACKED: %s\n", __func__);
576 return(NX_AZURE_IOT_SUCCESS);
577 }
578
__wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT * nx_azure_iot_ptr)579 UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr)
580 {
581 printf("HIJACKED: %s\n", __func__);
582 return(NX_AZURE_IOT_SUCCESS);
583 }
584