--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linklayerprotocols/pppnif/SPPP/PPPCCP.CPP Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,1016 @@
+// 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 "PPPLOG.H"
+#include <in_sock.h>
+#include "PPPCCP.H"
+#include "PPP_VER.H"
+#include "CCPINI.H"
+#include <commsdattypeinfov1_1.h>
+#include "PPPConfig.h"
+
+#if defined(__VC32__) && (_MSC_VER < 1300)
+ #define PMF(x) x
+#else
+ #define PMF(x) &x
+#endif
+
+//
+// PPP for ESock
+//
+// warning C4355: 'this' : used in base member initializer list
+#pragma warning (disable:4355)
+CPppCcp::CPppCcp(CPppLcp* aLcp)
+ : CBase(), MPppFsm(aLcp, EPppPhaseNetwork, KPppIdCcp),
+ iRecvr(this, PMF(CPppCcp::Recv), PMF(CPppCcp::SendFlowOn), aLcp, EPppPhaseNetwork, KPppIdCcp,
+ PMF(MPppRecvr::FrameError), PMF(MPppRecvr::KillProtocol))
+ {
+ __DECLARE_FSM_NAME(_S("CCP"));
+ }
+#pragma warning (default:4355)
+
+void CPppCcp::RemoveRegistration()
+ {
+ Deregister();
+ iRecvr.Deregister();
+ }
+
+CPppCcp::~CPppCcp()
+ {
+ CObjectCon* con;
+ TInt i;
+
+ Deregister();
+ iRecvr.Deregister();
+ delete iSendCallBack;
+ delete iIniFilePtr;
+
+ //
+ // OK Spin around removing all the Compressor Config information
+ //
+ CPppCompConfig* CompressorData;
+
+ TSglQueIter<CPppCompConfig> Iterator(iCompressorConfig);
+ Iterator.SetToFirst();
+
+ CompressorData = Iterator++;
+ while(CompressorData)
+ {
+ delete CompressorData;
+ CompressorData = Iterator++;
+ }
+
+
+ if (iCompressor)
+ {
+ iPppLcp->PppNewCompressor(NULL);
+ iCompressor->Close();
+ iCompressor = NULL;
+ }
+
+ if (iDeCompressor)
+ {
+ iPppLcp->PppNewDeCompressor(NULL);
+ iDeCompressor->Close();
+ iDeCompressor = NULL;
+ }
+
+ //
+ // Delete all the Containers
+ //
+ if(iCompressorCon)
+ {
+ con = iCompressorCon;
+
+ for(i=0 ; i<con->Count() ; ++i)
+ CNifFactory::ControlledDelete((*con)[i]);
+ iCompressorCon = NULL;
+ }
+
+
+ if(iDeCompressorCon)
+ {
+ con = iDeCompressorCon;
+ for(i=0 ; i<con->Count() ; ++i)
+ CNifFactory::ControlledDelete((*con)[i]);
+ iDeCompressorCon = NULL;
+ }
+
+ iSendQ.Free();
+
+ if (!iRequestWorkList.IsEmpty())
+ {
+ iRequestWorkList.Free();
+ }
+
+ }
+
+CPppCcp* CPppCcp::NewL(CPppLcp* aLcp)
+ {
+ CPppCcp* ccp = new (ELeave) CPppCcp(aLcp);
+ CleanupStack::PushL(ccp);
+ ccp->ConstructL();
+ CleanupStack::Pop();
+ return ccp;
+ }
+
+void CPppCcp::FsmTerminationPhaseComplete()
+ {
+ }
+
+
+void CPppCcp::RemoteCompressorHasReset()
+//
+//
+//
+ {
+ //
+ // Increment the Reset Id
+ //
+ iResetId++;
+ iResetId %= 256;
+ }
+
+void CPppCcp::ConstructL()
+// Construct the Link Protocol Object
+// This method now reads the number of compressor and its information
+// incrementally. Replaces ini file code.
+ {
+ Register();
+ iRecvr.Register();
+
+ TCallBack scb(SendCallBack, this);
+ iSendCallBack = new(ELeave) CAsyncCallBack(scb, KCcpSendPriority);
+
+ // Initialise CCP Finite State Machine
+ FsmConstructL();
+
+ // Initialise a queue
+ iCompressorConfig.SetOffset(_FOFF(CPppCompConfig,link));
+ iIniFilePtr = CPppIniData::NewL();
+
+ // Initialise CObject containers
+ iCompressorCon = (iPppLcp->ContainerForDlls())->CreateL();
+ iDeCompressorCon = (iPppLcp->ContainerForDlls())->CreateL();
+
+ //
+ // Be warned this code was written expecting the ini file only to be used
+ // for compressor configuration, it's not generic
+ //
+ CPppCompConfig* CompressorData;
+ TBool Loop;
+ TUint numberOfTurns=0;
+ do
+ {
+ Loop = FALSE;
+ numberOfTurns++;
+ CompressorData = CPppCompConfig::NewL();
+ //coverity[leave_without_push]
+ //Function ReadCompressorInfo is not leaveable, hence no need to push the object CompressorData into cleanup stack
+ if (iIniFilePtr->ReadCompressorInfo(CompressorData, numberOfTurns))
+ {
+ //
+ // Check there is a dll of this name
+ //
+ //coverity[leave_without_push]
+ //Function ReadCompressorInfo is not leaveable, hence no need to push the object CompressorData into cleanup stack
+ if (iPppLcp->DoesDllExist(CompressorData->Name()))
+ {
+ iCompressorConfig.AddLast(*CompressorData);
+ }
+ else
+ {
+ delete CompressorData;
+ }
+
+ Loop = TRUE;
+ }
+ }
+ while (Loop);
+
+ delete CompressorData;
+
+ FsmOpen();
+ }
+
+
+void CPppCcp::SendResetRequestL()
+//
+// Create and Send a Reset Request
+//
+ {
+ const TUint pktLen = 4;
+ RMBufPacket pkt;
+ RMBufPktInfo* info = NULL;
+ pkt.AllocL(pktLen);
+ CleanupStack::PushL(pkt);
+ info = pkt.NewInfoL();
+ CleanupStack::Pop();
+ info->iLength = pktLen;
+
+ // Construct packet header
+ TUint8* ptr = pkt.First()->Ptr();
+ *ptr++ = KPppCcpResetReq;
+ *ptr++ = iResetId;
+ BigEndian::Put16(ptr, (TUint16)pktLen);
+
+ // Send it
+ pkt.Pack();
+ SendFrame(pkt);
+ }
+
+void CPppCcp::Info(TNifIfInfo& aInfo) const
+//
+//
+//
+ {
+ FillInInfo(aInfo);
+ }
+
+void CPppCcp::FillInInfo(TNifIfInfo& aInfo)
+//
+//
+//
+ {
+
+ aInfo.iVersion = TVersion(KPPPMajorVersionNumber, KPPPMinorVersionNumber, KPPPBuildVersionNumber);
+ aInfo.iFlags = KNifIfIsBase | KNifIfUsesNotify | KNifIfCreatedByLink;
+ _LIT(KCcp, "ccp");
+ aInfo.iName = KCcp;
+ aInfo.iProtocolSupported=KPppIdEsock;
+ }
+
+TInt CPppCcp::State()
+//
+//
+//
+ {
+
+ if (FsmIsThisLayerOpen())
+ return (iUpperFlowOn) ? EIfUp : EIfBusy;
+ else
+ return EIfDown;
+ }
+
+void CPppCcp::SendFlowOn()
+ {
+ LOG( iPppLcp->iLogger->Printf(_L("CCP Flow On iUpperFlowOn=%d\n"), iUpperFlowOn); )
+
+ iLowerFlowOn = ETrue;
+ if (!iSendQ.IsEmpty())
+ iSendCallBack->CallBack();
+ }
+
+TInt CPppCcp::SendCallBack(TAny* aCProtocol)
+ {
+ ((CPppCcp*)aCProtocol)->DoSend();
+ return 0;
+ }
+
+void CPppCcp::DoSend()
+ {
+ if (FsmIsThisLayerOpen())
+ {
+ RMBufPacket pkt;
+ while (iSendQ.Remove(pkt))
+ {
+ RMBufPktInfo*info = pkt.Unpack();
+ TPppAddr addr;
+ info->iDstAddr = addr;
+ pkt.Pack();
+ if (iRecvr.SendFrame(pkt)<=0)
+ {
+ LOG( iPppLcp->iLogger->Printf(_L("CCP Flow Off\n")); )
+ iLowerFlowOn = EFalse;
+ break;
+ }
+ }
+ if (iLowerFlowOn&&!iUpperFlowOn)
+ iUpperFlowOn = ETrue;
+ }
+ }
+
+TInt CPppCcp::Send(RMBufChain& aPacket, TAny*)
+//
+//
+//
+ {
+ iSendQ.Append(aPacket);
+ iSendCallBack->CallBack();
+ if (!FsmIsThisLayerOpen() || !iLowerFlowOn)
+ iUpperFlowOn = EFalse;
+ return iUpperFlowOn;
+ }
+
+//
+// NCP Upcalls from FSM
+//
+
+TInt CPppCcp::FsmLayerStarted()
+//
+// Open the layer below. Nothing to do here as this won't be worth running without an NCP!
+//
+ {
+ return KErrNone;
+ }
+
+void CPppCcp::FsmLayerFinished(TInt /*aReason*/)
+//
+// Close the layer below. CCP should not close the link if it terminates, so there is nothing
+// to do here.
+//
+ {}
+
+void CPppCcp::FsmLayerUp()
+//
+// Hmm the link is back up.
+//
+ {
+ SendFlowOn();
+ return;
+ }
+
+void CPppCcp::FsmLayerDown(TInt aReason)
+//
+// Hmmm the link has gone down
+//
+ {
+
+ if(aReason==KErrNone)
+ return;
+ //
+ // Make a note of which compressor we were using
+ //
+ }
+
+void CPppCcp::FsmFillinConfigRequestL(RPppOptionList& aRequestList)
+//
+// Fillin Config Request to be sent
+//
+ {
+ if ((iSoftwareCompressionOn = iPppLcp->GetLcpConfig()->GetEnableSwComp()) == TRUE)
+ {
+ TSglQueIter<CPppCompConfig> Iterator(iCompressorConfig);
+ Iterator.SetToFirst();
+
+ //
+ // This is the initial Config Request.
+ // We then just want to fill in the 1:st option from the ini-file
+ //
+
+ AddToRequestListL(aRequestList,Iterator);
+ //
+ // Add _all_ supported to a temporary working list
+ //
+ if (!iRequestWorkList.IsEmpty())
+ iRequestWorkList.Free();
+ Iterator.SetToFirst();
+ do
+ {
+ AddToRequestListL(iRequestWorkList,Iterator);
+ }
+ while(Iterator);
+ }
+ }
+
+void CPppCcp::AddToRequestListL(RPppOptionList& aRequestList, TSglQueIter<CPppCompConfig>& aIterator)
+ {
+
+ CPppCompConfig* Data = aIterator++;
+ if (Data)
+ {
+ //
+ // Add this option to the list
+ //
+ if (Data->OptionsLength())
+ {
+ TPtrC8 Temp = Data->Options();
+ aRequestList.CreateAndAddL(Data->ID(), Temp);
+ }
+ else
+ {
+ //
+ // No options
+ //
+ aRequestList.CreateAndAddL(Data->ID());
+ }
+ }
+ }
+
+void CPppCcp::FsmCheckConfigRequest(RPppOptionList& aRequestList, RPppOptionList& aAckList, RPppOptionList& aNakList, RPppOptionList& aRejList)
+//
+// Check options in a recvd config request
+//
+ {
+
+ // Check that software compression is turned on.
+ // This may not occur as LCP also reads the database
+ // and sends a Protocol Reject for CCP in this case
+ if(!iSoftwareCompressionOn)
+ {
+ // Reject all options
+ aRequestList.RemoveOptions(aRejList);
+ return;
+ }
+
+ RPppOption requestedOption;
+ CPppCompConfig* nakOption = NULL;
+ CPppCompConfig* supportedOption = NULL;
+ TSglQueIter<CPppCompConfig> supportedOptionsIter(iCompressorConfig);
+
+ // This loop control variable ensures that after we have successfully matched
+ // an algorithm we don't keep searching through supportedOptionsIter
+ TBool optionMatched = EFalse;
+
+ // If we have matched the option to an algorithm that we support, do we support the
+ // parameters of the algorithm in the request?
+ TBool paramsMatched = EFalse;
+
+ // Used as a ptr to the parameters of requestedOption during param match
+ TPtrC8 requestedParams;
+
+ // An acknowledgement should only contain one algorithm - the one that we want to accept.
+ // Whilst processing, add only the first algorithm that we can acknowledge to aAckList.
+ // Successive algorithms that are found to be acceptable are added to the reject list.
+ TBool ackListFull = EFalse;
+
+ //
+ // Process all options in the config-request
+ //
+ while (aRequestList.Remove(requestedOption))
+ {
+
+ // Search supported compressor data for a match
+ supportedOptionsIter.SetToFirst();
+ optionMatched = EFalse;
+ nakOption = NULL;
+
+ do
+ {
+ supportedOption = supportedOptionsIter++;
+ if (!supportedOption)
+ continue;
+
+ // Is this algorithm supported?
+ if (supportedOption->ID() == requestedOption.OptType())
+ {
+ // Found an algorithm match - now match the parameters.
+ paramsMatched = EFalse;
+ requestedParams.Set(requestedOption.ValuePtr(), requestedOption.ValueLength());
+
+ if (supportedOption->Options() == requestedParams)
+ paramsMatched = ETrue;
+
+ // Do the algorithm parameters match the ones that we use?
+ if(paramsMatched)
+ {
+ // The parameters matched so add this option to the ack list,
+ // or if we already have an option that we want to Ack, reject this option
+ if (!ackListFull)
+ {
+ aAckList.Append(requestedOption);
+ ackListFull = ETrue;
+ }
+ else
+ aRejList.Append(requestedOption);
+
+ // return program flow to the outer while loop
+ // because we don't need to continue searching
+ optionMatched = ETrue;
+ }
+ else
+ {
+ // This algorithm is a potential nak, so keep a pointer to it.
+ // It cannot be added to the nak list yet, because
+ // there may be a better match later on in the iterator.
+ // However, we only want to keep a pointer to the first potential
+ // NAK that we find - to preserve the priority implied by the order
+ // of compressors in the ini file.
+ if (nakOption==NULL)
+ nakOption = supportedOption;
+ }
+ }
+
+ } while (supportedOptionsIter && !optionMatched);
+
+ // Finished searching through supported compressor config
+ if (!optionMatched)
+ {
+ // Decide whether to Nak or Reject
+ if (nakOption==NULL)
+ {
+ // Reject this algorithm as it is not recognised
+ aRejList.Append(requestedOption);
+ }
+ else
+ {
+ // Nak this algorithm as it is recognised, but the parameters are not supported
+ // Modify requestedOption to contain the params from nakOption and add requestedOption to aNakList
+ TRAPD(ret, requestedOption.SetL(requestedOption.OptType(), (nakOption->Options()).Ptr(), nakOption->OptionsLength()));
+ if (ret == KErrNone)
+ {
+ aNakList.Append(requestedOption);
+ }
+ else
+ {
+ // Could not modify the RPppOption - probably not enough memory
+ // Rejecting this option may not be appropriate, but it is probably better than sending a Nak with
+ // the same parameters as the received request - this would result in an endless loop
+ LOG( iPppLcp->iLogger->Printf(_L("Could not construct the Config-Nak (error %d) - Rejecting this option instead"), ret); )
+ aRejList.Append(requestedOption);
+ }
+ }
+ }
+
+ }
+ // Finished processing the options in the request
+
+ return;
+ }
+
+void CPppCcp::FrameError()
+
+ {
+ return;
+ }
+
+
+void CPppCcp::KillProtocol()
+ {
+ /*
+ * OK now this protocol has been rejected
+ * so throw away all frames received by it.
+ */
+ iDead = ETrue;
+ SetState(EPppFsmClosed);
+ return;
+ }
+
+
+void CPppCcp::FsmApplyConfigRequest(RPppOptionList& aRequestList)
+//
+// Apply options in a recvd config request (that was ACK'd)
+//
+ {
+ TMBufPktQIter iter(aRequestList);
+ TSglQueIter<CPppCompConfig> Iterator(iCompressorConfig);
+ CPppCompConfig* Data = 0;
+ // Used as a ptr to the parameters of requestedOption during param match
+ TPtrC8 requestedParams;
+ RPppOption opt;
+ TBool compressorFound = false ;
+
+ while (opt = iter++, !opt.IsEmpty())
+ {
+ Iterator.SetToFirst();
+
+ //
+ // Is the option type one we support
+ //
+ do
+ {
+ Data = Iterator++;
+ if (Data)
+ {
+ //
+ // Add this option to the list
+ //
+ if ( Data->ID()== opt.OptType() )
+ {
+ // Can we match the parameters
+ requestedParams.Set(opt.ValuePtr(), opt.ValueLength());
+ if (Data->Options() == requestedParams)
+ {
+ compressorFound = true ;
+#ifdef _DEBUG
+ LOG(iPppLcp->iLogger->Printf(_L("Attempting to load Compressor DLL\n"));)
+ switch (opt.OptType())
+ {
+ case 0x11:
+ LOG(iPppLcp->iLogger->Printf(_L("STAC LZS compression requested\n"));)
+ LOG(iPppLcp->iLogger->Printf(_L("STAC LZS parameters = 0x%04x 0x%02x\n"),
+ ((requestedParams[0]<<8) | requestedParams[1]), requestedParams[2]);)
+ break ;
+
+ case 0x12:
+ LOG(iPppLcp->iLogger->Printf(_L("M$ PPC/PPE compression requested\n"));)
+ LOG(iPppLcp->iLogger->Printf(_L("M$ PPC/PPE parameters = 0x%02x 0x%02x 0x%02x 0x%02xr\n"),
+ requestedParams[0], requestedParams[1],
+ requestedParams[2], requestedParams[3]);)
+ break ;
+
+ default:
+ LOG(iPppLcp->iLogger->Printf(_L("Unsupported compression algorithm!\n"));)
+ break ;
+ }
+#endif // _DEBUG
+
+
+ //
+ // Now we load the compressor based on the file name
+ //
+
+ if (iCompressor != NULL)
+ {
+ iPppLcp->PppNewCompressor(NULL);
+ iCompressor->Close();
+ iCompressor = NULL;
+ }
+
+ TRAPD( Ret, iCompressor = LoadCompressorL(*Data, iPppLcp->MaxTransferSize() ));
+
+ if (Ret == KErrNone)
+ {
+ iPppLcp->PppNewCompressor(iCompressor);
+ LOG(iPppLcp->iLogger->Write(_L("Compressor DLL loaded OK\n"));)
+ }
+ else
+ {
+ //
+ // Can't load the Dll, only reason I can think off
+ // is not enough memory, so time to close down.
+ //
+ LOG(iPppLcp->iLogger->Write(_L("Couldn't load Compressor DLL\n"));)
+ iPppLcp->Stop(Ret, MNifIfNotify::EDisconnect);
+ }
+ }
+ }
+ }
+ if (compressorFound)
+ break;
+ }
+ while(Iterator);
+ }
+ if (!compressorFound)
+ {
+ LOG(iPppLcp->iLogger->Write(_L("Couldn't match requested compression settings in ppp.ini\n"));)
+ }
+ return;
+ }
+
+void CPppCcp::FsmRecvConfigAck(RPppOptionList& aReplyList)
+//
+// Recvd a Config Ack - apply the options
+//
+ {
+ TSglQueIter<CPppCompConfig> Iterator(iCompressorConfig);
+ CPppCompConfig* Data = 0;
+
+ TMBufPktQIter iter(aReplyList);
+ RPppOption opt;
+
+ while (opt = iter++, !opt.IsEmpty())
+ {
+ Iterator.SetToFirst();
+
+ //
+ // Is the option type one we support
+ //
+ do
+ {
+ Data = Iterator++;
+ if (Data)
+ {
+ //
+ // Add this option to the list
+ //
+ if ( Data->ID()== opt.OptType() )
+ {
+ LOG(iPppLcp->iLogger->Printf(_L("New DeCompressor\n"));)
+
+ //
+ // Dynamically load the DeCompressor
+ //
+ if (iDeCompressor != NULL)
+ {
+ iPppLcp->PppNewDeCompressor(NULL);
+ iDeCompressor->Close();
+ iDeCompressor = NULL;
+ }
+
+ TRAPD( Ret, iDeCompressor = LoadDeCompressorL(*Data,
+ iPppLcp->MaxTransferSize()));
+
+ if (Ret == KErrNone)
+ {
+ iPppLcp->PppNewDeCompressor(iDeCompressor);
+ }
+ else
+ {
+ //
+ // Can't load the Dll, only reason I can think off
+ // is not enough memory, so time to close down.
+ //
+ iPppLcp->Stop(Ret, MNifIfNotify::EDisconnect);
+ }
+
+ break;
+ }
+ }
+ }
+ while (Iterator);
+ }
+
+ LOG(iPppLcp->iLogger->Write(_L("(Outgoing Compression On)\n"));)
+
+ return;
+ }
+
+void CPppCcp::FsmRecvConfigNak(RPppOptionList& /*aReplyList*/, RPppOptionList& aReqList)
+//
+// Recvd a Config Nak - The associated original request is in aReqList
+//
+ {
+
+ TMBufPktQIter iterReq(aReqList);
+ RPppOption optReq;
+ optReq = iterReq++;
+
+ TMBufPktQIter iterWork(iRequestWorkList);
+ RPppOption optWork;
+
+ //
+ // Find First option of the requested type and delete it from the iRequestWorkList
+ //
+ while (optWork = iterWork.Current(), !optWork.IsEmpty())
+ {
+ if(optWork.OptType()==optReq.OptType())
+ {
+ optWork.Init(); //??
+ iterWork.Remove(optWork);
+ optWork.Free();
+ break;
+ }
+ iterWork++;
+ }
+
+ //
+ // Add next option of the requested type, if it doesn't exist add a new optiontype
+ //
+ iterWork.SetToFirst();
+
+ TBool noOptions = EFalse;
+ while (optWork = iterWork++, !optWork.IsEmpty())
+ {
+ if(optWork.OptType()==optReq.OptType())
+ {
+ if (!aReqList.IsEmpty())
+ aReqList.Free();
+ //PG 09/11/2001
+ //Following needs to be changed to use ReplaceOptions so as not to create new memory
+ //The whole method needs to be rewritten
+ TRAPD(err,aReqList.CreateAndAddL(optWork.OptType(), optWork.ValuePtr(), optWork.ValueLength()));
+ __ASSERT_DEBUG(err == KErrNone,PppPanic(EPppPanic_PPPNoMemory));
+ if(err)
+ return;
+ noOptions = ETrue;
+ break;
+ }
+ }
+ //
+ // No more options where found try to add next option in turn
+ //
+ if(noOptions == EFalse)
+ {
+ //
+ // Clear the List...
+ //
+ if (!aReqList.IsEmpty())
+ aReqList.Free();
+
+ //
+ // ...and put next option in the list that we support(taken from
+ // the options left in the iRequestWorkList)
+ //
+ iterWork.SetToFirst();
+
+ if(optWork = iterWork++, !optWork.IsEmpty())
+ {
+ TRAPD(err,aReqList.CreateAndAddL(optWork.OptType(), optWork.ValuePtr(), optWork.ValueLength()));
+ __ASSERT_DEBUG(err == KErrNone,PppPanic(EPppPanic_PPPNoMemory));
+ err = err; //remove remark in UREL
+ }
+ }
+ }
+
+void CPppCcp::FsmRecvConfigReject(RPppOptionList& aReplyList, RPppOptionList& aReqList)
+//
+// Recvd a Config Reject - The associated original request is in aReqList
+//
+ {
+//
+ // Remove the unsupported compressor(s) from the Temporary iRequestWorkList
+ //
+ TMBufPktQIter iter(aReplyList);
+ RPppOption opt;
+ while (opt = iter++, !opt.IsEmpty())
+ {
+ //
+ // Remove _all_ unsupported options
+ //
+ TInt error = KErrNone;
+ while(error == KErrNone)
+ {
+ error = iRequestWorkList.RemoveOption(opt);
+ }
+ }
+
+ //
+ // Clear the Request List (aReqList)...
+ //
+ if (!aReqList.IsEmpty())
+ aReqList.Free();
+
+ //
+ // ...and put next option in the list that we support(taken from
+ // the options left in the iRequestWorkList)
+ //
+ TMBufPktQIter iterWork(iRequestWorkList);
+ RPppOption optWork;
+
+ if(optWork = iterWork++, !optWork.IsEmpty())
+ {
+ TRAPD(err,aReqList.CreateAndAddL(optWork.OptType(), optWork.ValuePtr(), optWork.ValueLength()));
+ __ASSERT_DEBUG(err==KErrNone,PppPanic(EPppPanic_PPPNoMemory));
+ err = err; //Remove remark in UREL
+ }
+ }
+
+void CPppCcp::SendResetAckL(TUint8 aId)
+ {
+ const TUint pktLen = 4;
+ RMBufPacket pkt;
+ RMBufPktInfo* info = NULL;
+ pkt.AllocL(pktLen);
+ CleanupStack::PushL(pkt);
+ info = pkt.NewInfoL();
+ CleanupStack::Pop();
+ info->iLength = pktLen;
+
+ // Construct packet header
+ TUint8* ptr = pkt.First()->Ptr();
+ *ptr++ = KPppCcpResetAck;
+ *ptr++ = aId;
+ BigEndian::Put16(ptr, (TUint16)pktLen);
+
+ // Send it
+ pkt.Pack();
+ SendFrame(pkt);
+
+ //
+ // Not all compressors use the Ack, so I have a generic function
+ // to complete the Reset
+ //
+ RemoteCompressorHasReset();
+ }
+
+TBool CPppCcp::FsmRecvUnknownCode(TUint8 aCode, TUint8 aId, TInt /*aLength*/, RMBufChain& aPacket)
+//
+// Recvd an unrecognised opcode - No we have two opcodes that no-one else is
+// interested in
+//
+ {
+ TBool RetCode;
+
+ switch (aCode)
+ {
+ case KPppCcpResetReq:
+ {
+ //
+ // Tell the compressor about this, and send an ACK to the other end
+ //
+ //PG none of the currrently existing compressors use the packet passed as parameter
+ // Following line caused a memory leak when the packet len is 0
+ // aPacket.TrimStart(4);
+
+ //
+ // Some compressors require a Reset ACK some don't
+ //
+ if (iCompressor)
+ {
+// if (iCompressor->ResetCompressor(aLength-4, aPacket) == TRUE)
+ if (iCompressor->ResetCompressor(0, aPacket) == TRUE)
+ {
+ TRAPD(Ret,SendResetAckL(aId));
+ if (KErrNone!=Ret)
+ {
+ LOG( iPppLcp->iLogger->Printf(_L("ERROR:\tSendResetAck Failed\n")); )
+ }
+ }
+ }
+
+ RetCode = ETrue;
+ break;
+ }
+ case KPppCcpResetAck:
+ {
+// aPacket.TrimStart(4);
+ if (aId == iResetId)
+ {
+// iDeCompressor->ResetDecompressor(aLength-4, aPacket);
+ iDeCompressor->ResetDecompressor(0, aPacket);
+ RetCode = ETrue;
+ }
+ else
+ {
+ RetCode = EFalse;
+ }
+ break;
+ }
+ default:
+ {
+ RetCode = EFalse;
+ break;
+ }
+ }
+ return RetCode;
+ }
+
+//
+
+
+void CPppCcp::Recv(RMBufChain& aPacket)
+ {
+ aPacket.Free();
+ return;
+ }
+
+CPppDeCompressor* CPppCcp::LoadDeCompressorL( CPppCompConfig& aPPPCompConfig,
+ TInt aMaxFrameLength)
+ {
+ CPppCompFactory* Factory=NULL;
+ CPppDeCompressor* DeCompressor;
+
+#ifdef _UNICODE
+ Factory = (CPppCompFactory*)FindPppFactoryL(aPPPCompConfig.Name(), TUid::Uid(KUidUnicodePppCompressionModule), *iDeCompressorCon);
+#else
+ Factory = (CPppCompFactory*)FindPppFactoryL(aPPPCompConfig.Name(), TUid::Uid(KUidPppCompressionModule), *iDeCompressorCon);
+#endif
+
+ CleanupStack::PushL(TCleanupItem(CNifFactory::Cleanup, Factory));
+
+ if(aPPPCompConfig.OptionsLength())
+ DeCompressor = Factory->NewPppDeCompressorL(this, aMaxFrameLength,&aPPPCompConfig.Options()[0]);
+ else
+ DeCompressor = Factory->NewPppDeCompressorL(this, aMaxFrameLength);
+
+ CleanupStack::PopAndDestroy(); // Close extra reference on Factory
+
+ return DeCompressor;
+ }
+
+CPppCompressor* CPppCcp::LoadCompressorL( CPppCompConfig& aPPPCompConfig,
+ TInt aMaxFrameLength)
+ {
+ CPppCompFactory* Factory=NULL;
+ CPppCompressor* Compressor;
+
+#ifdef _UNICODE
+ Factory = (CPppCompFactory*)FindPppFactoryL(aPPPCompConfig.Name(), TUid::Uid(KUidUnicodePppCompressionModule), *iCompressorCon);
+#else
+Factory = (CPppCompFactory*)FindPppFactoryL(aPPPCompConfig.Name(), TUid::Uid(KUidPppCompressionModule), *iCompressorCon);
+#endif
+
+ CleanupStack::PushL(TCleanupItem(CNifFactory::Cleanup, Factory));
+
+ if(aPPPCompConfig.OptionsLength())
+ Compressor = Factory->NewPppCompressorL(this, aMaxFrameLength,&aPPPCompConfig.Options()[0]);
+ else
+ Compressor = Factory->NewPppCompressorL(this, aMaxFrameLength);
+
+ CleanupStack::PopAndDestroy(); // Close extra reference on Factory
+
+ return Compressor;
+ }
+
+void CPppCcp::ReConfigLink()
+// Called from compressor/decompressor to force send of Config Request which
+// "downs" CCP. CCP then comes "up" again when the server replies with Config Ack.
+// Has been tested using predictor.
+// Currently only required by Predictor decompressor - RFC 1978
+ {
+ FsmOpen();
+ }
+
+void CPppCcp::UnloadCompressor()
+{
+ if (iCompressor != NULL)
+ {
+ LOG( iPppLcp->iLogger->Printf(_L("Unloading PPP compressor\n")); )
+ iPppLcp->PppNewCompressor(NULL);
+ iCompressor->Close();
+ iCompressor = NULL;
+ }
+}