52 #include <comms-infras/ss_nodemessages_rejoiningprovider.h> |
52 #include <comms-infras/ss_nodemessages_rejoiningprovider.h> |
53 #include <comms-infras/ss_nodemessages_internal_esock.h> |
53 #include <comms-infras/ss_nodemessages_internal_esock.h> |
54 #include <comms-infras/ss_nodemessages_factory.h> |
54 #include <comms-infras/ss_nodemessages_factory.h> |
55 #include <comms-infras/ss_nodemessages_mcpr.h> |
55 #include <comms-infras/ss_nodemessages_mcpr.h> |
56 #include <comms-infras/ss_nodemessages_cpr.h> |
56 #include <comms-infras/ss_nodemessages_cpr.h> |
57 |
|
58 |
57 |
59 #ifdef _DEBUG |
58 #ifdef _DEBUG |
60 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
59 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
61 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
60 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
62 _LIT(KSpecAssert_ESockCrStaCPRSC, "ESockCrStaCPRSC"); |
61 _LIT(KSpecAssert_ESockCrStaCPRSC, "ESockCrStaCPRSC"); |
519 |
518 |
520 //This transition may only be triggered by a peer message from a data client |
519 //This transition may only be triggered by a peer message from a data client |
521 __ASSERT_DEBUG(iContext.iPeer, User::Panic(KSpecAssert_ESockCrStaCPRSC, 13)); |
520 __ASSERT_DEBUG(iContext.iPeer, User::Panic(KSpecAssert_ESockCrStaCPRSC, 13)); |
522 __ASSERT_DEBUG(iContext.iPeer->Type()==TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRSC, 14)); |
521 __ASSERT_DEBUG(iContext.iPeer->Type()==TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRSC, 14)); |
523 |
522 |
|
523 __CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("TSendDestroyToSendingDataClient::DoL - iContext.iPeer->Flags(): %x"), iContext.iPeer->Flags())); |
524 if (!(iContext.iPeer->Flags() & |
524 if (!(iContext.iPeer->Flags() & |
525 (TCFClientType::EActivating|TCFClientType::EStarting|TCFClientType::ELeaving|TCFClientType::EStarted))) |
525 (TCFClientType::EActivating|TCFClientType::EStarting|TCFClientType::ELeaving|TCFClientType::EStarted))) |
526 { |
526 { |
527 // if dataclient is default and there is a non default present, don't kill the default. |
527 // if dataclient is default and there is a non default present, don't kill the default. |
528 if (!( iContext.iPeer->Flags() & TCFClientType::EDefault && |
528 if (!( iContext.iPeer->Flags() & TCFClientType::EDefault && |
623 |
623 |
624 EXPORT_DEFINE_SMELEMENT(TStopDataClients, NetStateMachine::MStateTransition, PRStates::TContext) |
624 EXPORT_DEFINE_SMELEMENT(TStopDataClients, NetStateMachine::MStateTransition, PRStates::TContext) |
625 EXPORT_C void TStopDataClients::DoL() |
625 EXPORT_C void TStopDataClients::DoL() |
626 { |
626 { |
627 __ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity)); |
627 __ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity)); |
628 TInt stopCode = ExtractErrorCode(iContext.iMessage); |
628 TInt aStopCode = ExtractErrorCode(iContext.iMessage); |
629 |
629 // Stop all non-default data clients before the default data client, as there are some cases where non-default data clients |
630 iContext.Node().PostToClients<TDefaultClientMatchPolicy>(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), |
630 // have a reference to the default data client. Also, stop non-default data clients unconditionally (i.e. whether started or |
631 TCFDataClient::TStop(stopCode).CRef(), TClientType(TCFClientType::EData, TCFClientType::EStarted)); |
631 // not) and the default data client only if started. This ensures that a non-default data client that is still starting |
632 iContext.iNodeActivity->ClearPostedTo(); |
632 // will receive the stop, so preventing a hang. |
633 } |
633 // |
|
634 // NOTE: the logic in this method is coupled to the logic in TNoTagOrDataClientsToStop. |
|
635 iContext.Node().PostToClients<TDefaultClientMatchPolicy>(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()),TCFDataClient::TStop(aStopCode).CRef(), TClientType(TCFClientType::EData), TClientType(0, TClientType::ELeaving|TCFClientType::EDefault), TCFClientType::EStopping); |
|
636 iContext.Node().PostToClients<TDefaultClientMatchPolicy>(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()),TCFDataClient::TStop(aStopCode).CRef(), TClientType(TCFClientType::EData, TCFClientType::EStarted|TCFClientType::EDefault), TClientType(0, TClientType::ELeaving), TCFClientType::EStopping); |
|
637 iContext.iNodeActivity->ClearPostedTo(); |
|
638 } |
|
639 |
|
640 void TStopDataClients::StopDataClient(RNodeInterface& aDataClient, TInt aStopCode) |
|
641 { |
|
642 aDataClient.SetFlags(TCFClientType::EStopping); |
|
643 aDataClient.PostMessage(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), TCFDataClient::TStop(aStopCode).CRef()); |
|
644 } |
|
645 |
634 |
646 |
635 EXPORT_DEFINE_SMELEMENT(TStopSelf, NetStateMachine::MStateTransition, PRStates::TContext) |
647 EXPORT_DEFINE_SMELEMENT(TStopSelf, NetStateMachine::MStateTransition, PRStates::TContext) |
636 EXPORT_C void TStopSelf::DoL() |
648 EXPORT_C void TStopSelf::DoL() |
637 { |
649 { |
638 __ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity)); |
650 __ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity)); |
1766 } |
1778 } |
1767 |
1779 |
1768 EXPORT_DEFINE_SMELEMENT(TNoTagOrDataClientsToStop, NetStateMachine::MStateFork, CoreNetStates::TContext) |
1780 EXPORT_DEFINE_SMELEMENT(TNoTagOrDataClientsToStop, NetStateMachine::MStateFork, CoreNetStates::TContext) |
1769 EXPORT_C TInt TNoTagOrDataClientsToStop::TransitionTag() |
1781 EXPORT_C TInt TNoTagOrDataClientsToStop::TransitionTag() |
1770 { |
1782 { |
1771 if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EStarted), |
1783 // Check if there are any non-default data clients, or the default data client is started. |
1772 TClientType(0, TClientType::ELeaving))) |
1784 // NOTE: the logic in this method is coupled to the logic in TStopDataClients - see that method for further explanation. |
1773 { |
1785 if ((iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EDefault | TCFClientType::EStarted), TClientType(0, TClientType::ELeaving))) |
1774 return CoreNetStates::KDataClientsToStop | NetStateMachine::EForward; |
1786 || (iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData), TClientType(0, TCFClientType::EDefault | TClientType::ELeaving)))) |
1775 } |
1787 { |
1776 return KNoTag; |
1788 return CoreNetStates::KDataClientsToStop; |
|
1789 } |
|
1790 return KNoTag; |
1777 } |
1791 } |
1778 |
1792 |
1779 EXPORT_DEFINE_SMELEMENT(TNoTagOrNoDataClientsToStop, NetStateMachine::MStateFork, CoreNetStates::TContext) |
1793 EXPORT_DEFINE_SMELEMENT(TNoTagOrNoDataClientsToStop, NetStateMachine::MStateFork, CoreNetStates::TContext) |
1780 TInt TNoTagOrNoDataClientsToStop::TransitionTag() |
1794 TInt TNoTagOrNoDataClientsToStop::TransitionTag() |
1781 /** |
1795 /** |