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