telephonyprotocols/pdplayer/src/PDPDeftSCPR.cpp
changeset 0 3553901f7fa8
child 21 2492a6e4aed7
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     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 // PDP SubConnection Provider implementation
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include <comms-infras/corescpractivities.h>
       
    24 #include "PDPDeftSCPR.h"
       
    25 #include "PDPSCPRStates.h"
       
    26 #include "PDPSCPRFactory.h"
       
    27 #include <comms-infras/ss_log.h>
       
    28 #include <comms-infras/commsdebugutility.h>
       
    29 #include <elements/nm_signatures.h>
       
    30 
       
    31 #if defined(__CFLOG_ACTIVE) || defined(SYMBIAN_TRACE_ENABLE)
       
    32 #define KPDPSCprTag KESockSubConnectionTag
       
    33 _LIT8(KPDPSCprSubTag, "pdpscpr");
       
    34 #endif
       
    35 
       
    36 using namespace Messages;
       
    37 using namespace MeshMachine;
       
    38 using namespace ESock;
       
    39 using namespace NetStateMachine;
       
    40 
       
    41 
       
    42 //-=========================================================
       
    43 //
       
    44 // Activities
       
    45 //
       
    46 //-=========================================================
       
    47 
       
    48 namespace PDPDeftSCprDataClientStartActivity
       
    49 {
       
    50 typedef MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingDataClientStarted> TAwaitingDataClientStartedOrError;
       
    51 
       
    52 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityStartDataClient, PDPDeftDataClientStart, TCFDataClient::TStart, PDPSCprStates::CStartActivity::NewL)
       
    53     FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, PDPSCprStates::TNoTagOrAlreadyStarted)
       
    54 	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KAlreadyStarted, PRStates::TSendDataClientStarted)
       
    55 
       
    56 	NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TCreatePrimaryPDPCtx, PDPSCprStates::TAwaitingPrimaryPDPCtxCreated, PDPSCprStates::TNoTagOrSendErrorRecoveryRequestOrError)
       
    57 	NODEACTIVITY_ENTRY(PDPSCprStates::KSendErrorRecoveryRequest, PDPSCprStates::TSendErrorRecoveryRequest, MeshMachine::TAwaitingErrorRecoveryResponseOrError, PDPSCprStates::TNoTagBackwardOrErrorTag)
       
    58  	THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TFillInGrantedParamsAndImsExtParams, MeshMachine::TNoTag)
       
    59     NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TOverrideProvisionAndStartDataClient, TAwaitingDataClientStartedOrError, MeshMachine::TNoTagOrErrorTag)
       
    60 	LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSendDataClientStarted)
       
    61 
       
    62 	// Cleanup if error occurred
       
    63     THROUGH_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TDoNothing, CoreNetStates::TNoTagOrNoDataClientsToStop)
       
    64     NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStopYourFlows, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag<CoreNetStates::KNoDataClientsToStop>)
       
    65     THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClientsToStop, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrProviderStopped)
       
    66     NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TDestroyPDPContext, PDPSCprStates::TAwaitingPDPContextDestroyed, MeshMachine::TTag<CoreNetStates::KProviderStopped>)
       
    67     THROUGH_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PRStates::TDestroyOrphanedDataClients, MeshMachine::TTag<CoreNetStates::KProviderStopped>)
       
    68     LAST_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, MeshMachine::TRaiseActivityError)
       
    69 NODEACTIVITY_END()
       
    70 }
       
    71 
       
    72 namespace PDPSCprNetworkStatusEventActivity
       
    73 {
       
    74 DECLARE_DEFINE_NODEACTIVITY(ECFActivityNotification, subConnStatusEvent, TPDPFSMMessages::TPDPFSMMessage)
       
    75 	FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingNetworkStatusEvent, PDPSCprStates::TNetworkStatusEventTypeTag)
       
    76 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
       
    77 
       
    78 	// Assume that anything other than EStatusUnattached means the network
       
    79 	// is still up, so just ignore this event.
       
    80 	LAST_NODEACTIVITY_ENTRY(RPacketService::EStatusAttached, MeshMachine::TDoNothing)
       
    81 	LAST_NODEACTIVITY_ENTRY(RPacketService::EStatusActive, MeshMachine::TDoNothing)
       
    82 	LAST_NODEACTIVITY_ENTRY(RPacketService::EStatusSuspended, MeshMachine::TDoNothing)
       
    83 
       
    84 	NODEACTIVITY_ENTRY(RPacketService::EStatusUnattached, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TNoTag)
       
    85 	LAST_NODEACTIVITY_ENTRY(KNoTag, SCprStates::TSendDataClientGoneDown)
       
    86 NODEACTIVITY_END()
       
    87 }
       
    88 
       
    89 namespace PDPDeftSCprGoneDownActivity
       
    90 {
       
    91 //TODO perhaps get this from a header file since its used in a number of places - see ss_subconn.cpp
       
    92 typedef MeshMachine::TAcceptErrorState<CoreNetStates::TAwaitingApplyResponse> TAwaitingApplyResponseOrError;
       
    93 
       
    94 //mandated by 3GPP TS 23.107 Annex C, the default going down needs to select a new default
       
    95 //among the non-defaults and swap the datapath. Swapping datapath is now done
       
    96 //transparently, i.e.: without the upper layer knowing (binders are kept, flows are swapped).
       
    97 //This arguably isn't pretty and could be changed to something more explicit, i.e.:
       
    98 //sending TBindToRequest to the upper layer SCPR so that it does an explit rebind.
       
    99 //[401TODO]: the swap only works for rawIp, doesn't for PPP.
       
   100 //[401TODO]: if we stick to the transpartent swap, we need to change the message
       
   101 //           this scpr sends to the flow. The flow responds with a full swap
       
   102 //           to TRejoin, whereas TRejoin doesn't mean swap - suggesting to
       
   103 //           introduce PDP level msg: TRejoinAndSwap.
       
   104 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityGoneDown, PDPDeftSCprGoneDown, TPDPFSMMessages::TPDPFSMMessage, PDPSCprStates::CPrimaryPDPGoneDownActivity::NewL)
       
   105 	FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingPDPContextGoneDown, MeshMachine::TActiveOrNoTag<ECFActivityStartDataClient>)
       
   106 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing, PDPSCprStates::CPrimaryPDPGoneDownActivity::TNoTagOrProviderStopped)
       
   107     THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TStoreOriginalDataClient, MeshMachine::TNoTag)
       
   108 	NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TRejoinDataClient, CoreNetStates::TAwaitingRejoinDataClientComplete, MeshMachine::TNoTag)
       
   109 	NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TApplyNewDefault, TAwaitingApplyResponseOrError, MeshMachine::TNoTag)
       
   110 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TSwitchToNewDefault, MeshMachine::TNoTag)
       
   111 	NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::CPrimaryPDPGoneDownActivity::TStopOriginalDataClient, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TNoTag)
       
   112 
       
   113 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TClearError)
       
   114 	THROUGH_NODEACTIVITY_ENTRY(KActiveTag, MeshMachine::TDoNothing, PDPSCprStates::TNoTagOrContentionTag)
       
   115 	//Awaiting for contention result, do not stop the start activity.
       
   116 	LAST_NODEACTIVITY_ENTRY(PDPSCprStates::KContentionTag, MeshMachine::TDoNothing)
       
   117 
       
   118 	LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TCancelDataClientStartInPDP)
       
   119 
       
   120     NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, CoreNetStates::TStopSelf, CoreNetStates::TAwaitingDataClientStopped, MeshMachine::TTag<CoreNetStates::KProviderStopped>)
       
   121     LAST_NODEACTIVITY_ENTRY(CoreNetStates::KProviderStopped, PDPSCprStates::TSendGoneDown)
       
   122 NODEACTIVITY_END()
       
   123 }
       
   124 
       
   125 namespace PDPDeftSCprClientLeaveActivity
       
   126 { //This activity will wait for ECFActivityBinderRequest to complete
       
   127 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityClientLeave, PDPDeftSCprClientLeave, TNodeSignal::TNullMessageId, MeshMachine::CNodeRetryActivity::NewL) //May be waiting for both messages
       
   128 	NODEACTIVITY_ENTRY(KNoTag, PRStates::TRemoveClientAndSendLeaveCompleteIfRequest, CoreStates::TAwaitingClientLeave, CoreNetStates::TNoTagBlockedByBindToAndNoClients)
       
   129 	LAST_NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TSendDataClientIdleIfNoSubconnsAndNoClients)
       
   130 NODEACTIVITY_END()
       
   131 }
       
   132 
       
   133 namespace PDPDeftSCprIoctlActivity
       
   134 {
       
   135 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityIoctl, PDPDeftSCprIoctl, TNodeSignal::TNullMessageId, MeshMachine::CNodeParallelMessageStoreActivityBase::NewL)
       
   136     FIRST_NODEACTIVITY_ENTRY(PDPSCprStates::TAwaitingIoctlMessage, MeshMachine::TNoTag)
       
   137     NODEACTIVITY_ENTRY(KNoTag, PDPSCprStates::TRetrieveSipAddr, CoreNetStates::TAwaitingRMessage2Processed, MeshMachine::TNoTag)
       
   138     LAST_NODEACTIVITY_ENTRY(KNoTag, CoreStates::TPostToOriginators)
       
   139 NODEACTIVITY_END()
       
   140 }
       
   141 
       
   142 namespace PDPDefSCprActivities
       
   143 {
       
   144 DECLARE_DEFINE_ACTIVITY_MAP(activityMap)
       
   145 	ACTIVITY_MAP_ENTRY(PDPDeftSCprDataClientStartActivity, PDPDeftDataClientStart)
       
   146 	ACTIVITY_MAP_ENTRY(PDPSCprNetworkStatusEventActivity, subConnStatusEvent)
       
   147 	ACTIVITY_MAP_ENTRY(PDPDeftSCprGoneDownActivity, PDPDeftSCprGoneDown)
       
   148     ACTIVITY_MAP_ENTRY(PDPDeftSCprClientLeaveActivity, PDPDeftSCprClientLeave)
       
   149     ACTIVITY_MAP_ENTRY(PDPDeftSCprIoctlActivity, PDPDeftSCprIoctl)
       
   150 ACTIVITY_MAP_END_BASE(PDPSCprActivities, activityMap)
       
   151 }
       
   152 
       
   153 //-=========================================================
       
   154 //
       
   155 // CPDPDefaultSubConnectionProvider methods
       
   156 //
       
   157 //-=========================================================
       
   158 
       
   159 CPDPDefaultSubConnectionProvider::CPDPDefaultSubConnectionProvider(ESock::CSubConnectionProviderFactoryBase& aFactory)
       
   160 	: CPDPSubConnectionProvider(aFactory, PDPDefSCprActivities::activityMap::Self())
       
   161     {
       
   162     LOG_NODE_CREATE1(KPDPSCprSubTag, CPDPDefaultSubConnectionProvider, " [factory=%08x]", &aFactory)
       
   163     __FLOG_OPEN(KCFNodeTag, KPDPSCprSubTag);
       
   164     }
       
   165 
       
   166 CPDPDefaultSubConnectionProvider::~CPDPDefaultSubConnectionProvider()
       
   167     {
       
   168 	LOG_NODE_DESTROY(KPDPSCprSubTag, CPDPDefaultSubConnectionProvider)
       
   169     __FLOG_CLOSE;
       
   170     }
       
   171 
       
   172 CPDPDefaultSubConnectionProvider* CPDPDefaultSubConnectionProvider::NewL(CPDPSubConnectionProviderFactory& aFactory)
       
   173 /**
       
   174 Construct a new PDP SubConnection Provider Object
       
   175 
       
   176 @params aFactory factory that create this object
       
   177 @param aConnProvider Connection Provider associated with this object
       
   178 */
       
   179 	{
       
   180 	CPDPDefaultSubConnectionProvider* ptr = new (ELeave) CPDPDefaultSubConnectionProvider(aFactory);
       
   181     CleanupStack::PushL(ptr);
       
   182     ptr->ConstructL();
       
   183     CleanupStack::Pop();
       
   184 	return ptr;
       
   185 	}
       
   186 
       
   187 void CPDPDefaultSubConnectionProvider::ConstructL()
       
   188     {
       
   189     CPDPSubConnectionProvider::ConstructL();
       
   190     iPdpFsmInterface = new (ELeave) CPdpFsmInterface(*this);
       
   191     }
       
   192 
       
   193 void CPDPDefaultSubConnectionProvider::PdpFsmAllContextEvent(TInt aNotification, TInt /*aParam*/)
       
   194     {
       
   195     if (aNotification == KNetworkStatusEvent)
       
   196         {
       
   197         TPDPFSMMessages::TPDPFSMMessage statusMsg(KNetworkStatusEvent, KErrNone);
       
   198         TRAP_IGNORE(ReceivedL(TNodeId(Id()), TNodeCtxId(0, Id()), statusMsg)); //TODO - use trap assert?
       
   199         }
       
   200     }
       
   201 
       
   202 void CPDPDefaultSubConnectionProvider::LinkUp()
       
   203     {
       
   204     if (iLinkUps++ == 0)
       
   205         {
       
   206 		TCFMessage::TStateChange msg(Elements::TStateChange(KLinkLayerOpen, KErrNone));
       
   207 		//Forward to control clients if there are any
       
   208 		TInt ctrlClientCount = PostToClients<TDefaultClientMatchPolicy>(Id(), msg, TClientType(TCFClientType::ECtrl));
       
   209 		if (0==ctrlClientCount)
       
   210 			{ //If there are no control clients any more, forward to the control provider
       
   211 			PostToClients<TDefaultClientMatchPolicy>(Id(), msg, TClientType(TCFClientType::ECtrlProvider));
       
   212 			}
       
   213         }
       
   214     }
       
   215 
       
   216 void CPDPDefaultSubConnectionProvider::LinkDown(TInt aCause)
       
   217     {
       
   218     if (++iLinkDowns-iLinkUps == 0 || iLinkUps == 0)
       
   219         {
       
   220         ControlProvider()->PostMessage(Id(),
       
   221             TCFMessage::TStateChange(Elements::TStateChange(KLinkLayerClosed, aCause)).CRef());
       
   222         }
       
   223 	SendDataClientIdleIfNoSubconnsAndNoClientsL();
       
   224     }
       
   225 
       
   226 void CPDPDefaultSubConnectionProvider::SendDataClientIdleIfNoSubconnsAndNoClientsL()
       
   227 	{
       
   228 	// linkDowns is called more places than linkup, so it may in fact be higher, would be nice if something was
       
   229 	// done in the future to make iLinkDowns and iLinkUps are symettrical
       
   230 	if (iLinkDowns-iLinkUps >= 0 || iLinkUps == 0)
       
   231 		{
       
   232 		if (GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl|TCFClientType::EAux))==NULL
       
   233 			&& GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, TCFClientType::EActive)) == NULL)
       
   234 			{
       
   235 			RNodeInterface* cp = ControlProvider();
       
   236 			if (cp)
       
   237 				{ //If there is no Control Provider we probably are an MCPR/Tier Manager/etc
       
   238 				cp->PostMessage(Id(), TCFControlProvider::TIdle().CRef());
       
   239 				}
       
   240 			return;
       
   241 			}
       
   242 
       
   243 		RNodeInterface* cc = GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::ECtrl));
       
   244 		if (cc==NULL)
       
   245 			{
       
   246 			TClientIter<TDefaultClientMatchPolicy> dciter = GetClientIter<TDefaultClientMatchPolicy>(
       
   247 				TClientType(
       
   248 					TCFClientType::EData,
       
   249 						TCFClientType::EActive
       
   250 						|TCFClientType::EActivating
       
   251 						|TCFClientType::EStarted
       
   252 						|TCFClientType::EStarting
       
   253 						|TCFClientType::ELeaving
       
   254 					)
       
   255 				);
       
   256 
       
   257 			TInt i = 0;
       
   258 			RNodeInterface* dc;
       
   259 			while ((dc = dciter[i++]) != NULL)
       
   260 				{
       
   261 				dc->PostMessage(Id(), TCFControlProvider::TIdle().CRef());
       
   262 				}
       
   263 			}
       
   264 		}
       
   265 	}