1 // Copyright (c) 2006-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 // COREPRACTIVITIES.CPP |
|
15 // Core PR Activities |
|
16 // THIS API IS INTERNAL TO NETWORKING AND IS SUBJECT TO CHANGE AND NOT FOR EXTERNAL USE |
|
17 // |
|
18 // |
|
19 |
|
20 /** |
|
21 @file |
|
22 @internalComponent |
|
23 */ |
|
24 |
|
25 #define SYMBIAN_NETWORKING_UPS |
|
26 |
|
27 #include "ss_corepractivities.h" |
|
28 |
|
29 |
|
30 #include <comms-infras/ss_log.h> |
|
31 #include "ss_internal_activities.h" |
|
32 #include <comms-infras/ss_coreprstates.h> |
|
33 #include <comms-infras/ss_subconnprov.h> |
|
34 #include <comms-infras/ss_mcprnodemessages.h> |
|
35 |
|
36 #include <comms-infras/ss_protocolparameterset.h> |
|
37 #include <ss_glob.h> |
|
38 |
|
39 |
|
40 #include <elements/nm_messages_child.h> |
|
41 #include <elements/nm_messages_peer.h> |
|
42 #include <elements/nm_messages_errorrecovery.h> |
|
43 #include "ss_nodemessages_dataclient.h" |
|
44 #include "ss_nodemessages_serviceprovider.h" |
|
45 #include <comms-infras/ss_nodemessages_rejoiningprovider.h> |
|
46 #include <comms-infras/ss_nodemessages_flow.h> |
|
47 #include "ss_nodemessages_factory.h" |
|
48 #include <comms-infras/ss_nodemessages_internal_esock.h> |
|
49 |
|
50 |
|
51 #ifdef _DEBUG |
|
52 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
53 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
54 _LIT(KSpecAssert_ESockCrStaCPRAC, "ESockCrStaCPRAC"); |
|
55 #endif |
|
56 |
|
57 #if defined __CFLOG_ACTIVE || defined ESOCK_EXTLOG_ACTIVE |
|
58 #define KCoreProviderStatesTag KESockCoreProviderTag |
|
59 _LIT8(KCoreProviderStatesSubTag, "coreprovstate"); |
|
60 #endif |
|
61 |
|
62 using namespace NetStateMachine; |
|
63 using namespace CoreStates; |
|
64 using namespace CoreNetStates; |
|
65 using namespace PRStates; |
|
66 using namespace PRActivities; |
|
67 using namespace CoreActivities; |
|
68 using namespace ESock; |
|
69 using namespace CorePanics; |
|
70 using namespace Elements; |
|
71 using namespace Messages; |
|
72 using namespace MeshMachine; |
|
73 using namespace Factories; |
|
74 |
|
75 |
|
76 #ifdef _DEBUG |
|
77 _LIT (KCorePrPanic,"CorePrPanic"); |
|
78 #endif |
|
79 |
|
80 namespace CoreErrorActivity |
|
81 { //Special parallel activity, must be started as the last one |
|
82 DEFINE_EXPORT_CUSTOM_NODEACTIVITY(ECFActivityError, CoreError, TEBase::TError, CErrorActivity::NewL) |
|
83 FIRST_NODEACTIVITY_ENTRY(CErrorActivity::TCFAwaitingError, MeshMachine::TNoTag) |
|
84 NODEACTIVITY_ENTRY(KNoTag, CErrorActivity::TSendErrorRecoveryReq, MeshMachine::TAwaitingMessageState<TEErrorRecovery::TErrorRecoveryResponse>, MeshMachine::TNoTag) |
|
85 LAST_NODEACTIVITY_ENTRY(KNoTag, CErrorActivity::TDoErrorRecovery) |
|
86 NODEACTIVITY_END() |
|
87 } |
|
88 |
|
89 namespace PRProvisionActivity |
|
90 { |
|
91 DECLARE_DEFINE_NODEACTIVITY(ECFActivityStoreProvision, PrProvision, TCFDataClient::TProvisionConfig) |
|
92 NODEACTIVITY_ENTRY(KNoTag, PRStates::TStoreProvision, CoreNetStates::TAwaitingProvision, MeshMachine::TNoTag) |
|
93 NODEACTIVITY_END() |
|
94 } |
|
95 |
|
96 namespace PRControlClientJoinActivity |
|
97 { |
|
98 DEFINE_EXPORT_NODEACTIVITY(ECFActivityClientJoin, PRControlClientJoin, TNodeSignal::TNullMessageId) //May be waiting for both messages |
|
99 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TAddControlClientAndSendJoinCompleteIfRequest, CoreNetStates::TAwaitingControlClientJoin, MeshMachine::TNoTag) |
|
100 NODEACTIVITY_END() |
|
101 } |
|
102 |
|
103 namespace PRDataClientJoinActivity |
|
104 { //This activity needs the activity object (& it can fail on AddClientL, so no point converting) |
|
105 DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientJoin, PRDataClientJoin, TCFPeer::TJoinRequest) |
|
106 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientJoinRequest, MeshMachine::TNoTag) |
|
107 LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TAddDataClientAndRespond) |
|
108 NODEACTIVITY_END() |
|
109 } |
|
110 |
|
111 namespace PRClientLeaveActivity |
|
112 {//This activity will wait for ECFActivityBinderRequest to complete |
|
113 DEFINE_EXPORT_NODEACTIVITY(ECFActivityClientLeave, PRClientLeave, TNodeSignal::TNullMessageId) //May be waiting for both messages |
|
114 NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessClientLeave, CoreStates::TAwaitingClientLeave, MeshMachine::TNoTag) |
|
115 NODEACTIVITY_END() |
|
116 } |
|
117 |
|
118 namespace PRDataClientIdleActivity |
|
119 { |
|
120 DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientIdle, PRDataClientIdle, TCFControlProvider::TIdle) |
|
121 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::THandleDataClientIdle, CoreNetStates::TAwaitingDataClientIdle, MeshMachine::TNoTag) |
|
122 NODEACTIVITY_END() |
|
123 } |
|
124 |
|
125 namespace PRDataClientActiveActivity |
|
126 { |
|
127 DEFINE_EXPORT_NODEACTIVITY(ECFActivityDataClientActive, PRDataClientActive, TCFControlProvider::TActive) |
|
128 NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TAwaitingDataClientActive, MeshMachine::TNoTag) |
|
129 NODEACTIVITY_END() |
|
130 } |
|
131 |
|
132 namespace PRDestroyActivity |
|
133 { |
|
134 //The generic Destroy activity. Carries out the node's goodbye handshake. |
|
135 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDestroy, PRDestroy, TEChild::TDestroy, CoreActivities::CDestroyActivity::New) |
|
136 FIRST_NODEACTIVITY_ENTRY(MeshMachine::TAwaitingDestroy, CoreActivities::CDestroyActivity::TNoTagBlockedByActivitiesOrLeavingDataClient) |
|
137 |
|
138 //Stop self first |
|
139 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, CoreStates::TNoTagOrNoClients) |
|
140 |
|
141 //The node mustn't go out of scope with clients present. The node must get rid of them first. |
|
142 NODEACTIVITY_ENTRY(KNoTag, CoreActivities::CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave, CoreStates::TAwaitingClientLeave, CDestroyActivity::TNoTagOrNoTagBackwards) |
|
143 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreActivities::CDestroyActivity::TProcessClientLeave, TTag<KNoClients>) |
|
144 |
|
145 THROUGH_NODEACTIVITY_ENTRY(KNoClients, PRStates::TProcessDestroy, MeshMachine::TNoTag) |
|
146 NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingLeaveComplete, CoreActivities::CDestroyActivity::TNoTagOrNoTagBackwards) |
|
147 LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingAndRemoveControlProvider) |
|
148 NODEACTIVITY_END() |
|
149 } |
|
150 |
|
151 namespace PRSetParamsRequest |
|
152 { |
|
153 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW |
|
154 DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRSetParams, TCFScpr::TSetParamsRequest) |
|
155 FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent) |
|
156 NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, MeshMachine::TTag<CoreNetStates::KBearerPresent>) |
|
157 LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TStoreParamsAndPostToOriginators) |
|
158 LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TStoreAndRespondWithCurrentParams) |
|
159 NODEACTIVITY_END() |
|
160 #else |
|
161 DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRSetParams, TNodeSignal::TNullMessageId) |
|
162 NODEACTIVITY_END() |
|
163 #endif |
|
164 } |
|
165 |
|
166 // no Store in case of GetParamsRequest |
|
167 namespace PRGetParamsRequest |
|
168 { |
|
169 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW |
|
170 DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRGetParams, TCFScpr::TGetParamsRequest) |
|
171 FIRST_NODEACTIVITY_ENTRY(PRStates::TAwaitingParamRequest, CoreNetStates::TNoTagOrBearerPresent) |
|
172 NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, PRStates::TPassToServiceProvider, CoreNetStates::TAwaitingParamResponse, MeshMachine::TTag<CoreNetStates::KBearerPresent>) |
|
173 LAST_NODEACTIVITY_ENTRY(CoreNetStates::KBearerPresent, CoreStates::TPostToOriginators) |
|
174 LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TRespondWithRetrievedParams) |
|
175 NODEACTIVITY_END() |
|
176 #else |
|
177 DEFINE_EXPORT_NODEACTIVITY(ECFActivityParamRequest, PRGetParams, TNodeSignal::TNullMessageId) |
|
178 NODEACTIVITY_END() |
|
179 #endif |
|
180 } |
|
181 |
|
182 namespace PRBindToActivity |
|
183 { |
|
184 //PRBindToActivity is responsible for handling TCFDataClient::TBindTo; |
|
185 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBindTo, PRBindTo, TCFDataClient::TBindTo, CBindToActivity::NewL) |
|
186 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBindTo, CBindToActivity::TNoTagOrBearerReady) |
|
187 //TBindTo can hold: |
|
188 //[KNoTag] - a valid serviceProvider cookie that this node isn't bound to; |
|
189 //[KBearerReady] - a valid serviceProvider cookie that this node is already bound to; |
|
190 //[KBearerReady] - a NULL serviceProvider (this node is at the stack's bottom); |
|
191 |
|
192 //{ JOINING NEW SERVICE PROVIDER |
|
193 //a valid serviceProvider supplied, new to this node, let's join it; |
|
194 NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TSendControlClientJoinRequest, CoreStates::TAwaitingJoinComplete, TTag<KBearerReady>) |
|
195 //} |
|
196 |
|
197 //serviceProvider provisionally joined. Now the activity needs to propagate iteslf (TBindTo) to its dataclients. |
|
198 //The dataclients are either present or not. If not this activity will assume this is the layer construction phase |
|
199 //and will attempt to construct a default dataclient. |
|
200 THROUGH_NODEACTIVITY_ENTRY(KBearerReady, MeshMachine::TDoNothing, CBindToActivity::TNoTagOrDataClientReady) |
|
201 |
|
202 //{ DATA CLIENT CREATION |
|
203 //No dataclients present, assume this is the layer creation phase. Attempt to create a dataclient. |
|
204 NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TCreateDataClient, TAcceptErrorState<CoreNetStates::TAwaitingDataClientJoin>, MeshMachine::TErrorTagOr<CBindToActivity::TNoTagOrBindToComplete>) |
|
205 //BindTo activity is the pre-start layer builder, hence it always requests the dataclient from the factory. |
|
206 //The factory (being aware of the phase) may decide to: |
|
207 //1. create a new dataclient -> process dataclient creation [KNoTag] |
|
208 //2. return a preexisting dataclient -> bind the client [KDataClientReady] |
|
209 //3. not to create a dataclient -> send TBindToComplete to the originator [KBindToComplete] |
|
210 THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessDataClientCreation, TTag<KDataClientReady>) |
|
211 //} |
|
212 |
|
213 THROUGH_NODEACTIVITY_ENTRY(KDataClientReady, MeshMachine::TDoNothing, CBindToActivity::TNoTagOrBearerReadyOrBindToComplete) |
|
214 //{ BINDING DATACLIENTS LOOP |
|
215 //Dataclient(s) is/are ready. Depending on whether the node has the lower layer or not, |
|
216 //we will [KNoTag] or will not [KNoBearer] need to request a binder for the dataclient. |
|
217 |
|
218 //{SERVICE PROVIDER PRESENT |
|
219 NODEACTIVITY_ENTRY(KNoTag, CBindToActivity::TRequestCommsBinder, TAcceptErrorState<CoreNetStates::TAwaitingBinderResponse>, TErrorTagOr<TTag<KBearerReady> >) |
|
220 //} |
|
221 NODEACTIVITY_ENTRY(KBearerReady, PRActivities::CBindToActivity::TSendBindTo, CBindToActivity::TAwaitingBindToCompleteOrError, |
|
222 TErrorTagOr<TTag<KDataClientReady | NetStateMachine::EBackward> >) |
|
223 //} |
|
224 |
|
225 //Binding is finished. If this is not autocommit (see TCFDataClient::TBindTo), the activity will reply TCFDataClient::TBindToComplete |
|
226 //to the sender await for the confirmation (TCFDataClient::TCommitBindTo) or cancelation (TBase::TCancel) from the sender. |
|
227 //If this is autommit, the activity will skip awaiting for TCFDataClient::TCommitBindTo and commit itself. |
|
228 THROUGH_NODEACTIVITY_ENTRY(KBindToComplete, CBindToActivity::TSendBindToComplete, CBindToActivity::TNoTagOrCommit) |
|
229 NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, MeshMachine::TAwaitingMessageState<TCFDataClient::TCommitBindTo>, TErrorTagOr<TTag<KCommit> >) |
|
230 |
|
231 //commiting (either implicit or explicit). |
|
232 NODEACTIVITY_ENTRY(KCommit, CBindToActivity::TCommit, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag) |
|
233 |
|
234 //This is not autocommit and the sender has just explicitly cancelled. Alternativelly this is an error path. |
|
235 //Cancelling/processing error entiles sending TCancel to all dataclients awaiting confirmation |
|
236 //as well as it entiles leaving the new service provider. |
|
237 NODEACTIVITY_ENTRY(KErrorTag, CBindToActivity::TCancel, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag) |
|
238 |
|
239 LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing) |
|
240 NODEACTIVITY_END() |
|
241 } |
|
242 |
|
243 namespace PRStartActivity |
|
244 { |
|
245 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStart, PRStart, TCFServiceProvider::TStart, PRActivities::CStartActivity::NewL) |
|
246 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStart, CoreNetStates::TNoTagOrBearerPresentBlockedByStop) |
|
247 NODEACTIVITY_ENTRY(KBearerPresent, CoreNetStates::TBindSelfToPresentBearer, CoreNetStates::TAwaitingBindToComplete, TTag<KBearerPresent>) |
|
248 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendNoBearer, MeshMachine::TAwaitingMessageState<TCFControlProvider::TBearer>, CoreNetStates::TNoTagOrBearerPresentOrErrorTag) |
|
249 |
|
250 //Start the service provider, use the default cancellation. |
|
251 //Forward TCancel to the service provider, wait for TStarted or TError (via the Error Activity) |
|
252 //When TStarted arrives after TCancel the activity will move to the nearest KErrorTag |
|
253 NODEACTIVITY_ENTRY(KBearerPresent, CoreNetStates::TStartServiceProviderRetry, CoreNetStates::TAwaitingStarted, MeshMachine::TNoTagOrErrorTag) |
|
254 LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing) |
|
255 //Start data clients, use the default cancellation. |
|
256 //Forward TCancel to the self, wait for TCFDataClient::TStarted or TError (via the Error Activity) |
|
257 //When TCFDataClient::TStarted arrives after TCancel the activity will move to the nearest KErrorTag |
|
258 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStartSelf, CoreNetStates::TAwaitingDataClientStarted, MeshMachine::TNoTagOrErrorTag) |
|
259 NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TErrorTag) |
|
260 LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError) |
|
261 LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStarted) |
|
262 NODEACTIVITY_END() |
|
263 } |
|
264 |
|
265 namespace PRStopActivity |
|
266 { |
|
267 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStop, PRStop, TCFServiceProvider::TStop, MeshMachine::CNodeRetryActivity::NewL) |
|
268 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingStop, TActiveOrNoTagBlockedByBindTo) |
|
269 THROUGH_NODEACTIVITY_ENTRY(KActiveTag, CoreNetStates::TCancelDataClientStart, MeshMachine::TNoTag) |
|
270 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, CoreNetStates::TNoTagOrNoBearer) |
|
271 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendStop, CoreNetStates::TAwaitingStopped, MeshMachine::TNoTag) |
|
272 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, TTag<CoreNetStates::KNoBearer>) |
|
273 LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoBearer, PRStates::TSendStoppedAndGoneDown) |
|
274 NODEACTIVITY_END() |
|
275 } |
|
276 |
|
277 namespace PRDataClientStartActivity |
|
278 { |
|
279 DECLARE_DEFINE_NODEACTIVITY(ECFActivityStartDataClient, PRDataClientStart, TCFDataClient::TStart) |
|
280 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, CoreNetStates::TNoTagOrNoDataClients) |
|
281 NODEACTIVITY_ENTRY(KNoTag, PRStates::TStartDataClients, TAcceptErrorState<CoreNetStates::TAwaitingDataClientsStarted>, MeshMachine::TErrorTagOr<MeshMachine::TTag<CoreNetStates::KNoDataClients> >) |
|
282 LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClients, PRStates::TSendDataClientStarted) |
|
283 |
|
284 NODEACTIVITY_ENTRY(KErrorTag, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TErrorTag) |
|
285 LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TRaiseAndClearActivityError) |
|
286 NODEACTIVITY_END() |
|
287 } |
|
288 |
|
289 namespace PRDataClientStopActivity |
|
290 { |
|
291 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStopDataClient, PRDataClientStop, TCFDataClient::TStop, MeshMachine::CNodeRetryActivity::NewL) |
|
292 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStop, MeshMachine::TNoTag) |
|
293 THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TProcessDataClientStop, CoreNetStates::TNoTagOrDataClientsToStopBlockedByStarting) |
|
294 |
|
295 NODEACTIVITY_ENTRY(CoreNetStates::KDataClientsToStop, CoreNetStates::TStopDataClients, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TNoTag) |
|
296 THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, CoreNetStates::TNoTagOrUnbindOnStop) |
|
297 |
|
298 NODEACTIVITY_ENTRY(CoreNetStates::KUnbind, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag) |
|
299 THROUGH_NODEACTIVITY_ENTRY(KNoTag, PRStates::TDestroyOrphanedDataClients, MeshMachine::TNoTag) |
|
300 LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendDataClientStopped) |
|
301 NODEACTIVITY_END() |
|
302 } |
|
303 |
|
304 |
|
305 namespace PRForwardStateChangeActivity |
|
306 { |
|
307 DECLARE_DEFINE_NODEACTIVITY(ECFActivityForwardStateChange, PRForwardStateChange, TCFMessage::TStateChange) |
|
308 NODEACTIVITY_ENTRY(KNoTag, PRStates::TForwardStateChange, MeshMachine::TAwaitingMessageState<TCFMessage::TStateChange>, MeshMachine::TNoTag) |
|
309 NODEACTIVITY_END() |
|
310 } |
|
311 |
|
312 namespace PRDataClientStatusChangeActivity |
|
313 { |
|
314 DECLARE_DEFINE_NODEACTIVITY(ECFActivityDataClientStatusChange, PRDataClientStatusChange, TCFControlProvider::TDataClientStatusChange) |
|
315 NODEACTIVITY_ENTRY(KNoTag, PRStates::THandleDataClientStatusChangeAndDestroyOrphans, CoreNetStates::TAwaitingDataClientStatusChange, MeshMachine::TNoTag) |
|
316 NODEACTIVITY_END() |
|
317 } |
|
318 |
|
319 namespace PRGoneDownActivity |
|
320 { |
|
321 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGoneDown, PRGoneDown, TCFControlClient::TGoneDown, CGoneDownActivity::NewL) |
|
322 // Our Service Provider has gone down unexpectedly (we haven't issued a TStop) |
|
323 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingGoneDown, MeshMachine::TNoTag) |
|
324 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TCancelAndCloseZone0ClientExtIfaces, MeshMachine::TNoTag) |
|
325 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendClientLeavingRequestToServiceProvider, MeshMachine::TAwaitingLeaveComplete, MeshMachine::TNoTag) |
|
326 NODEACTIVITY_ENTRY(KNoTag, CGoneDownActivity::TSendErrorRecoveryReq, MeshMachine::TAwaitingErrorRecoveryResponseOrError, CoreStates::TRetryOrIgnoreOrPropagate) |
|
327 THROUGH_NODEACTIVITY_ENTRY(CoreStates::KRetry, MeshMachine::TDoNothing, CGoneDownActivity::TIgnoreOrPropagate) |
|
328 LAST_NODEACTIVITY_ENTRY(CoreStates::KIgnore, MeshMachine::TDoNothing) |
|
329 NODEACTIVITY_ENTRY(CoreStates::KPropagate, CoreNetStates::TCancelStartAndStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TNoTag) |
|
330 LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendGoneDown) |
|
331 NODEACTIVITY_END() |
|
332 } |
|
333 |
|
334 |
|
335 namespace PRGoneUpActivity |
|
336 { |
|
337 // This Activity forward the TGoneUp event to the Control Clients nodes that are |
|
338 // not in the originator lis |
|
339 |
|
340 DECLARE_DEFINE_NODEACTIVITY(ECFActivityGoneUp, PRGoneUp, TCFControlClient::TGoneUp) |
|
341 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingGoneUp, MeshMachine::TNoTag) |
|
342 LAST_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendGoneUp) |
|
343 NODEACTIVITY_END() |
|
344 } |
|
345 |
|
346 namespace PRLegacyRMessage2HandlerActivity |
|
347 { |
|
348 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityLegacyRMessage2Handler, PRLegacyRMessage2Handler, TNodeSignal::TNullMessageId, MeshMachine::CNodeParallelMessageStoreActivityBase::NewL) |
|
349 FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingLegacyRMessage2Ext, MeshMachine::TNoTag) |
|
350 NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TProcessOrForwardRMessage2Ext, CoreNetStates::TAwaitingRMessage2Processed, MeshMachine::TNoTag) |
|
351 LAST_NODEACTIVITY_ENTRY(KNoTag, CoreStates::TPostToOriginators) |
|
352 NODEACTIVITY_END() |
|
353 } |
|
354 |
|
355 |
|
356 namespace CoreActivities |
|
357 { |
|
358 DECLARE_DEFINE_ACTIVITY_MAP(coreActivitiesAll) |
|
359 ACTIVITY_MAP_ENTRY(CoreErrorActivity, CoreError) //Must be first in the table |
|
360 ACTIVITY_MAP_END() |
|
361 |
|
362 //-========================================================= |
|
363 // |
|
364 //Error Activity |
|
365 // |
|
366 //-========================================================= |
|
367 MeshMachine::CNodeActivityBase* CErrorActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode ) |
|
368 { |
|
369 TUint c = GetNextActivityCountL(aActivitySig,aNode); |
|
370 return new(ELeave)CErrorActivity(aActivitySig, aNode, c); |
|
371 } |
|
372 |
|
373 CErrorActivity::CErrorActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aActivitiesCount) |
|
374 : MeshMachine::CNodeParallelActivityBase(aActivitySig, aNode, aActivitiesCount), iErroredActivityId(MeshMachine::KActivityNull) |
|
375 { |
|
376 } |
|
377 |
|
378 CErrorActivity::~CErrorActivity() |
|
379 { |
|
380 if (Error() != KErrNone) |
|
381 { |
|
382 CNodeActivityBase* a = iNode.FindActivityById(iErroredActivityId); |
|
383 if (a) |
|
384 { |
|
385 a->SetError(Error()); |
|
386 a->SetIdle(); |
|
387 } |
|
388 } |
|
389 SetError(KErrNone); |
|
390 } |
|
391 |
|
392 TBool CErrorActivity::IsIdle() const |
|
393 { |
|
394 return NetStateMachine::ACore::IsIdle(); |
|
395 } |
|
396 |
|
397 void CErrorActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& /*aOriginator*/, const TStateTriple& aFirst) |
|
398 { |
|
399 __ASSERT_DEBUG(IsIdle(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 1)); |
|
400 MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CErrorActivity %08x:\tStartL->starting activity"), this)); |
|
401 |
|
402 NetStateMachine::ACore::Start(&aContext, aFirst); |
|
403 |
|
404 MESH_LOG_ACTIVITY_EXT(KESockMeshMachine, this, &aContext, (_L8("CErrorActivity %08x:\tStartL->activity started"),this)); |
|
405 } |
|
406 |
|
407 TBool CErrorActivity::Next(TNodeContextBase& aContext) |
|
408 { |
|
409 TBool ret = EFalse; |
|
410 |
|
411 |
|
412 if (aContext.iMessage.IsMessage<TEBase::TCancel>()) |
|
413 { |
|
414 CNodeActivityBase* a = iNode.FindActivityById(iErroredActivityId); |
|
415 //Special handling for TCancel. |
|
416 if (a && a->FindOriginator(aContext.iSender) != KErrNotFound) |
|
417 { |
|
418 ret = ETrue; |
|
419 //iActiviy could have handled it, but chose not to. |
|
420 Cancel(aContext); |
|
421 //consume the message, otherwise the iActivity will get idled and iActivity reference |
|
422 //will become invalid. |
|
423 aContext.iMessage.ClearMessageId(); |
|
424 } |
|
425 } |
|
426 else |
|
427 { |
|
428 //If we have sent TErrorRecoveryRequest, we had to have set PostedToId() to the recipient (ControlProvider) |
|
429 //as otherwise there would be no path for propagating the potential TCancel. |
|
430 //The response however (TErrorRecoveryResponse or TError) will not necesserily come from that recipient (CP) |
|
431 //(for example it could be coming from the MCpr and we could be the SCpr). |
|
432 //Normally this would be a problem because any unrelated TError message arriving to the node |
|
433 //and presented to the awaiting state would easily be confused with the response (TError == no recovery on the MCpr == EPropagate). |
|
434 //We avoid the problem by checking all arriving messages if they are adressed to our activity (but we don't |
|
435 //check the sender. |
|
436 const TNodeCtxId* recipient = address_cast<const TNodeCtxId>(&aContext.iRecipient); |
|
437 if (recipient && (ActivityId() == recipient->NodeCtx())) |
|
438 { |
|
439 ret = ACore::Next(&aContext); |
|
440 if(ret) |
|
441 { |
|
442 MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CNodeActivityBase %08x:\tNext->transition"), this)); |
|
443 } |
|
444 } |
|
445 } |
|
446 return ret; |
|
447 } |
|
448 |
|
449 EXPORT_DEFINE_SMELEMENT(CErrorActivity::TAwaitingError, NetStateMachine::MState, CErrorActivity::TContext) |
|
450 EXPORT_C TBool CErrorActivity::TAwaitingError::Accept() |
|
451 { |
|
452 if (! iContext.iMessage.IsMessage<TEBase::TError>()) |
|
453 { |
|
454 return EFalse; |
|
455 } |
|
456 |
|
457 TEBase::TError& errorMessage = message_cast<TEBase::TError>(iContext.iMessage); |
|
458 |
|
459 //Diagnostic panic only. TError message should not be travelling around with KErrNone. |
|
460 //If you see this panic, please send a proper error code. |
|
461 __ASSERT_DEBUG(errorMessage.iValue != KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 2)); |
|
462 |
|
463 MeshMachine::CNodeActivityBase* aa = iContext.Node().FindAddressedActivity(iContext); |
|
464 |
|
465 //TError is always a response. If there is no activity addressed by the TError, |
|
466 //then we assume the activity hasn't bothered waiting for the result. |
|
467 //We hence ignore the error. |
|
468 if (aa) |
|
469 { |
|
470 aa->SetError(errorMessage.iValue); |
|
471 aa->SetIdle(); |
|
472 } |
|
473 errorMessage.ClearMessageId(); |
|
474 return EFalse; |
|
475 } |
|
476 |
|
477 DEFINE_SMELEMENT(CErrorActivity::TCFAwaitingError, NetStateMachine::MState, CErrorActivity::TContext) |
|
478 EXPORT_C TBool CErrorActivity::TCFAwaitingError::Accept() |
|
479 { |
|
480 if (! iContext.iMessage.IsMessage<TEBase::TError>()) |
|
481 { |
|
482 return EFalse; |
|
483 } |
|
484 |
|
485 TEBase::TError& errorMessage = message_cast<TEBase::TError>(iContext.iMessage); |
|
486 |
|
487 //Diagnostic panic only. TError message should not be travelling around with KErrNone. |
|
488 //If you see this panic, please send a proper error code. |
|
489 __ASSERT_DEBUG(errorMessage.iValue != KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 3)); |
|
490 |
|
491 RNodeInterface* client = iContext.Node().FindClient(iContext.iSender); |
|
492 if (client && |
|
493 client->Type() & TCFClientType::EServProvider && |
|
494 iContext.Node().ControlProvider() != NULL && |
|
495 iContext.Node().CountActivities(ECFActivityDestroy) == 0) |
|
496 { |
|
497 //this is the only way out into the activity and into error recovery steps |
|
498 //that error activity is responsible for doing. |
|
499 return ETrue; |
|
500 } |
|
501 |
|
502 return CErrorActivity::TAwaitingError::Accept(); |
|
503 } |
|
504 |
|
505 //Simply leaving from this DoL will NOT have the effect of sending TError to originators |
|
506 //of the Errored activity! iContext.iNodeActivity is the Error activity. |
|
507 //Reassign iContext.iNodeActivity before leaving or handle the error. |
|
508 EXPORT_DEFINE_SMELEMENT(CErrorActivity::TSendErrorRecoveryReq, NetStateMachine::MStateTransition, CErrorActivity::TContext) |
|
509 EXPORT_C void CErrorActivity::TSendErrorRecoveryReq::DoL() |
|
510 { |
|
511 //Find matching activity, if any |
|
512 MeshMachine::CNodeActivityBase* aa = iContext.Node().FindAddressedActivity(iContext); |
|
513 //we are started based on the fact the the last message iContext.Node()'s received is TError |
|
514 TEBase::TError& errmsg = message_cast<TEBase::TError>(iContext.iMessage); |
|
515 |
|
516 //The error comes from someone else than our Data Client (or we wouldn't be here). |
|
517 //It may be our Service Provider or it can be some other node which has originated |
|
518 //an activity on us (in which case the errored activity must be present). |
|
519 if (aa==NULL) |
|
520 { |
|
521 __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ASendErrorRecoveryReq::DoL - TError but no addressed activity - ignoring"))); |
|
522 #ifdef SYMBIAN_NETWORKING_UPS |
|
523 // Terminate the error activity (not UPS specific). |
|
524 iContext.iNodeActivity->SetIdle(); |
|
525 #endif //SYMBIAN_NETWORKING_UPS |
|
526 return; |
|
527 } |
|
528 |
|
529 AContextStore* intf = NULL; |
|
530 if (aa->SupportsExtInterface(AContextStore::KInterfaceId)) |
|
531 { |
|
532 //FetchExtInterfaceL below can never leave because it is being checked few lines above in the "if" |
|
533 intf = reinterpret_cast<AContextStore*>(aa->FetchExtInterfaceL(AContextStore::KInterfaceId)); |
|
534 } |
|
535 |
|
536 //Check if there is any point in sending Error Recovery Request |
|
537 if (intf==NULL || !intf->IsStored() || !iContext.Node().ControlProvider()) |
|
538 { |
|
539 __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ERROR: ASendErrorRecoveryReq::DoL - KErrNotSupported"))); |
|
540 iContext.iNodeActivity->SetIdle(); |
|
541 aa->SetError(errmsg.iValue); |
|
542 aa->SetIdle(); |
|
543 return; |
|
544 } |
|
545 |
|
546 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
547 CoreActivities::CErrorActivity& activity = static_cast<CoreActivities::CErrorActivity&>(*iContext.iNodeActivity); |
|
548 __ASSERT_DEBUG(activity.iErroredActivityId==MeshMachine::KActivityNull, User::Panic(KSpecAssert_ESockCrStaCPRAC, 4)); |
|
549 // Save a reference to the activity and a point |
|
550 // Each time we use the activity, query it from the node, because the activity may have gone away (originator left node etc) |
|
551 activity.iErroredActivityId = aa->ActivityId(); |
|
552 |
|
553 activity.SetError(errmsg.iValue); |
|
554 activity.iMessageId = errmsg.iMsgId; |
|
555 |
|
556 TErrContext ctx(iContext.NodeId(), errmsg.iMsgId, aa->ActivitySigId(), TStateChange(0, errmsg.iValue)); |
|
557 TEErrorRecovery::TErrorRecoveryRequest msg(ctx); |
|
558 |
|
559 activity.PostRequestTo( |
|
560 *iContext.Node().ControlProvider(),//ControlProvider() verified above |
|
561 TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef() |
|
562 ); |
|
563 |
|
564 //The original activiy might have set 'sent to', but that's surely |
|
565 //not meaningful anymore (we've just received a response from that 'sent to'). |
|
566 //We could have pretended that the orginal activity knows it's sent |
|
567 //error recovery to the control provider but it's best just to clear |
|
568 //'sent to' (and handle TCancel from here (CErrorActivity::Next()). |
|
569 aa->ClearPostedTo(); |
|
570 } |
|
571 |
|
572 EXPORT_DEFINE_SMELEMENT(CErrorActivity::TDoErrorRecovery, NetStateMachine::MStateTransition, CErrorActivity::TContext) |
|
573 EXPORT_C void CErrorActivity::TDoErrorRecovery::DoL() |
|
574 { |
|
575 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
576 CoreActivities::CErrorActivity* act = static_cast<CoreActivities::CErrorActivity*>(iContext.iNodeActivity); |
|
577 CNodeActivityBase* a = iContext.Node().FindActivityById(act->iErroredActivityId); |
|
578 if (a == NULL) |
|
579 { |
|
580 iContext.iNodeActivity->SetIdle(); |
|
581 return; |
|
582 } |
|
583 |
|
584 if (iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>()) |
|
585 { |
|
586 TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse; |
|
587 if (resp.iAction == TErrResponse::ERetry) |
|
588 { //rerun current transition |
|
589 __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to retry"))); |
|
590 __ASSERT_DEBUG(a->SupportsExtInterface(AContextStore::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported)); |
|
591 |
|
592 AContextStore* intf = reinterpret_cast<AContextStore*>(a->FetchExtInterfaceL(AContextStore::KInterfaceId)); |
|
593 __ASSERT_DEBUG(intf->IsStored(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 5)); |
|
594 intf->Retry(*a,iContext); |
|
595 if (iContext.iReturn == KErrNone) |
|
596 { //retry succeded |
|
597 act->SetError(KErrNone); |
|
598 } |
|
599 //if Retry had failed, then the d'tor of act will raise the error on |
|
600 //and terminate act->iActivity, |
|
601 } |
|
602 else if (resp.iAction == TErrResponse::EPropagate) |
|
603 { //set new error values and fall through |
|
604 __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("ADoErrorRecovery::DoL - instructed to propagate the error"))); |
|
605 act->iMessageId = resp.iMessageId; |
|
606 a->SetError(resp.iError); |
|
607 } |
|
608 else //if (resp.iAction == TErrResponse::EIgnore) |
|
609 { |
|
610 __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, |
|
611 _L8("WARNING: ADoErrorRecovery::DoL() - instructed to ignore the error!"))); |
|
612 } |
|
613 } |
|
614 } |
|
615 |
|
616 |
|
617 //-========================================================= |
|
618 // |
|
619 //Destroy Activity - will delete the node when destructed |
|
620 // |
|
621 //-========================================================= |
|
622 |
|
623 EXPORT_C MeshMachine::CNodeActivityBase* CDestroyActivity::New(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
624 { |
|
625 TAny* space = BorrowPreallocatedSpace(aNode, sizeof(CDestroyActivity)); |
|
626 CDestroyActivity* self = new (space) CDestroyActivity(aActivitySig, aNode); |
|
627 self->InsertPreallocatedDestroyActivity(); //Destructing preallocated activity |
|
628 return self; |
|
629 } |
|
630 |
|
631 CDestroyActivity::CDestroyActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
632 : CNodeRetryActivity(aActivitySig, aNode), |
|
633 APreallocatedOriginators<1>(iOriginators) |
|
634 { |
|
635 //Mark the provider for deletion, so that it's not served by the factory from now on. |
|
636 static_cast<ESock::CMMCommsProviderBase&>(iNode).MarkMeForDeletion(); |
|
637 } |
|
638 |
|
639 void CDestroyActivity::Destroy() |
|
640 { |
|
641 ReturnPreallocatedSpace(this); |
|
642 this->~CDestroyActivity(); //Run the destructor |
|
643 |
|
644 //Delete the provider. |
|
645 static_cast<ESock::CMMCommsProviderBase&>(iNode).DeleteMeNow(); |
|
646 } |
|
647 |
|
648 TBool CDestroyActivity::Next(TNodeContextBase& aContext) |
|
649 { |
|
650 if (aContext.iMessage.IsMessage<TEBase::TCancel>()) |
|
651 { |
|
652 return ETrue; |
|
653 } |
|
654 else |
|
655 return CNodeActivityBase::Next(aContext); |
|
656 } |
|
657 |
|
658 EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext) |
|
659 EXPORT_C TInt CDestroyActivity::TNoTagOrNoTagBackwards::TransitionTag() |
|
660 { |
|
661 if (iContext.iMessage.IsMessage<TEChild::TLeft>()) |
|
662 { |
|
663 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData|TCFClientType::ECtrl)); |
|
664 __ASSERT_DEBUG(iter[0], User::Panic(KSpecAssert_ESockCrStaCPRAC, 7)); //One leaving client must still be there. |
|
665 return iter[1] == NULL ? MeshMachine::KNoTag : MeshMachine::KNoTag | NetStateMachine::EBackward; |
|
666 } |
|
667 else if (iContext.iMessage.IsMessage<TEPeer::TLeaveComplete>()) |
|
668 { |
|
669 __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl|TCFClientType::EData))==NULL, |
|
670 User::Panic(KCorePrPanic, KPanicClientsStillPresent)); |
|
671 if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider))==NULL) |
|
672 { |
|
673 return NetStateMachine::EForward | MeshMachine::KNoTag; |
|
674 } |
|
675 return NetStateMachine::EBackward | MeshMachine::KNoTag; //Loop back to the same triple (& remove the peer) |
|
676 } |
|
677 __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockCrStaCPRAC, 8)); |
|
678 return KNoTag; |
|
679 } |
|
680 |
|
681 EXPORT_DEFINE_SMELEMENT(CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave, NetStateMachine::MStateTransition, PRStates::TContext) |
|
682 EXPORT_C void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::DoL() |
|
683 { |
|
684 if (iContext.iMessage.IsMessage<TEChild::TLeft>()) |
|
685 { |
|
686 ProcessClientLeaveL(); |
|
687 } |
|
688 else |
|
689 { |
|
690 MakeClientsLeaveL(); |
|
691 } |
|
692 } |
|
693 |
|
694 void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::MakeClientsLeaveL() |
|
695 { |
|
696 __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl))==NULL, |
|
697 User::Panic(KCorePrPanic, KPanicClientsStillPresent)); |
|
698 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
699 iContext.iNodeActivity->ClearPostedTo(); |
|
700 |
|
701 //MZTODO: this asserion may need to be changed since TDestroy can |
|
702 //come while data client is active etc. |
|
703 __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EActive|TCFClientType::EActivating|TCFClientType::EStarting|TCFClientType::EStarted))==NULL, |
|
704 User::Panic(KCorePrPanic, KPanicClientsStillPresent)); |
|
705 |
|
706 TClientIter<TDefaultClientMatchPolicy> dciter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData), TClientType(0, TCFClientType::ELeaving)); |
|
707 RNodeInterface* dc = NULL; |
|
708 while ((dc = dciter[0]) != NULL) //always inspect the first elem as we're invalidating the iterator with each hit. |
|
709 { |
|
710 dc->PostMessage(iContext.NodeId(), TEChild::TDestroy().CRef()); |
|
711 dc->SetFlags(TCFClientType::ELeaving); |
|
712 } |
|
713 } |
|
714 |
|
715 void CDestroyActivity::TMakeClientsLeaveOrProcessClientLeave::ProcessClientLeaveL() |
|
716 { |
|
717 CDestroyActivity::TProcessClientLeave processClientLeave(iContext); |
|
718 processClientLeave.DoL(); |
|
719 } |
|
720 |
|
721 |
|
722 //-========================================================= |
|
723 // |
|
724 //Loppin Activity |
|
725 // |
|
726 //-========================================================= |
|
727 EXPORT_C ACountLoopActivity::~ACountLoopActivity() |
|
728 { |
|
729 } |
|
730 |
|
731 |
|
732 EXPORT_C MeshMachine::CNodeActivityBase* CCountLoopActivityBase::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
733 { |
|
734 return new (ELeave) CCountLoopActivityBase(aActivitySig, aNode); |
|
735 } |
|
736 |
|
737 EXPORT_C CCountLoopActivityBase::CCountLoopActivityBase(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
738 : MeshMachine::CNodeActivityBase(aActivitySig, aNode), |
|
739 TIfStaticFetcherNearestInHierarchy(this) |
|
740 { |
|
741 } |
|
742 |
|
743 EXPORT_C CCountLoopActivityBase::~CCountLoopActivityBase() |
|
744 { |
|
745 } |
|
746 |
|
747 EXPORT_DEFINE_SMELEMENT(ACountLoopActivity::TNoTagOrNoTagBackwards, NetStateMachine::MStateFork, PRStates::TContext) |
|
748 EXPORT_C TInt ACountLoopActivity::TNoTagOrNoTagBackwards::TransitionTag() |
|
749 { |
|
750 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
751 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ACountLoopActivity::KInterfaceId),User::Panic(KCorePrPanic, KPanicInterfaceNotSupported)); |
|
752 ACountLoopActivity* countLoopActivity = static_cast<ACountLoopActivity*>(iContext.iNodeActivity->FetchExtInterface(ACountLoopActivity::KInterfaceId)); |
|
753 if (countLoopActivity->DecCount() > 0) |
|
754 { |
|
755 return KNoTag | NetStateMachine::EBackward; |
|
756 } |
|
757 return KNoTag | NetStateMachine::EForward; |
|
758 } |
|
759 |
|
760 |
|
761 |
|
762 |
|
763 |
|
764 //-========================================================= |
|
765 // |
|
766 // |
|
767 //Binding Activity |
|
768 // |
|
769 // |
|
770 //-========================================================= |
|
771 EXPORT_C ABindingActivity::~ABindingActivity() |
|
772 { |
|
773 //Handle premature termination of the ABindingActivity object |
|
774 //by responding to the originator |
|
775 //If the originator has not been replied to yet, reply now with an error code |
|
776 if (IsBinding()) |
|
777 { |
|
778 ReplyToOriginator(KErrAbort); |
|
779 } |
|
780 } |
|
781 |
|
782 EXPORT_C void ABindingActivity::StoreOriginator(const TRuntimeCtxId& aNodeCtxId) |
|
783 { |
|
784 //Check if the originator wasn't set before. If it was, it must be replied to before storing ths new one. |
|
785 __ASSERT_DEBUG(iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 9)); |
|
786 iOriginator = aNodeCtxId; |
|
787 } |
|
788 |
|
789 EXPORT_C void ABindingActivity::ReplyToOriginator(TInt aError) |
|
790 { |
|
791 //NOTE: Please do not make this diagnostic panic conditional. |
|
792 //Please allow it to server everyone equally. |
|
793 //Please handle the error conditions properly so that you obey this API's semantics. |
|
794 //If you are not providing a clean error handling solution for your activity, |
|
795 //please use IsBinding() before calling this API! |
|
796 __ASSERT_DEBUG(!iOriginator.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 10)); //The iOriginator must be set. |
|
797 RClientInterface::OpenPostMessageClose(iOurNode, iOriginator, TCFDataClient::TBindToComplete(aError).CRef()); |
|
798 iOriginator.SetNull(); |
|
799 } |
|
800 |
|
801 EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CoreStates::TContext) |
|
802 EXPORT_C void ABindingActivity::TSendBindToComplete::DoL() |
|
803 { |
|
804 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
805 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 11)); |
|
806 ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId)); |
|
807 bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error()); |
|
808 } |
|
809 |
|
810 EXPORT_DEFINE_SMELEMENT(ABindingActivity::TSendBindToCompleteIfExpected, NetStateMachine::MStateTransition, CoreStates::TContext) |
|
811 EXPORT_C void ABindingActivity::TSendBindToCompleteIfExpected::DoL() |
|
812 { |
|
813 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
814 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId), User::Panic(KSpecAssert_ESockCrStaCPRAC, 12)); |
|
815 ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterfaceL(ABindingActivity::KInterfaceId)); |
|
816 if (bindingActivity->IsBinding()) |
|
817 { |
|
818 bindingActivity->ReplyToOriginator(iContext.iNodeActivity->Error()); |
|
819 } |
|
820 } |
|
821 |
|
822 void ABindingActivity::FinalReplyToOriginator(TInt aError) |
|
823 /** |
|
824 Intended to be called from derived class destructors to arrange for a TBindToComplete reply to be sent |
|
825 before any other messages in those derived class destructors (for example TDestroy). |
|
826 */ |
|
827 { |
|
828 if (IsBinding()) |
|
829 { |
|
830 ReplyToOriginator(aError); |
|
831 // Ensure that we don't send another reply in ~ABindingActivity. |
|
832 iOriginator = Messages::TNodeCtxId(); |
|
833 } |
|
834 } |
|
835 |
|
836 } // CoreActivities |
|
837 |
|
838 |
|
839 namespace PRActivities |
|
840 { |
|
841 DECLARE_DEFINE_ACTIVITY_MAP(coreActivitiesPR) |
|
842 ACTIVITY_MAP_ENTRY(PRDataClientJoinActivity, PRDataClientJoin) |
|
843 ACTIVITY_MAP_ENTRY(PRControlClientJoinActivity, PRControlClientJoin) |
|
844 ACTIVITY_MAP_ENTRY(PRClientLeaveActivity, PRClientLeave) |
|
845 ACTIVITY_MAP_ENTRY(PRForwardStateChangeActivity, PRForwardStateChange) |
|
846 ACTIVITY_MAP_ENTRY(PRBindToActivity, PRBindTo) |
|
847 ACTIVITY_MAP_END_BASE(CoreActivities,coreActivitiesAll) |
|
848 |
|
849 //Activity Map provided by CorePr to be used by SCprs. |
|
850 //(it is further extended in CoreSCpr). |
|
851 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesSCpr) |
|
852 ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision) |
|
853 ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart) |
|
854 ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop) |
|
855 ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart) |
|
856 ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop) |
|
857 ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle) |
|
858 ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive) |
|
859 ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy) |
|
860 ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown) |
|
861 ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro |
|
862 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW |
|
863 ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams) |
|
864 ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams) |
|
865 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW |
|
866 ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler) |
|
867 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR) |
|
868 |
|
869 //Activity Map provided by CorePr to be used by Cprs. |
|
870 //(it is further extended in CoreCpr). |
|
871 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesCpr) |
|
872 ACTIVITY_MAP_ENTRY(PRProvisionActivity, PrProvision) |
|
873 ACTIVITY_MAP_ENTRY(PRStartActivity, PRStart) |
|
874 ACTIVITY_MAP_ENTRY(PRStopActivity, PRStop) |
|
875 ACTIVITY_MAP_ENTRY(PRDataClientStartActivity, PRDataClientStart) |
|
876 ACTIVITY_MAP_ENTRY(PRDataClientStopActivity, PRDataClientStop) |
|
877 ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle) |
|
878 ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive) |
|
879 ACTIVITY_MAP_ENTRY(PRDestroyActivity, PRDestroy) |
|
880 ACTIVITY_MAP_ENTRY(PRGoneDownActivity, PRGoneDown) |
|
881 ACTIVITY_MAP_ENTRY(PRGoneUpActivity, PRGoneUp) //robertomaro |
|
882 ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange) |
|
883 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW |
|
884 ACTIVITY_MAP_ENTRY(PRSetParamsRequest, PRSetParams) |
|
885 ACTIVITY_MAP_ENTRY(PRGetParamsRequest, PRGetParams) |
|
886 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW |
|
887 ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler) |
|
888 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR) |
|
889 |
|
890 //Activity Map provided by CorePr to be used by MCprs. |
|
891 //(it is further extended in CoreMCpr). |
|
892 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesMCpr) |
|
893 ACTIVITY_MAP_ENTRY(PRDataClientIdleActivity, PRDataClientIdle) |
|
894 ACTIVITY_MAP_ENTRY(PRDataClientActiveActivity, PRDataClientActive) |
|
895 ACTIVITY_MAP_ENTRY(PRDataClientStatusChangeActivity, PRDataClientStatusChange) |
|
896 ACTIVITY_MAP_ENTRY(PRLegacyRMessage2HandlerActivity, PRLegacyRMessage2Handler) |
|
897 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR) |
|
898 |
|
899 //Activity Map provided by CorePr to be used by TMs. |
|
900 //(it is further extended in CoreTM). |
|
901 DEFINE_EXPORT_ACTIVITY_MAP(coreActivitiesTM) |
|
902 ACTIVITY_MAP_END_BASE(PRActivities,coreActivitiesPR) |
|
903 |
|
904 |
|
905 |
|
906 |
|
907 //-========================================================= |
|
908 // |
|
909 //CBindToActivity |
|
910 // |
|
911 //-========================================================= |
|
912 EXPORT_C CBindToActivity::CBindToActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TInt aNextActivityCount) |
|
913 : MeshMachine::CNodeParallelActivityBase(aActivitySig, aNode, aNextActivityCount), |
|
914 CoreActivities::ABindingActivity(aNode.Id()), |
|
915 TIfStaticFetcherNearestInHierarchy(this) |
|
916 { |
|
917 } |
|
918 |
|
919 EXPORT_C MeshMachine::CNodeActivityBase* CBindToActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
920 { |
|
921 //there can be only one BindTo activity running at a time. |
|
922 TUint c = GetNextActivityCountL(aActivitySig,aNode); |
|
923 __ASSERT_DEBUG(c == 1,User::Panic(KCorePrPanic, KPanicPeerMisbehaving)); |
|
924 if (c > 1) |
|
925 { |
|
926 User::Leave(KErrInUse); |
|
927 } |
|
928 return new (ELeave) CBindToActivity(aActivitySig, aNode, c); |
|
929 } |
|
930 |
|
931 EXPORT_C CBindToActivity::~CBindToActivity() |
|
932 { |
|
933 //If the activity is aborted then no cleanup will be performed (the destroy activity will do |
|
934 //that for us) so we should not assert that iSuccessfulDataClients is empty or iNewServiceProvider |
|
935 //is null. |
|
936 |
|
937 //CBindToActivity::TCommit or CBindToActivity::TCancel should have been executed |
|
938 //and rendered iSuccessfulDataClients empty. |
|
939 //__ASSERT_DEBUG(iSuccessfulDataClients.Count() == 0, User::Panic(KCorePrPanic, KPanicIncorrectState)); |
|
940 |
|
941 //CBindToActivity::iNewServiceProvider should have been cleared by CBindToActivity::TCommit or CBindToActivity::TCancel |
|
942 //__ASSERT_DEBUG(iNewServiceProvider == NULL, User::Panic(KCorePrPanic, KPanicIncorrectState)); |
|
943 |
|
944 iSuccessfulDataClients.Close(); |
|
945 } |
|
946 |
|
947 Messages::RNodeInterface* CBindToActivity::NextDataClient() |
|
948 { |
|
949 TClientIter<TDefaultClientMatchPolicy> iter = iNode.GetClientIter<TDefaultClientMatchPolicy>( |
|
950 /*include*/TClientType(TCFClientType::EData), |
|
951 /*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint)); |
|
952 iCurrentDataClient = iter++; |
|
953 while (iCurrentDataClient && (iSuccessfulDataClients.Find(iCurrentDataClient) != KErrNotFound)) |
|
954 { |
|
955 iCurrentDataClient = iter++; |
|
956 }; |
|
957 return iCurrentDataClient; |
|
958 } |
|
959 |
|
960 TBool CBindToActivity::DataClientsAutocommit() |
|
961 { |
|
962 TInt nonLeavingDataClients = iNode.CountClients<TDefaultClientMatchPolicy>( |
|
963 /*include*/TClientType(TCFClientType::EData), |
|
964 /*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint)); |
|
965 return nonLeavingDataClients <=1 && IsAutocommit(); |
|
966 } |
|
967 |
|
968 |
|
969 void CBindToActivity::AddClientAsSuccessfulL(Messages::RNodeInterface* aDataClient) |
|
970 { |
|
971 __ASSERT_DEBUG(aDataClient, User::Panic(KCorePrPanic, KPanicDataClient)); |
|
972 __ASSERT_DEBUG(iSuccessfulDataClients.Find(aDataClient) == KErrNotFound, User::Panic(KCorePrPanic, KPanicIncorrectState)); |
|
973 iSuccessfulDataClients.Append(aDataClient); |
|
974 } |
|
975 |
|
976 void CBindToActivity::RemoveClientFromSuccessful(Messages::RNodeInterface* aDataClient) |
|
977 { |
|
978 TInt index = iSuccessfulDataClients.Find(aDataClient); |
|
979 __ASSERT_DEBUG(index >= 0, User::Panic(KCorePrPanic, KPanicDataClient)); |
|
980 iSuccessfulDataClients.Remove(index); |
|
981 } |
|
982 |
|
983 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendControlClientJoinRequest, NetStateMachine::MStateTransition, CBindToActivity::TContext) |
|
984 void CBindToActivity::TSendControlClientJoinRequest::DoL() |
|
985 { |
|
986 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
987 CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity); |
|
988 const TCFDataClient::TBindTo& bindToMsg(message_cast<const TCFDataClient::TBindTo>(iContext.iMessage)); |
|
989 |
|
990 __ASSERT_DEBUG(!bindToMsg.iNodeId.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider)); |
|
991 RNodeInterface* newServiceProvider = iContext.Node().AddClientL(bindToMsg.iNodeId, |
|
992 TClientType(TCFClientType::EServProvider, TCFClientType::EActivating)); |
|
993 __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider)); |
|
994 activity.iNewServiceProvider = bindToMsg.iNodeId; |
|
995 //Join the new service provider |
|
996 iContext.Activity()->PostRequestTo(*newServiceProvider, |
|
997 TCFControlClient::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef()); |
|
998 } |
|
999 |
|
1000 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TAwaitingBindToCompleteOrError, NetStateMachine::MState, CRejoinDataClientActivity::TContext) |
|
1001 TBool CBindToActivity::TAwaitingBindToCompleteOrError::Accept() |
|
1002 { |
|
1003 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1004 CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity); |
|
1005 if (CoreNetStates::TAwaitingBindToComplete(iContext).Accept()) |
|
1006 { |
|
1007 if (activity.IsBinding()) |
|
1008 { |
|
1009 //Activity is binding (i.e.: we havent received TBindToComplete as a response |
|
1010 //to null-carrying TBindTo. |
|
1011 activity.ReplyToOriginator(KErrNone); |
|
1012 } |
|
1013 activity.ResetCurrentDataClient(); |
|
1014 return ETrue; |
|
1015 } |
|
1016 else if (iContext.iMessage.IsMessage<TEBase::TError>()) |
|
1017 { |
|
1018 activity.ReplyToOriginator(message_cast<TEBase::TError>(iContext.iMessage).iValue); |
|
1019 activity.RemoveClientFromSuccessful(activity.CurrentDataClient()); |
|
1020 activity.ResetCurrentDataClient(); |
|
1021 return ETrue; |
|
1022 } |
|
1023 return EFalse; |
|
1024 } |
|
1025 |
|
1026 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrDataClientReady, NetStateMachine::MStateFork, CBindToActivity::TContext) |
|
1027 TInt CBindToActivity::TNoTagOrDataClientReady::TransitionTag() |
|
1028 { |
|
1029 //Any non-leaving dataclients already present? |
|
1030 if (iContext.Node().CountClients<TDefaultClientMatchPolicy>( |
|
1031 /*include*/TClientType(TCFClientType::EData), |
|
1032 /*exclude*/TClientType(0, TCFClientType::ELeaving | TCFClientType::EConfigAccessPoint))) |
|
1033 { |
|
1034 return KDataClientReady; |
|
1035 } |
|
1036 return KNoTag; |
|
1037 } |
|
1038 |
|
1039 |
|
1040 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TRequestCommsBinder, NetStateMachine::MStateTransition, CBindToActivity::TContext) |
|
1041 void CBindToActivity::TRequestCommsBinder::DoL() |
|
1042 { |
|
1043 __ASSERT_DEBUG(iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)),User::Panic(KCorePrPanic, KPanicDataClient)); |
|
1044 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1045 CBindToActivity& activity = static_cast<CBindToActivity&>(*iContext.iNodeActivity); |
|
1046 |
|
1047 //The service provider has been joined already and must be found here |
|
1048 __ASSERT_DEBUG(!activity.iNewServiceProvider.IsNull(), User::Panic(KCorePrPanic, KPanicNoServiceProvider)); |
|
1049 RNodeInterface* newServiceProvider = iContext.Node().FindClient(activity.iNewServiceProvider); |
|
1050 __ASSERT_DEBUG(newServiceProvider, User::Panic(KCorePrPanic, KPanicNoServiceProvider)); |
|
1051 //We must not be in this transition if dc was not found |
|
1052 __ASSERT_DEBUG(activity.CurrentDataClient(), User::Panic(KCorePrPanic, KPanicDataClient)); |
|
1053 |
|
1054 // Also if it is not so common to have multiple DataClient (except |
|
1055 // for the relation "SCPR<-CPR"), there are situation where it happens |
|
1056 // and where only one of them is marked as Default. |
|
1057 // So, we check if this is the case and, in case the |
|
1058 // Originator of this activity is NOT a Default one, send ECreateNew. |
|
1059 |
|
1060 // If the Current DC is marked as Default, we ask to the lower layer |
|
1061 // to "AttachToDefault". If it is not, we ask "CreateNew". |
|
1062 TInt subConnOpenType = (activity.CurrentDataClient()->Flags() & TCFClientType::EDefault) ? |
|
1063 TSubConnOpen::EAttachToDefault : TSubConnOpen::ECreateNew; |
|
1064 |
|
1065 // --- WORKAROUND START --- |
|
1066 // [399TODO] There are situation were we don't have any DataClient marked |
|
1067 // as Default, but, asking for ECreateNew, the lower layer doesn't |
|
1068 // manage the request very well. |
|
1069 // This is a WORKAROUND and need fixing (see DEF113154). |
|
1070 // In the meanwhile, we count the number of "DefaultDataClient" and, |
|
1071 // if the result is "0", we ask the lower layer "AttachToDefault" |
|
1072 TInt numberOfDefaultDataClient = iContext.Node().CountClients<TDefaultClientMatchPolicy>( |
|
1073 TClientType(TCFClientType::EData, TCFClientType::EDefault) |
|
1074 ); |
|
1075 if (numberOfDefaultDataClient == 0) |
|
1076 { |
|
1077 subConnOpenType = TSubConnOpen::EAttachToDefault; |
|
1078 } |
|
1079 // --- WORKAROUND END --- |
|
1080 |
|
1081 // Send "TCommsBinderRequest" to the Current ServiceProvider |
|
1082 activity.PostRequestTo( |
|
1083 *newServiceProvider, |
|
1084 TCFServiceProvider::TCommsBinderRequest(subConnOpenType).CRef() |
|
1085 ); |
|
1086 } |
|
1087 |
|
1088 |
|
1089 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCreateDataClient, NetStateMachine::MStateTransition, CBindToActivity::TContext) |
|
1090 void CBindToActivity::TCreateDataClient::DoL() |
|
1091 { |
|
1092 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1093 |
|
1094 IssuePeerCreationRequestL (); |
|
1095 } |
|
1096 |
|
1097 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindTo, NetStateMachine::MStateTransition, CBindToActivity::TContext) |
|
1098 void CBindToActivity::TSendBindTo::DoL() |
|
1099 { |
|
1100 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1101 CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity); |
|
1102 |
|
1103 //Provisionally stash the current dataclient as successful. If it fails to bind, we'll unstash it |
|
1104 //We're doing this now, as stashing may fail and we don't want that to be the sole reason for |
|
1105 //unrolling. |
|
1106 bindToActivity.AddClientAsSuccessfulL(bindToActivity.CurrentDataClient()); |
|
1107 |
|
1108 TCFServiceProvider::TCommsBinderResponse* commsBinderResponse = message_cast<TCFServiceProvider::TCommsBinderResponse>(&iContext.iMessage); |
|
1109 Messages::TNodeId commsBinder = commsBinderResponse ? commsBinderResponse->iNodeId : Messages::TNodeId::NullId(); |
|
1110 |
|
1111 bindToActivity.PostRequestTo(*bindToActivity.CurrentDataClient(), |
|
1112 TCFDataClient::TBindTo(commsBinder, !bindToActivity.DataClientsAutocommit()).CRef()); |
|
1113 } |
|
1114 |
|
1115 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TSendBindToComplete, NetStateMachine::MStateTransition, CBindToActivity::TContext) |
|
1116 void CBindToActivity::TSendBindToComplete::DoL() |
|
1117 { |
|
1118 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1119 iContext.iNodeActivity->PostToOriginators(TCFDataClient::TBindToComplete().CRef()); |
|
1120 } |
|
1121 |
|
1122 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrCommit, NetStateMachine::MStateFork, CBindToActivity::TContext) |
|
1123 TInt CBindToActivity::TNoTagOrCommit::TransitionTag() |
|
1124 { |
|
1125 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1126 CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity); |
|
1127 if (bindToActivity.IsAutocommit()) |
|
1128 { |
|
1129 return KCommit; |
|
1130 } |
|
1131 return KNoTag; |
|
1132 } |
|
1133 |
|
1134 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext) |
|
1135 EXPORT_C TInt CBindToActivity::TNoTagOrBindToComplete::TransitionTag() |
|
1136 { |
|
1137 TCFFactory::TPeerFoundOrCreated& dcJoined = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage); |
|
1138 |
|
1139 if (dcJoined.iNodeId.IsNull()) |
|
1140 { |
|
1141 //Factory decided not to create a dataclient; |
|
1142 return KBindToComplete; |
|
1143 } |
|
1144 |
|
1145 //factory created a new citizen. |
|
1146 return KNoTag; |
|
1147 } |
|
1148 |
|
1149 |
|
1150 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReady, NetStateMachine::MStateFork, CBindToActivity::TContext) |
|
1151 TInt CBindToActivity::TNoTagOrBearerReady::TransitionTag() |
|
1152 { |
|
1153 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1154 CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity); |
|
1155 TCFDataClient::TBindTo& bindToReq = message_cast<TCFDataClient::TBindTo>(iContext.iMessage); |
|
1156 bindToActivity.SetAutocommit(!bindToReq.iValue); |
|
1157 |
|
1158 if (bindToReq.iNodeId.IsNull()) |
|
1159 //received a null service provider, the node is at the stack's bottom. |
|
1160 { |
|
1161 return KBearerReady; |
|
1162 } |
|
1163 |
|
1164 RNodeInterface* sp = iContext.Node().ServiceProvider(); |
|
1165 if (sp && bindToReq.iNodeId == sp->RecipientId()) |
|
1166 { |
|
1167 //received the same service provider, it's already bound to. |
|
1168 bindToActivity.iNewServiceProvider = sp->RecipientId(); |
|
1169 return KBearerReady; |
|
1170 } |
|
1171 RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToReq.iNodeId); |
|
1172 if (newServiceProvider) |
|
1173 { |
|
1174 __ASSERT_DEBUG(newServiceProvider->Type() == TCFClientType::EServProvider, User::Panic(KCorePrPanic, KPanicIncorrectState)); |
|
1175 //Ok, we've received a TBindTo holding a service provider that we already know of and that is not |
|
1176 //our current service provider. We're going to assume this node tolerates multiple service providers (like MCPRs do). |
|
1177 //the current service provider will be swapped, but won't be dropped. |
|
1178 bindToActivity.iNewServiceProvider = bindToReq.iNodeId; |
|
1179 newServiceProvider->SetFlags(TCFClientType::EActivating); |
|
1180 bindToActivity.SetDontLeaveServiceProvider(); |
|
1181 return KBearerReady; |
|
1182 } |
|
1183 else |
|
1184 { |
|
1185 bindToActivity.iNewServiceProvider = TNodeId::NullId(); |
|
1186 } |
|
1187 //The node received a new service provider... |
|
1188 return KNoTag; |
|
1189 } |
|
1190 |
|
1191 |
|
1192 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TNoTagOrBearerReadyOrBindToComplete, NetStateMachine::MStateFork, CBindToActivity::TContext) |
|
1193 TInt CBindToActivity::TNoTagOrBearerReadyOrBindToComplete::TransitionTag() |
|
1194 { |
|
1195 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1196 CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity); |
|
1197 |
|
1198 if (!bindToActivity.NextDataClient()) |
|
1199 { |
|
1200 //No more dataclients to bind |
|
1201 return KBindToComplete; |
|
1202 } |
|
1203 |
|
1204 if (bindToActivity.iNewServiceProvider.IsNull()) |
|
1205 { |
|
1206 //There is no service provider (new or old) below us. |
|
1207 return KBearerReady; |
|
1208 } |
|
1209 |
|
1210 return KNoTag; |
|
1211 } |
|
1212 |
|
1213 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCommit, NetStateMachine::MStateTransition, CBindToActivity::TContext) |
|
1214 void CBindToActivity::TCommit::DoL() |
|
1215 { |
|
1216 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1217 CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity); |
|
1218 |
|
1219 TInt count = bindToActivity.DataClientsAutocommit() ? 0 : bindToActivity.iSuccessfulDataClients.Count(); |
|
1220 while (count ) |
|
1221 { |
|
1222 bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TCFDataClient::TCommitBindTo().CRef()); |
|
1223 }; |
|
1224 bindToActivity.iSuccessfulDataClients.Reset(); |
|
1225 RNodeInterface* sp = iContext.Node().ServiceProvider(); |
|
1226 |
|
1227 if (sp && sp->RecipientId() != bindToActivity.iNewServiceProvider) |
|
1228 { |
|
1229 if (bindToActivity.ShouldLeaveServiceProvider()) |
|
1230 { |
|
1231 bindToActivity.PostRequestTo(*sp, TEPeer::TLeaveRequest().CRef()); |
|
1232 sp->SetFlags(TCFClientType::ELeaving); |
|
1233 } |
|
1234 else |
|
1235 { |
|
1236 //Didn't leave, no need for waiting for TLeaveComplete; |
|
1237 bindToActivity.SetIdle(); |
|
1238 } |
|
1239 sp->ClearFlags(TCFClientType::EActive); |
|
1240 } |
|
1241 else |
|
1242 { |
|
1243 //Didn't leave, no need for waiting for TLeaveComplete; |
|
1244 bindToActivity.SetIdle(); |
|
1245 } |
|
1246 |
|
1247 if (!bindToActivity.iNewServiceProvider.IsNull() && (sp == NULL || sp->RecipientId() != bindToActivity.iNewServiceProvider)) |
|
1248 { |
|
1249 RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider); |
|
1250 if (newServiceProvider) |
|
1251 { |
|
1252 __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState)); |
|
1253 newServiceProvider->ClearFlags(TCFClientType::EActivating); |
|
1254 newServiceProvider->SetFlags(TCFClientType::EActive); |
|
1255 // Note: iContext.Node().ServiceProvider() must be re-evaluated in the ASSERT below (i.e. don't use any previously cached value). |
|
1256 __ASSERT_DEBUG(iContext.Node().ServiceProvider() == newServiceProvider, User::Panic(KCorePrPanic, KPanicIncorrectState)); |
|
1257 } |
|
1258 } |
|
1259 bindToActivity.iNewServiceProvider = TNodeId::NullId(); |
|
1260 } |
|
1261 |
|
1262 EXPORT_DEFINE_SMELEMENT(CBindToActivity::TCancel, NetStateMachine::MStateTransition, CBindToActivity::TContext) |
|
1263 void CBindToActivity::TCancel::DoL() |
|
1264 { |
|
1265 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1266 CBindToActivity& bindToActivity = static_cast<CBindToActivity&>(*iContext.iNodeActivity); |
|
1267 TInt count = bindToActivity.iSuccessfulDataClients.Count(); |
|
1268 while (count ) |
|
1269 { |
|
1270 bindToActivity.PostRequestTo(*bindToActivity.iSuccessfulDataClients[--count], TEBase::TCancel().CRef()); |
|
1271 }; |
|
1272 bindToActivity.iSuccessfulDataClients.Reset(); |
|
1273 |
|
1274 TBool setIdle = ETrue; |
|
1275 if (!bindToActivity.iNewServiceProvider.IsNull()) |
|
1276 { |
|
1277 RNodeInterface* newServiceProvider = iContext.Node().FindClient(bindToActivity.iNewServiceProvider); |
|
1278 if (newServiceProvider && newServiceProvider != iContext.Node().ServiceProvider()) |
|
1279 { |
|
1280 __ASSERT_DEBUG(newServiceProvider->Flags() & TCFClientType::EActivating, User::Panic(KCorePrPanic, KPanicIncorrectState)); |
|
1281 newServiceProvider->ClearFlags(TCFClientType::EActivating); |
|
1282 if (bindToActivity.ShouldLeaveServiceProvider()) |
|
1283 { |
|
1284 bindToActivity.PostRequestTo(*newServiceProvider, TEPeer::TLeaveRequest().CRef()); |
|
1285 newServiceProvider->SetFlags(TCFClientType::ELeaving); |
|
1286 setIdle = EFalse; |
|
1287 } |
|
1288 } |
|
1289 } |
|
1290 |
|
1291 if (setIdle) |
|
1292 { |
|
1293 bindToActivity.SetIdle(); |
|
1294 } |
|
1295 bindToActivity.iNewServiceProvider = TNodeId::NullId(); |
|
1296 } |
|
1297 |
|
1298 |
|
1299 //-========================================================= |
|
1300 // |
|
1301 //Rejoin DataClient Activity |
|
1302 // |
|
1303 //-========================================================= |
|
1304 EXPORT_C MeshMachine::CNodeActivityBase* CRejoinDataClientActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
1305 { |
|
1306 TUint c = GetNextActivityCountL(aActivitySig,aNode); |
|
1307 return new(ELeave)CRejoinDataClientActivity(aActivitySig, c, aNode); |
|
1308 } |
|
1309 |
|
1310 CRejoinDataClientActivity::~CRejoinDataClientActivity() |
|
1311 { |
|
1312 if ( iDataClients.Count() ) |
|
1313 { |
|
1314 if (Error() != KErrNone) |
|
1315 { |
|
1316 //An error has occured when processing rejoin as the activity hasn't been properly wrapped |
|
1317 //up. This error must have happened before any of the clients have been added to the new |
|
1318 //owner as such addition must either collectively succeed or collectively fail. Reinstall |
|
1319 //clients in at the current owner. |
|
1320 for (TInt i = 0; i < iDataClients.Count(); i++) |
|
1321 { |
|
1322 if (!(iDataClients[i].iDataClient.Flags() & TCFClientType::EActive)) |
|
1323 { |
|
1324 #ifndef __GCCXML__ |
|
1325 //If the dataclient managed to report idle in the mean time, have him destroyed |
|
1326 RClientInterface::OpenPostMessageClose(iNode.Id(), iDataClients[i].iDataClient.RecipientId(), TEChild::TDestroy().CRef()); |
|
1327 #endif |
|
1328 } |
|
1329 iDataClients[i].iDataClient.ClearFlags(TCFClientType::EActivating); |
|
1330 #ifndef __GCCXML__ |
|
1331 //Simulate client leaving on the new owner. |
|
1332 RClientInterface::OpenPostMessageClose(iDataClients[i].iDataClient.RecipientId(), iDataClients[i].iNewOwner, |
|
1333 TEChild::TLeft().CRef()); |
|
1334 #endif |
|
1335 } |
|
1336 } |
|
1337 else |
|
1338 { |
|
1339 //All clear. Remove the clients for good. |
|
1340 for (TInt i = 0; i < iDataClients.Count(); i++) |
|
1341 { |
|
1342 iNode.RemoveClient(iDataClients[i].iDataClient.RecipientId()); |
|
1343 } |
|
1344 } |
|
1345 } |
|
1346 iDataClients.Reset(); |
|
1347 } |
|
1348 |
|
1349 |
|
1350 void CRejoinDataClientActivity::TCFDataClientJoiningRequest::DispatchL(const TRuntimeCtxId& aSender, const TRuntimeCtxId& aRecipient) |
|
1351 { |
|
1352 const TNodeId& nodeId = address_cast<const TNodeId>(aRecipient); //This message type operates on nodes |
|
1353 MeshMachine::AMMNodeBase* nodeBase = reinterpret_cast<MeshMachine::AMMNodeBase*>(nodeId.Node().FetchNodeInterfaceL(AMMNodeBase::KInterfaceId)); |
|
1354 RNodeInterface* client = NULL; |
|
1355 client = nodeBase->AddClientL(iDataClient, iDataClientType); |
|
1356 client->SetFlags(TCFClientType::EJoining|TCFClientType::EStarted); |
|
1357 RClientInterface::OpenPostMessageClose(nodeId, aSender, TCFPeer::TJoinComplete().CRef()); |
|
1358 } |
|
1359 |
|
1360 |
|
1361 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TAwaitingJoinComplete, NetStateMachine::MState, CRejoinDataClientActivity::TContext) |
|
1362 TBool CRejoinDataClientActivity::TAwaitingJoinComplete::Accept() |
|
1363 { |
|
1364 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 13)); |
|
1365 if (iContext.iMessage.IsMessage<TCFPeer::TJoinComplete>()) |
|
1366 { |
|
1367 return ETrue; |
|
1368 } |
|
1369 else if (iContext.iMessage.IsMessage<TEBase::TError>()) |
|
1370 { |
|
1371 iContext.iNodeActivity->SetError(message_cast<TEBase::TError>(iContext.iMessage).iValue); |
|
1372 iContext.iNodeActivity->SetIdle(); |
|
1373 iContext.iMessage.ClearMessageId(); |
|
1374 } |
|
1375 return EFalse; |
|
1376 } |
|
1377 |
|
1378 |
|
1379 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinDataClient, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext) |
|
1380 EXPORT_C void CRejoinDataClientActivity::TRejoinDataClient::DoL() |
|
1381 { |
|
1382 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 14)); |
|
1383 CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity); |
|
1384 |
|
1385 TCFRejoiningProvider::TRejoinDataClientRequest& rejoinDCMsg = message_cast<TCFRejoiningProvider::TRejoinDataClientRequest>(iContext.iMessage); |
|
1386 RNodeInterface* subject = iContext.Node().FindClient(rejoinDCMsg.iNodeId1); |
|
1387 if (NULL == subject //client not found |
|
1388 || subject->Flags() & TCFClientType::ELeaving //client leaving/gone |
|
1389 || !(subject->Flags() & TCFClientType::EActive)) //client reported idle or never bound to |
|
1390 { |
|
1391 User::Leave(KErrNotFound); |
|
1392 } |
|
1393 if (subject->Flags() & TCFClientType::EActivating) //client requested by someone |
|
1394 { |
|
1395 User::Leave(KErrInUse); |
|
1396 } |
|
1397 |
|
1398 rejoinActivity->iDataClients.AppendL(TMigrationPairs(*subject, rejoinDCMsg.iNodeId2)); |
|
1399 |
|
1400 CRejoinDataClientActivity::TCFDataClientJoiningRequest msg(subject->RecipientId(), subject->ClientType()); |
|
1401 |
|
1402 RClientInterface::OpenPostMessageClose( |
|
1403 iContext.NodeId(), |
|
1404 rejoinDCMsg.iNodeId2, |
|
1405 msg); |
|
1406 |
|
1407 //Set Client being migrated to a new owner.. reference handed over. secure lifetime. |
|
1408 subject->SetFlags(TCFClientType::EActivating); |
|
1409 } |
|
1410 |
|
1411 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TApplyRejoin, NetStateMachine::MStateTransition, CRejoinDataClientActivity::TContext) |
|
1412 void CRejoinDataClientActivity::TApplyRejoin::DoL() |
|
1413 { |
|
1414 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 15)); |
|
1415 CRejoinDataClientActivity* rejoinActivity = static_cast<CRejoinDataClientActivity*>(iContext.iNodeActivity); |
|
1416 __ASSERT_DEBUG(rejoinActivity->iDataClients.Count(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 16)); |
|
1417 for (TInt i = 0; i < rejoinActivity->iDataClients.Count(); i++) |
|
1418 { |
|
1419 RClientInterface::OpenPostMessageClose(iContext.NodeId(), rejoinActivity->iDataClients[i].iDataClient.RecipientId(), |
|
1420 TCFFlow::TRejoin(rejoinActivity->iDataClients[i].iNewOwner).CRef()); |
|
1421 rejoinActivity->iDataClients[i].iDataClient.SetFlags(TCFClientType::ELeaving); |
|
1422 } |
|
1423 rejoinActivity->PostRequestTo(iContext.NodeId(), TCFScpr::TApplyRequest().CRef()); |
|
1424 } |
|
1425 |
|
1426 EXPORT_DEFINE_SMELEMENT(CRejoinDataClientActivity::TRejoinLoopTag,NetStateMachine::MStateFork, CRejoinDataClientActivity::TContext) |
|
1427 EXPORT_C TInt CRejoinDataClientActivity::TRejoinLoopTag::TransitionTag() |
|
1428 { |
|
1429 if (iContext.iMessage.IsMessage<TCFRejoiningProvider::TRejoinDataClientRequest>()) |
|
1430 { |
|
1431 return CoreStates::KLoopTag | NetStateMachine::EBackward; |
|
1432 } |
|
1433 return MeshMachine::KNoTag | NetStateMachine::EForward; |
|
1434 } |
|
1435 |
|
1436 //-========================================================= |
|
1437 // |
|
1438 // CommsBinderActivity (parallel) |
|
1439 // |
|
1440 //-========================================================= |
|
1441 |
|
1442 EXPORT_C MeshMachine::CNodeActivityBase* CCommsBinderActivity::NewL( const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode ) |
|
1443 { |
|
1444 TUint c = GetNextActivityCountL(aActivitySig,aNode); |
|
1445 return new(ELeave)CCommsBinderActivity(aActivitySig, aNode, c); |
|
1446 } |
|
1447 |
|
1448 EXPORT_C CCommsBinderActivity::CCommsBinderActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aNextActivityCount) |
|
1449 : MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aNextActivityCount), |
|
1450 TIfStaticFetcherNearestInHierarchy(this) |
|
1451 { |
|
1452 } |
|
1453 |
|
1454 //-========================================================= |
|
1455 // |
|
1456 // CCommsBinderActivity |
|
1457 // |
|
1458 // Aggregate class containing common functionality for |
|
1459 // CommsBinderActivity and CCommsBinderCombiningActivity. |
|
1460 // |
|
1461 //-========================================================= |
|
1462 |
|
1463 EXPORT_C TBool CCommsBinderActivity::TDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext) |
|
1464 { |
|
1465 TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId()); |
|
1466 __ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 17)); //Diagnostic |
|
1467 if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext)) |
|
1468 { |
|
1469 return EFalse; |
|
1470 } |
|
1471 return ETrue; |
|
1472 } |
|
1473 |
|
1474 EXPORT_C TBool CCommsBinderActivity::TDefaultDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext) |
|
1475 { |
|
1476 TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId()); |
|
1477 __ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 18)); //Diagnostic |
|
1478 if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext, TCFClientType::EDefault)) |
|
1479 { |
|
1480 return EFalse; |
|
1481 } |
|
1482 return ETrue; |
|
1483 } |
|
1484 |
|
1485 EXPORT_C /*virtual*/ CCommsBinderActivity::~CCommsBinderActivity() |
|
1486 { |
|
1487 if(!iBinderRequestParameters.IsNull()) |
|
1488 { |
|
1489 iBinderRequestParameters.Close(); |
|
1490 } |
|
1491 } |
|
1492 |
|
1493 EXPORT_C void CCommsBinderActivity::StoreBinder(RNodeInterface* aDataClient) |
|
1494 { |
|
1495 __ASSERT_DEBUG(iPendingBinder == aDataClient || iPendingBinder == NULL, User::Panic(KSpecAssert_ESockCrStaCPRAC, 19)); |
|
1496 iPendingBinder = aDataClient; |
|
1497 } |
|
1498 |
|
1499 EXPORT_C RNodeInterface* CCommsBinderActivity::Binder() const |
|
1500 { |
|
1501 return iPendingBinder; |
|
1502 } |
|
1503 |
|
1504 EXPORT_C void CCommsBinderActivity::StoreBinderRequestParameters(const RCFParameterFamilyBundleC& aBinderRequestParameters) |
|
1505 { |
|
1506 __ASSERT_DEBUG(iBinderRequestParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 20)); |
|
1507 if(! aBinderRequestParameters.IsNull()) |
|
1508 { |
|
1509 iBinderRequestParameters.Open(aBinderRequestParameters); |
|
1510 } |
|
1511 } |
|
1512 |
|
1513 void CCommsBinderActivity::SendCustomFlowProvision() |
|
1514 /** |
|
1515 Send a custom message that provisions a flow with flow parameters |
|
1516 */ |
|
1517 { |
|
1518 __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 21)); |
|
1519 |
|
1520 // Only send the message if we have parameters to send |
|
1521 if(!iBinderRequestParameters.IsNull()) |
|
1522 { |
|
1523 RParameterFamily parameterFamily = |
|
1524 iBinderRequestParameters.FindFamily(KFlowParametersFamily); |
|
1525 |
|
1526 if(!parameterFamily.IsNull()) |
|
1527 { |
|
1528 STypeId typeId = STypeId::CreateSTypeId(CFlowRequestParameters::EUid, CFlowRequestParameters::EType); |
|
1529 CFlowRequestParameters* flowParams = static_cast<CFlowRequestParameters*>(parameterFamily.FindParameterSet(typeId, RParameterFamily::ERequested)); |
|
1530 |
|
1531 iPendingBinder->PostMessage( |
|
1532 iNode.Id(), |
|
1533 TCFInternalEsock::TFlowProvision( |
|
1534 flowParams->GetFlowParams() |
|
1535 ).CRef() |
|
1536 ); |
|
1537 } |
|
1538 } |
|
1539 } |
|
1540 |
|
1541 |
|
1542 void CCommsBinderActivity::SendBinderResponseToOriginator() |
|
1543 /** |
|
1544 Send out CommsBinderResponse to all originators. |
|
1545 |
|
1546 We send to all originators that have joined up until this point, and store this count |
|
1547 in iOriginatorsCountSnapshot. See comment in ProcessBindToComplete(). |
|
1548 */ |
|
1549 { |
|
1550 __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 22)); |
|
1551 |
|
1552 PostRequestTo( |
|
1553 address_cast<Messages::TNodeId>(FirstOriginator().RecipientId()), |
|
1554 TCFServiceProvider::TCommsBinderResponse(iPendingBinder->RecipientId()).CRef()); |
|
1555 |
|
1556 iPendingBinder->SetFlags(TCFClientType::EActivating); |
|
1557 } |
|
1558 |
|
1559 void CCommsBinderActivity::BindToComplete() |
|
1560 { |
|
1561 __ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 23)); |
|
1562 TUint c = iNode.CountActivities(ActivitySigId()); |
|
1563 // Note: this routine can be used with parallel and non-parallel binder activities. In the |
|
1564 // former case we start with multiple activities and eventually end up with a single one. In |
|
1565 // the latter case we have a single activity throughout. |
|
1566 if(c == 1) |
|
1567 { |
|
1568 iPendingBinder->ClearFlags(TCFClientType::EActivating); |
|
1569 } |
|
1570 iPendingBinder = NULL; |
|
1571 } |
|
1572 |
|
1573 // |
|
1574 // CCommsBinderActivity methods that are embedded transitions/states/stateforks |
|
1575 // |
|
1576 |
|
1577 EXPORT_C RNodeInterface* CCommsBinderActivity::IsDataClientPresent(TNodeContextBase& aContext, TUint aClientFlags) |
|
1578 /** |
|
1579 Check if we have a data client and, if so, store it as the binder for this activity. |
|
1580 |
|
1581 @param aContext Node context |
|
1582 @param aClientFlags client flags to use in iterator check |
|
1583 @return ETrue if data client present, else EFalse. |
|
1584 */ |
|
1585 { |
|
1586 // Be careful not to use a client to which we have already sent TDestroy previously. |
|
1587 // Find the first data client that does not have the ELeaving flag set. If all are |
|
1588 // marked ELeaving then return EFalse - they are on the way out and will disappear |
|
1589 // eventually. The effect will be that a new data client will be created. |
|
1590 RNodeInterface* dataClient = aContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, aClientFlags), TClientType(0, TCFClientType::ELeaving)); |
|
1591 return dataClient; |
|
1592 } |
|
1593 |
|
1594 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext) |
|
1595 EXPORT_C TInt CCommsBinderActivity::TNoTagOrUseExisting::TransitionTag() |
|
1596 { |
|
1597 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 24)); |
|
1598 TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage); |
|
1599 |
|
1600 // Save away the parameters sent to us so that they are accessible during the activity |
|
1601 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported)); |
|
1602 CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId)); |
|
1603 intf->StoreBinderRequestParameters(msg.iFamilyBundle); |
|
1604 |
|
1605 if(msg.iValue == TSubConnOpen::EAttachToDefault) |
|
1606 { |
|
1607 RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext); |
|
1608 if (dc) |
|
1609 { |
|
1610 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported)); |
|
1611 CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId)); |
|
1612 |
|
1613 intf->StoreBinder(dc); |
|
1614 return CoreStates::KUseExisting; |
|
1615 } |
|
1616 } |
|
1617 return MeshMachine::KNoTag; |
|
1618 } |
|
1619 |
|
1620 //MZTODO - logic of: |
|
1621 //TNoTagOrWaitForIncomingOrUseExisting |
|
1622 //& |
|
1623 //TNoTagOrWaitForIncomingOrUseExistingDefault |
|
1624 //has been copied but does not seem right, as both use EDefault? |
|
1625 //Why? |
|
1626 |
|
1627 //[401TODO] DL : Only one of TNoTagOrWaitForIncomingOrUseExisting(Default) is used, is it ok to nuke one? |
|
1628 |
|
1629 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting, NetStateMachine::MStateFork, CCommsBinderActivity::TContext) |
|
1630 EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExisting::TransitionTag() |
|
1631 { |
|
1632 TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage); |
|
1633 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 25)); |
|
1634 |
|
1635 if (msg.iValue == TSubConnOpen::EWaitForIncoming) |
|
1636 { |
|
1637 return CoreNetStates::KWaitForIncoming; |
|
1638 } |
|
1639 |
|
1640 else |
|
1641 { |
|
1642 RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault); |
|
1643 if (dc) |
|
1644 { |
|
1645 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported)); |
|
1646 CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId)); |
|
1647 |
|
1648 intf->StoreBinder(dc); |
|
1649 return CoreStates::KUseExisting; |
|
1650 } |
|
1651 } |
|
1652 |
|
1653 return MeshMachine::KNoTag; |
|
1654 } |
|
1655 |
|
1656 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault, NetStateMachine::MStateFork, CCommsBinderActivity::TContext) |
|
1657 EXPORT_C TInt CCommsBinderActivity::TNoTagOrWaitForIncomingOrUseExistingDefault::TransitionTag() |
|
1658 { |
|
1659 TCFServiceProvider::TCommsBinderRequest& msg = message_cast<TCFServiceProvider::TCommsBinderRequest>(iContext.iMessage); |
|
1660 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 26)); |
|
1661 |
|
1662 if(msg.iValue == TSubConnOpen::EAttachToDefault) |
|
1663 { |
|
1664 RNodeInterface* dc = CCommsBinderActivity::IsDataClientPresent(iContext, TCFClientType::EDefault); |
|
1665 if (dc) |
|
1666 { |
|
1667 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported)); |
|
1668 CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId)); |
|
1669 |
|
1670 intf->StoreBinder(dc); |
|
1671 return CoreStates::KUseExisting; |
|
1672 } |
|
1673 } |
|
1674 else if (msg.iValue == TSubConnOpen::EWaitForIncoming) |
|
1675 { |
|
1676 return CoreNetStates::KWaitForIncoming; |
|
1677 } |
|
1678 return MeshMachine::KNoTag; |
|
1679 } |
|
1680 |
|
1681 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TStorePendingBinder, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext) |
|
1682 EXPORT_C void CCommsBinderActivity::TStorePendingBinder::DoL() |
|
1683 { |
|
1684 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 27)); |
|
1685 message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage); |
|
1686 |
|
1687 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported)); |
|
1688 CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId)); |
|
1689 |
|
1690 intf->StoreBinder(iContext.iPeer); |
|
1691 } |
|
1692 |
|
1693 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendBinderResponse, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext) |
|
1694 EXPORT_C void CCommsBinderActivity::TSendBinderResponse::DoL() |
|
1695 { |
|
1696 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 28)); |
|
1697 |
|
1698 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported)); |
|
1699 CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId)); |
|
1700 |
|
1701 intf->SendBinderResponseToOriginator(); |
|
1702 } |
|
1703 |
|
1704 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TSendCustomFlowProvision, NetStateMachine::MStateTransition, CCommsBinderActivity::TContext) |
|
1705 EXPORT_C void CCommsBinderActivity::TSendCustomFlowProvision::DoL() |
|
1706 { |
|
1707 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 29)); |
|
1708 |
|
1709 __ASSERT_DEBUG(iContext.iNodeActivity->SupportsExtInterface(CCommsBinderActivity::KInterfaceId), User::Panic(KCorePrPanic, KPanicExtInterfaceNotSupported)); |
|
1710 CCommsBinderActivity* intf = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId)); |
|
1711 |
|
1712 intf->SendCustomFlowProvision(); |
|
1713 } |
|
1714 |
|
1715 EXPORT_DEFINE_SMELEMENT(CCommsBinderActivity::TAwaitingBindToComplete, NetStateMachine::MState, PRStates::TContext) |
|
1716 EXPORT_C TBool CCommsBinderActivity::TAwaitingBindToComplete::Accept() |
|
1717 { |
|
1718 CoreNetStates::TAwaitingBindToComplete awaitingBindToComplete(iContext); |
|
1719 if (awaitingBindToComplete.Accept()) |
|
1720 { |
|
1721 CCommsBinderActivity* binderActivity = reinterpret_cast<CCommsBinderActivity*>(iContext.iNodeActivity->FetchExtInterface(CCommsBinderActivity::KInterfaceId)); |
|
1722 __ASSERT_DEBUG(binderActivity, User::Panic(KSpecAssert_ESockCrStaCPRAC, 30)); |
|
1723 binderActivity->BindToComplete(); |
|
1724 iContext.Node().DestroyOrphanedDataClients(); |
|
1725 return ETrue; |
|
1726 } |
|
1727 return EFalse; |
|
1728 } |
|
1729 |
|
1730 //-========================================================= |
|
1731 // |
|
1732 //CNoBearer Activity |
|
1733 // |
|
1734 //-========================================================= |
|
1735 |
|
1736 CNoBearer::CNoBearer(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode, TUint aActivitiesCount) |
|
1737 : MeshMachine::CNodeRetryParallelActivity(aActivitySig, aNode, aActivitiesCount), |
|
1738 ABindingActivity(aNode.Id()), |
|
1739 TIfStaticFetcherNearestInHierarchy(this) |
|
1740 { |
|
1741 } |
|
1742 |
|
1743 /*virtual*/ CNoBearer::~CNoBearer() |
|
1744 { |
|
1745 iNoBearerParameters.Close(); |
|
1746 } |
|
1747 |
|
1748 EXPORT_C MeshMachine::CNodeActivityBase* CNoBearer::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
1749 { |
|
1750 TUint c = GetNextActivityCountL(aActivitySig,aNode); |
|
1751 return new(ELeave)CNoBearer(aActivitySig, aNode, c); |
|
1752 } |
|
1753 |
|
1754 EXPORT_C TNodePeerId& CNoBearer::GetOriginator() |
|
1755 { |
|
1756 __ASSERT_DEBUG(iOriginators.Count() == 1, User::Panic(KSpecAssert_ESockCrStaCPRAC, 31)); |
|
1757 return iOriginators[0]; |
|
1758 } |
|
1759 |
|
1760 EXPORT_C void CNoBearer::ReturnInterfacePtrL(CoreActivities::ABindingActivity*& aInterface) |
|
1761 { |
|
1762 aInterface = this; |
|
1763 } |
|
1764 |
|
1765 EXPORT_C TBool CNoBearer::TServiceProviderMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext) |
|
1766 { |
|
1767 TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId()); |
|
1768 __ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 32)); //Diagnostic |
|
1769 if (c == 1 || aContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)) != 0) |
|
1770 { |
|
1771 return EFalse; |
|
1772 } |
|
1773 return ETrue; |
|
1774 } |
|
1775 |
|
1776 EXPORT_DEFINE_SMELEMENT(CNoBearer::TRequestCommsBinder, NetStateMachine::MStateTransition, CNoBearer::TContext) |
|
1777 EXPORT_C void CNoBearer::TRequestCommsBinder::DoL() |
|
1778 { |
|
1779 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1780 CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity); |
|
1781 |
|
1782 RNodeInterface* sp = iContext.Node().ServiceProvider(); |
|
1783 __ASSERT_DEBUG(sp, User::Panic(KCorePrPanic, KPanicNoServiceProvider)); |
|
1784 |
|
1785 TSubConnOpen::TSubConnType type = TSubConnOpen::EAttachToDefault; |
|
1786 if (!(noBearer.GetOriginator().Flags() & TCFClientType::EDefault)) |
|
1787 { |
|
1788 type = TSubConnOpen::ECreateNew; |
|
1789 } |
|
1790 |
|
1791 noBearer.PostRequestTo( |
|
1792 *sp, |
|
1793 TCFServiceProvider::TCommsBinderRequest( |
|
1794 type, noBearer.iNoBearerParameters |
|
1795 ).CRef() |
|
1796 ); |
|
1797 } |
|
1798 |
|
1799 EXPORT_DEFINE_SMELEMENT(CNoBearer::TStoreRequestParameters, NetStateMachine::MStateTransition, CNoBearer::TContext) |
|
1800 EXPORT_C void CNoBearer::TStoreRequestParameters::DoL() |
|
1801 { |
|
1802 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1803 CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity); |
|
1804 const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage); |
|
1805 __ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 33)); // handle should be empty when this fn is called |
|
1806 if(noBearerMessage.iFamilyBundle.IsNull()) |
|
1807 { |
|
1808 noBearer.iNoBearerParameters.Open(); |
|
1809 } |
|
1810 else |
|
1811 { |
|
1812 noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle); |
|
1813 } |
|
1814 } |
|
1815 |
|
1816 EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrDataClientsToStart, NetStateMachine::MStateFork, CNoBearer::TContext) |
|
1817 TInt CNoBearer::TNoTagOrDataClientsToStart::TransitionTag() |
|
1818 { |
|
1819 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1820 CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity); |
|
1821 |
|
1822 const TNodePeerId& originator = activity.GetOriginator(); |
|
1823 __ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 34)); |
|
1824 |
|
1825 if (activity.Error() == KErrNone && (originator.Flags() & (TCFClientType::EStarting|TCFClientType::EStarted|TCFClientType::ELeaving)) == 0) |
|
1826 { |
|
1827 //Start dc |
|
1828 return CoreNetStates::KDataClientsToStart; |
|
1829 } |
|
1830 //Finish the activity |
|
1831 return MeshMachine::KNoTag; |
|
1832 } |
|
1833 |
|
1834 EXPORT_DEFINE_SMELEMENT(CNoBearer::TStartOriginatingDataClient, NetStateMachine::MStateTransition, CNoBearer::TContext) |
|
1835 void CNoBearer::TStartOriginatingDataClient::DoL() |
|
1836 { |
|
1837 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1838 CNoBearer& activity = static_cast<CNoBearer&>(*iContext.iNodeActivity); |
|
1839 TNodePeerId& originator = activity.GetOriginator(); |
|
1840 __ASSERT_DEBUG(originator.Type() & TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRAC, 35)); |
|
1841 activity.PostRequestTo(originator.Peer(), TCFDataClient::TStart().CRef()); |
|
1842 originator.SetFlags(TCFClientType::EStarting); |
|
1843 } |
|
1844 |
|
1845 EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresent, NetStateMachine::MStateFork, CNoBearer::TContext) |
|
1846 EXPORT_C TInt CNoBearer::TNoTagOrBearerPresent::TransitionTag() |
|
1847 { |
|
1848 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1849 CNoBearer& noBearer = static_cast<CNoBearer&>(*iContext.iNodeActivity); |
|
1850 const TCFControlProvider::TNoBearer& noBearerMessage = message_cast<TCFControlProvider::TNoBearer>(iContext.iMessage); |
|
1851 __ASSERT_DEBUG(noBearer.iNoBearerParameters.IsNull(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 36)); // should not yet be set when this fn is called |
|
1852 noBearer.iNoBearerParameters.Open(noBearerMessage.iFamilyBundle); |
|
1853 |
|
1854 CoreNetStates::TNoTagOrBearerPresent fork(iContext); |
|
1855 return fork.TransitionTag(); |
|
1856 } |
|
1857 |
|
1858 EXPORT_DEFINE_SMELEMENT(CNoBearer::TNoTagOrBearerPresentForAutostart, NetStateMachine::MStateFork, CNoBearer::TContext) |
|
1859 EXPORT_C TInt CNoBearer::TNoTagOrBearerPresentForAutostart::TransitionTag() |
|
1860 { |
|
1861 TInt cntrlClients = iContext.Node().CountClients<TDefaultClientMatchPolicy>( |
|
1862 /*include*/TClientType(TCFClientType::ECtrl)); |
|
1863 if (cntrlClients > 0 && |
|
1864 iContext.Node().ServiceProvider() && |
|
1865 !(iContext.Node().ServiceProvider()->Flags() & TCFClientType::EStarted)) |
|
1866 { |
|
1867 //This fork calculates if the NoBearer activity (which this fork has been implemented for) |
|
1868 //should attempt to autostart the service provider when returning it to the sender of TNoBearer. |
|
1869 //The philosphy here is that if the local node doesn't have a control client, then there's noone |
|
1870 //that could posibly start it. It will hence decide to autostart as the top layer of what looks |
|
1871 //like an implicit connection. In the future this autostart behaviour should become a specialty |
|
1872 //of someone more concrete (rather than generic function). We are speculating about the implicit |
|
1873 //top layer that could acquire this function if it ever comes into being. |
|
1874 return CoreNetStates::KBearerPresent; |
|
1875 } |
|
1876 return KNoTag; |
|
1877 } |
|
1878 |
|
1879 |
|
1880 //-========================================================= |
|
1881 // |
|
1882 //CStartActivity Activity |
|
1883 // |
|
1884 //-========================================================= |
|
1885 CStartActivity::CStartActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
1886 : MeshMachine::CNodeRetryActivity(aActivitySig, aNode), |
|
1887 CoreActivities::ABindingActivity(aNode.Id()), |
|
1888 TIfStaticFetcherNearestInHierarchy(this) |
|
1889 { |
|
1890 } |
|
1891 |
|
1892 EXPORT_C CStartActivity::~CStartActivity() |
|
1893 { |
|
1894 } |
|
1895 |
|
1896 EXPORT_C MeshMachine::CNodeActivityBase* CStartActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
1897 { |
|
1898 return new (ELeave) CStartActivity(aActivitySig, aNode); |
|
1899 } |
|
1900 |
|
1901 //-========================================================= |
|
1902 // |
|
1903 //Gone Down Activity |
|
1904 // |
|
1905 //-========================================================= |
|
1906 MeshMachine::CNodeActivityBase* CGoneDownActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
1907 { |
|
1908 CGoneDownActivity* self = new (ELeave) CGoneDownActivity(aActivitySig,aNode); |
|
1909 return self; |
|
1910 } |
|
1911 |
|
1912 CGoneDownActivity::CGoneDownActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode) |
|
1913 : MeshMachine::CNodeRetryActivity(aActivitySig, aNode) |
|
1914 { |
|
1915 } |
|
1916 |
|
1917 CGoneDownActivity::~CGoneDownActivity() |
|
1918 { |
|
1919 //This is a gone down activity. Error mode is its only/natural state |
|
1920 //CGoneDownActivity inherits ultimatelly from CNodeActivityBase, which |
|
1921 //will attempt to interpret the error mode as a failure to execute (and |
|
1922 //auto respond to orignators), which we don't want. Hence clearing |
|
1923 //the error and allowing 'this' to die peacefully. |
|
1924 SetError(KErrNone); |
|
1925 } |
|
1926 |
|
1927 void CGoneDownActivity::StartL(TNodeContextBase& aContext, const Messages::XNodePeerId& aOriginator, const TStateTriple& aFirst) |
|
1928 { |
|
1929 //399TODO: for the moment ignore duplicated TGoneDown messages |
|
1930 //but this needs to be fixed (someone is sending TGoneDown from TSendDataClientStopped |
|
1931 //hence the problem) |
|
1932 |
|
1933 //ASSERT(IsIdle()); |
|
1934 if (!IsIdle()) |
|
1935 { |
|
1936 return; |
|
1937 } |
|
1938 |
|
1939 //This activity provides service for only one single requestor at a time. |
|
1940 __ASSERT_DEBUG(iOriginators.Count()==0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 37)); //Diagnostic panic |
|
1941 |
|
1942 TCFControlClient::TGoneDown& msg = message_cast<TCFControlClient::TGoneDown>(aContext.iMessage); |
|
1943 SetError(msg.iValue1); |
|
1944 iGoneDownApId = msg.iValue2; |
|
1945 |
|
1946 MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->starting activity"), this)); |
|
1947 NetStateMachine::ACore::Start(&aContext, aFirst); |
|
1948 |
|
1949 MESH_LOG_ACTIVITY_EXT(KMeshMachineSubTag, this, &aContext, (_L8("CGoneDownActivity %08x:\tStartL->activity started"), this)); |
|
1950 (void)aOriginator; |
|
1951 } |
|
1952 |
|
1953 //Find next DC to rebind |
|
1954 TBool CGoneDownActivity::IsIdle() const |
|
1955 { |
|
1956 return NetStateMachine::ACore::IsIdle(); |
|
1957 } |
|
1958 |
|
1959 DEFINE_SMELEMENT(CGoneDownActivity::TSendErrorRecoveryReq, NetStateMachine::MStateTransition, CGoneDownActivity::TContext) |
|
1960 void CGoneDownActivity::TSendErrorRecoveryReq::DoL() |
|
1961 { |
|
1962 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
1963 CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity); |
|
1964 |
|
1965 //TInt error = ExtractErrorCode(iContext.iMessage); |
|
1966 TErrContext ctx(iContext.NodeId(), TCFControlClient::TGoneDown::Id(), activity.ActivitySigId(), TStateChange(0, activity.Error())); |
|
1967 ctx.iInfo = (TAny*)activity.iGoneDownApId; |
|
1968 TEErrorRecovery::TErrorRecoveryRequest msg(ctx); |
|
1969 |
|
1970 //We can not set SetSentTo() to Control Provider, because the response may not be coming from it |
|
1971 //(for example it could be coming from the MCpr and we could be the SCpr). |
|
1972 //Normally this would be a problem because any unrelated TError message arriving to the node |
|
1973 //and presented to the awaiting state would easily be confused with the response (TError == |
|
1974 //no recovery on the MCpr == EPropagate). |
|
1975 //We avoid the problem by checking all arriving TError messages if they are adressed to our activity. |
|
1976 __ASSERT_DEBUG(iContext.Node().ControlProvider(), User::Panic(KCorePrPanic, KPanicNoControlProvider)); |
|
1977 activity.PostRequestTo(*iContext.Node().ControlProvider(), |
|
1978 TCFSafeMessage::TRequestCarrierEast<TEErrorRecovery::TErrorRecoveryRequest>(msg).CRef()); |
|
1979 activity.ClearPostedTo(); |
|
1980 } |
|
1981 |
|
1982 DEFINE_SMELEMENT(CGoneDownActivity::TIgnoreOrPropagate, NetStateMachine::MStateFork, CGoneDownActivity::TContext) |
|
1983 TInt CGoneDownActivity::TIgnoreOrPropagate::TransitionTag() |
|
1984 { |
|
1985 __ASSERT_DEBUG(iContext.iMessage.IsMessage<TEErrorRecovery::TErrorRecoveryResponse>(), User::Panic(KSpecAssert_ESockCrStaCPRAC, 38)); |
|
1986 RNodeInterface* sp = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted)); |
|
1987 if (sp) |
|
1988 { |
|
1989 return CoreStates::KIgnore | NetStateMachine::EForward; |
|
1990 } |
|
1991 //There is no started service provider, the reconnection, mobility, etc must have failed, |
|
1992 //continue with tearing this layer down. |
|
1993 CGoneDownActivity& activity = static_cast<CGoneDownActivity&>(*iContext.iNodeActivity); |
|
1994 TErrResponse& resp = message_cast<TEErrorRecovery::TErrorRecoveryResponse>(iContext.iMessage).iErrResponse; |
|
1995 resp.iAction=TErrResponse::EPropagate; |
|
1996 __ASSERT_DEBUG(activity.Error()!=KErrNone, User::Panic(KSpecAssert_ESockCrStaCPRAC, 39)); |
|
1997 resp.iError = activity.Error(); |
|
1998 return CoreStates::KPropagate | NetStateMachine::EForward; |
|
1999 } |
|
2000 |
|
2001 |
|
2002 EXPORT_DEFINE_SMELEMENT(CStartActivity::TAwaitingBindToCompleteOrCancel, NetStateMachine::MState, CStartActivity::TContext) |
|
2003 TBool CStartActivity::TAwaitingBindToCompleteOrCancel::Accept() |
|
2004 { |
|
2005 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCorePrPanic, KPanicNoActivity)); |
|
2006 if (iContext.iMessage.IsMessage<TEBase::TCancel>()) |
|
2007 { |
|
2008 iContext.iNodeActivity->SetError(KErrCancel); |
|
2009 iContext.iMessage.ClearMessageId(); |
|
2010 return EFalse; |
|
2011 } |
|
2012 else |
|
2013 { |
|
2014 CoreNetStates::TAwaitingBindToComplete state(iContext); |
|
2015 return state.Accept(); |
|
2016 } |
|
2017 } |
|
2018 } //PRActivities |
|
2019 |
|
2020 EXPORT_DEFINE_SMELEMENT(PRDataClientStopActivity::TNoTagOrProviderStopped, NetStateMachine::MStateFork, PRDataClientStopActivity::TContext) |
|
2021 EXPORT_C TInt PRDataClientStopActivity::TNoTagOrProviderStopped::TransitionTag() |
|
2022 { |
|
2023 iContext.iNodeActivity->SetError(message_cast<TCFDataClient::TStop>(iContext.iMessage).iValue); |
|
2024 if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>( |
|
2025 TClientType(TCFClientType::EData, TCFClientType::EStarted)) != NULL) |
|
2026 { |
|
2027 // At least one started data client |
|
2028 return MeshMachine::KNoTag; |
|
2029 } |
|
2030 return CoreNetStates::KProviderStopped; |
|
2031 } |
|
2032 |
|
2033 |
|
2034 |
|