diff -r 000000000000 -r 3553901f7fa8 telephonyprotocols/pdplayer/src/PDPSCPR.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/telephonyprotocols/pdplayer/src/PDPSCPR.cpp Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,594 @@ +// 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, TPDPFSMMessages::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, TPDPFSMMessages::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, TPDPFSMMessages::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) + { + 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) + { + TPDPFSMMessages::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); + } + } + }