diff -r 6b1d113cdff3 -r 6638e7f4bd8f telephonyprotocols/pdplayer/src/PDPSCPR.cpp --- a/telephonyprotocols/pdplayer/src/PDPSCPR.cpp Mon May 03 13:37:20 2010 +0300 +++ b/telephonyprotocols/pdplayer/src/PDPSCPR.cpp Thu May 06 15:10:38 2010 +0100 @@ -1,595 +1,595 @@ -// Copyright (c) 2006-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: -// PDP SubConnection Provider implementation -// -// - -/** - @file - @internalComponent -*/ - - -#include "PDPSCPRStates.h" -#include "PDPDeftSCPR.h" -#include "PDPSCPR.h" -#include "PDPSCPRFactory.h" -#include -#include -#include -#include -#include - -#if defined __FLOG_ACTIVE || defined SYMBIAN_TRACE_ENABLE -#define KPDPSCprTag KESockSubConnectionTag -_LIT8(KPDPSCprSubTag, "pdpscpr"); -#endif - -using namespace Messages; -using namespace MeshMachine; -using namespace ESock; -using namespace NetStateMachine; -using namespace Factories; - -//We reserve space for two preallocated activities that may start concurrently on the SCPR -//node: destroy and data client stop. -static const TUint KDefaultMaxPreallocatedActivityCount = 2; -static const TUint KMaxPreallocatedActivitySize = sizeof(MeshMachine::CNodeRetryParallelActivity) + sizeof(MeshMachine::APreallocatedOriginators<4>); -static const TUint KPDPSCPRPreallocatedActivityBufferSize = KDefaultMaxPreallocatedActivityCount * KMaxPreallocatedActivitySize; - -//-========================================================= -// -// CPDPSubConnectionProvider Activities -// -//-========================================================= - -namespace PDPSCprProvisionActivity -{ -DECLARE_DEFINE_NODEACTIVITY(ECFActivityStoreProvision, provision, TCFDataClient::TProvisionConfig) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TStoreProvisionAndInitSelf, CoreNetStates::TAwaitingProvision, MeshMachine::TNoTag) -NODEACTIVITY_END() -} - -namespace PDPSCprStartActivity -{ -DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, PDPScprStart, TCFServiceProvider::TStart, MeshMachine::CNodeRetryActivity::NewL) - FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStart, CoreNetStates::TNoTagOrBearerPresentBlockedByStop) - NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStartSelf, CoreNetStates::TAwaitingDataClientStarted, MeshMachine::TNoTag) - LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStarted) - LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreStates::TPanic) -NODEACTIVITY_END() -} - -namespace PDPSCprDataClientStartActivity -{ -typedef MeshMachine::TAcceptErrorState TAwaitingDataClientStartedOrError; - -DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStartDataClient, pdpDataClientStart, TCFDataClient::TStart, PDPSCprStates::CStartActivity::NewL) - FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, MeshMachine::TNoTag) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TCreateSecondaryOrMbmsPDPCtx, PDPSCprStates::TAwaitingPDPCtxCreated, PDPSCprStates::TNoTagOrError) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSetTFT, PDPSCprStates::TAwaitingTFTSet, PDPSCprStates::TNoTagOrError) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSetQoS, PDPSCprStates::TAwaitingQoSSet, PDPSCprStates::TNoTagOrError) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TActivatePDPContext, PDPSCprStates::TAwaitingPDPContextActive, PDPSCprStates::TNoTagOrError) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TOverrideProvisionAndStartDataClient, TAwaitingDataClientStartedOrError, MeshMachine::TNoTagOrErrorTag) - //This call below is somewhat obscure, but must be performed for the final activation of a pdp context. - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TGetNegotiatedQoS, PDPSCprStates::TAwaitingNegotiatedQoSRetrieved, PDPSCprStates::TNoTagOrError) - LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TRaiseParamsGrantedAndSendDataClientStarted) - - // Cleanup if error occurred - THROUGH_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing, CoreNetStates::TNoTagOrNoDataClientsToStop) - NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStopYourFlows, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag) - THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClientsToStop, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrProviderStopped) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TDestroyPDPContext, PDPSCprStates::TAwaitingPDPContextDestroyed, MeshMachine::TTag) - THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PRStates::TDestroyOrphanedDataClients, MeshMachine::TTag) - LAST_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, MeshMachine::TRaiseActivityError) -NODEACTIVITY_END() -} - -namespace PDPSCprStopActivity -{ -DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStopDataClient, Stop, TCFDataClient::TStop, MeshMachine::CNodeRetryActivity::NewL) - FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingDataClientStopOrCancel, MeshMachine::TNoTag) - THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, PRDataClientStopActivity::TNoTagOrProviderStoppedBlockedByStart) - - // stopping - NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStopYourFlows, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag) - THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrProviderStopped) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TDestroyPDPContext, PDPSCprStates::TAwaitingPDPContextDestroyed, MeshMachine::TTag) - THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PRStates::TDestroyOrphanedDataClients, MeshMachine::TTag) - LAST_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PDPSCprStates::TSendDataClientStopped) -NODEACTIVITY_END() -} - -namespace PDPSCprGoneDownActivity -{ -DECLARE_DEFINE_NODEACTIVITY(ECFActivityGoneDown, goneDown, TPDPMessages::TPDPFSMMessage) - FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingPDPContextGoneDown, MeshMachine::TActiveOrNoTag) - THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSendGoneDown, CoreNetStates::TNoTagOrNoDataClientsToStop) - NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStopYourFlows, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag) - - LAST_NODEACTIVITY_ENTRY(KActiveTag, CoreNetStates::TCancelDataClientStart) //MZTODO: This triple should wait for TError sent as a response to TCancel - LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClientsToStop, MeshMachine::TClearError) -NODEACTIVITY_END() -} - -namespace PDPSCprSetParameters -{ -#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW -DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, paramRequest, TCFScpr::TSetParamsRequest) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TStoreAndRespondWithCurrentParams, PRStates::TAwaitingParamRequest, MeshMachine::TNoTag) -#else -DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, paramRequest, TCFScpr::TParamsRequest) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TStoreParamsAndRespond, SCprStates::TAwaitingParamRequest, MeshMachine::TNoTag) -#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW -NODEACTIVITY_END() -} - -namespace PDPSCprApply -{ -DECLARE_DEFINE_NODEACTIVITY(ECFActivityApplyChanges, pdpApplyReq, TCFScpr::TApplyRequest) -#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW - FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingApplyRequest, MeshMachine::TNoTag) -#else - FIRST_NODEACTIVITY_ENTRY(SCprStates::TAwaitingApplyRequest, MeshMachine::TNoTag) -#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSetTFT, PDPSCprStates::TAwaitingTFTSet, PDPSCprStates::TNoTagOrError) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSetQoS, PDPSCprStates::TAwaitingQoSSet, PDPSCprStates::TNoTagOrError) - NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TModifyActivePDPContext, PDPSCprStates::TAwaitingActivePDPContextModified, PDPSCprStates::TNoTagOrError) - LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TRaiseParamsGrantedAndSendApplyResponse) - LAST_NODEACTIVITY_ENTRY(KErrorTag, PDPSCprStates::TRaiseParamsRejectedL) -NODEACTIVITY_END() -} - -namespace PDPSCprParamsChanged -{ -DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, paramsChanged, TPDPMessages::TPDPFSMMessage) - FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingParamsChanged, PDPSCprStates::TNoTagOrError) - LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TRaiseParamsChanged) - LAST_NODEACTIVITY_ENTRY(KErrorTag, PDPSCprStates::TRaiseParamsRejectedL) -NODEACTIVITY_END() -} - -namespace PDPSCprContextBlockedUnblockedActivity -{ -DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, ctxBlockedUnblocked, TPDPMessages::TPDPFSMMessage) - FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingContextBlockedOrUnblocked, MeshMachine::TNoTag) - THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TForwardContextBlockedOrUnblockedToDC, PDPSCprStates::TBlockedOrUnblocked) - LAST_NODEACTIVITY_ENTRY(PDPSCprStates::KBlocked, PDPSCprStates::TSendDataTransferTemporarilyBlocked) - /** - This needs to send DataTransferUnblocked progress, but this needs to be discussed with people in finland - when they return. In old world, KLinkLayerOpen was sent in this case, but KLinkLayerOpen has changed and is misused for - this purpose. Should be a new, functionallity specific progress . - */ - LAST_NODEACTIVITY_ENTRY(PDPSCprStates::KUnblocked, PDPSCprStates::TSendDataTransferUnblocked) -NODEACTIVITY_END() -} - -namespace PDPSCprStateChangeActivity -{ -DECLARE_DEFINE_NODEACTIVITY(ECFActivityForwardStateChange, forwardStateChange, TCFMessage::TStateChange) - //Bin all the progresses received, PDP.SCPR will generate its own ones. - NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingMessageState, MeshMachine::TNoTag) -NODEACTIVITY_END() -} - -namespace PDPSCprAuthenticationActivity -{ -DECLARE_DEFINE_NODEACTIVITY(ECFActivityAuthentication, PDPSCprAuthentication, TLinkMessage::TAuthenticate) - NODEACTIVITY_ENTRY(KNoTag, AgentSCprStates::TSendAuthenticateComplete, AgentSCprStates::TAwaitingAuthenticate, MeshMachine::TNoTag) -NODEACTIVITY_END() -} - -namespace PDPSCprActivities -{ -DEFINE_ACTIVITY_MAP(activityMap) - ACTIVITY_MAP_ENTRY(PDPSCprProvisionActivity, provision) - ACTIVITY_MAP_ENTRY(PDPSCprStartActivity, PDPScprStart) - ACTIVITY_MAP_ENTRY(PDPSCprDataClientStartActivity, pdpDataClientStart) - ACTIVITY_MAP_ENTRY(PDPSCprSetParameters, paramRequest) - ACTIVITY_MAP_ENTRY(PDPSCprParamsChanged, paramsChanged) - ACTIVITY_MAP_ENTRY(PDPSCprContextBlockedUnblockedActivity, ctxBlockedUnblocked) - ACTIVITY_MAP_ENTRY(PDPSCprApply, pdpApplyReq) - ACTIVITY_MAP_ENTRY(PDPSCprStopActivity, Stop) - ACTIVITY_MAP_ENTRY(PDPSCprGoneDownActivity, goneDown) - ACTIVITY_MAP_ENTRY(PDPSCprStateChangeActivity, forwardStateChange) - ACTIVITY_MAP_ENTRY(PDPSCprAuthenticationActivity, PDPSCprAuthentication) -ACTIVITY_MAP_END_BASE(SCprActivities, coreSCprActivities) -} - -//-========================================================= -// -// CPDPSubConnectionProvider methods -// -//-========================================================= -CPDPSubConnectionProvider* CPDPSubConnectionProvider::NewL(CPDPSubConnectionProviderFactory& aFactory) -/** -Construct a new PDP SubConnection Provider Object - -@params aFactory factory that create this object -@param aConnProvider Connection Provider associated with this object -*/ - { - CPDPSubConnectionProvider* ptr = new (ELeave) CPDPSubConnectionProvider(aFactory); - CleanupStack::PushL(ptr); - ptr->ConstructL(); - CleanupStack::Pop(); - return ptr; - } - - -CPDPSubConnectionProvider::~CPDPSubConnectionProvider() - { - LOG_NODE_DESTROY(KPDPSCprSubTag, CPDPSubConnectionProvider) - __FLOG_CLOSE; - if (iPdpFsmInterface) - { - iPdpFsmInterface->Close(); - } - } - - -CPDPSubConnectionProvider::CPDPSubConnectionProvider(ESock::CSubConnectionProviderFactoryBase& aFactory) -:CCoreSubConnectionProvider(aFactory, PDPSCprActivities::activityMap::Self()), - iPDPFsmContextId(EInvalidContextId), - iPdpFsmInterface(NULL), - iActivityAwaitingResponse(KActivityNull), - iProvisionFailure(KErrCorrupt) - { - LOG_NODE_CREATE1(KPDPSCprSubTag, CPDPSubConnectionProvider, " [factory=%08x]", &aFactory) - __FLOG_OPEN(KCFNodeTag, KPDPSCprSubTag); - } - - -CPDPSubConnectionProvider::CPDPSubConnectionProvider(ESock::CSubConnectionProviderFactoryBase& aFactory, - const MeshMachine::TNodeActivityMap& aActivityMap) -:CCoreSubConnectionProvider(aFactory, aActivityMap), - iPDPFsmContextId(EInvalidContextId), - iPdpFsmInterface(NULL), - iActivityAwaitingResponse(KActivityNull), - iParamsRelease(MPDPParamMapper::KParameterRelInvalid) - { - } - -void CPDPSubConnectionProvider::ConstructL() -/** -IP SubConnection Provider Second Phase Constructor -*/ - { - CCoreSubConnectionProvider::ConstructL(KPDPSCPRPreallocatedActivityBufferSize); - } - -void CPDPSubConnectionProvider::Received(TNodeContextBase& aContext) - { - Messages::TNodeSignal::TMessageId noPeerIds[] = { - TCFFactory::TPeerFoundOrCreated::Id(), - TCFPeer::TJoinRequest::Id(), - TCFMessage::TStateChange::Id(), - Messages::TNodeSignal::TNullMessageId::Id() - }; - MeshMachine::AMMNodeBase::Received(noPeerIds, aContext); - MeshMachine::AMMNodeBase::PostReceived(aContext); - } - -void CPDPSubConnectionProvider::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) - { - ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aMessage, aRecipient); - - PDPSCprStates::TContext ctx(*this, aMessage, aSender, aRecipient); - CPDPSubConnectionProvider::Received(ctx); - User::LeaveIfError(ctx.iReturn); - } - -void CPDPSubConnectionProvider::Event(TInt aEvent, TInt aParam) - { - TPDPMessages::TPDPFSMMessage msg(aEvent, aParam); - - RClientInterface::OpenPostMessageClose(TNodeCtxId(iActivityAwaitingResponse, Id()), Id(), msg); - iActivityAwaitingResponse = KActivityNull; - } - -void CPDPSubConnectionProvider::LinkUp() - { - if (iLinkUps++ == 0) - { - iDefaultSCPR->LinkUp(); - } - } - -void CPDPSubConnectionProvider::LinkDown(TInt aCause) - { - if (--iLinkUps == 0) - { - iDefaultSCPR->LinkDown(aCause); - } - } - -CSubConQosR99ParamSet* CPDPSubConnectionProvider::GrantedQoS() - { - if(static_cast(this)->GetParameterBundle().IsNull()) - { - return NULL; - } - RParameterFamily qosFamily=static_cast(this)->GetParameterBundle().FindFamily(KSubConQoSFamily); - if (qosFamily.IsNull()) - { - return NULL; - } - CSubConQosR99ParamSet* qosParams = static_cast(qosFamily.FindParameterSet( - STypeId::CreateSTypeId(KSubCon3GPPExtParamsFactoryUid,KSubConQosR99ParamsType), RParameterFamily::EGranted)); - if (!qosParams) - { - qosParams = static_cast(qosFamily.FindParameterSet( - STypeId::CreateSTypeId(KSubCon3GPPExtParamsFactoryUid,KSubConQosR5ParamsType), RParameterFamily::EGranted)); - } - ASSERT(qosParams); - return qosParams; - } - -TInt CPDPSubConnectionProvider::QoSRank() -/** -This method calculates the qos ranking as specified in 3GPP TS 23.107 Annex C. -Magic number usage is deemed justified based on the content of 3GPP TS 23.107. -*/ - { - CSubConQosR99ParamSet* qosParams = GrantedQoS(); - ASSERT(qosParams); - - switch (qosParams->GetTrafficClass()) - { - case RPacketQoS::ETrafficClassConversational: - return 2; - case RPacketQoS::ETrafficClassStreaming: - return 3; - case RPacketQoS::ETrafficClassInteractive: - { - switch (qosParams->GetTrafficHandlingPriority()) - { - case RPacketQoS::ETrafficPriority1: - return 1; - case RPacketQoS::ETrafficPriority2: - return 4; - case RPacketQoS::ETrafficPriority3: - return 5; - default: - ; - } - break; - } - case RPacketQoS::ETrafficClassBackground: - return 6; - default: - ; - } - return 7; - } - - -MFactoryQuery::TMatchResult THighestQoSQuery::Match(TFactoryObjectInfo& aSubConnectionInfo) - { - CPDPSubConnectionProvider* sc = static_cast(aSubConnectionInfo.iInfo.iFactoryObject); - ASSERT(sc && sc->ControlProvider()); - if (sc->ControlProvider()->RecipientId() == iCtrlProvider && - sc->iPDPFsmContextId != CPDPSubConnectionProvider::EInvalidContextId) - { - if (NULL == iHighestQoSProvider) - { - iHighestQoSProvider = sc; - } - else if (sc->QoSRank() > iHighestQoSProvider->QoSRank()) - { - iHighestQoSProvider = sc; - } - } - return MFactoryQuery::EContinue; - } - -TTFTInfo CPDPSubConnectionProvider::GetTftInfoL(CSubConIPAddressInfoParamSet* aParamSet) - { - /** TODO: What to do if there will be second request before ggsn responce back and first one will go to the granted list - Assigning of id's is not correct in that case*/ - - TTFTInfo tft; - RPacketContext::TPacketFilterV2 pf; - - TUint aParamSetNum = aParamSet->GetParamNum(); - /** TODO: It should be only one in the queue, so remove the loop */ - for (TUint i=0; iGetParamInfoL(i)); - - TInetAddr addr(paramInfo.iCliDstAddr); - TUint32 ipv4Addr = addr.Address(); - - if(ipv4Addr) - { - addr.ConvertToV4Mapped(); - } - - TIp6Addr ipv6 = addr.Ip6Address(); - Mem::Copy(&pf.iSrcAddr,&ipv6,RPacketContext::KIPAddressSize); - - pf.iId = FindPacketFilterIdL(paramInfo); - Mem::Fill(pf.iSrcAddrSubnetMask, sizeof(pf.iSrcAddrSubnetMask), 0xFF); - pf.iSrcPortMin = pf.iSrcPortMax = paramInfo.iCliDstAddr.Port(); - pf.iDestPortMin = pf.iDestPortMax = paramInfo.iCliSrcAddr.Port(); - pf.iProtocolNumberOrNextHeader = paramInfo.iProtocolId; - - tft.AddPacketFilter(pf); - } - - return tft; - } - -TTFTOperationCode CPDPSubConnectionProvider::GetOperationCodeL(CSubConIPAddressInfoParamSet* aParamSet) - { - TTFTOperationCode result(0); - TInt count = aParamSet->GetParamNum(); - if(count > 0) - { - CSubConIPAddressInfoParamSet::TSubConIPAddressInfo paramInfo(aParamSet->GetParamInfoL(0)); - switch(paramInfo.iState) - { - case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::EAdd: - result = KAddFilters; - break; - case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::ERemove: - result = KRemoveFilters; - break; - case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::ENone: - if(aParamSet->GetOperationCode() == CSubConIPAddressInfoParamSet::EDelete) - { - result = KDeleteTFT; - } - break; - default: ; - /** TODO: What to do with an error */ - } - } - else - { - /** TODO: Panic? */ - } - - return result; - } - -TUint CPDPSubConnectionProvider::FindPacketFilterIdL(CSubConIPAddressInfoParamSet::TSubConIPAddressInfo aParamInfo) - { - TUint id = 0; - - switch(aParamInfo.iState) - { - case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::EAdd : - { - TUint i = 0; - TUint mask = 1; - - // search bitwise for an empty slot - while(!(mask & iPacketFilterMaskId) && i<8) - { - mask <<= 1; - ++i; - } - - // if not found assigne the first slot - id = (i>=8) ? 1 : i; - } - break; - case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::ERemove : - id = FindIdOfMatchingParamSetL(aParamInfo); - break; - case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::ENone : - break; - default: ; - /** TODO: What to do with an error */ - } - - // increase by one since id is starting from 1 - return id; - } - -TUint CPDPSubConnectionProvider::FindIdOfMatchingParamSetL(CSubConIPAddressInfoParamSet::TSubConIPAddressInfo aParamInfo) - { - // check the list of the granted params for an index - if(GetParameterBundle().IsNull()) - { - return 0; - } - RParameterFamily ipAddressInfoFamily=GetParameterBundle().FindFamily(KSubConIPAddressInfoFamily); - if( ipAddressInfoFamily.IsNull() ) - { - return 0; - } - - CSubConIPAddressInfoParamSet* ipAddressInfoSet = - static_cast( - ipAddressInfoFamily.FindParameterSet( - STypeId::CreateSTypeId(CSubConIPAddressInfoParamSet::EUid,CSubConIPAddressInfoParamSet::ETypeId), - RParameterFamily::EGranted)); - if( ipAddressInfoSet == NULL ) - { - return 0; - } - TUint count = ipAddressInfoSet->GetParamNum(); - - TBool found(EFalse); - TUint i=0; - - for(i=0; iGetParamInfoL(i)); - - found = paramInfo.Compare(aParamInfo); - } - // use the index against corresponding array of id's - return found ? iPacketFilterId[i] : 0; - } - -void CPDPSubConnectionProvider::NewPacketFilterAddedL(CSubConIPAddressInfoParamSet::TSubConIPAddressInfo aParamInfo, TUint aId) - { - RParameterFamily ipAddressInfoFamily = GetParameterBundle().FindFamily(KSubConIPAddressInfoFamily); - if ( ! ipAddressInfoFamily.IsNull()) - { - CSubConIPAddressInfoParamSet* grantedIPAddressInfo = CSubConIPAddressInfoParamSet::NewL(ipAddressInfoFamily, RParameterFamily::EGranted); - - if(grantedIPAddressInfo) - { - grantedIPAddressInfo->AddParamInfo(aParamInfo); - - iPacketFilterId.Append(aId); - iPacketFilterMaskId |= 1 << aId; - } - else - { - User::Leave(KErrNotFound); - } - } - } - -void CPDPSubConnectionProvider::PacketFilterRemovedL(TUint aId) - { - RParameterFamily ipAddressInfoFamily = GetParameterBundle().FindFamily(KSubConIPAddressInfoFamily); - - if ( ! ipAddressInfoFamily.IsNull()) - { - // find an index from given id value - //TUint count = iPacketFilterId.Count(); - TInt index = iPacketFilterId.Find(aId); - - //for (index = 0; (index < count) && (iPacketFilterId[index] != aId); ++index){} - - if(index >= 0) - { - CSubConIPAddressInfoParamSet* grantedIPAddressInfo = CSubConIPAddressInfoParamSet::NewL(ipAddressInfoFamily, RParameterFamily::EGranted); - - if(grantedIPAddressInfo) - { - grantedIPAddressInfo->RemoveParamInfo(index); - - iPacketFilterId.Remove(index); - iPacketFilterMaskId &= !(1 << aId); - } - else - { - User::Leave(KErrNotFound); - } - } - else - { - User::Leave(KErrNotFound); - } - } - } +// Copyright (c) 2006-2010 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: +// PDP SubConnection Provider implementation +// +// + +/** + @file + @internalComponent +*/ + + +#include "PDPSCPRStates.h" +#include "PDPDeftSCPR.h" +#include "PDPSCPR.h" +#include "PDPSCPRFactory.h" +#include +#include +#include +#include +#include + +#if defined __FLOG_ACTIVE || defined SYMBIAN_TRACE_ENABLE +#define KPDPSCprTag KESockSubConnectionTag +_LIT8(KPDPSCprSubTag, "pdpscpr"); +#endif + +using namespace Messages; +using namespace MeshMachine; +using namespace ESock; +using namespace NetStateMachine; +using namespace Factories; + +//We reserve space for two preallocated activities that may start concurrently on the SCPR +//node: destroy and data client stop. +static const TUint KDefaultMaxPreallocatedActivityCount = 2; +static const TUint KMaxPreallocatedActivitySize = sizeof(MeshMachine::CNodeRetryParallelActivity) + sizeof(MeshMachine::APreallocatedOriginators<4>); +static const TUint KPDPSCPRPreallocatedActivityBufferSize = KDefaultMaxPreallocatedActivityCount * KMaxPreallocatedActivitySize; + +//-========================================================= +// +// CPDPSubConnectionProvider Activities +// +//-========================================================= + +namespace PDPSCprProvisionActivity +{ +DECLARE_DEFINE_NODEACTIVITY(ECFActivityStoreProvision, provision, TCFDataClient::TProvisionConfig) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TStoreProvisionAndInitSelf, CoreNetStates::TAwaitingProvision, MeshMachine::TNoTag) +NODEACTIVITY_END() +} + +namespace PDPSCprStartActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, PDPScprStart, TCFServiceProvider::TStart, MeshMachine::CNodeRetryActivity::NewL) + FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStart, CoreNetStates::TNoTagOrBearerPresentBlockedByStop) + NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStartSelf, CoreNetStates::TAwaitingDataClientStarted, MeshMachine::TNoTag) + LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStarted) + LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreStates::TPanic) +NODEACTIVITY_END() +} + +namespace PDPSCprDataClientStartActivity +{ +typedef MeshMachine::TAcceptErrorState TAwaitingDataClientStartedOrError; + +DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStartDataClient, pdpDataClientStart, TCFDataClient::TStart, PDPSCprStates::CStartActivity::NewL) + FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, MeshMachine::TNoTag) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TCreateSecondaryOrMbmsPDPCtx, PDPSCprStates::TAwaitingPDPCtxCreated, PDPSCprStates::TNoTagOrError) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSetTFT, PDPSCprStates::TAwaitingTFTSet, PDPSCprStates::TNoTagOrError) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSetQoS, PDPSCprStates::TAwaitingQoSSet, PDPSCprStates::TNoTagOrError) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TActivatePDPContext, PDPSCprStates::TAwaitingPDPContextActive, PDPSCprStates::TNoTagOrError) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TOverrideProvisionAndStartDataClient, TAwaitingDataClientStartedOrError, MeshMachine::TNoTagOrErrorTag) + //This call below is somewhat obscure, but must be performed for the final activation of a pdp context. + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TGetNegotiatedQoS, PDPSCprStates::TAwaitingNegotiatedQoSRetrieved, PDPSCprStates::TNoTagOrError) + LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TRaiseParamsGrantedAndSendDataClientStarted) + + // Cleanup if error occurred + THROUGH_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing, CoreNetStates::TNoTagOrNoDataClientsToStop) + NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStopYourFlows, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag) + THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClientsToStop, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrProviderStopped) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TDestroyPDPContext, PDPSCprStates::TAwaitingPDPContextDestroyed, MeshMachine::TTag) + THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PDPSCprStates::TCleanupFSMAndDataClients, MeshMachine::TTag) + LAST_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, MeshMachine::TRaiseActivityError) +NODEACTIVITY_END() +} + +namespace PDPSCprStopActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStopDataClient, Stop, TCFDataClient::TStop, MeshMachine::CNodeRetryActivity::NewL) + FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingDataClientStopOrCancel, MeshMachine::TNoTag) + THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, PRDataClientStopActivity::TNoTagOrProviderStoppedBlockedByStart) + + // stopping + NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStopYourFlows, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag) + THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrProviderStopped) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TDestroyPDPContext, PDPSCprStates::TAwaitingPDPContextDestroyed, MeshMachine::TTag) + THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PDPSCprStates::TCleanupFSMAndDataClients, MeshMachine::TTag) + LAST_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PDPSCprStates::TSendDataClientStopped) +NODEACTIVITY_END() +} + +namespace PDPSCprGoneDownActivity +{ +DECLARE_DEFINE_NODEACTIVITY(ECFActivityGoneDown, goneDown, TPDPMessages::TPDPFSMMessage) + FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingPDPContextGoneDown, MeshMachine::TActiveOrNoTag) + THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSendGoneDown, CoreNetStates::TNoTagOrNoDataClientsToStop) + NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStopYourFlows, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag) + + LAST_NODEACTIVITY_ENTRY(KActiveTag, CoreNetStates::TCancelDataClientStart) //MZTODO: This triple should wait for TError sent as a response to TCancel + LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClientsToStop, MeshMachine::TClearError) +NODEACTIVITY_END() +} + +namespace PDPSCprSetParameters +{ +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW +DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, paramRequest, TCFScpr::TSetParamsRequest) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TStoreAndRespondWithCurrentParams, PRStates::TAwaitingParamRequest, MeshMachine::TNoTag) +#else +DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, paramRequest, TCFScpr::TParamsRequest) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TStoreParamsAndRespond, SCprStates::TAwaitingParamRequest, MeshMachine::TNoTag) +#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW +NODEACTIVITY_END() +} + +namespace PDPSCprApply +{ +DECLARE_DEFINE_NODEACTIVITY(ECFActivityApplyChanges, pdpApplyReq, TCFScpr::TApplyRequest) +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingApplyRequest, MeshMachine::TNoTag) +#else + FIRST_NODEACTIVITY_ENTRY(SCprStates::TAwaitingApplyRequest, MeshMachine::TNoTag) +#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSetTFT, PDPSCprStates::TAwaitingTFTSet, PDPSCprStates::TNoTagOrError) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSetQoS, PDPSCprStates::TAwaitingQoSSet, PDPSCprStates::TNoTagOrError) + NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TModifyActivePDPContext, PDPSCprStates::TAwaitingActivePDPContextModified, PDPSCprStates::TNoTagOrError) + LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TRaiseParamsGrantedAndSendApplyResponse) + LAST_NODEACTIVITY_ENTRY(KErrorTag, PDPSCprStates::TRaiseParamsRejectedL) +NODEACTIVITY_END() +} + +namespace PDPSCprParamsChanged +{ +DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, paramsChanged, TPDPMessages::TPDPFSMMessage) + FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingParamsChanged, PDPSCprStates::TNoTagOrError) + LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TRaiseParamsChanged) + LAST_NODEACTIVITY_ENTRY(KErrorTag, PDPSCprStates::TRaiseParamsRejectedL) +NODEACTIVITY_END() +} + +namespace PDPSCprContextBlockedUnblockedActivity +{ +DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, ctxBlockedUnblocked, TPDPMessages::TPDPFSMMessage) + FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingContextBlockedOrUnblocked, MeshMachine::TNoTag) + THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TForwardContextBlockedOrUnblockedToDC, PDPSCprStates::TBlockedOrUnblocked) + LAST_NODEACTIVITY_ENTRY(PDPSCprStates::KBlocked, PDPSCprStates::TSendDataTransferTemporarilyBlocked) + /** + This needs to send DataTransferUnblocked progress, but this needs to be discussed with people in finland + when they return. In old world, KLinkLayerOpen was sent in this case, but KLinkLayerOpen has changed and is misused for + this purpose. Should be a new, functionallity specific progress . + */ + LAST_NODEACTIVITY_ENTRY(PDPSCprStates::KUnblocked, PDPSCprStates::TSendDataTransferUnblocked) +NODEACTIVITY_END() +} + +namespace PDPSCprStateChangeActivity +{ +DECLARE_DEFINE_NODEACTIVITY(ECFActivityForwardStateChange, forwardStateChange, TCFMessage::TStateChange) + //Bin all the progresses received, PDP.SCPR will generate its own ones. + NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingMessageState, MeshMachine::TNoTag) +NODEACTIVITY_END() +} + +namespace PDPSCprAuthenticationActivity +{ +DECLARE_DEFINE_NODEACTIVITY(ECFActivityAuthentication, PDPSCprAuthentication, TLinkMessage::TAuthenticate) + NODEACTIVITY_ENTRY(KNoTag, AgentSCprStates::TSendAuthenticateComplete, AgentSCprStates::TAwaitingAuthenticate, MeshMachine::TNoTag) +NODEACTIVITY_END() +} + +namespace PDPSCprActivities +{ +DEFINE_ACTIVITY_MAP(activityMap) + ACTIVITY_MAP_ENTRY(PDPSCprProvisionActivity, provision) + ACTIVITY_MAP_ENTRY(PDPSCprStartActivity, PDPScprStart) + ACTIVITY_MAP_ENTRY(PDPSCprDataClientStartActivity, pdpDataClientStart) + ACTIVITY_MAP_ENTRY(PDPSCprSetParameters, paramRequest) + ACTIVITY_MAP_ENTRY(PDPSCprParamsChanged, paramsChanged) + ACTIVITY_MAP_ENTRY(PDPSCprContextBlockedUnblockedActivity, ctxBlockedUnblocked) + ACTIVITY_MAP_ENTRY(PDPSCprApply, pdpApplyReq) + ACTIVITY_MAP_ENTRY(PDPSCprStopActivity, Stop) + ACTIVITY_MAP_ENTRY(PDPSCprGoneDownActivity, goneDown) + ACTIVITY_MAP_ENTRY(PDPSCprStateChangeActivity, forwardStateChange) + ACTIVITY_MAP_ENTRY(PDPSCprAuthenticationActivity, PDPSCprAuthentication) +ACTIVITY_MAP_END_BASE(SCprActivities, coreSCprActivities) +} + +//-========================================================= +// +// CPDPSubConnectionProvider methods +// +//-========================================================= +CPDPSubConnectionProvider* CPDPSubConnectionProvider::NewL(CPDPSubConnectionProviderFactory& aFactory) +/** +Construct a new PDP SubConnection Provider Object + +@params aFactory factory that create this object +@param aConnProvider Connection Provider associated with this object +*/ + { + CPDPSubConnectionProvider* ptr = new (ELeave) CPDPSubConnectionProvider(aFactory); + CleanupStack::PushL(ptr); + ptr->ConstructL(); + CleanupStack::Pop(); + return ptr; + } + + +CPDPSubConnectionProvider::~CPDPSubConnectionProvider() + { + LOG_NODE_DESTROY(KPDPSCprSubTag, CPDPSubConnectionProvider) + __FLOG_CLOSE; + if (iPdpFsmInterface) + { + iPdpFsmInterface->Close(); + } + } + + +CPDPSubConnectionProvider::CPDPSubConnectionProvider(ESock::CSubConnectionProviderFactoryBase& aFactory) +:CCoreSubConnectionProvider(aFactory, PDPSCprActivities::activityMap::Self()), + iPDPFsmContextId(EInvalidContextId), + iPdpFsmInterface(NULL), + iActivityAwaitingResponse(KActivityNull), + iProvisionFailure(KErrCorrupt) + { + LOG_NODE_CREATE1(KPDPSCprSubTag, CPDPSubConnectionProvider, " [factory=%08x]", &aFactory) + __FLOG_OPEN(KCFNodeTag, KPDPSCprSubTag); + } + + +CPDPSubConnectionProvider::CPDPSubConnectionProvider(ESock::CSubConnectionProviderFactoryBase& aFactory, + const MeshMachine::TNodeActivityMap& aActivityMap) +:CCoreSubConnectionProvider(aFactory, aActivityMap), + iPDPFsmContextId(EInvalidContextId), + iPdpFsmInterface(NULL), + iActivityAwaitingResponse(KActivityNull), + iParamsRelease(MPDPParamMapper::KParameterRelInvalid) + { + } + +void CPDPSubConnectionProvider::ConstructL() +/** +IP SubConnection Provider Second Phase Constructor +*/ + { + CCoreSubConnectionProvider::ConstructL(KPDPSCPRPreallocatedActivityBufferSize); + } + +void CPDPSubConnectionProvider::Received(TNodeContextBase& aContext) + { + Messages::TNodeSignal::TMessageId noPeerIds[] = { + TCFFactory::TPeerFoundOrCreated::Id(), + TCFPeer::TJoinRequest::Id(), + TCFMessage::TStateChange::Id(), + Messages::TNodeSignal::TNullMessageId::Id() + }; + MeshMachine::AMMNodeBase::Received(noPeerIds, aContext); + MeshMachine::AMMNodeBase::PostReceived(aContext); + } + +void CPDPSubConnectionProvider::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) + { + ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aMessage, aRecipient); + + PDPSCprStates::TContext ctx(*this, aMessage, aSender, aRecipient); + CPDPSubConnectionProvider::Received(ctx); + User::LeaveIfError(ctx.iReturn); + } + +void CPDPSubConnectionProvider::Event(TInt aEvent, TInt aParam) + { + TPDPMessages::TPDPFSMMessage msg(aEvent, aParam); + + RClientInterface::OpenPostMessageClose(TNodeCtxId(iActivityAwaitingResponse, Id()), Id(), msg); + iActivityAwaitingResponse = KActivityNull; + } + +void CPDPSubConnectionProvider::LinkUp() + { + if (iLinkUps++ == 0) + { + iDefaultSCPR->LinkUp(); + } + } + +void CPDPSubConnectionProvider::LinkDown(TInt aCause) + { + if (--iLinkUps == 0) + { + iDefaultSCPR->LinkDown(aCause); + } + } + +CSubConQosR99ParamSet* CPDPSubConnectionProvider::GrantedQoS() + { + if(static_cast(this)->GetParameterBundle().IsNull()) + { + return NULL; + } + RParameterFamily qosFamily=static_cast(this)->GetParameterBundle().FindFamily(KSubConQoSFamily); + if (qosFamily.IsNull()) + { + return NULL; + } + CSubConQosR99ParamSet* qosParams = static_cast(qosFamily.FindParameterSet( + STypeId::CreateSTypeId(KSubCon3GPPExtParamsFactoryUid,KSubConQosR99ParamsType), RParameterFamily::EGranted)); + if (!qosParams) + { + qosParams = static_cast(qosFamily.FindParameterSet( + STypeId::CreateSTypeId(KSubCon3GPPExtParamsFactoryUid,KSubConQosR5ParamsType), RParameterFamily::EGranted)); + } + ASSERT(qosParams); + return qosParams; + } + +TInt CPDPSubConnectionProvider::QoSRank() +/** +This method calculates the qos ranking as specified in 3GPP TS 23.107 Annex C. +Magic number usage is deemed justified based on the content of 3GPP TS 23.107. +*/ + { + CSubConQosR99ParamSet* qosParams = GrantedQoS(); + ASSERT(qosParams); + + switch (qosParams->GetTrafficClass()) + { + case RPacketQoS::ETrafficClassConversational: + return 2; + case RPacketQoS::ETrafficClassStreaming: + return 3; + case RPacketQoS::ETrafficClassInteractive: + { + switch (qosParams->GetTrafficHandlingPriority()) + { + case RPacketQoS::ETrafficPriority1: + return 1; + case RPacketQoS::ETrafficPriority2: + return 4; + case RPacketQoS::ETrafficPriority3: + return 5; + default: + ; + } + break; + } + case RPacketQoS::ETrafficClassBackground: + return 6; + default: + ; + } + return 7; + } + + +MFactoryQuery::TMatchResult THighestQoSQuery::Match(TFactoryObjectInfo& aSubConnectionInfo) + { + CPDPSubConnectionProvider* sc = static_cast(aSubConnectionInfo.iInfo.iFactoryObject); + ASSERT(sc && sc->ControlProvider()); + if (sc->ControlProvider()->RecipientId() == iCtrlProvider && + sc->iPDPFsmContextId != CPDPSubConnectionProvider::EInvalidContextId) + { + if (NULL == iHighestQoSProvider) + { + iHighestQoSProvider = sc; + } + else if (sc->QoSRank() > iHighestQoSProvider->QoSRank()) + { + iHighestQoSProvider = sc; + } + } + return MFactoryQuery::EContinue; + } + +TTFTInfo CPDPSubConnectionProvider::GetTftInfoL(CSubConIPAddressInfoParamSet* aParamSet) + { + /** TODO: What to do if there will be second request before ggsn responce back and first one will go to the granted list + Assigning of id's is not correct in that case*/ + + TTFTInfo tft; + RPacketContext::TPacketFilterV2 pf; + + TUint aParamSetNum = aParamSet->GetParamNum(); + /** TODO: It should be only one in the queue, so remove the loop */ + for (TUint i=0; iGetParamInfoL(i)); + + TInetAddr addr(paramInfo.iCliDstAddr); + TUint32 ipv4Addr = addr.Address(); + + if(ipv4Addr) + { + addr.ConvertToV4Mapped(); + } + + TIp6Addr ipv6 = addr.Ip6Address(); + Mem::Copy(&pf.iSrcAddr,&ipv6,RPacketContext::KIPAddressSize); + + pf.iId = FindPacketFilterIdL(paramInfo); + Mem::Fill(pf.iSrcAddrSubnetMask, sizeof(pf.iSrcAddrSubnetMask), 0xFF); + pf.iSrcPortMin = pf.iSrcPortMax = paramInfo.iCliDstAddr.Port(); + pf.iDestPortMin = pf.iDestPortMax = paramInfo.iCliSrcAddr.Port(); + pf.iProtocolNumberOrNextHeader = paramInfo.iProtocolId; + + tft.AddPacketFilter(pf); + } + + return tft; + } + +TTFTOperationCode CPDPSubConnectionProvider::GetOperationCodeL(CSubConIPAddressInfoParamSet* aParamSet) + { + TTFTOperationCode result(0); + TInt count = aParamSet->GetParamNum(); + if(count > 0) + { + CSubConIPAddressInfoParamSet::TSubConIPAddressInfo paramInfo(aParamSet->GetParamInfoL(0)); + switch(paramInfo.iState) + { + case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::EAdd: + result = KAddFilters; + break; + case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::ERemove: + result = KRemoveFilters; + break; + case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::ENone: + if(aParamSet->GetOperationCode() == CSubConIPAddressInfoParamSet::EDelete) + { + result = KDeleteTFT; + } + break; + default: ; + /** TODO: What to do with an error */ + } + } + else + { + /** TODO: Panic? */ + } + + return result; + } + +TUint CPDPSubConnectionProvider::FindPacketFilterIdL(CSubConIPAddressInfoParamSet::TSubConIPAddressInfo aParamInfo) + { + TUint id = 0; + + switch(aParamInfo.iState) + { + case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::EAdd : + { + TUint i = 0; + TUint mask = 1; + + // search bitwise for an empty slot + while(!(mask & iPacketFilterMaskId) && i<8) + { + mask <<= 1; + ++i; + } + + // if not found assigne the first slot + id = (i>=8) ? 1 : i; + } + break; + case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::ERemove : + id = FindIdOfMatchingParamSetL(aParamInfo); + break; + case CSubConIPAddressInfoParamSet::TSubConIPAddressInfo::ENone : + break; + default: ; + /** TODO: What to do with an error */ + } + + // increase by one since id is starting from 1 + return id; + } + +TUint CPDPSubConnectionProvider::FindIdOfMatchingParamSetL(CSubConIPAddressInfoParamSet::TSubConIPAddressInfo aParamInfo) + { + // check the list of the granted params for an index + if(GetParameterBundle().IsNull()) + { + return 0; + } + RParameterFamily ipAddressInfoFamily=GetParameterBundle().FindFamily(KSubConIPAddressInfoFamily); + if( ipAddressInfoFamily.IsNull() ) + { + return 0; + } + + CSubConIPAddressInfoParamSet* ipAddressInfoSet = + static_cast( + ipAddressInfoFamily.FindParameterSet( + STypeId::CreateSTypeId(CSubConIPAddressInfoParamSet::EUid,CSubConIPAddressInfoParamSet::ETypeId), + RParameterFamily::EGranted)); + if( ipAddressInfoSet == NULL ) + { + return 0; + } + TUint count = ipAddressInfoSet->GetParamNum(); + + TBool found(EFalse); + TUint i=0; + + for(i=0; iGetParamInfoL(i)); + + found = paramInfo.Compare(aParamInfo); + } + // use the index against corresponding array of id's + return found ? iPacketFilterId[i] : 0; + } + +void CPDPSubConnectionProvider::NewPacketFilterAddedL(CSubConIPAddressInfoParamSet::TSubConIPAddressInfo aParamInfo, TUint aId) + { + RParameterFamily ipAddressInfoFamily = GetParameterBundle().FindFamily(KSubConIPAddressInfoFamily); + if ( ! ipAddressInfoFamily.IsNull()) + { + CSubConIPAddressInfoParamSet* grantedIPAddressInfo = CSubConIPAddressInfoParamSet::NewL(ipAddressInfoFamily, RParameterFamily::EGranted); + + if(grantedIPAddressInfo) + { + grantedIPAddressInfo->AddParamInfo(aParamInfo); + + iPacketFilterId.Append(aId); + iPacketFilterMaskId |= 1 << aId; + } + else + { + User::Leave(KErrNotFound); + } + } + } + +void CPDPSubConnectionProvider::PacketFilterRemovedL(TUint aId) + { + RParameterFamily ipAddressInfoFamily = GetParameterBundle().FindFamily(KSubConIPAddressInfoFamily); + + if ( ! ipAddressInfoFamily.IsNull()) + { + // find an index from given id value + //TUint count = iPacketFilterId.Count(); + TInt index = iPacketFilterId.Find(aId); + + //for (index = 0; (index < count) && (iPacketFilterId[index] != aId); ++index){} + + if(index >= 0) + { + CSubConIPAddressInfoParamSet* grantedIPAddressInfo = CSubConIPAddressInfoParamSet::NewL(ipAddressInfoFamily, RParameterFamily::EGranted); + + if(grantedIPAddressInfo) + { + grantedIPAddressInfo->RemoveParamInfo(index); + + iPacketFilterId.Remove(index); + iPacketFilterMaskId &= !(1 << aId); + } + else + { + User::Leave(KErrNotFound); + } + } + else + { + User::Leave(KErrNotFound); + } + } + }