1 #include "nx_api.h"
2 #include "nx_ip.h"
3 #include "nxd_sntp_client.h"
4 
5 extern void test_control_return(UINT status);
6 #if !defined(NX_DISABLE_IPV4)
7 /* Define SNTP packet size. */
8 #define NX_SNTP_CLIENT_PACKET_SIZE                 (NX_UDP_PACKET + 100)
9 
10 /* Define SNTP packet pool size. */
11 #define NX_SNTP_CLIENT_PACKET_POOL_SIZE            (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET)))
12 
13 /* NTP server reply. */
14 static char pkt_data[90] = {
15 
16     /* Ethernet header */
17     0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c,
18     0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00,
19 
20     /* IP layer */
21     0x45, 0x00, 0x00, 0x4c,
22     0x00, 0x00, 0x40, 0x00,
23     0x40, 0x11, 0xbc, 0xa3,
24     0xc0, 0xa8, 0x7e, 0x82,
25     0xc0, 0xa8, 0x7e, 0x2a,
26 
27     /* UDP header */
28     0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, 0x28, 0x3f,
29 
30     /* SNTP data  */
31     0x1c,                   // flags was 28 which= server mode 4 and version 3
32     0x2,                    // stratum
33     0x3,                    // poll interval
34     0xf9,                   // clock precision
35     0x0, 0x0,0x4,0x23,      // root delay
36     0x0, 0x0,0x8,0xf3,      // root dispersion
37     0x82,0x95,0x11,0x8,     // ref ID
38 
39   /* for March 30, 2017, 16:14:23.665 */
40     0xdc,0x87,0xab,0xc1, 0x16,0xe4,0xbc,0x59,  // ref timestamp
41 
42     0xdc,0x87,0xad,0x5f, 0xa7,0x00,0x68,0x0,   // origin timestamp
43 
44     0xdc,0x87,0xad,0x5f, 0xa7,0xc9,0xfd,0x90,  // receive timestamp
45 
46     0xdc,0x87,0xad,0x5f, 0xa7,0xcc,0x42,0x36
47 };
48 
49 static UINT pkt_size = 90;
50 
51 
52 extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr);
53 
54 /* Set up client thread and network resources. */
55 
56 static NX_PACKET_POOL      client_packet_pool;
57 static NX_IP               client_ip;
58 static TX_THREAD           sntp_client_thread;
59 static NX_SNTP_CLIENT      sntp_client;
60 
61 
62 #define CLIENT_IP_ADDRESS       IP_ADDRESS(192,168,126,42)
63 #define SERVER_IP_ADDRESS       IP_ADDRESS(192,168,126,130)
64 #define SERVER_IP_ADDRESS_2     SERVER_IP_ADDRESS
65 
66 /* Set up the SNTP network and address index; */
67 static UINT     iface_index;
68 
69 static UINT     error_counter;
70 
71 /* Set up client thread entry point. */
72 static void sntp_client_thread_entry(ULONG info);
73 
74 static void inject_sntp_server_reply();
75 
76 /* Define what the initial system looks like.  */
77 #ifdef CTEST
test_application_define(void * first_unused_memory)78 VOID test_application_define(void *first_unused_memory)
79 #else
80 void netx_sntp_client_unicast_display_date_test_application_define(void *first_unused_memory)
81 #endif
82 {
83 
84 UINT     status;
85 UCHAR    *free_memory_pointer;
86 
87     error_counter = 0;
88 
89     free_memory_pointer = (UCHAR *)first_unused_memory;
90 
91     /* Create client packet pool. */
92     status =  nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool",
93                                     NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer,
94                                     NX_SNTP_CLIENT_PACKET_POOL_SIZE);
95     free_memory_pointer =  free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE;
96 
97     /* Check for errors. */
98     if (status != NX_SUCCESS)
99         error_counter++;
100 
101     /* Initialize the NetX system. */
102     nx_system_initialize();
103 
104 
105     /* Create Client IP instances */
106     status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS,
107                           0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500,
108                           free_memory_pointer, 2048, 1);
109     free_memory_pointer =  free_memory_pointer + 2048;
110 
111     /* Check for error. */
112     if (status != NX_SUCCESS)
113         error_counter++;
114 
115     /* Enable ARP and supply ARP cache memory. */
116     status =  nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048);
117     free_memory_pointer = free_memory_pointer + 2048;
118 
119     /* Check for error. */
120     if (status != NX_SUCCESS)
121         error_counter++;
122 
123 
124     /* Enable UDP for client. */
125     status =  nx_udp_enable(&client_ip);
126 
127     /* Check for error. */
128     if (status != NX_SUCCESS)
129         error_counter++;
130 
131     status = nx_icmp_enable(&client_ip);
132 
133     /* Check for error. */
134     if (status != NX_SUCCESS)
135         error_counter++;
136 
137     /* Create the client thread */
138     status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry,
139                               (ULONG)(&sntp_client), free_memory_pointer, 2048,
140                               4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
141     free_memory_pointer = free_memory_pointer + 2048;
142 
143     /* Check for errors */
144     if (status != TX_SUCCESS)
145         error_counter++;
146 
147     /* set the SNTP network interface to the primary interface. */
148     iface_index = 0;
149 
150     /* Create the SNTP Client to run in broadcast mode.. */
151     status =  nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool,
152                                     NX_NULL,
153                                     NX_NULL,
154                                     NX_NULL /* no random_number_generator callback */);
155 
156     /* Check for error. */
157     if (status != NX_SUCCESS)
158         error_counter++;
159 
160     tx_thread_resume(&sntp_client_thread);
161 
162     return;
163 }
164 
165 /* Define size of buffer to display client's local time. */
166 #define BUFSIZE 50
167 
168 /* If 1000 ticks per second, the precision should be 1ms. */
169 #if (NX_IP_PERIODIC_RATE == 1000)
170 #define EXPECTED_DATE0  "Mar 30, 2017 16:14:23.655 UTC "
171 #define EXPECTED_DATE1  "Mar 30, 2017 16:14:23.656 UTC "
172 #define EXPECTED_DATE2  "Mar 30, 2017 16:14:23.657 UTC "
173 #define EXPECTED_DATE3  "Mar 30, 2017 16:14:23.658 UTC "
174 #define EXPECTED_DATE4  "Mar 30, 2017 16:14:23.659 UTC "
175 #define EXPECTED_DATE5  "Mar 30, 2017 16:14:23.660 UTC "
176 #define EXPECTED_DATE6  "Mar 30, 2017 16:14:23.661 UTC "
177 #else
178 #define EXPECTED_DATE0  "Mar 30, 2017 16:14:23.655 UTC "
179 #define EXPECTED_DATE1  "Mar 30, 2017 16:14:23.665 UTC "
180 #define EXPECTED_DATE2  "Mar 30, 2017 16:14:23.675 UTC "
181 #define EXPECTED_DATE3  "Mar 30, 2017 16:14:23.685 UTC "
182 #define EXPECTED_DATE4  "Mar 30, 2017 16:14:23.695 UTC "
183 #define EXPECTED_DATE5  "Mar 30, 2017 16:14:23.705 UTC "
184 #define EXPECTED_DATE6  "Mar 30, 2017 16:14:23.715 UTC "
185 #endif
186 
187 /* Define the client thread.  */
sntp_client_thread_entry(ULONG info)188 void    sntp_client_thread_entry(ULONG info)
189 {
190 
191 UINT   status;
192 UINT   server_status;
193 CHAR   buffer[BUFSIZE];
194 ULONG  base_seconds;
195 ULONG  base_fraction;
196 ULONG  seconds, milliseconds;
197 UINT   loops;
198 UINT   display_done = NX_FALSE;
199 
200 
201     printf("NetX Test:   NETX SNTP Client Unicast Display Date Test................");
202 
203     /* Give other threads (IP instance) a chance to initialize. */
204     tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
205 
206     /* Use the IPv4 service to initialize the Client and set the IPv4 SNTP server. */
207     status = nx_sntp_client_initialize_unicast(&sntp_client, SERVER_IP_ADDRESS);
208 
209     /* Check for error. */
210     if (status != NX_SUCCESS)
211         error_counter++;
212 
213     /* Set the base time which is quite old but should suffice. */
214     base_seconds =  0xd2c96b90;  /* Jan 24, 2012 UTC */
215     base_fraction = 0xa132db1e;
216 
217 
218     /* Apply to the SNTP Client local time.  */
219     status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction);
220 
221     /* Check for error. */
222     if (status != NX_SUCCESS)
223         error_counter++;
224 
225     status = nx_sntp_client_run_unicast(&sntp_client);
226 
227     if (status != NX_SUCCESS)
228         error_counter++;
229 
230     inject_sntp_server_reply();
231     loops = 0;
232     do
233     {
234 
235         /* First verify we have a valid SNTP service running. */
236         status = nx_sntp_client_receiving_updates(&sntp_client, &server_status);
237 
238         if ((status == NX_SUCCESS) && (server_status == NX_TRUE))
239         {
240 
241             /* Server status is good. Now get the Client local time. */
242 
243             /* Display the local time in years, months, date format.  */
244             status = nx_sntp_client_get_local_time(&sntp_client, &seconds, &milliseconds, &buffer[0]);
245 
246             if (status == NX_SUCCESS)
247             {
248 
249                 status = nx_sntp_client_utility_display_date_time(&sntp_client, &buffer[0], BUFSIZE);
250 
251                 if (status != NX_SUCCESS)
252                 {
253                     error_counter++;
254                 }
255                 else
256                 {
257                    if (!memcmp(&buffer[0], EXPECTED_DATE0, strlen(EXPECTED_DATE0)) ||
258                        !memcmp(&buffer[0], EXPECTED_DATE1, strlen(EXPECTED_DATE0)) ||
259                        !memcmp(&buffer[0], EXPECTED_DATE2, strlen(EXPECTED_DATE0)) ||
260                        !memcmp(&buffer[0], EXPECTED_DATE3, strlen(EXPECTED_DATE0)) ||
261                        !memcmp(&buffer[0], EXPECTED_DATE4, strlen(EXPECTED_DATE0)) ||
262                        !memcmp(&buffer[0], EXPECTED_DATE5, strlen(EXPECTED_DATE0)) ||
263                        !memcmp(&buffer[0], EXPECTED_DATE6, strlen(EXPECTED_DATE0)))
264                     {
265 
266                         display_done = NX_TRUE;
267                         break;
268                     }
269                     else
270                     {
271 printf("date: %s.\n", buffer);
272                         error_counter++;
273                     }
274                 }
275             }
276 
277         }
278         else
279         {
280 
281             /* Wait a short bit to check again. */
282             tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
283         }
284 
285         loops++;
286 
287     } while((loops < 4) && (display_done == NX_FALSE));
288 
289     /* We can stop the SNTP service if for example we think the SNTP service has stopped. */
290     status = nx_sntp_client_stop(&sntp_client);
291 
292     if (status != NX_SUCCESS)
293         error_counter++;
294 
295     status = nx_sntp_client_delete(&sntp_client);
296 
297     if (status != NX_SUCCESS)
298         error_counter++;
299 
300     if(error_counter)
301     {
302         printf("ERROR!\n");
303         test_control_return(1);
304     }
305     else
306     {
307         printf("SUCCESS!\n");
308         test_control_return(0);
309     }
310 
311     return;
312 }
313 
314 
inject_sntp_server_reply()315 void inject_sntp_server_reply()
316 {
317 
318 UINT                    status;
319 NX_PACKET              *my_packet;
320 
321     /* Now, this packet is a received one, allocate the packet and let the IP stack receives it.  */
322     /* Allocate a packet.  */
323     status =  nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0,  5 * NX_IP_PERIODIC_RATE);
324 
325     /* Check status.  */
326     if (status != NX_SUCCESS)
327     {
328         error_counter++;
329         return;
330     }
331 
332     my_packet -> nx_packet_length = pkt_size - 14;
333     memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length);
334     my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length;
335 
336     my_packet -> nx_packet_prepend_ptr += 16;
337     my_packet -> nx_packet_append_ptr += 16;
338 
339     _nx_ip_packet_deferred_receive(&client_ip, my_packet);
340 
341 }
342 
343 #else
344 
345 #ifdef CTEST
test_application_define(void * first_unused_memory)346 VOID test_application_define(void *first_unused_memory)
347 #else
348 void    netx_sntp_client_unicast_display_date_test_application_define(void *first_unused_memory)
349 #endif
350 {
351 
352     /* Print out test information banner.  */
353     printf("NetX Test:   NETX SNTP Client Unicast Display Date Test................N/A\n");
354 
355     test_control_return(3);
356 }
357 #endif
358