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 "nx_api.h"
12 #ifndef SAMPLE_DHCP_DISABLE
13 #include "nxd_dhcp_client.h"
14 #endif /* SAMPLE_DHCP_DISABLE */
15 #include "nxd_dns.h"
16 #include "nxd_sntp_client.h"
17 #include "nx_secure_tls_api.h"
18
19 /* Defined, HTTP proxy is enabled. */
20 /*
21 #define SAMPLE_HTTP_PROXY_ENABLE
22 */
23
24 #ifdef SAMPLE_HTTP_PROXY_ENABLE
25 #ifndef NX_ENABLE_HTTP_PROXY
26 #error "SYMBOL NX_ENABLE_HTTP_PROXY must be defined. "
27 #endif /* NX_ENABLE_HTTP_PROXY */
28 #endif /* SAMPLE_HTTP_PROXY_ENABLE */
29
30 #if defined(SAMPLE_HTTP_PROXY_ENABLE)
31 #include "nx_http_proxy_client.h"
32 #endif /* SAMPLE_HTTP_PROXY_ENABLE */
33
34 /* Include the sample. */
35 extern VOID sample_entry(NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr, VOID *dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time));
36
37 /* Define the helper thread for running Azure SDK on ThreadX (THREADX IoT Platform). */
38 #ifndef SAMPLE_HELPER_STACK_SIZE
39 #define SAMPLE_HELPER_STACK_SIZE (4096)
40 #endif /* SAMPLE_HELPER_STACK_SIZE */
41
42 #ifndef SAMPLE_HELPER_THREAD_PRIORITY
43 #define SAMPLE_HELPER_THREAD_PRIORITY (4)
44 #endif /* SAMPLE_HELPER_THREAD_PRIORITY */
45
46 /* Define user configurable symbols. */
47 #ifndef SAMPLE_IP_STACK_SIZE
48 #define SAMPLE_IP_STACK_SIZE (2048)
49 #endif /* SAMPLE_IP_STACK_SIZE */
50
51 #ifndef SAMPLE_PACKET_COUNT
52 #define SAMPLE_PACKET_COUNT (32)
53 #endif /* SAMPLE_PACKET_COUNT */
54
55 #ifndef SAMPLE_PACKET_SIZE
56 #define SAMPLE_PACKET_SIZE (1536)
57 #endif /* SAMPLE_PACKET_SIZE */
58
59 #define SAMPLE_POOL_SIZE ((SAMPLE_PACKET_SIZE + sizeof(NX_PACKET)) * SAMPLE_PACKET_COUNT)
60
61 #ifndef SAMPLE_ARP_CACHE_SIZE
62 #define SAMPLE_ARP_CACHE_SIZE (512)
63 #endif /* SAMPLE_ARP_CACHE_SIZE */
64
65 #ifndef SAMPLE_IP_THREAD_PRIORITY
66 #define SAMPLE_IP_THREAD_PRIORITY (1)
67 #endif /* SAMPLE_IP_THREAD_PRIORITY */
68
69 #if defined(SAMPLE_DHCP_DISABLE) && !defined(SAMPLE_NETWORK_CONFIGURE)
70 #ifndef SAMPLE_IPV4_ADDRESS
71 /*#define SAMPLE_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33)*/
72 #error "SYMBOL SAMPLE_IPV4_ADDRESS must be defined. This symbol specifies the IP address of device. "
73 #endif /* SAMPLE_IPV4_ADDRESS */
74
75 #ifndef SAMPLE_IPV4_MASK
76 /*#define SAMPLE_IPV4_MASK 0xFFFFFF00UL*/
77 #error "SYMBOL SAMPLE_IPV4_MASK must be defined. This symbol specifies the IP address mask of device. "
78 #endif /* SAMPLE_IPV4_MASK */
79
80 #ifndef SAMPLE_GATEWAY_ADDRESS
81 /*#define SAMPLE_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1)*/
82 #error "SYMBOL SAMPLE_GATEWAY_ADDRESS must be defined. This symbol specifies the gateway address for routing. "
83 #endif /* SAMPLE_GATEWAY_ADDRESS */
84
85 #ifndef SAMPLE_DNS_SERVER_ADDRESS
86 /*#define SAMPLE_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1)*/
87 #error "SYMBOL SAMPLE_DNS_SERVER_ADDRESS must be defined. This symbol specifies the dns server address for routing. "
88 #endif /* SAMPLE_DNS_SERVER_ADDRESS */
89 #else
90 #define SAMPLE_IPV4_ADDRESS IP_ADDRESS(0, 0, 0, 0)
91 #define SAMPLE_IPV4_MASK IP_ADDRESS(0, 0, 0, 0)
92
93 #ifndef SAMPLE_DHCP_WAIT_OPTION
94 #define SAMPLE_DHCP_WAIT_OPTION (20 * NX_IP_PERIODIC_RATE)
95 #endif /* SAMPLE_DHCP_WAIT_OPTION */
96
97 #endif /* SAMPLE_DHCP_DISABLE */
98
99 #ifndef SAMPLE_SNTP_SYNC_MAX
100 #define SAMPLE_SNTP_SYNC_MAX 30
101 #endif /* SAMPLE_SNTP_SYNC_MAX */
102
103 #ifndef SAMPLE_SNTP_UPDATE_MAX
104 #define SAMPLE_SNTP_UPDATE_MAX 10
105 #endif /* SAMPLE_SNTP_UPDATE_MAX */
106
107 #ifndef SAMPLE_SNTP_UPDATE_INTERVAL
108 #define SAMPLE_SNTP_UPDATE_INTERVAL (NX_IP_PERIODIC_RATE / 2)
109 #endif /* SAMPLE_SNTP_UPDATE_INTERVAL */
110
111 /* Default time. GMT: Friday, Jan 1, 2022 12:00:00 AM. Epoch timestamp: 1640995200. */
112 #ifndef SAMPLE_SYSTEM_TIME
113 #define SAMPLE_SYSTEM_TIME 1640995200
114 #endif /* SAMPLE_SYSTEM_TIME */
115
116 /* Seconds between Unix Epoch (1/1/1970) and NTP Epoch (1/1/1999) */
117 #define SAMPLE_UNIX_TO_NTP_EPOCH_SECOND 0x83AA7E80
118
119 #if defined(SAMPLE_HTTP_PROXY_ENABLE)
120 #ifndef SAMPLE_HTTP_PROXY_SERVER
121 #define SAMPLE_HTTP_PROXY_SERVER IP_ADDRESS(192, 168, 100, 6)
122 #endif /* SAMPLE_HTTP_PROXY_SERVER */
123
124 #ifndef SAMPLE_HTTP_PROXY_SERVER_PORT
125 #define SAMPLE_HTTP_PROXY_SERVER_PORT 8888
126 #endif /* SAMPLE_HTTP_PROXY_SERVER_PORT */
127
128 #ifndef SAMPLE_HTTP_PROXY_USER_NAME
129 #define SAMPLE_HTTP_PROXY_USER_NAME ""
130 #endif /* SAMPLE_HTTP_PROXY_USER_NAME */
131
132 #ifndef SAMPLE_HTTP_PROXY_PASSWORD
133 #define SAMPLE_HTTP_PROXY_PASSWORD ""
134 #endif /* SAMPLE_HTTP_PROXY_PASSWORD */
135 #endif /* SAMPLE_HTTP_PROXY_ENABLE */
136
137 static TX_THREAD sample_helper_thread;
138 static NX_PACKET_POOL pool_0;
139 static NX_IP ip_0;
140 static NX_DNS dns_0;
141 #ifndef SAMPLE_DHCP_DISABLE
142 static NX_DHCP dhcp_0;
143 #endif /* SAMPLE_DHCP_DISABLE */
144 static NX_SNTP_CLIENT sntp_client;
145
146 /* System clock time for UTC. */
147 static ULONG unix_time_base;
148
149 /* Define the stack/cache for ThreadX. */
150 static ULONG sample_ip_stack[SAMPLE_IP_STACK_SIZE / sizeof(ULONG)];
151 #ifndef SAMPLE_POOL_STACK_USER
152 static ULONG sample_pool_stack[SAMPLE_POOL_SIZE / sizeof(ULONG)];
153 static ULONG sample_pool_stack_size = sizeof(sample_pool_stack);
154 #else
155 extern ULONG sample_pool_stack[];
156 extern ULONG sample_pool_stack_size;
157 #endif
158 #ifndef SAMPLE_NETWORK_CONFIGURE
159 static ULONG sample_arp_cache_area[SAMPLE_ARP_CACHE_SIZE / sizeof(ULONG)];
160 #endif
161 static ULONG sample_helper_thread_stack[SAMPLE_HELPER_STACK_SIZE / sizeof(ULONG)];
162
163 static const CHAR *sntp_servers[] =
164 {
165 "0.pool.ntp.org",
166 "1.pool.ntp.org",
167 "2.pool.ntp.org",
168 "3.pool.ntp.org",
169 };
170 static UINT sntp_server_index;
171
172 /* Define the prototypes for sample thread. */
173 static void sample_helper_thread_entry(ULONG parameter);
174
175 #ifndef SAMPLE_DHCP_DISABLE
176 static UINT dhcp_wait();
177 #endif /* SAMPLE_DHCP_DISABLE */
178
179 static UINT dns_create(ULONG dns_server_address);
180
181 static UINT sntp_time_sync();
182 static UINT unix_time_get(ULONG *unix_time);
183
184 #ifndef SAMPLE_NETWORK_DRIVER
185 #define SAMPLE_NETWORK_DRIVER _nx_ram_network_driver
186 #endif /* SAMPLE_NETWORK_DRIVER */
187
188 /* Include the platform IP driver. */
189 void SAMPLE_NETWORK_DRIVER(struct NX_IP_DRIVER_STRUCT *driver_req);
190
191 #ifdef SAMPLE_BOARD_SETUP
192 void SAMPLE_BOARD_SETUP();
193 #endif /* SAMPLE_BOARD_SETUP */
194
195 #ifdef SAMPLE_NETWORK_CONFIGURE
196 void SAMPLE_NETWORK_CONFIGURE(NX_IP *ip_ptr, ULONG *dns_address);
197 #endif
198
199 /* Define main entry point. */
main(void)200 int main(void)
201 {
202
203 #ifdef SAMPLE_BOARD_SETUP
204 SAMPLE_BOARD_SETUP();
205 #endif /* SAMPLE_BOARD_SETUP */
206
207 /* Enter the ThreadX kernel. */
208 tx_kernel_enter();
209 }
210
211 /* Define what the initial system looks like. */
tx_application_define(void * first_unused_memory)212 void tx_application_define(void *first_unused_memory)
213 {
214
215 UINT status;
216
217 NX_PARAMETER_NOT_USED(first_unused_memory);
218
219 /* Initialize the NetX system. */
220 nx_system_initialize();
221
222 /* Create a packet pool. */
223 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", SAMPLE_PACKET_SIZE,
224 (UCHAR *)sample_pool_stack , sample_pool_stack_size);
225
226 /* Check for pool creation error. */
227 if (status)
228 {
229 printf("nx_packet_pool_create fail: %u\r\n", status);
230 return;
231 }
232
233 /* Create an IP instance. */
234 status = nx_ip_create(&ip_0, "NetX IP Instance 0",
235 SAMPLE_IPV4_ADDRESS, SAMPLE_IPV4_MASK,
236 &pool_0, SAMPLE_NETWORK_DRIVER,
237 (UCHAR*)sample_ip_stack, sizeof(sample_ip_stack),
238 SAMPLE_IP_THREAD_PRIORITY);
239
240 /* Check for IP create errors. */
241 if (status)
242 {
243 printf("nx_ip_create fail: %u\r\n", status);
244 return;
245 }
246
247 #ifndef SAMPLE_NETWORK_CONFIGURE
248 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
249 status = nx_arp_enable(&ip_0, (VOID *)sample_arp_cache_area, sizeof(sample_arp_cache_area));
250
251 /* Check for ARP enable errors. */
252 if (status)
253 {
254 printf("nx_arp_enable fail: %u\r\n", status);
255 return;
256 }
257
258 /* Enable ICMP traffic. */
259 status = nx_icmp_enable(&ip_0);
260
261 /* Check for ICMP enable errors. */
262 if (status)
263 {
264 printf("nx_icmp_enable fail: %u\r\n", status);
265 return;
266 }
267 #endif
268
269 /* Enable TCP traffic. */
270 status = nx_tcp_enable(&ip_0);
271
272 /* Check for TCP enable errors. */
273 if (status)
274 {
275 printf("nx_tcp_enable fail: %u\r\n", status);
276 return;
277 }
278
279 /* Enable UDP traffic. */
280 status = nx_udp_enable(&ip_0);
281
282 /* Check for UDP enable errors. */
283 if (status)
284 {
285 printf("nx_udp_enable fail: %u\r\n", status);
286 return;
287 }
288
289 /* Initialize TLS. */
290 nx_secure_tls_initialize();
291
292 /* Create sample helper thread. */
293 status = tx_thread_create(&sample_helper_thread, "Demo Thread",
294 sample_helper_thread_entry, 0,
295 sample_helper_thread_stack, SAMPLE_HELPER_STACK_SIZE,
296 SAMPLE_HELPER_THREAD_PRIORITY, SAMPLE_HELPER_THREAD_PRIORITY,
297 TX_NO_TIME_SLICE, TX_AUTO_START);
298
299 /* Check status. */
300 if (status)
301 {
302 printf("Demo helper thread creation fail: %u\r\n", status);
303 return;
304 }
305 }
306
307 /* Define sample helper thread entry. */
sample_helper_thread_entry(ULONG parameter)308 void sample_helper_thread_entry(ULONG parameter)
309 {
310
311 UINT status;
312 ULONG ip_address = 0;
313 ULONG network_mask = 0;
314 ULONG gateway_address = 0;
315 UINT unix_time;
316 ULONG dns_server_address[3];
317 #ifndef SAMPLE_DHCP_DISABLE
318 UINT dns_server_address_size = sizeof(dns_server_address);
319 #endif
320 #if defined(SAMPLE_HTTP_PROXY_ENABLE)
321 NXD_ADDRESS proxy_server_address;
322 #endif /* SAMPLE_HTTP_PROXY_ENABLE */
323
324 NX_PARAMETER_NOT_USED(parameter);
325
326 #if defined(SAMPLE_HTTP_PROXY_ENABLE)
327
328 /* Enabled HTTP proxy. */
329 proxy_server_address.nxd_ip_version = NX_IP_VERSION_V4;
330 proxy_server_address.nxd_ip_address.v4 = SAMPLE_HTTP_PROXY_SERVER;
331 status = nx_http_proxy_client_enable(&ip_0, &proxy_server_address, SAMPLE_HTTP_PROXY_SERVER_PORT,
332 SAMPLE_HTTP_PROXY_USER_NAME, sizeof(SAMPLE_HTTP_PROXY_USER_NAME) - 1,
333 SAMPLE_HTTP_PROXY_PASSWORD, sizeof(SAMPLE_HTTP_PROXY_PASSWORD) - 1);
334 if (status)
335 {
336 printf("Failed to enable HTTP proxy!\r\n");
337 return;
338 }
339 #endif /* SAMPLE_HTTP_PROXY_ENABLE */
340
341 #ifndef SAMPLE_DHCP_DISABLE
342 if (dhcp_wait())
343 {
344 printf("Failed to get the IP address!\r\n");
345 return;
346 }
347 #elif defined(SAMPLE_NETWORK_CONFIGURE)
348 SAMPLE_NETWORK_CONFIGURE(&ip_0, &dns_server_address[0]);
349 #else
350 nx_ip_gateway_address_set(&ip_0, SAMPLE_GATEWAY_ADDRESS);
351 #endif /* SAMPLE_DHCP_DISABLE */
352
353 /* Get IP address and gateway address. */
354 nx_ip_address_get(&ip_0, &ip_address, &network_mask);
355 nx_ip_gateway_address_get(&ip_0, &gateway_address);
356
357 /* Output IP address and gateway address. */
358 printf("IP address: %lu.%lu.%lu.%lu\r\n",
359 (ip_address >> 24),
360 (ip_address >> 16 & 0xFF),
361 (ip_address >> 8 & 0xFF),
362 (ip_address & 0xFF));
363 printf("Mask: %lu.%lu.%lu.%lu\r\n",
364 (network_mask >> 24),
365 (network_mask >> 16 & 0xFF),
366 (network_mask >> 8 & 0xFF),
367 (network_mask & 0xFF));
368 printf("Gateway: %lu.%lu.%lu.%lu\r\n",
369 (gateway_address >> 24),
370 (gateway_address >> 16 & 0xFF),
371 (gateway_address >> 8 & 0xFF),
372 (gateway_address & 0xFF));
373
374 #ifndef SAMPLE_DHCP_DISABLE
375 /* Retrieve DNS server address. */
376 nx_dhcp_interface_user_option_retrieve(&dhcp_0, 0, NX_DHCP_OPTION_DNS_SVR, (UCHAR *)(dns_server_address),
377 &dns_server_address_size);
378 #elif !defined(SAMPLE_NETWORK_CONFIGURE)
379 dns_server_address[0] = SAMPLE_DNS_SERVER_ADDRESS;
380 #endif /* SAMPLE_DHCP_DISABLE */
381
382 /* Create DNS. */
383 status = dns_create(dns_server_address[0]);
384
385 /* Check for DNS create errors. */
386 if (status)
387 {
388 printf("dns_create fail: %u\r\n", status);
389 return;
390 }
391
392 /* Sync up time by SNTP at start up. */
393 status = sntp_time_sync();
394
395 /* Check status. */
396 if (status)
397 {
398 printf("SNTP Time Sync failed.\r\n");
399 printf("Set Time to default value: SAMPLE_SYSTEM_TIME.");
400 unix_time_base = SAMPLE_SYSTEM_TIME;
401 }
402 else
403 {
404 printf("SNTP Time Sync successfully.\r\n");
405 }
406
407 unix_time_get((ULONG *)&unix_time);
408 srand(unix_time);
409
410 /* Start sample. */
411 sample_entry(&ip_0, &pool_0, (VOID *)&dns_0, unix_time_get);
412 }
413
414 #ifndef SAMPLE_DHCP_DISABLE
dhcp_wait()415 static UINT dhcp_wait()
416 {
417 UINT status;
418 ULONG actual_status;
419
420 printf("DHCP In Progress...\r\n");
421
422 /* Create the DHCP instance. */
423 status = nx_dhcp_create(&dhcp_0, &ip_0, "DHCP Client");
424
425 /* Check status. */
426 if (status)
427 {
428 return(status);
429 }
430
431 /* Request NTP server. */
432 status = nx_dhcp_user_option_request(&dhcp_0, NX_DHCP_OPTION_NTP_SVR);
433
434 /* Check status. */
435 if (status)
436 {
437 nx_dhcp_delete(&dhcp_0);
438 return(status);
439 }
440
441 /* Start the DHCP Client. */
442 status = nx_dhcp_start(&dhcp_0);
443
444 /* Check status. */
445 if (status)
446 {
447 nx_dhcp_delete(&dhcp_0);
448 return(status);
449 }
450
451 /* Wait util address is solved. */
452 status = nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &actual_status, SAMPLE_DHCP_WAIT_OPTION);
453
454 /* Check status. */
455 if (status)
456 {
457 nx_dhcp_delete(&dhcp_0);
458 return(status);
459 }
460
461 return(NX_SUCCESS);
462 }
463 #endif /* SAMPLE_DHCP_DISABLE */
464
dns_create(ULONG dns_server_address)465 static UINT dns_create(ULONG dns_server_address)
466 {
467 UINT status;
468
469 /* Create a DNS instance for the Client. Note this function will create
470 the DNS Client packet pool for creating DNS message packets intended
471 for querying its DNS server. */
472 status = nx_dns_create(&dns_0, &ip_0, (UCHAR *)"DNS Client");
473 if (status)
474 {
475 return(status);
476 }
477
478 /* Is the DNS client configured for the host application to create the packet pool? */
479 #ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
480
481 /* Yes, use the packet pool created above which has appropriate payload size
482 for DNS messages. */
483 status = nx_dns_packet_pool_set(&dns_0, ip_0.nx_ip_default_packet_pool);
484 if (status)
485 {
486 nx_dns_delete(&dns_0);
487 return(status);
488 }
489 #endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */
490
491 /* Add an IPv4 server address to the Client list. */
492 status = nx_dns_server_add(&dns_0, dns_server_address);
493 if (status)
494 {
495 nx_dns_delete(&dns_0);
496 return(status);
497 }
498
499 /* Output DNS Server address. */
500 printf("DNS Server address: %lu.%lu.%lu.%lu\r\n",
501 (dns_server_address >> 24),
502 (dns_server_address >> 16 & 0xFF),
503 (dns_server_address >> 8 & 0xFF),
504 (dns_server_address & 0xFF));
505
506 return(NX_SUCCESS);
507 }
508
509 /* Sync up the local time. */
sntp_time_sync_internal(ULONG sntp_server_address)510 static UINT sntp_time_sync_internal(ULONG sntp_server_address)
511 {
512 UINT status;
513 UINT server_status;
514 UINT i;
515
516 /* Create the SNTP Client to run in broadcast mode.. */
517 status = nx_sntp_client_create(&sntp_client, &ip_0, 0, &pool_0,
518 NX_NULL,
519 NX_NULL,
520 NX_NULL /* no random_number_generator callback */);
521
522 /* Check status. */
523 if (status)
524 {
525 return(status);
526 }
527
528 /* Use the IPv4 service to initialize the Client and set the IPv4 SNTP server. */
529 status = nx_sntp_client_initialize_unicast(&sntp_client, sntp_server_address);
530
531 /* Check status. */
532 if (status)
533 {
534 nx_sntp_client_delete(&sntp_client);
535 return(status);
536 }
537
538 /* Set local time to 0 */
539 status = nx_sntp_client_set_local_time(&sntp_client, 0, 0);
540
541 /* Check status. */
542 if (status)
543 {
544 nx_sntp_client_delete(&sntp_client);
545 return(status);
546 }
547
548 /* Run Unicast client */
549 status = nx_sntp_client_run_unicast(&sntp_client);
550
551 /* Check status. */
552 if (status)
553 {
554 nx_sntp_client_stop(&sntp_client);
555 nx_sntp_client_delete(&sntp_client);
556 return(status);
557 }
558
559 /* Wait till updates are received */
560 for (i = 0; i < SAMPLE_SNTP_UPDATE_MAX; i++)
561 {
562
563 /* First verify we have a valid SNTP service running. */
564 status = nx_sntp_client_receiving_updates(&sntp_client, &server_status);
565
566 /* Check status. */
567 if ((status == NX_SUCCESS) && (server_status == NX_TRUE))
568 {
569
570 /* Server status is good. Now get the Client local time. */
571 ULONG sntp_seconds, sntp_fraction;
572 ULONG system_time_in_second;
573
574 /* Get the local time. */
575 status = nx_sntp_client_get_local_time(&sntp_client, &sntp_seconds, &sntp_fraction, NX_NULL);
576
577 /* Check status. */
578 if (status != NX_SUCCESS)
579 {
580 continue;
581 }
582
583 /* Get the system time in second. */
584 system_time_in_second = tx_time_get() / TX_TIMER_TICKS_PER_SECOND;
585
586 /* Convert to Unix epoch and minus the current system time. */
587 unix_time_base = (sntp_seconds - (system_time_in_second + SAMPLE_UNIX_TO_NTP_EPOCH_SECOND));
588
589 /* Time sync successfully. */
590
591 /* Stop and delete SNTP. */
592 nx_sntp_client_stop(&sntp_client);
593 nx_sntp_client_delete(&sntp_client);
594
595 return(NX_SUCCESS);
596 }
597
598 /* Sleep. */
599 tx_thread_sleep(SAMPLE_SNTP_UPDATE_INTERVAL);
600 }
601
602 /* Time sync failed. */
603
604 /* Stop and delete SNTP. */
605 nx_sntp_client_stop(&sntp_client);
606 nx_sntp_client_delete(&sntp_client);
607
608 /* Return success. */
609 return(NX_NOT_SUCCESSFUL);
610 }
611
sntp_time_sync()612 static UINT sntp_time_sync()
613 {
614 UINT status;
615 ULONG gateway_address;
616 ULONG sntp_server_address[3];
617 #ifndef SAMPLE_DHCP_DISABLE
618 UINT sntp_server_address_size = sizeof(sntp_server_address);
619 #endif
620
621 #ifndef SAMPLE_DHCP_DISABLE
622 /* Retrieve NTP server address. */
623 status = nx_dhcp_interface_user_option_retrieve(&dhcp_0, 0, NX_DHCP_OPTION_NTP_SVR, (UCHAR *)(sntp_server_address),
624 &sntp_server_address_size);
625
626 /* Check status. */
627 if (status == NX_SUCCESS)
628 {
629 for (UINT i = 0; (i * 4) < sntp_server_address_size; i++)
630 {
631 printf("SNTP Time Sync...%lu.%lu.%lu.%lu (DHCP)\r\n",
632 (sntp_server_address[i] >> 24),
633 (sntp_server_address[i] >> 16 & 0xFF),
634 (sntp_server_address[i] >> 8 & 0xFF),
635 (sntp_server_address[i] & 0xFF));
636
637 /* Start SNTP to sync the local time. */
638 status = sntp_time_sync_internal(sntp_server_address[i]);
639
640 /* Check status. */
641 if(status == NX_SUCCESS)
642 {
643 return(NX_SUCCESS);
644 }
645 }
646 }
647 #endif /* SAMPLE_DHCP_DISABLE */
648
649 /* Sync time by NTP server array. */
650 for (UINT i = 0; i < SAMPLE_SNTP_SYNC_MAX; i++)
651 {
652 printf("SNTP Time Sync...%s\r\n", sntp_servers[sntp_server_index]);
653
654 /* Make sure the network is still valid. */
655 while (nx_ip_gateway_address_get(&ip_0, &gateway_address))
656 {
657 tx_thread_sleep(NX_IP_PERIODIC_RATE);
658 }
659
660 /* Look up SNTP Server address. */
661 status = nx_dns_host_by_name_get(&dns_0, (UCHAR *)sntp_servers[sntp_server_index], &sntp_server_address[0], 5 * NX_IP_PERIODIC_RATE);
662
663 /* Check status. */
664 if (status == NX_SUCCESS)
665 {
666
667 /* Start SNTP to sync the local time. */
668 status = sntp_time_sync_internal(sntp_server_address[0]);
669
670 /* Check status. */
671 if(status == NX_SUCCESS)
672 {
673 return(NX_SUCCESS);
674 }
675 }
676
677 /* Switch SNTP server every time. */
678 sntp_server_index = (sntp_server_index + 1) % (sizeof(sntp_servers) / sizeof(sntp_servers[0]));
679 }
680
681 return(NX_NOT_SUCCESSFUL);
682 }
683
unix_time_get(ULONG * unix_time)684 static UINT unix_time_get(ULONG *unix_time)
685 {
686
687 /* Return number of seconds since Unix Epoch (1/1/1970 00:00:00). */
688 *unix_time = unix_time_base + (tx_time_get() / TX_TIMER_TICKS_PER_SECOND);
689
690 return(NX_SUCCESS);
691 }
692