datacommsserver/esockserver/core_states/ss_coreprstates.cpp
changeset 22 592244873960
parent 5 68ef71f0cd72
child 30 df67dc5d759e
equal deleted inserted replaced
5:68ef71f0cd72 22:592244873960
    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");
    78 using namespace Elements;
    77 using namespace Elements;
    79 using namespace Messages;
    78 using namespace Messages;
    80 using namespace MeshMachine;
    79 using namespace MeshMachine;
    81 using namespace Factories;
    80 using namespace Factories;
    82 
    81 
       
    82 const TUint32 KOrphanExcludeFlags = TCFClientType::EActive|TCFClientType::EActivating|TCFClientType::ELeaving|TCFClientType::EStarted|TCFClientType::EStarting;
       
    83 
    83 //-=========================================================
    84 //-=========================================================
    84 //
    85 //
    85 // Panics
    86 // Panics
    86 //
    87 //
    87 //-=========================================================
    88 //-=========================================================
   392 //-=========================================================
   393 //-=========================================================
   393 
   394 
   394 EXPORT_DEFINE_SMELEMENT(TAwaitingClientLeave, NetStateMachine::MState, CoreStates::TContext)
   395 EXPORT_DEFINE_SMELEMENT(TAwaitingClientLeave, NetStateMachine::MState, CoreStates::TContext)
   395 EXPORT_C TBool TAwaitingClientLeave::Accept()
   396 EXPORT_C TBool TAwaitingClientLeave::Accept()
   396 	{
   397 	{
   397 	return iContext.iMessage.IsMessage<TEChild::TLeft>()
   398 	return iContext.iMessage.IsMessage<TEPeer::TLeaveRequest>() || iContext.iMessage.IsMessage<TEChild::TLeft>();
   398 		|| iContext.iMessage.IsMessage<TEPeer::TLeaveRequest>();
       
   399 	}
   399 	}
   400 
   400 
   401 EXPORT_DEFINE_SMELEMENT(TDestroyOrphanedDataClients, NetStateMachine::MStateTransition, PRStates::TContext)
   401 EXPORT_DEFINE_SMELEMENT(TDestroyOrphanedDataClients, NetStateMachine::MStateTransition, PRStates::TContext)
   402 EXPORT_C void TDestroyOrphanedDataClients::DoL()
   402 EXPORT_C void TDestroyOrphanedDataClients::DoL()
   403 	{
   403 	{
   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 &&
   529       		   iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData),
   529       		   iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData),
   530       		                                                           TClientType(0, TCFClientType::EDefault)) > 0))
   530       		                                                           TClientType(0, TCFClientType::EDefault)) > 0))
   531       		{
   531       		{
   532 	    	iContext.iPeer->PostMessage(iContext.NodeId(), TEChild::TDestroy().CRef());
   532 			// Send from null activity so no cancel message can ever get at it.
       
   533 			iContext.iPeer->PostMessage(Messages::TNodeCtxId(MeshMachine::KActivityNull, iContext.NodeId()), TEChild::TDestroy().CRef());
   533 	    	iContext.iPeer->SetFlags(TClientType::ELeaving);
   534 	    	iContext.iPeer->SetFlags(TClientType::ELeaving);
   534 	    	}
   535 	    	}
   535 	    else
   536 	    else
   536 	    	{
   537 	    	{
   537 	    	__CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("TSendDestroyToSendingDataClient::DoL - default client not destroyed, there is an active non default one")));
   538 	    	__CFLOG_VAR((KCoreProviderStatesTag, KCoreProviderStatesSubTag, _L8("TSendDestroyToSendingDataClient::DoL - default client not destroyed, there is an active non default one")));
   623 
   624 
   624 EXPORT_DEFINE_SMELEMENT(TStopDataClients, NetStateMachine::MStateTransition, PRStates::TContext)
   625 EXPORT_DEFINE_SMELEMENT(TStopDataClients, NetStateMachine::MStateTransition, PRStates::TContext)
   625 EXPORT_C void TStopDataClients::DoL()
   626 EXPORT_C void TStopDataClients::DoL()
   626 	{
   627 	{
   627 	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
   628 	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
   628 	TInt stopCode = ExtractErrorCode(iContext.iMessage);
   629 	TInt aStopCode = ExtractErrorCode(iContext.iMessage);
   629 
   630     // 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()),
   631     // 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));
   632     // 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();
   633     // will receive the stop, so preventing a hang.
   633 	}
   634     //
       
   635     // NOTE: the logic in this method is coupled to the logic in TNoTagOrDataClientsToStop.
       
   636 	iContext.Node().PostToClients<TDefaultClientMatchPolicy>(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()),TCFDataClient::TStop(aStopCode).CRef(), TClientType(TCFClientType::EData), TClientType(0, TClientType::ELeaving|TCFClientType::EDefault), TCFClientType::EStopping);
       
   637 	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);
       
   638     iContext.iNodeActivity->ClearPostedTo();
       
   639 	}
       
   640 
       
   641 void TStopDataClients::StopDataClient(RNodeInterface& aDataClient, TInt aStopCode)
       
   642     {
       
   643     aDataClient.SetFlags(TCFClientType::EStopping);
       
   644     aDataClient.PostMessage(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), TCFDataClient::TStop(aStopCode).CRef());
       
   645     }
       
   646 
   634 
   647 
   635 EXPORT_DEFINE_SMELEMENT(TStopSelf, NetStateMachine::MStateTransition, PRStates::TContext)
   648 EXPORT_DEFINE_SMELEMENT(TStopSelf, NetStateMachine::MStateTransition, PRStates::TContext)
   636 EXPORT_C void TStopSelf::DoL()
   649 EXPORT_C void TStopSelf::DoL()
   637 	{
   650 	{
   638 	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
   651 	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
   651     	{
   664     	{
   652     	return EFalse;
   665     	return EFalse;
   653     	}
   666     	}
   654 	if (iContext.iPeer)
   667 	if (iContext.iPeer)
   655 		{
   668 		{
   656 		iContext.iPeer->ClearFlags(TCFClientType::EStarted);
   669 		iContext.iPeer->ClearFlags(TCFClientType::EStarted | TCFClientType::EStopping); 		
   657 		}
   670 		}
   658 	if (iContext.iNodeActivity &&
   671 	if (iContext.iNodeActivity &&
   659 	    (iContext.iNodeActivity->ActivitySigId() == ECFActivityStop ||
   672 	    (iContext.iNodeActivity->ActivitySigId() == ECFActivityStop ||
   660 	     iContext.iNodeActivity->ActivitySigId() == ECFActivityStopDataClient))
   673 	     iContext.iNodeActivity->ActivitySigId() == ECFActivityStopDataClient))
   661     	{
   674     	{
   673     	{
   686     	{
   674     	return EFalse;
   687     	return EFalse;
   675     	}
   688     	}
   676 	if (iContext.iPeer)
   689 	if (iContext.iPeer)
   677 		{
   690 		{
   678 		iContext.iPeer->ClearFlags(TCFClientType::EStarted);
   691 		iContext.iPeer->ClearFlags(TCFClientType::EStarted | TCFClientType::EStopping); 
   679 		}
   692 		}
   680 	if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EStarted)))
   693 	if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EStopping)))  
   681 		{
   694 		{
   682 		//There are more to wait for
   695 		//There are more to wait for
   683 		iContext.iMessage.ClearMessageId();
   696 		iContext.iMessage.ClearMessageId();
   684 		return EFalse;
   697 		return EFalse;
   685 		}
   698 		}
   895    	RNodeInterface* cl = iter[0];
   908    	RNodeInterface* cl = iter[0];
   896    	//It is perfectly possible that there is no Control Provider at all.
   909    	//It is perfectly possible that there is no Control Provider at all.
   897    	if (cl)
   910    	if (cl)
   898    		{
   911    		{
   899 		__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
   912 		__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
   900    		cl->PostMessage(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), TEChild::TLeft().CRef());
   913    		iContext.iNodeActivity->PostToOriginators(TEChild::TLeft().CRef());
   901    		iContext.Node().RemoveClient(cl->RecipientId(),iContext);
   914    		iContext.Node().RemoveClient(cl->RecipientId(),iContext);
   902    		__ASSERT_DEBUG(iter[1] == NULL, User::Panic(KSpecAssert_ESockCrStaCPRSC, 19)); //But it is not possible to have two Control Providers!
   915    		__ASSERT_DEBUG(iter[1] == NULL, User::Panic(KSpecAssert_ESockCrStaCPRSC, 19)); //But it is not possible to have two Control Providers!
   903    		}
   916    		}
   904 	}
   917 	}
   905 
   918 
  1046         }
  1059         }
  1047     return ETrue;
  1060     return ETrue;
  1048 	}
  1061 	}
  1049 
  1062 
  1050 EXPORT_DEFINE_SMELEMENT(TAwaitingStop, NetStateMachine::MState, CoreNetStates::TContext)
  1063 EXPORT_DEFINE_SMELEMENT(TAwaitingStop, NetStateMachine::MState, CoreNetStates::TContext)
  1051 TBool TAwaitingStop::Accept()
  1064 EXPORT_C TBool TAwaitingStop::Accept()
  1052 	{
  1065 	{
  1053 	if (!iContext.iMessage.IsMessage<TCFServiceProvider::TStop>())
  1066 	if (!iContext.iMessage.IsMessage<TCFServiceProvider::TStop>())
  1054     	{
  1067     	{
  1055     	return EFalse;
  1068     	return EFalse;
  1056     	}
  1069     	}
  1345 
  1358 
  1346 EXPORT_DEFINE_SMELEMENT(TSendBindToComplete, NetStateMachine::MStateTransition, CoreNetStates::TContext)
  1359 EXPORT_DEFINE_SMELEMENT(TSendBindToComplete, NetStateMachine::MStateTransition, CoreNetStates::TContext)
  1347 EXPORT_C void TSendBindToComplete::DoL()
  1360 EXPORT_C void TSendBindToComplete::DoL()
  1348 	{
  1361 	{
  1349 	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
  1362 	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
  1350 	iContext.iNodeActivity->PostToOriginators(TCFDataClient::TBindToComplete(iContext.iNodeActivity->Error()).CRef());
  1363 	iContext.iNodeActivity->PostToOriginators(TCFDataClient::TBindToComplete().CRef());
  1351 	}
  1364 	}
  1352 
  1365 
  1353 EXPORT_DEFINE_SMELEMENT(TBindSelfToPresentBearer, NetStateMachine::MStateTransition, CoreNetStates::TContext)
  1366 EXPORT_DEFINE_SMELEMENT(TBindSelfToPresentBearer, NetStateMachine::MStateTransition, CoreNetStates::TContext)
  1354 EXPORT_C void TBindSelfToPresentBearer::DoL()
  1367 EXPORT_C void TBindSelfToPresentBearer::DoL()
  1355 	{
  1368 	{
  1492 
  1505 
  1493 
  1506 
  1494 EXPORT_DEFINE_SMELEMENT(TAwaitingBindTo, NetStateMachine::MState, CoreStates::TContext)
  1507 EXPORT_DEFINE_SMELEMENT(TAwaitingBindTo, NetStateMachine::MState, CoreStates::TContext)
  1495 EXPORT_C TBool TAwaitingBindTo::Accept()
  1508 EXPORT_C TBool TAwaitingBindTo::Accept()
  1496 	{
  1509 	{
  1497 	const TCFDataClient::TBindTo* bindToMessage = message_cast<TCFDataClient::TBindTo>(&iContext.iMessage);
  1510 	return iContext.iMessage.IsMessage<TCFDataClient::TBindTo>();
  1498 	if (bindToMessage)
       
  1499     	{
       
  1500     	//TBindTo is always a response. there's gotta be an activity.
       
  1501     	if (iContext.iNodeActivity && iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId))
       
  1502         	{
       
  1503         	ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterface(ABindingActivity::KInterfaceId));
       
  1504        	    bindingActivity->StoreOriginator(iContext.iSender);
       
  1505         	}
       
  1506         return ETrue;
       
  1507     	}
       
  1508     return EFalse;
       
  1509 	}
  1511 	}
  1510 
  1512 
  1511 EXPORT_DEFINE_SMELEMENT(TAwaitingBindToOrCancel, NetStateMachine::MState, CoreStates::TContext)
  1513 EXPORT_DEFINE_SMELEMENT(TAwaitingBindToOrCancel, NetStateMachine::MState, CoreStates::TContext)
  1512 TBool TAwaitingBindToOrCancel::Accept()
  1514 TBool TAwaitingBindToOrCancel::Accept()
  1513 	{
  1515 	{
  1598 	}
  1600 	}
  1599 
  1601 
  1600 EXPORT_DEFINE_SMELEMENT(CoreNetStates::TAwaitingBindToComplete, NetStateMachine::MState, CoreNetStates::TContext)
  1602 EXPORT_DEFINE_SMELEMENT(CoreNetStates::TAwaitingBindToComplete, NetStateMachine::MState, CoreNetStates::TContext)
  1601 EXPORT_C TBool CoreNetStates::TAwaitingBindToComplete::Accept()
  1603 EXPORT_C TBool CoreNetStates::TAwaitingBindToComplete::Accept()
  1602 	{
  1604 	{
  1603 	TCFDataClient::TBindToComplete* bindToComplete = message_cast<TCFDataClient::TBindToComplete>(&iContext.iMessage);
  1605 	return iContext.iMessage.IsMessage<TCFDataClient::TBindToComplete>();
  1604 	if (bindToComplete)
       
  1605     	{
       
  1606     	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
       
  1607 	    iContext.iNodeActivity->SetError(bindToComplete->iValue);
       
  1608 		return ETrue;
       
  1609     	}
       
  1610     return EFalse;
       
  1611 	}
  1606 	}
  1612 
  1607 
  1613 EXPORT_DEFINE_SMELEMENT(TAwaitingProvision, NetStateMachine::MState, PRStates::TContext)
  1608 EXPORT_DEFINE_SMELEMENT(TAwaitingProvision, NetStateMachine::MState, PRStates::TContext)
  1614 EXPORT_C TBool TAwaitingProvision::Accept()
  1609 EXPORT_C TBool TAwaitingProvision::Accept()
  1615 	{
  1610 	{
  1766 	}
  1761 	}
  1767 
  1762 
  1768 EXPORT_DEFINE_SMELEMENT(TNoTagOrDataClientsToStop, NetStateMachine::MStateFork, CoreNetStates::TContext)
  1763 EXPORT_DEFINE_SMELEMENT(TNoTagOrDataClientsToStop, NetStateMachine::MStateFork, CoreNetStates::TContext)
  1769 EXPORT_C TInt TNoTagOrDataClientsToStop::TransitionTag()
  1764 EXPORT_C TInt TNoTagOrDataClientsToStop::TransitionTag()
  1770 	{
  1765 	{
  1771 	if (iContext.Node().GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EStarted),
  1766     // Check if there are any non-default data clients, or the default data client is started.
  1772 		TClientType(0, TClientType::ELeaving)))
  1767     // NOTE: the logic in this method is coupled to the logic in TStopDataClients - see that method for further explanation.
  1773 		{
  1768     if ((iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EDefault | TCFClientType::EStarted), TClientType(0, TClientType::ELeaving))) 
  1774        	return CoreNetStates::KDataClientsToStop | NetStateMachine::EForward;
  1769 	 || (iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData), TClientType(0, TCFClientType::EDefault | TClientType::ELeaving))))
  1775     	}
  1770         {
  1776 	return KNoTag;
  1771         return CoreNetStates::KDataClientsToStop;
       
  1772         }
       
  1773     return KNoTag;
  1777 	}
  1774 	}
  1778 
  1775 
  1779 EXPORT_DEFINE_SMELEMENT(TNoTagOrNoDataClientsToStop, NetStateMachine::MStateFork, CoreNetStates::TContext)
  1776 EXPORT_DEFINE_SMELEMENT(TNoTagOrNoDataClientsToStop, NetStateMachine::MStateFork, CoreNetStates::TContext)
  1780 TInt TNoTagOrNoDataClientsToStop::TransitionTag()
  1777 TInt TNoTagOrNoDataClientsToStop::TransitionTag()
  1781 /**
  1778 /**
  1851     }
  1848     }
  1852 
  1849 
  1853 EXPORT_DEFINE_SMELEMENT(TNoTagOrNoClients, NetStateMachine::MStateFork, CoreNetStates::TContext)
  1850 EXPORT_DEFINE_SMELEMENT(TNoTagOrNoClients, NetStateMachine::MStateFork, CoreNetStates::TContext)
  1854 TInt TNoTagOrNoClients::TransitionTag()
  1851 TInt TNoTagOrNoClients::TransitionTag()
  1855 /**
  1852 /**
  1856 Returns KNoTag uif sender is marked EDefault, else CoreNetStates::KNonDefault.
  1853 Return KNoTag if there are data or control clients, else return KNoClients.
  1857 */
  1854 */
  1858     {
  1855     {
  1859     return iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData | TCFClientType::ECtrl))? KNoTag : KNoClients;
  1856     return iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData | TCFClientType::ECtrl))? KNoTag : KNoClients;
  1860     }
  1857     }
  1861 
  1858 
  2169 		{
  2166 		{
  2170 		startActivity->Cancel(iContext);
  2167 		startActivity->Cancel(iContext);
  2171 		}
  2168 		}
  2172 	}
  2169 	}
  2173 
  2170 
       
  2171 //-=========================================================
       
  2172 //
       
  2173 //  PRDestroyOrphans and PRDestroy
       
  2174 //
       
  2175 //-=========================================================
       
  2176 
       
  2177 void DestroyFirstClient(PRStates::TContext& aContext, const TClientType& aIncClientType, const TClientType& aExcClientType = TClientType::NullType())
       
  2178 /**
       
  2179 Send a TDestroy to the first non-default data client, or to the default data client if there
       
  2180 are no non-default data clients.  We need to destroy the non-default data clients before the default data
       
  2181 client because there can be internal references from non-default clients to the default data client.  
       
  2182 
       
  2183 The include and exclude iteration parameters are used to narrow the data client list as the caller requires.
       
  2184 */
       
  2185     {
       
  2186     TClientIter<TDefaultClientMatchPolicy> iter = aContext.Node().GetClientIter<TDefaultClientMatchPolicy>(aIncClientType, aExcClientType);
       
  2187 
       
  2188     RNodeInterface* client = NULL;
       
  2189     RNodeInterface* defaultClient = NULL;
       
  2190     while ((client = iter++) != NULL)
       
  2191         {
       
  2192         if (!(client->Flags() & TCFClientType::EDefault))
       
  2193             {
       
  2194             // Found a non-default data client, so destroy it.
       
  2195             break;
       
  2196             }
       
  2197         else
       
  2198             {
       
  2199             // Remember default data client.  Destroy it only if no non-default data clients.
       
  2200             if (defaultClient == NULL)
       
  2201                 {
       
  2202                 defaultClient = client;
       
  2203                 }
       
  2204             }
       
  2205         }
       
  2206     
       
  2207     if (client == NULL)
       
  2208         {
       
  2209         client = defaultClient;
       
  2210         }
       
  2211     // Should we panic if client is NULL?
       
  2212     if (client)
       
  2213         {
       
  2214         aContext.iNodeActivity->PostRequestTo(*client, TEChild::TDestroy().CRef());
       
  2215         client->SetFlags(TClientType::ELeaving);
       
  2216         }
       
  2217      }
       
  2218 
       
  2219 DEFINE_SMELEMENT(TDestroyFirstOrphan, NetStateMachine::MStateTransition, PRStates::TContext)
       
  2220 void TDestroyFirstOrphan::DoL()
       
  2221 /**
       
  2222 Destroy first orphan data client
       
  2223 */
       
  2224     {
       
  2225     DestroyFirstClient(iContext, TClientType(TCFClientType::EData), TClientType(0, KOrphanExcludeFlags));
       
  2226     }
       
  2227 
       
  2228 DEFINE_SMELEMENT(TDestroyFirstClient, NetStateMachine::MStateTransition, PRStates::TContext)
       
  2229 void TDestroyFirstClient::DoL()
       
  2230 /**
       
  2231 Destroy first data client
       
  2232 */
       
  2233     {
       
  2234     DestroyFirstClient(iContext, TClientType(TCFClientType::EData), TClientType(0, TCFClientType::ELeaving));
       
  2235     }
       
  2236 
       
  2237 DEFINE_SMELEMENT(TOrphansOrNoTag, NetStateMachine::MStateFork, PRStates::TContext)
       
  2238 TInt TOrphansOrNoTag::TransitionTag()
       
  2239 /**
       
  2240 If there are orphan data clients present, return KOrphans, else return KNoTag
       
  2241 */
       
  2242     {
       
  2243     if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(
       
  2244             TClientType(TCFClientType::EData), TClientType(0, KOrphanExcludeFlags)))
       
  2245         {
       
  2246         return KOrphans;
       
  2247         }
       
  2248     return KNoTag;
       
  2249     }
       
  2250 
       
  2251 DEFINE_SMELEMENT(TOrphansBackwardsOrNoTag, NetStateMachine::MStateFork, PRStates::TContext)
       
  2252 TInt TOrphansBackwardsOrNoTag::TransitionTag()
       
  2253 /**
       
  2254 If there are orphan data clients present, return KOrphans|EBackward, else return KNoTag
       
  2255 */
       
  2256     {
       
  2257     TOrphansOrNoTag orphansOrNoTag(iContext);
       
  2258     TInt tag = orphansOrNoTag.TransitionTag();
       
  2259     if (tag == KOrphans)
       
  2260         {
       
  2261         tag = KOrphans | NetStateMachine::EBackward;
       
  2262         }
       
  2263     return tag;
       
  2264     }
       
  2265 
       
  2266 DEFINE_SMELEMENT(TNoTagBackwardsOrNoClients, NetStateMachine::MStateFork, PRStates::TContext)
       
  2267 TInt TNoTagBackwardsOrNoClients::TransitionTag()
       
  2268 /**
       
  2269 If there are (non-leaving) data clients present, return KNoTag|EBackward, else return KNoClients
       
  2270 */
       
  2271     {
       
  2272     TNonLeavingNoTagOrNoClients nonLeavingNoTagOrNoClients(iContext);
       
  2273     TInt tag = nonLeavingNoTagOrNoClients.TransitionTag();
       
  2274     if (tag == KNoTag)
       
  2275         {
       
  2276         tag = KNoTag | NetStateMachine::EBackward;
       
  2277         }
       
  2278     return tag;
       
  2279     }
       
  2280 
       
  2281 
       
  2282 DEFINE_SMELEMENT(TNonLeavingNoTagOrNoClients, NetStateMachine::MStateFork, PRStates::TContext)
       
  2283 TInt TNonLeavingNoTagOrNoClients::TransitionTag()
       
  2284 /**
       
  2285 If there are (non-leaving) data clients left, return KNoTag, else return KNoClients
       
  2286 */
       
  2287     {
       
  2288     if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(
       
  2289             TClientType(TCFClientType::EData), TClientType(0, TCFClientType::ELeaving)))
       
  2290         {
       
  2291         return KNoTag;
       
  2292         }
       
  2293 
       
  2294     return KNoClients;
       
  2295     }