|
1 // Copyright (c) 1997-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 // |
|
15 |
|
16 #include <comms-infras/ss_log.h> |
|
17 #include <ss_std.h> |
|
18 #include <ss_glob.h> |
|
19 #include "SS_conn.H" |
|
20 #include "ss_subconn.h" |
|
21 |
|
22 #include <comms-infras/ss_subconnflow.h> |
|
23 #include <comms-infras/ss_roles.h> |
|
24 #include <comms-infras/ss_tiermanagerutils.h> |
|
25 #include "ss_flowrequest.h" |
|
26 #include <comms-infras/ss_esockstates.h> |
|
27 #include "ss_flowrequeststates.h" |
|
28 #include <comms-infras/ss_tiermanager.h> |
|
29 #include <comms-infras/ss_corepractivities.h> |
|
30 #include <cs_subconparams.h> |
|
31 |
|
32 #include <comms-infras/ss_nodemessages_serviceprovider.h> |
|
33 #include <elements/nm_messages_child.h> |
|
34 #include "ss_internal_activities.h" |
|
35 |
|
36 |
|
37 #ifdef _DEBUG |
|
38 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
39 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
40 _LIT(KSpecAssert_ESockSSockFlwRq, "ESockSSockFlwRq"); |
|
41 #endif |
|
42 |
|
43 using namespace ESock; |
|
44 using namespace NetStateMachine; |
|
45 using namespace FlowRequestStates; |
|
46 using namespace FlowRequestActivities; |
|
47 using namespace Messages; |
|
48 using namespace MeshMachine; |
|
49 |
|
50 namespace FlowRequestDestroyActivity |
|
51 { |
|
52 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDestroy, FlowRequestDestroy, TEChild::TDestroy, FlowRequestActivities::CFlowRequestDestroyActivity::New) |
|
53 FIRST_NODEACTIVITY_ENTRY(MeshMachine::TAwaitingDestroy, MeshMachine::TNoTag) |
|
54 THROUGH_NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TRemoveRequestor, MeshMachine::TNoTag) |
|
55 //TCFSubConnFlowRequest adds subconnection as a control provider so remove if necessary |
|
56 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingAndRemoveControlProvider, MeshMachine::TNoTag) |
|
57 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TLeaveServiceProvidersOrSetIdle, MeshMachine::TNoTag) |
|
58 //TDestroyAwaitingLeaveCompleteLoop loops back to its own triple if more SPs |
|
59 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSetIdleIfNoServiceProviders, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards) |
|
60 LAST_NODEACTIVITY_ENTRY(KNoTag, CoreStates::TAbortAllActivities) |
|
61 NODEACTIVITY_END() |
|
62 } |
|
63 |
|
64 namespace ImplicitFlowActivity |
|
65 { |
|
66 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityImplicitFlow, ImplicitFlow, TCFInternalEsock::TFlowRequest, FlowRequestActivities::CFlowRequestActivity::NewL) |
|
67 FIRST_NODEACTIVITY_ENTRY(FlowRequestStates::TAwaitingImplicitFlowRequest, MeshMachine::TNoTag) |
|
68 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CFlowRequestActivity::TStoreFlowParams, MeshMachine::TNoTag) |
|
69 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TRequestCSRCreation, CoreNetStates::TAwaitingCSRCreated, MeshMachine::TNoTag) |
|
70 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TSelectMetaPlane, CoreNetStates::TAwaitingBindTo, MeshMachine::TNoTag) |
|
71 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendControlClientJoinRequest, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag) |
|
72 NODEACTIVITY_ENTRY(KNoTag, CoreActivities::ABindingActivity::TSendBindToCompleteAndRequestCommsBinder, CoreNetStates::TAwaitingBinderResponse,MeshMachine::TNoTag) |
|
73 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TJoinReceivedSCpr, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag) |
|
74 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::ABindingActivity::TSendBindToComplete, MeshMachine::TNoTag) |
|
75 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TRequestCommsBinderFromSCpr, CoreNetStates::TAwaitingBinderResponse, MeshMachine::TNoTag) |
|
76 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendBindTo, CoreNetStates::TAwaitingBindToComplete, MeshMachine::TNoTag) |
|
77 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::ABindingActivity::TSendBindToComplete, MeshMachine::TNoTag) |
|
78 //Cleanup |
|
79 THROUGH_NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TRemoveRequestor, MeshMachine::TNoTag) |
|
80 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TLeaveServiceProvidersOrSetIdle, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag) |
|
81 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSetIdleIfNoServiceProviders, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards) |
|
82 LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) |
|
83 NODEACTIVITY_END() |
|
84 } |
|
85 |
|
86 namespace ConnectionFlowActivity |
|
87 { |
|
88 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionFlow, ConnectionFlow, TCFInternalEsock::TFlowRequest, FlowRequestActivities::CFlowRequestActivity::NewL) |
|
89 FIRST_NODEACTIVITY_ENTRY(FlowRequestStates::TAwaitingConnFlowRequest, MeshMachine::TNoTag) |
|
90 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CFlowRequestActivity::TStoreFlowParams, MeshMachine::TNoTag) |
|
91 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TJoinCpr, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag) |
|
92 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TRequestCommsBinder, CoreNetStates::TAwaitingBinderResponse, MeshMachine::TNoTag) |
|
93 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TJoinReceivedSCpr, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag) |
|
94 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::ABindingActivity::TSendBindToComplete, MeshMachine::TNoTag) |
|
95 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TRequestCommsBinderFromSCpr, CoreNetStates::TAwaitingBinderResponse, MeshMachine::TNoTag) |
|
96 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendBindTo, CoreNetStates::TAwaitingBindToComplete,MeshMachine::TNoTag) |
|
97 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::ABindingActivity::TSendBindToComplete, MeshMachine::TNoTag) |
|
98 //Cleanup |
|
99 THROUGH_NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TRemoveRequestor, MeshMachine::TNoTag) |
|
100 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TLeaveServiceProvidersOrSetIdle, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag) |
|
101 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSetIdleIfNoServiceProviders, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards) |
|
102 LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) |
|
103 NODEACTIVITY_END() |
|
104 } |
|
105 |
|
106 namespace SubConnectionFlowActivity |
|
107 { |
|
108 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivitySubConnectionFlow, SubConnectionFlow, TCFInternalEsock::TFlowRequest, FlowRequestActivities::CFlowRequestActivity::NewL) |
|
109 FIRST_NODEACTIVITY_ENTRY(FlowRequestStates::TAwaitingSubConnFlowRequest, MeshMachine::TNoTag) |
|
110 |
|
111 // Send TNoBearer to CSubConnection and wait for TBindTo? |
|
112 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CFlowRequestActivity::TStoreFlowParams, MeshMachine::TNoTag) |
|
113 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TJoinSubConnection, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag) |
|
114 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TSendNoBearer, MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingBindTo>, MeshMachine::TNoTagOrErrorTag) |
|
115 |
|
116 // NoBearer Succeeded |
|
117 // Forward TBindTo to the socket itself. After all it is the one to do the binding |
|
118 NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TForwardBindToMsgToOriginator, CoreNetStates::TAwaitingBindToComplete, MeshMachine::TNoTag) |
|
119 THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TClearError, MeshMachine::TNoTag) // The socket will error the client. Allow the BindToComplete to finish naturally. |
|
120 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::ABindingActivity::TSendBindToComplete, MeshMachine::TNoTag) |
|
121 |
|
122 // Cleanup |
|
123 THROUGH_NODEACTIVITY_ENTRY(KNoTag, FlowRequestStates::TRemoveRequestor, MeshMachine::TNoTag) |
|
124 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TLeaveServiceProvidersOrSetIdle, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag) |
|
125 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSetIdleIfNoServiceProviders, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards) |
|
126 LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) |
|
127 |
|
128 // There was an error from the NoBearer request so lets clean up |
|
129 NODEACTIVITY_ENTRY(KErrorTag, FlowRequestStates::TLeaveSubConnection, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag) |
|
130 LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TRaiseAndClearActivityError) |
|
131 NODEACTIVITY_END() |
|
132 } |
|
133 |
|
134 namespace FlowRequestActivities |
|
135 { |
|
136 DECLARE_DEFINE_ACTIVITY_MAP(flowRequestActivities) |
|
137 ACTIVITY_MAP_ENTRY(CoreErrorActivity, CoreError) |
|
138 ACTIVITY_MAP_ENTRY(ImplicitFlowActivity, ImplicitFlow) |
|
139 ACTIVITY_MAP_ENTRY(ConnectionFlowActivity, ConnectionFlow) |
|
140 ACTIVITY_MAP_ENTRY(SubConnectionFlowActivity, SubConnectionFlow) |
|
141 ACTIVITY_MAP_ENTRY(FlowRequestDestroyActivity, FlowRequestDestroy) |
|
142 ACTIVITY_MAP_END() |
|
143 } |
|
144 |
|
145 CFlowRequest::CFlowRequest(TSubSessionUniqueId aSubSessionUniqueId) |
|
146 : ACFMMNodeIdBase(FlowRequestActivities::flowRequestActivities::Self()), |
|
147 ASubSessionPlatsecApiExt(aSubSessionUniqueId), |
|
148 TIfStaticFetcherNearestInHierarchy(this) |
|
149 { |
|
150 LOG_NODE_CREATE(KESockFlowTag, CFlowRequest); |
|
151 } |
|
152 |
|
153 CFlowRequest::~CFlowRequest() |
|
154 { |
|
155 // We own the flow parameters sent to us and need to close them but |
|
156 // it is possible for the pointer to be null if the CFlowRequest |
|
157 // is created then destroyed before it is started. This will happen |
|
158 // if e.g., it is popped and destroyed from the cleanup stack due to |
|
159 // the allocation of a second object by the flow requests's creator |
|
160 // causing a leave due to OOM before the flow request could be |
|
161 // started. |
|
162 iFlowParameters.Close(); |
|
163 LOG_NODE_DESTROY(KESockFlowTag, CFlowRequest); |
|
164 __ASSERT_DEBUG(iClients.Count()==0, User::Panic(KSpecAssert_ESockSSockFlwRq, 1)); //Please fix your node. |
|
165 } |
|
166 |
|
167 void CFlowRequest::Received(TNodeContextBase& aContext) |
|
168 { |
|
169 TNodeSignal::TMessageId noPeerIds[] = { |
|
170 TCFInternalEsock::TFlowRequest::Id(), |
|
171 TNodeSignal::TMessageId() |
|
172 }; |
|
173 MeshMachine::AMMNodeBase::Received(noPeerIds, aContext); |
|
174 MeshMachine::AMMNodeBase::PostReceived(aContext); |
|
175 } |
|
176 |
|
177 CFlowRequest* CFlowRequest::NewL(TSubSessionUniqueId aSubSessionUniqueId) |
|
178 { |
|
179 CFlowRequest* request = new(ELeave) CFlowRequest(aSubSessionUniqueId); |
|
180 |
|
181 CleanupStack::PushL(request); |
|
182 request->ConstructL(); |
|
183 CleanupStack::Pop(); |
|
184 |
|
185 return request; |
|
186 } |
|
187 |
|
188 void CFlowRequest::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage) |
|
189 { |
|
190 // TODO: TCFMessage::TConnectionGoingDown - If this message is received |
|
191 // a new flow request needs to be sent on behalf of the socket, and |
|
192 // this one needs to cleanup/destroy itself. This is for the race condition |
|
193 // where either the idle timer triggers and begin stopping the connection, |
|
194 // or the connection is lost (both resulting in TConnectionGoingDown) while |
|
195 // the flow request is in progress. |
|
196 if (aMessage.IsMessage<TCFMessage::TStateChange>() || |
|
197 aMessage.IsMessage<TCFControlClient::TGoneDown>() ) |
|
198 { |
|
199 // Note of caution: As a control client of providers the CFlowRequest |
|
200 // could be bombarded with messages that we have no interest in. |
|
201 // TStateChange is one, but there could be others. Due to the nature |
|
202 // of the mesh machine if we don't handle them it will forward them |
|
203 // to the CSocket which only expects a limited set of messages from |
|
204 // the CFlowRequest. The CSocket wont like the messages and its not |
|
205 // great for performance to forward them unnecessarily so try to kill |
|
206 // them off here. |
|
207 aMessage.ClearMessageId(); |
|
208 return; |
|
209 } |
|
210 |
|
211 TNodeContext<CFlowRequest> ctx(*this, aMessage, aSender, aRecipient); |
|
212 CFlowRequest::Received(ctx); |
|
213 User::LeaveIfError(ctx.iReturn); |
|
214 } |
|
215 |
|
216 void CFlowRequest::ReturnInterfacePtrL(MPlatsecApiExt*& aInterface) |
|
217 { |
|
218 aInterface = this; |
|
219 } |
|
220 |
|
221 CImplicitFlowRequest::CImplicitFlowRequest(TSubSessionUniqueId aSubSessionUniqueId, const TNodeId& aTierManagerFC, TUid aTierId) |
|
222 : CFlowRequest(aSubSessionUniqueId), |
|
223 iTierManagerFC(aTierManagerFC), |
|
224 iTierId(aTierId) |
|
225 { |
|
226 __ASSERT_DEBUG(!iTierManagerFC.IsNull() && iTierId.iUid!=0, User::Panic(KSpecAssert_ESockSSockFlwRq, 2)); |
|
227 LOG_NODE_CREATE(KESockFlowTag, CImplicitFlowRequest); |
|
228 } |
|
229 |
|
230 CImplicitFlowRequest::~CImplicitFlowRequest() |
|
231 { |
|
232 LOG_NODE_DESTROY(KESockFlowTag, CImplicitFlowRequest); |
|
233 if (!iCSR.IsNull()) |
|
234 { |
|
235 RNodeInterface::OpenPostMessageClose(Id(), iCSR, TEChild::TDestroy().CRef()); |
|
236 iCSR.SetNull(); |
|
237 } |
|
238 } |
|
239 |
|
240 CImplicitFlowRequest* CImplicitFlowRequest::NewL(TSubSessionUniqueId aSubSessionUniqueId, const TNodeId& aTierManagerFC, TUid aTierId) |
|
241 { |
|
242 CImplicitFlowRequest* request = new(ELeave) CImplicitFlowRequest(aSubSessionUniqueId, aTierManagerFC, aTierId); |
|
243 |
|
244 CleanupStack::PushL(request); |
|
245 request->ConstructL(); |
|
246 CleanupStack::Pop(); |
|
247 |
|
248 return request; |
|
249 } |
|
250 |
|
251 // |
|
252 //TCFFlowRequestBase |
|
253 TCFFlowRequestBase::TCFFlowRequestBase(TSubSessionUniqueId aSubSessionUniqueId) |
|
254 : iSubSessionUniqueId(aSubSessionUniqueId), iFlowParams() |
|
255 { |
|
256 } |
|
257 |
|
258 // |
|
259 //TCFImplicitFlowRequest |
|
260 void TCFImplicitFlowRequest::StartL(const TNodeId& aSender, const Messages::ANode& aItf) |
|
261 { |
|
262 TUid tierId = TierManagerUtils::MapTierIdsForLegacyImplicitFlowsL( |
|
263 TUid::Uid(iFlowParams.iAddrFamily), |
|
264 iFlowParams.iProtocol |
|
265 ); |
|
266 |
|
267 CImplicitFlowRequest* req = CImplicitFlowRequest::NewL(iSubSessionUniqueId, aItf.NodeId(),tierId); |
|
268 CleanupStack::PushL(req); |
|
269 req->AddClientL(aSender, TClientType(TCFClientType::ECtrl)); |
|
270 TCFInternalEsock::TFlowRequest msg(iFlowParams); |
|
271 req->ReceivedL(aSender, req->Id(), msg); //trigger the activity |
|
272 CleanupStack::Pop(req); |
|
273 } |
|
274 |
|
275 void TCFImplicitFlowRequest::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient) |
|
276 { |
|
277 const TNodeId& nodeId = address_cast<const TNodeId>(aRecipient); //This message type operates on nodes |
|
278 __ASSERT_DEBUG(nodeId==SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)), User::Panic(KSpecAssert_ESockSSockFlwRq, 3)); //Implicit socket -> Must be dispatched on the TMF container! |
|
279 StartL(address_cast<TNodeId>(aSender), nodeId.Node()); |
|
280 } |
|
281 |
|
282 // |
|
283 //TCFConnFlowRequest |
|
284 void TCFConnFlowRequest::StartL(const TNodeId& aSender) |
|
285 { |
|
286 __ASSERT_DEBUG(iSession, User::Panic(KSpecAssert_ESockSSockFlwRq, 4)); |
|
287 CConnection* cn = iSession->CConnectionFromHandle(iHandle); |
|
288 User::LeaveIfError(cn? KErrNone : KErrBadHandle); |
|
289 |
|
290 RNodeInterface* cnsp = cn->ServiceProvider(); |
|
291 User::LeaveIfError(cnsp? KErrNone : KErrNotReady); |
|
292 |
|
293 CFlowRequest* req = CFlowRequest::NewL(iSubSessionUniqueId); |
|
294 CleanupStack::PushL(req); |
|
295 req->AddClientL(aSender, TClientType(TCFClientType::ECtrl)); |
|
296 req->AddClientL(cnsp->RecipientId(), TClientType(TCFClientType::EServProvider, TCFClientType::EActive)); |
|
297 TCFInternalEsock::TFlowRequest msg(iFlowParams); //Message to triger flow activity |
|
298 req->ReceivedL(aSender, req->Id(), msg); |
|
299 CleanupStack::Pop(req); |
|
300 } |
|
301 |
|
302 void TCFConnFlowRequest::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient) |
|
303 { |
|
304 const TNodeId& nodeId = address_cast<const TNodeId>(aRecipient); //This message type operates on nodes |
|
305 __ASSERT_DEBUG(nodeId==SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::EConnPlane)), User::Panic(KSpecAssert_ESockSSockFlwRq, 5)); //Should be dispatched on the Connection Plane container! |
|
306 StartL(address_cast<TNodeId>(aSender)); |
|
307 } |
|
308 |
|
309 // |
|
310 //TCFSubConnFlowRequest |
|
311 void TCFSubConnFlowRequest::StartL(const TNodeId& aSender) |
|
312 { |
|
313 __ASSERT_DEBUG(iSession, User::Panic(KSpecAssert_ESockSSockFlwRq, 6)); |
|
314 CSubConnection* scn = iSession->CSubConnectionFromHandle(iHandle); |
|
315 User::LeaveIfError(scn ? KErrNone : KErrBadHandle); |
|
316 |
|
317 CFlowRequest* req = CFlowRequest::NewL(iSubSessionUniqueId); |
|
318 CleanupStack::PushL(req); |
|
319 req->AddClientL(aSender, TClientType(TCFClientType::ECtrl)); |
|
320 |
|
321 // Formerly, the top level SCPR would have been set as the service provider to the flow request |
|
322 // Instead we will apply the subconnection itself as the control provider so that we can instead drive it with TNoBearer |
|
323 req->AddClientL(scn->Id(), TClientType(TCFClientType::ECtrlProvider, TCFClientType::EDefault)); |
|
324 TCFInternalEsock::TFlowRequest msg(iFlowParams); //Message to triger flow activity |
|
325 req->ReceivedL(aSender, req->Id(), msg); |
|
326 CleanupStack::Pop(req); |
|
327 } |
|
328 |
|
329 void TCFSubConnFlowRequest::DispatchL( const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient) |
|
330 { |
|
331 const TNodeId& nodeId = address_cast<const TNodeId>(aRecipient); //This message type operates on nodes |
|
332 __ASSERT_DEBUG(nodeId==SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ESubConnPlane)), User::Panic(KSpecAssert_ESockSSockFlwRq, 7)); //Should be dispatched on the SubConnection Plane container! |
|
333 StartL(address_cast<TNodeId>(aSender)); |
|
334 } |
|
335 |
|
336 |