Mercurial > templog
comparison network/PPP.c @ 110:4eb5a746d7af avr-http
Import avrusbmodem code minus the USB bits. Not built yet.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 15 Sep 2012 21:49:05 +0800 |
parents | 56d09a0969b5 |
children |
comparison
equal
deleted
inserted
replaced
109:315850d48eec | 110:4eb5a746d7af |
---|---|
1 /* | |
2 LUFA Powered Wireless 3G Modem Host | |
3 | |
4 Copyright (C) Mike Alexander, 2010. | |
5 Copyright (C) Dean Camera, 2010. | |
6 */ | |
7 | |
8 /* | |
9 Copyright 2010 Mike Alexander (mike [at] mikealex [dot] com) | |
10 Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) | |
11 | |
12 Permission to use, copy, modify, distribute, and sell this | |
13 software and its documentation for any purpose is hereby granted | |
14 without fee, provided that the above copyright notice appear in | |
15 all copies and that both that the copyright notice and this | |
16 permission notice and warranty disclaimer appear in supporting | |
17 documentation, and that the name of the author not be used in | |
18 advertising or publicity pertaining to distribution of the | |
19 software without specific, written prior permission. | |
20 | |
21 The author disclaim all warranties with regard to this | |
22 software, including all implied warranties of merchantability | |
23 and fitness. In no event shall the author be liable for any | |
24 special, indirect or consequential damages or any damages | |
25 whatsoever resulting from loss of use, data or profits, whether | |
26 in an action of contract, negligence or other tortious action, | |
27 arising out of or in connection with the use or performance of | |
28 this software. | |
29 */ | |
30 | |
31 #define INCLUDE_FROM_PPP_C | |
32 #include "PPP.h" | |
33 | |
34 static uint8_t OutgoingPacketID; // Unique packet ID | |
35 static PPP_Phases_t PPP_Phase; // PPP negotiation phases | |
36 static PPP_States_t LCP_State; // Each phase has a number of states | |
37 static PPP_States_t PAP_State; | |
38 static PPP_States_t IPCP_State; | |
39 static PPP_Packet_t* OutgoingPacket; // Pointer to the outgoing packet | |
40 static PPP_Packet_t* IncomingPacket; // Pointer to the incoming packet | |
41 static uint16_t CurrentProtocol; // Type of the last received packet | |
42 static uint8_t RestartCount; | |
43 static uint16_t LinkTimer; | |
44 static bool TimerOn; | |
45 static bool MarkForNAK; | |
46 static bool MarkForREJ; | |
47 static uint8_t OutgoingPacketBuffer[OUTGOING_PACKET_BUFFER_SIZE]; // Buffer to store the outgoing packet in | |
48 | |
49 PPP_Packet_t* dummy; | |
50 | |
51 | |
52 void PPP_InitPPP(void) | |
53 { | |
54 PPP_Phase = PPP_PHASE_Dead; | |
55 TimerOn = false; | |
56 } | |
57 | |
58 void PPP_StartLink(void) | |
59 { | |
60 OutgoingPacket = NULL; | |
61 CurrentProtocol = NONE; | |
62 TimerOn = false; | |
63 LinkTimer = 0; | |
64 uip_len = 0; | |
65 RestartCount = MAX_RESTARTS; | |
66 MarkForNAK = MarkForREJ = false; | |
67 OutgoingPacketID = -1; | |
68 OutgoingPacket = IncomingPacket = NULL; | |
69 LCP_State = PPP_STATE_Initial; | |
70 PAP_State = PPP_STATE_Initial; | |
71 IPCP_State = PPP_STATE_Initial; | |
72 PPP_Phase = PPP_PHASE_Establish; | |
73 PPP_ManageState(PPP_EVENT_Open, &LCP_State, PPP_LAYER_Physical); | |
74 PPP_ManageState(PPP_EVENT_Up, &LCP_State, PPP_LAYER_Physical); | |
75 } | |
76 | |
77 // Called every 10ms. Send events to the state machine every 3 seconds if the timer is currently running | |
78 void PPP_LinkTimer(void) | |
79 { | |
80 if (!TimerOn || LinkTimer++ < 300) | |
81 return; | |
82 | |
83 if (RestartCount > 0) | |
84 { | |
85 Debug_Print("Timer+\r\n"); | |
86 | |
87 switch(PPP_Phase) | |
88 { | |
89 case PPP_PHASE_Establish: | |
90 PPP_ManageState(PPP_EVENT_TOPlus, &LCP_State, PPP_LAYER_Physical); | |
91 break; | |
92 | |
93 case PPP_PHASE_Authenticate: | |
94 PPP_ManageState(PPP_EVENT_TOPlus, &PAP_State, PPP_LAYER_Authentication); | |
95 break; | |
96 | |
97 case PPP_PHASE_Network: | |
98 PPP_ManageState(PPP_EVENT_TOPlus, &IPCP_State, PPP_LAYER_Network); | |
99 break; | |
100 | |
101 default: | |
102 break; | |
103 } | |
104 } | |
105 else | |
106 { | |
107 Debug_Print("Timer-\r\n"); | |
108 | |
109 switch(PPP_Phase) | |
110 { | |
111 case PPP_PHASE_Establish: | |
112 PPP_ManageState(PPP_EVENT_TOMinus, &LCP_State, PPP_LAYER_Physical); | |
113 break; | |
114 | |
115 case PPP_PHASE_Authenticate: | |
116 PPP_ManageState(PPP_EVENT_TOMinus, &PAP_State, PPP_LAYER_Authentication); | |
117 break; | |
118 | |
119 case PPP_PHASE_Network: | |
120 PPP_ManageState(PPP_EVENT_TOMinus, &IPCP_State, PPP_LAYER_Network); | |
121 break; | |
122 | |
123 default: | |
124 break; | |
125 } | |
126 } | |
127 | |
128 LinkTimer = 0; // Reset Timer | |
129 } | |
130 | |
131 void PPP_ManageLink(void) | |
132 { | |
133 if (PPP_Phase == PPP_PHASE_Dead) | |
134 return; | |
135 | |
136 uint16_t ReadProtocol = network_read(); // Don't mess with CurrentProtocol in case we get 0 (No data) back | |
137 | |
138 if (ReadProtocol == 0) | |
139 return; | |
140 | |
141 CurrentProtocol = ReadProtocol; | |
142 IncomingPacket = (PPP_Packet_t*)uip_buf; // Map the incoming data to a packet | |
143 | |
144 Debug_Print("Got "); | |
145 | |
146 switch (CurrentProtocol) | |
147 { | |
148 case LCP: | |
149 Debug_Print("LCP "); | |
150 | |
151 switch(IncomingPacket->Code) | |
152 { | |
153 case REQ: | |
154 Debug_Print("REQ\r\n"); | |
155 | |
156 MarkForNAK = MarkForREJ = false; | |
157 | |
158 // List of options that we can support. If any other options come in, we have to REJ them | |
159 const uint8_t SupportedOptions[] = {LCP_OPTION_Maximum_Receive_Unit, | |
160 LCP_OPTION_Magic_Number, | |
161 LCP_OPTION_Async_Control_Character_Map, | |
162 LCP_OPTION_Authentication_Protocol, | |
163 LCP_OPTION_Protocol_Field_Compression, | |
164 LCP_OPTION_Address_and_Control_Field_Compression}; | |
165 | |
166 if ((MarkForREJ = PPP_TestForREJ(SupportedOptions, sizeof(SupportedOptions)))) // Check that we can support all the options the other end wants to use | |
167 { | |
168 PPP_ManageState(PPP_EVENT_RCRMinus, &LCP_State, PPP_LAYER_Physical); | |
169 break; | |
170 } | |
171 | |
172 static PPP_Option_t Option3 = {.Type = 0x03, .Length = 4, .Data = {0xc0, 0x23}}; | |
173 | |
174 if ((MarkForNAK = PPP_TestForNAK(&Option3))) // Check that the authentication protocol = PAP (0xc023) | |
175 { | |
176 PPP_ManageState(PPP_EVENT_RCRMinus, &LCP_State, PPP_LAYER_Physical); | |
177 break; | |
178 } | |
179 | |
180 PPP_ManageState(PPP_EVENT_RCRPlus, &LCP_State, PPP_LAYER_Physical); | |
181 break; | |
182 | |
183 case ACK: | |
184 Debug_Print("ACK\r\n"); | |
185 | |
186 if (IncomingPacket->PacketID != OutgoingPacketID) | |
187 { | |
188 Debug_Print("Out of sync\r\n"); | |
189 break; | |
190 } | |
191 | |
192 PPP_ManageState(PPP_EVENT_RCA, &LCP_State, PPP_LAYER_Physical); | |
193 break; | |
194 | |
195 case NAK: | |
196 Debug_Print("NAK\r\n"); | |
197 | |
198 if (IncomingPacket->PacketID != OutgoingPacketID) | |
199 { | |
200 Debug_Print("Out of sync\r\n"); | |
201 break; | |
202 } | |
203 | |
204 PPP_ProcessNAK(); | |
205 PPP_ManageState(PPP_EVENT_RCN, &LCP_State, PPP_LAYER_Physical); | |
206 break; | |
207 | |
208 case REJ: | |
209 Debug_Print("REJ\r\n"); | |
210 | |
211 if (IncomingPacket->PacketID != OutgoingPacketID) | |
212 { | |
213 Debug_Print("Out of sync\r\n"); | |
214 break; | |
215 } | |
216 | |
217 PPP_ProcessREJ(); | |
218 PPP_ManageState(PPP_EVENT_RCN, &LCP_State, PPP_LAYER_Physical); | |
219 break; | |
220 | |
221 case DISC: | |
222 case ECHOREQ: | |
223 case ECHOREPLY: | |
224 Debug_Print("DISC\r\n"); | |
225 PPP_ManageState(PPP_EVENT_RXR, &LCP_State, PPP_LAYER_Physical); | |
226 break; | |
227 | |
228 case TERMREQ: | |
229 Debug_Print("TERM\r\n"); | |
230 PPP_ManageState(PPP_EVENT_RTR, &LCP_State, PPP_LAYER_Physical); | |
231 break; | |
232 | |
233 case CODEREJ: | |
234 case PROTREJ: | |
235 Debug_Print("CODE/PROTREJ\r\n"); | |
236 PPP_ManageState(PPP_EVENT_RXJMinus, &LCP_State, PPP_LAYER_Physical); | |
237 break; | |
238 | |
239 default: | |
240 Debug_Print("unknown\r\n"); | |
241 PPP_ManageState(PPP_EVENT_RUC, &LCP_State, PPP_LAYER_Physical); | |
242 break; | |
243 } | |
244 break; | |
245 | |
246 case PAP: | |
247 Debug_Print("PAP "); | |
248 | |
249 switch(IncomingPacket->Code) | |
250 { | |
251 case REQ: | |
252 Debug_Print("REQ\r\n"); | |
253 PPP_ManageState(PPP_EVENT_RCRPlus, &PAP_State, PPP_LAYER_Authentication); | |
254 break; | |
255 | |
256 case ACK: | |
257 Debug_Print("ACK\r\n"); | |
258 PPP_ManageState(PPP_EVENT_RCRPlus, &PAP_State, PPP_LAYER_Authentication); // The host never sends a Configure request for PAP, but we need it to move the state machine to completion. So, fake it. | |
259 PPP_ManageState(PPP_EVENT_RCA, &PAP_State, PPP_LAYER_Authentication); | |
260 break; | |
261 } | |
262 break; | |
263 | |
264 case IPCP: | |
265 Debug_Print("IPCP "); | |
266 | |
267 switch(IncomingPacket->Code) | |
268 { | |
269 case REQ: | |
270 Debug_Print("REQ\r\n"); | |
271 | |
272 MarkForNAK = MarkForREJ = false; | |
273 | |
274 // List of options that we can support. If any other options come in, we have to REJ them | |
275 uint8_t SupportedOptions[] = {IPCP_OPTION_IP_address, IPCP_OPTION_Primary_DNS, IPCP_OPTION_Secondary_DNS}; | |
276 | |
277 if ((MarkForREJ = PPP_TestForREJ(SupportedOptions, sizeof(SupportedOptions)))) | |
278 { | |
279 PPP_ManageState(PPP_EVENT_RCRMinus, &IPCP_State, PPP_LAYER_Network); | |
280 break; | |
281 } | |
282 | |
283 PPP_ManageState(PPP_EVENT_RCRPlus, &IPCP_State, PPP_LAYER_Network); | |
284 break; | |
285 | |
286 case ACK: | |
287 Debug_Print("ACK\r\n"); | |
288 | |
289 if (IncomingPacket->PacketID != OutgoingPacketID) | |
290 { | |
291 Debug_Print("Out of sync\r\n"); | |
292 break; | |
293 } | |
294 | |
295 IPAddr1 = IncomingPacket->Options[0].Data[0]; // Store address for use in IP packets. | |
296 IPAddr2 = IncomingPacket->Options[0].Data[1]; // Assumption is that Option 3 is the first option, which it | |
297 IPAddr3 = IncomingPacket->Options[0].Data[2]; // should be as the PPP spec states that implementations should | |
298 IPAddr4 = IncomingPacket->Options[0].Data[3]; // not reorder packets, and we sent out a REQ with option 3 first | |
299 | |
300 PPP_ManageState(PPP_EVENT_RCA, &IPCP_State, PPP_LAYER_Network); | |
301 break; | |
302 | |
303 case NAK: | |
304 Debug_Print("NAK\r\n"); | |
305 if (IncomingPacket->PacketID != OutgoingPacketID) | |
306 { | |
307 Debug_Print("Out of sync\r\n"); | |
308 break; | |
309 } | |
310 | |
311 PPP_ProcessNAK(); | |
312 PPP_ManageState(PPP_EVENT_RCN, &IPCP_State, PPP_LAYER_Network); | |
313 break; | |
314 | |
315 case REJ: | |
316 Debug_Print("REJ\r\n"); | |
317 | |
318 if (IncomingPacket->PacketID != OutgoingPacketID) | |
319 { | |
320 Debug_Print("Out of sync\r\n"); | |
321 break; | |
322 } | |
323 | |
324 PPP_ProcessREJ(); | |
325 PPP_ManageState(PPP_EVENT_RCN, &IPCP_State, PPP_LAYER_Network); | |
326 break; | |
327 } | |
328 break; | |
329 | |
330 case IP: | |
331 TCPIP_GotNewPacket(); | |
332 break; | |
333 | |
334 default: | |
335 Debug_Print("unknown protocol: 0x"); | |
336 Debug_PrintHex(CurrentProtocol / 256); Debug_PrintHex(CurrentProtocol & 255); | |
337 Debug_Print("\r\n"); | |
338 break; | |
339 } | |
340 } | |
341 | |
342 | |
343 // Either create a new OutgoingPacket, or if we've just received a NAK or REJ we will have already changed the OutgoingPacket so just send that | |
344 static void Send_Configure_Request(void) | |
345 { | |
346 Debug_Print("Send Configure Request\r\n"); | |
347 | |
348 switch(PPP_Phase) | |
349 { | |
350 case PPP_PHASE_Establish: | |
351 if (OutgoingPacket == NULL) // Create a new packet | |
352 { | |
353 // When we send a REQ, we want to make sure that the other end supports these options | |
354 // static PPP_Option_t Option1 = {.Type = LCP_OPTION_Maximum_Receive_Unit, .Length = 4, .Data = {0x5, 0xa0}}; | |
355 static PPP_Option_t Option2 = {.Type = LCP_OPTION_Async_Control_Character_Map, .Length = 6, .Data = {0x0, 0x0, 0x0, 0x0}}; | |
356 static PPP_Option_t Option5 = {.Type = LCP_OPTION_Magic_Number, .Length = 6, .Data = {0x27, 0xf5, 0x46, 0xa1}}; | |
357 static PPP_Option_t Option7 = {.Type = LCP_OPTION_Protocol_Field_Compression, .Length = 2}; | |
358 static PPP_Option_t Option8 = {.Type = LCP_OPTION_Address_and_Control_Field_Compression, .Length = 2}; | |
359 static PPP_Option_t OptionD = {.Type = LCP_OPTION_Callback, .Length = 3, .Data = {0x6}}; | |
360 | |
361 //PPP_AddOption(OutgoingPacket, &Option1); | |
362 PPP_AddOption(&Option2); | |
363 PPP_AddOption(&Option5); | |
364 PPP_AddOption(&Option7); | |
365 PPP_AddOption(&Option8); | |
366 PPP_AddOption(&OptionD); | |
367 OutgoingPacket->Code = REQ; | |
368 CurrentProtocol = LCP; | |
369 } | |
370 break; | |
371 | |
372 case PPP_PHASE_Authenticate: | |
373 if (OutgoingPacket == NULL) // Create a new packet | |
374 { | |
375 static PPP_Option_t Option0 = {.Type = 0x00, .Length = 2}; | |
376 | |
377 PPP_AddOption(&Option0); | |
378 OutgoingPacket->Options[0].Type = 0x00; // No User Name | |
379 OutgoingPacket->Options[0].Length = 0x00; // No Password | |
380 OutgoingPacket->Code = REQ; | |
381 CurrentProtocol = PAP; | |
382 } | |
383 break; | |
384 | |
385 case PPP_PHASE_Network: | |
386 if (OutgoingPacket == NULL) // Create a new packet | |
387 { | |
388 // When we send a REQ, we want to make sure that the other end supports these options | |
389 static PPP_Option_t Option3 = {.Type = IPCP_OPTION_IP_address, .Length = 6, .Data = {0, 0, 0, 0}}; | |
390 static PPP_Option_t Option81 = {.Type = IPCP_OPTION_Primary_DNS, .Length = 6, .Data = {0, 0, 0, 0}}; | |
391 static PPP_Option_t Option83 = {.Type = IPCP_OPTION_Secondary_DNS, .Length = 6, .Data = {0, 0, 0, 0}}; | |
392 | |
393 PPP_AddOption(&Option3); // Make sure Option3 is first | |
394 PPP_AddOption(&Option81); | |
395 PPP_AddOption(&Option83); | |
396 OutgoingPacket->Code = REQ; | |
397 CurrentProtocol = IPCP; | |
398 } | |
399 break; | |
400 | |
401 default: | |
402 break; | |
403 } | |
404 | |
405 OutgoingPacket->PacketID = ++OutgoingPacketID; // Every new REQ Packet going out gets a new ID | |
406 RestartCount--; // Decrement the count before we restart the layer | |
407 uip_len = uip_ntohs(OutgoingPacket->Length); | |
408 memcpy(uip_buf, OutgoingPacket, uip_len); // Copy the outgoing packet to the buffer for sending | |
409 | |
410 network_send(CurrentProtocol); // Send either the new packet or the modified packet | |
411 } | |
412 | |
413 | |
414 // We change the incoming packet code to send an ACK to the remote end, and re-use all the data from the incoming packet | |
415 static void Send_Configure_Ack(void) | |
416 { | |
417 Debug_Print("Send Configure ACK\r\n"); | |
418 | |
419 IncomingPacket->Code = ACK; | |
420 network_send(CurrentProtocol); | |
421 } | |
422 | |
423 // We change the incoming packet code to send a NAK or REJ to the remote end. The incoming packet has already been altered to show which options to NAK/REJ | |
424 static void Send_Configure_Nak_Rej(void) | |
425 { | |
426 if (MarkForNAK) | |
427 { | |
428 Debug_Print("Send Configure NAK\r\n"); | |
429 IncomingPacket->Code = NAK; | |
430 } | |
431 else if (MarkForREJ) | |
432 { | |
433 Debug_Print("Send Configure REJ\r\n"); | |
434 IncomingPacket->Code = REJ; | |
435 } | |
436 else | |
437 { | |
438 return; | |
439 } | |
440 | |
441 uip_len = uip_ntohs(IncomingPacket->Length); | |
442 network_send(CurrentProtocol); | |
443 } | |
444 | |
445 // Send a TERM to the remote end. | |
446 static void Send_Terminate_Request(void) | |
447 { | |
448 Debug_Print("Send Terminate Request\r\n"); | |
449 | |
450 OutgoingPacket = (PPP_Packet_t*)uip_buf; // Build the outgoing packet in uip_buf | |
451 CurrentProtocol = LCP; | |
452 OutgoingPacket->Code = TERMREQ; | |
453 OutgoingPacket->Length = UIP_HTONS(sizeof(PPP_Packet_t)); | |
454 OutgoingPacket->PacketID = ++OutgoingPacketID; // Every new REQ Packet going out gets a new ID | |
455 | |
456 RestartCount--; | |
457 | |
458 uip_len = uip_ntohs(OutgoingPacket->Length); | |
459 network_send(CurrentProtocol); // Send the packet | |
460 } | |
461 | |
462 // Send a TERM ACK to the remote end. | |
463 static void Send_Terminate_Ack(void) | |
464 { | |
465 Debug_Print("Send Terminate ACK\r\n"); | |
466 | |
467 IncomingPacket->Code = TERMREPLY; | |
468 network_send(CurrentProtocol); | |
469 } | |
470 | |
471 // Send a REJ to the remote end. | |
472 static void Send_Code_Reject(void) | |
473 { | |
474 Debug_Print("Send Code Reject\r\n"); | |
475 | |
476 IncomingPacket->Code = CODEREJ; | |
477 network_send(CurrentProtocol); | |
478 } | |
479 | |
480 // Send an ECHO to the remote end. | |
481 static void Send_Echo_Reply(void) | |
482 { | |
483 Debug_Print("Send Echo Reply\r\n"); | |
484 | |
485 IncomingPacket->Code = ECHOREPLY; | |
486 network_send(CurrentProtocol); | |
487 } | |
488 | |
489 // Called by the state machine when the current layer comes up. Use this to start the next layer up. | |
490 static void This_Layer_Up(PPP_Layers_t Layer) | |
491 { | |
492 CurrentProtocol = NONE; | |
493 OutgoingPacket = NULL; // Clear the outgoing packet | |
494 | |
495 switch(Layer) | |
496 { | |
497 case PPP_LAYER_Physical: | |
498 Debug_Print("**LCP Up**\r\n"); | |
499 PPP_Phase = PPP_PHASE_Authenticate; | |
500 OutgoingPacketID = -1; | |
501 PPP_ManageState(PPP_EVENT_Open, &PAP_State, PPP_LAYER_Authentication); | |
502 PPP_ManageState(PPP_EVENT_Up, &PAP_State, PPP_LAYER_Authentication); | |
503 break; | |
504 | |
505 case PPP_LAYER_Authentication: | |
506 Debug_Print("**PAP Up**\r\n"); | |
507 PPP_Phase = PPP_PHASE_Network; | |
508 OutgoingPacketID = -1; | |
509 PPP_ManageState(PPP_EVENT_Open, &IPCP_State, PPP_LAYER_Network); | |
510 PPP_ManageState(PPP_EVENT_Up, &IPCP_State, PPP_LAYER_Network); | |
511 break; | |
512 | |
513 case PPP_LAYER_Network: | |
514 Debug_Print("**IPCP Up**\r\n"); | |
515 ConnectedState = LINKMANAGEMENT_STATE_InitializeTCPStack; | |
516 break; | |
517 | |
518 default: | |
519 break; | |
520 } | |
521 } | |
522 | |
523 // Called by the state machine when a layer goes down. Use this to stop the next layer up | |
524 static void This_Layer_Down(PPP_Layers_t Layer) | |
525 { | |
526 OutgoingPacket = NULL; // Clear the outgoing packet | |
527 | |
528 switch(Layer) | |
529 { | |
530 case PPP_LAYER_Physical: | |
531 Debug_Print("**LCP Down**\r\n"); | |
532 PPP_ManageState(PPP_EVENT_Down, &PAP_State, PPP_LAYER_Authentication); | |
533 PPP_Phase = PPP_PHASE_Establish; | |
534 break; | |
535 | |
536 case PPP_LAYER_Authentication: | |
537 Debug_Print("**PAP Down**\r\n"); | |
538 PPP_ManageState(PPP_EVENT_Down, &IPCP_State, PPP_LAYER_Network); | |
539 break; | |
540 | |
541 case PPP_LAYER_Network: | |
542 Debug_Print("**IPCP Down**\r\n"); | |
543 break; | |
544 | |
545 default: | |
546 break; | |
547 } | |
548 } | |
549 | |
550 // Called by the state machine when the current layer starts | |
551 static void This_Layer_Started(PPP_Layers_t Layer) | |
552 { | |
553 switch(Layer) | |
554 { | |
555 case PPP_LAYER_Physical: | |
556 Debug_Print("**LCP Started**\r\n"); | |
557 break; | |
558 | |
559 case PPP_LAYER_Authentication: | |
560 Debug_Print("**PAP Started**\r\n"); | |
561 break; | |
562 | |
563 case PPP_LAYER_Network: | |
564 Debug_Print("**IPCP Started**\r\n"); | |
565 break; | |
566 | |
567 default: | |
568 break; | |
569 } | |
570 } | |
571 | |
572 // Called by the state machine when the current layer finishes | |
573 static void This_Layer_Finished(PPP_Layers_t Layer) | |
574 { | |
575 switch(Layer) | |
576 { | |
577 case PPP_LAYER_Physical: | |
578 Debug_Print("**LCP Finished**\r\n"); | |
579 break; | |
580 | |
581 case PPP_LAYER_Authentication: | |
582 Debug_Print("**PAP Finished**\r\n"); | |
583 break; | |
584 | |
585 case PPP_LAYER_Network: | |
586 Debug_Print("**IPCP Finished**\r\n"); | |
587 break; | |
588 | |
589 default: | |
590 break; | |
591 } | |
592 | |
593 Debug_Print("**Rebooting**\r\n"); | |
594 Reboot(); | |
595 } | |
596 | |
597 | |
598 // We get a NAK if our outbound Configure Request contains valid options, but the values are wrong. So we adjust our values for when the next Configure Request is sent | |
599 static void PPP_ProcessNAK(void) | |
600 { | |
601 PPP_Option_t* CurrentOption = NULL; | |
602 | |
603 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) // Scan options in NAK packet | |
604 { | |
605 if (PPP_CheckForOption(CurrentOption)) | |
606 PPP_ChangeOption(OutgoingPacket, CurrentOption); // If the NAK'd option is already in the outgoing packet then change the existing option | |
607 else | |
608 PPP_AddOption(CurrentOption); // Otherwise add it | |
609 } | |
610 } | |
611 | |
612 // We get a REJ if our outbound Configure Request contains any options not acceptable to the remote end. So we remove those options. | |
613 static void PPP_ProcessREJ(void) | |
614 { | |
615 PPP_Option_t* CurrentOption = NULL; | |
616 | |
617 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) // Scan options in REJ packet | |
618 PPP_RemoveOption(OutgoingPacket, CurrentOption->Type); // Remove the options(s) we don't want | |
619 } | |
620 | |
621 // Test to see if the incoming packet contains any options we can't support If so, take out all good options and leave the bad ones to be sent out in the REJ | |
622 static bool PPP_TestForREJ(const uint8_t Options[], | |
623 const uint8_t NumOptions) | |
624 { | |
625 PPP_Option_t* CurrentOption = NULL; | |
626 bool FoundBadOption = false; | |
627 bool ThisOptionOK; | |
628 | |
629 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) // Scan incoming options | |
630 { | |
631 ThisOptionOK = false; | |
632 | |
633 for (uint8_t i = 0; i < NumOptions; i++) | |
634 { | |
635 if (CurrentOption->Type == Options[i]) | |
636 { | |
637 ThisOptionOK = true; | |
638 break; | |
639 } | |
640 } | |
641 | |
642 if (!ThisOptionOK) | |
643 FoundBadOption = true; | |
644 } | |
645 | |
646 if (!FoundBadOption) // No bad options. Return, leaving the packet untouched | |
647 return false; | |
648 | |
649 // We found some bad options, so now we need to go through the packet and remove all others, leaving the bad options to be sent out in the REJ | |
650 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) | |
651 { | |
652 for (uint8_t i = 0; i < NumOptions; i++) | |
653 { | |
654 if (CurrentOption->Type == Options[i]) | |
655 { | |
656 PPP_RemoveOption(IncomingPacket, CurrentOption->Type); | |
657 CurrentOption = NULL; // Start again. Easier than moving back (as next option has now moved into place of current option) | |
658 break; | |
659 } | |
660 } | |
661 } | |
662 | |
663 return true; | |
664 } | |
665 | |
666 // Test to see if the incoming packet contains an option with values that we can't accept | |
667 static bool PPP_TestForNAK(const PPP_Option_t* const Option) | |
668 { | |
669 PPP_Option_t* CurrentOption = NULL; | |
670 bool FoundBadOption = false; | |
671 | |
672 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) // Scan options in receiver buffer | |
673 { | |
674 if (CurrentOption->Type == Option->Type) | |
675 { | |
676 for (uint8_t i = 0; i < Option->Length - 2; i++) | |
677 { | |
678 if (CurrentOption->Data[i] != Option->Data[i]) | |
679 FoundBadOption = true; | |
680 } | |
681 } | |
682 } | |
683 | |
684 if (!FoundBadOption) // No bad option. Return, leaving the packet untouched | |
685 return false; | |
686 | |
687 // We found a bad option, so now we need to go through the packet and remove all others, leaving the bad option to be sent out in the NAK | |
688 // and change the bad option to have a value that we can support | |
689 while ((CurrentOption = PPP_GetNextOption(IncomingPacket, CurrentOption)) != NULL) | |
690 { | |
691 if (CurrentOption->Type == Option->Type) | |
692 { | |
693 PPP_ChangeOption(IncomingPacket, Option); | |
694 } | |
695 else | |
696 { | |
697 PPP_RemoveOption(IncomingPacket, CurrentOption->Type); | |
698 CurrentOption = NULL; // Start again. Easier than moving back (as next option has now moved into place of current option) | |
699 } | |
700 } | |
701 | |
702 return true; | |
703 } | |
704 | |
705 | |
706 ///////////////////////////// | |
707 // Packet Helper functions // | |
708 ///////////////////////////// | |
709 | |
710 // Check if the given option is in the outgoing packet | |
711 static bool PPP_CheckForOption(const PPP_Option_t* const Option) | |
712 { | |
713 PPP_Option_t* CurrentOption = NULL; | |
714 | |
715 while ((CurrentOption = PPP_GetNextOption(OutgoingPacket, CurrentOption)) != NULL) // Scan options in the packet | |
716 { | |
717 if (CurrentOption->Type == Option->Type) | |
718 return true; | |
719 } | |
720 | |
721 return false; | |
722 } | |
723 | |
724 // Add the given option to the end of the outgoing packet and adjust the size of the packet | |
725 static void PPP_AddOption(const PPP_Option_t* const Option) | |
726 { | |
727 uint16_t OldPacketLength, NewPacketLength; | |
728 | |
729 if (OutgoingPacket == NULL) | |
730 { | |
731 OutgoingPacket = (PPP_Packet_t*)&OutgoingPacketBuffer; | |
732 OldPacketLength = sizeof(PPP_Packet_t); // If we're creating a new empty packet | |
733 } | |
734 else | |
735 OldPacketLength = uip_ntohs(OutgoingPacket->Length); // If the packet already exists | |
736 | |
737 NewPacketLength = OldPacketLength + Option->Length; | |
738 | |
739 if (NewPacketLength > OUTGOING_PACKET_BUFFER_SIZE) | |
740 { | |
741 Debug_Print("*** Packet overflow ***\r\n"); | |
742 return; | |
743 } | |
744 | |
745 memcpy((void*)OutgoingPacket + OldPacketLength, Option, Option->Length); // Add the new option | |
746 | |
747 OutgoingPacket->Length = uip_htons(NewPacketLength); | |
748 } | |
749 | |
750 // Try and find the option in the packet, and if it exists, change its value to that in the passed-in option (assumes the option lengths are the same) | |
751 static void PPP_ChangeOption(PPP_Packet_t* const ThisPacket, | |
752 const PPP_Option_t* const Option) | |
753 { | |
754 PPP_Option_t* CurrentOption = NULL; | |
755 | |
756 while ((CurrentOption = PPP_GetNextOption(ThisPacket, CurrentOption)) != NULL) // Scan options in the packet | |
757 { | |
758 if (CurrentOption->Type == Option->Type) | |
759 memcpy(CurrentOption->Data, Option->Data, Option->Length - 2); // Copy the data portion of the option (not Type or Length) | |
760 } | |
761 } | |
762 | |
763 // Try and find the option in the packet, and if it exists remove it and adjust the size of the packet | |
764 static void PPP_RemoveOption(PPP_Packet_t* const ThisPacket, | |
765 const uint8_t Type) | |
766 { | |
767 PPP_Option_t* CurrentOption = NULL; | |
768 PPP_Option_t* NextOption = NULL; | |
769 | |
770 while ((CurrentOption = PPP_GetNextOption(ThisPacket, CurrentOption)) != NULL) // Scan the options in the packet | |
771 { | |
772 if (CurrentOption->Type == Type) // Is it the packet we want to remove? | |
773 { | |
774 NextOption = PPP_GetNextOption(ThisPacket, CurrentOption); // Find the next option in the packet | |
775 uint8_t OptionLength = CurrentOption->Length; // Save the Option Length as the memcpy will change CurrentOption->Length | |
776 | |
777 if (NextOption != NULL) // If it's not the last option in the packet ... | |
778 { | |
779 uint16_t LenToCopy = uip_ntohs(ThisPacket->Length) - ((void*)CurrentOption - (void*)ThisPacket) - OptionLength; | |
780 memcpy(CurrentOption, NextOption, LenToCopy); // ... move all further options forward | |
781 } | |
782 | |
783 ThisPacket->Length = uip_htons(uip_ntohs(ThisPacket->Length) - OptionLength); // Adjust the length | |
784 } | |
785 } | |
786 } | |
787 | |
788 // Get the next option in the packet from the option that is passed in. Return NULL if last packet | |
789 static PPP_Option_t* PPP_GetNextOption(const PPP_Packet_t* const ThisPacket, | |
790 const PPP_Option_t* const CurrentOption) | |
791 { | |
792 PPP_Option_t* NextOption; | |
793 | |
794 if (CurrentOption == NULL) | |
795 NextOption = (PPP_Option_t*)ThisPacket->Options; // First option | |
796 else | |
797 NextOption = (PPP_Option_t*)((uint8_t*)CurrentOption + CurrentOption->Length); | |
798 | |
799 // Check that we haven't overrun the end of the packet | |
800 if (((void*)NextOption - (void*)ThisPacket->Options) < (uip_ntohs(ThisPacket->Length) - 4)) | |
801 return NextOption; | |
802 else | |
803 return NULL; | |
804 } | |
805 | |
806 | |
807 | |
808 ///////////////////////////////////////////////////////////////////////////////////////// | |
809 // The main PPP state machine - following RFC1661 - http://tools.ietf.org/html/rfc1661 // | |
810 ///////////////////////////////////////////////////////////////////////////////////////// | |
811 | |
812 static void PPP_ManageState(const PPP_Events_t Event, | |
813 PPP_States_t* const State, | |
814 PPP_Layers_t const Layer) | |
815 { | |
816 switch (*State) | |
817 { | |
818 case PPP_STATE_Initial: | |
819 | |
820 switch (Event) | |
821 { | |
822 case PPP_EVENT_Up: | |
823 *State = PPP_STATE_Closed; | |
824 break; | |
825 | |
826 case PPP_EVENT_Open: | |
827 *State = PPP_STATE_Starting; | |
828 This_Layer_Started(Layer); | |
829 break; | |
830 | |
831 case PPP_EVENT_Close: | |
832 *State = PPP_STATE_Initial; | |
833 break; | |
834 | |
835 case PPP_EVENT_TOPlus: | |
836 case PPP_EVENT_TOMinus: | |
837 break; | |
838 | |
839 default: | |
840 Debug_Print("Illegal Event\r\n"); | |
841 break; | |
842 } | |
843 break; | |
844 | |
845 case PPP_STATE_Starting: | |
846 | |
847 switch (Event) | |
848 { | |
849 case PPP_EVENT_Up: | |
850 *State = PPP_STATE_Req_Sent; | |
851 RestartCount = MAX_RESTARTS; | |
852 LinkTimer = 0; | |
853 TimerOn = true; | |
854 Send_Configure_Request(); | |
855 break; | |
856 | |
857 case PPP_EVENT_Open: | |
858 *State = PPP_STATE_Starting; | |
859 break; | |
860 | |
861 case PPP_EVENT_Close: | |
862 *State = PPP_STATE_Initial; | |
863 This_Layer_Finished(Layer); | |
864 break; | |
865 | |
866 case PPP_EVENT_TOPlus: | |
867 case PPP_EVENT_TOMinus: | |
868 break; | |
869 | |
870 default: | |
871 Debug_Print("Illegal Event\r\n"); | |
872 break; | |
873 } | |
874 break; | |
875 | |
876 case PPP_STATE_Closed: | |
877 | |
878 switch (Event) | |
879 { | |
880 case PPP_EVENT_Down: | |
881 *State = PPP_STATE_Initial; | |
882 break; | |
883 | |
884 case PPP_EVENT_Open: | |
885 *State = PPP_STATE_Req_Sent; | |
886 RestartCount = MAX_RESTARTS; | |
887 LinkTimer = 0; | |
888 TimerOn = true; | |
889 Send_Configure_Request(); | |
890 break; | |
891 | |
892 case PPP_EVENT_Close: | |
893 case PPP_EVENT_RTA: | |
894 case PPP_EVENT_RXJPlus: | |
895 case PPP_EVENT_RXR: | |
896 *State = PPP_STATE_Closed; | |
897 break; | |
898 | |
899 case PPP_EVENT_RCRPlus: | |
900 case PPP_EVENT_RCRMinus: | |
901 case PPP_EVENT_RCA: | |
902 case PPP_EVENT_RCN: | |
903 *State = PPP_STATE_Closed; | |
904 Send_Terminate_Ack(); | |
905 break; | |
906 | |
907 case PPP_EVENT_TOPlus: | |
908 case PPP_EVENT_TOMinus: | |
909 break; | |
910 | |
911 default: | |
912 Debug_Print("Illegal Event\r\n"); | |
913 break; | |
914 } | |
915 break; | |
916 | |
917 case PPP_STATE_Stopped: | |
918 | |
919 switch (Event) | |
920 { | |
921 case PPP_EVENT_Down: | |
922 *State = PPP_STATE_Starting; | |
923 This_Layer_Started(Layer); | |
924 break; | |
925 | |
926 case PPP_EVENT_Open: | |
927 *State = PPP_STATE_Stopped; | |
928 break; | |
929 | |
930 case PPP_EVENT_Close: | |
931 *State = PPP_STATE_Closed; | |
932 break; | |
933 | |
934 case PPP_EVENT_RCRPlus: | |
935 *State = PPP_STATE_Ack_Sent; | |
936 RestartCount = MAX_RESTARTS; | |
937 LinkTimer = 0; | |
938 TimerOn = true; | |
939 Send_Configure_Request(); | |
940 Send_Configure_Ack(); | |
941 break; | |
942 | |
943 case PPP_EVENT_RCRMinus: | |
944 *State = PPP_STATE_Req_Sent; | |
945 RestartCount = MAX_RESTARTS; | |
946 LinkTimer = 0; | |
947 TimerOn = true; | |
948 Send_Configure_Request(); | |
949 Send_Configure_Nak_Rej(); | |
950 break; | |
951 | |
952 case PPP_EVENT_RCA: | |
953 case PPP_EVENT_RCN: | |
954 case PPP_EVENT_RTR: | |
955 *State = PPP_STATE_Stopped; | |
956 Send_Terminate_Ack(); | |
957 break; | |
958 | |
959 case PPP_EVENT_RTA: | |
960 case PPP_EVENT_RXJPlus: | |
961 case PPP_EVENT_RXR: | |
962 *State = PPP_STATE_Stopped; | |
963 break; | |
964 | |
965 case PPP_EVENT_RUC: | |
966 *State = PPP_STATE_Stopped; | |
967 Send_Code_Reject(); | |
968 break; | |
969 | |
970 case PPP_EVENT_RXJMinus: | |
971 *State = PPP_STATE_Stopped; | |
972 This_Layer_Finished(Layer); | |
973 break; | |
974 | |
975 case PPP_EVENT_TOPlus: | |
976 case PPP_EVENT_TOMinus: | |
977 break; | |
978 | |
979 default: | |
980 Debug_Print("Illegal Event\r\n"); | |
981 break; | |
982 } | |
983 break; | |
984 | |
985 case PPP_STATE_Closing: | |
986 | |
987 switch (Event) | |
988 { | |
989 case PPP_EVENT_Down: | |
990 TimerOn = false; | |
991 *State = PPP_STATE_Initial; | |
992 break; | |
993 | |
994 case PPP_EVENT_Open: | |
995 *State = PPP_STATE_Stopping; | |
996 break; | |
997 | |
998 case PPP_EVENT_Close: | |
999 *State = PPP_STATE_Closing; | |
1000 break; | |
1001 | |
1002 case PPP_EVENT_TOPlus: | |
1003 Send_Terminate_Request(); | |
1004 *State = PPP_STATE_Closing; | |
1005 break; | |
1006 | |
1007 case PPP_EVENT_TOMinus: | |
1008 *State = PPP_STATE_Closed; | |
1009 TimerOn = false; | |
1010 This_Layer_Finished(Layer); | |
1011 break; | |
1012 | |
1013 case PPP_EVENT_RCRPlus: | |
1014 case PPP_EVENT_RCRMinus: | |
1015 case PPP_EVENT_RCA: | |
1016 case PPP_EVENT_RCN: | |
1017 case PPP_EVENT_RXJPlus: | |
1018 case PPP_EVENT_RXR: | |
1019 *State = PPP_STATE_Closing; | |
1020 break; | |
1021 | |
1022 case PPP_EVENT_RTR: | |
1023 *State = PPP_STATE_Closing; | |
1024 Send_Terminate_Ack(); | |
1025 break; | |
1026 | |
1027 case PPP_EVENT_RTA: | |
1028 case PPP_EVENT_RXJMinus: | |
1029 *State = PPP_STATE_Closed; | |
1030 TimerOn = false; | |
1031 This_Layer_Finished(Layer); | |
1032 break; | |
1033 | |
1034 case PPP_EVENT_RUC: | |
1035 *State = PPP_STATE_Closing; | |
1036 Send_Code_Reject(); | |
1037 break; | |
1038 | |
1039 default: | |
1040 Debug_Print("Illegal Event\r\n"); | |
1041 break; | |
1042 } | |
1043 break; | |
1044 | |
1045 case PPP_STATE_Stopping: | |
1046 | |
1047 switch (Event) | |
1048 { | |
1049 case PPP_EVENT_Down: | |
1050 *State = PPP_STATE_Starting; | |
1051 TimerOn = false; | |
1052 break; | |
1053 | |
1054 case PPP_EVENT_Open: | |
1055 *State = PPP_STATE_Stopping; | |
1056 break; | |
1057 | |
1058 case PPP_EVENT_Close: | |
1059 *State = PPP_STATE_Closing; | |
1060 break; | |
1061 | |
1062 case PPP_EVENT_TOPlus: | |
1063 Send_Terminate_Request(); | |
1064 *State = PPP_STATE_Stopping; | |
1065 break; | |
1066 | |
1067 case PPP_EVENT_TOMinus: | |
1068 This_Layer_Finished(Layer); | |
1069 TimerOn = false; | |
1070 *State = PPP_STATE_Stopped; | |
1071 break; | |
1072 | |
1073 case PPP_EVENT_RCRPlus: | |
1074 case PPP_EVENT_RCRMinus: | |
1075 case PPP_EVENT_RCA: | |
1076 case PPP_EVENT_RCN: | |
1077 case PPP_EVENT_RXJPlus: | |
1078 case PPP_EVENT_RXR: | |
1079 *State = PPP_STATE_Stopping; | |
1080 break; | |
1081 | |
1082 case PPP_EVENT_RTR: | |
1083 Send_Terminate_Ack(); | |
1084 *State = PPP_STATE_Stopping; | |
1085 break; | |
1086 | |
1087 case PPP_EVENT_RTA: | |
1088 case PPP_EVENT_RXJMinus: | |
1089 This_Layer_Finished(Layer); | |
1090 TimerOn = false; | |
1091 *State = PPP_STATE_Stopped; | |
1092 break; | |
1093 | |
1094 case PPP_EVENT_RUC: | |
1095 Send_Code_Reject(); | |
1096 *State = PPP_STATE_Stopping; | |
1097 break; | |
1098 | |
1099 default: | |
1100 Debug_Print("Illegal Event\r\n"); | |
1101 break; | |
1102 } | |
1103 break; | |
1104 | |
1105 case PPP_STATE_Req_Sent: | |
1106 | |
1107 switch (Event) | |
1108 { | |
1109 case PPP_EVENT_Down: | |
1110 *State = PPP_STATE_Starting; | |
1111 TimerOn = false; | |
1112 break; | |
1113 | |
1114 case PPP_EVENT_Open: | |
1115 case PPP_EVENT_RTA: | |
1116 case PPP_EVENT_RXJPlus: | |
1117 case PPP_EVENT_RXR: | |
1118 *State = PPP_STATE_Req_Sent; | |
1119 break; | |
1120 | |
1121 case PPP_EVENT_Close: | |
1122 RestartCount = MAX_RESTARTS; | |
1123 LinkTimer = 0; | |
1124 Send_Terminate_Request(); | |
1125 *State = PPP_STATE_Closing; | |
1126 break; | |
1127 | |
1128 case PPP_EVENT_TOPlus: | |
1129 Send_Configure_Request(); | |
1130 *State = PPP_STATE_Req_Sent; | |
1131 break; | |
1132 | |
1133 case PPP_EVENT_TOMinus: | |
1134 This_Layer_Finished(Layer); | |
1135 TimerOn = false; | |
1136 *State = PPP_STATE_Stopped; | |
1137 break; | |
1138 | |
1139 case PPP_EVENT_RCRPlus: | |
1140 if (Layer != PPP_LAYER_Authentication) // We faked a Configure request for PAP. So no need to answer it if we're in the authentication phase | |
1141 Send_Configure_Ack(); | |
1142 | |
1143 *State = PPP_STATE_Ack_Sent; | |
1144 break; | |
1145 | |
1146 case PPP_EVENT_RCRMinus: | |
1147 Send_Configure_Nak_Rej(); | |
1148 *State = PPP_STATE_Req_Sent; | |
1149 break; | |
1150 | |
1151 case PPP_EVENT_RCA: | |
1152 RestartCount = MAX_RESTARTS; | |
1153 LinkTimer = 0; | |
1154 *State = PPP_STATE_Ack_Rcvd; | |
1155 break; | |
1156 | |
1157 case PPP_EVENT_RCN: | |
1158 RestartCount = MAX_RESTARTS; | |
1159 LinkTimer = 0; | |
1160 Send_Configure_Request(); | |
1161 *State = PPP_STATE_Req_Sent; | |
1162 break; | |
1163 | |
1164 case PPP_EVENT_RTR: | |
1165 Send_Terminate_Ack(); | |
1166 *State = PPP_STATE_Req_Sent; | |
1167 break; | |
1168 | |
1169 case PPP_EVENT_RUC: | |
1170 Send_Code_Reject(); | |
1171 *State = PPP_STATE_Req_Sent; | |
1172 break; | |
1173 | |
1174 case PPP_EVENT_RXJMinus: | |
1175 This_Layer_Finished(Layer); | |
1176 TimerOn = false; | |
1177 *State = PPP_STATE_Stopped; | |
1178 break; | |
1179 | |
1180 default: | |
1181 Debug_Print("Illegal Event\r\n"); | |
1182 break; | |
1183 } | |
1184 break; | |
1185 | |
1186 case PPP_STATE_Ack_Rcvd: | |
1187 | |
1188 switch (Event) | |
1189 { | |
1190 case PPP_EVENT_Down: | |
1191 *State = PPP_STATE_Starting; | |
1192 TimerOn = false; | |
1193 break; | |
1194 | |
1195 case PPP_EVENT_Open: | |
1196 case PPP_EVENT_RXR: | |
1197 *State = PPP_STATE_Ack_Rcvd; | |
1198 break; | |
1199 | |
1200 case PPP_EVENT_Close: | |
1201 RestartCount = MAX_RESTARTS; | |
1202 LinkTimer = 0; | |
1203 Send_Terminate_Request(); | |
1204 *State = PPP_STATE_Closing; | |
1205 break; | |
1206 | |
1207 case PPP_EVENT_TOPlus: | |
1208 case PPP_EVENT_RCA: | |
1209 case PPP_EVENT_RCN: | |
1210 Send_Configure_Request(); | |
1211 *State = PPP_STATE_Req_Sent; | |
1212 break; | |
1213 | |
1214 case PPP_EVENT_TOMinus: | |
1215 This_Layer_Finished(Layer); | |
1216 TimerOn = false; | |
1217 *State = PPP_STATE_Stopped; | |
1218 break; | |
1219 | |
1220 case PPP_EVENT_RCRPlus: | |
1221 Send_Configure_Ack(); | |
1222 This_Layer_Up(Layer); | |
1223 TimerOn = false; | |
1224 *State = PPP_STATE_Opened; | |
1225 break; | |
1226 | |
1227 case PPP_EVENT_RCRMinus: | |
1228 Send_Configure_Nak_Rej(); | |
1229 *State = PPP_STATE_Ack_Rcvd; | |
1230 break; | |
1231 | |
1232 case PPP_EVENT_RTR: | |
1233 Send_Terminate_Ack(); | |
1234 *State = PPP_STATE_Req_Sent; | |
1235 break; | |
1236 | |
1237 case PPP_EVENT_RTA: | |
1238 case PPP_EVENT_RXJPlus: | |
1239 Send_Terminate_Ack(); | |
1240 *State = PPP_STATE_Req_Sent; | |
1241 break; | |
1242 | |
1243 case PPP_EVENT_RUC: | |
1244 Send_Code_Reject(); | |
1245 *State = PPP_STATE_Ack_Rcvd; | |
1246 break; | |
1247 | |
1248 case PPP_EVENT_RXJMinus: | |
1249 This_Layer_Finished(Layer); | |
1250 TimerOn = false; | |
1251 *State = PPP_STATE_Stopped; | |
1252 break; | |
1253 | |
1254 default: | |
1255 Debug_Print("Illegal Event\r\n"); | |
1256 break; | |
1257 } | |
1258 break; | |
1259 | |
1260 case PPP_STATE_Ack_Sent: | |
1261 | |
1262 switch (Event) | |
1263 { | |
1264 case PPP_EVENT_Down: | |
1265 *State = PPP_STATE_Starting; | |
1266 TimerOn = false; | |
1267 break; | |
1268 | |
1269 case PPP_EVENT_Open: | |
1270 case PPP_EVENT_RTA: | |
1271 case PPP_EVENT_RXJPlus: | |
1272 case PPP_EVENT_RXR: | |
1273 *State = PPP_STATE_Ack_Sent; | |
1274 break; | |
1275 | |
1276 case PPP_EVENT_Close: | |
1277 RestartCount = MAX_RESTARTS; | |
1278 LinkTimer = 0; | |
1279 Send_Terminate_Request(); | |
1280 *State = PPP_STATE_Closing; | |
1281 break; | |
1282 | |
1283 case PPP_EVENT_TOPlus: | |
1284 Send_Configure_Request(); | |
1285 *State = PPP_STATE_Ack_Sent; | |
1286 break; | |
1287 | |
1288 case PPP_EVENT_TOMinus: | |
1289 This_Layer_Finished(Layer); | |
1290 TimerOn = false; | |
1291 *State = PPP_STATE_Stopped; | |
1292 break; | |
1293 | |
1294 case PPP_EVENT_RCRPlus: | |
1295 Send_Configure_Ack(); | |
1296 *State = PPP_STATE_Ack_Sent; | |
1297 break; | |
1298 | |
1299 case PPP_EVENT_RCRMinus: | |
1300 Send_Configure_Nak_Rej(); | |
1301 *State = PPP_STATE_Req_Sent; | |
1302 break; | |
1303 | |
1304 case PPP_EVENT_RCA: | |
1305 RestartCount = MAX_RESTARTS; | |
1306 LinkTimer = 0; | |
1307 TimerOn = false; | |
1308 This_Layer_Up(Layer); | |
1309 *State = PPP_STATE_Opened; | |
1310 break; | |
1311 | |
1312 case PPP_EVENT_RCN: | |
1313 RestartCount = MAX_RESTARTS; | |
1314 LinkTimer = 0; | |
1315 Send_Configure_Request(); | |
1316 *State = PPP_STATE_Ack_Sent; | |
1317 break; | |
1318 | |
1319 case PPP_EVENT_RTR: | |
1320 Send_Terminate_Ack(); | |
1321 *State = PPP_STATE_Req_Sent; | |
1322 break; | |
1323 | |
1324 case PPP_EVENT_RUC: | |
1325 Send_Code_Reject(); | |
1326 *State = PPP_STATE_Ack_Sent; | |
1327 break; | |
1328 | |
1329 case PPP_EVENT_RXJMinus: | |
1330 This_Layer_Finished(Layer); | |
1331 TimerOn = false; | |
1332 *State = PPP_STATE_Stopped; | |
1333 break; | |
1334 | |
1335 default: | |
1336 Debug_Print("Illegal Event\r\n"); | |
1337 break; | |
1338 } | |
1339 break; | |
1340 | |
1341 case PPP_STATE_Opened: | |
1342 | |
1343 switch (Event) | |
1344 { | |
1345 case PPP_EVENT_Down: | |
1346 This_Layer_Down(Layer); | |
1347 *State = PPP_STATE_Starting; | |
1348 break; | |
1349 | |
1350 case PPP_EVENT_Open: | |
1351 case PPP_EVENT_RXJPlus: | |
1352 *State = PPP_STATE_Opened; | |
1353 break; | |
1354 | |
1355 case PPP_EVENT_Close: | |
1356 This_Layer_Down(Layer); | |
1357 RestartCount = MAX_RESTARTS; | |
1358 LinkTimer = 0; | |
1359 TimerOn = true; | |
1360 Send_Terminate_Request(); | |
1361 *State = PPP_STATE_Closing; | |
1362 break; | |
1363 | |
1364 case PPP_EVENT_RCRPlus: | |
1365 This_Layer_Down(Layer); | |
1366 TimerOn = true; | |
1367 Send_Configure_Request(); | |
1368 Send_Configure_Ack(); | |
1369 *State = PPP_STATE_Ack_Sent; | |
1370 break; | |
1371 | |
1372 case PPP_EVENT_RCRMinus: | |
1373 This_Layer_Down(Layer); | |
1374 TimerOn = true; | |
1375 Send_Configure_Request(); | |
1376 Send_Configure_Nak_Rej(); | |
1377 *State = PPP_STATE_Req_Sent; | |
1378 break; | |
1379 | |
1380 case PPP_EVENT_RCA: | |
1381 case PPP_EVENT_RCN: | |
1382 case PPP_EVENT_RTA: | |
1383 This_Layer_Down(Layer); | |
1384 TimerOn = true; | |
1385 Send_Configure_Request(); | |
1386 *State = PPP_STATE_Req_Sent; | |
1387 break; | |
1388 | |
1389 case PPP_EVENT_RTR: | |
1390 This_Layer_Down(Layer); | |
1391 RestartCount = 0; | |
1392 LinkTimer = 0; | |
1393 TimerOn = true; | |
1394 Send_Terminate_Ack(); | |
1395 *State = PPP_STATE_Stopping; | |
1396 break; | |
1397 | |
1398 case PPP_EVENT_RUC: | |
1399 Send_Code_Reject(); | |
1400 *State = PPP_STATE_Opened; | |
1401 break; | |
1402 | |
1403 case PPP_EVENT_RXJMinus: | |
1404 This_Layer_Down(Layer); | |
1405 RestartCount = MAX_RESTARTS; | |
1406 LinkTimer = 0; | |
1407 TimerOn = true; | |
1408 Send_Terminate_Request(); | |
1409 *State = PPP_STATE_Stopping; | |
1410 break; | |
1411 | |
1412 case PPP_EVENT_RXR: | |
1413 Send_Echo_Reply(); | |
1414 *State = PPP_STATE_Opened; | |
1415 break; | |
1416 | |
1417 default: | |
1418 Debug_Print("Illegal Event\r\n"); | |
1419 break; | |
1420 } | |
1421 break; | |
1422 | |
1423 default: | |
1424 break; | |
1425 } | |
1426 } |