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
7 #if !defined(NX_DISABLE_IPV4)
8
9 /* Define SNTP packet size. */
10 #define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100)
11
12 /* Define SNTP packet pool size. */
13 #define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET)))
14
15 /* NTP server reply. */
16 static char pkt_data[90] = {
17 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c,
18 0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00, 0x45, 0x00,
19 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
20 0xbc, 0xa3, 0xc0, 0xa8, 0x7e, 0x82, 0xc0, 0xa8,
21 0x7e, 0x2a, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38,
22 0x7f, 0xa0, 0x1c, 0x02, 0x00, 0xec, 0x00, 0x00,
23 0x07, 0xdd, 0x00, 0x00, 0x06, 0x6e, 0x89, 0xbd,
24 0x04, 0x0a, 0xd6, 0x4b, 0xd7, 0xeb, 0xb3, 0x25,
25 0xe0, 0x52, 0xd2, 0xc9, 0x6b, 0x90, 0xa1, 0x32,
26 0xdb, 0x1e, 0xd6, 0x4b, 0xd8, 0x5b, 0x20, 0x27,
27 0x62, 0xa4, 0xd6, 0x4b, 0xd8, 0x5b, 0x20, 0x2c,
28 0x4b, 0x46 };
29
30 static UINT pkt_size = 90;
31
32 static ULONG expected_seconds = 0xd64bd85b;
33 static ULONG expected_milliseconds = 0x88;
34 static ULONG tolerance_milliseconds = 200;
35
36 extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr);
37
38 /* Set up client thread and network resources. */
39
40 static NX_PACKET_POOL client_packet_pool;
41 static NX_IP client_ip;
42 static TX_THREAD sntp_client_thread;
43 static NX_SNTP_CLIENT sntp_client;
44
45
46 #define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42)
47 #define SERVER_IP_ADDRESS IP_ADDRESS(192,168,126,130)
48 #define SERVER_IP_ADDRESS_2 SERVER_IP_ADDRESS
49
50 /* Set up the SNTP network and address index; */
51 static UINT iface_index;
52
53 static UINT error_counter;
54
55 /* Set up client thread entry point. */
56 static void sntp_client_thread_entry(ULONG info);
57
58 static void inject_sntp_server_reply();
59
60 /* Define what the initial system looks like. */
61 #ifdef CTEST
test_application_define(void * first_unused_memory)62 VOID test_application_define(void *first_unused_memory)
63 #else
64 void netx_sntp_client_unicast_basic_test_application_define(void *first_unused_memory)
65 #endif
66 {
67
68 UINT status;
69 UCHAR *free_memory_pointer;
70
71 error_counter = 0;
72
73 free_memory_pointer = (UCHAR *)first_unused_memory;
74
75 /* Create client packet pool. */
76 status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool",
77 NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer,
78 NX_SNTP_CLIENT_PACKET_POOL_SIZE);
79 free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE;
80
81 /* Check for errors. */
82 if (status != NX_SUCCESS)
83 error_counter++;
84
85 /* Initialize the NetX system. */
86 nx_system_initialize();
87
88
89 /* Create Client IP instances */
90 status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS,
91 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500,
92 free_memory_pointer, 2048, 1);
93 free_memory_pointer = free_memory_pointer + 2048;
94
95 /* Check for error. */
96 if (status != NX_SUCCESS)
97 error_counter++;
98
99 /* Enable ARP and supply ARP cache memory. */
100 status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048);
101 free_memory_pointer = free_memory_pointer + 2048;
102
103 /* Check for error. */
104 if (status != NX_SUCCESS)
105 error_counter++;
106
107
108 /* Enable UDP for client. */
109 status = nx_udp_enable(&client_ip);
110
111 /* Check for error. */
112 if (status != NX_SUCCESS)
113 error_counter++;
114
115 status = nx_icmp_enable(&client_ip);
116
117 /* Check for error. */
118 if (status != NX_SUCCESS)
119 error_counter++;
120
121 /* Create the client thread */
122 status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry,
123 (ULONG)(&sntp_client), free_memory_pointer, 2048,
124 4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
125 free_memory_pointer = free_memory_pointer + 2048;
126
127 /* Check for errors */
128 if (status != TX_SUCCESS)
129 error_counter++;
130
131 /* set the SNTP network interface to the primary interface. */
132 iface_index = 0;
133
134 /* Create the SNTP Client to run in broadcast mode.. */
135 status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool,
136 NX_NULL,
137 NX_NULL,
138 NX_NULL /* no random_number_generator callback */);
139
140 /* Check for error. */
141 if (status != NX_SUCCESS)
142 error_counter++;
143
144 tx_thread_resume(&sntp_client_thread);
145
146 return;
147 }
148
149 /* Define size of buffer to display client's local time. */
150 #define BUFSIZE 50
151
152 /* Define the client thread. */
sntp_client_thread_entry(ULONG info)153 void sntp_client_thread_entry(ULONG info)
154 {
155
156 UINT status;
157 UINT spin;
158 UINT server_status;
159 CHAR buffer[BUFSIZE];
160 ULONG base_seconds;
161 ULONG base_fraction;
162 ULONG seconds, milliseconds, microseconds, fraction;
163 ULONG expected_fraction;
164
165 printf("NetX Test: NETX SNTP Client Unicast Basic Test.......................");
166
167 status = nx_sntp_client_delete(&sntp_client);
168
169 /* Check for error. */
170 if (status != NX_SUCCESS)
171 error_counter++;
172
173 /* Create the SNTP Client to run in broadcast mode.. */
174 status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool,
175 NX_NULL,
176 NX_NULL,
177 NX_NULL /* no random_number_generator callback */);
178
179 /* Check for error. */
180 if (status != NX_SUCCESS)
181 error_counter++;
182
183 /* Give other threads (IP instance) a chance to initialize. */
184 tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
185
186 /* Use the IPv4 service to initialize the Client and set the IPv4 SNTP server. */
187 status = nx_sntp_client_initialize_unicast(&sntp_client, SERVER_IP_ADDRESS);
188
189 /* Check for error. */
190 if (status != NX_SUCCESS)
191 error_counter++;
192
193 /* Set the base time which is approximately the number of seconds since the turn of the last century. */
194 base_seconds = 0xd2c96b90; /* Jan 24, 2012 UTC */
195 base_fraction = 0xa132db1e;
196
197 /* Apply to the SNTP Client local time. */
198 status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction);
199
200 /* Check for error. */
201 if (status != NX_SUCCESS)
202 error_counter++;
203
204 status = nx_sntp_client_run_unicast(&sntp_client);
205
206 if (status != NX_SUCCESS)
207 error_counter++;
208
209 inject_sntp_server_reply();
210
211 spin = NX_TRUE;
212
213 /* Now check periodically for time changes. */
214 while(spin)
215 {
216
217 /* First verify we have a valid SNTP service running. */
218 status = nx_sntp_client_receiving_updates(&sntp_client, &server_status);
219
220 if ((status == NX_SUCCESS) && (server_status == NX_TRUE))
221 {
222
223 /* Server status is good. Now get the Client local time. */
224
225 /* Display the local time in years, months, date format. */
226 status = nx_sntp_client_get_local_time(&sntp_client, &seconds, &fraction, &buffer[0]);
227
228 /* Convert fraction to microseconds. */
229 nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds);
230
231 milliseconds = ((microseconds + 500) / 1000);
232
233 if (status == NX_SUCCESS)
234 {
235 if ((seconds == expected_seconds) && ((INT)milliseconds > (INT)(expected_milliseconds - tolerance_milliseconds)) &&
236 (milliseconds < (expected_milliseconds + tolerance_milliseconds)))
237 {
238
239 /* Get extended local time. */
240 status = nx_sntp_client_get_local_time_extended(&sntp_client, &seconds, &fraction, &buffer[0], sizeof(buffer));
241 if (status == NX_SUCCESS)
242 {
243
244 /* Convert fraction to microseconds. */
245 nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds);
246
247 /* Compare microseconds with milliseconds. */
248 if (((microseconds + 500) / 1000) != milliseconds)
249 {
250 error_counter++;
251 }
252
253 /* Convert microseconds to fraction. */
254 nx_sntp_client_utility_usecs_to_fraction(microseconds, &expected_fraction);
255
256 /* Compare expected_fraction with fraction. */
257 if (expected_fraction != fraction)
258 {
259 error_counter++;
260 }
261 }
262 else
263 {
264 error_counter++;
265 }
266 break;
267 }
268 else
269 {
270 error_counter++;
271 break;
272 }
273 }
274
275 }
276 else
277 {
278
279 /* Wait a short bit to check again. */
280 tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
281 }
282 }
283
284 /* We can stop the SNTP service if for example we think the SNTP service has stopped. */
285 status = nx_sntp_client_stop(&sntp_client);
286
287 if (status != NX_SUCCESS)
288 error_counter++;
289
290 status = nx_sntp_client_delete(&sntp_client);
291
292 if (status != NX_SUCCESS)
293 error_counter++;
294
295 if(error_counter)
296 {
297 printf("ERROR!\n");
298 test_control_return(1);
299 }
300 else
301 {
302 printf("SUCCESS!\n");
303 test_control_return(0);
304 }
305
306 return;
307 }
308
309
inject_sntp_server_reply()310 void inject_sntp_server_reply()
311 {
312
313 UINT status;
314 NX_PACKET *my_packet;
315
316 /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */
317 /* Allocate a packet. */
318 status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 5 * NX_IP_PERIODIC_RATE);
319
320 /* Check status. */
321 if (status != NX_SUCCESS)
322 {
323 error_counter++;
324 return;
325 }
326
327 my_packet -> nx_packet_length = pkt_size - 14;
328 memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length);
329 my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length;
330
331 my_packet -> nx_packet_prepend_ptr += 16;
332 my_packet -> nx_packet_append_ptr += 16;
333
334 _nx_ip_packet_deferred_receive(&client_ip, my_packet);
335
336 }
337 #else
338
339 #ifdef CTEST
test_application_define(void * first_unused_memory)340 VOID test_application_define(void *first_unused_memory)
341 #else
342 void netx_sntp_client_unicast_basic_test_application_define(void *first_unused_memory)
343 #endif
344 {
345
346 /* Print out test information banner. */
347 printf("NetX Test: NETX SNTP Client Unicast Basic Test.......................N/A\n");
348
349 test_control_return(3);
350 }
351 #endif
352