linklayerprotocols/pppnif/te_ppp/dummyppp/src/dummypppnif.cpp
changeset 0 af10295192d8
child 5 1422c6cd3f0c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linklayerprotocols/pppnif/te_ppp/dummyppp/src/dummypppnif.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,3749 @@
+// Copyright (c) 2002-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:
+// This module contains the code for the dummy PPP Nif class which communicates with the upper PPP Nif
+// via PPP "proxy"
+// 
+//
+
+#include <comms-infras/nifif.h>
+#include <nifvar.h>
+#include <nifutl.h>
+#include <es_mbuf.h>
+#include <comms-infras/commsdebugutility.h>
+#include <connectprog.h>
+#include <in_chk.h>
+#include <commsdattypeinfov1_1.h>
+
+//New ppp progress states file
+#include "PppProg.h"
+
+#include "dummypppnif.h"
+#include "DummyPPPNifVar.h"
+
+
+const TInt KLoWatMark = 2;
+const TInt KHiWatMark = 6;
+
+
+// Internal flag bits used  
+const TUint KDummyPPPSendBusy = 0x00001000;
+const TUint KDummyPPPApplyPending = 0x00010000;
+
+//only for generating the logs
+_LIT(KCodeTextString,"	%s [0x%02x]");
+_LIT(KCodeTextWithoutSpacesString,"	%s [0x%02x]");
+_LIT(KIdentifierLengthString,"	Id = 0x%02x, Len = %d");
+_LIT(KLengthString,"	Length = %d");
+_LIT(KLengthString2,"	    Length = 0x%02x");
+_LIT(KTCPLengthString,"	    Length = %d, Hdr len = %d");
+_LIT(KUDPLengthPortString,"	    Length = %d, Src port = %d, Dst port = %d");
+_LIT(KBytesRemainingString,"        %d byte%s remaining");
+_LIT(KLcpCodeString,"	Code = %s [0x%02x]");
+_LIT(KCodeString,"	Code = 0x%02x");
+_LIT(KCodeString2,"	Code = 0x%04x");
+_LIT(KProtocolString,"	Protocol = 0x%04x");
+_LIT(KNumberString,"	Number = 0x%08x");
+_LIT(KSecondsString,"	Seconds = %d");
+_LIT(KSizeString,"	    Size = %d");
+_LIT(KMapString,"	    Map = 0x%08x");
+_LIT(KProtocolTextString,"	    Protocol = %s [0x%04x]");
+_LIT(KLcpOptFcsTypeString,"	    Types =%s%s%s");
+_LIT(KMaximumBytesString,"	    Maximum bytes = %d");
+_LIT(KUserNameString,"	Username = \"%S\"");
+_LIT(KPasswordString,"	Password = \"%S\"");
+_LIT(KMessageString,"	Message = \"%S\"");
+_LIT(KDelayString,"	    Delay=%d\n");
+_LIT(KNameString,"	Name = \"%S\"");
+_LIT(KChangeMaskString,"	Change Mask = 0x%x: ");
+_LIT(KChecksumString,"	Checksum = 0x%x");
+_LIT(KChecksumString3,"	    Chksum = 0x%04x (0x%04x) !!!");
+_LIT(KConnectionString,"	    Connection = 0x%x");
+_LIT(KHdrLengthString,"	Length = %d, Hdr len = %d");
+_LIT(KIDFragmentString,"	Id = 0x%04x, Fragment = %d %s%s%s");
+_LIT(KSrcDstAddrString,"	Src = %d.%d.%d.%d, Dst = %d.%d.%d.%d");
+_LIT(KIpv6SrcAddress,"    Src = %x:%x:%x:%x:%x:%x:%x:%x");
+_LIT(KIpv6DstAddress,"    Dst = %x:%x:%x:%x:%x:%x:%x:%x");
+_LIT(KIpv6Class,"    Class = %d");
+_LIT(KIpv6FlowLabel,"    FlowLabel = %d");
+_LIT(KIpv6PayloadLen,"    Payload = %d words");
+_LIT(KIpv6NextHeadType,"    Next Header type is [%d]");
+_LIT(KIpv6HopLimit,"    Hop Limit is %d");
+_LIT(KIpv6UnknownHeadType,"    Unknown next header: [%d]");
+_LIT(KConnectionNoString,"	Connection number [0x%02x]");
+_LIT(KRemoteAddrString,"	    Remote Address = %d.%d.%d.%d");
+_LIT(KOurAddrString,"	    Our Address = %d.%d.%d.%d");
+_LIT(KMaxSlotString,"	      Max Slot Id = %d");
+_LIT(KCompSlotString,"	      Comp Slot Id = %d");
+_LIT(KAddrString,"	    Address = %d.%d.%d.%d");
+_LIT(KPortString,"	    Src port = %d, Dst port = %d");
+_LIT(KWindowUrgentString,"	    Window = %d, Urgent = %d");
+_LIT(KSeqAckString,"	    Seq = 0x%08x, Ack = 0x%08x");
+_LIT(KFlagsString,"	    Flags = %s%s%s%s%s%s");
+
+#define EIGHT_SPACE_MARGIN			_S("        ")
+#define FOURTEEN_SPACE_MARGIN		_S("              ")
+
+/*
+ * This sections defines a whole load of constants etc... not very exciting
+ */
+#ifdef __FLOG_ACTIVE
+_LIT8(KDummyPppLogFolder	,"dummypppnif");
+_LIT8(KDummyPppLogFile, "dummypppnif.txt");
+#endif // #ifdef __FLOG_ACTIVE
+
+_LIT(KEndOfLine, "\n");
+
+/*
+ * The Link class
+ */
+
+CDummyPPPLink::CDummyPPPLink(CNifIfFactory& aFactory)
+	: CNifIfLink(aFactory)
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP Link Created\r\n"));
+	}
+
+CDummyPPPLink::~CDummyPPPLink()
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP Link Destroyed\r\n"));
+	TimerDelete();
+	iNifIf->End();
+	iNifIf->CloseLog();
+	}
+ 
+void CDummyPPPLink::OpenL()
+//
+// Start connect establishment
+//
+	{
+	switch (iState)
+		{
+	case EDummyPPPLinkConnecting:
+	case EDummyPPPLinkOpen:
+		return;
+	case EDummyPPPLinkClosed:
+		iState = EDummyPPPLinkConnecting;
+		break;
+	default:
+		return;
+		}
+	CDummyNifLog::Printf(_L("Dummy PPP LinkOpen\r\n"));
+	}
+
+void CDummyPPPLink::LinkDown(TInt /*aStatus*/)
+//
+// Link down - drop out of packet mode
+// and notify reason
+//
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP LinkDown\r\n"));
+	iState = EDummyPPPLinkClosed;
+	}
+ 
+TInt CDummyPPPLink::Send(RMBufChain& aPdu, TAny* aSource)
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP LinkSend\r\n"));
+
+	return iNifIf->Send(aPdu, aSource);
+	}
+TInt CDummyPPPIf::Send(RMBufChain& aPacket, TAny* )
+{
+	
+	//To send over serial port to NTRAS
+	//return Send(aPacket, iDummyPPPId);
+
+	CDummyNifLog::Write(_L("DummyPPP::RecvdfromPPP\n"));
+	CDummyNifLog::Printf(_L("Dummy PPP Send\r\n"));
+	logUser->Dump(aPacket, KDummyPPPRecvChannel);
+
+	//Added to send to PPP interface directly
+	if(!ProcessPPPPacket(aPacket))
+	{
+		if(SwitchIPHeaders(*ptrTransPktPPP))
+		{
+			SendtoPPP(*ptrTransPktPPP);
+		}
+
+	}
+	return iSendFlowOn;
+}
+
+TInt CDummyPPPIf::SwitchIPHeaders(RMBufChain& aPacket)
+{
+	CDummyNifLog::Printf(_L("DummyPPP::SwitchIPHeaders\r\n"));
+	TInt iResult = 0;
+	// this received data has already been looped back...
+	// get the ip header from the RMBufChain
+	TInet6HeaderIP4* ip4 = (TInet6HeaderIP4*) aPacket.First()->Next()->Ptr();
+	// get the udp header as well - assume only udp traffic here
+	TInet6HeaderUDP* udp = (TInet6HeaderUDP*) ip4->EndPtr();
+
+	TUint dstPort = udp->DstPort();
+	if(KDummyPppNifCmdPort == dstPort)
+	{	
+		// let's use the first payload byte as the command byte
+		if(*(udp->EndPtr())== KForceDisconnect)
+		{
+			CDummyNifLog::Printf(_L("DummyPPP::Sending LinkLayerDown signal\r\n"));
+			// do some action
+			iNotify->IfProgress(KLinkLayerClosed, KErrCommsLineFail);
+			iNotify->LinkLayerDown(KErrCommsLineFail, MNifIfNotify::EDisconnect);
+		}
+	}
+	else
+	{
+
+		// update the headers (addresses, checksums etc) to UpdateHeaders(ip4, udp);
+		// swap over the destination and source addresses
+		TUint32 tempSrc,tempDest;
+		tempSrc = ip4->SrcAddr();
+		tempDest = ip4->DstAddr();
+    
+		ip4->SetSrcAddr(tempDest);
+		ip4->SetDstAddr(tempSrc);
+
+		TUint tempChksum;
+		tempChksum = ip4->Checksum();
+		// we've changed the ip hdr so need to recalculate the ip hdr checksum
+		ip4->SetChecksum(0); 
+		tempChksum = TChecksum::Calculate((TUint16*)ip4, ip4->HeaderLength());
+		tempChksum = TChecksum::ComplementedFold(tempChksum);
+		ip4->SetChecksum(tempChksum);
+		//ip4->SetChecksum(TChecksum::ComplementedFold(TChecksum::Calculate((TUint16*)ip4, ip4->HeaderLength())));
+
+		// also want to set the udp checksum to zero cos it will be wrong now that we have 
+		// changed the ip hdr - just set to zero and it is ignored
+		udp->SetChecksum(0);
+		iResult = 1;
+	}
+	return iResult;
+}
+void CDummyPPPIf::SendtoPPP(RMBufChain& aPacket)
+{
+	CDummyNifLog::Printf(_L("Dummy PPP SendtoPPP\r\n"));
+	iSendNumBufs += aPacket.NumBufs();
+	iLink->iSendQ.Append(aPacket);
+
+	switch (iLink->iState)
+		{
+	case EDummyPPPLinkConnecting:
+		aPacket.Free();
+		break;
+	case EDummyPPPLinkOpen:
+		if (iSendFlowOn && iSendNumBufs>=iSendHiWat)
+			{
+			iSendFlowOn = EFalse;
+			CDummyNifLog::Printf(_L("DummyPPP::SendtoPPP() Flow off, iSendNumBufs %d"), iSendNumBufs);
+			}
+		else if (!(iFlags & KDummyPPPSendBusy))
+			DoSendtoPPP();
+		break;
+	case EDummyPPPLinkClosed:
+		{
+		TRAPD(err, iLink->OpenL());
+		aPacket.Free();
+		}
+		break;
+	default:
+		aPacket.Free();
+		break;
+		}
+	
+	iSendCallBack->CallBack();
+}
+
+TInt CDummyPPPIf::SendCallBack(TAny* aCProtocol)
+	{
+	((CDummyPPPIf*)aCProtocol)->DoSendtoPPP();
+	return 0;
+	}
+void CDummyPPPIf::DoSendtoPPP()
+{
+	if (iFlags & KDummyPPPSendBusy)
+		return;
+	
+    if (ipktRecvPPP.IsEmpty())
+	{
+   		RMBufPacket pkt;
+		if (!iLink->iSendQ.Remove(pkt))
+		{
+			iSendNumBufs=0; // Must be so
+			return;
+		}
+	
+		CDummyNifLog::Write(_L("DummyPPP::DoSendtoPPP()\n"));
+		logUser->Dump(pkt, KDummyPPPSendChannel);
+
+		// Get next packet from send queue
+		do
+			{
+			iFlags |= KDummyPPPSendBusy;
+			iSendNumBufs -= pkt.NumBufs();
+			iProtocol->Process(pkt, (CProtocolBase*)this);
+
+			// the following Free() may not actually do anything if the packet has already been freed.
+			pkt.Free();
+
+			if (!iSendFlowOn && iSendNumBufs<iSendLoWat)
+				{
+				CDummyNifLog::Printf(_L("DummyPPP::DoSendtoPPP(): Flow on, iSendNumBufs %d"), iSendNumBufs);
+				iSendFlowOn = ETrue;
+				//for CppLcp's LinkFlowOn()
+				iProtocol->StartSending(iProtocol);
+				}
+			} while (iLink->iSendQ.Remove(pkt));
+		iFlags &= ~KDummyPPPSendBusy;
+	}
+}
+
+TInt CDummyPPPIf::ProcessPPPPacket(RMBufChain& aPacket)
+/**
+ * Processes all packets received from PPP
+ *
+ * @param RMBufChain& aPacket
+ * @returns nonzero if completed task
+ * @returns 0 if need to send it to PPP
+ */
+{
+	// Check if Handle ConfigRequest, ConfigAck, ConfigNak 
+	//not responding to ConfigReject
+	CDummyNifLog::Printf(_L("Dummy PPP ProcessPPPPacket\r\n"));
+    TUint result = 0;
+
+	result = DecodePacket(aPacket);
+	if(result == 1) 
+	{	if(iCodeRec == KPppLcpConfigReject)
+		{
+			//Panic as DpppLink does not respond to protocol reject
+		}
+		else
+		{
+			if(((iCodeRec == KPppLcpConfigAck)
+				||(iCodeRec == KPppLcpConfigNak)
+				||(iCodeRec == KPppLcpConfigRequest))
+				&&(iDummyPPPState<EDummyPPPFsmOpened))
+			{
+				ProcessConfig();
+			}
+			else
+			{
+				ProcessPAPandIPCP();
+			}
+		}
+		ipktRecvPPP.Free();
+	}
+    if(result == 0)
+	{
+		//Added to initialize the SendPPP index	
+		ipktRecvPPP.Pack();
+		ptrTransPktPPP = &ipktRecvPPP;
+		SetupSendPPP();
+	}
+	return result;
+}
+
+TInt CDummyPPPIf::DecodePacket(RMBufChain& aPacket)
+/**
+ * Decodes RMBufChain received from PPP
+ *
+ * @param RMBufChain& aPacket
+ * @returns 1 if need processing further
+ * @returns 0 if need to send it to PPP
+ * @returns 2 if packet is discarded
+ */
+{
+	TInt result = 0;
+	
+	// N.B. ipktRecvPPP must be freed at the end of the previous receive / send sequence.
+	// Freeing it here merely covers for a defect where it is not freed as expected.
+	// Doubly freeing RMBufChain does not result in error. 
+	ipktRecvPPP.Free();
+	
+	// If ipktRecvPPP not Freed, Assign Panics.
+	ipktRecvPPP.Assign(aPacket);
+	ipktRecvPPP.Unpack();
+	RMBufPktInfo* info = ipktRecvPPP.Info();
+
+	CDummyNifLog::Printf(_L("Dummy PPP DecodePacket\r\n"));
+	// Extract and drop LCP header
+	ipktRecvPPP.Align(4);
+	TUint8* ptr = ipktRecvPPP.First()->Ptr();
+	iCodeRec = *ptr++;
+	iIdRec = *ptr++;
+	iLenRec = BigEndian::Get16(ptr);
+	
+	// Check packet length is OK
+	if (info->iLength<iLenRec || info->iLength<4 || info->iLength!=iLenRec)
+	{
+		// Too short!
+		ipktRecvPPP.Free();
+		return result;
+	}
+	else 
+	{
+		if (info->iLength>iLenRec)
+			ipktRecvPPP.TrimEnd(iLenRec);
+	}
+
+	if(iCodeRec == KPppLcpConfigReject)
+	{
+		//not responding to protocol reject
+		return result;
+	}
+
+	// If op is unknown
+	switch (iCodeRec)
+		{
+	case KPppLcpConfigAck:
+	case KPppLcpConfigNak:
+		// Filter out bad acks
+		if (iDummyPPPState>=EDummyPPPFsmReqSent && iIdRec!=iDummyPPPRequestId)
+			break;
+		else
+			iDummyPPPRequestId |= KPppRequestIdAnswered;
+		// fall through ...
+	case KPppLcpConfigRequest:
+		// Option negotiation ops
+		// Split the MBuf chain in separate options
+
+		//if(len<=4)
+		if(iLenRec<4)
+			break;
+		
+		//
+		// Hmmm sometimes we receive a Config request of Length 4
+		// i.e. no options Send a Config ACK
+		// 
+		if ( (iLenRec == 4) && (iCodeRec == KPppLcpConfigRequest))
+			{
+			result = 1;
+			break;
+			}
+		if (iLenRec == 4)
+			{
+			break;
+			}
+		else
+			{
+			ipktRecvPPP.TrimStart(4);
+			//ProcessConfig(op, id, len-4, pkt);
+			result = 1;
+			break;
+			}
+	case KPppLcpTerminateAck:
+		//To be opened only in case if Dummy PPPNif sends Terminate Request so blocked
+
+		// Filter out bad acks
+		//if ((iDummyPPPState==EPppFsmClosing || iDummyPPPState==EPppFsmStopping) && id!=iTerminateId)
+		//	break;
+		//else
+		//	iTerminateId |= KPppRequestIdAnswered;
+		// fall through ...
+	case KPppLcpTerminateRequest:
+		if(iLenRec<4)
+			break;
+
+		ipktRecvPPP.TrimStart(4);
+		ProcessTerminate();
+		result = 2;
+		break;
+	
+	default:
+		break;
+	}
+	//pkt.Free();
+	if(iDummyPPPState==EDummyPPPFsmIPOpen)
+		result = 0;
+	return result;
+
+	}
+
+void CDummyPPPIf::ProcessConfig()
+	{	
+
+	// Split the recvd packet into separate options
+	// placing each option in a queue where it can be
+	// easily parsed and manipulated in the upcall handlers.
+	RPppOptionList rcvlist;	// Recvd list of options
+ 
+	
+	RPppOptionList acklist;	// List of Ack'd options - only valid of the following are empty
+	RPppOptionList naklist;	// List of Nak'd options - only valid of the following is empty
+	RPppOptionList rejlist;	// List of Rejected options
+
+	CDummyNifLog::Printf(_L("Dummy PPP ProcessConfig\r\n"));
+
+	enum TDummyPPPResult { ENop, EAck, ENak, ERej };
+
+	TDummyPPPResult reply = ENop;
+
+    TRAPD(err, rcvlist.SetL(ipktRecvPPP));
+	if (err!=KErrNone)
+		return;
+
+	if (iCodeRec == KPppLcpConfigRequest)
+		{
+		// About to drop out of opened state to need to reset things
+		// BEFORE the new request is processed.
+		if (iDummyPPPState == EDummyPPPFsmOpened)
+			{
+			TRAPD(err, InitialiseConfigRequestL());
+			if (err != KErrNone)
+				{
+				CDummyNifLog::Printf(_L("Dummy PPP InitialiseConfigRequestL failed\r\n"));
+				return;
+				}
+			}
+		
+		// Check options, and split into list of OK, Bad and Unknown
+		// Note - the naklist options will have been updated to
+		// contain acceptable values.
+		if (iCodeRec==KPppLcpConfigRequest)
+			CheckRecvConfigRequest(rcvlist, acklist, naklist, rejlist);
+
+		if (!rejlist.IsEmpty())
+			{
+			reply = ERej;
+			naklist.Free();
+			acklist.Free();
+			}
+		else if (!naklist.IsEmpty())
+			{
+			reply = ENak;
+			acklist.Free();
+			}
+		else if (!acklist.IsEmpty())
+			{
+			reply = EAck;
+			SetupConfigRequest(acklist);
+			}
+			
+			//Added to initialize the SendPPP index
+			ipktRecvPPP.Pack();
+			ptrTransPktPPP = &ipktRecvPPP;
+		}		
+
+	// State processing
+
+	switch (iDummyPPPState)
+		{
+
+	case EDummyPPPFsmInitial:
+	case EDummyPPPFsmStarting:
+		TRAPD(err, InitialiseConfigRequestL());
+		if (err==KErrNone)
+			SendConfigRequest();
+		SetState(EDummyPPPFsmReqSent);
+	case EDummyPPPFsmClosing:
+	case EDummyPPPFsmStopping:
+		break;
+	case EDummyPPPFsmClosed:
+		SetPppId(KPppIdLcp);
+		SendTerminateAck();
+		break;
+
+	case EDummyPPPFsmStopped:
+		switch (iCodeRec)
+			{
+		case KPppLcpConfigRequest:
+			TRAPD(err, InitialiseConfigRequestL());
+			if (err==KErrNone)
+			{
+				SendConfigRequest();
+				SetPppId(KPppIdLcp);
+			}
+			switch (reply)
+				{
+			case EAck:
+				SendConfigReply(acklist, KPppLcpConfigAck);
+				SetState(EDummyPPPFsmAckSent);
+				break;
+			case ENak:
+				SendConfigReply(naklist, KPppLcpConfigNak);
+				SetState(EDummyPPPFsmReqSent);
+				break;
+			case ERej:
+				SendConfigReply(rejlist, KPppLcpConfigReject);
+				SetState(EDummyPPPFsmReqSent);
+				break;
+			default:
+				break;
+				}
+			break;
+		case KPppLcpConfigAck:
+		case KPppLcpConfigNak:
+		//Not responding to a reject
+		//case KPppLcpConfigReject:
+			SetPppId(KPppIdLcp);
+			SendTerminateAck();
+			break;
+			}
+		break;
+	
+	case EDummyPPPFsmReqSent:
+		switch (iCodeRec)
+			{
+		case KPppLcpConfigRequest:
+			switch (reply)
+				{
+			case EAck:
+				SendConfigReply(acklist, KPppLcpConfigAck);
+				SetState(EDummyPPPFsmAckSent);
+				break;
+			case ENak:
+				// RFC 1661 4.6
+				if(CheckMaxFailureExceeded() == TRUE)
+					SendConfigReply(naklist, KPppLcpConfigReject);
+				else
+					{
+					DecrementDummyPPPMaxFailureCount();
+					SendConfigReply(naklist, KPppLcpConfigNak);
+					}
+				break;
+			case ERej:
+				SendConfigReply(rejlist, KPppLcpConfigReject);
+				SetState(EDummyPPPFsmReqSent);
+				break;
+			default:
+				break;
+				}
+			break;
+		case KPppLcpConfigAck:
+			InitRestartCountForConfig();
+			CheckRecvConfigAck(rcvlist);
+			SetState(EDummyPPPFsmAckRecvd);
+			break;
+		case KPppLcpConfigNak:
+			InitRestartCountForConfig();
+			CheckRecvConfigNak(rcvlist, iDummyPPPRequestList);
+			//SendConfigRequestAfterNak(rcvlist);
+			SetNewId();
+			SendConfigRequest();
+			break;
+		case KPppLcpConfigReject:
+			//Not responding to a reject
+			//InitRestartCountForConfig();
+			//CheckRecvConfigReject(rcvlist, iDummyPPPRequestList);
+			//SendConfigRequestAfterReject(rcvlist);
+			//SetNewId();
+			//SendConfigRequest();
+			break;
+			}
+		break;
+	
+	case EDummyPPPFsmAckRecvd:
+		switch (iCodeRec)
+			{
+		case KPppLcpConfigRequest:
+			switch (reply)
+				{
+			case EAck:
+				SendConfigReply(acklist, KPppLcpConfigAck);
+				SetState(EDummyPPPFsmOpened);
+				//As external option negotiation complete
+				iFlags |= KDummyPPPApplyPending; 
+				break;
+			case ENak:
+				// RFC 1661 4.6
+				if(CheckMaxFailureExceeded() == TRUE)
+					SendConfigReply(naklist, KPppLcpConfigReject);
+				else
+					{
+					DecrementDummyPPPMaxFailureCount();
+					SendConfigReply(naklist, KPppLcpConfigNak);
+					}
+				break;
+			case ERej:
+				SendConfigReply(rejlist, KPppLcpConfigReject);
+				break;
+			default:
+				break;
+				}
+			break;
+		case KPppLcpConfigAck:
+			//InitRestartCountForConfig();
+			//CheckRecvConfigAck(rcvlist);
+			//SetState(EDummyPPPFsmOpened);
+			//As external option negotiation complete
+			//iFlags |= KDummyPPPApplyPending; 
+			break;
+		case KPppLcpConfigNak:
+		//Not responding to a reject
+		//case KPppLcpConfigReject:
+			SendConfigRequest();
+			SetState(EDummyPPPFsmReqSent);
+			break;
+			}
+		break;
+
+	case EDummyPPPFsmAckSent:
+		switch (iCodeRec)
+			{
+		case KPppLcpConfigRequest:
+			switch (reply)
+				{
+			case EAck:
+				SendConfigReply(acklist, KPppLcpConfigAck);
+				break;
+			case ENak:
+				// RFC 1661 4.6
+				if(CheckMaxFailureExceeded() == TRUE)
+					SendConfigReply(naklist, KPppLcpConfigReject);
+				else
+					{
+					DecrementDummyPPPMaxFailureCount();
+					SendConfigReply(naklist, KPppLcpConfigNak);
+					}
+				SetState(EDummyPPPFsmReqSent);
+				break;
+			case ERej:
+				SendConfigReply(rejlist, KPppLcpConfigReject);
+				SetState(EDummyPPPFsmReqSent);
+				break;
+			default:
+				break;
+				}
+			break;
+		case KPppLcpConfigAck:
+			InitRestartCountForConfig();
+			CheckRecvConfigAck(rcvlist);
+			SetState(EDummyPPPFsmOpened);
+			//As external option negotiation complete
+			iFlags |= KDummyPPPApplyPending; 
+			break;
+		case KPppLcpConfigNak:
+			InitRestartCountForConfig();
+			CheckRecvConfigNak(rcvlist, iDummyPPPRequestList);
+			//SendConfigRequestAfterNak(rcvlist);
+			SetNewId();
+			SendConfigRequest();
+			break;
+		case KPppLcpConfigReject:
+			//Not responding to a reject
+			//InitRestartCountForConfig();
+			//CheckRecvConfigReject(rcvlist, iDummyPPPRequestList);
+			//SendConfigRequestAfterReject(rcvlist);
+			//SetNewId();
+			//SendConfigRequest();
+			break;
+			}
+		break;
+
+	case EDummyPPPFsmOpened:
+		// Config Reset done above
+		switch (iCodeRec)
+			{
+		case KPppLcpConfigRequest:
+			SendConfigRequest();
+			switch (reply)
+				{
+			case EAck:
+				SendConfigReply(acklist, KPppLcpConfigAck);
+				SetState(EDummyPPPFsmAckSent);
+				break;
+			case ENak:
+				SendConfigReply(naklist, KPppLcpConfigNak);
+				SetState(EDummyPPPFsmReqSent);
+				break;
+			case ERej:
+				SendConfigReply(rejlist, KPppLcpConfigReject);
+				SetState(EDummyPPPFsmReqSent);
+				break;
+			default:
+				break;
+				}
+			break;
+		case KPppLcpConfigAck:
+			SendConfigRequest();
+			CheckRecvConfigAck(rcvlist);
+			SetState(EDummyPPPFsmReqSent);
+			break;
+		case KPppLcpConfigNak:
+			CheckRecvConfigNak(rcvlist, iDummyPPPRequestList);
+			//SendConfigRequestAfterNak(rcvlist);
+			SetNewId();
+			SendConfigRequest();
+			SetState(EDummyPPPFsmReqSent);
+			break;
+		case KPppLcpConfigReject:
+			//Not responding to the reject
+			//CheckRecvConfigReject(rcvlist, iDummyPPPRequestList);
+			//SendConfigRequestAfterReject(rcvlist);
+			//SetNewId();
+			//SendConfigRequest();
+			//SetState(EDummyPPPFsmReqSent);
+			break;
+			}
+		break;
+		default:
+			//Do nothing
+		break; 
+		}
+
+	rcvlist.Free();	
+	acklist.Free();
+	naklist.Free();
+	rejlist.Free();
+
+	}
+	
+void CDummyPPPIf::ProcessPAPandIPCP()
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP ProcessPAPandIPCP\r\n"));
+	// Split the recvd packet into separate options
+	// placing each option in a queue where it can be
+	// easily parsed and manipulated in the upcall handlers.
+	RPppOptionList rcvlist;	// Recvd list of options
+	enum TDummyPPPResult { ENop, EAck, ENak, ERej };
+
+	RPppOptionList acklist;	// List of Ack'd options - only valid of the following are empty
+	RPppOptionList naklist;	// List of Nak'd options - only valid of the following is empty
+	RPppOptionList rejlist;	// List of Rejected options
+
+
+	TDummyPPPResult reply = ENop;
+
+    TRAPD(err, rcvlist.SetL(ipktRecvPPP));
+	if (err!=KErrNone)
+		return;
+
+	TInt iAction = ENop; 
+
+	//For overriding PAP
+	if (iDummyPPPState == EDummyPPPFsmOpened)
+	{
+		SetPppId(KPppIdIpcp);
+		SetState(EDummyPPPFsmPapAckSent);
+	}
+	if(iDummyPPPState < EDummyPPPFsmPapAuthAckRecvd)
+		{
+		if (iDummyPPPState == EDummyPPPFsmOpened)
+		{
+			//Just for testing Nak packet
+			//SendPapRequest();
+			//SendPapNak(rcvlist);
+			//SetState(EDummyPPPFsmPapAuthReqSent);
+		}
+			
+		iAction = CheckRecvPapReq();
+		reply = (iAction == KPppPapNak)?ENak:reply;
+		reply = (iAction == KPppPapAck)?EAck:reply;
+			
+		}
+	else
+		CheckRecvIPCPReq(rcvlist, acklist, naklist, rejlist);
+
+	if (!rejlist.IsEmpty())
+		{
+		reply = ERej;
+		naklist.Free();
+		acklist.Free();
+		}
+	else if (!naklist.IsEmpty())
+		{
+		reply = ENak;
+		acklist.Free();
+		}
+	else if (!acklist.IsEmpty())
+		{
+		reply = EAck;
+		//SetupConfigRequest(acklist);
+		}
+	 
+	
+	//Added to initialize the SendPPP index
+	ipktRecvPPP.Pack();
+	ptrTransPktPPP = &ipktRecvPPP;
+	
+	// State processing
+
+	switch (iDummyPPPState)
+		{
+			case EDummyPPPFsmOpened:
+				//Commenting Pap nego for the time being as PPP is rejecting it.
+				//so skipping to IPCP Nego state
+				//SetPppId(KPppIdPap);
+				//SendPapRequest();
+				//SetState(EDummyPPPFsmPapAuthReqSent);
+				SetPppId(KPppIdIpcp);
+				SetState(EDummyPPPFsmPapAckSent);
+
+				break;
+			case EDummyPPPFsmPapAuthAckRecvd:
+					if(reply == EAck)
+					{
+						SendConfigReply(acklist, KPppLcpConfigAck);
+						SetPppId(KPppIdIpcp);
+						SetState(EDummyPPPFsmPapAckSent);
+						break;
+					}
+					if(reply == ENak)
+					{
+						SendConfigReply(naklist, KPppLcpConfigNak);
+						break;
+					}
+				break;
+			case EDummyPPPFsmPapAckSent:
+				if(iCodeRec == KPppLcpConfigRequest)
+				{
+					switch(reply)
+					{
+					case EAck:
+						SendConfigReply(acklist, KPppLcpConfigAck);
+						SetPppId(KPppIdIpcp);
+						SendIPCPReq();
+						SetState(EDummyPPPIPCPReqSent);
+						break;
+					case ENak:
+					default:
+						SetPppId(KPppIdIpcp);
+						SendIPCPDummyNak();
+						break;
+					}
+				}
+				else
+				{
+					switch(reply)
+					{
+					case EAck:
+						SetPppId(KPppIdIpcp);
+						SendConfigReply(acklist, KPppLcpConfigAck);
+						SetState(EDummyPPPFsmIPOpen);
+						break;
+					case ENak:
+					default:
+						SetPppId(KPppIdIpcp);
+						SendIPCPDummyNak();
+						break;
+					}
+				}
+				break;
+			case EDummyPPPIPCPReqSent:
+				switch(reply)
+					{
+					case EAck:
+						SendConfigReply(acklist, KPppLcpConfigAck);
+						SetState(EDummyPPPFsmIPOpen);
+						break;
+				
+					case ENak:
+					default:
+						SetPppId(KPppIdIpcp);
+						SendIPCPReq();
+						break;
+					}
+				break;
+			default:
+				//Do nothing
+				break;
+		}
+
+	}
+
+void CDummyPPPIf::ProcessTerminate()
+	{
+	if (iCodeRec==KPppLcpTerminateRequest)
+		{
+		switch (iDummyPPPState)
+			{
+		case EDummyPPPFsmInitial:
+		case EDummyPPPFsmStarting:
+			// bad event
+			break;
+		case EDummyPPPFsmClosed:
+		case EDummyPPPFsmStopped:
+		case EDummyPPPFsmClosing:
+		case EDummyPPPFsmStopping:
+			SendTerminateAck();
+			break;
+		case EDummyPPPFsmReqSent:
+		case EDummyPPPFsmAckRecvd:
+		case EDummyPPPFsmAckSent:
+			iNotify->LinkLayerDown(KErrTimedOut, MNifIfNotify::EDisconnect);
+			iLink->LinkDown(KErrCouldNotConnect);
+			SendTerminateAck();
+			SetState(EDummyPPPFsmReqSent);
+			break;
+		case EDummyPPPFsmOpened:
+		case EDummyPPPFsmPapAuthReqSent:
+		case EDummyPPPFsmPapAuthAckRecvd:
+		case EDummyPPPFsmPapAckSent:
+		case EDummyPPPIPCPReqSent:
+			//SendTerminateAck();
+		case EDummyPPPFsmIPOpen:
+			// Fix for DEF002615
+			// Dummy PPP should not convey KErrCommsLineFail to PPP when a Terminate Request 
+			// is received. So blocking these two lines.
+			//iLink->Stop(KErrCommsLineFail,MNifIfNotify::EDisconnect);
+			//iLink->LinkDown(KErrCommsLineFail);
+			iDummyPPPRestartCount = 0;
+			SetState(EDummyPPPFsmInitial);
+			break;
+			}
+		}
+	else // KPppLcpTerminateAck
+		{
+			{
+			switch (iDummyPPPState)
+				{
+			case EDummyPPPFsmInitial:
+			case EDummyPPPFsmStarting:
+				// bad event
+				break;
+			case EDummyPPPFsmClosed:
+			case EDummyPPPFsmStopped:
+				iLink->LinkDown(KErrCommsLineFail);
+				iNotify->LinkLayerDown(KErrNone, MNifIfNotify::EDisconnect);
+				break;
+			case EDummyPPPFsmClosing:
+				iLink->LinkDown(KErrCommsLineFail);
+				SetState(EDummyPPPFsmClosed);
+				break;
+			case EDummyPPPFsmStopping:
+				iLink->LinkDown(KErrCommsLineFail);
+				SetState(EDummyPPPFsmStopped);
+				iNotify->LinkLayerDown(KErrNone, MNifIfNotify::EDisconnect);
+				break;
+			case EDummyPPPFsmReqSent:
+			case EDummyPPPFsmAckSent:
+				break;
+			case EDummyPPPFsmAckRecvd:
+				SetState(EDummyPPPFsmReqSent);
+				break;
+			case EDummyPPPFsmOpened:
+			case EDummyPPPFsmPapAuthReqSent:
+			case EDummyPPPFsmPapAuthAckRecvd:
+			case EDummyPPPFsmPapAckSent:
+			case EDummyPPPIPCPReqSent:
+			case EDummyPPPFsmIPOpen:
+				iLink->Stop(KErrCommsLineFail,MNifIfNotify::EDisconnect);
+				SendConfigRequest();
+				SetState(EDummyPPPFsmReqSent);
+				break;
+				}
+			}
+		}
+
+	}
+void CDummyPPPIf::SetupSendPPP()
+{	
+	CDummyNifLog::Printf(_L("Dummy PPP SetupSendPPP\r\n"));
+	if(ipktRecvPPP.IsEmpty())
+	{
+		
+		//Storing data received into Recv Q
+		iRecvQ.Append(ipktRecvPPP);
+		//iSendNumBufs += ipktRecvPPP.NumBufs();
+		
+		iRecvQ.Remove(*ptrTransPktPPP);
+
+		//ptrTransPktPPP = &ipktRecvPPP;
+
+	}
+}
+
+void CDummyPPPIf::SendPapRequest()
+	{
+	 CDummyNifLog::Printf(_L("Dummy PPP SendPapRequest\r\n"));
+#ifdef _UNICODE
+	TBuf8<256> user,pass;
+
+	//Only for testing
+	//ConvertTo8Bit(user, iLink->UserName());
+	//ConvertTo8Bit(pass, iProtocol->PassWord());
+	
+	user = _L8("EpochUser");
+	pass = _L8("EpochPass");
+	
+#else
+	TPtrC8 user, pass;
+	user.Set(iProtocol->UserName());
+	pass.Set(iProtocol->PassWord());
+#endif
+
+	RMBufPacket pkt;
+	RMBufPktInfo* info = NULL;
+
+	TInt len = 4+user.Length()+1+pass.Length()+1;
+	TRAPD(err, pkt.AllocL(len));
+	if (err!=KErrNone)
+		return;
+	TRAP(err, info = pkt.NewInfoL());
+	if (err!=KErrNone)
+		{
+		pkt.Free();
+		return;
+		}
+	TUint8* ptr = pkt.First()->Ptr();
+	*ptr++ = KPppPapRequest;
+	//Considering it as a New request
+	//if (aNewRequest)
+	//	{
+		iDummyPPPTryCount = KDummyPPPPapRetries;
+		if (++iCurrentDummyPPPId==0)
+			++iCurrentDummyPPPId;
+	//	}
+	*ptr++ = iCurrentDummyPPPId;
+	BigEndian::Put16(ptr, (TUint16)len);
+	ptr += 2;
+	*ptr++ = (TUint8)user.Length();	
+	Mem::Copy(ptr, (TUint8*)user.Ptr(), user.Length());
+	ptr += user.Length();
+	*ptr++ = (TUint8)pass.Length();	
+	Mem::Copy(ptr, (TUint8*)pass.Ptr(), pass.Length());
+	ptr += pass.Length();
+	info->iLength = len;	
+	TPppAddr::Cast((info->iDstAddr)).SetProtocol(KPppIdPap);
+	pkt.Pack();
+	SendtoPPP(pkt);
+	iLink->TimerCancel();
+	iLink->TimerAfter(KDummyPPPPapWaitTime*1000);
+	--iDummyPPPTryCount;
+
+	}
+void CDummyPPPIf::SendPapAck(RPppOptionList& aReplyList)
+	{
+	
+	CDummyNifLog::Printf(_L("Dummy PPP SendPapAck\r\n"));
+	RPppOption opt;
+	RMBufPacket pkt;
+	RPppOptionList iAckList;	// List of Ack'd options - only valid of the following are empty
+ 
+	while (aReplyList.Remove(opt))
+		{
+		opt.OptType();
+		iAckList.Append(opt);
+		}
+		
+	TRAPD(err, iAckList.CreatePacketL(pkt, KPppIdPap, KPppPapAck, iIdRec));
+	if (err==KErrNone)
+		{
+		SendtoPPP(pkt);
+		}
+	}
+void CDummyPPPIf::SendPapNak(RPppOptionList& aReplyList)
+	{
+		
+	CDummyNifLog::Printf(_L("SendPapNak\r\n"));
+	RPppOption opt;
+	RMBufPacket pkt;
+	RMBufPacket* Packet;
+	RPppOptionList iNakList;	// List of Nak'd options - only valid of the following is empty
+
+	while (aReplyList.Remove(opt))
+		{
+		opt.OptType();
+		iNakList.Append(opt);
+		}
+	TRAPD(err, iNakList.CreatePacketL(pkt, KPppIdPap, KPppPapNak, iIdRec));
+	if (err==KErrNone)
+		{
+		Packet = (RMBufPacket*)&pkt;
+		RMBufPktInfo*info = Packet->Unpack();
+	    TPppAddr::Cast((info->iDstAddr)).SetProtocol(KPppIdPap);
+		TPppAddr::Cast(info->iDstAddr).SetAddress(iLocalAddr);
+		Packet->Pack();
+		SendtoPPP(pkt);
+		}
+	}
+
+TInt CDummyPPPIf::CheckRecvPapReq()
+	{
+		CDummyNifLog::Printf(_L("Dummy PPP CheckRecvPapReq\r\n"));
+		switch (iCodeRec)
+		{
+		case KPppPapRequest:
+			{
+			TPtrC8 user;
+			TPtrC8 pass;
+			user.Set(&iCodeRec,sizeof(iCodeRec));   
+			pass.Set(&iIdRec,sizeof(iIdRec));   
+			}
+			return 0;
+		case KPppPapAck:
+			if (iIdRec==iCurrentDummyPPPId)
+			{
+				iLink->TimerCancel();
+				//Fix for DEF03548 Changing progress states to match that in pppprog.h
+				iNotify->IfProgress(EPppProgressAuthenticationComplete,KErrNone);
+				return KPppPapNak;
+			}
+			else
+			{
+				return KPppPapAck;
+			}
+		case KPppPapNak:
+			if (iIdRec==iCurrentDummyPPPId)
+			{
+				iLink->TimerCancel();
+				//Fix for DEF03548 Changing progress states to match that in pppprog.h
+				iNotify->IfProgress(EPppProgressAuthenticationComplete,KErrIfAuthenticationFailure);
+			}
+			else
+			{
+				return KPppPapNak;
+			}
+		break;
+		default:
+			return KPppPapNak;
+		}
+		return KPppPapRequest;
+	}
+void CDummyPPPIf::SendIPCPDummyNak()
+	{
+		CDummyNifLog::Printf(_L("Dummy PPP SendIPCPDummyNak\r\n"));
+		TRAPD(err, InitializeIPCPConfigRequestL());
+		if (err==KErrNone)
+		{
+			if (iDummyPPPRequestList.IsEmpty())
+			{
+				CDummyNifLog::Printf(_L("Request list empty\r\n"));
+				return;
+			}
+
+			RMBufPacket Packet;	
+			//iDummyPPPRequestId = iIdRec;
+			TRAPD(err, iDummyPPPRequestList.CreatePacketL(Packet, KPppIdIpcp, KPppLcpConfigNak, (TUint8)iIdRec));
+			if (err!=KErrNone)
+			{
+				//__DEBUGGER();
+				return;
+			}
+	
+			ptrTransPktPPP = &Packet;
+
+			RMBufPktInfo*info = Packet.Unpack();
+		 
+			TPppAddr::Cast((info->iDstAddr)).SetProtocol(KPppIdIpcp);
+			TPppAddr::Cast(info->iDstAddr).SetAddress(iLocalAddr);
+			Packet.Pack();
+
+			SendtoPPP(*ptrTransPktPPP);
+		}
+	}
+void CDummyPPPIf::InitializeIPCPConfigRequestL()
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP InitializeIPCPConfigRequestL()\r\n"));
+	SetNewId();
+	InitRestartCountForConfig();
+	
+	if (!iDummyPPPRequestList.IsEmpty())
+		iDummyPPPRequestList.Free();
+	
+	iDummyPPPRequestList.CreateAndAddL(KPppIpcpOptIpAddress, iLocalAddr);
+	
+	//BigEndian::Put32(opt.ValuePtr(), iRemoteAddr);
+	//iDummyPPPRequestList.CreateAndAddL(KPppIpcpOptPrimaryDnsAddress, iPrimaryDns);
+	//iDummyPPPRequestList.CreateAndAddL(KPppIpcpOptSecondaryDnsAddress, iSecondaryDns);
+
+	}
+void CDummyPPPIf::SendIPCPReq()
+	{
+		CDummyNifLog::Printf(_L("Dummy PPP SendIPCPReq\r\n"));
+		TRAPD(err, InitializeIPCPConfigRequestL());
+		if (err==KErrNone)
+		{
+			if (iDummyPPPRequestList.IsEmpty())
+			{
+				CDummyNifLog::Printf(_L("Request list empty\r\n"));
+				return;
+			}
+
+			RMBufPacket Packet;	
+			//iDummyPPPRequestId = iIdRec;
+			TRAPD(err, iDummyPPPRequestList.CreatePacketL(Packet, KPppIdIpcp, KPppLcpConfigRequest, (TUint8)iIdRec));
+			if (err!=KErrNone)
+			{
+			//__DEBUGGER();
+				return;
+			}
+	
+			ptrTransPktPPP = &Packet;
+
+			RMBufPktInfo*info = Packet.Unpack();
+		 
+			TPppAddr::Cast((info->iDstAddr)).SetProtocol(KPppIdIpcp);
+			TPppAddr::Cast(info->iDstAddr).SetAddress(iLocalAddr);
+			Packet.Pack();
+
+			SendtoPPP(*ptrTransPktPPP);
+		}
+	}
+void CDummyPPPIf::CheckRecvIPCPReq(RPppOptionList& aRequestList, RPppOptionList& aAckList, RPppOptionList& aNakList, RPppOptionList& aRejList)
+	{
+	RPppOption opt;
+	TUint8 temp;
+	CDummyNifLog::Printf(_L("Dummy PPP CheckRecvIPCPReq\r\n"));
+	while (aRequestList.Remove(opt))
+		{
+		temp = opt.OptType();
+		switch (temp)
+			{
+		case KPppIpcpOptIpAddress:
+			{
+			TUint32 addr = BigEndian::Get32(opt.ValuePtr());
+			if (addr==0)
+				{
+					aNakList.Append(opt);
+				}
+			else
+				aAckList.Append(opt);
+			}
+			break;
+		case KPppIpcpOptIpAddresses:
+         {
+			TUint32 remoteAddr = BigEndian::Get32(opt.ValuePtr());
+			TUint32 addr = BigEndian::Get32(opt.ValuePtr()+4);
+
+         if (remoteAddr == 0)
+            {
+				aRejList.Append(opt);
+            }
+         else if (addr == 0)
+            {
+				aNakList.Append(opt);
+				}
+			else
+            {
+				iRemoteAddr = remoteAddr;
+				aAckList.Append(opt);
+            }
+         }
+		 break;
+			}
+		}
+	}
+
+void CDummyPPPIf::SetState(TDummyPPPToPPPFsmState aState)
+	{
+	CDummyNifLog::Write(_L("DummyPPP::SetState()"));
+
+	_LIT(KStateString,"State %s -> %s");
+
+
+	CDummyNifLog::Printf(KStateString,CDummyNifLog::StateToText(iDummyPPPState), CDummyNifLog::StateToText(aState));
+
+	iDummyPPPState = aState;
+	}
+void CDummyPPPIf::SetPppId(TUint aProt)
+	{
+	CDummyNifLog::Printf(_L("DummyPPP::SetPppId to %d\n"),aProt);
+	iSendPppId = aProt;
+	}
+
+void CDummyPPPIf::InitRestartCountForConfig()
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP InitRestartCountForConfig\r\n"));
+	// RFC 1661 4.6 Max-Configure
+	iDummyPPPWaitTime = KDummyPPPWaitTimeConfig;
+	iDummyPPPRestartCount = KDummyPPPMaxRestartConfig;
+	}
+
+void CDummyPPPIf::SetNewId()
+	{
+	TUint8 id = ++iCurrentDummyPPPId;
+	if (iCurrentDummyPPPId==0)
+		++iCurrentDummyPPPId;
+	iDummyPPPRequestId = id;
+	CDummyNifLog::Printf(_L("Dummy PPP SetNewId %d\r\n"),iDummyPPPRequestId);
+	}
+
+void CDummyPPPIf::InitialiseConfigRequestL()
+	{
+	TUint32 iDummyPPPRecvEscMap = 0;
+	SetNewId();
+	InitRestartCountForConfig();
+	SetPppId(KPppIdLcp);
+	
+	CDummyNifLog::Printf(_L("Dummy PPP InitialiseConfigRequest\r\n"));
+	if (!iDummyPPPRequestList.IsEmpty())
+		iDummyPPPRequestList.Free();
+	
+	// Create a new magic number
+	iPPPRemMagicNumber = 0;
+	
+	if (iDummyPPPLocMagicNumber == 0)
+	{
+		//CPppLcp::NewMagicNumber(iDummyPPPLocMagicNumber);
+		//Only for testing
+		iDummyPPPLocMagicNumber = 54321;
+	}
+	
+	iDummyPPPRequestList.CreateAndAddL(KPppLcpOptMagicNumber, (TUint32)iDummyPPPLocMagicNumber);
+	if ((iOrigConfig().iHandshake & KConfigSendXoff)!=0
+		|| (iOrigConfig().iHandshake & KConfigSendXoff)!=0)
+		{
+		if (iOrigConfig().iXonChar<32)
+			iDummyPPPRecvEscMap |= 1<<iOrigConfig().iXonChar;
+		if (iOrigConfig().iXoffChar<32)
+			iDummyPPPRecvEscMap |= 1<<iOrigConfig().iXoffChar;
+		}
+	//for testing options
+	//iDummyPPPRequestList.CreateAndAddL(KPppLcpOptEscapeCharMap,iDummyPPPRecvEscMap);
+	//iDummyPPPRequestList.CreateAndAddL(KPppLcpOptProtocolCompress);
+	//iDummyPPPRequestList.CreateAndAddL(KPppLcpOptAddrCtrlCompress);
+
+	}
+
+void CDummyPPPIf::SetupConfigRequest(RPppOptionList& aRequestList)
+//
+// Apply options in a recvd config request (that was ACK'd)
+//
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP SetupConfigRequest\r\n"));
+	TMBufPktQIter iter(aRequestList);
+	RPppOption opt;
+
+	while (opt = iter++, !opt.IsEmpty())
+		{
+		switch (opt.OptType())
+			{
+		case KPppLcpOptMaxRecvUnit:
+			//iMaxSendSize = BigEndian::Get16(opt.ValuePtr());
+			break;
+		case KPppLcpOptMagicNumber:
+			iPPPRemMagicNumber = BigEndian::Get32(opt.ValuePtr());
+			break;
+		default:
+			//ExtOptApplyConfigRequest(opt);
+			break;
+			}
+		}
+	}
+
+void CDummyPPPIf::CheckRecvConfigRequest(RPppOptionList& aRequestList, RPppOptionList& aAckList, RPppOptionList& aNakList, RPppOptionList& aRejList)
+//
+// Check options in a recvd config request
+//
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP CheckRecvConfigRequest\r\n"));
+	RPppOption opt;
+	//only for debugging
+	TUint8 temp;
+
+	while (aRequestList.Remove(opt))
+		{
+		temp = opt.OptType();
+		switch (temp)
+			{
+		case KPppLcpOptMaxRecvUnit:
+			if (opt.ValueLength()<0)
+				aNakList.Append(opt);
+			else
+				{
+				if (opt.ValueLength()<2)
+					aRejList.Append(opt);
+				else
+					aAckList.Append(opt);
+				}
+			break;
+
+		case KPppLcpOptMagicNumber:
+			if (opt.ValueLength()<0)
+				aNakList.Append(opt);
+			else
+				{
+				if (opt.ValueLength()!=4)
+					aRejList.Append(opt);
+				else
+					{
+					iPPPRemMagicNumber = BigEndian::Get32(opt.ValuePtr());
+					if (iPPPRemMagicNumber!=iDummyPPPLocMagicNumber)
+						{
+						aAckList.Append(opt);
+						}
+					else
+						{
+						//CPppLcp::NewMagicNumber(iPPPRemMagicNumber);
+						//Only for testing
+						iPPPRemMagicNumber = 11111;
+						BigEndian::Put32(opt.ValuePtr(), iPPPRemMagicNumber);
+						aNakList.Append(opt);
+						}
+					}
+				}
+			break;
+		case KPppLcpOptMultiLinkEndPointDescriminator:
+	        aAckList.Append(opt);
+			break;
+
+		default:
+			//ExtOptCheckConfigRequest(aPacket, (CProtocolBase*)this);
+    		iPppOptions->ExtOptCheckConfigRequest(opt, aAckList, aNakList, aRejList);
+			}
+		}
+	}
+
+void CDummyPPPIf::CheckRecvConfigAck(RPppOptionList& aReplyList)
+//
+// Recvd a Config Ack - apply the options
+//
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP CheckRecvConfigAck\r\n"));
+	TMBufPktQIter iter(aReplyList);
+	RPppOption opt;
+		
+	while (opt = iter++, !opt.IsEmpty())
+		{
+		switch (opt.OptType())
+			{
+		case KPppLcpOptMaxRecvUnit:
+			//iMaxRecvSize = BigEndian::Get16(opt.ValuePtr());
+			break;
+		case KPppLcpOptMagicNumber:
+			// Magic number is OK
+			//SendDummyPPPIdentification();
+			break;
+		default:
+			iPppOptions->ExtOptRecvConfigAck(opt);
+			break;
+			}
+		}
+	}
+
+void CDummyPPPIf::CheckRecvConfigNak(RPppOptionList& aReplyList, RPppOptionList& aReqList)
+//
+// Recvd a Config Nak - The associated original request is in aReqList
+//
+	{
+	CDummyNifLog::Printf(_L("DummyPPP::CheckRecvConfigNak\r\n"));
+	TMBufPktQIter iter(aReplyList);
+	RPppOption opt;
+	
+	while (opt = iter++, !opt.IsEmpty())
+		{
+		switch (opt.OptType())
+			{
+		case KPppLcpOptMaxRecvUnit:
+			aReqList.ReplaceOption(opt);
+			break;
+		case KPppLcpOptMagicNumber:
+			{
+			iDummyPPPLocMagicNumber = BigEndian::Get32(opt.ValuePtr());
+			aReqList.ReplaceOption(opt);
+			}
+			break;
+		default:
+			iPppOptions->ExtOptRecvConfigNak(opt, aReqList);
+			break;
+			}
+		}
+	}
+
+void CDummyPPPIf::CheckRecvConfigReject(RPppOptionList& aReplyList, RPppOptionList& aReqList)
+//
+// Recvd a Config Reject - The associated original request is in aReqList
+//
+	{
+	TMBufPktQIter iter(aReplyList);
+	RPppOption opt;
+	CDummyNifLog::Printf(_L("Dummy PPP CheckRecvConfigReject\r\n"));
+	
+	while (opt = iter++, !opt.IsEmpty())
+		{
+		switch (opt.OptType())
+			{
+		case KPppLcpOptMaxRecvUnit:
+			aReqList.RemoveOption(opt);
+			break;
+		case KPppLcpOptMagicNumber:
+			aReqList.RemoveOption(opt);
+			break;
+		default:
+			iPppOptions->ExtOptRecvConfigReject(opt, aReqList);
+			break;
+			}
+		}
+	}
+
+
+void CDummyPPPIf::SendConfigRequest()
+//
+// Send the config request in iDummyPPPRequestList
+//
+	{
+
+	if (iDummyPPPRequestList.IsEmpty())
+		{
+		CDummyNifLog::Write(_L("DummyPPP Request list empty\r\n"));
+		return;
+		}
+
+	CDummyNifLog::Printf(_L("Dummy PPP SendConfigRequest\r\n"));
+	RMBufPacket pkt;	
+	iDummyPPPRequestId &= 0xff;
+	TRAPD(err, iDummyPPPRequestList.CreatePacketL(pkt, iSendPppId, KPppLcpConfigRequest, (TUint8)iDummyPPPRequestId));
+	if (err==KErrNone)
+		{
+		SendtoPPP(pkt);
+		--iDummyPPPRestartCount;
+		iLink->TimerCancel();
+		TInt temp=iDummyPPPWaitTime;
+		iLink->TimerAfter(iDummyPPPWaitTime*1000);
+		iDummyPPPWaitTime=temp;
+		}	
+	}
+
+void CDummyPPPIf::SendConfigReply(RPppOptionList& aOptList,TUint8 aType)
+	{
+	RMBufPacket pkt;
+	CDummyNifLog::Printf(_L("Dummy PPP SendConfigReply\r\n"));
+	TRAPD(err, aOptList.CreatePacketL(pkt, iSendPppId, aType, iIdRec));
+	if (err==KErrNone)
+		{
+		SendtoPPP(pkt);
+		iLink->TimerCancel();
+		TInt temp=iDummyPPPWaitTime;
+		iLink->TimerAfter(iDummyPPPWaitTime*1000);
+		iDummyPPPWaitTime=temp;
+		}
+	}
+
+void CDummyPPPIf::SendTerminateAck()
+	{
+	RMBufPacket pkt;
+	RMBufPktInfo* info=NULL;
+	CDummyNifLog::Printf(_L("Dummy PPP SendTerminateAck\r\n"));
+	TRAPD(err, pkt.AllocL(4));
+	if (err ==KErrNone)
+		{
+		TRAP(err,info = pkt.NewInfoL());
+		}
+	if (err ==KErrNone)
+		{
+		info->iLength = 4;
+		TPppAddr::Cast((info->iDstAddr)).SetProtocol(iSendPppId);
+		TUint8* ptr = pkt.First()->Ptr();
+		*ptr++ = KPppLcpTerminateAck;
+		*ptr++ = iIdRec;
+		BigEndian::Put16(ptr, (TUint16)4);
+		pkt.Pack();
+		SendtoPPP(pkt);
+		}
+	else
+		{
+		pkt.Free();
+		__ASSERT_DEBUG(EFalse,User::Invariant());
+		}
+	}
+
+void CDummyPPPIf::SendDummyPPPIdentification()
+	{
+
+	CDummyNifLog::Printf(_L("Dummy PPP SendDummyPPPIdentification\r\n"));
+	TInt err;
+	TPtrC8 id = _L8("Symbian Epoc!");
+	RMBufPacket pkt;
+	RMBufPktInfo* info = NULL;
+	TRAP(err, info = pkt.NewInfoL());
+	if (err!=KErrNone)
+		return;
+	info->iLength = 4+4+id.Length();
+	TRAP(err, pkt.AllocL(info->iLength));
+	if (err!=KErrNone)
+		{
+		pkt.FreeInfo();
+		return;
+		}
+	TUint8* ptr = pkt.First()->Ptr();
+	*ptr++ = (TUint8)KPppLcpIdentification;
+	SetNewId();
+	*ptr++ = iDummyPPPRequestId;
+	BigEndian::Put16(ptr, (TUint16)info->iLength);
+	BigEndian::Put32(ptr+2, (TUint32)iDummyPPPLocMagicNumber);
+	pkt.CopyIn(id, 8);
+	pkt.Pack();
+	SendtoPPP(pkt);
+	}
+TInt CDummyPPPLink::Start()
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP Link::Start\r\n"));
+	
+	//As CreateL is not called before Start calling it here
+	TRAPD(err, iNifIf->CreateL());
+	if (err != KErrNone)
+		return err;
+	iState = EDummyPPPLinkOpen;
+ 
+	iNotify->IfProgress(KLinkLayerOpen, KErrNone);
+	iNotify->LinkLayerUp();
+
+	iNifIf->OpenFSM();
+	iNifIf->InitRestartCountForConfig();
+	//Setting iSendFlowOn to start
+	iNifIf->SetFlowOnFlag(ETrue);
+	iNifIf->iProtocol->StartSending((CProtocolBase*)iNifIf);
+	
+	return KErrNone;
+	}
+void CDummyPPPIf::CloseFSM()
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP Close FSM Request\r\n"));
+	
+	//Setting response to PPP state machine
+	if((iDummyPPPState == EDummyPPPFsmInitial)
+		||(iDummyPPPState == EDummyPPPFsmStarting))
+		{
+		//Do nothing
+		}
+	if((iDummyPPPState == EDummyPPPFsmClosed)
+		||(iDummyPPPState == EDummyPPPFsmClosing))
+		{
+		SetState(EDummyPPPFsmInitial);
+		}
+    if((iDummyPPPState == EDummyPPPFsmStopped)
+		||(iDummyPPPState == EDummyPPPFsmStopping)
+		||(iDummyPPPState == EDummyPPPFsmReqSent)
+		||(iDummyPPPState == EDummyPPPFsmAckRecvd)
+		||(iDummyPPPState == EDummyPPPFsmAckSent)
+		||(iDummyPPPState == EDummyPPPFsmOpened))
+		{
+		SetState(EDummyPPPFsmStarting);
+		}
+}
+void CDummyPPPIf::ChangeStateforTimerComplete()
+	{
+	
+	CDummyNifLog::Printf(_L("Dummy PPP Timer Expired %d \r\n"),iDummyPPPRestartCount);
+	if((iDummyPPPState == EDummyPPPFsmInitial)
+		||(iDummyPPPState == EDummyPPPFsmStarting)
+		||(iDummyPPPState == EDummyPPPFsmClosed)
+		||(iDummyPPPState == EDummyPPPFsmStopped)
+		||(iDummyPPPState == EDummyPPPFsmOpened))
+		// Bad Event
+		return;
+   
+	if (iDummyPPPRestartCount>0)
+		{
+		switch (iDummyPPPState)
+			{
+		case EDummyPPPFsmClosing:
+		case EDummyPPPFsmStopping:
+			//SendTerminateRequest();
+			break;
+		case EDummyPPPFsmReqSent:
+		case EDummyPPPFsmAckRecvd:
+		case EDummyPPPFsmAckSent:
+			//PG RFC 1661 4.6 double timeout period
+			//if (iDummyPPPWaitTime*2<KDummyPPPFsmRequestMaxTimeout)
+			//	iDummyPPPWaitTime = iDummyPPPWaitTime*2;
+			//SendConfigRequest();
+			
+			//if(iDummyPPPState == EDummyPPPFsmAckRecvd)
+			//	SetState(EDummyPPPFsmReqSent);
+			break;
+		default:
+			break;
+			}
+		}
+	else
+		{
+	
+		switch (iDummyPPPState)
+			{
+		case EDummyPPPFsmClosing:
+			SetState(EDummyPPPFsmClosed);
+			break;
+		case EDummyPPPFsmStopping:
+		case EDummyPPPFsmReqSent:
+		case EDummyPPPFsmAckRecvd:
+		case EDummyPPPFsmAckSent:
+			SetState(EDummyPPPFsmStopped);
+			break;
+		default:
+			break;
+			}
+		}
+
+	if (iDummyPPPTryCount>0)
+		SendPapRequest();
+	}
+
+void CDummyPPPLink::TimerComplete(TInt)
+	{
+
+	CDummyNifLog::Write(_L("DummyPPP Link::TimerComplete()"));
+
+	//
+	// Upcall from Timer
+	//
+    iNifIf->ChangeStateforTimerComplete();
+
+	//Here while closing down it crashes!
+	//iNifIf->CloseFSM();
+    //iNotify->LinkLayerDown(KErrTimedOut, MNifIfNotify::EDisconnect);
+	
+	}
+
+
+void CDummyPPPLink::Stop(TInt aError, MNifIfNotify::TAction aAction)		
+	{
+	switch (iState)
+		{
+	case EDummyPPPLinkClosed:
+		return;
+	case EDummyPPPLinkConnecting:
+		iState = EDummyPPPLinkClosed;
+		break;
+	case EDummyPPPLinkOpen:
+		//iNifIf->PacketModeOff();
+		iState = EDummyPPPLinkClosed;
+		break;
+	default:
+		break;
+		}
+	CDummyNifLog::Printf(_L("DummyPPP Link::Stop(aError %d, TAction %d)"), aError, aAction);
+	//Commenting as this has to be conveyed by PPP and not DummyPPP Nif
+	//iNotify->IfProgress(KLinkLayerClosed, aError);
+	iNifIf->CloseFSM();
+	//Commenting as this has to be conveyed by PPP and not DummyPPP Nif
+	iNotify->LinkLayerDown(aError, aAction);
+	
+	}
+
+void CDummyPPPLink::IfProgress(TInt /*aResult*/)
+	{
+	}
+void CDummyPPPIf::BindL(TAny *aId)
+	{
+	CDummyNifLog::Printf(_L("BindL(aId %x)\r\n"),aId);
+	if (iProtocol)
+		User::Leave(KErrAlreadyExists);
+	iProtocol = (CProtocolBase*)aId;
+	}
+
+void CDummyPPPIf::SetFlowOnFlag(TBool aFlag)
+	{
+		CDummyNifLog::Printf(_L("Dummy PPP SetFlowOnFlag\r\n"));
+		iSendFlowOn = aFlag;
+	}
+
+CNifIfBase* CDummyPPPLink::GetBinderL(const TDesC& aName)
+	{
+	CDummyNifLog::Printf(_L("DummyPPP LinkGetBinderL(%S)"), &aName);
+
+	iNifIf = new(ELeave) CDummyPPPIf(this);
+	return iNifIf;
+
+	}
+
+TInt CDummyPPPLink::Notification(TAgentToNifEventType aEvent,void* aInfo)
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP LinkNotification\r\n"));
+	if ((aEvent!=EAgentToNifEventTypeDisableTimers) 
+		|| (aInfo!=NULL))
+		return KErrUnknown;
+	return KErrNone;
+	}
+
+void CDummyPPPLink::Restart(CNifIfBase*)
+	{}
+
+CDummyPPPIf::CDummyPPPIf(CDummyPPPLink* aLink)
+	: CNifIfBase(*aLink)
+	{
+	CDummyNifLog::Printf(_L("DummyPPP Constructed"));
+
+	//__DECLARE_FSM_NAME(_S("DUMMY_PPP FSM"));
+
+	iLink = aLink;
+	
+	//Settings for flow control
+	iSendLoWat = KLoWatMark;
+	iSendHiWat = KHiWatMark;
+
+	// generate my local ip address (ip4) - vals potentially will be overwritten by any derived classes
+	iLocalAddress = KDummyPppNifLocalAddressBase;//0x0A220C1BB; //+ ((TUint32)this)%255;
+    
+	//For IPCP Nego.
+	//PresetAddr(iLocalAddr, TPtrC(KCDTypeNameIpAddr));
+	iLocalAddr = iLocalAddress;
+
+	//PresetAddr(iPrimaryDns, TPtrC(KCDTypeNameIpNameServer1));
+	//PresetAddr(iSecondaryDns, TPtrC(KCDTypeNameIpNameServer2));
+	//iPrimaryNbns = IPADDR(0,0,0,0);
+	//iSecondaryNbns = IPADDR(0,0,0,0);
+	//PresetAddr(iNetworkMask, TPtrC(KCDTypeNameIpNetMask));
+
+	// need to give each if a unique id so we will number and count them as we create them
+	//++iNumOfIfs;
+	//iIfNum = iNumOfIfs;
+
+	//Even if this is given, when the identification command for the nif is given
+	//it always turns up as a ipcp.comm as PPP Nif gives the information overlooking this.
+	iIfName.Format(_L("dummypppnif[0x%08x]"), this);
+
+
+
+	}
+TInt CDummyPPPIf::PresetAddr(TUint32& aAddr, const TDesC& aVarName)
+/**
+ * Preset IP adress in aAddr with value from CommDB. The field name
+ * is given in aVarName. Examples are "IpAddr" and "IpNameServer1"
+ *
+ * @param aAddr    IP address to be set
+ * @param aVarName name of CommDB field
+ * @return KErrNone if success, global error code otherwise
+ */
+	{
+	if (aAddr!=0)
+		return KErrNone;
+	
+	TBuf<KCommsDbSvrMaxFieldLength> name;
+	TInetAddr addr;
+    
+
+	(void)iNotify->ReadDes(aVarName, name); // ignore return value
+
+	const TInt ret = addr.Input(name);
+	if (ret==KErrNone)
+		aAddr = addr.Address();
+
+	return ret;
+	}
+
+
+void CDummyPPPIf::Info(TNifIfInfo& aInfo) const
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP Info\r\n"));
+	aInfo.iVersion = TVersion(1,1,1);
+	aInfo.iFlags = KNifIfIsBase | KNifIfUsesNotify | KNifIfCreatedByLink;
+	aInfo.iName.Copy(iIfName);
+	aInfo.iProtocolSupported = 0;
+	}
+
+void CDummyPPPLink::FillInInfo(TNifIfInfo& aInfo, TAny* aPtr)
+	{
+	aInfo.iProtocolSupported=0;
+	aInfo.iVersion = TVersion(1,1,1);
+	aInfo.iFlags = KNifIfIsBase | KNifIfIsLink | KNifIfUsesNotify | KNifIfCreatedByFactory;
+    aInfo.iName = _L("dummyppplink");
+	aInfo.iName.AppendFormat(_L("[0x%08x]"), aPtr);
+	aInfo.iFlags |= KNifIfCreatesBinder;
+	}
+
+void CDummyPPPLink::Info(TNifIfInfo& aInfo) const
+	{
+	FillInInfo(aInfo,(TAny*) this);
+	CDummyNifLog::Printf(_L("Dummy PPP LinkInfo\r\n"));
+	}
+
+TInt CDummyPPPIf::Control(TUint aLevel, TUint aName, TDes8& aOption, TAny* /* aSource */)
+	{
+	CDummyNifLog::Printf(_L("DummyPPP::Control(aLevel %x, aName %x, ...)"), aLevel, aName);
+
+	if (aLevel==KSOLInterface)
+		{
+		switch (aName)
+			{
+		case KSoIfInfo:
+			{
+			TSoIfInfo& opt = *(TSoIfInfo*)aOption.Ptr();
+
+			_LIT(KName, "MyName");
+			opt.iName.Copy(KName);
+			opt.iFeatures = KIfCanBroadcast | KIfCanMulticast;
+			opt.iMtu = 1500;
+			opt.iSpeedMetric = 0;
+			return KErrNone;
+			}
+
+		case KSoIfHardwareAddr:
+			return KErrNotSupported;
+
+		case KSoIfConfig:
+			{
+			TSoInetIfConfig& opt = *(TSoInetIfConfig*)aOption.Ptr();
+			if (opt.iFamily!=KAfInet)
+				return KErrNotSupported;
+
+			TUint32 address;
+			const TInt KPort = 65;
+
+			opt.iConfig.iAddress.SetAddress(iLocalAddress);
+			opt.iConfig.iAddress.SetPort(KPort);
+
+			// network mask
+			opt.iConfig.iNetMask.Input(KNetworkMask);
+			opt.iConfig.iNetMask.SetPort(KPort);
+
+			// broadcast address
+			address = KDummyPppNifLocalAddressBase + KBroadcastAddressSuffix;
+			opt.iConfig.iBrdAddr.SetAddress(address);
+			opt.iConfig.iBrdAddr.SetPort(KPort);
+
+			// default gateway
+			address = KDummyPppNifLocalAddressBase + KDefaultGatewayAddressSuffix;
+			opt.iConfig.iDefGate.SetAddress(address);
+			opt.iConfig.iDefGate.SetPort(KPort);
+
+			// primary DNS, just make same as default gateway
+			opt.iConfig.iNameSer1.SetAddress(address);
+			opt.iConfig.iNameSer1.SetPort(KPort);
+
+			// secondary DNS
+			address = KDummyPppNifLocalAddressBase + KSecondaryDnsAddressSuffix;
+			opt.iConfig.iNameSer2.SetAddress(address);
+			opt.iConfig.iNameSer2.SetPort(KPort);
+
+			return KErrNone;
+			}
+
+		case KSoIfGetConnectionInfo:
+			TSoIfConnectionInfo& opt = *(TSoIfConnectionInfo*)aOption.Ptr();
+			TInt err = KErrNone;
+			TBuf<2*KCommsDbSvrMaxColumnNameLength+1> fieldName;
+			_LIT(KSlashChar, "\\");
+
+			fieldName.Copy(TPtrC(KCDTypeNameIAP));
+			fieldName.Append(KSlashChar);
+			fieldName.Append(TPtrC(KCDTypeNameRecordTag));
+			if ((err = iNotify->ReadInt(fieldName, opt.iIAPId)) != KErrNone)
+				return err;
+
+			fieldName.Copy(TPtrC(IAP));
+			fieldName.Append(KSlashChar);
+			fieldName.Append(TPtrC(KCDTypeNameIAPNetwork));
+			if ((err = iNotify->ReadInt(fieldName, opt.iNetworkId)) != KErrNone)
+				return err;
+
+			return KErrNone;
+			}
+		}
+	return KErrNotSupported;
+	}
+
+TInt CDummyPPPIf::Notification(TAgentToNifEventType /*aEvent*/, void * /*aInfo*/)
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP Notification\r\n"));	
+	return KErrNone;
+	}
+
+void CDummyNifLog::Write(const TDesC& aDes)
+//
+// Write aText to the log
+//
+	{	
+#ifndef __FLOG_ACTIVE
+	(void)aDes;
+#else
+	__FLOG_STATIC0(KDummyPppLogFolder, KDummyPppLogFile, aDes);
+#endif
+	}
+ 
+void CDummyNifLog::Printf(TRefByValue<const TDesC> aFmt,...)
+//
+// Write a mulitple argument list to the log, trapping and ignoring any leave
+//
+	{
+#ifndef __FLOG_ACTIVE
+	(void)aFmt;
+#else
+	VA_LIST list;
+	VA_START(list, aFmt);
+
+	TBuf <1024> LineBuf;
+	LineBuf.AppendFormatList( aFmt, list);
+
+	__FLOG_STATIC0(KDummyPppLogFolder, KDummyPppLogFile, LineBuf);
+#endif // #ifdef __FLOG_ACTIVE
+	}
+
+void CDummyNifLog::HexDump(const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen, TInt aWidth)
+	{
+	TBuf<0x100> buf;
+	TInt i = 0;
+	const TText* p = aHeader;
+	while (aLen>0)
+		{
+		TInt n = aLen>aWidth ? aWidth : aLen;
+		if (p!=NULL)
+			{
+			_LIT(string1,"%s%04x : ");
+			buf.AppendFormat(string1, p, i);
+			}
+		TInt j;
+		_LIT(string2,"%02x ");
+		for (j=0; j<n; j++)
+			buf.AppendFormat(string2, aPtr[i+j]);
+		_LIT(string3,"   ");
+		while (j++<KHexDumpWidth)
+			buf.Append(string3);
+		_LIT(string4," ");
+		buf.Append(string4);
+		_LIT(string5,"%c");
+		for (j=0; j<n; j++)
+			buf.AppendFormat(string5, aPtr[i+j]<32 || aPtr[i+j]>126 ? '.' : aPtr[i+j]);
+		buf.Append(KEndOfLine);
+		Write(buf);
+		buf.SetLength(0);
+		aLen -= n;
+		i += n;
+		p = aMargin;
+		}
+	}
+
+
+
+void CDummyPPPIf::CreateL()
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP CreateL"));
+	logUser = new(ELeave) CDummyNifLog;
+	TCallBack scb(SendCallBack, this);	
+	iSendCallBack = new(ELeave) CAsyncCallBack(scb, KDummyPPPSendPriority);
+	}
+
+void CDummyPPPIf::OpenFSM()
+{
+	logUser->Printf(_L("Open FSM Request\r\n"));
+	
+	iDummyPPPMaxFailureCount = KDummyPPPMaxRestartConfig;
+	
+	if(iDummyPPPState == EDummyPPPFsmInitial)
+	{
+		SetState(EDummyPPPFsmStarting);
+		TRAPD(err, InitialiseConfigRequestL());
+		if (err==KErrNone)
+			SendConfigRequest();
+		SetState(EDummyPPPFsmReqSent);
+	}
+}
+
+void CDummyPPPIf::CloseLog()
+	{	
+	logUser->Printf(_L("Dummy PPP CloseLog\r\n"));	
+	delete logUser;
+	}
+void CDummyPPPIf::End()
+	{
+	CDummyNifLog::Printf(_L("Dummy PPP End\r\n"));	
+	ipktRecvPPP.Free();
+	delete iSendCallBack;
+	iSendCallBack = NULL;
+	}
+
+//The following code is for logs only
+const TText* CDummyNifLog::StateToText(TDummyPPPToPPPFsmState aState)
+	{
+
+	// States
+	switch (aState)
+		{
+	case EDummyPPPFsmInitial:
+		return _S("INITIAL");
+	case EDummyPPPFsmStarting:
+		return _S("STARTING");
+	case EDummyPPPFsmClosed:
+		return _S("CLOSED");
+	case EDummyPPPFsmStopped:
+		return _S("STOPPED");
+	case EDummyPPPFsmStopping:
+		return _S("STOPPING");
+	case EDummyPPPFsmClosing:
+		return _S("CLOSING");
+	case EDummyPPPFsmReqSent:
+		return _S("REQUEST SENT");
+	case EDummyPPPFsmAckRecvd:
+		return _S("ACK RECEIVED");
+	case EDummyPPPFsmAckSent:
+		return _S("ACK SENT");
+	case EDummyPPPFsmOpened:
+		return _S("OPENED");
+	case EDummyPPPFsmPapAuthReqSent:
+		return _S("PAP REQUEST SENT");
+	case EDummyPPPFsmPapAuthAckRecvd:
+		return _S("PAP ACK RECEIVED");
+	case EDummyPPPFsmPapAckSent:
+		return _S("PAP ACK SENT");
+	case EDummyPPPIPCPReqSent:
+		return _S("IPCP REQUEST SENT");
+	case EDummyPPPFsmIPOpen:
+		return _S("IP OPENED");
+	default:	// Should never happen in theory!
+		return _S("UNKNOWN");
+		}
+	}
+
+
+const TText* CDummyNifLog::LcpCodeToText(TUint aValue)
+	{
+
+	// LCP Codes
+	switch (aValue)
+		{
+	case KPppLcpEchoRequest:
+		return _S("Echo request");
+	case KPppLcpEchoReply:
+		return _S("Echo reply");
+	case KPppLcpDiscardRequest:
+		return _S("Discard request");
+	case KPppLcpIdentification:
+		return _S("Identification");
+	case KPppLcpTimeRemaining:
+		return _S("Time remaining");
+	default:
+		return FsmCodeToText(aValue);
+		}
+	}
+
+const TText* CDummyNifLog::FsmCodeToText(TUint aValue)
+	{
+
+	// LCP Codes
+	switch (aValue)
+		{
+	case KPppLcpConfigRequest:
+		return _S("Config Request");
+	case KPppLcpConfigAck:
+		return _S("Config ACK");
+	case KPppLcpConfigNak:
+		return _S("Config NAK");
+	case KPppLcpConfigReject:
+		return _S("Config Reject");
+	case KPppLcpTerminateRequest:
+		return _S("Terminate request");
+	case KPppLcpTerminateAck:
+		return _S("Terminate ACK");
+	case KPppLcpCodeReject:
+		return _S("Code Reject");
+	case KPppLcpProtocolReject:
+		return _S("Protocol Reject");
+	case KPppCcpResetReq:
+		// Only used by CCP, but this is the easiest place to put it
+		return _S("Reset Request");
+	case KPppCcpResetAck:
+		// Only used by CCP, but this is the easiest place to put it
+		//__DEBUGGER();
+		return _S("Reset Ack");
+	default:
+		return _S("Unknown");
+		}
+	}
+
+const TText* CDummyNifLog::PapCodeToText(TUint aValue)
+	{
+
+	// PAP Codes
+	switch (aValue)
+		{
+	case 1:
+		return _S("Authenticate Request");
+	case 2:
+		return _S("Authenticate ACK");
+	case 3:
+		return _S("Authenticate NAK");
+	default:
+		return _S("Unknown");
+		}
+	}
+
+const TText* CDummyNifLog::CbcpCodeToText(TUint aValue)
+	{
+
+	// CHAP Codes
+	switch (aValue)
+		{
+	case 1:
+		return _S("Callback Request");
+	case 2:
+		return _S("Callback Response");
+	case 3:
+		return _S("Callback Ack");
+	default:
+		return _S("Unknown");
+		}
+	}
+
+const TText* CDummyNifLog::ChapCodeToText(TUint aValue)
+	{
+
+	// CHAP Codes
+	switch (aValue)
+		{
+	case 1:
+		return _S("Challenge");
+	case 2:
+		return _S("Response");
+	case 3:
+		return _S("Success");
+	case 4:
+		return _S("Failure");
+	default:
+		return _S("Unknown");
+		}
+	}
+
+const TText* CDummyNifLog::IpProtocolToText(TUint aValue)
+	{
+
+	// IP Protocols
+	switch (aValue)
+		{
+	case 1:
+		return _S("ICMP");
+	case 58:
+		return _S("ICMPv6");
+	case 17:
+		return _S("UDP");
+	case 6:
+		return _S("TCP");
+
+	default:
+		return _S("Unknown");
+		}
+	}
+
+const TText* CDummyNifLog::IpcpCodeToText(TUint aValue)
+	{
+
+	// IPCP Codes
+	switch (aValue)
+		{
+	case KPppIpcpOptIpAddresses:
+		return _S("IP Addresses");
+	case KPppIpcpOptIpCompressionProtocol:
+		return _S("IP Compression Protocol");
+	case KPppIpcpOptIpAddress:
+		return _S("IP Address");
+	case KPppIpcpOptPrimaryDnsAddress:
+		return _S("Primary DNS Address");
+	case KPppIpcpOptSecondaryDnsAddress:
+		return _S("Secondary DNS Address");
+	case KPppIpcpOptPrimaryNbnsAddress:
+		return _S("Primary NBNS Address");
+	case KPppIpcpOptSecondaryNbnsAddress:
+		return _S("Secondary NBNS Address");
+	default:
+		return _S("Unknown");
+		}
+	}
+
+const TText* CDummyNifLog::Ip6cpCodeToText(TUint aValue)
+	{
+	// IP6CP Codes
+	switch (aValue)
+		{
+	case KPppIp6cpOptInterfaceIdentifier:
+		return _S("Interface Identifier");
+	case KPppIp6cpOptCompressionProtocol:
+		return _S("Compression Protocol");
+	default:
+		return _S("Unknown");
+		}
+	}
+const TText* CDummyNifLog::CcpCodeToText(TUint aValue)
+	{
+
+	// CCP Codes
+	switch (aValue)
+		{
+	case KPppCcpOptOui:
+		return _S("OUI");
+	case KPppCcpOptPred1:
+		return _S("Predictor type1");
+	case KPppCcpOptPred2:
+		return _S("Predictor type2");
+	case KPppCcpOptPuddle:
+		return _S("Puddle");
+	case KPppCcpOptHP:
+		return _S("HP PPC");
+	case KPppCcpOptStac:
+		return _S("Stac LZS");
+	case KPppCcpOptMsoft:
+		return _S("Microsoft PPC");
+	case KPppCcpOptGandalf:
+		return _S("Gandalf");
+	case KPppCcpOptV42bis:
+		return _S("V42bis");
+	case KPppCcpOptReserved:
+		return _S("Reserved");
+	case 4:
+	case 5:
+	case 6:
+	case 7:
+	case 8:
+	case 9:
+	case 10:
+	case 11:
+	case 12:
+	case 13:
+	case 14:
+	case 15:
+		return _S("unassigned");
+	default:
+		return _S("Unknown");
+		}
+	}
+
+
+TInt CDummyNifLog::DumpLcp(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 code = *ptr++;
+	TUint8 id = *ptr++;
+	TInt len = BigEndian::Get16(ptr);
+	if(len>aDes.Length())
+		{
+		Printf(_L("WARNING: Length reported in header was more than actual frame length\n"));
+		return len;
+		}
+	else if (len<aDes.Length())
+		Printf(_L("WARNING: Length reported in header was less than actual frame length!\n"));
+
+	ptr += 2;
+	aDes.Set(ptr, aDes.Length()-4);
+	
+	Printf(KCodeTextString, LcpCodeToText(code), code);
+	Printf(KIdentifierLengthString, id, len);
+	
+	switch (code)
+		{
+	case KPppLcpConfigRequest:
+	case KPppLcpConfigAck:
+	case KPppLcpConfigNak:
+	case KPppLcpConfigReject:
+			{
+			TInt n = len-4;
+			TInt tmp = 0;
+			while (n>0 && aDes.Length()>0)
+				{
+				tmp = DumpLcpOption(aDes);
+				if (tmp == 0)	//Check for an error in the DumpLcpOption (0 is interpreted as an error)
+					{
+					Printf(_L("WARNING: Length reported in LCP Option was incorrect! Dumping data instead\n"));
+					DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+					break;
+					}
+				n=n-tmp;
+				}	
+
+			if (n>0)
+				Printf(KBytesRemainingString, n, (n>1)?"s":"");
+			}
+
+		break;
+	case KPppLcpTerminateRequest:
+	case KPppLcpTerminateAck:
+			{
+			if (len>4)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+			}
+		break;
+	case KPppLcpCodeReject:
+			{
+			TUint val = *ptr;
+			Printf(KCodeString, val);
+			}
+		break;
+	case KPppLcpProtocolReject:
+			{
+			TUint val = BigEndian::Get16(ptr);		
+			Printf(KProtocolString, val);
+			}
+		break;
+	case KPppLcpEchoRequest:
+			{
+			TUint val = BigEndian::Get32(ptr);	
+			Printf(KNumberString, val);
+			if (len>0)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr+4, len-8);
+			}
+		break;
+	case KPppLcpEchoReply:
+			{
+			TUint val = BigEndian::Get32(ptr);
+			Printf(KNumberString, val);
+			if (len>0)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr+4, len-8);
+			}
+		break;
+	case KPppLcpDiscardRequest:
+			{
+			TUint val = BigEndian::Get32(ptr);
+			Printf(KNumberString, val);
+			if (len>0)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr+4, len-8);
+			}
+		break;
+	case KPppLcpIdentification:
+			{
+			TUint val = BigEndian::Get32(ptr);
+			Printf(KNumberString, val);
+			if (len>0)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr+4, len-8);
+			}
+		break;
+	case KPppLcpTimeRemaining:
+			{
+			TUint val = BigEndian::Get32(ptr);
+			ptr+=4;
+			Printf(KNumberString, val);
+			val = BigEndian::Get32(ptr);
+			Printf(KSecondsString, val);
+			}
+		break;
+	default:
+		break;
+		}
+
+	return len;
+	}
+
+TInt CDummyNifLog::DumpLcpOption(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 opt = *ptr++;
+	TUint8 len = *ptr++;
+
+	if(len > aDes.Length())
+		{
+		Printf(_L("WARNING: Length reported in option header was more than actual frame length\n"));
+		return 0;	//Return an incorrect length to flag this error.
+		}
+
+	if(len < 2)
+		{
+		Printf(_L("WARNING: Length reported in option header was less than a correct frame length\n"));
+		return 0;	//Return an incorrect length. (the minimum correct length of an option is 2)
+		}
+	
+	Printf(KLcpCodeString, LcpOptToText(opt), opt);
+	Printf(KLengthString, len);
+	
+	switch (opt)
+		{
+	case KPppLcpOptMaxRecvUnit:
+			{
+			TUint val = BigEndian::Get16(ptr);
+			Printf(KSizeString, val);
+			}
+		break;
+	case KPppLcpOptEscapeCharMap:
+			{
+			TUint val = BigEndian::Get32(ptr);
+			Printf(KMapString, val);
+			}
+		break;
+	case KPppLcpOptAuthenticationProtocol:
+			{
+			TUint val = BigEndian::Get16(ptr);
+
+			Printf(KProtocolTextString, ProtocolToText(val), val);
+			if (val != KPppIdChap)
+				{
+				if (len>4)
+					DumpBytes(EIGHT_SPACE_MARGIN, ptr+2, len-4);
+				}
+			else
+				{
+				if(len>4)
+					DumpChapType(ptr+2);
+				}
+			}
+		break;
+	case KPppLcpOptQualityProtocol:
+			{
+			TUint val = BigEndian::Get16(ptr);
+			Printf(KProtocolTextString, ProtocolToText(val), val);
+			if (len>4)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr+2, len-4);
+			}
+		break;
+	case KPppLcpOptMagicNumber:
+			{
+			TUint val = BigEndian::Get32(ptr);
+			Printf(KNumberString, val);
+			}
+		break;
+	case KPppLcpOptProtocolCompress:
+	case KPppLcpOptAddrCtrlCompress:
+		break;
+	case KPppLcpOptFcsType:
+			{
+			TUint val = *ptr++;
+			//only for display
+			//Printf(KLcpOptFcsTypeString, (val&KPppDummyPPPFcs0Flag)?_S(" None"):_S(""), (val&KPppDummyPPPFcs16Flag)?_S(" 16 bit"):_S(""), (val&KPppDummyPPPFcs32Flag)?_S(" 32 bit"):_S(""));
+			Printf(KLcpOptFcsTypeString, val?_S(" None"):_S(""));
+			}
+		break;
+	case KPppLcpOptPadding:
+			{
+			TUint val = *ptr++;
+			Printf(KMaximumBytesString, val);
+			}
+		break;
+	case KPppLcpOptCallback:
+			{
+			TUint val = *ptr++;
+			Printf(KCodeTextString, CallbackOpToText(val), val);
+			if (len>3)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr+3, len-3);
+			}
+		break;
+	case KPppLcpOptCompoundFrames:
+		break;
+		}
+	aDes.Set((TUint8*)aDes.Ptr()+len, aDes.Length()-len);
+	return len;
+	}
+
+TInt CDummyNifLog::DumpPap(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 code = *ptr++;
+	TUint8 id = *ptr++;
+	TInt len = BigEndian::Get16(ptr);
+	ptr += 2;
+
+	Printf(KCodeTextString, PapCodeToText(code), code);
+	Printf(KIdentifierLengthString, id, len);
+	
+	if (code==1)
+		{
+		TInt n = *ptr++;
+		TPtrC8 v;
+		v.Set(ptr, n);    ptr += n;
+		TBuf16<KLogBufferSize> temp;
+		temp.Copy(v.Left(Min(v.Length(),KLogBufferSize)));
+		Printf(KUserNameString, &temp);
+		n = *ptr++;
+		v.Set(ptr, n);    ptr += n;
+		temp.Copy(v.Left(Min(v.Length(),KLogBufferSize)));
+		Printf(KPasswordString, &temp);
+		}
+	else if (code==2 || code==3)
+		{
+		TInt n = *ptr++;
+		TPtrC8 v;
+		v.Set(ptr, n);    ptr += n;
+		TBuf16<KLogBufferSize> temp;
+		temp.Copy(v.Left(Min(v.Length(),KLogBufferSize)));
+		Printf(KMessageString, &temp);
+		}
+
+	aDes.Set(aDes.Ptr()+len, aDes.Length()-len);
+	return len;
+	}
+
+TInt CDummyNifLog::DumpCbcp(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 code = *ptr++;
+	TUint8 id = *ptr++;
+	TInt len = BigEndian::Get16(ptr);
+	TInt length = len;
+	ptr += 2;
+
+	Printf(KCodeTextString, CbcpCodeToText(code), code);
+	Printf(KIdentifierLengthString, id, len);
+
+	//
+	// OK we can be offered many options at once, so 
+	// loop for the length and decode them.
+	//
+	len -= 4; // Subtract the stuff we know about
+
+	TUint8	type;
+	TUint	typeLen;
+	while (len)
+		{
+		// Yes I know we can have a permanent loop but I just don't care
+		type = *ptr++;
+		switch(type)
+			{
+		case 1:
+				{
+				_LIT(string1,"        No CallBack\n");
+				Write(string1);
+				}
+			break;
+		case 2:
+				{
+				_LIT(string2,"        Callback to a user specified No.\n");
+				Write(string2);
+				}
+			break;
+		case 3:
+				{
+				_LIT(string3,"        Callback to a pre specified No.\n");
+				Write(string3);
+				}
+			break;
+		case 4:
+				{
+				_LIT(string4,"        Callback to one of a list of numbers\n");
+				Write(string4);
+				}
+			break;
+		default:
+				{
+				_LIT(string5,"        Unknown Callback type\n");
+				Write(string5);
+				}
+			break;
+		}
+
+		if (len == 1)
+			len = 0;
+
+		typeLen = *ptr++;
+			Printf(KLengthString,typeLen);
+
+		if (typeLen > 2)
+		 	Printf(KDelayString,*ptr++);
+
+		if (typeLen > 3)
+			{
+			//
+			// Dump the Address Type field
+			//
+			if (*ptr++ == 1)
+				{
+				_LIT(string6,"            PSTN/ISDN\n");
+				Write(string6);
+				}
+			else
+				{
+				_LIT(string7,"            Other\n");
+				Write(string7);
+				}
+			}
+
+		//
+		// Dump the NULL terminated ASCII string
+		//
+ 		DumpBytes(EIGHT_SPACE_MARGIN, ptr, (typeLen-4));
+		len -= typeLen;
+		}
+
+	aDes.Set(aDes.Ptr()+length, aDes.Length()-length);
+	return length;
+	}
+
+TInt CDummyNifLog::DumpChap(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 code = *ptr++;
+	TUint8 id = *ptr++;
+	TInt len = BigEndian::Get16(ptr);
+	ptr += 2;
+
+	Printf(KCodeTextWithoutSpacesString,FsmCodeToText(code), code);
+	Printf(KIdentifierLengthString, id, len);
+	
+	if (code==1 || code==2)
+		{
+		TInt n = *ptr++;
+		DumpBytes(EIGHT_SPACE_MARGIN, ptr, n);
+		ptr += n;
+
+		n = len-(4+1+n);
+		TPtrC8 v;
+		v.Set(ptr, n);    ptr += n;
+		TBuf16<KLogBufferSize> temp;
+		temp.Copy(v);
+		Printf(KNameString, &temp);
+		}
+	else if (code==3 || code==4)
+		{
+		TInt n = (len-4);
+		TPtrC8 v;
+		v.Set(ptr, n);
+		ptr += n;
+		TBuf16<KLogBufferSize> temp;
+		temp.Copy(v);
+		Printf(KMessageString, &temp);
+		}
+
+	aDes.Set(aDes.Ptr()+len, aDes.Length()-len);
+	return len;
+	}
+
+
+TInt CDummyNifLog::DumpCcp(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 code = *ptr++;
+	TUint8 id = *ptr++;
+	TInt len = BigEndian::Get16(ptr);
+	ptr += 2;
+	aDes.Set(ptr, aDes.Length()-4);
+
+	Printf(KCodeTextWithoutSpacesString,FsmCodeToText(code), code);
+	Printf(KIdentifierLengthString, id, len);
+	
+	switch (code)
+		{
+	case KPppLcpConfigRequest:
+	case KPppLcpConfigAck:
+	case KPppLcpConfigNak:
+	case KPppLcpConfigReject:
+			{
+			TInt n = len-4;
+			TInt tmp = 0;
+			while (n>0 && aDes.Length()>0)
+				{
+				tmp = DumpCcpOption(aDes);
+				if (tmp == 0) 	//Check for an error in the DumpCcpOption (0 is interpreted as an error)
+					{
+					Printf(_L("WARNING: Length reported in CCP Option was incorrect! Dumping data instead\n"));
+					DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+					break;
+					}
+				n=n-tmp;
+				}	
+
+			if (n>0)
+				Printf(KBytesRemainingString, n, (n>1)?"s":"");
+			}
+		break;
+	case KPppLcpTerminateRequest:
+	case KPppLcpTerminateAck:
+			{
+			if (len>4)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+			}
+		break;
+	case KPppLcpCodeReject:
+			{
+			TUint val = BigEndian::Get16(ptr);
+			Printf(KCodeString, val);
+			}
+		break;
+	case KPppLcpProtocolReject:
+			{
+			TUint val = BigEndian::Get16(ptr);
+			Printf(KProtocolString, val);
+			}
+		break;
+		}
+	return len;
+	}
+
+TInt CDummyNifLog::DumpCcpOption(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 opt = *ptr++;
+	TUint8 len = *ptr++;
+
+	if(len > aDes.Length())
+		{
+		Printf(_L("WARNING: Length reported in option header was more than actual frame length\n"));
+		return 0;	//Return an incorrect length to flag this error.
+		}
+
+	if(len < 2)
+		{
+		Printf(_L("WARNING: Length reported in option header was less than a correct frame length\n"));
+		return 0;	//Return an incorrect length. (the minimum correct length of an option is 2)
+		}
+
+	Printf(KCodeTextString, CcpCodeToText(opt), opt);
+	Printf(KLengthString, len);
+
+	DumpBytes(FOURTEEN_SPACE_MARGIN, ptr, len-2);
+	aDes.Set((TUint8*)aDes.Ptr()+len, aDes.Length()-len);
+	return len;
+	}
+
+TInt CDummyNifLog::DumpIp6cp(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 code = *ptr++;
+	TUint8 id = *ptr++;
+	TInt len = BigEndian::Get16(ptr);
+	ptr += 2;
+	aDes.Set(ptr, aDes.Length()-4);
+
+	Printf(KCodeTextWithoutSpacesString, FsmCodeToText(code), code);
+	Printf(KIdentifierLengthString, id, len);
+	
+	switch (code)
+		{
+	case KPppLcpConfigRequest:
+	case KPppLcpConfigAck:
+	case KPppLcpConfigNak:
+	case KPppLcpConfigReject:
+			{
+			TInt n = len-4;
+			//only for testing display
+			//while (n>0 && aDes.Length()>0)
+			//	n -= DumpIp6cpOption(aDes);
+			if (n>0)
+				Printf(KBytesRemainingString, n, (n>1)?"s":"");
+			}
+		break;
+	case KPppLcpTerminateRequest:
+	case KPppLcpTerminateAck:
+			{
+			if (len>4)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+			}
+		break;
+	case KPppLcpCodeReject:
+			{
+			TUint val = BigEndian::Get16(ptr);
+			Printf(KCodeString2, val);
+			}
+		break;
+	case KPppLcpProtocolReject:
+			{
+			TUint val = BigEndian::Get16(ptr);
+			Printf(KProtocolString, val);
+			}
+		break;
+		}
+	return len;
+	}
+TInt CDummyNifLog::DumpIp(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 c = *ptr++;
+//	TUint ver = c >> 4;
+	TUint hlen = (c & 0xf) << 2;
+//	TUint8 tos = *ptr;
+	ptr++;
+	TUint16 len = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+	ptr+=2;
+	TUint16 id = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+	ptr+=2;
+	TUint16 frag = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+	ptr+=2;
+	TBool zf = (frag & 0x8000);
+	TBool df = (frag & 0x4000);
+	TBool mf = (frag & 0x2000);
+	frag = (TUint16)((frag & 0x1fff)<<3);
+//	TUint8 ttl = *ptr;
+	ptr++;
+	TUint8 proto = *ptr++;
+//	TUint16 chksum = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+	ptr+=2;
+	TUint32 srca = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+	ptr+=4;
+	TUint32 dsta = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+	ptr+=4;
+//	TBool opts = (hlen>20);
+
+	Printf(KHdrLengthString, len, hlen);
+	Printf(KSrcDstAddrString,(srca&0xff000000)>>24,(srca&0x00ff0000)>>16,(srca&0x0000ff00)>>8,(srca&0x000000ff),
+							 (dsta&0xff000000)>>24,(dsta&0x00ff0000)>>16,(dsta&0x0000ff00)>>8,(dsta&0x000000ff));
+	Printf(KIDFragmentString, id, frag, df?_S("<DF>"):_S(""), mf?_S("<MF>"):_S(""), zf?_S("<Z>"):_S(""));
+//	Printf(KTOSTTLChksumString, tos, ttl, chksum);
+	Printf(KCodeTextString, IpProtocolToText(proto), proto);
+	
+	if (hlen>20)
+		ptr += (hlen-20);
+	
+	TInt n = (TInt)ptr-(TInt)aDes.Ptr();
+	TInt tlen = aDes.Length()-n;
+	aDes.Set(ptr, tlen);
+
+	switch (proto)
+		{
+	case 1:
+		return n+DumpIcmp(aDes, tlen);
+	case 6:
+		return n+DumpTcp(aDes, srca, dsta, tlen);
+	case 17:
+		return n+DumpUdp(aDes, srca, dsta, tlen);
+	default:
+		return n;
+		}
+	}
+
+TInt CDummyNifLog::DumpIpcp(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 code = *ptr++;
+	TUint8 id = *ptr++;
+	TInt len = BigEndian::Get16(ptr);
+	ptr += 2;
+	aDes.Set(ptr, aDes.Length()-4);
+
+	Printf(KCodeTextWithoutSpacesString, FsmCodeToText(code), code);
+	Printf(KIdentifierLengthString, id, len);
+	
+	switch (code)
+		{
+	case KPppLcpConfigRequest:
+	case KPppLcpConfigAck:
+	case KPppLcpConfigNak:
+	case KPppLcpConfigReject:
+			{
+			TInt n = len-4;
+			TInt tmp = 0;
+			while (n>0 && aDes.Length()>0)
+				{
+				tmp = DumpIpcpOption(aDes);
+				if (tmp == 0)  	//Check for an error in the DumpIpcpOption (0 is interpreted as an error)
+					{
+					Printf(_L("WARNING: Length reported in IPCP Option was incorrect! Dumping data instead\n"));
+					DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+					break;
+					}
+				n=n-tmp;
+				}	
+
+			if (n>0)
+				Printf(KBytesRemainingString, n, (n>1)?"s":"");
+			}
+		break;
+	case KPppLcpTerminateRequest:
+	case KPppLcpTerminateAck:
+			{
+			if (len>4)
+				DumpBytes(EIGHT_SPACE_MARGIN, ptr, len-4);
+			}
+		break;
+	case KPppLcpCodeReject:
+			{
+			TUint val = BigEndian::Get16(ptr);
+			Printf(KCodeString2, val);
+			}
+		break;
+	case KPppLcpProtocolReject:
+			{
+			TUint val = BigEndian::Get16(ptr);
+			Printf(KProtocolString, val);
+			}
+		break;
+		}
+	return len;
+	}
+
+TInt CDummyNifLog::DumpIpcpOption(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 opt = *ptr++;
+	TUint8 len = *ptr++;
+
+	if(len > aDes.Length())
+		{
+		Printf(_L("WARNING: Length reported in option header was more than actual frame length\n"));
+		return 0;	//Return an incorrect length to flag this error.
+		}
+
+	if(len < 2)
+		{
+		Printf(_L("WARNING: Length reported in option header was less than a correct frame length\n"));
+		return 0;	//Return an incorrect length. (the minimum correct length of an option is 2)
+		}
+
+	Printf(KCodeTextString, IpcpCodeToText(opt), opt);
+	Printf(KLengthString2, len);
+	
+   TUint32 val;
+
+	switch (opt)
+		{
+	case KPppIpcpOptIpAddresses:
+		val = BigEndian::Get32(ptr);
+		Printf(KRemoteAddrString,(val&0xff000000)>>24,(val&0x00ff0000)>>16,(val&0x0000ff00)>>8,(val&0x000000ff));
+		val = BigEndian::Get32(ptr+4);
+		Printf(KOurAddrString,(val&0xff000000)>>24,(val&0x00ff0000)>>16,(val&0x0000ff00)>>8,(val&0x000000ff));
+		break;
+	case KPppIpcpOptIpCompressionProtocol:
+			{
+			TUint prot = BigEndian::Get16(ptr);
+			ptr += 2;
+			Printf(KProtocolTextString, ProtocolToText(prot), prot);
+			if (len>4)
+				{
+				switch (prot)
+					{
+				case KPppIdVjCompTcp:
+					Printf(KMaxSlotString, *ptr++);
+					Printf(KCompSlotString, *ptr++);
+					break;
+				default:
+					DumpBytes(FOURTEEN_SPACE_MARGIN, ptr+4, len-4);
+					break;
+					}
+				}
+			}
+		break;
+	case KPppIpcpOptIpAddress:
+	case KPppIpcpOptPrimaryDnsAddress:
+	case KPppIpcpOptSecondaryDnsAddress:
+	case KPppIpcpOptPrimaryNbnsAddress:
+	case KPppIpcpOptSecondaryNbnsAddress:
+			{
+			val = BigEndian::Get32(ptr);
+			Printf(KAddrString,(val&0xff000000)>>24,(val&0x00ff0000)>>16,(val&0x0000ff00)>>8,(val&0x000000ff));
+			}
+		break;
+		}
+	aDes.Set((TUint8*)aDes.Ptr()+len, aDes.Length()-len);
+	return len;
+	}
+
+TInt CDummyNifLog::DumpIp6(TPtrC8& aDes)
+	{
+	// This dumps the main IPv6 Header, no support for option headers
+	// IPv6 Headers are FIXED length, but are chainable...
+	TUint16* ptr = (TUint16*)aDes.Ptr();
+	
+	// First 32 bits contain version(4), class(8), Flow Label(20)
+	
+	TUint32 first = ByteOrder::Swap32((TUint32) *ptr);
+	//TUint8 ver = (TUint8)((first >> 28) & 0xf);
+	TUint8 cls = (TUint8)((first >> 20) & 0xff);
+	TUint32 flowLab = (first & 0xfffff);
+	ptr+=2;
+
+	// Second 32 bits contain payload length (16), next header type (8), hop limit (8)
+	TUint16 payLoadLen = ByteOrder::Swap16( *ptr++ );
+	TUint16 next = ByteOrder::Swap16( *ptr++ ); 
+	TUint8 nextHead = (TUint8)((next >> 8) & 0xff);
+	TUint8 hopLimit = (TUint8)(next & 0xff);
+	
+	// Source address (128 bits)
+	TUint16 s1 = ByteOrder::Swap16( *ptr++ );
+	TUint16 s2 = ByteOrder::Swap16( *ptr++ );
+	TUint16 s3 = ByteOrder::Swap16( *ptr++ );
+	TUint16 s4 = ByteOrder::Swap16( *ptr++ );
+	TUint16 s5 = ByteOrder::Swap16( *ptr++ );
+	TUint16 s6 = ByteOrder::Swap16( *ptr++ );
+	TUint16 s7 = ByteOrder::Swap16( *ptr++ );
+	TUint16 s8 = ByteOrder::Swap16( *ptr++ );
+	
+	// Destination address (128 bits)
+	TUint16 a1 = ByteOrder::Swap16( *ptr++ );
+	TUint16 a2 = ByteOrder::Swap16( *ptr++ );
+	TUint16 a3 = ByteOrder::Swap16( *ptr++ );
+	TUint16 a4 = ByteOrder::Swap16( *ptr++ );
+	TUint16 a5 = ByteOrder::Swap16( *ptr++ );
+	TUint16 a6 = ByteOrder::Swap16( *ptr++ );
+	TUint16 a7 = ByteOrder::Swap16( *ptr++ );
+	TUint16 a8 = ByteOrder::Swap16( *ptr++ );
+	
+	//Printf(_L("    Version is %d"),ver);	// Should be 6 for IPv6 !!
+	Printf(KIpv6Class, cls);
+	Printf(KIpv6FlowLabel, flowLab);
+	Printf(KIpv6PayloadLen, payLoadLen);
+	Printf(KIpv6NextHeadType, nextHead);
+	Printf(KIpv6HopLimit, hopLimit);
+	Printf(KIpv6SrcAddress, s1,s2,s3,s4,s5,s6,s7,s8);
+	Printf(KIpv6DstAddress, a1,a2,a3,a4,a5,a6,a7,a8);
+	
+	TInt n = (TInt)ptr-(TInt)aDes.Ptr();
+	TInt tlen = aDes.Length()-n;
+	aDes.Set( (TUint8*) ptr, tlen);
+
+	switch (nextHead)
+		{
+		case 6:		// TCP Packet
+			Printf(_L("        TCP Data"));
+			//DumpTcp(aDes);
+			HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+			break;
+		case 17:	// UDP Packet
+			Printf(_L("        UDP Data"));
+			DumpUdp(aDes,s8,a8,tlen);
+			break;
+		case 43:	// Routing Header
+			Printf(_L("        Routing Header"));
+			//DumpRouter
+			HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+			break;
+		case 44:	// Fragment Header
+			Printf(_L("        Packet Fragment"));
+			//DumpFragment
+			HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+			break;
+		case 50:	// ESP Payload
+			Printf(_L("        ESP Payload"));
+			HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+			break;
+		case 58:	// ICMPv6
+			Printf(_L("        ICMPv6"));
+			DumpIcmp(aDes,tlen);
+			break;
+		case 59:	// No Next Header
+			Printf(_L("        NO NEXT HEADER"));
+			HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+			break;
+		default:
+			Printf(KIpv6UnknownHeadType, nextHead);
+			HexDump(EIGHT_SPACE_MARGIN,EIGHT_SPACE_MARGIN, aDes.Ptr(), tlen);
+		}
+
+	return n;	
+	}
+
+TInt CDummyNifLog::DumpVjCompTcp(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint16	change = *ptr++;
+	TUint8	urgent=0;
+	TInt16	window=0;
+	TUint16	ack=0;
+	TUint16	sequence=0;
+	TBuf<50> changeMaskBuf;;
+	TUint8	connection=0;
+
+	changeMaskBuf.Append(KChangeMaskString);
+
+	if (change & KVjCompMaskConn)
+		{	
+		_LIT(string7,"C");
+		changeMaskBuf.Append(string7);
+		connection = *ptr++;
+		}
+
+	TUint16 checksum = BigEndian::Get16(ptr);
+	ptr += 2;
+
+	if (change & KVjCompMaskPush)
+		{
+		_LIT(string8,"P");
+		changeMaskBuf.Append(string8);
+		}
+
+	/*
+	*	Don't reorder SpecialI && SpecialD, they are like this
+	*	as SpecialD is the SWAU bits and SpecialI is SWU
+	*
+	*/
+
+	if ((change & KVjCompMaskSpecials) == KVjCompMaskSpecialD)
+		{
+		_LIT(string1,"	Special D");
+		Write(string1);
+		}
+	else if ((change & KVjCompMaskSpecials) == KVjCompMaskSpecialI)
+		{
+		_LIT(string2,"	Special I");
+		Write(string2);
+		}
+	else
+		{
+		if (change & KVjCompMaskUrgent)
+			{
+			_LIT(string3,"U");
+			changeMaskBuf.Append(string3);
+			urgent = *ptr++;
+			}
+
+		if (change & KVjCompMaskWindow )
+			{
+			//only for display
+			//window = (TInt16)DecodeSignedDelta(ptr);
+			_LIT(string4,"W");
+			changeMaskBuf.Append(string4);
+			}
+
+		if (change & KVjCompMaskAck )
+			{
+			//only for display
+			//ack = DecodeDelta(ptr);
+			_LIT(string5,"A");
+			changeMaskBuf.Append(string5);
+			}
+
+		if (change & KVjCompMaskSeq)
+			{	
+			//only for display
+			//sequence = DecodeDelta(ptr);
+			_LIT(string6,"S");
+			changeMaskBuf.Append(string6);
+			}
+		}
+
+
+	TUint16	ipId=0;
+	if (change & KVjCompMaskIp)
+		{	
+		//only for display
+	    //ipId = DecodeDelta(ptr);
+		_LIT(string9,"I");
+		changeMaskBuf.Append(string9);
+		}
+
+	Printf(TRefByValue<const TDesC>(changeMaskBuf), change);
+
+	Printf(KChecksumString, checksum);
+
+	if (change & KVjCompMaskConn)
+		{
+		Printf(KConnectionString,connection);
+		}
+
+	if	(urgent)
+		{
+		_LIT(string10,"	Urgent Delta = 0x%x");
+		Printf(string10,urgent);
+		}
+
+	if (window)
+		{
+		_LIT(string11,"	Window Delta = %d");
+		Printf(string11,window);
+		}
+
+	if (ack)
+		{
+		_LIT(string12,"	Ack Delta = 0x%x");
+		Printf(string12,ack);
+		}
+
+	if (sequence)
+		{
+		_LIT(string13,"	Sequence Delta = 0x%x");
+		Printf(string13,sequence);
+		}
+
+	if (ipId)
+		{
+		_LIT(string14,"	IPId = 0x%x");
+		Printf(string14,ipId);
+		}
+
+	return 1;
+	}
+TInt CDummyNifLog::DumpVjUncompTcp(TPtrC8& aDes)
+	{
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 c = *ptr++;
+//	TUint ver = c >> 4;
+	TUint hlen = (c & 0xf) << 2;
+//	TUint8 tos = *ptr;
+	ptr++;
+	TUint16 len = ByteOrder::Swap16((TUint16)(*ptr++ | *ptr++<<8));
+	TUint16 id = ByteOrder::Swap16((TUint16)(*ptr++ | *ptr++<<8));
+	TUint16 frag = ByteOrder::Swap16((TUint16)(*ptr++ | *ptr++<<8));
+	TBool zf = (frag & 0x8000);
+	TBool df = (frag & 0x4000);
+	TBool mf = (frag & 0x2000);
+	frag = (TUint16)((frag & 0x1fff)<<3);
+//	TUint8 ttl = *ptr;
+	ptr++;
+	TUint8 proto = *ptr++;
+//	TUint16 chksum = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+	ptr+=2;
+	TUint32 srca = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+	ptr+=4;
+	TUint32 dsta = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+	ptr+=4;
+//	TBool opts = (hlen>20);
+
+	Printf(KHdrLengthString, len, hlen);
+	Printf(KSrcDstAddrString, (srca&0xff000000)>>24,(srca&0x00ff0000)>>16,(srca&0x0000ff00)>>8,(srca&0x000000ff),
+							  (dsta&0xff000000)>>24,(dsta&0x00ff0000)>>16,(dsta&0x0000ff00)>>8,(dsta&0x000000ff));
+	Printf(KIDFragmentString, id, frag, df?_S("<DF>"):_S(""), mf?_S("<MF>"):_S(""), zf?_S("<Z>"):_S(""));
+//	Printf(KTOSTTLChksumString, tos, ttl, chksum);
+	Printf(KConnectionNoString, proto);
+	
+	if (hlen>20)
+		ptr += (hlen-20);
+	
+	TInt n = (TInt)ptr-(TInt)aDes.Ptr();
+	TInt tlen = aDes.Length()-n;
+	aDes.Set(ptr, tlen);
+	return n+DumpTcp(aDes, srca, dsta, tlen);
+	}
+
+TInt CDummyNifLog::DumpTcp(TPtrC8& aDes, TUint32 aSrcA, TUint32 aDstA, TInt aLength)
+	{
+	
+	TInt n = Min(aLength, aDes.Length());
+	TInt len = n;
+	
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint8 osum0 = ptr[16];
+	ptr[16] = 0;
+	TUint8 osum1 = ptr[17];
+	ptr[17] = 0;
+
+	TUint32 sum = 0;
+	sum += (aSrcA >> 16);
+	sum += (aSrcA & 0xffff);
+	sum += (aDstA >> 16);
+	sum += (aDstA & 0xffff);
+	sum += 6;
+	sum += n;
+	while (n>1)
+		{
+		sum += (ptr[0]<<8);
+		sum += (ptr[1]);
+		ptr += 2;
+		n -= 2;
+		}
+	if (n>0)
+		sum += (ptr[0]<<8);
+	while (sum>0xffff)
+		{
+		sum = (sum & 0xffff) + (sum>>16);
+		}
+	sum = ~sum & 0xffff;
+	ptr = (TUint8*)aDes.Ptr();
+	ptr[16] = osum0;
+	ptr[17] = osum1;
+	
+	TUint srcp = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+	ptr +=2;
+	TUint dstp = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+	ptr +=2;
+	TUint32 seqnum = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+	ptr+=4;
+	TUint32 acknum = ByteOrder::Swap32(*ptr | (*(ptr+1)<<8) | (*(ptr+2)<<16) | (*(ptr+3)<<24));
+	ptr+=4;
+
+	TUint8 c = *ptr++;
+	TUint hlen = (c>>4)<<2;
+
+	c = *ptr++;
+	TUint urgf = c & 0x20;
+	TUint ackf = c & 0x10;
+	TUint pshf = c & 0x08;
+	TUint rstf = c & 0x04;
+	TUint synf = c & 0x02;
+	TUint finf = c & 0x01;
+
+	TUint window = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+	ptr+=2;
+	TUint chksum = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+	ptr+=2;
+	TUint urgptr = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+	ptr+=2;
+	
+	Printf(KTCPLengthString, len, hlen);
+	Printf(KPortString, srcp, dstp);
+//	Printf(KDestPortString, dstp);
+//	Printf(KTCPHeaderLengthString, hlen);
+	Printf(KSeqAckString, seqnum, acknum);
+	Printf(KFlagsString, urgf?_S(" <URG>"):_S(""), ackf?_S(" <ACK>"):_S(""), pshf?_S(" <PSH>"):_S(""),
+		                      rstf?_S(" <RST>"):_S(""), synf?_S(" <SYN>"):_S(""), finf?_S(" <FIN>"):_S(""));
+	Printf(KWindowUrgentString, window, urgptr);
+	if (chksum != sum)
+		Printf(KChecksumString3, chksum, sum);
+
+	if (hlen>20)
+		{
+		_LIT(string2,"	TCP Options %d bytes");
+		Printf(string2, hlen-20);
+		TInt h, i, opt, optlen=0;
+		h = hlen-20;
+		for (i=0; i<h; i+=optlen)
+			{
+			opt = ptr[i];
+			if (opt == 0) // KTcpOptEol
+				break;
+			if (opt == 1) // KTcpOptNop
+				optlen = 1;
+			else
+				{
+				if (i+1 >= h)
+					break;
+				optlen = ptr[i+1];
+				if (optlen < 2)
+					optlen = 2;
+				}
+
+			switch (opt)
+				{
+			case 1:
+					{
+					_LIT(string3,"	    NOP");
+					Write(string3);
+					}
+				break;
+			case 2:
+					{
+					_LIT(string4,"	    Max Seg Size = %d");
+					Printf(string4, BigEndian::Get16(ptr+i+2));
+					}
+				break;
+			default:
+					{
+					_LIT(string5,"	    Unknown [0x%02x]");
+					Printf(string5, opt);
+					}
+				break;
+				}
+			}
+		}
+	
+	ptr += (hlen-20);
+	TInt n1 = (TInt)aDes.Ptr()-(TInt)ptr;
+	aDes.Set(ptr, aDes.Length()-n1);
+	return n1;
+	}
+
+TInt CDummyNifLog::DumpIcmp(TPtrC8& aDes, TInt aLength)
+	{
+
+	if (aLength < 2)
+		return 0;
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+
+	_LIT(string1,"	    Type = %d, Code = %d\n");
+	Printf(string1, *ptr, *(ptr+1));
+	HexDump(FOURTEEN_SPACE_MARGIN, FOURTEEN_SPACE_MARGIN, ptr, aLength);
+	return 0;
+	}
+
+TInt CDummyNifLog::DumpUdp(TPtrC8& aDes, TUint32 /* aSrcA */, TUint32 /*aDstA */, TInt aLength)
+	{
+	if (aLength < 6)
+		return 0;
+
+	TUint8* ptr = (TUint8*)aDes.Ptr();
+	TUint srcp = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+	ptr +=2;
+	TUint dstp = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+	ptr +=2;
+	TUint16 len = ByteOrder::Swap16((TUint16)(*ptr | (*(ptr+1)<<8)));
+	ptr += 2;
+
+	ptr += 2;						// skip checksum
+	Printf(KUDPLengthPortString, len, srcp, dstp);
+	//Printf(KPortString, srcp, dstp);
+
+	//for testing only
+	return 0;
+	}
+
+void CDummyNifLog::Dump(RMBufChain& aPacket, TInt aChannel)
+	{
+
+	RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPacket);
+	TUint prot = TPppAddr::Cast(info->iDstAddr).GetProtocol();
+	
+	TBuf8<1536> buf;
+	buf.SetMax();
+	aPacket.CopyOut(buf, aPacket.First()->Length());
+	
+	if (aChannel==KDummyPPPSendChannel)
+		{
+		_LIT(string1,"Dummy PPP Send %d bytes");
+		Printf(string1, info->iLength);
+		}
+	else if (aChannel==KDummyPPPRecvChannel)
+		{
+		_LIT(string2,"Dummy PPP Recv %d bytes");
+		Printf(string2, info->iLength);
+		}
+	else
+		{
+		_LIT(string3,"Dummy PPP %d bytes");
+		Printf(string3, info->iLength);
+		}
+
+	TPtrC8 des(buf);
+	switch (prot)
+		{
+	case KPppIdLcp:
+		DumpLcp(des);
+		break;
+	case KPppIdPap:
+		DumpPap(des);
+		break;
+	case KPppIdChap:
+		DumpChap(des);
+		break;
+	case KPppIdIpcp:
+		DumpIpcp(des);
+		break;
+	case KPppIdIp6cp:
+		DumpIp6cp(des);
+		break;
+	case KPppIdIp:
+		DumpIp(des);
+		break;
+	case KPppIdIp6:
+		DumpIp6(des);
+		break;
+	case KPppIdVjCompTcp:
+		DumpVjCompTcp(des);
+		break;
+	case KPppIdVjUncompTcp:
+		DumpVjUncompTcp(des);
+		break;
+
+	default:
+		Printf(_L("Raw Bytes:"));
+		HexDump(NULL,_S(""),des.Ptr(), des.Length(),8);
+		Write(KEndOfLine);
+	}
+}
+
+void CDummyNifLog::DumpChapType(const TUint8* aPtr)
+	{
+
+	switch (*aPtr)
+		{
+	case 5:
+			{
+			_LIT(string1,"	    Algorithm=MD5\n");
+			Write(string1);
+			}
+		break;
+	case 0x80:
+			{
+			_LIT(string2,"	    Algorithm=Microsoft\n");
+			Write(string2);
+			}
+		break;
+	default:
+			{
+			_LIT(string3,"	    Algorithm=Unknown\n");
+			Write(string3);
+			}
+		break;
+		}
+	}
+
+const TText* CDummyNifLog::CallbackOpToText(TUint aValue)
+	{
+
+	// CB Codes
+	switch (aValue)
+		{
+	case 0:
+		return _S("Location preset");
+	case 1:
+		return _S("Dialing string");
+	case 2:
+		return _S("Location identifier");
+	case 3:
+		return _S("E.164 number");
+	case 4:
+		return _S("Distinguished name");
+	case 5:
+		return _S("E.165 number");
+	case 6:
+		return _S("MS CBCP");
+	default:
+		return _S("Unknown operation");
+		}
+	}
+
+const TText* CDummyNifLog::LcpOptToText(TUint aValue)
+	{
+
+	// LCP Options
+	switch (aValue)
+		{
+	case KPppLcpOptMaxRecvUnit:
+		return _S("Max receive size");
+	case KPppLcpOptEscapeCharMap:
+		return _S("Escape char map");
+	case KPppLcpOptAuthenticationProtocol:
+		return _S("Authentication protocol");
+	case KPppLcpOptQualityProtocol:
+		return _S("Quality protocol");
+	case KPppLcpOptMagicNumber:
+		return _S("Magic number");
+	case KPppLcpOptProtocolCompress:
+		return _S("Protocol field compression");
+	case KPppLcpOptAddrCtrlCompress:
+		return _S("Addr & Ctrl field compression");
+	case KPppLcpOptFcsType:
+		return _S("Fcs Type");
+	case KPppLcpOptPadding:
+		return _S("Padding");
+	case KPppLcpOptCallback:
+		return _S("Callback protocol");
+	case KPppLcpOptCompoundFrames:
+		return _S("Compound frames");
+	case KPppLcpOptMRRU:
+ 		return _S("MRRU");
+ 	case KPppLcpOptMultiLinkEndPointDescriminator:
+ 		return _S("Multi-link End-Point Descriminator");
+	default:
+		return _S("Unknown");
+		}
+	}
+
+const TText* CDummyNifLog::ProtocolToText(TUint aValue)
+	{
+
+	// Protocols
+	switch (aValue)
+		{
+	case KPppIdLcp:
+		return _S("LCP");
+	case KPppIdPap:
+		return _S("PAP");
+	case KPppIdChap:
+		return _S("CHAP");
+	case KPppIdMsCbcp:
+		return _S("MSCBCP");
+	case KPppIdIpcp:
+		return _S("IPCP");
+	case KPppIdIp6cp:
+		return _S("IP6CP");
+	case KPppIdIp:
+		return _S("IP");
+	case KPppIdIp6:
+		return _S("IPv6");
+	case KPppIdVjCompTcp:
+		return _S("VJ Comp tcp");
+	case KPppIdVjUncompTcp:
+		return _S("VJ Uncomp tcp");
+	case KPppIdCcp:
+		return _S("CCP");
+	case KPppIdCompressed:
+		return _S("PPP Compressed");
+	default:
+		return _S("Unknown");
+		}
+	}
+
+void CDummyNifLog::LogUserData(RMBufChain& aPacket, TInt aChannel)
+//
+// Stores the current total of data transferred
+//
+{
+	TBuf8<1536> buf;
+	buf.SetMax();
+	aPacket.CopyOut(buf, aPacket.First()->Length());
+	
+	TPtrC8 des(buf);
+
+	TUint8* ptr = (TUint8*)des.Ptr();
+	ptr+=2;
+	TUint16 len = ByteOrder::Swap16((TUint16)(*ptr | *(ptr+1)<<8));
+
+	if (aChannel==KDummyPPPSendChannel)
+	{
+		iSentData+=len;
+	}
+	else
+	{
+		if (aChannel==KDummyPPPRecvChannel)
+			iRecvdData+=len;
+	}
+
+}
+
+void CDummyNifLog::DumpBytes(const TText* aMargin, const TUint8* aPtr, TInt aLen)
+	{
+	HexDump(NULL,aMargin,aPtr,aLen,8);
+	}