linklayerprotocols/pppnif/SPPP/PPPLRD.CPP
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linklayerprotocols/pppnif/SPPP/PPPLRD.CPP	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,204 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <es_ini.h>
+#include <in_iface.h>
+#include "PPPLRD.H"
+#include "PPPLOG.H"
+#include "PPPLCP.H"
+#include "PPPBASE.H"
+
+//
+CPppLrd::CPppLrd(CPppLcp* aPppLcp):iPppLcp(aPppLcp)
+	{}
+	
+CPppLrd::~CPppLrd()
+	{
+	TimerCancel();
+	TimerDelete();
+	}
+	
+CPppLrd* CPppLrd::NewL(CPppLcp* aPppLcp)
+/**
+Create a new object instance.
+
+@return Pointer to new object
+*/
+	{
+	CPppLrd* self=new (ELeave)CPppLrd(aPppLcp);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+    CleanupStack::Pop();
+	return self;
+	}
+	
+void CPppLrd::ConstructL()
+/**
+Initialize the object and start the timer.
+*/
+	{
+	iShiftRegister = KShiftRegisterWidth;
+	iBitCount = KSampleWidth;
+	TimerConstructL(KPppLrdTimerPriority);
+	// Initialise with default value
+	iPppLrdEnabled	= KPppLrdDefaultEnabledMode; 
+	iLrdPeriod		= KPppLrdDefaultTimerPeriod; 
+	// Override default with values from INI file
+	ReadIniFileL();
+	StartTimer();
+	}
+
+void CPppLrd::ReadIniFileL()
+/**
+Read the LRD section of the ppp.ini file.
+*/
+	{
+	CESockIniData* ini = NULL;
+	TRAPD(res,
+		if (iPppLcp->PppLinkMode() == CPppLcpConfig::EPppLinkIsServer)
+			{
+			ini = CESockIniData::NewL(PPP_SERVER_INI_FILE);
+			}
+		else
+			{
+			ini = CESockIniData::NewL(PPP_INI_FILE);
+			}
+		)
+	if(res!=KErrNone)
+		{
+		if(res==KErrNotFound)
+			return;
+		User::Leave(res);
+		}
+	CleanupStack::PushL(ini);
+	TInt	entry = 0;
+	// Read enable switch
+	if (ini->FindVar(LRDSECTIONNAME,LRDENTRYNAME_ENABLE, entry))
+		{
+		if (entry == 0) 
+			iPppLrdEnabled = EFalse;
+		else
+			iPppLrdEnabled = ETrue;
+		}
+	// Read period value
+	if (ini->FindVar(LRDSECTIONNAME,LRDENTRYNAME_PERIOD, entry))
+		{
+		if((entry >= KPppLrdTimerPeriodMin) && (entry <=KPppLrdTimerPeriodMax))
+			iLrdPeriod = entry;
+		}
+
+	CleanupStack::PopAndDestroy();
+	}
+
+void CPppLrd::StartTimer()
+/**
+Start the timer.
+*/
+	{
+	if(iPppLrdEnabled)
+		{
+		iLastEchoAck = ETrue;
+		TimerAfter(iLrdPeriod*1000000);
+		}
+	}
+
+void CPppLrd::StopTimer()
+/**
+Stop the timer.
+*/
+	{
+	TimerCancel();
+	}
+
+void CPppLrd::RecvEchoReply(TUint8 aIdentifier)
+/**
+Upcall from LCP when an Echo Reply packet is received.
+
+@param aIdentifier Packet identifier
+*/
+	{
+	// Check this reply matches the last request
+	iLastEchoAck = (iLastEchoAck || (iEchoReqFrameIdentifier == aIdentifier));
+	LOG( iPppLcp->iLogger->Printf(_L("CPppLrd::RecvEchoReply "));)
+	if(iLastEchoAck)
+		{LOG( iPppLcp->iLogger->Printf(_L("TRUE\n"));)}
+	else
+		{LOG( iPppLcp->iLogger->Printf(_L("FALSE\n"));)}
+	}
+	
+void CPppLrd::TimerComplete(TInt /*aStatus*/)
+/**
+Checks how many Echo Reply packets we've received and shuts down the link
+if we've missed too many.  If we're still OK, send another Echo Request.
+Called by MTimer on timer expiry.
+
+@param aStatus Aynchronous request completion status (ignored)
+*/
+	{
+	// Shift Register
+	iShiftRegister <<=1;
+	// Update Bit counter
+	iBitCount -= (iShiftRegister & KBitOverflow ? 1:0);
+	// Update Register with last answer
+	iShiftRegister |=(iLastEchoAck?1:0);
+	// Update Bit counter
+	iBitCount += (iLastEchoAck?1:0);
+	LOG( iPppLcp->iLogger->Printf(_L("CPppLrd::TimerComplete \n")); )
+	//  Check the number of missed echo answers
+	if(iBitCount == (KSampleWidth-KMaxNFailure))
+		{
+		// too many missed replies - we're dead
+		// signal that to the PPP stack
+		// with code below? - Check that 1st
+		// Changed Error Code to reflect faulty transmission chain
+		iPppLcp->Stop(KErrIfLRDBadLine,MNifIfNotify::EDisconnect);
+		LOG( iPppLcp->iLogger->Printf(_L("Lrd detected a link FAILURE\nDropping the connection\n")); )
+		return;
+		}
+	// Otherwise if we're opened carry on sending echo request
+	if(iPppLcp->FsmIsThisLayerOpen())
+		iEchoReqFrameIdentifier = iPppLcp->SendEchoRequest();
+	else 
+		iEchoReqFrameIdentifier = 0;
+	if(iEchoReqFrameIdentifier)
+		iLastEchoAck = EFalse;
+	else
+		// if for some reason sending the echo req failed
+		// disable decrementing the counter
+		// We still trigger the timer and retry later on
+		iLastEchoAck = ETrue;
+	TimerAfter(iLrdPeriod*1000000);
+	}
+
+void CPppLrd::EnableOrDisableTimer(TBool aEnable)
+/**
+Leave enabled or disable the echo check by starting or stopping the timer.
+If the timer is stopped, it will not be restarted by this method.
+
+@param aEnable EFalse to stop the timer
+*/
+	{
+	if (!aEnable)
+		{
+		StopTimer();
+		iPppLrdEnabled=EFalse;
+		}
+	else
+		{
+		iPppLrdEnabled=ETrue;	
+		// TODO: do we need to reset anything here?
+		}
+	}
+