|
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 } |