diff -r 000000000000 -r af10295192d8 linklayerprotocols/pppnif/SPPP/PPPCCP.CPP --- /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 +#include "PPPCCP.H" +#include "PPP_VER.H" +#include "CCPINI.H" +#include +#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 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 ; iCount() ; ++i) + CNifFactory::ControlledDelete((*con)[i]); + iCompressorCon = NULL; + } + + + if(iDeCompressorCon) + { + con = iDeCompressorCon; + for(i=0 ; iCount() ; ++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 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& 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 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 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 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; + } +}