1 /* This demo tests the nx_ppp_restart() function.  The PPP_1 instance is never started.
2    So PPP_0 fails to complete the LCP protocol. After so many attempts at the LCP
3    protocol, the PPP_0 should go into a FAILED state and call the link down callback.
4    NetX PPP has a restart function which reinitializes the PPP instance so it can
5    restart the PPP protocol again.
6 
7    This test runs until the second link down event occurs. This is considered a successful
8    outcome because it verifies the NetX PPP properly resets the LCP state, removes packets on
9    the receive queue, resets the buffer markers, and clears authentication status.
10 
11 */
12 
13 #include "tx_api.h"
14 #include "nx_api.h"
15 #include "nx_ppp.h"
16 
17 extern void         test_control_return(UINT status);
18 
19 #if !defined(NX_DISABLE_IPV4)
20 
21 /* Define demo stack size.   */
22 
23 #define DEMO_STACK_SIZE     2048
24 
25 
26 /* Define the ThreadX and NetX object control blocks...  */
27 
28 static TX_THREAD               thread_0;
29 static NX_PACKET_POOL          pool_0;
30 static NX_IP                   ip_0;
31 static NX_PPP                  ppp_0;
32 static NX_PPP                  ppp_1;
33 
34 
35 /* Define the counters used in the demo application...  */
36 
37 static ULONG                   ppp_0_link_up_counter;
38 static ULONG                   ppp_0_link_down_counter;
39 static ULONG                   error_counter = 0;
40 
41 /* Define thread prototypes.  */
42 static void         thread_0_entry(ULONG thread_input);
43 static void         link_up_callback(NX_PPP *ppp_ptr);
44 static void         link_down_callback(NX_PPP *ppp_ptr);
45 static void         ppp_0_serial_byte_output(UCHAR byte);
46 static void         invalid_packet_handler(NX_PACKET *packet_ptr);
47 
48 
49 /* Define what the initial system looks like.  */
50 #ifdef CTEST
test_application_define(void * first_unused_memory)51 VOID test_application_define(void *first_unused_memory)
52 #else
53 void    netx_ppp_LCP_timeout_test_application_define(void *first_unused_memory)
54 #endif
55 {
56 
57 CHAR    *pointer;
58 UINT    status;
59 
60 
61     /* Setup the working pointer.  */
62     pointer =  (CHAR *) first_unused_memory;
63 
64     /* Create the thread 0.  */
65     tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
66             pointer, DEMO_STACK_SIZE,
67             5, 5, TX_NO_TIME_SLICE, TX_AUTO_START);
68     pointer =  pointer + DEMO_STACK_SIZE;
69 
70     /* Initialize the NetX system.  */
71     nx_system_initialize();
72 
73     /* Create a packet pool.  */
74     status =  nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048);
75     pointer = pointer + 2048;
76 
77     /* Check for pool creation error.  */
78     if (status)
79         error_counter++;
80 
81     /* Create an IP instance.  */
82     status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL,
83                           &pool_0, nx_ppp_driver, pointer, 2048, 1);
84     pointer =  pointer + 2048;
85 
86     /* Check for pool creation error.  */
87     if (status)
88         error_counter++;
89 
90     /* Create the PPP instance.  */
91     status =  nx_ppp_create(&ppp_0, "PPP0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output);
92     pointer =  pointer + 2048;
93 
94     /* Check for PPP create error.   */
95     if (status)
96         error_counter++;
97 
98     /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */
99     status =  nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5));
100 
101     /* Check for PPP IP address assign error.   */
102     if (status)
103         error_counter++;
104 
105     /* Register the link up/down callbacks.  */
106     status =  nx_ppp_link_up_notify(&ppp_0, link_up_callback);
107     status += nx_ppp_link_down_notify(&ppp_0, link_down_callback);
108 
109     /* Check for PPP link up/down callback registration error(s).   */
110     if (status)
111         error_counter++;
112 
113     /* Enable UDP traffic.  */
114     nx_udp_enable(&ip_0);
115 }
116 
117 
118 /* Define the test threads.  */
119 
thread_0_entry(ULONG thread_input)120 static void    thread_0_entry(ULONG thread_input)
121 {
122 
123 UINT        status;
124 ULONG       ip_status;
125 
126 
127     /* Print out test information banner.  */
128     printf("NetX Test:   PPP LCP Timeout/Restart Test..............................");
129 
130     if (error_counter)
131     {
132         printf("ERROR\n");
133         test_control_return(1);
134     }
135 
136     do
137     {
138 
139         /* Wait for the link to come up.  */
140         status =  nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, NX_IP_PERIODIC_RATE);
141 
142         if (ppp_0_link_down_counter > 1)
143         {
144             /* Deleting the PPP_0 instance. Test is complete.  */
145             status = NX_SUCCESS;
146             break;
147         }
148     } while (status != NX_SUCCESS);
149 
150 
151     /* Check status.  */
152     if ((status) || (error_counter) || (ppp_0_link_down_counter != 2))
153     {
154         printf("ERROR!\n");
155         test_control_return(1);
156     }
157 
158     printf("SUCCESS!\n");
159     nx_ppp_delete(&ppp_0);
160     test_control_return(0);
161 
162 }
163 
164 
165 /* Define serial output routines.  Normally these routines would
166    map to physical UART routines and the nx_ppp_byte_receive call
167    would be made from a UART receive interrupt.  */
168 
ppp_0_serial_byte_output(UCHAR byte)169 static void    ppp_0_serial_byte_output(UCHAR byte)
170 {
171 
172     /* Just feed the PPP 1 input routine.  */
173     nx_ppp_byte_receive(&ppp_1, byte);
174 }
175 
176 
invalid_packet_handler(NX_PACKET * packet_ptr)177 static void invalid_packet_handler(NX_PACKET *packet_ptr)
178 {
179 
180     error_counter++;
181     nx_packet_release(packet_ptr);
182 }
183 
184 
link_up_callback(NX_PPP * ppp_ptr)185 static void link_up_callback(NX_PPP *ppp_ptr)
186 {
187 
188     /* Just increment the link up counter.  */
189     ppp_0_link_up_counter++;
190 }
191 
192 
link_down_callback(NX_PPP * ppp_ptr)193 static void link_down_callback(NX_PPP *ppp_ptr)
194 {
195 
196     /* Just increment the link down counter.  */
197     ppp_0_link_down_counter++;
198 
199     if (ppp_ptr -> nx_ppp_protocol_retry_counter != NX_PPP_MAX_LCP_PROTOCOL_RETRIES)
200     {
201         /* Error with retry counter */
202         error_counter++;
203     }
204     else if (ppp_ptr -> nx_ppp_lcp_state != NX_PPP_LCP_FAILED_STATE)
205     {
206 
207         /* Error: the PPP is not in the LCP failed state */
208         error_counter++;
209     }
210 
211     /* Restart the PPP instance.  */
212     nx_ppp_restart(ppp_ptr);
213 
214     return;
215 }
216 #else
217 
218 #ifdef CTEST
test_application_define(void * first_unused_memory)219 VOID test_application_define(void *first_unused_memory)
220 #else
221 void    netx_ppp_LCP_timeout_test_application_define(void *first_unused_memory)
222 #endif
223 {
224 
225     /* Print out test information banner.  */
226     printf("NetX Test:   PPP LCP Timeout/Restart Test..............................N/A\n");
227 
228     test_control_return(3);
229 }
230 #endif
231 
232 
233 
234