diff -r 000000000000 -r 3553901f7fa8 telephonyprotocols/pdplayer/src/PDPCPR.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pdpprovision.h" +#include +#include +#include "pdpcpravailabilitylistener.h" +#include +#include +#include +#include +#include +#include + +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 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 iter = this->GetClientIter(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(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(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(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(); + } + } + +