85 //Register with self for availability notifications. Self will report _any_ availabilty change (even available->available) back to |
85 //Register with self for availability notifications. Self will report _any_ availabilty change (even available->available) back to |
86 //this activity. This activity can trigger mobility (see CMobilityActivity::TNoTagOrErrorTagOrStartMobilityHandshakeBackwardsOnMobilityTriggerBlockedByErrorRecovery) |
86 //this activity. This activity can trigger mobility (see CMobilityActivity::TNoTagOrErrorTagOrStartMobilityHandshakeBackwardsOnMobilityTriggerBlockedByErrorRecovery) |
87 //if it sees that the availability notification has influcenced what the currently preffered bearer should be. |
87 //if it sees that the availability notification has influcenced what the currently preffered bearer should be. |
88 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TSendAvailabilityRequest, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake>) |
88 THROUGH_NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TSendAvailabilityRequest, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake>) |
89 |
89 |
90 //<BEGIN> MAIN LOOP **************** |
90 //<BEGIN> MAIN LOOP **************** |
91 //The main mobility handshake loop. The loop is executed when performing migration from one service provider to another. |
91 //The main mobility handshake loop. The loop is executed when performing migration from one service provider to another. |
92 //The entry condition for the loop is that: |
92 //The entry condition for the loop is that: |
93 //- upgrade: a better then current access point is now available (a better access point reported available) |
93 //- upgrade: a better then current access point is now available (a better access point reported available) |
94 //- downgrade: |
94 //- downgrade: |
95 // (a) the current access point is being rejected by the client (e.g.: the current access point doesn't seem to route traffic where required) |
95 // (a) the current access point is being rejected by the client (e.g.: the current access point doesn't seem to route traffic where required) |
96 // (b) the current access point ceases to be available (reports availability below reasonable threshold). |
96 // (b) the current access point ceases to be available (reports availability below reasonable threshold). |
97 // NOTE: if the current bearer ceases to be available completely (goes down), then this will be assisted by an error recovery request; |
97 // NOTE: if the current bearer ceases to be available completely (goes down), then this will be assisted by an error recovery request; |
98 // NOTE: This tuple doesn't actually do (b), i.e.: assumes the threshold of '1' (in 0..100 availability score range) |
98 // NOTE: This tuple doesn't actually do (b), i.e.: assumes the threshold of '1' (in 0..100 availability score range) |
99 //Before awaitng for availability change or rejection by the client (TAwaitingCurrentCarrierRejectedOrAvailabilityChange), the activity |
99 //Before awaitng for availability change or rejection by the client (TAwaitingCurrentCarrierRejectedOrAvailabilityChange), the activity |
100 //first checks (TNoTagOrAwaitMobilityBlockedByErrorRecovery) if the availability has changed since it last checked |
100 //first checks (TNoTagOrAwaitMobilityBlockedByErrorRecovery) if the availability has changed since it last checked |
101 //(availability could have been reported amidst the previous handshake loop) |
101 //(availability could have been reported amidst the previous handshake loop) |
102 THROUGH_NODEACTIVITY_ENTRY(MobilityMCprStates::KStartMobilityHandshake, CMobilityActivity::TClearHandshakingFlag, CMobilityActivity::TNoTagOrAwaitMobilityBlockedByErrorRecovery) |
102 THROUGH_NODEACTIVITY_ENTRY(MobilityMCprStates::KStartMobilityHandshake, CMobilityActivity::TClearHandshakingFlag, CMobilityActivity::TNoTagOrAwaitMobilityBlockedByErrorRecovery) |
103 NODEACTIVITY_ENTRY(MobilityMCprStates::KAwaitMobility, MeshMachine::TDoNothing, CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange, CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTriggerBlockedByErrorRecovery) |
103 NODEACTIVITY_ENTRY(MobilityMCprStates::KAwaitMobility, MeshMachine::TDoNothing, CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange, CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTriggerBlockedByErrorRecovery) |
104 |
104 |
105 //Mobility has been triggered ((a) or (b)). Start mobility handshake (set handshaking flag and inform the client about the preferred bearer) |
105 //Mobility has been triggered ((a) or (b)). Start mobility handshake (set handshaking flag and inform the client about the preferred bearer) |
106 NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag, MobilityMCprStates::TAwaitingMigrationRequestedOrRejected, CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards) |
106 NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag, MobilityMCprStates::TAwaitingMigrationRequestedOrRejected, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards) |
107 //The client accepts the new access point. |
107 //The client accepts the new access point. |
108 //For the moment it is sufficient to use the re-connect activity, in the future we may want to |
108 //For the moment it is sufficient to use the re-connect activity, in the future we may want to |
109 //customise the behavior, for example start the new layer before rebinding it, etc. |
109 //customise the behavior, for example start the new layer before rebinding it, etc. |
110 //Should rebinding fail, the mobility activity will be set to an error mode. The error mode will be cleared if |
110 //Should rebinding fail, the mobility activity will be set to an error mode. The error mode will be cleared if |
111 //there are other bearers this activity can offer. If there aren't the data client will be errored. |
111 //there are other bearers this activity can offer. If there aren't the data client will be errored. |
112 NODEACTIVITY_ENTRY(MobilityMCprStates::KReConnect, CMobilityActivity::TRequestReConnect, MCprStates::TAwaitingReConnectCompleteOrError, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards) |
112 NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TRequestReConnect, MCprStates::TAwaitingReConnectCompleteOrError, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards) |
113 //Rebinding has been successful. As far as MCPR is concerned, the mobility is finished, but the MCPR must await |
113 //Rebinding has been successful. As far as MCPR is concerned, the mobility is finished, but the MCPR must await |
114 //for the handshake (accept|reject) before it can offer another bearer. |
114 //for the handshake (accept|reject) before it can offer another bearer. |
115 NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationCompleted, MobilityMCprStates::TAwaitingMigrationAcceptedOrRejected, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake|EBackward>) |
115 NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationCompleted, MobilityMCprStates::TAwaitingMigrationAcceptedOrRejected, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake|EBackward>) |
116 NODEACTIVITY_END() |
116 NODEACTIVITY_END() |
117 } |
117 } |
118 |
118 |
119 namespace MCprConnectionStartRecoveryActivity |
119 namespace MCprConnectionStartRecoveryActivity |
208 //There's a couple of reasons why the activity may be in an error mode: |
208 //There's a couple of reasons why the activity may be in an error mode: |
209 //- rejection |
209 //- rejection |
210 // - current bearer rejected; |
210 // - current bearer rejected; |
211 // - proposed bearer rejected; |
211 // - proposed bearer rejected; |
212 // - failure to migrate to the proposed bearer; |
212 // - failure to migrate to the proposed bearer; |
213 lastRejected = iAvailable ? iAvailable : |
213 lastRejected = iPreferred ? iPreferred : |
214 static_cast<RMetaServiceProviderInterface*>(aContext.Node().ServiceProvider()); |
214 static_cast<RMetaServiceProviderInterface*>(aContext.Node().ServiceProvider()); |
215 } |
215 } |
216 |
216 |
217 iCandidate = iAvailable; |
217 iPreferred = NULL; //Do not remember rejected candidate any longer |
218 iAvailable = NULL; //Do not remember rejected candidate any longer |
|
219 while ((candidate = static_cast<RMetaServiceProviderInterface*>(iter++)) != NULL) |
218 while ((candidate = static_cast<RMetaServiceProviderInterface*>(iter++)) != NULL) |
220 { |
219 { |
221 const TAvailabilityStatus& status = candidate->AvailabilityStatus(); |
220 const TAvailabilityStatus& status = candidate->AvailabilityStatus(); |
222 if (!status.IsKnown()) |
221 if (!status.IsKnown()) |
223 { |
222 { |
256 void CMobilityActivity::ClearHandshakingFlag() |
254 void CMobilityActivity::ClearHandshakingFlag() |
257 { |
255 { |
258 static_cast<CMobilityMetaConnectionProvider&>(iNode).iIsHandshakingNow = EFalse; |
256 static_cast<CMobilityMetaConnectionProvider&>(iNode).iIsHandshakingNow = EFalse; |
259 } |
257 } |
260 |
258 |
261 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
259 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
262 TInt CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards::TransitionTag() |
260 TInt CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards::TransitionTag() |
263 { |
261 { |
264 if (iContext.Activity()->Error() == KErrNone && |
262 if (iContext.Activity()->Error() == KErrNone && |
265 (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) || |
263 (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) || |
266 message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage))) |
264 message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage))) |
267 { |
265 { |
268 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
266 return MeshMachine::KNoTag | NetStateMachine::EForward; |
269 if( activity.iCurrent!=activity.iAvailable ) |
|
270 return MobilityMCprStates::KReConnect | NetStateMachine::EForward; |
|
271 else |
|
272 return MeshMachine::KNoTag | NetStateMachine::EForward; |
|
273 } |
|
274 return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward; |
|
275 } |
|
276 |
|
277 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
|
278 TInt CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards::TransitionTag() |
|
279 { |
|
280 if (iContext.Activity()->Error() == KErrNone && |
|
281 (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) || |
|
282 message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage))) |
|
283 { |
|
284 return MeshMachine::KNoTag | NetStateMachine::EForward; |
|
285 } |
267 } |
286 return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward; |
268 return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward; |
287 } |
269 } |
288 |
270 |
289 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
271 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
290 TInt CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger::TransitionTag() |
272 TInt CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger::TransitionTag() |
291 { |
273 { |
292 //This is where the judgement is made on whether to trigger mobility (offer the client another bearer) |
274 //This is where the judgement is made on whether to trigger mobility (offer the client another bearer) |
293 //or ignore and come back waiting. |
275 //or ignore and come back waiting. |
294 __ASSERT_DEBUG(iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>() || |
276 __ASSERT_DEBUG(iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>() || |
295 iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>(), |
277 iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>(), |
296 User::Panic(KCoreMobileMCprPanic, KPanicIncorrectMessage)); |
278 User::Panic(KCoreMobileMCprPanic, KPanicIncorrectMessage)); |
297 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
279 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
298 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
280 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
299 |
281 |
300 if (activity.EvaluatePreference(iContext)) |
282 if (activity.EvaluatePreference(iContext)) |
301 { |
283 { |
302 activity.SetError(KErrNone); |
284 activity.SetError(KErrNone); |
303 return KNoTag; |
285 return KNoTag; |
304 } |
286 } |
348 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
330 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
349 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
331 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
350 |
332 |
351 //Inform the CPR that a potential migration is available. We only support a single data client |
333 //Inform the CPR that a potential migration is available. We only support a single data client |
352 //in this implementation. |
334 //in this implementation. |
353 __ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
335 __ASSERT_DEBUG(activity.iPreferred, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
354 |
336 |
355 //Compute all this here to keep EvaluatePreference() as fast as possible |
337 //Compute all this here to keep EvaluatePreference() as fast as possible |
356 activity.iCurrent = static_cast<RMetaServiceProviderInterface*>(iContext.Node().ServiceProvider()); |
338 activity.iCurrent = static_cast<RMetaServiceProviderInterface*>(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted))); |
357 __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
339 __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
358 |
340 |
359 //Perform a simple check if this is an upgrade or not |
341 //Perform a simple check if this is an upgrade or not |
360 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
342 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
361 RNodeInterface* sp = iter++; |
343 RNodeInterface* sp = iter++; |
362 while (sp && sp!=activity.iCurrent && sp!=activity.iAvailable) |
344 while (sp && sp!=activity.iCurrent && sp!=activity.iPreferred) |
363 { |
345 { |
364 sp = iter++; |
346 sp = iter++; |
365 } |
347 } |
366 |
348 |
367 TBool isUpgrade = (sp != activity.iCurrent); //If current was found first -> this is not an upgrade |
349 TBool isUpgrade = (sp != activity.iCurrent); //If current was found first -> this is not an upgrade |
368 if( activity.iCurrent == activity.iAvailable && activity.iCandidate ) |
350 TCFMobilityControlClient::TMigrationNotification msg(activity.iCurrent->ProviderInfo().APId(), |
369 { |
351 activity.iPreferred->ProviderInfo().APId(), |
370 // The available client is the same as the current and a candidate exists, this indicates that |
352 isUpgrade, EFalse); |
371 // an error has occured when trying to start the candidate bearer and the control as reverted to |
353 |
372 // the current bearer. In this situation the notification needs to look as if the bearer has |
354 activity.PostToOriginators(msg); |
373 // migrated from the failed candidate to the current bearer. |
|
374 TCFMobilityControlClient::TMigrationNotification msg(activity.iCandidate->ProviderInfo().APId(), |
|
375 activity.iAvailable->ProviderInfo().APId(), |
|
376 isUpgrade, EFalse); |
|
377 activity.PostToOriginators(msg); |
|
378 } |
|
379 else |
|
380 { |
|
381 // Standard case where migration is going from current to available. |
|
382 TCFMobilityControlClient::TMigrationNotification msg(activity.iCurrent->ProviderInfo().APId(), |
|
383 activity.iAvailable->ProviderInfo().APId(), |
|
384 isUpgrade, EFalse); |
|
385 activity.PostToOriginators(msg); |
|
386 } |
|
387 |
|
388 activity.ClearPostedTo(); |
355 activity.ClearPostedTo(); |
389 activity.SetHandshakingFlag(); |
356 activity.SetHandshakingFlag(); |
390 } |
357 } |
391 |
358 |
392 |
359 |
406 void CMobilityActivity::TRequestReConnect::DoL() |
373 void CMobilityActivity::TRequestReConnect::DoL() |
407 { |
374 { |
408 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
375 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
409 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
376 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
410 |
377 |
411 __ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
378 __ASSERT_DEBUG(activity.iPreferred, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
412 __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
379 __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
413 __ASSERT_DEBUG(activity.iCurrent!=activity.iAvailable, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 1)); |
380 __ASSERT_DEBUG(activity.iCurrent!=activity.iPreferred, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 1)); |
414 |
381 |
415 // For the moment it is sufficient to use the re-connect activity, in the future we may want to |
382 // For the moment it is sufficient to use the re-connect activity, in the future we may want to |
416 // customise the behavior, for example start the new layer before rebinding it, etc. |
383 // customise the behavior, for example start the new layer before rebinding it, etc. |
417 TCFMcpr::TReConnect msg(activity.iCurrent->RecipientId(), activity.iAvailable->RecipientId()); |
384 TCFMcpr::TReConnect msg(activity.iCurrent->RecipientId(), activity.iPreferred->RecipientId()); |
418 activity.PostRequestTo(iContext.NodeId(), msg); |
385 activity.PostRequestTo(iContext.NodeId(), msg); |
419 } |
386 } |
420 |
387 |
421 DEFINE_SMELEMENT(CMobilityActivity::TInformMigrationCompleted, NetStateMachine::MStateTransition, CMobilityActivity::TContext) |
388 DEFINE_SMELEMENT(CMobilityActivity::TInformMigrationCompleted, NetStateMachine::MStateTransition, CMobilityActivity::TContext) |
422 void CMobilityActivity::TInformMigrationCompleted::DoL() |
389 void CMobilityActivity::TInformMigrationCompleted::DoL() |
499 |
466 |
500 DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext) |
467 DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext) |
501 void CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() |
468 void CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() |
502 { |
469 { |
503 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
470 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
504 RNodeInterface* newSP = NULL; |
471 RNodeInterface* startingSP = NULL; |
505 RNodeInterface* curSP = iContext.Node().ServiceProvider(); //Our current started Service Provider. |
472 RNodeInterface* stoppingSP = NULL; |
506 |
473 |
507 //Choose Service Providers to work on |
474 //Choose Service Providers to work on |
508 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
475 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
509 RNodeInterface* itf = NULL; |
476 RNodeInterface* itf = NULL; |
510 for (itf = iter++; itf!=NULL && newSP==NULL; itf = iter++) |
477 for (itf = iter++; itf!=NULL && stoppingSP==NULL; itf = iter++) |
511 { |
478 { |
512 if (itf==curSP) |
479 if (itf->Flags() & TCFClientType::EStarted) |
513 { |
480 { |
514 newSP = iter++; //And the new one to try next |
481 stoppingSP = itf; //Our current started Service Provider. |
|
482 startingSP = iter++; //And the new one to try next |
515 } |
483 } |
516 } |
484 } |
517 |
485 |
518 //Sanity check. |
486 //Sanity check. |
519 //The new provider must not be started, there can be only one started at a time. |
487 //The new provider must not be started, there can be only one started at a time. |
520 __ASSERT_DEBUG(newSP==NULL || (newSP->Flags() & TCFClientType::EStarted)==0, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 3)); |
488 __ASSERT_DEBUG(startingSP==NULL || (startingSP->Flags() & TCFClientType::EStarted)==0, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 3)); |
521 |
489 |
522 //If there is no other Service Provider to try, return KErrNotFound |
490 //If there is no other Service Provider to try, return KErrNotFound |
523 if (newSP==NULL || curSP == NULL) |
491 if (startingSP==NULL || stoppingSP == NULL) |
524 { |
492 { |
525 #ifdef __CFLOG_ACTIVE |
493 #ifdef __CFLOG_ACTIVE |
526 __CFLOG_VAR((KCoreMCprStatesTag, KCoreMCprStatesSubTag, _L8("WARNING: CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() - no more choices, abandoning recovery."))); |
494 __CFLOG_VAR((KCoreMCprStatesTag, KCoreMCprStatesSubTag, _L8("WARNING: CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() - no more choices, abandoning recovery."))); |
527 #endif |
495 #endif |
528 User::Leave(KErrNotFound); |
496 User::Leave(KErrNotFound); |
529 } |
497 } |
530 |
498 |
531 //Diagnostinc - there must be a data client or we cannot be here |
499 //Diagnostinc - there must be a data client or we cannot be here |
532 __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)), User::Panic(KCoreMobileMCprPanic, KPanicNoDataClient)); |
500 __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)), User::Panic(KCoreMobileMCprPanic, KPanicNoDataClient)); |
533 iContext.iNodeActivity->PostRequestTo(iContext.NodeId(), |
501 iContext.iNodeActivity->PostRequestTo(iContext.NodeId(), |
534 TCFMcpr::TReConnect(curSP->RecipientId(), newSP->RecipientId()).CRef()); |
502 TCFMcpr::TReConnect(stoppingSP->RecipientId(), startingSP->RecipientId()).CRef()); |
535 } |
503 } |
536 |
504 |
537 DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext) |
505 DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext) |
538 void CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest::DoL() |
506 void CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest::DoL() |
539 { |
507 { |
540 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
508 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
541 CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity); |
509 CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity); |
542 |
510 |
543 RNodeInterface* started = iContext.Node().ServiceProvider(); |
511 RNodeInterface* started = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted)); |
544 TUint apId = (TUint)activity.iOriginalErrContext.iInfo; |
512 TUint apId = (TUint)activity.iOriginalErrContext.iInfo; |
545 RNodeInterface* gonedownsp = iContext.Node().FindServiceProvider(apId); |
513 RNodeInterface* gonedownsp = iContext.Node().FindServiceProvider(apId); |
546 if (started && started != gonedownsp) |
514 if (started && started != gonedownsp) |
547 { |
515 { |
548 CConnectionRecoveryActivity::TSendRetryRecoveryResponse tr(iContext); |
516 CConnectionRecoveryActivity::TSendRetryRecoveryResponse tr(iContext); |