telephonyprotocols/pdplayer/src/PDPSCPR.cpp
changeset 0 3553901f7fa8
child 5 7ef16719d8cb
--- /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 <comms-infras/ss_log.h>
+#include <comms-infras/ss_msgintercept.h>
+#include <comms-infras/agentscprstates.h>
+#include <comms-infras/agentscpractivities.h>
+#include <comms-infras/ss_nodemessages_factory.h>
+
+#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<CoreNetStates::TAwaitingDataClientStarted> 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<CoreNetStates::KNoDataClientsToStop>)
+    THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClientsToStop, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrProviderStopped)
+    NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TDestroyPDPContext, PDPSCprStates::TAwaitingPDPContextDestroyed, MeshMachine::TTag<CoreNetStates::KProviderStopped>)
+    THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PRStates::TDestroyOrphanedDataClients, MeshMachine::TTag<CoreNetStates::KProviderStopped>)
+    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<CoreNetStates::KProviderStopped>)
+	THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrProviderStopped)
+	NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TDestroyPDPContext, PDPSCprStates::TAwaitingPDPContextDestroyed, MeshMachine::TTag<CoreNetStates::KProviderStopped>)
+	THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PRStates::TDestroyOrphanedDataClients, MeshMachine::TTag<CoreNetStates::KProviderStopped>)
+	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<ECFActivityStartDataClient>)
+	THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSendGoneDown, CoreNetStates::TNoTagOrNoDataClientsToStop)
+	NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStopYourFlows, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag<CoreNetStates::KNoDataClientsToStop>)
+
+	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<TCFMessage::TStateChange>, 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<CSubConnectionProviderBase*>(this)->GetParameterBundle().IsNull())
+        {
+        return NULL;
+        }
+    RParameterFamily qosFamily=static_cast<CSubConnectionProviderBase*>(this)->GetParameterBundle().FindFamily(KSubConQoSFamily);
+    if (qosFamily.IsNull())
+        {
+        return NULL;
+        }
+    CSubConQosR99ParamSet* qosParams = static_cast<CSubConQosR99ParamSet*>(qosFamily.FindParameterSet(
+        STypeId::CreateSTypeId(KSubCon3GPPExtParamsFactoryUid,KSubConQosR99ParamsType), RParameterFamily::EGranted));
+    if (!qosParams)
+        {
+        qosParams = static_cast<CSubConQosR99ParamSet*>(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<CPDPSubConnectionProvider*>(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; i<aParamSetNum; ++i)
+		{
+	//	TUint8* pfAddr(pf.iSrcAddr);
+
+		CSubConIPAddressInfoParamSet::TSubConIPAddressInfo paramInfo(aParamSet->GetParamInfoL(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<CSubConIPAddressInfoParamSet*>(
+            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; i<count && !found; ++i)
+		{
+		CSubConIPAddressInfoParamSet::TSubConIPAddressInfo paramInfo(ipAddressInfoSet->GetParamInfoL(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);
+			}
+		}
+	}