1 /* This tests the basic PPP logic with PAP authentication. */
2
3 #include "tx_api.h"
4 #include "nx_api.h"
5 #include "nx_ppp.h"
6
7 extern void test_control_return(UINT status);
8
9 #if !defined(NX_DISABLE_IPV4)
10
11 /* Define demo stack size. */
12
13 #define DEMO_STACK_SIZE 2048
14 #define DEMO_DATA "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
15
16
17 /* Define the ThreadX and NetX object control blocks... */
18
19 static TX_THREAD thread_0;
20 static TX_THREAD thread_1;
21 static NX_PACKET_POOL pool_0;
22 static NX_IP ip_0;
23 static NX_IP ip_1;
24 static NX_PPP ppp_0;
25 static NX_PPP ppp_1;
26 static NX_UDP_SOCKET socket_0;
27 static NX_UDP_SOCKET socket_1;
28
29
30 /* Define the counters used in the demo application... */
31
32 static ULONG error_counter = 0;
33 static UINT thread_1_alive = NX_TRUE;
34 static ULONG ppp_0_link_up_counter;
35 static ULONG ppp_0_link_down_counter;
36 static ULONG ppp_1_link_up_counter;
37 static ULONG ppp_1_link_down_counter;
38
39 /* Define thread prototypes. */
40 static void thread_0_entry(ULONG thread_input);
41 static void thread_1_entry(ULONG thread_input);
42 static void ppp_0_serial_byte_output(UCHAR byte);
43 static void ppp_1_serial_byte_output(UCHAR byte);
44 static void invalid_packet_handler(NX_PACKET *packet_ptr);
45 static void link_up_callback(NX_PPP *ppp_ptr);
46 static void link_down_callback(NX_PPP *ppp_ptr);
47 static UINT generate_login(CHAR *name, CHAR *password);
48 static UINT verify_login(CHAR *name, CHAR *password);
49
50
51 /* Define what the initial system looks like. */
52
53 #ifdef CTEST
test_application_define(void * first_unused_memory)54 VOID test_application_define(void *first_unused_memory)
55 #else
56 void netx_ppp_pap_basic_test_application_define(void *first_unused_memory)
57 #endif
58 {
59
60 CHAR *pointer;
61 UINT status;
62
63
64 /* Setup the working pointer. */
65 pointer = (CHAR *) first_unused_memory;
66
67 /* Create the thread 0. */
68 tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
69 pointer, DEMO_STACK_SIZE,
70 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START);
71 pointer = pointer + DEMO_STACK_SIZE;
72
73 /* Create the thread 1. */
74 tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
75 pointer, DEMO_STACK_SIZE,
76 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START);
77 pointer = pointer + DEMO_STACK_SIZE;
78
79 /* Initialize the NetX system. */
80 nx_system_initialize();
81
82 /* Create a packet pool. */
83 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 2 * NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048);
84 pointer = pointer + 2048;
85
86 /* Check for pool creation error. */
87 if (status)
88 {
89 error_counter++;
90 }
91
92 /* Create the first PPP instance. */
93 status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output);
94 pointer = pointer + 2048;
95
96 /* Check for PPP create error. */
97 if (status)
98 {
99 error_counter++;
100 }
101
102 /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */
103 status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5));
104
105 /* Check for PPP IP address assign error. */
106 if (status)
107 {
108 error_counter++;
109 }
110
111 /* Register the link up/down callbacks. */
112 status = nx_ppp_link_up_notify(&ppp_0, link_up_callback);
113 status += nx_ppp_link_down_notify(&ppp_0, link_down_callback);
114
115 /* Check for PPP link up/down callback registration error(s). */
116 if (status)
117 {
118 error_counter++;
119 }
120
121 /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */
122 status = nx_ppp_pap_enable(&ppp_0, NX_NULL, verify_login);
123
124 /* Check for PPP PAP enable error. */
125 if (status)
126 {
127 error_counter++;
128 }
129
130 /* Create an IP instance. */
131 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver,
132 pointer, 2048, 1);
133 pointer = pointer + 2048;
134
135 /* Check for IP create error. */
136 if (status)
137 {
138 error_counter++;
139 }
140
141 /* Create the next PPP instance. */
142 status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output);
143 pointer = pointer + 2048;
144
145 /* Check for PPP create error. */
146 if (status)
147 {
148 error_counter++;
149 }
150
151 /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */
152 status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0));
153
154 /* Check for PPP IP address assign error. */
155 if (status)
156 {
157 error_counter++;
158 }
159
160 /* Register the link up/down callbacks. */
161 status = nx_ppp_link_up_notify(&ppp_1, link_up_callback);
162 status += nx_ppp_link_down_notify(&ppp_1, link_down_callback);
163
164 /* Check for PPP link up/down callback registration error(s). */
165 if (status)
166 {
167 error_counter++;
168 }
169
170 /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer. */
171 status = nx_ppp_pap_enable(&ppp_1, generate_login, NX_NULL);
172
173 /* Check for PPP PAP enable error. */
174 if (status)
175 {
176 error_counter++;
177 }
178
179 /* Create another IP instance. */
180 status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver,
181 pointer, 2048, 1);
182 pointer = pointer + 2048;
183
184 /* Check for IP create error. */
185 if (status)
186 {
187 error_counter++;
188 }
189
190 /* Enable UDP traffic. */
191 status = nx_udp_enable(&ip_0);
192 status += nx_udp_enable(&ip_1);
193 if (status)
194 {
195 error_counter++;
196 }
197 }
198
199
200 /* Define the test threads. */
201
thread_0_entry(ULONG thread_input)202 void thread_0_entry(ULONG thread_input)
203 {
204
205 UINT status;
206 ULONG ip_status;
207 NX_PACKET *my_packet;
208
209
210 printf("NetX Test: PPP PAP Basic Test........................................");
211
212 if (error_counter)
213 {
214
215 printf("ERROR!\n");
216 test_control_return(1);
217 }
218
219 /* Wait for the link to come up. */
220 do
221 {
222
223 status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE);
224 }while(status != NX_SUCCESS);
225
226 /* Create a UDP socket. */
227 status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
228
229 /* Check status. */
230 if (status)
231 {
232 error_counter++;
233 }
234
235 /* Bind the UDP socket to the IP port. */
236 status = nx_udp_socket_bind(&socket_0, 0x88, NX_WAIT_FOREVER);
237
238 /* Check status. */
239 if (status)
240 {
241 error_counter++;
242 }
243
244 /* Disable checksum logic for this socket. */
245 nx_udp_socket_checksum_disable(&socket_0);
246
247 /* Let receiver thread run. */
248 tx_thread_relinquish();
249
250 /* Allocate a packet. */
251 status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER);
252
253 /* Check status. */
254 if (status != NX_SUCCESS)
255 {
256 error_counter++;
257 }
258
259 /* Write ABCs into the packet payload! */
260 nx_packet_data_append(my_packet, DEMO_DATA, sizeof(DEMO_DATA), &pool_0, NX_WAIT_FOREVER);
261
262 /* Send the UDP packet. */
263 status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89);
264
265 /* Check status. */
266 if (status != NX_SUCCESS)
267 {
268 error_counter++;
269 }
270
271 /* Relinquish to thread 1. */
272 tx_thread_relinquish();
273
274 /* Wait for the other thread to finish. */
275 while(thread_1_alive)
276 {
277 tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
278 }
279
280 /* Receive a UDP packet. */
281 status = nx_udp_socket_receive(&socket_0, &my_packet, 5 * NX_IP_PERIODIC_RATE);
282
283 /* Check status. */
284 if (status != NX_SUCCESS)
285 {
286 error_counter++;
287 }
288 else
289 {
290
291 /* Check the echo data. */
292 if (memcmp(my_packet -> nx_packet_prepend_ptr, DEMO_DATA, sizeof(DEMO_DATA)) != 0)
293 {
294 error_counter++;
295 }
296
297 /* Release the packet. */
298 status = nx_packet_release(my_packet);
299
300 /* Check status. */
301 if (status != NX_SUCCESS)
302 {
303 error_counter++;
304 }
305 }
306
307 if (error_counter)
308 {
309 printf("ERROR!\n");
310 test_control_return(1);
311 }
312 else
313 {
314 printf("SUCCESS!\n");
315 test_control_return(0);
316 }
317 }
318
thread_1_entry(ULONG thread_input)319 void thread_1_entry(ULONG thread_input)
320 {
321
322 UINT status;
323 ULONG ip_status;
324 NX_PACKET *my_packet;
325
326
327 /* Wait for the link to come up. */
328 do
329 {
330
331 status = nx_ip_status_check(&ip_1, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE);
332 }while(status != NX_SUCCESS);
333
334 /* Create a UDP socket. */
335 status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
336
337 /* Check status. */
338 if (status)
339 {
340 error_counter++;
341 thread_1_alive = NX_FALSE;
342 return;
343 }
344
345 /* Bind the UDP socket to the IP port. */
346 status = nx_udp_socket_bind(&socket_1, 0x89, NX_WAIT_FOREVER);
347
348 /* Check status. */
349 if (status)
350 {
351 error_counter++;
352 thread_1_alive = NX_FALSE;
353 return;
354 }
355
356 /* Receive a UDP packet. */
357 status = nx_udp_socket_receive(&socket_1, &my_packet, 5 * NX_IP_PERIODIC_RATE);
358
359 /* Check status. */
360 if (status != NX_SUCCESS)
361 {
362 error_counter++;
363 thread_1_alive = NX_FALSE;
364 return;
365 }
366
367 /* Send the UDP packet. */
368 status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(1, 2, 3, 4), 0x88);
369
370 /* Check status. */
371 if (status != NX_SUCCESS)
372 {
373 error_counter++;
374
375 /* Release the packet. */
376 status = nx_packet_release(my_packet);
377
378 /* Check status. */
379 if (status != NX_SUCCESS)
380 {
381 error_counter++;
382 thread_1_alive = NX_FALSE;
383 return;
384 }
385 }
386
387 thread_1_alive = NX_FALSE;
388
389 return;
390
391 }
392
393 /* Define serial output routines. Normally these routines would
394 map to physical UART routines and the nx_ppp_byte_receive call
395 would be made from a UART receive interrupt. */
396
ppp_0_serial_byte_output(UCHAR byte)397 static void ppp_0_serial_byte_output(UCHAR byte)
398 {
399
400 /* Just feed the PPP 1 input routine. */
401 nx_ppp_byte_receive(&ppp_1, byte);
402 }
403
ppp_1_serial_byte_output(UCHAR byte)404 static void ppp_1_serial_byte_output(UCHAR byte)
405 {
406
407 /* Just feed the PPP 0 input routine. */
408 nx_ppp_byte_receive(&ppp_0, byte);
409 }
410
invalid_packet_handler(NX_PACKET * packet_ptr)411 static void invalid_packet_handler(NX_PACKET *packet_ptr)
412 {
413 /* Print out the non-PPP byte. In Windows, the string "CLIENT" will
414 be sent before Windows PPP starts. Once CLIENT is received, we need
415 to send "CLIENTSERVER" to establish communication. It's also possible
416 to receive modem commands here that might need some response to
417 continue. */
418 nx_packet_release(packet_ptr);
419 }
420
link_up_callback(NX_PPP * ppp_ptr)421 static void link_up_callback(NX_PPP *ppp_ptr)
422 {
423
424 /* Just increment the link up counter. */
425 if (ppp_ptr == &ppp_0)
426 ppp_0_link_up_counter++;
427 else
428 ppp_1_link_up_counter++;
429 }
430
link_down_callback(NX_PPP * ppp_ptr)431 static void link_down_callback(NX_PPP *ppp_ptr)
432 {
433
434 /* Just increment the link down counter. */
435 if (ppp_ptr == &ppp_0)
436 ppp_0_link_down_counter++;
437 else
438 ppp_1_link_down_counter++;
439
440 /* Restart the PPP instance. */
441 nx_ppp_restart(ppp_ptr);
442 }
443
generate_login(CHAR * name,CHAR * password)444 static UINT generate_login(CHAR *name, CHAR *password)
445 {
446
447 /* Make a name and password, called "myname" and "mypassword". */
448 name[0] = 'm';
449 name[1] = 'y';
450 name[2] = 'n';
451 name[3] = 'a';
452 name[4] = 'm';
453 name[5] = 'e';
454 name[6] = (CHAR) 0;
455
456 password[0] = 'm';
457 password[1] = 'y';
458 password[2] = 'p';
459 password[3] = 'a';
460 password[4] = 's';
461 password[5] = 's';
462 password[6] = 'w';
463 password[7] = 'o';
464 password[8] = 'r';
465 password[9] = 'd';
466 password[10] = (CHAR) 0;
467
468 return(NX_SUCCESS);
469 }
470
verify_login(CHAR * name,CHAR * password)471 static UINT verify_login(CHAR *name, CHAR *password)
472 {
473
474 if ((name[0] == 'm') &&
475 (name[1] == 'y') &&
476 (name[2] == 'n') &&
477 (name[3] == 'a') &&
478 (name[4] == 'm') &&
479 (name[5] == 'e') &&
480 (name[6] == (CHAR) 0) &&
481 (password[0] == 'm') &&
482 (password[1] == 'y') &&
483 (password[2] == 'p') &&
484 (password[3] == 'a') &&
485 (password[4] == 's') &&
486 (password[5] == 's') &&
487 (password[6] == 'w') &&
488 (password[7] == 'o') &&
489 (password[8] == 'r') &&
490 (password[9] == 'd') &&
491 (password[10] == (CHAR) 0))
492 return(NX_SUCCESS);
493 else
494 return(NX_PPP_ERROR);
495 }
496 #else
497
498 #ifdef CTEST
test_application_define(void * first_unused_memory)499 VOID test_application_define(void *first_unused_memory)
500 #else
501 void netx_ppp_pap_basic_test_application_define(void *first_unused_memory)
502 #endif
503 {
504
505 /* Print out test information banner. */
506 printf("NetX Test: PPP PAP Basic Test........................................N/A\n");
507
508 test_control_return(3);
509 }
510 #endif
511
512