networkcontrol/iptransportlayer/src/netmcpractivities.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // NETMCPR_ACTIVITIES.H
       
    15 // 
       
    16 //
       
    17 
       
    18 #define SYMBIAN_NETWORKING_UPS
       
    19 
       
    20 #include "netmcpr.h"
       
    21 #include "netmcprstates.h"
       
    22 #include "netmcpractivities.h"
       
    23 #include "IPMessages.h"
       
    24 #include <comms-infras/ss_nodemessages_serviceprovider.h>
       
    25 #include <comms-infras/ss_nodemessages_selector.h>
       
    26 #include <comms-infras/ss_nodemessages_factory.h>
       
    27 #include <comms-infras/ss_nodemessages_tiermanagerfactory.h>
       
    28 #include <comms-infras/coremcprstates.h>
       
    29 #include <comms-infras/coremcpractivities.h>
       
    30 #include <ss_glob.h>
       
    31 #include <elements/nm_messages_errorrecovery.h>
       
    32 #include <elements/nm_messages_child.h>
       
    33 
       
    34 //#ifdef SYMBIAN_NETWORKING_UPS
       
    35 #include "netmcprups_activities.h"
       
    36 //#include <comms-infras/upsprstates.h>
       
    37 //#include <comms-infras/upsmessages.h>
       
    38 //using namespace UpsMCprActivities;
       
    39 //using namespace NetMCprUpsActivities;
       
    40 //#endif //SYMBIAN_NETWORKING_UPS
       
    41 
       
    42 using namespace Messages;
       
    43 using namespace MeshMachine;
       
    44 using namespace NetStateMachine;
       
    45 using namespace ESock;
       
    46 using namespace MCprActivities;
       
    47 using namespace NetMCprActivities;
       
    48 using namespace NetMCprLegacyActivities;
       
    49 
       
    50 namespace NetMCprDeferredSelectActivity
       
    51 {
       
    52 /** Deferred selection activity to support legacy user prompt behaviour.
       
    53 
       
    54 	This activity forms an extension to the basic ConnectionStartRecovery activity (in Core).
       
    55 	It starts before the basic ConnectionStartRecovery activity, remembers the original recovery
       
    56 	request, and triggers the basic ConnectionStartRecovery activity after a successful completion.
       
    57 
       
    58 	Along with ConnectionStartRecovery activity, it belongs to a group of Error Recovery Activities.
       
    59 	Error Recovery Activities need to handle their own errors (generated as well as returned).
       
    60 
       
    61 	The legacy selection may not be fully completed (i.e. certain service providers
       
    62 	could have been skipped during selection). This activity completes the selection,
       
    63 	potentially providing more connection choices after an unsuccessful attempt
       
    64 	to start a connection (with previously selected choices).
       
    65 */
       
    66 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionStartRecovery, MCprDeferredSelect, TEErrorRecovery::TErrorRecoveryRequest, CDeferredSelectionActivity::NewL)
       
    67 	//Intercept the reconnection request if appropriate
       
    68 	FIRST_NODEACTIVITY_ENTRY(CDeferredSelectionActivity::TAwaitingConnectionStartRecoveryRequest, MeshMachine::TNoTag)
       
    69 	NODEACTIVITY_ENTRY(KNoTag, CDeferredSelectionActivity::TParkReConnectRequestAndFindOrCreateTierManager, CDeferredSelectionActivity::TState<MCprStates::TAwaitingTierManagerCreated>, MeshMachine::TNoTag)
       
    70 	NODEACTIVITY_ENTRY(KNoTag, CDeferredSelectionActivity::TJoinTierManager, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
       
    71 	NODEACTIVITY_ENTRY(KNoTag, CDeferredSelectionActivity::TCompleteDeferredSelection, CDeferredSelectionActivity::TState<MCprStates::TAwaitingSelectComplete>, MeshMachine::TNoTag)
       
    72 	NODEACTIVITY_ENTRY(KNoTag, CDeferredSelectionActivity::TProcessSelectComplete, CDeferredSelectionActivity::TState<MCprStates::TAwaitingSelectComplete>, MeshMachine::TNoTag)
       
    73 	NODEACTIVITY_ENTRY(KNoTag, CDeferredSelectionActivity::TJoinServiceProvider, CDeferredSelectionActivity::TState<CoreStates::TAwaitingJoinComplete>, MeshMachine::TNoTagOrErrorTag)
       
    74 	//Now run the basic reconnection which will fail if our selection did not give us any more choices
       
    75 	LAST_NODEACTIVITY_ENTRY(KNoTag, CDeferredSelectionActivity::TReDispatchReConnectRequest)
       
    76 	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
       
    77 NODEACTIVITY_END()
       
    78 }
       
    79 
       
    80 namespace NetMcprPromptingReSelectActivity
       
    81 {
       
    82 /* This activity is started when there is a need to re-connect and the network
       
    83  * MCPr contains any information regarding to this. The behaviour of this activity
       
    84  * is almost the same as the DeferredSelection activity but it uses different
       
    85  * Extensions and different connection preferences. Basically this activity is used
       
    86  * if prompt dialog shold be invoked during re-selection and we have to use the
       
    87  * so called 399 selection instead of the legacy one.
       
    88  * 
       
    89  * NOTE: THIS ACTIVITY HAS TO BE REMOVED AS THIS KIND OF PROMTING FUNCTIONALITY IS NOT
       
    90  * ENOUGH GENERIC. THE SAME BEHAVIOUR SHOULD WE HAVE INDEPENDENTLY OF THE GIVEN SELECTION
       
    91  * MECHANISM AND SELECTORS... THERE WILL BE A DEFECT WHICH WILL COVER AND DESCRIBE THE PROBLEM.   
       
    92 */
       
    93 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityConnectionStartRecovery, MCprPromptingReSelect, TEErrorRecovery::TErrorRecoveryRequest, CPromptingReSelectActivity::NewL)
       
    94 	//Intercept the reconnection request if appropriate
       
    95 	FIRST_NODEACTIVITY_ENTRY(CPromptingReSelectActivity::TAwaitingConnectionStartRecoveryRequest, MeshMachine::TNoTag)
       
    96 	NODEACTIVITY_ENTRY(KNoTag, CPromptingReSelectActivity::TParkReConnectRequestAndFindOrCreateTierManager, CPromptingReSelectActivity::TState<MCprStates::TAwaitingTierManagerCreated>, MeshMachine::TNoTag)
       
    97 	NODEACTIVITY_ENTRY(KNoTag, CPromptingReSelectActivity::TJoinTierManager, CoreStates::TAwaitingJoinComplete, MeshMachine::TNoTag)
       
    98 	NODEACTIVITY_ENTRY(KNoTag, CPromptingReSelectActivity::TCompletePromptingReSelection, CPromptingReSelectActivity::TState<MCprStates::TAwaitingSelectComplete>, MeshMachine::TNoTag)
       
    99 	NODEACTIVITY_ENTRY(KNoTag, CPromptingReSelectActivity::TProcessSelectComplete, CPromptingReSelectActivity::TState<MCprStates::TAwaitingSelectComplete>, MeshMachine::TNoTag)
       
   100 	NODEACTIVITY_ENTRY(KNoTag, CPromptingReSelectActivity::TJoinServiceProvider, CPromptingReSelectActivity::TState<CoreStates::TAwaitingJoinComplete>, MeshMachine::TNoTagOrErrorTag)
       
   101 	//Now run the basic reconnection which will fail if our selection did not give us any more choices
       
   102 	LAST_NODEACTIVITY_ENTRY(KNoTag, CPromptingReSelectActivity::TReDispatchReConnectRequest)
       
   103 	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing)
       
   104 NODEACTIVITY_END()
       
   105 }
       
   106 
       
   107 #ifdef DUMMY_MOBILITY_MCPR
       
   108 namespace NetMCprDummyMobilityActivity
       
   109 {
       
   110 DECLARE_DEFINE_NODEACTIVITY(ECFActivityDummyMobilityActivity, MCprDummyMobility, TCFMessage::TMigrationAvailable)
       
   111 	FIRST_NODEACTIVITY_ENTRY(NetMCprStates::TDummyAwaitingMigrationAvailable, MeshMachine::TNoTag)
       
   112 	NODEACTIVITY_ENTRY(KNoTag, NetMCprStates::TSendMigrationAvailable, NetMCprStates::TAwaitingMigrationRequestedOrMigrationRejected, NetMCprStates::TMigrationRequestedOrMigrationRejected)
       
   113 
       
   114 	LAST_NODEACTIVITY_ENTRY(NetMCprStates::KMigrationRejected, MeshMachine::TDoNothing)
       
   115 
       
   116 	NODEACTIVITY_ENTRY(NetMCprStates::KMigrationRequested, NetMCprStates::TSendMigrateToAccessPoint, NetMCprStates::TAwaitingMigrationRejectedOrMigrationAccepted, MeshMachine::TNoTag) // we dont actually care
       
   117 
       
   118 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
       
   119 NODEACTIVITY_END()
       
   120 }
       
   121 #endif
       
   122 
       
   123 namespace NetMCprProcessPolicyParamsActivity
       
   124 {
       
   125 DECLARE_DEFINE_NODEACTIVITY(ECFActivityCustom, MCprProcessPolicyParams, TCFIPMessage::TPolicyParams)
       
   126 	NODEACTIVITY_ENTRY(KNoTag, NetMCprStates::TProcessPolicyParams, NetMCprStates::TAwaitingPolicyParams, MeshMachine::TNoTag)
       
   127 NODEACTIVITY_END()
       
   128 }
       
   129 
       
   130 namespace NetMCprActivities
       
   131 {
       
   132 DEFINE_ACTIVITY_MAP(netMCprActivities)
       
   133 	ACTIVITY_MAP_ENTRY(NetMCprDeferredSelectActivity, MCprDeferredSelect)
       
   134 	ACTIVITY_MAP_ENTRY(NetMcprPromptingReSelectActivity, MCprPromptingReSelect)
       
   135 	ACTIVITY_MAP_ENTRY(NetMCprProcessPolicyParamsActivity, MCprProcessPolicyParams)
       
   136 #ifdef SYMBIAN_NETWORKING_UPS
       
   137 	ACTIVITY_MAP_ENTRY(NetMCprPolicyCheckRequestActivity, NetMCprPolicyCheckRequest)		 // UPS support
       
   138 	ACTIVITY_MAP_ENTRY(NetMCprUpsNoBearerActivity, NetMCprUpsNoBearer)						 // UPS support
       
   139 	ACTIVITY_MAP_ENTRY(NetMCprMonitorProviderStatusActivity, NetMCprUpsProviderStatusChange) // UPS support					
       
   140 	ACTIVITY_MAP_ENTRY(NetMCprUpsStatusChangeActivity, NetMCprUpsStatusChange)				 // UPS support
       
   141 	#endif
       
   142 ACTIVITY_MAP_END_BASE(MobilityMCprActivities, mobilityMCprActivities)
       
   143 }
       
   144 
       
   145 //
       
   146 //Re Connection - CDeferredSelectionActivity
       
   147 DEFINE_SMELEMENT(CDeferredSelectionActivity::TAwaitingConnectionStartRecoveryRequest, NetStateMachine::MState, CDeferredSelectionActivity::TContext)
       
   148 TBool CDeferredSelectionActivity::TAwaitingConnectionStartRecoveryRequest::Accept()
       
   149 	{
       
   150 	//If this is a reconnect request plus we can obtain some more options from the deferred selection, start this activity.
       
   151 	//If we can not obtan any more choices do not bother with starting, go straight to the standard reconnection.
       
   152 	if (MCprStates::TAwaitingConnectionStartRecoveryRequest::Accept()
       
   153 		&& iContext.Node().AccessPointConfig().FindExtension(TDeferredSelectionPrefsExt::TypeId()))
       
   154 		{
       
   155 		ASSERT(iContext.Node().ProviderInfo().Instance()); //We only support deferred selection for legacy providers on this layer
       
   156 		return ETrue;
       
   157 		}
       
   158 	return EFalse;
       
   159 	}
       
   160 
       
   161 DEFINE_SMELEMENT(CDeferredSelectionActivity::TParkReConnectRequestAndFindOrCreateTierManager, NetStateMachine::MStateTransition, CDeferredSelectionActivity::TContext)
       
   162 void CDeferredSelectionActivity::TParkReConnectRequestAndFindOrCreateTierManager::DoL()
       
   163 	{
       
   164 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   165 	CDeferredSelectionActivity& activity = static_cast<CDeferredSelectionActivity&>(*iContext.iNodeActivity);
       
   166 	activity.iOriginalErrContext = message_cast<TEErrorRecovery::TErrorRecoveryRequest>(iContext.iMessage).iErrContext;
       
   167 	activity.ParkReConnectRequestL(iContext);
       
   168 
       
   169 	//Not leaving getter plus asserted
       
   170 	const TDeferredSelectionPrefsExt* ext = static_cast<const TDeferredSelectionPrefsExt*>(iContext.Node().AccessPointConfig().FindExtension(TDeferredSelectionPrefsExt::TypeId()));
       
   171 	ASSERT(ext);
       
   172 	ASSERT(ext->iTierId.iUid!=0);
       
   173 	TAlwaysFindFactoryQuery query;
       
   174 	iContext.iNodeActivity->PostRequestTo(SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)),
       
   175 		TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, ext->iTierId, &query).CRef());
       
   176 	}
       
   177 
       
   178 DEFINE_SMELEMENT(CDeferredSelectionActivity::TCompleteDeferredSelection, NetStateMachine::MStateTransition, CDeferredSelectionActivity::TContext)
       
   179 void CDeferredSelectionActivity::TCompleteDeferredSelection::DoL()
       
   180 	{
       
   181 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   182 	CDeferredSelectionActivity& ac = static_cast<CDeferredSelectionActivity&>(*iContext.iNodeActivity);
       
   183 
       
   184 	const TDeferredSelectionPrefsExt& ext = static_cast<const TDeferredSelectionPrefsExt&>(iContext.Node().AccessPointConfig().FindExtensionL(
       
   185 	        TDeferredSelectionPrefsExt::TypeId()));
       
   186 	ac.PostRequestTo(ac.iTierManager, TCFSelector::TSimpleSelect(TSelectionPrefs(ext.iPrefs)).CRef());
       
   187 	}
       
   188 
       
   189 DEFINE_SMELEMENT(CDeferredSelectionActivity::TProcessSelectComplete, NetStateMachine::MStateTransition, CDeferredSelectionActivity::TContext)
       
   190 void CDeferredSelectionActivity::TProcessSelectComplete::DoL()
       
   191 	{
       
   192 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   193 	CDeferredSelectionActivity& activity = static_cast<CDeferredSelectionActivity&>(*iContext.iNodeActivity);
       
   194 	activity.iSelectedMcpr = message_cast<TCFSelector::TSelectComplete>(iContext.iMessage).iNodeId;
       
   195 
       
   196 	//The provider must be valid and different from what we already have
       
   197 	if (iContext.Node().FindClient(activity.iSelectedMcpr))
       
   198 		{
       
   199 		iContext.iNodeActivity->SetError(
       
   200 		    static_cast<CDeferredSelectionActivity*>(iContext.iNodeActivity)->iOriginalErrContext.iStateChange.iError);
       
   201 		}
       
   202 	else if (activity.iSelectedMcpr.IsNull())
       
   203     	{
       
   204     	User::Leave(
       
   205     	    static_cast<CDeferredSelectionActivity*>(iContext.iNodeActivity)->iOriginalErrContext.iStateChange.iError);
       
   206     	}
       
   207 	}
       
   208 
       
   209 DEFINE_SMELEMENT(CDeferredSelectionActivity::TJoinServiceProvider, NetStateMachine::MStateTransition, CDeferredSelectionActivity::TContext)
       
   210 void CDeferredSelectionActivity::TJoinServiceProvider::DoL()
       
   211 	{
       
   212 	//Final select complete
       
   213 	ASSERT(message_cast<TCFSelector::TSelectComplete>(iContext.iMessage).iNodeId.IsNull());
       
   214 
       
   215 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   216 	CDeferredSelectionActivity& activity = static_cast<CDeferredSelectionActivity&>(*iContext.iNodeActivity);
       
   217 
       
   218 	//Join the new service provider
       
   219 	RNodeInterface* client = iContext.Node().AddClientL(activity.iSelectedMcpr, TClientType(TCFClientType::EServProvider));
       
   220 
       
   221 	//Join the selected provider as a control client, send select complete message.
       
   222 	//There is no need to remember the channel (SetSentTo()) because we do not expect any answer.
       
   223 	activity.PostRequestTo(*client,
       
   224 		TCFServiceProvider::TJoinRequest(iContext.NodeId(), TCFClientType::ECtrl).CRef());
       
   225 	}
       
   226 
       
   227 DEFINE_SMELEMENT(CDeferredSelectionActivity::TReDispatchReConnectRequest, NetStateMachine::MStateTransition, CDeferredSelectionActivity::TContext)
       
   228 void CDeferredSelectionActivity::TReDispatchReConnectRequest::DoL()
       
   229 	{
       
   230 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   231 	CDeferredSelectionActivity& activity = static_cast<CDeferredSelectionActivity&>(*iContext.iNodeActivity);
       
   232 	activity.ReDispatchReConnectRequestL(iContext);
       
   233 	}
       
   234 
       
   235 DEFINE_SMELEMENT(CDeferredSelectionActivity::TJoinTierManager, NetStateMachine::MStateTransition, CDeferredSelectionActivity::TContext)
       
   236 void CDeferredSelectionActivity::TJoinTierManager::DoL()
       
   237 	{
       
   238 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   239 	CDeferredSelectionActivity& ac = static_cast<CDeferredSelectionActivity&>(*iContext.iNodeActivity);
       
   240 	ac.iTierManager = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage).iNodeId;
       
   241     ASSERT(!ac.iTierManager.IsNull()); //Must always be valid.
       
   242     ac.PostRequestTo(ac.iTierManager, TCFPeer::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef());
       
   243 	}
       
   244 
       
   245 MeshMachine::CNodeActivityBase* CDeferredSelectionActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   246     {
       
   247     return new (ELeave) CDeferredSelectionActivity(aActivitySig, aNode);
       
   248     }
       
   249 
       
   250 CDeferredSelectionActivity::CDeferredSelectionActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   251 :	MeshMachine::CNodeActivityBase(aActivitySig, aNode)
       
   252 	{
       
   253 	}
       
   254 
       
   255 CDeferredSelectionActivity::~CDeferredSelectionActivity()
       
   256 	{
       
   257 	if (!iTierManager.IsNull())
       
   258 		{
       
   259 		RClientInterface::OpenPostMessageClose(iNode.Id(), iTierManager, TEChild::TLeft().CRef());
       
   260 		iTierManager.SetNull();
       
   261 		}
       
   262 	}
       
   263 
       
   264 void CDeferredSelectionActivity::ParkReConnectRequestL(const TNodeContextBase& aContext)
       
   265 	{
       
   266 	User::LeaveIfError(StoreContext(aContext));
       
   267 	}
       
   268 
       
   269 void CDeferredSelectionActivity::ReDispatchReConnectRequestL(const TNodeContextBase& aContext)
       
   270 	{
       
   271 	TBuf8<__Align8(sizeof(TNodeContextBase))> ctxBuf;
       
   272 	TBuf8<__Align8(TSignalBase::KMaxInlineMessageSize + TSignalBase::KMaxUnstoredOverhead)> msgBuf;
       
   273 	TNodeCtxId dummy;
       
   274 
       
   275 	TNodeContextBase* storedContext = LoadContext(aContext.iNode, aContext.iNodeActivity, ctxBuf, msgBuf, dummy);
       
   276 
       
   277 	//We should never be here if parking of the original request failed!
       
   278 	__ASSERT_ALWAYS(storedContext, User::Panic(KNetMCprPanic, KPanicNoContext));
       
   279 	PostToOriginators(storedContext->iMessage);
       
   280 	iContextDesc.Zero();
       
   281 	}
       
   282 
       
   283 void CDeferredSelectionActivity::ReplyToOriginators(TEErrorRecovery::TErrorRecoveryResponse& aCFMessageSig)
       
   284 	{
       
   285 //TODO[PROD] - logging
       
   286    	//MESH_LOG_MESSAGE(KESockComponentTag, KESockMeshMachine, aCFMessageSig, this,_S8("CConnectionRecoveryActivity:\tPostToOriginators"));
       
   287 	for (TInt n = iOriginators.Count() - 1;n>=0; n--)
       
   288 		{
       
   289 		Messages::TNodePeerId& peerId = iOriginators[n];
       
   290 		//aCFMessageSig.SetActivity(peerId.iActivityId);
       
   291 		TCFSafeMessage::TResponseCarrierWest<TEErrorRecovery::TErrorRecoveryResponse> resp(aCFMessageSig, peerId.Peer().RecipientId());
       
   292 		PostToOriginator(peerId, resp);
       
   293 		}
       
   294 	}
       
   295 
       
   296 
       
   297 //
       
   298 //Re Connection - CPromptingReSelectActivity
       
   299 DEFINE_SMELEMENT(CPromptingReSelectActivity::TAwaitingConnectionStartRecoveryRequest, NetStateMachine::MState, CPromptingReSelectActivity::TContext)
       
   300 TBool CPromptingReSelectActivity::TAwaitingConnectionStartRecoveryRequest::Accept()
       
   301 	{
       
   302 	//If this is a reconnect request plus we can obtain some more options from the deferred selection, start this activity.
       
   303 	//If we can not obtan any more choices do not bother with starting, go straight to the standard reconnection.
       
   304 	if (MCprStates::TAwaitingConnectionStartRecoveryRequest::Accept())
       
   305 	    {
       
   306 	    const TPromptingSelectionPrefsExt* ext = static_cast<const TPromptingSelectionPrefsExt*>(
       
   307 	            iContext.Node().AccessPointConfig().FindExtension(TPromptingSelectionPrefsExt::TypeId()));
       
   308 		if (ext)
       
   309             {
       
   310     		/* it possible that the extension contains a list with 0 element in it. The reason for that:
       
   311     		 * As the 'CIpProtoProviderSelector' selector receives one-by-one the preferences not as a list
       
   312     		 * it cannot know when the selection on that given layer will be finished. So when there is a 
       
   313     		 * prompting AP the RunL of that selector will append an extension to the Network MCPr, indicating
       
   314     		 * that there was already a prompt, with an empty list in that extension. However if the given 
       
   315     		 * preference was the last one in the list which needed to prompt the RunL will append the given
       
   316     		 * extension to the Network MCPr with an empty list just to indicate that the prompting has happened
       
   317     		 * so no other dialog should be invoked. So during re-selection there will be an extension appended 
       
   318     		 * to the Network MCPr with an empty list. Here is the code which checks this situation and acts
       
   319     		 * according to the situation.
       
   320     		 * 
       
   321     		 * NOTE: this whole activity has to be removed and the prompting logic should be re-worked in every
       
   322     		 * IPProto level selector by _NOT_ using the Network level MCPR at all!!!!!!! There will be a defect for
       
   323     		 * this problem!!!
       
   324     		 * 
       
   325     		 */
       
   326             const TConnPref& pref = ext->iPrefs;
       
   327             const TConnIdList& list = static_cast<const TConnIdList&>(pref);
       
   328 		
       
   329     		if (list.Count() == 1)
       
   330     			{
       
   331     			return ETrue;
       
   332     			}
       
   333     		else
       
   334     			{
       
   335     			//remove the empty list and return with EFalse so the default errorhandling will take place...
       
   336     			const_cast<TPromptingSelectionPrefsExt*>(ext)->iPromptingInProgress = EFalse;
       
   337     			}
       
   338             }
       
   339 	    }
       
   340 	return EFalse;
       
   341 	}
       
   342 
       
   343 DEFINE_SMELEMENT(CPromptingReSelectActivity::TParkReConnectRequestAndFindOrCreateTierManager, NetStateMachine::MStateTransition, CPromptingReSelectActivity::TContext)
       
   344 void CPromptingReSelectActivity::TParkReConnectRequestAndFindOrCreateTierManager::DoL()
       
   345 	{
       
   346 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   347 	CPromptingReSelectActivity& activity = static_cast<CPromptingReSelectActivity&>(*iContext.iNodeActivity);
       
   348 	activity.iOriginalErrContext = message_cast<TEErrorRecovery::TErrorRecoveryRequest>(iContext.iMessage).iErrContext;
       
   349 	activity.ParkReConnectRequestL(iContext);
       
   350 
       
   351 	//Not leaving getter plus asserted
       
   352 	const TPromptingSelectionPrefsExt* ext = static_cast<const TPromptingSelectionPrefsExt*>(iContext.Node().AccessPointConfig().FindExtension(TPromptingSelectionPrefsExt::TypeId()));
       
   353 	ASSERT(ext);
       
   354 	ASSERT(ext->iTierId.iUid!=0);
       
   355 	TAlwaysFindFactoryQuery query;
       
   356 	iContext.iNodeActivity->PostRequestTo(SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)),
       
   357 		TCFFactory::TFindOrCreatePeer(TCFPlayerRole::ETierMgrPlane, ext->iTierId, &query).CRef());
       
   358 	}
       
   359 
       
   360 DEFINE_SMELEMENT(CPromptingReSelectActivity::TCompletePromptingReSelection, NetStateMachine::MStateTransition, CPromptingReSelectActivity::TContext)
       
   361 void CPromptingReSelectActivity::TCompletePromptingReSelection::DoL()
       
   362 	{
       
   363 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   364 	CPromptingReSelectActivity& ac = static_cast<CPromptingReSelectActivity&>(*iContext.iNodeActivity);
       
   365 
       
   366 	const TPromptingSelectionPrefsExt& ext = static_cast<const TPromptingSelectionPrefsExt&>(iContext.Node().AccessPointConfig().FindExtensionL(
       
   367 	        TPromptingSelectionPrefsExt::TypeId()));
       
   368 	ac.PostRequestTo(ac.iTierManager, TCFSelector::TSimpleSelect(TSelectionPrefs(ext.iPrefs)).CRef());
       
   369 	}
       
   370 
       
   371 DEFINE_SMELEMENT(CPromptingReSelectActivity::TProcessSelectComplete, NetStateMachine::MStateTransition, CPromptingReSelectActivity::TContext)
       
   372 void CPromptingReSelectActivity::TProcessSelectComplete::DoL()
       
   373 	{
       
   374 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   375 	CPromptingReSelectActivity& activity = static_cast<CPromptingReSelectActivity&>(*iContext.iNodeActivity);
       
   376 	activity.iSelectedMcpr = message_cast<TCFSelector::TSelectComplete>(iContext.iMessage).iNodeId;
       
   377 
       
   378 	//The provider must be valid and different from what we already have
       
   379 	if (iContext.Node().FindClient(activity.iSelectedMcpr))
       
   380 		{
       
   381 		iContext.iNodeActivity->SetError(
       
   382 		    static_cast<CPromptingReSelectActivity*>(iContext.iNodeActivity)->iOriginalErrContext.iStateChange.iError);
       
   383 		}
       
   384 	else if (activity.iSelectedMcpr.IsNull())
       
   385     	{
       
   386     	User::Leave(
       
   387     	    static_cast<CPromptingReSelectActivity*>(iContext.iNodeActivity)->iOriginalErrContext.iStateChange.iError);
       
   388     	}
       
   389 	}
       
   390 
       
   391 DEFINE_SMELEMENT(CPromptingReSelectActivity::TJoinServiceProvider, NetStateMachine::MStateTransition, CPromptingReSelectActivity::TContext)
       
   392 void CPromptingReSelectActivity::TJoinServiceProvider::DoL()
       
   393 	{
       
   394 	//Final select complete
       
   395 	ASSERT(message_cast<TCFSelector::TSelectComplete>(iContext.iMessage).iNodeId.IsNull());
       
   396 
       
   397 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   398 	CPromptingReSelectActivity& activity = static_cast<CPromptingReSelectActivity&>(*iContext.iNodeActivity);
       
   399 
       
   400 	//Join the new service provider
       
   401 	RNodeInterface* client = iContext.Node().AddClientL(activity.iSelectedMcpr, TClientType(TCFClientType::EServProvider));
       
   402 
       
   403 	//Join the selected provider as a control client, send select complete message.
       
   404 	//There is no need to remember the channel (SetSentTo()) because we do not expect any answer.
       
   405 	activity.PostRequestTo(*client,
       
   406 		TCFServiceProvider::TJoinRequest(iContext.NodeId(), TCFClientType::ECtrl).CRef());
       
   407 	}
       
   408 
       
   409 DEFINE_SMELEMENT(CPromptingReSelectActivity::TReDispatchReConnectRequest, NetStateMachine::MStateTransition, CPromptingReSelectActivity::TContext)
       
   410 void CPromptingReSelectActivity::TReDispatchReConnectRequest::DoL()
       
   411 	{
       
   412 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   413 	CPromptingReSelectActivity& activity = static_cast<CPromptingReSelectActivity&>(*iContext.iNodeActivity);
       
   414 	activity.ReDispatchReConnectRequestL(iContext);
       
   415 	}
       
   416 
       
   417 DEFINE_SMELEMENT(CPromptingReSelectActivity::TJoinTierManager, NetStateMachine::MStateTransition, CPromptingReSelectActivity::TContext)
       
   418 void CPromptingReSelectActivity::TJoinTierManager::DoL()
       
   419 	{
       
   420 	__ASSERT_DEBUG(iContext.iNodeActivity, User::Panic(KNetMCprPanic, KPanicNoActivity));
       
   421 	CPromptingReSelectActivity& ac = static_cast<CPromptingReSelectActivity&>(*iContext.iNodeActivity);
       
   422 	ac.iTierManager = message_cast<TCFFactory::TPeerFoundOrCreated>(iContext.iMessage).iNodeId;
       
   423     ASSERT(!ac.iTierManager.IsNull()); //Must always be valid.
       
   424     ac.PostRequestTo(ac.iTierManager, TCFPeer::TJoinRequest(iContext.NodeId(), TClientType(TCFClientType::ECtrl)).CRef());
       
   425 	}
       
   426 
       
   427 MeshMachine::CNodeActivityBase* CPromptingReSelectActivity::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   428     {
       
   429     return new (ELeave) CPromptingReSelectActivity(aActivitySig, aNode);
       
   430     }
       
   431 
       
   432 CPromptingReSelectActivity::CPromptingReSelectActivity(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
       
   433 :	MeshMachine::CNodeActivityBase(aActivitySig, aNode)
       
   434 	{
       
   435 	}
       
   436 
       
   437 CPromptingReSelectActivity::~CPromptingReSelectActivity()
       
   438 	{
       
   439 	if (!iTierManager.IsNull())
       
   440 		{
       
   441 		RClientInterface::OpenPostMessageClose(iNode.Id(), iTierManager, TEChild::TLeft().CRef());
       
   442 		iTierManager.SetNull();
       
   443 		}
       
   444 	}
       
   445 
       
   446 void CPromptingReSelectActivity::ParkReConnectRequestL(const TNodeContextBase& aContext)
       
   447 	{
       
   448 	User::LeaveIfError(StoreContext(aContext));
       
   449 	}
       
   450 
       
   451 void CPromptingReSelectActivity::ReDispatchReConnectRequestL(const TNodeContextBase& aContext)
       
   452 	{
       
   453 	TBuf8<__Align8(sizeof(TNodeContextBase))> ctxBuf;
       
   454 	TBuf8<__Align8(TSignalBase::KMaxInlineMessageSize + TSignalBase::KMaxUnstoredOverhead)> msgBuf;
       
   455 	TNodeCtxId dummy;
       
   456 	TNodeContextBase* storedContext = LoadContext(aContext.iNode, aContext.iNodeActivity, ctxBuf, msgBuf, dummy);
       
   457 
       
   458 	//We should never be here if parking of the original request failed!
       
   459 	__ASSERT_ALWAYS(storedContext, User::Panic(KNetMCprPanic, KPanicNoContext));
       
   460 	PostToOriginators(storedContext->iMessage);
       
   461 	iContextDesc.Zero();
       
   462 	}
       
   463 
       
   464 void CPromptingReSelectActivity::ReplyToOriginators(TEErrorRecovery::TErrorRecoveryResponse& aCFMessageSig)
       
   465 	{
       
   466 //TODO[PROD] - logging
       
   467    	//MESH_LOG_MESSAGE(KESockComponentTag, KESockMeshMachine, aCFMessageSig, this,_S8("CConnectionRecoveryActivity:\tPostToOriginators"));
       
   468 	for (TInt n = iOriginators.Count() - 1;n>=0; n--)
       
   469 		{
       
   470 		Messages::TNodePeerId& peerId = iOriginators[n];
       
   471 		//aCFMessageSig.SetActivity(peerId.iActivityId);
       
   472 		TCFSafeMessage::TResponseCarrierWest<TEErrorRecovery::TErrorRecoveryResponse> resp(aCFMessageSig, peerId.Peer().RecipientId());
       
   473 		PostToOriginator(peerId, resp);
       
   474 		}
       
   475 	}
       
   476 
       
   477