--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/rtp/cfrtp/src/rtpscprstates.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,280 @@
+// 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:
+// RTP SubConnection Provider states/transitions
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include <comms-infras/corescpractivities.h>
+#include <comms-infras/ss_tiermanager.h>
+#include <ss_glob.h>
+#include <comms-infras/ss_nodemessages_factory.h>
+#include <cflog.h>
+
+#include <rtp_uid.h>
+#include <rtp_subconparams.h>
+#include "rtpscprstates.h"
+#include <rtp_subconparams.h>
+#include "rtpprovisioninfo.h"
+#include "rtp_cfmessages.h"
+
+
+using namespace ESock;
+using namespace NetStateMachine;
+using namespace RtpSCprStates;
+using namespace Messages;
+
+
+// Modified to do the following
+// 1.If service provider does not exist, check if RTP
+// 2.1If yes, then send commsBinder Request to Ctrl Provider, if not RTP (ie IP) panic as in original scheme
+// 3.If service provider exists => stacking has already been done, work as original scheme
+DEFINE_SMELEMENT(TSendCommsBinderToCntrlProv, NetStateMachine::MStateTransition,RtpSCprStates::TContext)
+void TSendCommsBinderToCntrlProv::DoL()
+ {
+ RNodeInterface* ctrlProvider = iContext.Node().ControlProvider();
+ ESock::TCFServiceProvider::TCommsBinderRequest commsBinderReq(RSubConnection::EAttachToDefault);
+ iContext.iNodeActivity->PostRequestTo(*ctrlProvider,commsBinderReq);
+ }
+
+DEFINE_SMELEMENT(TNoTagOrErrorTag, NetStateMachine::MStateFork, RtpSCprStates::TContext)
+TInt TNoTagOrErrorTag::TransitionTag()
+ {
+ Messages::TEBase::TError* msg = message_cast<Messages::TEBase::TError>(&iContext.iMessage);
+ if (msg)
+ {
+ iContext.iNodeActivity->SetError(msg->iValue);
+ }
+ /* Now that was not an Error Message so check if it the response to some
+ message we know of. */
+ TRtpMessages::TRtpMessageReadyForBind* prov = message_cast<TRtpMessages::TRtpMessageReadyForBind>(&iContext.iMessage);
+ if (prov)
+ {
+ if(prov->iValue != KErrNone)
+ {
+ iContext.iNodeActivity->SetError(prov->iValue);
+ return MeshMachine::KErrorTag | NetStateMachine::EForward;
+ }
+ else
+ {
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+ }
+ /* Activity not in an error due to the message we received */
+ if (KErrNone==iContext.iNodeActivity->Error())
+ {
+ return MeshMachine::KNoTag | NetStateMachine::EForward;
+ }
+
+ __CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TNoTagOrErrorTag:Returning Error Tag"));
+ /* Default */
+ return MeshMachine::KErrorTag | NetStateMachine::EForward;
+ }
+
+
+/* Overriden TCommsBinderRequest. Transition will send comms-binder with ECreateNew to IpDefScpr. */
+DEFINE_SMELEMENT(TRequestCommsBinder, NetStateMachine::MStateTransition,RtpSCprStates::TContext)
+void TRequestCommsBinder::DoL()
+ {
+ RNodeInterface* sp = iContext.Node().ServiceProvider();
+
+ __ASSERT_DEBUG(sp , User::Panic(KRtpScprPanic, CorePanics::KPanicNoServiceProvider));
+ iContext.iNodeActivity->PostRequestTo(*sp,TCFServiceProvider::TCommsBinderRequest(RSubConnection::ECreateNew,iContext.Node().GetLocalParameterBundle()).CRef());
+ }
+
+/* State which will accept the ProvisionDone message from RTP Flow. */
+DEFINE_SMELEMENT(TAwaitingReadyForBind, NetStateMachine::MState,RtpSCprStates::TContext)
+TBool TAwaitingReadyForBind::Accept()
+ {
+ return iContext.iMessage.IsMessage<TRtpMessages::TRtpMessageReadyForBind>();
+ }
+
+
+DEFINE_SMELEMENT(TSetPostedToFlow, NetStateMachine::MStateTransition,RtpSCprStates::TContext)
+void TSetPostedToFlow::DoL()
+ {
+ RNodeInterface* client = iContext.iNode.FindClient(message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage).iNodeId);
+ /* No need for explicit check. We will not be here if there is no client anyways */
+ iContext.iNodeActivity->SetPostedTo(client->RecipientId());
+ }
+
+
+DEFINE_SMELEMENT(TAwaitingBinderRequest, NetStateMachine::MState, RtpSCprStates::TContext)
+TBool TAwaitingBinderRequest::Accept()
+ {
+ if (! iContext.iMessage.IsMessage<ESock::TCFServiceProvider::TCommsBinderRequest>())
+ {
+ return EFalse;
+ }
+
+ /* Now extract the FlowParams (if present) and store it for sending it along with NoBearer
+ to IpDefScpr */
+ ESock::TCFServiceProvider::TCommsBinderRequest& msg = message_cast<ESock::TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
+
+ /* Only one type of bundle is supported( Whatever is used for RTP will be used by RTCP.
+ If they are different it is an error case [TO BE DONE] Handle these */
+ if(msg.iFamilyBundle.IsNull())
+ {
+ return EFalse;
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+
+
+DEFINE_SMELEMENT(TCreateDataClient, NetStateMachine::MStateTransition,RtpSCprStates::TContext)
+void TCreateDataClient::InitLocalParameterBundleL(CSubConRTPGenericParamSet* aReqGenericParams)
+ {
+ ESock::RCFParameterFamilyBundle &localBundle = iContext.Node().GetOrCreateLocalParameterBundleL();
+
+ /* Also add a TFlowParams to the LocalParametrBundle. This will be used by the lower
+ * SCPR to create the appropriate flows for the APL Protocol
+ */
+ TFlowParams flowParams;
+ /* Currently some values are hardcoded. this will be removed when full migration to
+ * Dynamic Stacking is done
+ */
+ flowParams.iProtocol = aReqGenericParams->GetServiceProtocolID();
+ flowParams.iAddrFamily = KAfInet;
+ flowParams.iSocketType = KSockDatagram; //Or ProtocolManager::FindProtocolL will Leave
+
+ CFlowRequestParameters* pFlowParams = CFlowRequestParameters::NewL();
+ CleanupStack::PushL(pFlowParams);
+ pFlowParams->SetFlowParams(flowParams);
+
+ RParameterFamily family = localBundle.CreateFamilyL(KFlowParametersFamily);
+ family.AddParameterSetL(pFlowParams, RParameterFamily::ERequested);
+ CleanupStack::Pop(pFlowParams);
+ }
+
+void TCreateDataClient::DoL()
+ {
+ ESock::TCFServiceProvider::TCommsBinderRequest* binderReq = message_cast<ESock::TCFServiceProvider::TCommsBinderRequest>(&iContext.iMessage);
+ __ASSERT_DEBUG(binderReq, User::Panic(KRtpScprPanic, CorePanics::KPanicIncorrectMessage));
+
+ /* Parameter bundle is must. Without that RtpScpr should'nt have been created */
+ __ASSERT_DEBUG(!iContext.Node().iParameterBundle.IsNull(), User::Panic(KRtpScprPanic, CorePanics::KPanicPeerMisbehaving));
+
+ RParameterFamily parameterFamily = iContext.Node().iParameterBundle.FindFamily(KProtocolExtensionFamily);
+
+ if(parameterFamily.IsNull())
+ {
+ __CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient IncorrectParameterBundle"));
+ User::Leave(KErrNotSupported);
+ }
+
+ STypeId typeId = STypeId::CreateSTypeId(CSubConRTPParamFactory::iUid, KSubConnRTPGenericParamsType);
+ CSubConRTPGenericParamSet* reqGenericParams = static_cast<CSubConRTPGenericParamSet*>(parameterFamily.FindParameterSet(typeId,RParameterFamily::ERequested));
+ if(0 == reqGenericParams)
+ {
+ __CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient IncorrectParameterBundle"));
+ User::Leave(KErrNotSupported);
+ }
+
+ /* Error cases */
+ if( reqGenericParams->GetServiceProtocolID() != KProtocolInetUdp ||
+ reqGenericParams->GetLowerSubConnType() != RSubConnection::EAttachToDefault ||
+ reqGenericParams->GetProtocolUiDRtp() != TUid::Uid(KRtpFlowImplementationUid))
+ {
+ __CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient IncorrectArguments"));
+ User::Leave(KErrNotSupported);
+ }
+
+ /* There can be only Two DataFlows per SCPR. Should leave if this condition fails */
+ TInt numberOfDefaultDataClient = iContext.Node().CountClients<TDefaultClientMatchPolicy>(ESock::TCFClientType::EData);
+ if(numberOfDefaultDataClient >= 2)
+ {
+ __CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient: Tried to create third flow <ERROR>"));
+ User::Leave(KErrNotSupported);
+ }
+
+ Messages::TNodeId factoryContainer;
+ factoryContainer = SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::EDataPlane));
+
+ __ASSERT_DEBUG(iContext.Node().ControlProvider(), User::Panic(KRtpScprPanic, CorePanics::KPanicNoControlProvider));
+
+ Messages::TNodeId controlProvider = iContext.Node().ControlProvider()->RecipientId();
+ TSubConnOpen::TSubConnType protocolType = TSubConnOpen::EAttachToDefault;
+
+ // Determine what protocol we want the flow factory to create
+ if(binderReq && ! binderReq->iFamilyBundle.IsNull())
+ {
+ // Find the flow parameter family of parameters
+ RParameterFamily parameterFamily = binderReq->iFamilyBundle.FindFamily(KFlowParametersFamily);
+
+ if(!parameterFamily.IsNull())
+ {
+ STypeId typeId = STypeId::CreateSTypeId(CFlowRequestParameters::EUid, CFlowRequestParameters::EType);
+ CFlowRequestParameters* flowParams = static_cast<CFlowRequestParameters*>(parameterFamily.FindParameterSet(typeId, RParameterFamily::ERequested));
+
+ // The type of flow created by the flow factory is dependent only on the protocol type
+ protocolType = (TSubConnOpen::TSubConnType)flowParams->GetFlowParams().iProtocol;
+ }
+ }
+
+ TDefaultFlowFactoryQuery dataClientQuery( controlProvider, iContext.NodeId(),iContext.iMessage.MessageId(), protocolType);
+
+ TCFFactory::TFindOrCreatePeer msg(TCFPlayerRole::EDataPlane, reqGenericParams->GetProtocolUiDRtp(),&dataClientQuery);
+
+ iContext.iNodeActivity->PostRequestTo(factoryContainer, msg);
+
+
+ if(0 == numberOfDefaultDataClient)
+ {
+
+ __CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient Creating Data Flow (1)."));
+
+ InitLocalParameterBundleL(reqGenericParams);
+
+ /* If a Second subconnection is Opened. Then the existing Config should
+ * be removed */
+
+ RMetaExtensionContainer mec;
+ mec.Open(iContext.Node().AccessPointConfig());
+ CleanupClosePushL(mec);
+
+ /* Now add the RTP Creation parameters to the AccessPointconfig() */
+ CRtpProvisionConfig* rtpProvision = CRtpProvisionConfig::NewLC();
+
+ rtpProvision->SetBandWidth(reqGenericParams->BandWidth());
+ rtpProvision->SetRtptimeConversion(reqGenericParams->RtptimeConversion());
+ rtpProvision->SetRtpAutoSend(reqGenericParams->RtpAutoSend());
+ rtpProvision->SetRtpTimeNow(reqGenericParams->RtpTimeNow());
+ rtpProvision->SetCNAMEL(reqGenericParams->GetCNAME());
+ rtpProvision->SetDefDestinationAddr(reqGenericParams->GetDefDestinationAddr());
+ rtpProvision->SetMaxDropOut(reqGenericParams->MaxDropOut());
+ rtpProvision->SetMaxMisorder(reqGenericParams->MaxMisorder());
+ rtpProvision->SetMinSequential(reqGenericParams->MinSequencial());
+ rtpProvision->SetRtcpReportInterval(reqGenericParams->GetRtcpReportInterval());
+
+ mec.AppendExtensionL(rtpProvision);
+
+ /* Ownership no longer with us */
+ CleanupStack::Pop();
+
+ iContext.Node().AccessPointConfig().Close();
+ iContext.Node().AccessPointConfig().Open(mec);
+ CleanupStack::PopAndDestroy(&mec);
+ }
+ else
+ {
+ __CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient Creating Data Flow (2)."));
+ }
+ }