datacommsserver/esockserver/core_states/ss_coreprstates.cpp
branchRCL_3
changeset 12 8b5d60ce1e94
parent 9 77effd21b2c9
child 13 0b0e9fce0b58
equal deleted inserted replaced
11:98a7181d2ce7 12:8b5d60ce1e94
    77 using namespace Elements;
    77 using namespace Elements;
    78 using namespace Messages;
    78 using namespace Messages;
    79 using namespace MeshMachine;
    79 using namespace MeshMachine;
    80 using namespace Factories;
    80 using namespace Factories;
    81 
    81 
       
    82 const TUint32 KOrphanExcludeFlags = TCFClientType::EActive|TCFClientType::EActivating|TCFClientType::ELeaving|TCFClientType::EStarted|TCFClientType::EStarting;
       
    83 
    82 //-=========================================================
    84 //-=========================================================
    83 //
    85 //
    84 // Panics
    86 // Panics
    85 //
    87 //
    86 //-=========================================================
    88 //-=========================================================
   391 //-=========================================================
   393 //-=========================================================
   392 
   394 
   393 EXPORT_DEFINE_SMELEMENT(TAwaitingClientLeave, NetStateMachine::MState, CoreStates::TContext)
   395 EXPORT_DEFINE_SMELEMENT(TAwaitingClientLeave, NetStateMachine::MState, CoreStates::TContext)
   394 EXPORT_C TBool TAwaitingClientLeave::Accept()
   396 EXPORT_C TBool TAwaitingClientLeave::Accept()
   395 	{
   397 	{
   396 	return iContext.iMessage.IsMessage<TEChild::TLeft>()
   398 	return iContext.iMessage.IsMessage<TEPeer::TLeaveRequest>() || iContext.iMessage.IsMessage<TEChild::TLeft>();
   397 		|| iContext.iMessage.IsMessage<TEPeer::TLeaveRequest>();
       
   398 	}
   399 	}
   399 
   400 
   400 EXPORT_DEFINE_SMELEMENT(TDestroyOrphanedDataClients, NetStateMachine::MStateTransition, PRStates::TContext)
   401 EXPORT_DEFINE_SMELEMENT(TDestroyOrphanedDataClients, NetStateMachine::MStateTransition, PRStates::TContext)
   401 EXPORT_C void TDestroyOrphanedDataClients::DoL()
   402 EXPORT_C void TDestroyOrphanedDataClients::DoL()
   402 	{
   403 	{
   518 
   519 
   519 	//This transition may only be triggered by a peer message from a data client
   520 	//This transition may only be triggered by a peer message from a data client
   520 	__ASSERT_DEBUG(iContext.iPeer, User::Panic(KSpecAssert_ESockCrStaCPRSC, 13));
   521 	__ASSERT_DEBUG(iContext.iPeer, User::Panic(KSpecAssert_ESockCrStaCPRSC, 13));
   521 	__ASSERT_DEBUG(iContext.iPeer->Type()==TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRSC, 14));
   522 	__ASSERT_DEBUG(iContext.iPeer->Type()==TCFClientType::EData, User::Panic(KSpecAssert_ESockCrStaCPRSC, 14));
   522 
   523 
   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 &&
   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")));
   685     	{
   686     	{
   686     	return EFalse;
   687     	return EFalse;
   687     	}
   688     	}
   688 	if (iContext.iPeer)
   689 	if (iContext.iPeer)
   689 		{
   690 		{
   690 		iContext.iPeer->ClearFlags(TCFClientType::EStopping); 
   691 		iContext.iPeer->ClearFlags(TCFClientType::EStarted | TCFClientType::EStopping); 
   691 		}
   692 		}
   692 	if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EStopping)))  
   693 	if (iContext.Node().CountClients<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EStopping)))  
   693 		{
   694 		{
   694 		//There are more to wait for
   695 		//There are more to wait for
   695 		iContext.iMessage.ClearMessageId();
   696 		iContext.iMessage.ClearMessageId();
   907    	RNodeInterface* cl = iter[0];
   908    	RNodeInterface* cl = iter[0];
   908    	//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.
   909    	if (cl)
   910    	if (cl)
   910    		{
   911    		{
   911 		__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
   912 		__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
   912    		cl->PostMessage(TNodeCtxId(iContext.ActivityId(), iContext.NodeId()), TEChild::TLeft().CRef());
   913    		iContext.iNodeActivity->PostToOriginators(TEChild::TLeft().CRef());
   913    		iContext.Node().RemoveClient(cl->RecipientId(),iContext);
   914    		iContext.Node().RemoveClient(cl->RecipientId(),iContext);
   914    		__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!
   915    		}
   916    		}
   916 	}
   917 	}
   917 
   918 
  1357 
  1358 
  1358 EXPORT_DEFINE_SMELEMENT(TSendBindToComplete, NetStateMachine::MStateTransition, CoreNetStates::TContext)
  1359 EXPORT_DEFINE_SMELEMENT(TSendBindToComplete, NetStateMachine::MStateTransition, CoreNetStates::TContext)
  1359 EXPORT_C void TSendBindToComplete::DoL()
  1360 EXPORT_C void TSendBindToComplete::DoL()
  1360 	{
  1361 	{
  1361 	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
  1362 	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
  1362 	iContext.iNodeActivity->PostToOriginators(TCFDataClient::TBindToComplete(iContext.iNodeActivity->Error()).CRef());
  1363 	iContext.iNodeActivity->PostToOriginators(TCFDataClient::TBindToComplete().CRef());
  1363 	}
  1364 	}
  1364 
  1365 
  1365 EXPORT_DEFINE_SMELEMENT(TBindSelfToPresentBearer, NetStateMachine::MStateTransition, CoreNetStates::TContext)
  1366 EXPORT_DEFINE_SMELEMENT(TBindSelfToPresentBearer, NetStateMachine::MStateTransition, CoreNetStates::TContext)
  1366 EXPORT_C void TBindSelfToPresentBearer::DoL()
  1367 EXPORT_C void TBindSelfToPresentBearer::DoL()
  1367 	{
  1368 	{
  1504 
  1505 
  1505 
  1506 
  1506 EXPORT_DEFINE_SMELEMENT(TAwaitingBindTo, NetStateMachine::MState, CoreStates::TContext)
  1507 EXPORT_DEFINE_SMELEMENT(TAwaitingBindTo, NetStateMachine::MState, CoreStates::TContext)
  1507 EXPORT_C TBool TAwaitingBindTo::Accept()
  1508 EXPORT_C TBool TAwaitingBindTo::Accept()
  1508 	{
  1509 	{
  1509 	const TCFDataClient::TBindTo* bindToMessage = message_cast<TCFDataClient::TBindTo>(&iContext.iMessage);
  1510 	return iContext.iMessage.IsMessage<TCFDataClient::TBindTo>();
  1510 	if (bindToMessage)
       
  1511     	{
       
  1512     	//TBindTo is always a response. there's gotta be an activity.
       
  1513     	if (iContext.iNodeActivity && iContext.iNodeActivity->SupportsExtInterface(ABindingActivity::KInterfaceId))
       
  1514         	{
       
  1515         	ABindingActivity* bindingActivity = reinterpret_cast<ABindingActivity*>(iContext.iNodeActivity->FetchExtInterface(ABindingActivity::KInterfaceId));
       
  1516        	    bindingActivity->StoreOriginator(iContext.iSender);
       
  1517         	}
       
  1518         return ETrue;
       
  1519     	}
       
  1520     return EFalse;
       
  1521 	}
  1511 	}
  1522 
  1512 
  1523 EXPORT_DEFINE_SMELEMENT(TAwaitingBindToOrCancel, NetStateMachine::MState, CoreStates::TContext)
  1513 EXPORT_DEFINE_SMELEMENT(TAwaitingBindToOrCancel, NetStateMachine::MState, CoreStates::TContext)
  1524 TBool TAwaitingBindToOrCancel::Accept()
  1514 TBool TAwaitingBindToOrCancel::Accept()
  1525 	{
  1515 	{
  1610 	}
  1600 	}
  1611 
  1601 
  1612 EXPORT_DEFINE_SMELEMENT(CoreNetStates::TAwaitingBindToComplete, NetStateMachine::MState, CoreNetStates::TContext)
  1602 EXPORT_DEFINE_SMELEMENT(CoreNetStates::TAwaitingBindToComplete, NetStateMachine::MState, CoreNetStates::TContext)
  1613 EXPORT_C TBool CoreNetStates::TAwaitingBindToComplete::Accept()
  1603 EXPORT_C TBool CoreNetStates::TAwaitingBindToComplete::Accept()
  1614 	{
  1604 	{
  1615 	TCFDataClient::TBindToComplete* bindToComplete = message_cast<TCFDataClient::TBindToComplete>(&iContext.iMessage);
  1605 	return iContext.iMessage.IsMessage<TCFDataClient::TBindToComplete>();
  1616 	if (bindToComplete)
       
  1617     	{
       
  1618     	__ASSERT_DEBUG(iContext.iNodeActivity, CorePrPanic(KPanicNoActivity));
       
  1619 	    iContext.iNodeActivity->SetError(bindToComplete->iValue);
       
  1620 		return ETrue;
       
  1621     	}
       
  1622     return EFalse;
       
  1623 	}
  1606 	}
  1624 
  1607 
  1625 EXPORT_DEFINE_SMELEMENT(TAwaitingProvision, NetStateMachine::MState, PRStates::TContext)
  1608 EXPORT_DEFINE_SMELEMENT(TAwaitingProvision, NetStateMachine::MState, PRStates::TContext)
  1626 EXPORT_C TBool TAwaitingProvision::Accept()
  1609 EXPORT_C TBool TAwaitingProvision::Accept()
  1627 	{
  1610 	{
  1865     }
  1848     }
  1866 
  1849 
  1867 EXPORT_DEFINE_SMELEMENT(TNoTagOrNoClients, NetStateMachine::MStateFork, CoreNetStates::TContext)
  1850 EXPORT_DEFINE_SMELEMENT(TNoTagOrNoClients, NetStateMachine::MStateFork, CoreNetStates::TContext)
  1868 TInt TNoTagOrNoClients::TransitionTag()
  1851 TInt TNoTagOrNoClients::TransitionTag()
  1869 /**
  1852 /**
  1870 Returns KNoTag uif sender is marked EDefault, else CoreNetStates::KNonDefault.
  1853 Return KNoTag if there are data or control clients, else return KNoClients.
  1871 */
  1854 */
  1872     {
  1855     {
  1873     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;
  1874     }
  1857     }
  1875 
  1858 
  2183 		{
  2166 		{
  2184 		startActivity->Cancel(iContext);
  2167 		startActivity->Cancel(iContext);
  2185 		}
  2168 		}
  2186 	}
  2169 	}
  2187 
  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     }