diff -r 000000000000 -r af10295192d8 networkcontrol/iptransportlayer/src/ipdeftbasescpr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networkcontrol/iptransportlayer/src/ipdeftbasescpr.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,397 @@ +// 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: +// IP Default Base SubConnection Provider implementation +// +// + +/** + @file + @internalComponent +*/ + +#define SYMBIAN_NETWORKING_UPS + +#include "IPMessages.h" + +#include +#include +#include +#include +#include "ipdeftbasescpr.h" +#include +#include +#include + +#include +#ifdef SYMBIAN_NETWORKING_UPS +#include +#endif + +#ifdef SYMBIAN_TRACE_ENABLE + #define KIPDeftSCprTag KESockSubConnectionTag +#endif // SYMBIAN_TRACE_ENABLE + + +using namespace Messages; +using namespace MeshMachine; +using namespace ESock; +using namespace IPDeftSCprBaseActivities; +using namespace PRActivities; +using namespace CoreNetStates; + +//We reserve space for two preallocated activities that may start concurrently on the default base 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 KIPDeftBaseSCPRPreallocatedActivityBufferSize = KDefaultMaxPreallocatedActivityCount * KMaxPreallocatedActivitySize; + +//-========================================================= +// +// States +// +//-========================================================= +namespace IPBaseSCprStates +{ +DEFINE_SMELEMENT(TAwaitingAddressUpdate, NetStateMachine::MState, IPBaseSCprStates::TContext) +TBool TAwaitingAddressUpdate::Accept() + { + return iContext.iMessage.IsMessage(); + } + +DEFINE_SMELEMENT(TStoreAddressUpdate, NetStateMachine::MStateTransition, IPBaseSCprStates::TContext) +void TStoreAddressUpdate::DoL() + { + RIPDataClientNodeInterface* client = static_cast(iContext.iPeer); + if (NULL == client) + { + User::Leave(KErrNotFound); + } + + TCFIPMessage::TDataClientRouted& addressUpdateMsg = message_cast(iContext.iMessage); + client->iCliDstAddr = addressUpdateMsg.iAddrUpdate.iDestSockAddr; + client->iCliSrcAddr = addressUpdateMsg.iAddrUpdate.iSrcSockAddr; + client->iProtocolId = addressUpdateMsg.iAddrUpdate.iProtocolId; + if (iContext.Node().iIapId == CIpSubConnectionProviderBase::KInvalidIapId) + { + iContext.Node().iIapId = addressUpdateMsg.iAddrUpdate.iIapId; + } + } + +DEFINE_SMELEMENT(TRejoinDataClient, NetStateMachine::MStateTransition, IPBaseSCprStates::TContext) +void TRejoinDataClient::DoL() + { + PRActivities::CRejoinDataClientActivity::TRejoinDataClient sendRejoinReq(iContext); + sendRejoinReq.DoL(); + ASSERT(iContext.iNodeActivity); + PRActivities::CRejoinDataClientActivity* rejoinActivity = + static_cast(iContext.iNodeActivity); + RIPDataClientNodeInterface& dc = + static_cast( + rejoinActivity->iDataClients[rejoinActivity->iDataClients.Count()-1].iDataClient); + TNodeId& newOwner = rejoinActivity->iDataClients[rejoinActivity->iDataClients.Count()-1].iNewOwner; + + RClientInterface::OpenPostMessageClose(dc.RecipientId(), newOwner, + TCFIPMessage::TDataClientRouted(TAddrUpdate(dc.iCliSrcAddr, dc.iCliDstAddr, dc.iProtocolId, iContext.Node().iIapId)).CRef()); + } + + +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW +/* +State waiting for TTransportNotification message which carries TCP Receive window. +*/ +DEFINE_SMELEMENT(TAwaitingTransportNotification, NetStateMachine::MState, IPBaseSCprStates::TContext) +TBool IPBaseSCprStates::TAwaitingTransportNotification::Accept() + { + return iContext.iMessage.IsMessage(); + } +/* +StateTransition which will iterate thru all the data clients, send the TCP receive window size to them. +*/ +DEFINE_SMELEMENT(TSendTransportNotificationToDataClients, NetStateMachine::MStateTransition,IPBaseSCprStates::TContext) +void IPBaseSCprStates::TSendTransportNotificationToDataClients::DoL() + { + + //data client iterator. + //Exclude data clients that are ELeaving otherwise the PostMessage() below will panic. + TClientIter iter = iContext.Node().GetClientIter(TClientType(TCFClientType::EData), TClientType(0, TCFClientType::ELeaving)); + //Data Client number + TInt dataCliNum =NULL; + //Send message to all data clients. + RNodeInterface* dataClient = iter[dataCliNum]; + + TCFMessage::TTransportNotification message; + while (dataClient) + { + //Post messages to the data client. Message will flow to all the data clients i.e. socket flows. + dataClient->PostMessage(iContext.NodeId(), message); + dataCliNum++; + dataClient = iter[dataCliNum]; + } + } +#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + +} + + +//-========================================================= +// +// Activities +// +//-========================================================= + +namespace IPDeftBaseSCprAddressUpdate +{ +DECLARE_DEFINE_NODEACTIVITY(ECFActivityAddressUpdate, IPDeftBaseSCprAddressUpdate, TCFIPMessage::TDataClientRouted) + NODEACTIVITY_ENTRY(KNoTag, IPBaseSCprStates::TStoreAddressUpdate, IPBaseSCprStates::TAwaitingAddressUpdate, MeshMachine::TNoTag) +NODEACTIVITY_END() +} + +namespace IPDeftSCprRejoinDataClient +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityRejoin, IPDeftSCprRejoin, TCFRejoiningProvider::TRejoinDataClientRequest, PRActivities::CRejoinDataClientActivity::NewL) + // If an SCprNoBearer is being processed (e.g. RSocket::Connect()) when IPDeftSCprRejoin is started (RSubConnection::AddSocket()), + // park until the SCprNoBearer completes. This ensures that the EStarting flag (set temporarily during SCprNoBearer) + // is not inadvertantly propagated (via the DataClientJoiningRequest message) to the receiving SCpr. If this happens, + // EStarting will never get reset on the receiving SCpr and can cause activities (like PRDataClientStop) to park + // permanently on that SCpr. + FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientRejoin, CoreNetStates::TNoTagBlockedByNoBearer) + NODEACTIVITY_ENTRY(KNoTag, IPBaseSCprStates::TRejoinDataClient, PRActivities::CRejoinDataClientActivity::TAwaitingJoinComplete, MeshMachine::TNoTag) + NODEACTIVITY_ENTRY(CoreStates::KLoopTag, IPBaseSCprStates::TRejoinDataClient, PRActivities::CRejoinDataClientActivity::TAwaitingJoinComplete, MeshMachine::TNoTag) + + NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendRejoinComplete, CoreNetStates::TAwaitingDataClientRejoinOrApplyOrCancel, PRActivities::CRejoinDataClientActivity::TRejoinLoopTag) + NODEACTIVITY_ENTRY(KNoTag, PRActivities::CRejoinDataClientActivity::TApplyRejoin, CoreNetStates::TAwaitingApplyResponse, MeshMachine::TNoTag) +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendApplyResponse) +#else + LAST_NODEACTIVITY_ENTRY(KNoTag, SCprStates::TSendApplyResponse) +#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW +NODEACTIVITY_END() +} + +namespace IPDeftBaseSCprBinderRequestActivity +{ +DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBinderRequest, IPDeftBaseSCprBinderRequest, TCFServiceProvider::TCommsBinderRequest, CCommsBinderActivity::NewL) + FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBinderRequest, TNoTagOrUseExistingOrPermissionDenied) + + NODEACTIVITY_ENTRY(KNoTag, PRStates::TCreateDataClient, CoreNetStates::TAwaitingDataClientJoin, MeshMachine::TNoTag) + + // Below this point we need to modify the error handling approach. If we're getting a TError on TBinderResponse, + // this means the client requesting the binder couldn't bind to it. As far as the client is concerned, this + // activity is finished (it has flagged an error). The standard error handling will result in erroring + // the originator. In this case we shouoldn't error the originator, instead, wrap up quietly. + THROUGH_NODEACTIVITY_ENTRY(KNoTag, CCommsBinderActivity::TProcessDataClientCreation, MeshMachine::TTag) + + NODEACTIVITY_ENTRY(CoreStates::KUseExisting, CCommsBinderActivity::TSendBinderResponse, CCommsBinderActivity::TAwaitingBindToComplete, MeshMachine::TNoTagOrErrorTag) + LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) + LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TClearError) + LAST_NODEACTIVITY_ENTRY(KPermissionDenied, MeshMachine::TRaiseAndClearActivityError) +NODEACTIVITY_END() +} + +namespace IPDeftBaseSCprBinderRequestActivity +{ +const TUint32 KSIPSecureId = 270490934; +const TUint32 KDHCPSecureId = 270522821; +const TUint32 KDNSSecureId = 268437634; + +DEFINE_SMELEMENT(TNoTagOrUseExistingOrPermissionDenied, NetStateMachine::MStateFork, TContext) +TInt TNoTagOrUseExistingOrPermissionDenied::TransitionTag() + { + ASSERT(iContext.iNodeActivity); + + // have to cast the context sicne we're inheriting + NetStateMachine::TContextAccessor ctxAccessor(iContext); + + if (ctxAccessor.Context().Node().ImsFlag()) + { + TSecureId secureId = 0; + MPlatsecApiExt* extn = NULL; + TRAPD(err, extn = reinterpret_cast(address_cast(iContext.iSender).Node().FetchNodeInterfaceL(MPlatsecApiExt::KInterfaceId))); + if (err == KErrNone || extn != NULL) + { + if ((extn->SecureId(secureId) != KErrNone) || + (secureId.iId != KSIPSecureId && secureId.iId != KDHCPSecureId && secureId.iId != KDNSSecureId)) + { + iContext.iNodeActivity->SetError(KErrPermissionDenied); + return KPermissionDenied; + } + } + } + + return PRActivities::CCommsBinderActivity::TNoTagOrUseExisting::TransitionTag(); + } +} + +namespace IPDeftBaseSCprDataClientStartActivity +{ +DEFINE_SMELEMENT(TGetParams, NetStateMachine::MStateTransition, TContext) +void TGetParams::DoL() + { + ASSERT(iContext.iNodeActivity); + if(iContext.Node().ServiceProvider() == NULL) + { + //The service provider could have dissapeared by now. + User::Leave(KErrDied); + } +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(), + TCFScpr::TGetParamsRequest(RCFParameterFamilyBundleC()).CRef()); +#else + iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(), + TCFScpr::TParamsRequest(RCFParameterFamilyBundleC()).CRef()); +#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + } +} + + +namespace IPDeftBaseSCprDataClientStartActivity +{ +DECLARE_DEFINE_NODEACTIVITY(ECFActivityStartDataClient, IPDeftBaseSCprDataClientStart, TCFDataClient::TStart ) + FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, MeshMachine::TNoTag) +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + NODEACTIVITY_ENTRY(KNoTag, IPDeftBaseSCprDataClientStartActivity::TGetParams, CoreNetStates::TAwaitingParamResponse, CoreNetStates::TNoTagOrNoDataClients) +#else + NODEACTIVITY_ENTRY(KNoTag, IPDeftBaseSCprDataClientStartActivity::TGetParams, CoreNetStates::TAwaitingParamResponse, MeshMachine::TNoTag) + THROUGH_NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStoreParams, CoreNetStates::TNoTagOrNoDataClients) +#endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + NODEACTIVITY_ENTRY(KNoTag, PRStates::TStartDataClients, CoreNetStates::TAwaitingDataClientsStarted, MeshMachine::TTag) + LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClients, PRStates::TSendDataClientStarted) +NODEACTIVITY_END() +} + +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + +/* +Custom activity which waits for TTransportNotification message from IPCPR. +Stores the TCP receive window size in pointer appended to TProvisionConfig +and sends the window to all data clients. +*/ +namespace IPDeftBaseSCPRBearerCharActivity +{ +DECLARE_DEFINE_NODEACTIVITY(IPDeftSCprBaseActivities::ECFActivityReceiveWin, IPDeftBaseSCPRBearerCharActivity, TCFMessage::TTransportNotification) + FIRST_NODEACTIVITY_ENTRY(IPBaseSCprStates::TAwaitingTransportNotification, MeshMachine::TNoTag) + THROUGH_NODEACTIVITY_ENTRY(KNoTag, IPBaseSCprStates::TSendTransportNotificationToDataClients, MeshMachine::TNoTag) + LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) +NODEACTIVITY_END() +} + +#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + +namespace IPDeftSCprBaseActivities +{ +DEFINE_ACTIVITY_MAP(ipscprbaseActivityMap) + ACTIVITY_MAP_ENTRY(IPDeftSCprRejoinDataClient, IPDeftSCprRejoin) + +#ifdef SYMBIAN_NETWORKING_UPS +ACTIVITY_MAP_END_BASE(UpsActivities, upsActivitiesSCpr) +#else +ACTIVITY_MAP_END_BASE(SCprActivities, coreSCprActivities) +#endif +} + + +namespace IPDeftBaseSCprActivities +{ +DEFINE_ACTIVITY_MAP(ipdeftbasescprActivityMap) + ACTIVITY_MAP_ENTRY(IPDeftBaseSCprAddressUpdate, IPDeftBaseSCprAddressUpdate) + ACTIVITY_MAP_ENTRY(IPDeftBaseSCprDataClientStartActivity, IPDeftBaseSCprDataClientStart) + +#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + ACTIVITY_MAP_ENTRY(IPDeftBaseSCPRBearerCharActivity, IPDeftBaseSCPRBearerCharActivity) +#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW + + ACTIVITY_MAP_ENTRY(IPDeftBaseSCprBinderRequestActivity, IPDeftBaseSCprBinderRequest) +ACTIVITY_MAP_END_BASE(IPDeftSCprBaseActivities, ipscprbaseActivityMap) +} + + +//-========================================================= +// +// CIpSubConnectionProviderBase methods +// +//-========================================================= +CIpSubConnectionProviderBase::CIpSubConnectionProviderBase(ESock::CSubConnectionProviderFactoryBase& aFactory, + const MeshMachine::TNodeActivityMap& aActivityMap) +:CCoreSubConnectionProvider(aFactory, aActivityMap), + iIapId(KInvalidIapId) + { + } + +RNodeInterface* CIpSubConnectionProviderBase::NewClientInterfaceL(const TClientType& aClientType, TAny* aClientInfo) + { + if (aClientType.Type() & TCFClientType::EData) + { + return new (ELeave) RIPDataClientNodeInterface(); + } + return CCoreSubConnectionProvider::NewClientInterfaceL(aClientType, aClientInfo); + } + + +//-========================================================= +// +// CIpDefaultBaseSubConnectionProvider methods +// +//-========================================================= +CIpDefaultBaseSubConnectionProvider::~CIpDefaultBaseSubConnectionProvider() + { + LOG_NODE_DESTROY(KIPDeftSCprTag, CIpDefaultBaseSubConnectionProvider); + } + +CIpDefaultBaseSubConnectionProvider::CIpDefaultBaseSubConnectionProvider(ESock::CSubConnectionProviderFactoryBase& aFactory, + const MeshMachine::TNodeActivityMap& aActivityMap) + : CIpSubConnectionProviderBase(aFactory, aActivityMap) + { + LOG_NODE_CREATE(KIPDeftSCprTag, CIpDefaultBaseSubConnectionProvider); + } + +CIpDefaultBaseSubConnectionProvider* CIpDefaultBaseSubConnectionProvider::NewL(ESock::CSubConnectionProviderFactoryBase& aFactory) + { + CIpDefaultBaseSubConnectionProvider* provider = new (ELeave) CIpDefaultBaseSubConnectionProvider(aFactory, IPDeftBaseSCprActivities::ipdeftbasescprActivityMap::Self()); + CleanupStack::PushL(provider); + provider->ConstructL(KIPDeftBaseSCPRPreallocatedActivityBufferSize); + + CleanupStack::Pop(provider); + return provider; + } + +void CIpDefaultBaseSubConnectionProvider::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) + { + TNodeContext ctx(*this, aMessage, aSender, aRecipient); + ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aMessage, aRecipient); + CCoreSubConnectionProvider::ReceivedL(aSender, aRecipient, aMessage); + User::LeaveIfError(ctx.iReturn); + } + +TBool CIpDefaultBaseSubConnectionProvider::ImsFlag() + { + TBool imsFlagSet = EFalse; + if ( iParameterBundle.IsNull() ) + { + return imsFlagSet; + } + + RParameterFamily family=iParameterBundle.FindFamily(KSubConnContextDescrParamsFamily); + if( ! family.IsNull()) + { + CSubConImsExtParamSet* imsExtGranted = static_cast( + family.FindParameterSet(STypeId::CreateSTypeId(KSubCon3GPPExtParamsFactoryUid,KSubConImsExtParamsType), + RParameterFamily::EGranted)); + + if (imsExtGranted) + imsFlagSet = imsExtGranted->GetImsSignallingIndicator(); + } + + return imsFlagSet; + } +