linklayerprotocols/pppnif/SPPP/PPPFSM.CPP
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 #include "PPPLCP.H"
       
    18 #include "PPPBASE.H"
       
    19 #include "PPPLOG.H"
       
    20 #include "ncpip.h"
       
    21 #include "PPPCCP.H" // for KPppIdCcp
       
    22 #include <es_ini.h>
       
    23 
       
    24 //
       
    25 // PPP State machine
       
    26 //
       
    27 
       
    28 MPppFsm::MPppFsm(CPppLcp* aPppLcp, TPppPhase aPhase, TUint aPppId)
       
    29 	: MPppRecvr(aPppLcp, aPhase, aPppId),	
       
    30 	// Values may be initialized via  .ini file, but unless specified otherwise:
       
    31 	iTerminateRequestEnabled(ETrue), // RFC-compliant termination phase (TerminateRequest) is enabled
       
    32 	iTerminateAckEnabled(ETrue),     // RFC-compliant termination phase (TerminateAck) is enabled
       
    33 	iFsmTerminationCauseError(KErrNone),
       
    34 	iMaxTerminateRequest(KPppFsmTerminateRequestRetries),      // Wait after Sending TerminateRequest
       
    35 	iTerminateRequestTimeout(KPppFsmTerminateRequestTimeout),  // Wait for TerminateAck after sending TerminateRequest	
       
    36 	iTerminateAckTimeout(KPppFsmTerminateAckTimeout),           // Wait after sending TerminateAck
       
    37 	iFsmTermination(EFalse),
       
    38 	iNoEvidenceOfPeer(EFalse),
       
    39 	iWaitTimeNoIncrease(EFalse)
       
    40 	{
       
    41 	}
       
    42 
       
    43 MPppFsm::~MPppFsm()
       
    44 	{
       
    45 	TimerDelete();
       
    46 	if (!iRequestList.IsEmpty())
       
    47 		iRequestList.Free();
       
    48 	}
       
    49 
       
    50 void MPppFsm::FsmConstructL()
       
    51 /**
       
    52 Construct the state machine object
       
    53 */
       
    54 	{
       
    55 	ReadIniFileL();
       
    56 	// Dump the configuration resulting from the .ini file:
       
    57 	
       
    58 	LOG(iPppLcp->iLogger->Printf(_L("%s FSM: TerminateRequestEnabled[%d], MaxTerminateRequest[%d], TerminateRequestTimeout[%d]"),\
       
    59 		__iFsmName,	
       
    60 		iTerminateRequestEnabled,
       
    61 		iMaxTerminateRequest,
       
    62 		iTerminateRequestTimeout);)
       
    63 	
       
    64 	LOG(iPppLcp->iLogger->Printf(_L("%s FSM: TerminateAckEnabled[%d], TerminateAckTimeout[%d]"),\
       
    65 		__iFsmName,
       
    66 		iTerminateAckEnabled,
       
    67 		iTerminateAckTimeout);)
       
    68 	
       
    69 	TimerConstructL(KPppFsmTimerPriority);
       
    70 	}
       
    71 
       
    72 void MPppFsm::TerminateLink()
       
    73 /**
       
    74 Tear down the protocol, regardless of the state of the FSM.
       
    75 */
       
    76 	{
       
    77 	// Support for Termination Phase.
       
    78 	// This is not according to the RFC, but it is done to avoid 
       
    79 	// any regressions in the existing PPP.	
       
    80 	switch(iState) 
       
    81 		{		
       
    82 		case EPppFsmStopping: // We have received TerminateRequest, sent TerminateAck and
       
    83 							  // are waiting for one timeout to expire.
       
    84 			break;	// Stay in EPppFsmStopping state            
       
    85 		default: 
       
    86 			SendInitialTerminateRequest();
       
    87 			SetState(EPppFsmClosing);
       
    88 		}			
       
    89 	}
       
    90 
       
    91 //
       
    92 // Open/Close calls from higher level protocols
       
    93 //
       
    94 
       
    95 TInt MPppFsm::FsmOpen()
       
    96 /**
       
    97 Begin the state machine and protocol.
       
    98 Called by the derived class during initialization.
       
    99 
       
   100 @return KErrNone if successful, otherwise one of the system-wide error codes
       
   101 */
       
   102 	{
       
   103 	LOG( iPppLcp->iLogger->Printf(_L("%s FSM Open Request"), __iFsmName); )
       
   104 	TInt err = KErrNone;
       
   105 	
       
   106 	InitMaxFailure();
       
   107 	
       
   108 	switch (iState)
       
   109 		{
       
   110 	case EPppFsmInitial:
       
   111 		err = FsmLayerStarted();
       
   112 		SetState(EPppFsmStarting);
       
   113 		break;
       
   114 	case EPppFsmStarting:
       
   115 		break;
       
   116 	case EPppFsmClosed:
       
   117 		err = FsmLayerStarted();
       
   118 		SendInitialConfigRequest();
       
   119 		SetState(EPppFsmReqSent);
       
   120 		break;
       
   121 	case EPppFsmStopped:
       
   122 	case EPppFsmClosing:
       
   123 	case EPppFsmStopping:
       
   124 	case EPppFsmOpened:
       
   125 		// Check that we *really* want to do this!
       
   126 		LowerLayerDown();
       
   127 		LowerLayerUp();
       
   128 		break;
       
   129 	case EPppFsmReqSent:
       
   130 	case EPppFsmAckRecvd:
       
   131 	case EPppFsmAckSent:
       
   132 		break;
       
   133 		}
       
   134 	iPppAbortCode = KErrNone;
       
   135 	return err;
       
   136 	}
       
   137 
       
   138 void MPppFsm::FsmClose(TInt aReason)
       
   139 /**
       
   140 Close the state machine and protocol.
       
   141 Called by the derived class on closing.
       
   142 
       
   143 @param aReason Reason for closing
       
   144 */
       
   145 	{
       
   146 	LOG( iPppLcp->iLogger->Printf(_L("%s FSM Close Request, error[%d]"), __iFsmName, aReason); )
       
   147 	switch (iState)
       
   148 		{
       
   149 	case EPppFsmInitial:
       
   150 	case EPppFsmClosed:
       
   151 	case EPppFsmClosing:
       
   152 		break;
       
   153 	case EPppFsmStarting:
       
   154 		FsmLayerFinished();
       
   155 		SetState(EPppFsmInitial);
       
   156 		break;
       
   157 	case EPppFsmStopped:
       
   158 		SetState(EPppFsmClosed);
       
   159 		break;
       
   160 	case EPppFsmStopping:
       
   161 		SetState(EPppFsmClosing);
       
   162 		break;
       
   163 	case EPppFsmOpened:
       
   164 		FsmLayerDown(aReason);
       
   165 		// continue into next statement
       
   166 	case EPppFsmReqSent:
       
   167 	case EPppFsmAckRecvd:
       
   168 	case EPppFsmAckSent:
       
   169 		SendInitialTerminateRequest();
       
   170 		SetState(EPppFsmClosing);
       
   171 		break;
       
   172 		}
       
   173 	}
       
   174 
       
   175 void MPppFsm::FsmAbort(TInt aReason)
       
   176 /**
       
   177 Abort the protocol.
       
   178 
       
   179 @param aReason Reason for aborting
       
   180 */
       
   181 // 29.11.00.  Changed slightly so that this does the same as RXJ- 
       
   182 // in the PPP RFC for all states.
       
   183 	{
       
   184 	LOG( iPppLcp->iLogger->Printf(_L("%s FSM Abort Request, error[%d]"), __iFsmName, aReason); )
       
   185 	switch (iState)
       
   186 		{
       
   187 	case EPppFsmInitial:
       
   188 	case EPppFsmStarting:
       
   189 		// bad event
       
   190 		break;
       
   191 	case EPppFsmClosed:
       
   192 	case EPppFsmStopped:
       
   193 		FsmLayerFinished();
       
   194 		break;
       
   195 	case EPppFsmClosing:
       
   196 		FsmLayerFinished();
       
   197 		SetState(EPppFsmClosed);
       
   198 		break;
       
   199 	case EPppFsmStopping:
       
   200 		FsmLayerFinished();
       
   201 		SetState(EPppFsmStopped);
       
   202 		break;
       
   203 	case EPppFsmOpened:
       
   204 		FsmLayerDown();
       
   205 		SendInitialTerminateRequest();
       
   206 		SetState(EPppFsmStopping);
       
   207 		break;
       
   208 	case EPppFsmReqSent:
       
   209 	case EPppFsmAckRecvd:
       
   210 	case EPppFsmAckSent:
       
   211 		FsmLayerFinished(aReason);
       
   212 		SetState(EPppFsmStopped);
       
   213 		break;
       
   214 		}
       
   215 	iPppAbortCode = aReason;
       
   216 	}
       
   217 
       
   218 
       
   219 
       
   220 //
       
   221 // Upcall from Timer
       
   222 //
       
   223 
       
   224 EXPORT_C void MPppFsm::TimerComplete(TInt /*aStatus*/)
       
   225 /**
       
   226 Called by MTimer on timer expiry.
       
   227 
       
   228 @param aStatus Aynchronous request completion status (ignored)
       
   229 */
       
   230 	{
       
   231 	LOG( iPppLcp->iLogger->Printf(_L("%s FSM Timer Expired %d "), __iFsmName, iRestartCount); )
       
   232 
       
   233 	switch (iState)
       
   234 		{
       
   235 	case EPppFsmInitial:
       
   236 	case EPppFsmStarting:
       
   237 	case EPppFsmClosed:
       
   238 	case EPppFsmStopped:
       
   239 	case EPppFsmOpened:
       
   240 		// Bad Event
       
   241 		return;
       
   242 	default:
       
   243 		break;
       
   244 		}
       
   245 
       
   246 	if (iRestartCount>0)
       
   247 		{
       
   248 		switch (iState)
       
   249 			{
       
   250 		case EPppFsmClosing:
       
   251 		case EPppFsmStopping:
       
   252 			SendTerminateRequest();
       
   253 			break;
       
   254 		case EPppFsmReqSent:
       
   255 		case EPppFsmAckRecvd:
       
   256 		case EPppFsmAckSent:
       
   257 			//PG RFC 1661 4.6 double timeout period
       
   258 			// Allow for configuration of non-doubling of timeout period (initially for
       
   259 			// conformance testing) - default behaviour is for doubling to occur.
       
   260 			if (!iWaitTimeNoIncrease && iWaitTime*2 < KPppFsmRequestMaxTimeout)
       
   261 				{
       
   262 				iWaitTime = iWaitTime * 2;
       
   263 				}
       
   264 			SendConfigRequest();
       
   265 			if(iState == EPppFsmAckRecvd)
       
   266 				SetState(EPppFsmReqSent);
       
   267 			break;
       
   268 		default:
       
   269 			break;
       
   270 			}
       
   271 		}
       
   272 	else		
       
   273 		{		
       
   274  		switch(iState)
       
   275   			{
       
   276   			case EPppFsmClosing: // We sent out TerminateRequests, no TerminateAcks received.
       
   277  				FsmLayerFinished(iFsmTerminationCauseError); // Authoritative Close of the Link --> KErrCancel
       
   278   				break;
       
   279   			case EPppFsmStopping: // We've sent TerminateAck and waited one restart period
       
   280   				FsmLayerFinished(iFsmTerminationCauseError); // Peer initiated disconnection.
       
   281   				break;
       
   282   			default:
       
   283   				// Don't abort if we're configured to persist.
       
   284   				if(!iPersist)
       
   285   					{
       
   286   					iFsmTermination = ETrue; // Used later to bring down the FSM as opposed to restarting it.
       
   287   					FsmLayerFinished(KErrTimedOut);
       
   288   					}
       
   289   				else
       
   290  					{
       
   291  					LOG( iPppLcp->iLogger->Printf(_L("%s FSM going idle"), __iFsmName); )
       
   292  					}
       
   293   				break;
       
   294   			}
       
   295 		
       
   296 		switch (iState)
       
   297 			{
       
   298 		case EPppFsmClosing:
       
   299 			SetState(EPppFsmClosed);
       
   300 			break;
       
   301 		case EPppFsmStopping:
       
   302 		case EPppFsmReqSent:
       
   303 		case EPppFsmAckRecvd:
       
   304 		case EPppFsmAckSent:
       
   305 			SetState(EPppFsmStopped);
       
   306 			break;
       
   307 		case EPppFsmInitial:
       
   308 		case EPppFsmStarting:
       
   309 		case EPppFsmClosed:
       
   310 		case EPppFsmStopped:
       
   311 		case EPppFsmOpened:
       
   312 		default:
       
   313 			break;
       
   314 			}
       
   315 		}
       
   316 	}
       
   317 
       
   318 //
       
   319 // Upcalls from Recvr
       
   320 //
       
   321 
       
   322 EXPORT_C void MPppFsm::LowerLayerUp()
       
   323 /**
       
   324 Called when the lower layer protocol has come up.
       
   325 */
       
   326 	{
       
   327 	LOG( iPppLcp->iLogger->Printf(_L("%s FSM Up Event"), __iFsmName); )
       
   328 	switch (iState)
       
   329 		{
       
   330 	case EPppFsmInitial:
       
   331 		SetState(EPppFsmOpened);
       
   332 		break;
       
   333 	case EPppFsmStarting:
       
   334 		SendInitialConfigRequest();
       
   335 		SetState(EPppFsmReqSent);
       
   336 		break;
       
   337 	case EPppFsmClosed:
       
   338 	case EPppFsmStopped:
       
   339 	case EPppFsmClosing:
       
   340 	case EPppFsmStopping:
       
   341 	case EPppFsmReqSent:
       
   342 	case EPppFsmAckRecvd:
       
   343 	case EPppFsmAckSent:
       
   344 	case EPppFsmOpened:
       
   345 		// Bad Event
       
   346 		break;
       
   347 		}
       
   348 	}
       
   349 
       
   350 
       
   351 EXPORT_C void MPppFsm::LowerLayerDown(TInt aStatus)
       
   352 /**
       
   353 Signals the Down event.
       
   354 Called when the lower layer protocol has gone down.
       
   355 This means that our layer can no longer receive or transmit anything.
       
   356 
       
   357 In case of LCP, this means that the physical link is closed (e.g. Peer dropped DTR)
       
   358 If we are LCP, this may mean that PPP is finished, because the link is no longer available.
       
   359 
       
   360 @param aStatus Error code indicating the reason the layer is going down
       
   361 */
       
   362 	{
       
   363 	LOG( iPppLcp->iLogger->Printf(_L("%s FSM Down Event, error[%d]"), __iFsmName, aStatus); )
       
   364 	
       
   365 	switch (iState)
       
   366 		{
       
   367 	case EPppFsmInitial:
       
   368 		// Bad Event
       
   369 		break;
       
   370 	case EPppFsmStarting:
       
   371 		FsmLayerDown(aStatus);
       
   372 		break;
       
   373 	case EPppFsmClosed:
       
   374 		SetState(EPppFsmInitial);
       
   375 		break;
       
   376 	case EPppFsmClosing: // We are waiting for Terminate Ack (or TerminateRequest retransmission)
       
   377 		SetState(EPppFsmInitial);
       
   378 		break;
       
   379 	case EPppFsmStopped:
       
   380 		if(!iFsmTermination) // We are not terminating, so we restart the FSM.
       
   381 			{
       
   382 			FsmLayerStarted();
       
   383 			SetState(EPppFsmStarting);
       
   384 			return; // The alternative is calling FsmTerminationPhaseComplete from every case.	
       
   385 			}
       
   386 		// If we are terminating, we terminate the FSM and notify Nifman that the NIF is finished.				
       
   387 		SetState(EPppFsmStarting);
       
   388 		break;
       
   389 	case EPppFsmStopping: // We are waiting 1 restart period after transmitting Terminate Ack 
       
   390 		SetState(EPppFsmStarting);
       
   391 		break;
       
   392 	case EPppFsmReqSent:
       
   393 	case EPppFsmAckRecvd:
       
   394 	case EPppFsmAckSent:
       
   395 		FsmLayerDown(aStatus);
       
   396 		SetState(EPppFsmStarting);
       
   397 		break;
       
   398 	case EPppFsmOpened:
       
   399 		FsmLayerDown(aStatus);
       
   400 		SetState(EPppFsmStarting);
       
   401 		break;
       
   402 		}
       
   403 	// This call is critical to make sure PPP reports its demise correctly. Otherwise, Nifman remains unaware, and 
       
   404 	// ESock / Nifman / PPP hangs.	
       
   405 	FsmTerminationPhaseComplete(); // ASSUMPTION: LCP signals to Nifman. Others do nothing.	
       
   406 	// Note: early return from EPppFsmStopped.
       
   407 	}
       
   408 
       
   409 EXPORT_C void MPppFsm::FrameError()
       
   410 /**
       
   411 Called when a bad frame is received.
       
   412 No action is currently taken.
       
   413 
       
   414 @see RecvFrame() is called instead when a good frame is received
       
   415 */
       
   416 	{
       
   417 	return;
       
   418 	}
       
   419 
       
   420 EXPORT_C void MPppFsm::KillProtocol()
       
   421 /**
       
   422 Called when the lower level protocol is killed.
       
   423 */
       
   424 	{
       
   425 	//
       
   426 	// This came to light as a result of the CCP work
       
   427 	// This happens if a protocol is told to shut down,
       
   428 	// I'm not sure how to handle it?? Do we just Stop it???
       
   429 	//
       
   430 	return;
       
   431 	}
       
   432 
       
   433 EXPORT_C TBool MPppFsm::RecvFrame(RMBufChain& aPacket)
       
   434 /**
       
   435 Receives and processes a PPP frame.
       
   436 Called by CPppLcp.
       
   437 
       
   438 @see FrameError() is called instead when a bad frame is received
       
   439 
       
   440 @param aPacket MBuf chain containing packet
       
   441 
       
   442 @return EFalse
       
   443 */
       
   444 	{
       
   445 	RMBufPacket pkt;
       
   446 	pkt.Assign(aPacket);
       
   447 	pkt.Unpack();
       
   448 	RMBufPktInfo* info = pkt.Info();
       
   449 
       
   450 	TUint8 op;
       
   451 	TUint8 id;
       
   452 	TInt len;
       
   453 	
       
   454 	// Extract and drop LCP header
       
   455 	pkt.Align(4);
       
   456 	TUint8* ptr = pkt.First()->Ptr();
       
   457 	op = *ptr++;
       
   458 	id = *ptr++;
       
   459 	len = BigEndian::Get16(ptr);
       
   460 	
       
   461 	// Check packet length is OK
       
   462 	if (info->iLength<len || info->iLength<4 )
       
   463 		{
       
   464 		// Too short!
       
   465 		pkt.Free();
       
   466 		return EFalse;
       
   467 		}
       
   468 	else if (info->iLength > len)
       
   469 		pkt.TrimEnd(len);
       
   470 	
       
   471 	// Received a potentially valid packet; probably we have a meaningful relationship with peer
       
   472 	iNoEvidenceOfPeer = EFalse;	
       
   473 	// If op is unknown
       
   474 	switch (op)
       
   475 		{
       
   476 	case KPppLcpConfigAck:
       
   477 	case KPppLcpConfigNak:
       
   478 	case KPppLcpConfigReject:
       
   479 		// Filter out bad acks
       
   480 		if (iState>=EPppFsmReqSent && id!=iRequestId)
       
   481 			break;
       
   482 		else
       
   483 			iRequestId |= KPppRequestIdAnswered;
       
   484 		// fall through ...
       
   485 	case KPppLcpConfigRequest:
       
   486 		// Option negotiation ops
       
   487 		// Split the MBuf chain in separate options
       
   488 
       
   489 		//if(len<=4)
       
   490 		if(len<4)
       
   491 			break;
       
   492 
       
   493 		//
       
   494 		// Hmmm sometimes we receive a Config request of Length 4
       
   495 		// i.e. no options Send a Config ACK
       
   496 		// 
       
   497 		if ( (len == 4) && (op == KPppLcpConfigRequest))
       
   498 			{
       
   499 			 if (ProcessEmptyConfigReq())
       
   500 				{
       
   501 				if (iPppId == KPppIdCcp)
       
   502 					{
       
   503 					// For empty CCP Config Requests send a Protocol Reject,
       
   504 					// otherwise we can end up continually exchanging empty
       
   505 					// Config Requests and Config ACK's.  KPppIdLcp is passed to
       
   506 					// CPppHdlcLink::Send() via FsmRejectPacket() to ensure
       
   507 					// transmission of an *LCP* Protocol Reject of CCP rather than
       
   508 					// a *CCP* Protocol Reject of CCP (subtle difference).
       
   509 					pkt.Pack();
       
   510 					FsmRejectPacket(pkt, KPppLcpProtocolReject, KPppIdLcp);
       
   511 					}
       
   512 				else
       
   513 					{
       
   514 					// Send an acknowledgement
       
   515 					ptr = pkt.First()->Ptr();
       
   516 					*ptr = KPppLcpConfigAck;
       
   517 					pkt.Pack();
       
   518 					SendFrame(pkt);
       
   519 					}
       
   520 				}
       
   521 			 else
       
   522 				{
       
   523 				break;
       
   524 				}
       
   525 			}
       
   526 		else if (len == 4 && (op != KPppLcpConfigAck && iPppLcp->QueryExternalIPConfiguration()))
       
   527 			{
       
   528 			// With Mobile IP, there is the possibility of having no options to negotiate, in which
       
   529 			// case an empty ConfigReq would be sent out.  This would be acknowledged by an empty
       
   530 			// ConfigAck, so ensure that we process the latter.
       
   531 			break;
       
   532 			}
       
   533 		else
       
   534 			{
       
   535 			pkt.TrimStart(4);
       
   536 			ProcessConfig(op, id, len-4, pkt);
       
   537 			}
       
   538 
       
   539 		break;	
       
   540 	case KPppLcpTerminateAck:
       
   541 		// Filter out bad acks
       
   542 		if ((iState==EPppFsmClosing || iState==EPppFsmStopping) && id!=iTerminateId)
       
   543 			break;
       
   544 		else
       
   545 			iTerminateId |= KPppRequestIdAnswered;
       
   546 		// fall through ...
       
   547 	case KPppLcpTerminateRequest:
       
   548 		if(len<4)
       
   549 			break;
       
   550 
       
   551 		pkt.TrimStart(4);
       
   552 		ProcessTerminate(op, id, len-4, pkt);
       
   553 		break;
       
   554 	case KPppLcpCodeReject:
       
   555 	case KPppLcpProtocolReject:
       
   556 		if(len<=4)
       
   557 			break;
       
   558 		pkt.TrimStart(4);
       
   559 		ProcessReject(op, id, len-4, pkt);
       
   560 		break;
       
   561 	default:		
       
   562 		if (!FsmRecvUnknownCode(op, id, len, pkt))
       
   563 			{
       
   564 			pkt.Pack();
       
   565 			FsmRejectPacket(pkt);
       
   566 			}
       
   567 		break;
       
   568 		}
       
   569 	pkt.Free();
       
   570 	return EFalse;
       
   571 	}
       
   572 	
       
   573 //
       
   574 // Rest of PPP
       
   575 //
       
   576 
       
   577 TBool MPppFsm::FsmRecvUnknownCode(TUint8 /*aCode*/, TUint8 /*aId*/, TInt /*aLength*/, RMBufChain& /*aPacket*/)
       
   578 /**
       
   579 Handle a received packet with an unknown code.
       
   580 
       
   581 @param aCode Packet code (ignored)
       
   582 @param aId Packet identifier (ignored)
       
   583 @param aLength Length of packet (ignored)
       
   584 @param aPacket MBuf chain containing packet (ignored)
       
   585 
       
   586 @return EFalse
       
   587 */
       
   588 	{
       
   589 	return EFalse;
       
   590 	}
       
   591 
       
   592 void MPppFsm::ProcessReject(TUint8 aCode, TUint8 /*aId*/, TInt /* aLength */, RMBufChain& aPacket)
       
   593 /**
       
   594 Handle a Code Reject or Protocol Reject.
       
   595 If the reject rejects a code (or protocol) that should
       
   596 be known terminate layer.
       
   597 (Note, As the behaviour of protocol reject is the same
       
   598 as code reject, this function handles protocol reject for LCP)
       
   599 
       
   600 @param aCode Packet code
       
   601 @param aId Packet identifier (ignored)
       
   602 @param aLength Length of packet (ignored)
       
   603 @param aPacket MBuf chain containing packet.
       
   604 */
       
   605 	{
       
   606 	TBool isCatastrophic = EFalse;
       
   607 	
       
   608 	// Valid reject packets should have a len >=4
       
   609 	if(aPacket.Length()<4)
       
   610 		return;
       
   611 
       
   612 	// Determine if the reject is acceptable
       
   613 	if (aCode==KPppLcpProtocolReject)
       
   614 		{
       
   615 		
       
   616 		aPacket.Align(2);
       
   617 		TUint prot = BigEndian::Get16(aPacket.First()->Ptr());
       
   618 		aPacket.TrimStart(2);
       
   619 		switch (prot)
       
   620 			{
       
   621 			case KPppIdLcp:
       
   622 				isCatastrophic = ETrue;
       
   623 				break;
       
   624 
       
   625 			case KPppIdCompressedData:
       
   626 				// Shut down and unload the current compressor
       
   627 				LOG( iPppLcp->iLogger->Printf(_L("Compressed Packet rejected: Unloading compressor.")); )
       
   628 				iPppLcp->PppUnloadCompressor() ;
       
   629 				break ;
       
   630 
       
   631 			default:
       
   632 				{
       
   633 				/*
       
   634 				*	Tut tut the existing code only handled Protocol rejects for the 
       
   635 				*	LCP protocol. What about all the others?
       
   636 				*/
       
   637 				iFsmTermination = ETrue; // Used later to bring down the FSM as opposed to restarting it.
       
   638 				iPppLcp->StopProtocol(prot);
       
   639 				break;
       
   640 				}
       
   641 			}
       
   642 		}
       
   643 	else
       
   644 		{
       
   645 		TUint8 code = aPacket.First()->Get(0);
       
   646 		switch (code)
       
   647 			{
       
   648 		case KPppLcpConfigRequest:
       
   649 		case KPppLcpConfigAck:
       
   650 		case KPppLcpConfigNak:
       
   651 		case KPppLcpConfigReject:
       
   652 		case KPppLcpTerminateRequest:
       
   653 		case KPppLcpTerminateAck:
       
   654 			isCatastrophic = ETrue;
       
   655 			break;
       
   656 		case KPppLcpCodeReject:
       
   657 		case KPppLcpProtocolReject:
       
   658 			iFsmTermination = ETrue;
       
   659 			isCatastrophic = ETrue;
       
   660 			break;
       
   661 		default:
       
   662 			break;
       
   663 			}
       
   664 		}
       
   665 
       
   666 	if (!isCatastrophic)
       
   667 		{
       
   668 		if (iState==EPppFsmAckRecvd)
       
   669 			SetState(EPppFsmReqSent);
       
   670 		return;
       
   671 		}
       
   672 
       
   673 	LOG( iPppLcp->iLogger->Printf(_L("%s Catastrophic Reject, packet code[%d]"), __iFsmName, aCode); )
       
   674 
       
   675 	switch (iState)
       
   676 		{
       
   677 	case EPppFsmInitial:
       
   678 	case EPppFsmStarting:
       
   679 		// bad event
       
   680 		break;
       
   681 	case EPppFsmClosed:
       
   682 	case EPppFsmStopped:
       
   683 		FsmLayerFinished();
       
   684 		break;
       
   685 	case EPppFsmClosing:
       
   686 		FsmLayerFinished();
       
   687 		SetState(EPppFsmClosed);
       
   688 		break;
       
   689 	case EPppFsmStopping:
       
   690 	case EPppFsmReqSent:
       
   691 	case EPppFsmAckRecvd:
       
   692 	case EPppFsmAckSent:
       
   693 		FsmLayerFinished();
       
   694 		SetState(EPppFsmStopped);
       
   695 		break;
       
   696 	case EPppFsmOpened:
       
   697 		FsmLayerDown();
       
   698 		SendInitialTerminateRequest();
       
   699 		SetState(EPppFsmStopped);
       
   700 		break;
       
   701 		}
       
   702 	}
       
   703 	
       
   704 void MPppFsm::ProcessTerminate(TUint8 aCode, TUint8 aId, TInt /*aLength*/, RMBufChain& /*aPacket*/)
       
   705 /**
       
   706 Handle a Terminate Request packet and cleanly terminate the connection.
       
   707 
       
   708 @param aCode Packet code
       
   709 @param aId Packet identifier
       
   710 @param aLength Length of packet (ignored)
       
   711 @param aPacket MBuf chain containing packet (ignored)
       
   712 */
       
   713 	{
       
   714 	LOG( iPppLcp->iLogger->Printf(_L("%s Terminate Request, packet code[%d]"), __iFsmName, aCode); )
       
   715 
       
   716 	if (aCode==KPppLcpTerminateRequest)
       
   717 		{
       
   718 		LOG( iPppLcp->iLogger->Printf(_L("Rx: TerminateRequest Id[%d]"), aId); )
       
   719 		iFsmTermination = ETrue; // Used later to bring down the FSM as opposed to restarting it.
       
   720 		iFsmTerminationCauseError = KErrDisconnected;
       
   721 		switch (iState)
       
   722 			{
       
   723 		case EPppFsmInitial:
       
   724 		case EPppFsmStarting:
       
   725 			// bad event
       
   726 			break;
       
   727 		case EPppFsmClosed:
       
   728 		case EPppFsmStopped:
       
   729 		case EPppFsmClosing:
       
   730 		case EPppFsmStopping:
       
   731 			SendTerminateAck(aId);
       
   732 			break;
       
   733 		case EPppFsmReqSent:
       
   734 		case EPppFsmAckRecvd:
       
   735 		case EPppFsmAckSent:
       
   736 			SendTerminateAck(aId);
       
   737 			FsmLayerFinished(KErrCouldNotConnect);
       
   738 			SetState(EPppFsmReqSent);
       
   739 			break;			
       
   740 		case EPppFsmOpened:
       
   741 			ZeroRestartCount();
       
   742 			if(iTerminateAckEnabled) // Fully RFC compliant shutdown sequence, as opposed to "Legacy" shutdown.
       
   743 									 // Once "Legacy" shutdown is removed, a check for TerminateAckEnabled may
       
   744 									 // be safely removed as well.
       
   745 				{                    
       
   746 				SendTerminateAck(aId);
       
   747 				
       
   748 				//  RFC1661 3.7: wait at least one restart period
       
   749 				TimerCancel();
       
   750  				TimerAfter(iTerminateAckTimeout * 1000); 
       
   751  				// If iTerminateAckTimeout is zero, we proceed to terminate the FSM and close the link almost
       
   752  				// immediately. This may result in TerminateAck send being cancelled when we close the actual link. 
       
   753  		
       
   754 				FsmLayerDown(KErrDisconnected);
       
   755 				}
       
   756 			else // "Legacy" shutdown sequence			     
       
   757 			     // Once "legacy" behaviour is not required any more, this section of code may be safely removed.
       
   758 				{
       
   759 				// We do not send terminate Ack.
       
   760 				FsmLayerDown();
       
   761 				FsmLayerFinished(KErrCommsLineFail);
       
   762 				// Note: 
       
   763 				// KErrCommsLineFail is given a special interpreation by the NCP, which may inform Nifman to 
       
   764 				// renegotiate the link, rather than terminate. 
       
   765 				}
       
   766 				
       
   767 			SetState(EPppFsmStopping);
       
   768 			break;
       
   769 		default:
       
   770 			break;
       
   771 			}					
       
   772 		} // KPppLcpterminateRequest
       
   773 	else // KPppLcpTerminateAck
       
   774 		{
       
   775 		LOG( iPppLcp->iLogger->Printf(_L("Rx: TerminateAck Id[%d]"), aId); )
       
   776 		
       
   777 		if (iPppAbortCode!=KErrNone)
       
   778 			{
       
   779 			iPppLcp->PhaseAborted(iPppAbortCode);
       
   780 			}
       
   781 		else
       
   782 			{
       
   783 			switch (iState)
       
   784 				{
       
   785 			case EPppFsmInitial:
       
   786 			case EPppFsmStarting:
       
   787 				// bad event
       
   788 				break;
       
   789 			case EPppFsmClosed:
       
   790 			case EPppFsmStopped:				
       
   791 				break;
       
   792 			case EPppFsmClosing: // Terminate Request Sent
       
   793 				FsmLayerFinished(iFsmTerminationCauseError);
       
   794 				SetState(EPppFsmClosed);
       
   795 				break;
       
   796 			case EPppFsmStopping: // Terminate Ack sent
       
   797 				FsmLayerFinished(iFsmTerminationCauseError);
       
   798 				SetState(EPppFsmStopped);
       
   799 				break;
       
   800 			case EPppFsmReqSent:
       
   801 			case EPppFsmAckSent:
       
   802 				KillProtocol();
       
   803  				break;
       
   804 			case EPppFsmAckRecvd:
       
   805 				SetState(EPppFsmReqSent);
       
   806 				break;
       
   807 			case EPppFsmOpened:
       
   808 				FsmLayerDown();
       
   809 				SendConfigRequest();
       
   810 				SetState(EPppFsmReqSent);
       
   811 				break;
       
   812 				}
       
   813 			}
       
   814 		}
       
   815 	}
       
   816 
       
   817 TBool MPppFsm::ProcessEmptyConfigReq()
       
   818 /**
       
   819 Handle Config Request with no options.
       
   820 
       
   821 @return ETrue on a valid state change
       
   822 */
       
   823 	{	
       
   824 	LOG( iPppLcp->iLogger->Printf(_L("%s Empty Config Request"), __iFsmName); )
       
   825 
       
   826 
       
   827    TBool retCode = EFalse;
       
   828 
       
   829 
       
   830 	// About to drop out of opened state to need to reset things
       
   831 	// BEFORE the new request is processed.
       
   832 	if (iState==EPppFsmOpened)
       
   833 		{
       
   834 		FsmLayerDown();
       
   835 		InitialiseConfigRequest();
       
   836 		}
       
   837 	
       
   838 
       
   839 	// State processing
       
   840 
       
   841 	switch (iState)
       
   842 		{
       
   843 	case EPppFsmInitial:
       
   844 	case EPppFsmStarting:
       
   845 		// Bad event
       
   846 	case EPppFsmClosing:
       
   847 	case EPppFsmStopping:
       
   848 		break;
       
   849 
       
   850 	case EPppFsmClosed:
       
   851 		//SendTerminateAck(aId);
       
   852 		break;
       
   853 	case EPppFsmStopped:
       
   854       {
       
   855 		SendInitialConfigRequest();
       
   856 		SetState(EPppFsmAckSent);
       
   857       retCode = ETrue;
       
   858 		break;
       
   859 		}
       
   860 	case EPppFsmReqSent:
       
   861       {
       
   862       retCode = ETrue;
       
   863 		SetState(EPppFsmAckSent);
       
   864 		break;
       
   865 		}
       
   866 	case EPppFsmAckRecvd:
       
   867 		{
       
   868       retCode = ETrue;
       
   869 		SetState(EPppFsmOpened);
       
   870 		FsmLayerUp();
       
   871 		break;
       
   872 		}
       
   873 	case EPppFsmAckSent:
       
   874 		{
       
   875       retCode = ETrue;
       
   876 		break;
       
   877 		}
       
   878 	case EPppFsmOpened:
       
   879 		{	
       
   880 		// This will cause empty config request to restart config negotiation
       
   881 		SendInitialConfigRequest();
       
   882 		SetState(EPppFsmAckSent);
       
   883 		retCode=ETrue;
       
   884 		break;
       
   885 		}
       
   886       }
       
   887    return retCode;
       
   888 	}	
       
   889 
       
   890 void MPppFsm::ProcessConfig(TUint8 aCode, TUint8 aId, TInt /* aLength */, RMBufChain& aPacket)
       
   891 /**
       
   892 Handle ConfigRequest, ConfigAck, ConfigNak and ConfigReject
       
   893 
       
   894 @param aCode Packet code
       
   895 @param aId Packet identifier
       
   896 @param aLength Length of packet (ignored)
       
   897 @param aPacket MBuf chain containing packet.
       
   898 */
       
   899 	{	
       
   900 	LOG( iPppLcp->iLogger->Printf(_L("%s Process Config, packet code[%d]"), __iFsmName, aCode); )
       
   901 
       
   902 	// Split the recvd packet into separate options
       
   903 	// placing each option in a queue where it can be
       
   904 	// easily parsed and manipulated in the upcall handlers.
       
   905 	RPppOptionList rcvlist;	// Recvd list of options
       
   906 
       
   907 	TRAPD(err, rcvlist.SetL(aPacket));
       
   908 	if (err!=KErrNone)
       
   909 		return;
       
   910 	
       
   911 	enum TCheckResult { ENop, EAck, ENak, ERej } reply = ENop;
       
   912 
       
   913 	RPppOptionList acklist;	// List of Ack'd options - only valid of the following are empty
       
   914 	RPppOptionList naklist;	// List of Nak'd options - only valid of the following is empty
       
   915 	RPppOptionList rejlist;	// List of Rejected options
       
   916 
       
   917 	if (aCode==KPppLcpConfigRequest)
       
   918 		{
       
   919 		// About to drop out of opened state to need to reset things
       
   920 		// BEFORE the new request is processed.
       
   921 		if (iState==EPppFsmOpened)
       
   922 			{
       
   923 			FsmLayerDown();
       
   924 			InitialiseConfigRequest();
       
   925 			}
       
   926 
       
   927 		// If any duplicated RFC1661 options, then discard the packet		
       
   928 		if (!FsmConfigRequestOptionsValid(rcvlist))
       
   929 			{
       
   930 			LOG( iPppLcp->iLogger->Printf(_L("%s FSM - ConfigRequest discarded due to duplicate RFC1661 options"), __iFsmName); )
       
   931 			rcvlist.Free();
       
   932 			return;
       
   933 			}
       
   934 
       
   935 		// Check options, and split into list of OK, Bad and Unknown
       
   936 		// Note - the naklist options will have been updated to
       
   937 		// contain acceptable values.
       
   938 
       
   939 		FsmCheckConfigRequest(rcvlist, acklist, naklist, rejlist);
       
   940 
       
   941 		if (!rejlist.IsEmpty())
       
   942 			{
       
   943 			reply = ERej;
       
   944 			naklist.Free();
       
   945 			acklist.Free();
       
   946 			}
       
   947 		else if (!naklist.IsEmpty())
       
   948 			{
       
   949 			reply = ENak;
       
   950 			acklist.Free();
       
   951 			}
       
   952 		else if (!acklist.IsEmpty())
       
   953 			{
       
   954 			reply = EAck;
       
   955 			FsmApplyConfigRequest(acklist);
       
   956 			}
       
   957 		else
       
   958 			{
       
   959 			// Panic - options lost by derived class!
       
   960 			}
       
   961 		}		
       
   962 		
       
   963 	// State processing
       
   964 
       
   965 	switch (iState)
       
   966 		{
       
   967 	case EPppFsmInitial:
       
   968 	case EPppFsmStarting:
       
   969 		// Bad event
       
   970 	case EPppFsmClosing:
       
   971 	case EPppFsmStopping:
       
   972 		break;
       
   973 
       
   974 	case EPppFsmClosed:
       
   975 		SendTerminateAck(aId);
       
   976 		break;
       
   977 
       
   978 	case EPppFsmStopped:
       
   979 		switch (aCode)
       
   980 			{
       
   981 		case KPppLcpConfigRequest:
       
   982 			SendInitialConfigRequest();
       
   983 			switch (reply)
       
   984 				{
       
   985 			case EAck:
       
   986 				SendConfigReply(acklist, KPppLcpConfigAck, aId);
       
   987 				SetState(EPppFsmAckSent);
       
   988 				break;
       
   989 			case ENak:
       
   990 				SendConfigReply(naklist, KPppLcpConfigNak, aId);
       
   991 				SetState(EPppFsmReqSent);
       
   992 				break;
       
   993 			case ERej:
       
   994 				SendConfigReply(rejlist, KPppLcpConfigReject, aId);
       
   995 				SetState(EPppFsmReqSent);
       
   996 				break;
       
   997 			default:
       
   998 				break;
       
   999 				}
       
  1000 			break;
       
  1001 		case KPppLcpConfigAck:
       
  1002 		case KPppLcpConfigNak:
       
  1003 		case KPppLcpConfigReject:
       
  1004 			SendTerminateAck(aId);
       
  1005 			break;
       
  1006 		default:
       
  1007 			break;
       
  1008 			}
       
  1009 		break;
       
  1010 	
       
  1011 	case EPppFsmReqSent:
       
  1012 		switch (aCode)
       
  1013 			{
       
  1014 		case KPppLcpConfigRequest:
       
  1015 			switch (reply)
       
  1016 				{
       
  1017 			case EAck:
       
  1018 				SendConfigReply(acklist, KPppLcpConfigAck, aId);
       
  1019 				SetState(EPppFsmAckSent);
       
  1020 				break;
       
  1021 			case ENak:
       
  1022 				// RFC 1661 4.6
       
  1023 				if(MaxFailureExceeded())
       
  1024 					SendConfigReply(naklist, KPppLcpConfigReject, aId);
       
  1025 				else
       
  1026 					{
       
  1027 					DecrementMaxFailure();
       
  1028 					SendConfigReply(naklist, KPppLcpConfigNak, aId);
       
  1029 					}
       
  1030 				SetState(EPppFsmReqSent);
       
  1031 				break;
       
  1032 			case ERej:
       
  1033 				SendConfigReply(rejlist, KPppLcpConfigReject, aId);
       
  1034 				SetState(EPppFsmReqSent);
       
  1035 				break;
       
  1036 			default:
       
  1037 				break;
       
  1038 				}
       
  1039 			break;
       
  1040 		case KPppLcpConfigAck:
       
  1041 			if (FsmAckOptionsValid(rcvlist, iRequestList))
       
  1042 				{
       
  1043 				InitRestartCountForConfig();
       
  1044 				FsmRecvConfigAck(rcvlist);
       
  1045 				SetState(EPppFsmAckRecvd);
       
  1046 				}
       
  1047 			else
       
  1048 				{
       
  1049 				LOG( iPppLcp->iLogger->Printf(_L("%s FSM - ConfigAck discarded due to option mismatch with original ConfigRequest"), __iFsmName); )
       
  1050 				}
       
  1051 			break;
       
  1052 		case KPppLcpConfigNak:
       
  1053 			InitRestartCountForConfig();
       
  1054 			FsmRecvConfigNak(rcvlist, iRequestList);
       
  1055 			SendConfigRequestAfterNak(rcvlist);
       
  1056 			break;
       
  1057 		case KPppLcpConfigReject:
       
  1058 			InitRestartCountForConfig();
       
  1059 			FsmRecvConfigReject(rcvlist, iRequestList);
       
  1060 			SendConfigRequestAfterReject(rcvlist);
       
  1061 			break;
       
  1062 		default:
       
  1063 			break;
       
  1064 			}
       
  1065 		break;
       
  1066 	
       
  1067 	case EPppFsmAckRecvd:
       
  1068 		switch (aCode)
       
  1069 			{
       
  1070 		case KPppLcpConfigRequest:
       
  1071 			switch (reply)
       
  1072 				{
       
  1073 			case EAck:
       
  1074 				SendConfigReply(acklist, KPppLcpConfigAck, aId);
       
  1075 				SetState(EPppFsmOpened);
       
  1076 				FsmLayerUp();
       
  1077 				break;
       
  1078 			case ENak:
       
  1079 				// RFC 1661 4.6
       
  1080 				if(MaxFailureExceeded())
       
  1081 					SendConfigReply(naklist, KPppLcpConfigReject, aId);
       
  1082 				else
       
  1083 					{
       
  1084 					DecrementMaxFailure();
       
  1085 					SendConfigReply(naklist, KPppLcpConfigNak, aId);
       
  1086 					}
       
  1087 				break;
       
  1088 			case ERej:
       
  1089 				SendConfigReply(rejlist, KPppLcpConfigReject, aId);
       
  1090 				break;
       
  1091 			default:
       
  1092 				break;
       
  1093 				}
       
  1094 			break;
       
  1095 		case KPppLcpConfigAck:
       
  1096 		case KPppLcpConfigNak:
       
  1097 		case KPppLcpConfigReject:
       
  1098 			SendConfigRequest();
       
  1099 			SetState(EPppFsmReqSent);
       
  1100 			break;
       
  1101 		default:
       
  1102 			break;
       
  1103 			}
       
  1104 		break;
       
  1105 
       
  1106 	case EPppFsmAckSent:
       
  1107 		switch (aCode)
       
  1108 			{
       
  1109 		case KPppLcpConfigRequest:
       
  1110 			switch (reply)
       
  1111 				{
       
  1112 			case EAck:
       
  1113 				SendConfigReply(acklist, KPppLcpConfigAck, aId);
       
  1114 				break;
       
  1115 			case ENak:
       
  1116 				// RFC 1661 4.6
       
  1117 				if(MaxFailureExceeded())
       
  1118 					SendConfigReply(naklist, KPppLcpConfigReject, aId);
       
  1119 				else
       
  1120 					{
       
  1121 					DecrementMaxFailure();
       
  1122 					SendConfigReply(naklist, KPppLcpConfigNak, aId);
       
  1123 					}
       
  1124 				SetState(EPppFsmReqSent);
       
  1125 				break;
       
  1126 			case ERej:
       
  1127 				SendConfigReply(rejlist, KPppLcpConfigReject, aId);
       
  1128 				SetState(EPppFsmReqSent);
       
  1129 				break;
       
  1130 			default:
       
  1131 				break;
       
  1132 				}
       
  1133 			break;
       
  1134 		case KPppLcpConfigAck:
       
  1135 			if (FsmAckOptionsValid(rcvlist, iRequestList))
       
  1136 				{
       
  1137 				InitRestartCountForConfig();
       
  1138 				FsmRecvConfigAck(rcvlist);
       
  1139 				SetState(EPppFsmOpened);
       
  1140 				FsmLayerUp();
       
  1141 				}
       
  1142 			else
       
  1143 				{
       
  1144 				LOG( iPppLcp->iLogger->Printf(_L("%s FSM - ConfigAck discarded due to option mismatch with original ConfigRequest"), __iFsmName); )
       
  1145 				}
       
  1146 			break;
       
  1147 		case KPppLcpConfigNak:
       
  1148 			InitRestartCountForConfig();
       
  1149 			FsmRecvConfigNak(rcvlist, iRequestList);
       
  1150 			SendConfigRequestAfterNak(rcvlist);
       
  1151 			break;
       
  1152 		case KPppLcpConfigReject:
       
  1153 			if (FsmRejectOptionsValid(rcvlist, iRequestList))
       
  1154 				{
       
  1155 				InitRestartCountForConfig();
       
  1156 				FsmRecvConfigReject(rcvlist, iRequestList);
       
  1157 				SendConfigRequestAfterReject(rcvlist);
       
  1158 				}
       
  1159 			else
       
  1160 				{
       
  1161 				LOG( iPppLcp->iLogger->Printf(_L("%s FSM - ConfigReject discarded due to option mismatch with original ConfigRequest"), __iFsmName); )
       
  1162 				}
       
  1163 			break;
       
  1164 		default:
       
  1165 			break;
       
  1166 			}
       
  1167 		break;
       
  1168 
       
  1169 	case EPppFsmOpened:
       
  1170 		// Config Reset done above
       
  1171 		switch (aCode)
       
  1172 			{
       
  1173 		case KPppLcpConfigRequest:
       
  1174 			SendConfigRequest();
       
  1175 			switch (reply)
       
  1176 				{
       
  1177 			case EAck:
       
  1178 				SendConfigReply(acklist, KPppLcpConfigAck, aId);
       
  1179 				SetState(EPppFsmAckSent);
       
  1180 				break;
       
  1181 			case ENak:
       
  1182 				SendConfigReply(naklist, KPppLcpConfigNak, aId);
       
  1183 				SetState(EPppFsmReqSent);
       
  1184 				break;
       
  1185 			case ERej:
       
  1186 				SendConfigReply(rejlist, KPppLcpConfigReject, aId);
       
  1187 				SetState(EPppFsmReqSent);
       
  1188 				break;
       
  1189 			default:
       
  1190 				break;
       
  1191 				}
       
  1192 			break;
       
  1193 		case KPppLcpConfigAck:
       
  1194 			SendConfigRequest();
       
  1195 			FsmRecvConfigAck(rcvlist);
       
  1196 			SetState(EPppFsmReqSent);
       
  1197 			break;
       
  1198 		case KPppLcpConfigNak:
       
  1199 			FsmRecvConfigNak(rcvlist, iRequestList);
       
  1200 			SendConfigRequestAfterNak(rcvlist);
       
  1201 			SetState(EPppFsmReqSent);
       
  1202 			break;
       
  1203 		case KPppLcpConfigReject:
       
  1204 			FsmRecvConfigReject(rcvlist, iRequestList);
       
  1205 			SendConfigRequestAfterReject(rcvlist);
       
  1206 			SetState(EPppFsmReqSent);
       
  1207 			break;
       
  1208 		default:
       
  1209 			break;
       
  1210 			}
       
  1211 		break;
       
  1212 
       
  1213 	default:
       
  1214 		// Invalid state
       
  1215 		LOG( iPppLcp->iLogger->Printf(_L("%s Invalid state %d"), __iFsmName, iState); )
       
  1216 		break;
       
  1217 		}
       
  1218 	rcvlist.Free();	
       
  1219 	acklist.Free();
       
  1220 	naklist.Free();
       
  1221 	rejlist.Free();
       
  1222 	}	
       
  1223 
       
  1224 void MPppFsm::SendConfigRequest()
       
  1225 /**
       
  1226 Send the config request in iRequestList
       
  1227 */
       
  1228 	{
       
  1229 	if (iPppAbortCode!=KErrNone)
       
  1230 		return;
       
  1231 	
       
  1232 
       
  1233 	// With Mobile IP, there is the possibility of having no options to negotiate, in which case
       
  1234 	// we would send an empty ConfigRequest rather than nothing.
       
  1235 
       
  1236 	TBool emptyList = iRequestList.IsEmpty();
       
  1237 	if (emptyList && !iPppLcp->QueryExternalIPConfiguration())
       
  1238 		{
       
  1239 		LOG( iPppLcp->iLogger->Printf(_L("%s FSM Request list empty"), __iFsmName); )
       
  1240 		return;
       
  1241 		}
       
  1242 
       
  1243 	RMBufPacket pkt;	
       
  1244 	iRequestId &= 0xff;
       
  1245 	TRAPD(err, iRequestList.CreatePacketL(pkt, iPppId, KPppLcpConfigRequest, (TUint8)iRequestId, emptyList));
       
  1246 	if (err!=KErrNone)
       
  1247 		{
       
  1248 		//__DEBUGGER();
       
  1249 		return;
       
  1250 		}
       
  1251 	SendFrame(pkt);
       
  1252 	--iRestartCount;
       
  1253 	TimerCancel();
       
  1254 	TInt temp=iWaitTime;
       
  1255 	if (iPppId==KPppIdIpcp && iLengthenTimers)
       
  1256 		temp=KPppFsmLengthenedRequestTimeout;
       
  1257 	TimerAfter(temp*1000);
       
  1258 	}
       
  1259 
       
  1260 
       
  1261 TInt MPppFsm::InitialiseConfigRequest()
       
  1262 /**
       
  1263 Delete any existing request list, then create a new one.
       
  1264 Initialise counters for sending config requests.
       
  1265 
       
  1266 @return Error code
       
  1267 
       
  1268 @post iRequestList is initialized
       
  1269 */
       
  1270 	{
       
  1271 	iLastCfgReqFcs = 0;
       
  1272 	iConsecCfgReq = 0;
       
  1273 	iRequestId = FsmNewId();
       
  1274 	InitRestartCountForConfig();
       
  1275 	if (!iRequestList.IsEmpty())
       
  1276 		iRequestList.Free();
       
  1277 	TRAPD(err, FsmFillinConfigRequestL(iRequestList));
       
  1278 	return err;
       
  1279 	}
       
  1280 
       
  1281 void MPppFsm::SendInitialConfigRequest()
       
  1282 /**
       
  1283 Initialise request list and send a request if successful.
       
  1284 */
       
  1285 	{
       
  1286 	if (InitialiseConfigRequest()==KErrNone)
       
  1287 		SendConfigRequest();
       
  1288 	}
       
  1289 
       
  1290 void MPppFsm::SendConfigRequestAfterNak(RPppOptionList& /*aOptsList*/)
       
  1291 /**
       
  1292 Update the options list and send a new config request after a Nak.
       
  1293 
       
  1294 @param aOptList Options list (ignored)
       
  1295 */
       
  1296 	{
       
  1297 	iRequestId = FsmNewId();
       
  1298 
       
  1299 	// Calc a 32bit CRC of the request list data
       
  1300 	// and compare with last recorded RequestAfterNAK CRC.
       
  1301 	// If the same, then it is more likely that negotiation
       
  1302 	// is not converging.
       
  1303 	TPppFcs32 fcs;
       
  1304 	iRequestList.Crc32(fcs);
       
  1305 
       
  1306 	if (fcs.Fcs()==iLastCfgReqFcs)
       
  1307 		{
       
  1308 		if (++iConsecCfgReq>KPppFsmNonConvergeLimit)
       
  1309 			{
       
  1310 			LOG( iPppLcp->iLogger->Printf(_L("NonConvergence limit reached")); )
       
  1311 			FsmAbort(KErrTimedOut);
       
  1312 			return;
       
  1313 			}
       
  1314 		}
       
  1315 	else
       
  1316 		{
       
  1317 		iLastCfgReqFcs = fcs.Fcs();
       
  1318 		iConsecCfgReq = 0;
       
  1319 		}
       
  1320 
       
  1321 	SendConfigRequest();
       
  1322 	}
       
  1323 
       
  1324 void MPppFsm::SendConfigRequestAfterReject(RPppOptionList& /*aOptsList*/)
       
  1325 /**
       
  1326 Update the options list and send a new config request after a Reject.
       
  1327 
       
  1328 @param aOptList Options list (ignored)
       
  1329 */
       
  1330 	{
       
  1331 	iRequestId = FsmNewId();
       
  1332 	SendConfigRequest();
       
  1333 	}
       
  1334 
       
  1335 void MPppFsm::SendConfigReply(RPppOptionList& aOptList, TUint8 aType, TUint8 aId)
       
  1336 /**
       
  1337 Reply to a config request with a set of options.
       
  1338 
       
  1339 @param aOptList Options list
       
  1340 @param aType Packet type (Ack, Nak, Rej)
       
  1341 @param aId Packet identifier
       
  1342 */
       
  1343 	{
       
  1344 	if (iPppAbortCode!=KErrNone)
       
  1345 		return;
       
  1346 	
       
  1347 	RMBufPacket pkt;	
       
  1348 	TRAPD(err, aOptList.CreatePacketL(pkt, iPppId, aType, aId, EFalse));
       
  1349 	if (err!=KErrNone)
       
  1350 		{
       
  1351 		//__DEBUGGER();
       
  1352 		return;
       
  1353 		}
       
  1354 	SendFrame(pkt);
       
  1355 //	TimerCancel();
       
  1356 //	TimerAfter(iWaitTime*1000);
       
  1357 	}
       
  1358 
       
  1359 void MPppFsm::SendInitialTerminateRequest()
       
  1360 /**
       
  1361 Send the first Terminate Request packet to begin connection teardown.
       
  1362 */
       
  1363 	{
       
  1364 	iTerminateId = FsmNewId();
       
  1365 	InitRestartCountForTerminate();
       
  1366 	if(iRestartCount > 0)
       
  1367 		{
       
  1368 		SendTerminateRequest();
       
  1369 		}
       
  1370 	else // We are configured to send zero Terminate Requests. 
       
  1371 		{
       
  1372 		TimerCancel();
       
  1373 		TimerAfter(0);	// As if we finished transmitting Terminate Requests.
       
  1374 		}
       
  1375 	}
       
  1376 
       
  1377 void MPppFsm::SendTerminateRequest()
       
  1378 /**
       
  1379 Send a Terminate Request packet.
       
  1380 
       
  1381 @pre SendInitialTerminateRequest() must have previously been called
       
  1382 */
       
  1383 	{
       
  1384 	RMBufPacket pkt;
       
  1385 	const TUint pktLen = 4;
       
  1386 	TUint8* ptr = NewPacket(pkt, pktLen);
       
  1387 	if (ptr == NULL)
       
  1388 		{
       
  1389 		__ASSERT_DEBUG(EFalse,PppPanic(EPppPanic_PPPNoMemory));
       
  1390 		return;
       
  1391 		}
       
  1392 		*ptr++ = KPppLcpTerminateRequest;
       
  1393 		iTerminateId &= 0xff;
       
  1394 		*ptr++ = (TUint8)iTerminateId;
       
  1395 	BigEndian::Put16(ptr, (TUint16)pktLen);
       
  1396 		pkt.Pack();
       
  1397 		SendFrame(pkt);
       
  1398 
       
  1399 		--iRestartCount;
       
  1400 		TimerCancel();
       
  1401 		TInt temp=iWaitTime;
       
  1402 		if (iLengthenTimers)
       
  1403 		temp=KPppFsmLengthenedTerminateTimeout;
       
  1404 	TimerAfter(temp*1000);
       
  1405 	LOG( iPppLcp->iLogger->Printf(_L("Tx: TerminateRequest Id[%d]. Restart Count[%d]"), iTerminateId, iRestartCount); )
       
  1406    	}
       
  1407 
       
  1408 void MPppFsm::SendTerminateAck(TUint8 aId)
       
  1409 /**
       
  1410 Send a Terminate Ack packet.
       
  1411 
       
  1412 @param aId Packet identifier
       
  1413 */
       
  1414 	{
       
  1415 	RMBufPacket pkt;
       
  1416 	const TUint pktLen = 4;
       
  1417 	TUint8* ptr = NewPacket(pkt, pktLen);
       
  1418 	if (ptr == NULL)
       
  1419 		{
       
  1420 		__ASSERT_DEBUG(EFalse,PppPanic(EPppPanic_PPPNoMemory));
       
  1421 		return;
       
  1422 		}
       
  1423 		*ptr++ = KPppLcpTerminateAck;
       
  1424 		*ptr++ = aId;
       
  1425 	BigEndian::Put16(ptr, (TUint16)pktLen);
       
  1426 		pkt.Pack();
       
  1427 		SendFrame(pkt);	
       
  1428  	 	
       
  1429  	 	LOG(iPppLcp->iLogger->Printf(_L("Tx: TerminateAck Id[%d]."),aId);)
       
  1430   		}	
       
  1431 	
       
  1432 void MPppFsm::InitRestartCountForConfig()
       
  1433 /**
       
  1434 Initialize the restart count and wait time
       
  1435 with values appropriate for the config phase.
       
  1436 */
       
  1437 	{
       
  1438 
       
  1439 	// RFC 1661 4.6 Max-Configure
       
  1440 	iWaitTime = iWaitTimeConfig;
       
  1441 	iRestartCount = iMaxRestartConfig;
       
  1442 	}
       
  1443 	
       
  1444 void MPppFsm::InitRestartCountForTerminate()
       
  1445 /**
       
  1446 Initialize the restart count and wait time for
       
  1447 with values appropriate for the termination phase.
       
  1448 */
       
  1449 	{
       
  1450 	if(iNoEvidenceOfPeer)
       
  1451 		{
       
  1452 		// If we've been told to terminate by our control and haven't yet heard anything from the peer then we 
       
  1453 		// don't attempt to send it a disconnect. This is a little unpleasant because if we've sent it a config
       
  1454 		// packet it may be left waiting for us until it times out, however the more likely state is that we
       
  1455 		// haven't yet completed sending the packet to it because the BCA is still waiting on its bearer to
       
  1456 		// set up. Unfortunately we don't seem to have a palatable way to abort this BCA write from here.
       
  1457  	 	LOG(iPppLcp->iLogger->Printf(_L("InitRestartCountForTerminate: no evidence of peer contact so terminating without notice"));)
       
  1458 		ZeroRestartCount();
       
  1459 		}
       
  1460 	else
       
  1461 		{
       
  1462 		iWaitTime     = iTerminateRequestTimeout; 
       
  1463  		iRestartCount = iMaxTerminateRequest;
       
  1464 		}
       
  1465 	}
       
  1466 	
       
  1467 void MPppFsm::ZeroRestartCount()
       
  1468 /**
       
  1469 Clear the restart count.
       
  1470 */
       
  1471 	{
       
  1472 	iRestartCount = 0;
       
  1473 	}
       
  1474 	
       
  1475 TUint8 MPppFsm::FsmNewId()
       
  1476 /**
       
  1477 Generate a new nonzero packet identifier.
       
  1478 
       
  1479 @return Packet identifier
       
  1480 */
       
  1481 	{
       
  1482 	if (++iCurrentId==0)
       
  1483 		++iCurrentId;
       
  1484 	return iCurrentId;
       
  1485 	}
       
  1486 
       
  1487 void MPppFsm::SetState(TPppFsmState aState)
       
  1488 /**
       
  1489 Set the next state in the FSM.
       
  1490 Cancels the timer when appropriate.
       
  1491 
       
  1492 @param aState Next state
       
  1493 */
       
  1494 	{
       
  1495 	LOG( iPppLcp->iLogger->DumpState(__iFsmName, iState, aState); )
       
  1496 	iState = aState;
       
  1497 	if (iState<EPppFsmClosing || iState==EPppFsmOpened)
       
  1498 		{
       
  1499 		if(iState == EPppFsmStarting)
       
  1500 			{
       
  1501 			iNoEvidenceOfPeer = ETrue;
       
  1502 			}
       
  1503 		TimerCancel();
       
  1504 		}
       
  1505 	}
       
  1506 
       
  1507 
       
  1508 void MPppFsm::FsmRejectPacket(RMBufChain& aPacket, TUint aReason, TUint aPppId)
       
  1509 /**
       
  1510 Send a Code Reject or Protocol Reject packet.
       
  1511 
       
  1512 @param aPacket MBuf chain containing packet; it will be used to send the reject message.
       
  1513 @param aReason Reason for rejecting (KPppLcpCodeReject or KPppLcpProtocolReject)
       
  1514 @param aPppId PPP protocol ID
       
  1515 */
       
  1516 	{
       
  1517 	RMBufPacket pkt;
       
  1518 	pkt.Assign(aPacket);
       
  1519 	pkt.Unpack();
       
  1520 	RMBufPktInfo* info = pkt.Info();
       
  1521 	
       
  1522 	// This function reuses the rejected packet chain to send the reject message,
       
  1523 	// so reserve some space at the beginning for the reject header.
       
  1524 	TInt prep = 0;
       
  1525 	if (aReason==KPppLcpCodeReject)
       
  1526 		prep = 4;
       
  1527 	else if (aReason==KPppLcpProtocolReject)
       
  1528 		prep = 6;
       
  1529 	else
       
  1530 		{
       
  1531 		// Unknown reject reason
       
  1532 		pkt.Free();
       
  1533 		return;
       
  1534 		}
       
  1535 
       
  1536 	TRAPD(err, pkt.PrependL(prep));
       
  1537 	if (err!=KErrNone)
       
  1538 		{
       
  1539 		pkt.Free();
       
  1540 		return;
       
  1541 		}
       
  1542 	info->iLength += prep;
       
  1543 
       
  1544 	// If the frame to be sent is too large, lop off the end to make it fit.
       
  1545 	__ASSERT_DEBUG(iPppLcp->MaxTransferSize() > 0, PppPanic(EPppPanic_InvalidData));
       
  1546 	if (info->iLength > iPppLcp->MaxTransferSize())
       
  1547 		{
       
  1548 		pkt.TrimEnd(iPppLcp->MaxTransferSize());
       
  1549 		info->iLength = iPppLcp->MaxTransferSize();
       
  1550 		}
       
  1551 
       
  1552 	TUint8* ptr = pkt.First()->Ptr();
       
  1553 
       
  1554 	*ptr++ = TUint8(aReason);	// xxx
       
  1555 	*ptr++ = FsmNewId();
       
  1556 	BigEndian::Put16(ptr, (TUint16)info->iLength);
       
  1557 	ptr += 2;
       
  1558 	if (aReason==KPppLcpProtocolReject)
       
  1559 		{
       
  1560 		BigEndian::Put16(ptr, (TUint16)TPppAddr::Cast((info->iDstAddr)).GetProtocol());
       
  1561 		TPppAddr::Cast((info->iDstAddr)).SetProtocol(KPppIdLcp);
       
  1562 		}
       
  1563 		
       
  1564 	pkt.Pack();
       
  1565 	if (aPppId == KPppIdAsIs)
       
  1566 		SendFrame(pkt);
       
  1567 	else
       
  1568 		iPppLcp->PppLink()->Send(pkt, aPppId);
       
  1569 	}
       
  1570 
       
  1571 void MPppFsm::ReadIniFileL()
       
  1572 /**
       
  1573 Reads the contents of the ppp.ini file.
       
  1574 
       
  1575 @leave Error code if file cannot be read
       
  1576 */
       
  1577 	// Added September 1999
       
  1578 	// Currently can read from ini file :-
       
  1579 	// Max-Configure
       
  1580 	// Max-Failure
       
  1581 	// Restart Timer
       
  1582 	// Enable TerminateRequest / TerminateAck
       
  1583 	// Max TerminateRequest
       
  1584 	// TerminateRequest timeout
       
  1585 	// TerminateAck timeout		
       
  1586 	{
       
  1587 	// Check the ini file exists and can be opened
       
  1588 	CESockIniData* ini = NULL;
       
  1589 	TRAPD(res,
       
  1590 		if (iPppLcp->PppLinkMode() == CPppLcpConfig::EPppLinkIsServer)
       
  1591 			{
       
  1592 			ini = CESockIniData::NewL(PPP_SERVER_INI_FILE);
       
  1593 			}
       
  1594 		else
       
  1595 			{
       
  1596 			ini = CESockIniData::NewL(PPP_INI_FILE);
       
  1597 			}
       
  1598 		)
       
  1599 	if(res!=KErrNone)
       
  1600 		{
       
  1601 		if(res==KErrNotFound)
       
  1602 			{
       
  1603 			// No .ini file; use default values
       
  1604 			iMaxFailureConfig = KPppMaxFailureDefault;
       
  1605 			iMaxRestartConfig = KPppFsmRequestRetries;
       
  1606 			iWaitTimeConfig = KPppFsmRequestTimeout;
       
  1607 			
       
  1608 			
       
  1609 			// Termination Phase Support.
       
  1610 			// If the .ini file is missing, full support is enabled.
       
  1611 			
       
  1612 			iTerminateRequestEnabled = ETrue;
       
  1613 			iMaxTerminateRequest     = KPppFsmTerminateRequestRetries;
       
  1614 			iTerminateRequestTimeout = KPppFsmTerminateRequestTimeout;
       
  1615  			
       
  1616 			iTerminateAckEnabled = ETrue;
       
  1617 			iTerminateAckTimeout = KPppFsmTerminateAckTimeout;
       
  1618 			
       
  1619 			return;
       
  1620 			}
       
  1621 		User::Leave(res);
       
  1622 		}
       
  1623 	CleanupStack::PushL(ini);
       
  1624 	TInt	entry;
       
  1625 //
       
  1626 // Max-Failure
       
  1627 	// Read enable switch
       
  1628 	if (ini->FindVar(LCPSECTIONNAME,PPPMAXFAILUREENTRYNAME_ENABLE, entry))
       
  1629 		{
       
  1630 		if (entry == 0) 
       
  1631 			iMaxFailureConfig = KPppMaxFailureDefault;
       
  1632 		else
       
  1633 			{
       
  1634 			if (ini->FindVar(LCPSECTIONNAME,PPPMAXFAILUREENTRYNAME_COUNT, entry))
       
  1635 				iMaxFailureConfig = entry;
       
  1636 			else
       
  1637 				iMaxFailureConfig = KPppMaxFailureDefault;
       
  1638 			}
       
  1639 		}
       
  1640 	else
       
  1641 		iMaxFailureConfig = KPppMaxFailureDefault;
       
  1642 
       
  1643 //
       
  1644 // Max-Configure
       
  1645 	// Read enable switch
       
  1646 	if (ini->FindVar(LCPSECTIONNAME,PPPMAXRESTARTENTRYNAME_ENABLE, entry))
       
  1647 		{
       
  1648 		if (entry == 0) 
       
  1649 			iMaxRestartConfig = KPppFsmRequestRetries;
       
  1650 		else
       
  1651 			{
       
  1652 			if (ini->FindVar(LCPSECTIONNAME,PPPMAXRESTARTENTRYNAME_COUNT, entry))
       
  1653 				iMaxRestartConfig = entry;
       
  1654 			else
       
  1655 				iMaxRestartConfig = KPppFsmRequestRetries;
       
  1656 			}
       
  1657 		}
       
  1658 	else
       
  1659 		iMaxRestartConfig = KPppFsmRequestRetries;
       
  1660 //
       
  1661 // Restart Timer
       
  1662 	// Read enable switch
       
  1663 	if (ini->FindVar(LCPSECTIONNAME,PPPRESTARTTIMERENTRYNAME_ENABLE, entry))
       
  1664 		{
       
  1665 		if (entry == 0) 
       
  1666 			iWaitTimeConfig = KPppFsmRequestTimeout;
       
  1667 		else
       
  1668 			{
       
  1669 			if (ini->FindVar(LCPSECTIONNAME,PPPRESTARTTIMERENTRYNAME_PERIOD, entry))
       
  1670 				iWaitTimeConfig = entry;
       
  1671 			else
       
  1672 				iWaitTimeConfig = KPppFsmRequestTimeout;
       
  1673 			}
       
  1674 		}
       
  1675 	else
       
  1676 		iWaitTimeConfig = KPppFsmRequestTimeout;
       
  1677 	
       
  1678 	
       
  1679 	//
       
  1680 	// Support PPP Termination Sequence Configurability, required for
       
  1681  	// CDMA support.
       
  1682  	//
       
  1683  	if(ini->FindVar(LCPSECTIONNAME, TERMINATE_REQUEST_ENABLE, entry))
       
  1684  		{
       
  1685  		if(0 == entry)
       
  1686  			{
       
  1687  			iTerminateRequestEnabled = EFalse; 			
       
  1688  			} 		
       
  1689  		}
       
  1690  		
       
  1691  	// Max Terminate Requests to be sent.
       
  1692  	if(iTerminateRequestEnabled)
       
  1693  		{
       
  1694  		if(ini->FindVar(LCPSECTIONNAME, MAX_TERMINATE_REQUEST_ENABLE, entry))
       
  1695 	 		{
       
  1696 	 		if(0 != entry)	
       
  1697 	 			{
       
  1698 	 		   	if (ini->FindVar(LCPSECTIONNAME, MAX_TERMINATE_REQUEST_COUNT, entry))
       
  1699 	 				{
       
  1700 	 				iMaxTerminateRequest = entry;
       
  1701 	 				}
       
  1702 	 			}
       
  1703 	 		} 	
       
  1704 	 		
       
  1705 	 	// Normal Terminate Request timeout
       
  1706 	 	if(ini->FindVar(LCPSECTIONNAME, TERMINATE_REQUEST_TIMER_ENABLE, entry))
       
  1707 	 		{
       
  1708 	 		if(0 != entry)	
       
  1709 	 			{
       
  1710 	 			if (ini->FindVar(LCPSECTIONNAME, TERMINATE_REQUEST_TIMER_PERIOD, entry))
       
  1711 	 				{
       
  1712 	 				iTerminateRequestTimeout = entry;
       
  1713 	 				}
       
  1714 	 			}
       
  1715 	 		}	 		 
       
  1716 		}
       
  1717 	else
       
  1718 		{
       
  1719 		// Special Case: Support legacy shutdown behaviour: send only one Terminate Request.
       
  1720 		// To disable sending TerminatRequest entirely, Enable TerminateRequest, and set MaxTerminateRequest to 0.
       
  1721 		// When support for legacy shutdown is not necessary, this code can be safely removed.
       
  1722 		iMaxTerminateRequest = 1;		
       
  1723 		}
       
  1724 		
       
  1725 	//
       
  1726 	// Terminate ACK configurability
       
  1727 	//
       
  1728 	// Is sending a configure ACK enabled?
       
  1729  	if(ini->FindVar(LCPSECTIONNAME, TERMINATE_ACK_ENABLE, entry))
       
  1730  		{
       
  1731  		if(0 == entry)	
       
  1732  			{
       
  1733  			iTerminateAckEnabled = EFalse;
       
  1734  			}
       
  1735  		}
       
  1736  	
       
  1737  	// Read Terminate ACK settings only if it is enabled
       
  1738  	if(iTerminateAckEnabled)
       
  1739  		{
       
  1740  		if(ini->FindVar(LCPSECTIONNAME, TERMINATE_ACK_TIMER_ENABLE, entry))
       
  1741  			{	
       
  1742  			if(0 != entry)
       
  1743  				{	
       
  1744  				if(ini->FindVar(LCPSECTIONNAME, TERMINATE_ACK_TIMER_PERIOD, entry))
       
  1745  					{
       
  1746  					iTerminateAckTimeout = entry;
       
  1747  					} 				
       
  1748  				} 			
       
  1749  			} 			 			
       
  1750  		}
       
  1751  
       
  1752  	// Setting that controls doubling of timeout value on restart timer
       
  1753  	if (ini->FindVar(LCPSECTIONNAME, PPP_RESTARTTIMER_ENTRYNAME_MODE, entry))
       
  1754  		{
       
  1755  		if (entry == 1)
       
  1756  			{
       
  1757  			iWaitTimeNoIncrease = ETrue;
       
  1758  			}
       
  1759  		}
       
  1760  
       
  1761  		
       
  1762  	CleanupStack::PopAndDestroy();
       
  1763 	}
       
  1764 
       
  1765 TUint8* MPppFsm::NewPacket(RMBufPacket& aPkt, TUint aLength)
       
  1766 /**
       
  1767 Allocate a new packet buffer and info header. The caller must fill in the
       
  1768 the packet and call its Pack() method before sending.
       
  1769 
       
  1770 @param aPkt reference to a packet
       
  1771 @param aLength length of the buffer
       
  1772 @return pointer to the beginning of the first packet in the chain or NULL on error
       
  1773 
       
  1774 @see RPppOptionList::CreatePacketL
       
  1775 */
       
  1776 	{
       
  1777 	TRAPD(err, aPkt.AllocL(aLength));
       
  1778 	if (err != KErrNone)
       
  1779 		{
       
  1780 		return NULL;
       
  1781 		}
       
  1782 	RMBufPktInfo* info=NULL;
       
  1783 	TRAP(err,info = aPkt.NewInfoL());
       
  1784 	if (err != KErrNone)
       
  1785 		{
       
  1786 		aPkt.Free();
       
  1787 		return NULL;
       
  1788 		}
       
  1789 	info->iLength = aLength;
       
  1790 	TPppAddr::Cast((info->iDstAddr)).SetProtocol(iPppId);
       
  1791 	return aPkt.First()->Ptr();
       
  1792 	}
       
  1793 
       
  1794 
       
  1795 TBool MPppFsm::FsmAckOptionsValid(RPppOptionList& /*aList*/, RPppOptionList& /*aRequestList*/)
       
  1796 /**
       
  1797 Perform validation checking on the option list of a ConfigAck or ConfigReject.
       
  1798 
       
  1799 @param aList option list of incoming ConfigAck or ConfigReject
       
  1800 @return ETrue if options valid, else EFalse.  EFalse return causes packet to be discarded.
       
  1801 */
       
  1802 	{
       
  1803 	return ETrue;
       
  1804 	}
       
  1805 
       
  1806 TBool MPppFsm::FsmRejectOptionsValid(RPppOptionList& /*aList*/, RPppOptionList& /*aRequestList*/)
       
  1807 /**
       
  1808 Perform validation checking on the option list of a ConfigAck or ConfigReject.
       
  1809 
       
  1810 @param aList option list of incoming ConfigAck or ConfigReject
       
  1811 @return ETrue if options valid, else EFalse.  EFalse return causes packet to be discarded.
       
  1812 */
       
  1813 	{
       
  1814 	return ETrue;
       
  1815 	}
       
  1816 TBool MPppFsm::FsmConfigRequestOptionsValid(RPppOptionList& /*aList*/)
       
  1817 /**
       
  1818 Perform validation checking on the option list of a ConfigRequest.
       
  1819 
       
  1820 @param aList option list of incoming ConfigRequest
       
  1821 @return ETrue if options valid, else EFalse.  EFalse return causes packet to be discarded.
       
  1822 */
       
  1823 	{
       
  1824 	return ETrue;
       
  1825 	}
       
  1826