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"))); |
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 { |
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 } |