realtimenetprots/rtp/cfrtp/src/rtpscprstates.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // RTP SubConnection Provider states/transitions
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include <comms-infras/corescpractivities.h>
       
    24 #include <comms-infras/ss_tiermanager.h>
       
    25 #include <ss_glob.h>
       
    26 #include <comms-infras/ss_nodemessages_factory.h>
       
    27 #include <cflog.h>
       
    28 
       
    29 #include <rtp_uid.h>
       
    30 #include <rtp_subconparams.h>
       
    31 #include "rtpscprstates.h"
       
    32 #include <rtp_subconparams.h>
       
    33 #include "rtpprovisioninfo.h" 
       
    34 #include "rtp_cfmessages.h"
       
    35 
       
    36 
       
    37 using namespace ESock;
       
    38 using namespace NetStateMachine;
       
    39 using namespace RtpSCprStates;
       
    40 using namespace Messages;
       
    41 
       
    42 
       
    43 // Modified to do the following
       
    44 // 1.If service provider does not exist, check if RTP
       
    45 // 2.1If yes, then send commsBinder Request to Ctrl Provider, if not RTP (ie IP) panic as in original scheme
       
    46 // 3.If service provider exists => stacking has already been done, work as original scheme
       
    47 DEFINE_SMELEMENT(TSendCommsBinderToCntrlProv, NetStateMachine::MStateTransition,RtpSCprStates::TContext)
       
    48 void TSendCommsBinderToCntrlProv::DoL()
       
    49 	{
       
    50 	RNodeInterface* ctrlProvider = iContext.Node().ControlProvider();
       
    51 	ESock::TCFServiceProvider::TCommsBinderRequest commsBinderReq(RSubConnection::EAttachToDefault);
       
    52 	iContext.iNodeActivity->PostRequestTo(*ctrlProvider,commsBinderReq);
       
    53 	}
       
    54 
       
    55 DEFINE_SMELEMENT(TNoTagOrErrorTag, NetStateMachine::MStateFork, RtpSCprStates::TContext)
       
    56 TInt TNoTagOrErrorTag::TransitionTag()
       
    57 	{
       
    58 	Messages::TEBase::TError* msg = message_cast<Messages::TEBase::TError>(&iContext.iMessage);
       
    59 	if (msg)
       
    60 		{
       
    61 		iContext.iNodeActivity->SetError(msg->iValue);
       
    62 		}
       
    63 	/* Now that was not an Error Message so check if it the response to some
       
    64 	   message we know of. */
       
    65 	TRtpMessages::TRtpMessageReadyForBind* prov = message_cast<TRtpMessages::TRtpMessageReadyForBind>(&iContext.iMessage);
       
    66 	if (prov)
       
    67 		{
       
    68 		if(prov->iValue != KErrNone)
       
    69 			{
       
    70 			iContext.iNodeActivity->SetError(prov->iValue);
       
    71 			return MeshMachine::KErrorTag | NetStateMachine::EForward;
       
    72 			}
       
    73 		else
       
    74 			{
       
    75 			return MeshMachine::KNoTag | NetStateMachine::EForward;	
       
    76 			}
       
    77 		}
       
    78 	/* Activity not in an error due to the message we received */
       
    79 	if (KErrNone==iContext.iNodeActivity->Error())
       
    80 		{
       
    81 		return MeshMachine::KNoTag | NetStateMachine::EForward;
       
    82 		}
       
    83 	
       
    84 	__CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TNoTagOrErrorTag:Returning Error Tag"));
       
    85 	/* Default */
       
    86 	return MeshMachine::KErrorTag | NetStateMachine::EForward;
       
    87 	}
       
    88 
       
    89 
       
    90 /* Overriden TCommsBinderRequest. Transition will send comms-binder with ECreateNew to IpDefScpr. */
       
    91 DEFINE_SMELEMENT(TRequestCommsBinder, NetStateMachine::MStateTransition,RtpSCprStates::TContext)
       
    92 void TRequestCommsBinder::DoL()
       
    93 	{
       
    94 	RNodeInterface* sp = iContext.Node().ServiceProvider();
       
    95 	
       
    96     __ASSERT_DEBUG(sp , User::Panic(KRtpScprPanic, CorePanics::KPanicNoServiceProvider));
       
    97 	iContext.iNodeActivity->PostRequestTo(*sp,TCFServiceProvider::TCommsBinderRequest(RSubConnection::ECreateNew,iContext.Node().GetLocalParameterBundle()).CRef());
       
    98 	}
       
    99 
       
   100 /* State which will accept the ProvisionDone message from RTP Flow. */
       
   101 DEFINE_SMELEMENT(TAwaitingReadyForBind, NetStateMachine::MState,RtpSCprStates::TContext)
       
   102 TBool TAwaitingReadyForBind::Accept()
       
   103 	{
       
   104 	return iContext.iMessage.IsMessage<TRtpMessages::TRtpMessageReadyForBind>();
       
   105 	}
       
   106 	
       
   107 	
       
   108 DEFINE_SMELEMENT(TSetPostedToFlow, NetStateMachine::MStateTransition,RtpSCprStates::TContext)
       
   109 void TSetPostedToFlow::DoL()
       
   110 	{
       
   111 	RNodeInterface* client = iContext.iNode.FindClient(message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage).iNodeId);
       
   112 	/* No need for explicit check. We will not be here if there is no client anyways */
       
   113 	iContext.iNodeActivity->SetPostedTo(client->RecipientId());	
       
   114 	}
       
   115 
       
   116 
       
   117 DEFINE_SMELEMENT(TAwaitingBinderRequest, NetStateMachine::MState, RtpSCprStates::TContext)
       
   118 TBool TAwaitingBinderRequest::Accept()
       
   119 	{
       
   120 	if (! iContext.iMessage.IsMessage<ESock::TCFServiceProvider::TCommsBinderRequest>())
       
   121 		{
       
   122 		return EFalse;
       
   123 		}
       
   124 	
       
   125 	/* Now extract the FlowParams (if present) and store it for sending it along with NoBearer
       
   126 	   to IpDefScpr */
       
   127 	ESock::TCFServiceProvider::TCommsBinderRequest& msg = message_cast<ESock::TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage);
       
   128 
       
   129 	/* Only one type of bundle is supported( Whatever is used for RTP will be used by RTCP.
       
   130       If they are different it is an error case [TO BE DONE] Handle these */
       
   131     if(msg.iFamilyBundle.IsNull())
       
   132     	{
       
   133     	return EFalse;
       
   134     	}
       
   135     else
       
   136     	{
       
   137     	return ETrue;
       
   138     	}
       
   139 	}
       
   140 	
       
   141 	
       
   142 DEFINE_SMELEMENT(TCreateDataClient, NetStateMachine::MStateTransition,RtpSCprStates::TContext)    
       
   143 void TCreateDataClient::InitLocalParameterBundleL(CSubConRTPGenericParamSet* aReqGenericParams)
       
   144 	{
       
   145 	ESock::RCFParameterFamilyBundle &localBundle = iContext.Node().GetOrCreateLocalParameterBundleL();
       
   146 	
       
   147 	/* Also add a TFlowParams to the LocalParametrBundle. This will be used by the lower
       
   148 	 * SCPR to create the appropriate flows for the APL Protocol 
       
   149 	 */
       
   150 	TFlowParams flowParams;
       
   151 	/* Currently some values are hardcoded. this will be removed when full migration to
       
   152 	 * Dynamic Stacking is done 
       
   153 	 */
       
   154 	flowParams.iProtocol   = aReqGenericParams->GetServiceProtocolID();
       
   155 	flowParams.iAddrFamily = KAfInet;
       
   156 	flowParams.iSocketType = KSockDatagram; //Or ProtocolManager::FindProtocolL will Leave
       
   157 	
       
   158 	CFlowRequestParameters* pFlowParams = CFlowRequestParameters::NewL();
       
   159 	CleanupStack::PushL(pFlowParams);
       
   160 	pFlowParams->SetFlowParams(flowParams);
       
   161 
       
   162 	RParameterFamily family = localBundle.CreateFamilyL(KFlowParametersFamily);
       
   163 	family.AddParameterSetL(pFlowParams, RParameterFamily::ERequested);
       
   164 	CleanupStack::Pop(pFlowParams);
       
   165 	}
       
   166 
       
   167 void TCreateDataClient::DoL()
       
   168 	{
       
   169 	ESock::TCFServiceProvider::TCommsBinderRequest* binderReq = message_cast<ESock::TCFServiceProvider::TCommsBinderRequest>(&iContext.iMessage);
       
   170 	__ASSERT_DEBUG(binderReq, User::Panic(KRtpScprPanic, CorePanics::KPanicIncorrectMessage));
       
   171    	
       
   172 	/* Parameter bundle is must. Without that RtpScpr should'nt have been created */
       
   173 	__ASSERT_DEBUG(!iContext.Node().iParameterBundle.IsNull(), User::Panic(KRtpScprPanic, CorePanics::KPanicPeerMisbehaving));
       
   174 	
       
   175 	RParameterFamily parameterFamily =	iContext.Node().iParameterBundle.FindFamily(KProtocolExtensionFamily);
       
   176 
       
   177     if(parameterFamily.IsNull())
       
   178     	{
       
   179  		__CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient IncorrectParameterBundle"));
       
   180 		User::Leave(KErrNotSupported);
       
   181     	}
       
   182     	
       
   183 	STypeId typeId = STypeId::CreateSTypeId(CSubConRTPParamFactory::iUid, KSubConnRTPGenericParamsType);
       
   184 	CSubConRTPGenericParamSet* reqGenericParams = static_cast<CSubConRTPGenericParamSet*>(parameterFamily.FindParameterSet(typeId,RParameterFamily::ERequested));
       
   185 	if(0 == reqGenericParams)
       
   186 		{
       
   187 		__CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient IncorrectParameterBundle"));
       
   188 		User::Leave(KErrNotSupported);
       
   189 		}		
       
   190 	
       
   191 	/* Error cases */
       
   192 	if( reqGenericParams->GetServiceProtocolID() != KProtocolInetUdp ||
       
   193 	    reqGenericParams->GetLowerSubConnType() != RSubConnection::EAttachToDefault ||
       
   194 	    reqGenericParams->GetProtocolUiDRtp() != TUid::Uid(KRtpFlowImplementationUid))
       
   195  		{
       
   196  		__CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient IncorrectArguments"));
       
   197  		User::Leave(KErrNotSupported);
       
   198 	 	}
       
   199 
       
   200 	/* There can be only Two DataFlows per SCPR. Should leave if this condition fails */
       
   201 	TInt numberOfDefaultDataClient = iContext.Node().CountClients<TDefaultClientMatchPolicy>(ESock::TCFClientType::EData);
       
   202 	if(numberOfDefaultDataClient >= 2)
       
   203 		{
       
   204 		__CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient: Tried to create third flow <ERROR>"));
       
   205 		User::Leave(KErrNotSupported);
       
   206 		}
       
   207 
       
   208 	Messages::TNodeId factoryContainer;
       
   209     factoryContainer = SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::EDataPlane));
       
   210     
       
   211     __ASSERT_DEBUG(iContext.Node().ControlProvider(), User::Panic(KRtpScprPanic, CorePanics::KPanicNoControlProvider));
       
   212     
       
   213     Messages::TNodeId controlProvider = iContext.Node().ControlProvider()->RecipientId();			
       
   214     TSubConnOpen::TSubConnType protocolType = TSubConnOpen::EAttachToDefault;
       
   215 	
       
   216 	// Determine what protocol we want the flow factory to create
       
   217 	if(binderReq && ! binderReq->iFamilyBundle.IsNull())
       
   218 		{
       
   219 		// Find the flow parameter family of parameters
       
   220 		RParameterFamily parameterFamily = binderReq->iFamilyBundle.FindFamily(KFlowParametersFamily);
       
   221 
       
   222 		if(!parameterFamily.IsNull())
       
   223 			{
       
   224 			STypeId typeId = STypeId::CreateSTypeId(CFlowRequestParameters::EUid, CFlowRequestParameters::EType);
       
   225 			CFlowRequestParameters* flowParams =	static_cast<CFlowRequestParameters*>(parameterFamily.FindParameterSet(typeId, RParameterFamily::ERequested));
       
   226 
       
   227 			// The type of flow created by the flow factory is dependent only on the protocol type
       
   228 			protocolType = (TSubConnOpen::TSubConnType)flowParams->GetFlowParams().iProtocol;
       
   229 			}
       
   230 		}
       
   231 		
       
   232 	TDefaultFlowFactoryQuery dataClientQuery( controlProvider, iContext.NodeId(),iContext.iMessage.MessageId(), protocolType);
       
   233 	    
       
   234 	TCFFactory::TFindOrCreatePeer msg(TCFPlayerRole::EDataPlane, reqGenericParams->GetProtocolUiDRtp(),&dataClientQuery);
       
   235 		
       
   236 	iContext.iNodeActivity->PostRequestTo(factoryContainer, msg);
       
   237 
       
   238 
       
   239 	if(0 == numberOfDefaultDataClient)
       
   240 		{
       
   241 
       
   242 		__CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient Creating Data Flow (1)."));
       
   243 		
       
   244 		InitLocalParameterBundleL(reqGenericParams);
       
   245 		
       
   246 	    /* If a Second subconnection is Opened. Then the existing Config should
       
   247 		 * be removed */	
       
   248 
       
   249 	    RMetaExtensionContainer mec;
       
   250 		mec.Open(iContext.Node().AccessPointConfig());
       
   251 		CleanupClosePushL(mec);
       
   252 		
       
   253 		/* Now add the RTP Creation parameters to the AccessPointconfig() */
       
   254 	    CRtpProvisionConfig* rtpProvision = CRtpProvisionConfig::NewLC();
       
   255 	    
       
   256 	    rtpProvision->SetBandWidth(reqGenericParams->BandWidth());
       
   257 	    rtpProvision->SetRtptimeConversion(reqGenericParams->RtptimeConversion());
       
   258 	    rtpProvision->SetRtpAutoSend(reqGenericParams->RtpAutoSend());
       
   259 	    rtpProvision->SetRtpTimeNow(reqGenericParams->RtpTimeNow());
       
   260 	    rtpProvision->SetCNAMEL(reqGenericParams->GetCNAME());
       
   261 	    rtpProvision->SetDefDestinationAddr(reqGenericParams->GetDefDestinationAddr());
       
   262 	    rtpProvision->SetMaxDropOut(reqGenericParams->MaxDropOut());
       
   263 	    rtpProvision->SetMaxMisorder(reqGenericParams->MaxMisorder());
       
   264 	    rtpProvision->SetMinSequential(reqGenericParams->MinSequencial());
       
   265 		rtpProvision->SetRtcpReportInterval(reqGenericParams->GetRtcpReportInterval());
       
   266 	    
       
   267 		mec.AppendExtensionL(rtpProvision);
       
   268 		
       
   269 	    /* Ownership no longer with us */
       
   270 	    CleanupStack::Pop();
       
   271 		
       
   272 		iContext.Node().AccessPointConfig().Close();
       
   273 		iContext.Node().AccessPointConfig().Open(mec);
       
   274 		CleanupStack::PopAndDestroy(&mec);
       
   275 		}
       
   276 	else
       
   277 		{
       
   278 		__CFLOG_0(KRTPSCprTag, KRTPSCprSubTag, _L8("TCreateDataClient Creating Data Flow (2)."));
       
   279 		}
       
   280 	}