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::TNoTagOrStartMobilityHandshakeBackwards) |
106 //ReConnect only needs to be done if the bearer is different from the curret bearer. |
|
107 NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationAvailableAndSetHandshakingFlag, MobilityMCprStates::TAwaitingMigrationRequestedOrRejected, CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards) |
|
108 //The client accepts the new access point. |
107 //The client accepts the new access point. |
109 //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 |
110 //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. |
111 //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 |
112 //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. |
113 //there are other bearers this activity can offer. If there aren't the data client will be errored. |
112 NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TRequestReConnect, MCprStates::TAwaitingReConnectCompleteOrError, CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards) |
114 NODEACTIVITY_ENTRY(MobilityMCprStates::KReConnect, 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 |
115 //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. |
116 //for the handshake (accept|reject) before it can offer another bearer. |
115 NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationCompleted, MobilityMCprStates::TAwaitingMigrationAcceptedOrRejected, CMobilityActivity::TRejectedOrStartMobilityHandshakeBackwards) |
117 NODEACTIVITY_ENTRY(KNoTag, CMobilityActivity::TInformMigrationCompleted, MobilityMCprStates::TAwaitingMigrationAcceptedOrRejected, CMobilityActivity::TRejectedOrStartMobilityHandshakeBackwards) |
116 NODEACTIVITY_ENTRY(MobilityMCprStates::KRejected, CoreNetStates::TStopDataClients, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake|NetStateMachine::EBackward>) |
118 NODEACTIVITY_ENTRY(MobilityMCprStates::KRejected, CoreNetStates::TStopDataClients, CoreNetStates::TAwaitingDataClientsStopped, MeshMachine::TTag<MobilityMCprStates::KStartMobilityHandshake|NetStateMachine::EBackward>) |
117 NODEACTIVITY_END() |
119 NODEACTIVITY_END() |
118 } |
120 } |
119 |
121 |
120 namespace MCprConnectionStartRecoveryActivity |
122 namespace MCprConnectionStartRecoveryActivity |
121 { |
123 { |
255 void CMobilityActivity::ClearHandshakingFlag() |
259 void CMobilityActivity::ClearHandshakingFlag() |
256 { |
260 { |
257 static_cast<CMobilityMetaConnectionProvider&>(iNode).iIsHandshakingNow = EFalse; |
261 static_cast<CMobilityMetaConnectionProvider&>(iNode).iIsHandshakingNow = EFalse; |
258 } |
262 } |
259 |
263 |
260 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
264 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
261 TInt CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards::TransitionTag() |
265 TInt CMobilityActivity::TNoTagOrReConnectOrStartMobilityHandshakeBackwards::TransitionTag() |
262 { |
266 { |
263 if (iContext.Activity()->Error() == KErrNone && |
267 if (iContext.Activity()->Error() == KErrNone && |
264 (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) || |
268 (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) || |
265 message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage))) |
269 message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage))) |
266 { |
270 { |
|
271 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
|
272 if( activity.iCurrent!=activity.iAvailable ) |
|
273 return MobilityMCprStates::KReConnect | NetStateMachine::EForward; |
|
274 else |
|
275 return MeshMachine::KNoTag | NetStateMachine::EForward; |
|
276 } |
|
277 return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward; |
|
278 } |
|
279 |
|
280 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
|
281 TInt CMobilityActivity::TNoTagOrStartMobilityHandshakeBackwards::TransitionTag() |
|
282 { |
|
283 if (iContext.Activity()->Error() == KErrNone && |
|
284 (message_cast<TCFMobilityProvider::TMigrationRequested>(&iContext.iMessage) || |
|
285 message_cast<TCFMcpr::TReConnectComplete>(&iContext.iMessage))) |
|
286 { |
267 return MeshMachine::KNoTag | NetStateMachine::EForward; |
287 return MeshMachine::KNoTag | NetStateMachine::EForward; |
268 } |
288 } |
269 return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward; |
289 return MobilityMCprStates::KStartMobilityHandshake | NetStateMachine::EBackward; |
270 } |
290 } |
271 |
291 |
272 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
292 DEFINE_SMELEMENT(CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger, NetStateMachine::MStateFork, CMobilityActivity::TContext) |
273 TInt CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger::TransitionTag() |
293 TInt CMobilityActivity::TNoTagOrAwaitMobilityBackwardsOnMobilityTrigger::TransitionTag() |
274 { |
294 { |
275 //This is where the judgement is made on whether to trigger mobility (offer the client another bearer) |
295 //This is where the judgement is made on whether to trigger mobility (offer the client another bearer) |
276 //or ignore and come back waiting. |
296 //or ignore and come back waiting. |
277 __ASSERT_DEBUG(iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>() || |
297 __ASSERT_DEBUG(iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>() || |
278 iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>(), |
298 iContext.iMessage.IsMessage<TCFAvailabilityControlClient::TAvailabilityNotification>(), |
279 User::Panic(KCoreMobileMCprPanic, KPanicIncorrectMessage)); |
299 User::Panic(KCoreMobileMCprPanic, KPanicIncorrectMessage)); |
280 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
300 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
281 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
301 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
282 |
302 |
283 if (activity.EvaluatePreference(iContext)) |
303 if (activity.EvaluatePreference(iContext)) |
284 { |
304 { |
285 activity.SetError(KErrNone); |
305 activity.SetError(KErrNone); |
286 return KNoTag; |
306 return KNoTag; |
287 } |
307 } |
321 |
341 |
322 // if rejected last ap and there's no more |
342 // if rejected last ap and there's no more |
323 if (iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>()) |
343 if (iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>()) |
324 { |
344 { |
325 TBool otherSP = EFalse; |
345 TBool otherSP = EFalse; |
326 |
346 |
327 // Find if there anymore available non rejected service providers |
347 // Find if there anymore available non rejected service providers |
328 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
348 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
329 __ASSERT_DEBUG(iter[0], User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); //A Service Provider must exist! |
349 __ASSERT_DEBUG(iter[0], User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); //A Service Provider must exist! |
330 RMetaServiceProviderInterface* rejected = static_cast<RMetaServiceProviderInterface*>(iContext.Node().ServiceProvider()); |
350 RMetaServiceProviderInterface* rejected = static_cast<RMetaServiceProviderInterface*>(iContext.Node().ServiceProvider()); |
331 RMetaServiceProviderInterface* candidate = NULL; |
351 RMetaServiceProviderInterface* candidate = NULL; |
332 |
352 |
333 while ((candidate = static_cast<RMetaServiceProviderInterface*>(iter++)) != NULL) |
353 while ((candidate = static_cast<RMetaServiceProviderInterface*>(iter++)) != NULL) |
334 { |
354 { |
335 if (candidate == rejected) |
355 if (candidate == rejected) |
336 { |
356 { |
337 continue; |
357 continue; |
338 } |
358 } |
339 |
359 |
340 const TAvailabilityStatus& status = candidate->AvailabilityStatus(); |
360 const TAvailabilityStatus& status = candidate->AvailabilityStatus(); |
341 if (!status.IsKnown()) |
361 if (!status.IsKnown()) |
342 { |
362 { |
343 continue; |
363 continue; |
344 } |
364 } |
378 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
398 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
379 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
399 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
380 |
400 |
381 //Inform the CPR that a potential migration is available. We only support a single data client |
401 //Inform the CPR that a potential migration is available. We only support a single data client |
382 //in this implementation. |
402 //in this implementation. |
383 __ASSERT_DEBUG(activity.iPreferred, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
403 __ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
384 |
404 |
385 //Compute all this here to keep EvaluatePreference() as fast as possible |
405 //Compute all this here to keep EvaluatePreference() as fast as possible |
386 activity.iCurrent = static_cast<RMetaServiceProviderInterface*>(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted))); |
406 activity.iCurrent = static_cast<RMetaServiceProviderInterface*>(iContext.Node().ServiceProvider()); |
387 __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
407 __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
388 |
408 |
389 //Perform a simple check if this is an upgrade or not |
409 //Perform a simple check if this is an upgrade or not |
390 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
410 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
391 RNodeInterface* sp = iter++; |
411 RNodeInterface* sp = iter++; |
392 while (sp && sp!=activity.iCurrent && sp!=activity.iPreferred) |
412 while (sp && sp!=activity.iCurrent && sp!=activity.iAvailable) |
393 { |
413 { |
394 sp = iter++; |
414 sp = iter++; |
395 } |
415 } |
396 |
416 |
397 TBool isUpgrade = (sp != activity.iCurrent); //If current was found first -> this is not an upgrade |
417 TBool isUpgrade = (sp != activity.iCurrent); //If current was found first -> this is not an upgrade |
398 TCFMobilityControlClient::TMigrationNotification msg(activity.iCurrent->ProviderInfo().APId(), |
418 if( activity.iCurrent == activity.iAvailable && activity.iCandidate ) |
399 activity.iPreferred->ProviderInfo().APId(), |
419 { |
400 isUpgrade, EFalse); |
420 // The available client is the same as the current and a candidate exists, this indicates that |
401 |
421 // an error has occured when trying to start the candidate bearer and the control as reverted to |
402 activity.PostToOriginators(msg); |
422 // the current bearer. In this situation the notification needs to look as if the bearer has |
|
423 // migrated from the failed candidate to the current bearer. |
|
424 TCFMobilityControlClient::TMigrationNotification msg(activity.iCandidate->ProviderInfo().APId(), |
|
425 activity.iAvailable->ProviderInfo().APId(), |
|
426 isUpgrade, EFalse); |
|
427 activity.PostToOriginators(msg); |
|
428 } |
|
429 else |
|
430 { |
|
431 // Standard case where migration is going from current to available. |
|
432 TCFMobilityControlClient::TMigrationNotification msg(activity.iCurrent->ProviderInfo().APId(), |
|
433 activity.iAvailable->ProviderInfo().APId(), |
|
434 isUpgrade, EFalse); |
|
435 activity.PostToOriginators(msg); |
|
436 } |
|
437 |
403 activity.ClearPostedTo(); |
438 activity.ClearPostedTo(); |
404 activity.SetHandshakingFlag(); |
439 activity.SetHandshakingFlag(); |
405 } |
440 } |
406 |
|
407 |
441 |
408 DEFINE_SMELEMENT(CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange, NetStateMachine::MState, CMobilityActivity::TContext) |
442 DEFINE_SMELEMENT(CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange, NetStateMachine::MState, CMobilityActivity::TContext) |
409 TBool CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange::Accept() |
443 TBool CMobilityActivity::TAwaitingCurrentCarrierRejectedOrAvailabilityChange::Accept() |
410 { |
444 { |
411 if (iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>()) |
445 if (iContext.iMessage.IsMessage<TCFMobilityProvider::TMigrationRejected>()) |
421 void CMobilityActivity::TRequestReConnect::DoL() |
455 void CMobilityActivity::TRequestReConnect::DoL() |
422 { |
456 { |
423 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
457 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
424 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
458 CMobilityActivity& activity = static_cast<CMobilityActivity&>(*iContext.iNodeActivity); |
425 |
459 |
426 __ASSERT_DEBUG(activity.iPreferred, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
460 __ASSERT_DEBUG(activity.iAvailable, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
427 __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
461 __ASSERT_DEBUG(activity.iCurrent, User::Panic(KCoreMobileMCprPanic, KPanicNoServiceProvider)); |
428 __ASSERT_DEBUG(activity.iCurrent!=activity.iPreferred, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 1)); |
462 __ASSERT_DEBUG(activity.iCurrent!=activity.iAvailable, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 1)); |
429 |
463 |
430 // For the moment it is sufficient to use the re-connect activity, in the future we may want to |
464 // For the moment it is sufficient to use the re-connect activity, in the future we may want to |
431 // customise the behavior, for example start the new layer before rebinding it, etc. |
465 // customise the behavior, for example start the new layer before rebinding it, etc. |
432 TCFMcpr::TReConnect msg(activity.iCurrent->RecipientId(), activity.iPreferred->RecipientId()); |
466 TCFMcpr::TReConnect msg(activity.iCurrent->RecipientId(), activity.iAvailable->RecipientId()); |
433 activity.PostRequestTo(iContext.NodeId(), msg); |
467 activity.PostRequestTo(iContext.NodeId(), msg); |
434 } |
468 } |
435 |
469 |
436 DEFINE_SMELEMENT(CMobilityActivity::TInformMigrationCompleted, NetStateMachine::MStateTransition, CMobilityActivity::TContext) |
470 DEFINE_SMELEMENT(CMobilityActivity::TInformMigrationCompleted, NetStateMachine::MStateTransition, CMobilityActivity::TContext) |
437 void CMobilityActivity::TInformMigrationCompleted::DoL() |
471 void CMobilityActivity::TInformMigrationCompleted::DoL() |
514 |
548 |
515 DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext) |
549 DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext) |
516 void CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() |
550 void CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() |
517 { |
551 { |
518 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
552 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
519 RNodeInterface* startingSP = NULL; |
553 RNodeInterface* newSP = NULL; |
520 RNodeInterface* stoppingSP = NULL; |
554 RNodeInterface* curSP = iContext.Node().ServiceProvider(); //Our current started Service Provider. |
521 |
555 |
522 //Choose Service Providers to work on |
556 //Choose Service Providers to work on |
523 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
557 TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider)); |
524 RNodeInterface* itf = NULL; |
558 RNodeInterface* itf = NULL; |
525 for (itf = iter++; itf!=NULL && stoppingSP==NULL; itf = iter++) |
559 for (itf = iter++; itf!=NULL && newSP==NULL; itf = iter++) |
526 { |
560 { |
527 if (itf->Flags() & TCFClientType::EStarted) |
561 if (itf==curSP) |
528 { |
562 { |
529 stoppingSP = itf; //Our current started Service Provider. |
563 newSP = iter++; //And the new one to try next |
530 startingSP = iter++; //And the new one to try next |
|
531 } |
564 } |
532 } |
565 } |
533 |
566 |
534 //Sanity check. |
567 //Sanity check. |
535 //The new provider must not be started, there can be only one started at a time. |
568 //The new provider must not be started, there can be only one started at a time. |
536 __ASSERT_DEBUG(startingSP==NULL || (startingSP->Flags() & TCFClientType::EStarted)==0, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 3)); |
569 __ASSERT_DEBUG(newSP==NULL || (newSP->Flags() & TCFClientType::EStarted)==0, User::Panic(KSpecAssert_ESockMbCrMCPRAct, 3)); |
537 |
570 |
538 //If there is no other Service Provider to try, return KErrNotFound |
571 //If there is no other Service Provider to try, return KErrNotFound |
539 if (startingSP==NULL || stoppingSP == NULL) |
572 if (newSP==NULL || curSP == NULL) |
540 { |
573 { |
541 #ifdef __CFLOG_ACTIVE |
574 #ifdef __CFLOG_ACTIVE |
542 __CFLOG_VAR((KCoreMCprStatesTag, KCoreMCprStatesSubTag, _L8("WARNING: CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() - no more choices, abandoning recovery."))); |
575 __CFLOG_VAR((KCoreMCprStatesTag, KCoreMCprStatesSubTag, _L8("WARNING: CConnectionRecoveryActivity::TProcessConnectionStartRecoveryRequest::DoL() - no more choices, abandoning recovery."))); |
543 #endif |
576 #endif |
544 User::Leave(KErrNotFound); |
577 User::Leave(KErrNotFound); |
545 } |
578 } |
546 |
579 |
547 //Diagnostinc - there must be a data client or we cannot be here |
580 //Diagnostinc - there must be a data client or we cannot be here |
548 __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)), User::Panic(KCoreMobileMCprPanic, KPanicNoDataClient)); |
581 __ASSERT_DEBUG(iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData)), User::Panic(KCoreMobileMCprPanic, KPanicNoDataClient)); |
549 iContext.iNodeActivity->PostRequestTo(iContext.NodeId(), |
582 iContext.iNodeActivity->PostRequestTo(iContext.NodeId(), |
550 TCFMcpr::TReConnect(stoppingSP->RecipientId(), startingSP->RecipientId()).CRef()); |
583 TCFMcpr::TReConnect(curSP->RecipientId(), newSP->RecipientId()).CRef()); |
551 } |
584 } |
552 |
585 |
553 DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext) |
586 DEFINE_SMELEMENT(CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest, NetStateMachine::MStateTransition, CConnectionRecoveryActivity::TContext) |
554 void CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest::DoL() |
587 void CConnectionRecoveryActivity::TProcessConnectionGoneDownRecoveryRequest::DoL() |
555 { |
588 { |
556 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
589 __ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KCoreMobileMCprPanic, KPanicNoActivity)); |
557 CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity); |
590 CConnectionRecoveryActivity& activity = static_cast<CConnectionRecoveryActivity&>(*iContext.iNodeActivity); |
558 |
591 |
559 RNodeInterface* started = iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider, TCFClientType::EStarted)); |
592 RNodeInterface* started = iContext.Node().ServiceProvider(); |
560 TUint apId = (TUint)activity.iOriginalErrContext.iInfo; |
593 TUint apId = (TUint)activity.iOriginalErrContext.iInfo; |
561 RNodeInterface* gonedownsp = iContext.Node().FindServiceProvider(apId); |
594 RNodeInterface* gonedownsp = iContext.Node().FindServiceProvider(apId); |
562 if (started && started != gonedownsp) |
595 if (started && started != gonedownsp) |
563 { |
596 { |
564 CConnectionRecoveryActivity::TSendRetryRecoveryResponse tr(iContext); |
597 CConnectionRecoveryActivity::TSendRetryRecoveryResponse tr(iContext); |