telephonyprotocols/pdplayer/src/PDPCPR.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
child 44 8b72faa1200f
child 60 1ac40e087278
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyprotocols/pdplayer/src/PDPCPR.cpp	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,303 @@
+// Copyright (c) 2008-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 Connection Provider implementation
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "PDPCPR.h"
+#include <comms-infras/ss_log.h>
+#include <comms-infras/ss_msgintercept.h>
+#include <comms-infras/corecpractivities.h>
+#include <elements/nm_address.h>
+#include <comms-infras/ss_nodemessages_parameters.h>
+#include <comms-infras/corescprstates.h>
+#include <elements/mm_context.h>
+#include <etelmm.h>
+#include <etelpckt.h>
+#include <comms-infras/ss_metaconnprov.h>
+#include "pdpprovision.h"
+#include <etel.h>
+#include <networking/cfbearers.h>
+#include "pdpcpravailabilitylistener.h"
+#include <comms-infras/ss_nodemessages.h>
+#include <networking/ipcpr_states.h>
+#include <comms-infras/linkmessages.h>
+#include <elements/nm_interfaces.h>
+#include <cs_genevent.h>
+#include <networking/etelbearers.h>
+
+using namespace ESock;
+
+
+//-=========================================================
+//
+// CPDPConnectionProvider methods
+//
+//-=========================================================	
+
+//We reserve space for two preallocated activities that may start concurrently on the CPR
+//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 KPDPCPRPreallocatedActivityBufferSize = KDefaultMaxPreallocatedActivityCount * KMaxPreallocatedActivitySize;
+
+namespace PDPCprLinkCharacteristicActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityParamRequest, PDPCprLinkCharacteristic, TCFScpr::TGetParamsRequest)
+    NODEACTIVITY_ENTRY(MeshMachine::KNoTag, PDPCprStates::TUpdateBundleAndRespondWithRetrievedParams, PRStates::TAwaitingParamRequest, MeshMachine::TNoTag)
+NODEACTIVITY_END()
+}
+
+// Agent SCPR Going Down Activity
+namespace PDPDataClientGoneDownActivity
+{
+DECLARE_DEFINE_NODEACTIVITY(ECFActivityDataClientGoneDown, PDPScprGoneDown, TCFControlProvider::TDataClientGoneDown)
+    // AwaitingDataClientGoneDown used rather than AlwaysAccept to mark data client EStopped
+    FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientGoneDown, CoreNetStates::TNoTagOrNonDefault)
+    LAST_NODEACTIVITY_ENTRY(MeshMachine::KNoTag, PRStates::TSendGoneDown)
+    LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNonDefault, MeshMachine::TDoNothing)    
+NODEACTIVITY_END()
+}
+
+namespace PDPCprActivities
+{
+DEFINE_ACTIVITY_MAP(activityMap)
+    ACTIVITY_MAP_ENTRY(PDPDataClientGoneDownActivity, PDPScprGoneDown)
+	ACTIVITY_MAP_ENTRY(PDPCprLinkCharacteristicActivity, PDPCprLinkCharacteristic)
+ACTIVITY_MAP_END_BASE(CprActivities, coreCprActivities)
+}
+
+
+CPDPConnectionProvider* CPDPConnectionProvider::NewL(ESock::CConnectionProviderFactoryBase& aFactory)
+    {
+    CPDPConnectionProvider* provider = new (ELeave) CPDPConnectionProvider(aFactory);
+    CleanupStack::PushL(provider);
+    provider->ConstructL();
+    CleanupStack::Pop(provider);
+	return provider;
+    }        
+
+
+void CPDPConnectionProvider::StartListener()
+/**
+ * Start listening for dynamic caps or network mode changes.
+ * @param None
+ * @return void
+ */
+	{
+	iDynamicCapsEventListener->NotifyDynamicCapsChange(this);
+	iNetworkModeEventListener->NotifyNetworkModeChange(this);
+	}
+
+void CPDPConnectionProvider::ConstructL()
+/**
+ * PDP Connection Provider Second Phase Constructor
+ * @param None
+ * @return void
+ */
+	{
+	CCoreConnectionProvider::ConstructL(KPDPCPRPreallocatedActivityBufferSize);
+	}
+
+void CPDPConnectionProvider::StopListener()
+/**
+ * Start listening for dynamic caps or network mode changes.
+ */
+	{
+	if(iDynamicCapsEventListener)
+		{
+		iDynamicCapsEventListener->Cancel();
+		}
+	if(iNetworkModeEventListener)
+		{
+		iNetworkModeEventListener->Cancel();
+		}
+	}
+
+CPDPConnectionProvider::CPDPConnectionProvider(ESock::CConnectionProviderFactoryBase& aFactory)
+	: CCoreConnectionProvider(aFactory, PDPCprActivities::activityMap::Self())
+/**
+ * Construct PDP connection provider.
+ */	
+    {        
+    LOG_NODE_CREATE(KESockConnectionTag, CPDPConnectionProvider);
+    }
+
+CPDPConnectionProvider::~CPDPConnectionProvider()
+/**
+ * Destroy PDP connection provider.
+ */
+    {    
+    LOG_NODE_DESTROY(KESockConnectionTag, CPDPConnectionProvider);
+    StopListener();
+	delete iDynamicCapsEventListener;
+	delete iNetworkModeEventListener;
+    }
+    
+void CPDPConnectionProvider::ReceivedL(const Messages::TRuntimeCtxId& aSender, const Messages::TNodeId& aRecipient, Messages::TSignatureBase& aMessage)
+	{
+	//ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aMessage, aRecipient);
+	MeshMachine::TNodeContext<CPDPConnectionProvider> ctx(*this, aMessage, aSender, aRecipient);
+	CCoreConnectionProvider::Received(ctx);
+	User::LeaveIfError(ctx.iReturn);
+	}
+	
+
+void CPDPConnectionProvider::BearerChangeDetectedL()
+/**
+ * Update the parmeter set in case of modulation change and send TPlaneNotification message to
+ * all the control client.
+ */
+	{
+	//Update bearers.
+	UpdateBearer();
+	
+	//Send msg to all control clients
+	CEventParamsChanged* eventChanged = CEventParamsChanged::NewL(KBearerInfo);
+	
+	CleanupStack::PushL(eventChanged);
+	//Create the family and set it to bearer type 
+	XBearerInfo* bearerInfo = XBearerInfo::NewL();
+	CleanupStack::PushL(bearerInfo);
+	
+	bearerInfo->SetBearerType(iBearerType);
+	
+	//Add bearer family to parameter set.
+	eventChanged->AddParameterSetL(KBearerInfo, bearerInfo);
+	CleanupStack::Pop(2,eventChanged);
+	
+	//Create the event node for bearer change notification.
+	CRefCountOwnedNotification* eventNode = new (ELeave) CRefCountOwnedNotification(eventChanged);
+	
+	//Build the CPR plane notification message, which will be retrieved by IPCPR.
+	TCFSubConnControlClient::TPlaneNotification msg(eventNode);
+	
+   	Messages::TClientIter<Messages::TDefaultClientMatchPolicy> iter = this->GetClientIter<Messages::TDefaultClientMatchPolicy>(Messages::TClientType(TCFClientType::ECtrl));
+    Messages::RNodeInterface* ctl;
+	while ((ctl = iter++) != NULL)
+		{
+		msg.iRefCountOwnedNotification->Open();
+		ctl->PostMessage(this->NodeId(), msg);
+		}
+
+	}
+
+
+void CPDPConnectionProvider::UpdateBearer()
+/**
+ * Update bearer type based on the change of the dynamic caps or network mode.
+ */
+	{
+	//Get dynamic caps
+	TUint dynamicCaps = iDynamicCapsEventListener->DynamicCaps();		
+	//Get network mode
+	RMobilePhone::TMobilePhoneNetworkMode networkMode = iNetworkModeEventListener->NetworkMode();
+	
+	//Resolve the bearer based on both dynamic caps and network mode
+	iBearerType = Bearer(dynamicCaps, networkMode);
+	iBearerSet = ETrue;
+	}
+
+
+TUint32 CPDPConnectionProvider::Bearer(TUint aDynamicCaps, RMobilePhone::TMobilePhoneNetworkMode& aNetworkMode)
+/**
+ * Determine bearer based on dynamic caps and network mode.
+ * @param aDynamicCaps a value of dynamic caps
+ * @param aNetworkMode a value of network mode
+ * @return Type of Bearer
+ *
+ */
+	{
+	
+	if ((aDynamicCaps & RPacketService::KCapsHSUPA) || (aDynamicCaps & RPacketService::KCapsHSDPA))
+		{
+		return KHsdpaBearer;
+		}
+	else if (aDynamicCaps & RPacketService::KCapsEGPRS)
+		{
+		return KEGprsBearer;
+		}
+	else
+		{
+		if(aNetworkMode == RMobilePhone::ENetworkModeGsm)
+			{
+		    return KGprsBearer;
+			}
+		else if(aNetworkMode == RMobilePhone::ENetworkModeWcdma)
+			{
+		    return KUmtsBearer;
+			}
+		else
+			{
+		   	return KDefaultBearer;
+			}
+		}
+	}
+
+
+DEFINE_SMELEMENT(PDPCprStates::TUpdateBundle, NetStateMachine::MStateTransition, PDPCprStates::TContext)
+void PDPCprStates::TUpdateBundle::DoL()
+/**
+ * Process TGetParamsRequest
+ */
+	{
+	// Node receives TGetParamsRequest msg containing the bundle.
+	// Determine current network type - GPRS/EDGE/UMTS/HSDPA and update the bundle.
+	const CTSYProvision& tsyProvision = static_cast<const CTSYProvision&>(iContext.Node().AccessPointConfig().FindExtensionL(
+	        STypeId::CreateSTypeId(CTSYProvision::EUid, CTSYProvision::ETypeId)));
+	if(!iContext.Node().iDynamicCapsEventListener)
+		{
+		iContext.Node().iDynamicCapsEventListener = CPDPCPRDynamicCapsListener::NewL(&tsyProvision);
+		}
+	if (!iContext.Node().iNetworkModeEventListener)
+		{
+		iContext.Node().iNetworkModeEventListener = CPDPCPRNetworkModeListener::NewL(&tsyProvision);
+		}
+
+	if(iContext.Node().iBearerSet == EFalse)
+		{
+		iContext.Node().UpdateBearer();
+		}
+	
+	TCFScpr::TGetParamsRequest& paramRequest = Messages::message_cast<TCFScpr::TGetParamsRequest>(iContext.iMessage);
+	if( (! paramRequest.iFamilyBundle.IsNull()) && (iContext.Node().GetParameterBundle() != paramRequest.iFamilyBundle))
+		{
+		iContext.Node().GetParameterBundle().Open(paramRequest.iFamilyBundle);
+		RParameterFamily family = iContext.Node().GetParameterBundle().FindFamily(KBearerInfo);	
+ 
+		if(!family.IsNull())
+			{
+			XBearerInfo *bearerType = static_cast<XBearerInfo*>(family.FindParameterSet(STypeId::CreateSTypeId(KIpBearerInfoUid, KIpBearerInfoParameterType), RParameterFamily::ERequested));
+		
+			if(bearerType)
+				{
+				bearerType->SetBearerType(iContext.Node().iBearerType);
+				}
+			}
+		}
+
+	if(iContext.Node().iDynamicCapsEventListener->IsDynamicCapsSupported())
+		{
+		// if Dynamic Caps supported, start listener, which would Notify of Dynamic Caps change
+		// no check required for network mode, since atleast one network mode is supported.
+		iContext.Node().StartListener();
+		}
+	}
+
+