networkcontrol/iptransportlayer/src/ipdeftbasescpr.cpp
changeset 0 af10295192d8
child 25 d15a50675083
child 52 3652a10b304a
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 // IP Default Base SubConnection Provider implementation
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #define SYMBIAN_NETWORKING_UPS
       
    24 
       
    25 #include "IPMessages.h"
       
    26 
       
    27 #include <comms-infras/corescpractivities.h>
       
    28 #include <comms-infras/ss_corepractivities.h>
       
    29 #include <comms-infras/ss_nodemessages_rejoiningprovider.h>
       
    30 #include <comms-infras/ss_nodemessages_dataclient.h>
       
    31 #include "ipdeftbasescpr.h"
       
    32 #include <comms-infras/ss_log.h>
       
    33 #include <comms-infras/ss_platsec_apiext.h>
       
    34 #include <networking/qos3gpp_subconparams.h>
       
    35 
       
    36 #include <comms-infras/ss_msgintercept.h>
       
    37 #ifdef SYMBIAN_NETWORKING_UPS
       
    38 #include <comms-infras/upspractivities.h>
       
    39 #endif
       
    40 
       
    41 #ifdef SYMBIAN_TRACE_ENABLE
       
    42 	#define KIPDeftSCprTag KESockSubConnectionTag
       
    43 #endif // SYMBIAN_TRACE_ENABLE
       
    44 
       
    45 
       
    46 using namespace Messages;
       
    47 using namespace MeshMachine;
       
    48 using namespace ESock;
       
    49 using namespace IPDeftSCprBaseActivities;
       
    50 using namespace PRActivities;
       
    51 using namespace CoreNetStates;
       
    52 
       
    53 //We reserve space for two preallocated activities that may start concurrently on the default base SCPR
       
    54 //node: destroy and data client stop.
       
    55 static const TUint KDefaultMaxPreallocatedActivityCount = 2;
       
    56 static const TUint KMaxPreallocatedActivitySize = sizeof(MeshMachine::CNodeRetryParallelActivity) + sizeof(MeshMachine::APreallocatedOriginators<4>);
       
    57 static const TUint KIPDeftBaseSCPRPreallocatedActivityBufferSize = KDefaultMaxPreallocatedActivityCount * KMaxPreallocatedActivitySize;
       
    58 
       
    59 //-=========================================================
       
    60 //
       
    61 // States
       
    62 //
       
    63 //-=========================================================
       
    64 namespace IPBaseSCprStates
       
    65 {
       
    66 DEFINE_SMELEMENT(TAwaitingAddressUpdate, NetStateMachine::MState, IPBaseSCprStates::TContext)
       
    67 TBool TAwaitingAddressUpdate::Accept()
       
    68 	{
       
    69 	return iContext.iMessage.IsMessage<TCFIPMessage::TDataClientRouted>();
       
    70 	}
       
    71 
       
    72 DEFINE_SMELEMENT(TStoreAddressUpdate, NetStateMachine::MStateTransition, IPBaseSCprStates::TContext)
       
    73 void TStoreAddressUpdate::DoL()
       
    74 	{
       
    75     RIPDataClientNodeInterface* client = static_cast<RIPDataClientNodeInterface*>(iContext.iPeer);
       
    76     if (NULL == client)
       
    77         {
       
    78         User::Leave(KErrNotFound);
       
    79         }
       
    80 
       
    81     TCFIPMessage::TDataClientRouted& addressUpdateMsg = message_cast<TCFIPMessage::TDataClientRouted>(iContext.iMessage);
       
    82     client->iCliDstAddr = addressUpdateMsg.iAddrUpdate.iDestSockAddr;
       
    83     client->iCliSrcAddr = addressUpdateMsg.iAddrUpdate.iSrcSockAddr;
       
    84     client->iProtocolId = addressUpdateMsg.iAddrUpdate.iProtocolId;
       
    85     if (iContext.Node().iIapId == CIpSubConnectionProviderBase::KInvalidIapId)
       
    86         {
       
    87         iContext.Node().iIapId = addressUpdateMsg.iAddrUpdate.iIapId;
       
    88         }
       
    89 	}
       
    90 
       
    91 DEFINE_SMELEMENT(TRejoinDataClient, NetStateMachine::MStateTransition, IPBaseSCprStates::TContext)
       
    92 void TRejoinDataClient::DoL()
       
    93 	{
       
    94     PRActivities::CRejoinDataClientActivity::TRejoinDataClient sendRejoinReq(iContext);
       
    95     sendRejoinReq.DoL();
       
    96 	ASSERT(iContext.iNodeActivity);
       
    97 	PRActivities::CRejoinDataClientActivity* rejoinActivity =
       
    98 	    static_cast<PRActivities::CRejoinDataClientActivity*>(iContext.iNodeActivity);
       
    99     RIPDataClientNodeInterface& dc =
       
   100         static_cast<RIPDataClientNodeInterface&>(
       
   101         rejoinActivity->iDataClients[rejoinActivity->iDataClients.Count()-1].iDataClient);
       
   102     TNodeId& newOwner = rejoinActivity->iDataClients[rejoinActivity->iDataClients.Count()-1].iNewOwner;
       
   103 
       
   104 	RClientInterface::OpenPostMessageClose(dc.RecipientId(), newOwner,
       
   105 		TCFIPMessage::TDataClientRouted(TAddrUpdate(dc.iCliSrcAddr, dc.iCliDstAddr, dc.iProtocolId, iContext.Node().iIapId)).CRef());
       
   106 	}
       
   107 	
       
   108 
       
   109 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   110 /*
       
   111 State waiting for TTransportNotification message which carries TCP Receive window.
       
   112 */
       
   113 DEFINE_SMELEMENT(TAwaitingTransportNotification, NetStateMachine::MState, IPBaseSCprStates::TContext)
       
   114 TBool IPBaseSCprStates::TAwaitingTransportNotification::Accept()
       
   115 	{
       
   116 	return iContext.iMessage.IsMessage<TCFMessage::TTransportNotification>();
       
   117 	}
       
   118 /*
       
   119 StateTransition which will iterate thru all the data clients, send the TCP receive window size to them.
       
   120 */
       
   121 DEFINE_SMELEMENT(TSendTransportNotificationToDataClients, NetStateMachine::MStateTransition,IPBaseSCprStates::TContext)
       
   122 void IPBaseSCprStates::TSendTransportNotificationToDataClients::DoL()
       
   123 	{
       
   124 	
       
   125 	//data client iterator.
       
   126 	//Exclude data clients that are ELeaving otherwise the PostMessage() below will panic.
       
   127 	TClientIter<TDefaultClientMatchPolicy> iter = iContext.Node().GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData), TClientType(0, TCFClientType::ELeaving));
       
   128    	//Data Client number
       
   129    	TInt dataCliNum =NULL;
       
   130   	//Send message to all data clients.
       
   131    	RNodeInterface* dataClient = iter[dataCliNum];
       
   132    	
       
   133    	TCFMessage::TTransportNotification message;
       
   134   	while (dataClient)
       
   135    		{
       
   136 		//Post messages to the data client. Message will flow to all the data clients i.e. socket flows.
       
   137  		dataClient->PostMessage(iContext.NodeId(), message);
       
   138  		dataCliNum++;
       
   139  		dataClient = iter[dataCliNum];
       
   140    		}
       
   141 	}
       
   142 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   143 
       
   144 }
       
   145 
       
   146 
       
   147 //-=========================================================
       
   148 //
       
   149 // Activities
       
   150 //
       
   151 //-=========================================================
       
   152 
       
   153 namespace IPDeftBaseSCprAddressUpdate
       
   154 {
       
   155 DECLARE_DEFINE_NODEACTIVITY(ECFActivityAddressUpdate, IPDeftBaseSCprAddressUpdate, TCFIPMessage::TDataClientRouted)
       
   156 	NODEACTIVITY_ENTRY(KNoTag, IPBaseSCprStates::TStoreAddressUpdate, IPBaseSCprStates::TAwaitingAddressUpdate, MeshMachine::TNoTag)
       
   157 NODEACTIVITY_END()
       
   158 }
       
   159 
       
   160 namespace IPDeftSCprRejoinDataClient
       
   161 {
       
   162 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityRejoin, IPDeftSCprRejoin, TCFRejoiningProvider::TRejoinDataClientRequest, PRActivities::CRejoinDataClientActivity::NewL)
       
   163 	// If an SCprNoBearer is being processed (e.g. RSocket::Connect()) when IPDeftSCprRejoin is started (RSubConnection::AddSocket()),
       
   164 	// park until the SCprNoBearer completes.  This ensures that the EStarting flag (set temporarily during SCprNoBearer)
       
   165 	// is not inadvertantly propagated (via the DataClientJoiningRequest message) to the receiving SCpr.  If this happens,
       
   166 	// EStarting will never get reset on the receiving SCpr and can cause activities (like PRDataClientStop) to park
       
   167 	// permanently on that SCpr.
       
   168 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientRejoin, CoreNetStates::TNoTagBlockedByNoBearer)
       
   169 	NODEACTIVITY_ENTRY(KNoTag,               IPBaseSCprStates::TRejoinDataClient, PRActivities::CRejoinDataClientActivity::TAwaitingJoinComplete, MeshMachine::TNoTag)
       
   170 	NODEACTIVITY_ENTRY(CoreStates::KLoopTag, IPBaseSCprStates::TRejoinDataClient, PRActivities::CRejoinDataClientActivity::TAwaitingJoinComplete, MeshMachine::TNoTag)
       
   171 
       
   172 	NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::TSendRejoinComplete, CoreNetStates::TAwaitingDataClientRejoinOrApplyOrCancel, PRActivities::CRejoinDataClientActivity::TRejoinLoopTag)
       
   173 	NODEACTIVITY_ENTRY(KNoTag, PRActivities::CRejoinDataClientActivity::TApplyRejoin, CoreNetStates::TAwaitingApplyResponse, MeshMachine::TNoTag)
       
   174 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   175 	LAST_NODEACTIVITY_ENTRY(KNoTag, PRStates::TSendApplyResponse)
       
   176 #else
       
   177 	LAST_NODEACTIVITY_ENTRY(KNoTag, SCprStates::TSendApplyResponse)
       
   178 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   179 NODEACTIVITY_END()
       
   180 }
       
   181 
       
   182 namespace IPDeftBaseSCprBinderRequestActivity
       
   183 {
       
   184 DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityBinderRequest, IPDeftBaseSCprBinderRequest, TCFServiceProvider::TCommsBinderRequest, CCommsBinderActivity::NewL)
       
   185 	FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingBinderRequest, TNoTagOrUseExistingOrPermissionDenied)
       
   186 
       
   187 	NODEACTIVITY_ENTRY(KNoTag, PRStates::TCreateDataClient, CoreNetStates::TAwaitingDataClientJoin, MeshMachine::TNoTag)
       
   188 
       
   189 	// Below this point we need to modify the error handling approach. If we're getting a TError on TBinderResponse,
       
   190 	// this means the client requesting the binder couldn't bind to it. As far as the client is concerned, this
       
   191 	// activity is finished (it has flagged an error). The standard error handling will result in erroring
       
   192 	// the originator. In this case we shouoldn't error the originator, instead, wrap up quietly.
       
   193 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, CCommsBinderActivity::TProcessDataClientCreation, MeshMachine::TTag<CoreStates::KUseExisting>)
       
   194 
       
   195 	NODEACTIVITY_ENTRY(CoreStates::KUseExisting, CCommsBinderActivity::TSendBinderResponse, CCommsBinderActivity::TAwaitingBindToComplete, MeshMachine::TNoTagOrErrorTag)
       
   196 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
       
   197 	LAST_NODEACTIVITY_ENTRY(KErrorTag, MeshMachine::TClearError)
       
   198 	LAST_NODEACTIVITY_ENTRY(KPermissionDenied, MeshMachine::TRaiseAndClearActivityError)
       
   199 NODEACTIVITY_END()
       
   200 }
       
   201 
       
   202 namespace IPDeftBaseSCprBinderRequestActivity
       
   203 {
       
   204 const TUint32 KSIPSecureId  = 270490934;
       
   205 const TUint32 KDHCPSecureId = 270522821;
       
   206 const TUint32 KDNSSecureId  = 268437634;
       
   207 
       
   208 DEFINE_SMELEMENT(TNoTagOrUseExistingOrPermissionDenied, NetStateMachine::MStateFork, TContext)
       
   209 TInt TNoTagOrUseExistingOrPermissionDenied::TransitionTag()
       
   210 	{
       
   211 	ASSERT(iContext.iNodeActivity);
       
   212 
       
   213 	// have to cast the context sicne we're inheriting
       
   214 	NetStateMachine::TContextAccessor<IPDeftBaseSCprBinderRequestActivity::TContext,CCommsBinderActivity::TContext> ctxAccessor(iContext);
       
   215 
       
   216 	if (ctxAccessor.Context().Node().ImsFlag())
       
   217 		{
       
   218 		TSecureId secureId = 0;
       
   219 		MPlatsecApiExt* extn = NULL;
       
   220 		TRAPD(err, extn = reinterpret_cast<MPlatsecApiExt*>(address_cast<TNodeId>(iContext.iSender).Node().FetchNodeInterfaceL(MPlatsecApiExt::KInterfaceId)));
       
   221 		if (err == KErrNone || extn != NULL)
       
   222 			{
       
   223 			if ((extn->SecureId(secureId) != KErrNone) ||
       
   224 				(secureId.iId != KSIPSecureId && secureId.iId != KDHCPSecureId && secureId.iId != KDNSSecureId))
       
   225 				{
       
   226 				iContext.iNodeActivity->SetError(KErrPermissionDenied);
       
   227 				return KPermissionDenied;
       
   228 				}
       
   229 			}
       
   230 		}
       
   231 
       
   232 	return PRActivities::CCommsBinderActivity::TNoTagOrUseExisting::TransitionTag();
       
   233 	}
       
   234 }
       
   235 
       
   236 namespace IPDeftBaseSCprDataClientStartActivity
       
   237 {
       
   238 DEFINE_SMELEMENT(TGetParams, NetStateMachine::MStateTransition, TContext)
       
   239 void TGetParams::DoL()
       
   240 	{
       
   241 	ASSERT(iContext.iNodeActivity);
       
   242 	if(iContext.Node().ServiceProvider() == NULL)
       
   243     	{
       
   244     	//The service provider could have dissapeared by now.
       
   245     	User::Leave(KErrDied);
       
   246     	}
       
   247 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   248 	iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(),
       
   249 		TCFScpr::TGetParamsRequest(RCFParameterFamilyBundleC()).CRef());
       
   250 #else
       
   251  	iContext.iNodeActivity->PostRequestTo(*iContext.Node().ServiceProvider(),
       
   252 		TCFScpr::TParamsRequest(RCFParameterFamilyBundleC()).CRef());
       
   253 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   254 	}
       
   255 }
       
   256 
       
   257 
       
   258 namespace IPDeftBaseSCprDataClientStartActivity
       
   259 {
       
   260 DECLARE_DEFINE_NODEACTIVITY(ECFActivityStartDataClient, IPDeftBaseSCprDataClientStart, TCFDataClient::TStart )
       
   261     FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientStart, MeshMachine::TNoTag)
       
   262 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   263 	NODEACTIVITY_ENTRY(KNoTag, IPDeftBaseSCprDataClientStartActivity::TGetParams, CoreNetStates::TAwaitingParamResponse, CoreNetStates::TNoTagOrNoDataClients)
       
   264 #else
       
   265 	NODEACTIVITY_ENTRY(KNoTag, IPDeftBaseSCprDataClientStartActivity::TGetParams, CoreNetStates::TAwaitingParamResponse, MeshMachine::TNoTag)
       
   266 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, SCprStates::TStoreParams, CoreNetStates::TNoTagOrNoDataClients)
       
   267 #endif // SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW	
       
   268 	NODEACTIVITY_ENTRY(KNoTag, PRStates::TStartDataClients, CoreNetStates::TAwaitingDataClientsStarted, MeshMachine::TTag<CoreNetStates::KNoDataClients>)
       
   269 	LAST_NODEACTIVITY_ENTRY(CoreNetStates::KNoDataClients, PRStates::TSendDataClientStarted)
       
   270 NODEACTIVITY_END()
       
   271 }
       
   272 
       
   273 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   274 
       
   275 /*
       
   276 Custom activity which waits for TTransportNotification message from IPCPR.
       
   277 Stores the TCP receive window size in pointer appended to TProvisionConfig
       
   278 and sends the window to all data clients.
       
   279 */
       
   280 namespace IPDeftBaseSCPRBearerCharActivity
       
   281 {
       
   282 DECLARE_DEFINE_NODEACTIVITY(IPDeftSCprBaseActivities::ECFActivityReceiveWin, IPDeftBaseSCPRBearerCharActivity, TCFMessage::TTransportNotification)
       
   283 	FIRST_NODEACTIVITY_ENTRY(IPBaseSCprStates::TAwaitingTransportNotification, MeshMachine::TNoTag)
       
   284 	THROUGH_NODEACTIVITY_ENTRY(KNoTag, IPBaseSCprStates::TSendTransportNotificationToDataClients, MeshMachine::TNoTag)
       
   285 	LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
       
   286 NODEACTIVITY_END()
       
   287 }
       
   288 
       
   289 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   290 
       
   291 namespace IPDeftSCprBaseActivities
       
   292 {
       
   293 DEFINE_ACTIVITY_MAP(ipscprbaseActivityMap)
       
   294 	ACTIVITY_MAP_ENTRY(IPDeftSCprRejoinDataClient, IPDeftSCprRejoin)
       
   295 
       
   296 #ifdef SYMBIAN_NETWORKING_UPS
       
   297 ACTIVITY_MAP_END_BASE(UpsActivities, upsActivitiesSCpr)
       
   298 #else
       
   299 ACTIVITY_MAP_END_BASE(SCprActivities, coreSCprActivities)
       
   300 #endif
       
   301 }
       
   302 
       
   303 
       
   304 namespace IPDeftBaseSCprActivities
       
   305 {
       
   306 DEFINE_ACTIVITY_MAP(ipdeftbasescprActivityMap)
       
   307 	ACTIVITY_MAP_ENTRY(IPDeftBaseSCprAddressUpdate, IPDeftBaseSCprAddressUpdate)
       
   308 	ACTIVITY_MAP_ENTRY(IPDeftBaseSCprDataClientStartActivity, IPDeftBaseSCprDataClientStart)
       
   309 	
       
   310 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   311 	ACTIVITY_MAP_ENTRY(IPDeftBaseSCPRBearerCharActivity, IPDeftBaseSCPRBearerCharActivity)
       
   312 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   313 	
       
   314 	ACTIVITY_MAP_ENTRY(IPDeftBaseSCprBinderRequestActivity, IPDeftBaseSCprBinderRequest)
       
   315 ACTIVITY_MAP_END_BASE(IPDeftSCprBaseActivities, ipscprbaseActivityMap)
       
   316 }
       
   317 
       
   318 
       
   319 //-=========================================================
       
   320 //
       
   321 // CIpSubConnectionProviderBase methods
       
   322 //
       
   323 //-=========================================================
       
   324 CIpSubConnectionProviderBase::CIpSubConnectionProviderBase(ESock::CSubConnectionProviderFactoryBase& aFactory,
       
   325                              const MeshMachine::TNodeActivityMap& aActivityMap)
       
   326 :CCoreSubConnectionProvider(aFactory, aActivityMap),
       
   327  iIapId(KInvalidIapId)
       
   328     {
       
   329     }
       
   330 
       
   331 RNodeInterface* CIpSubConnectionProviderBase::NewClientInterfaceL(const TClientType& aClientType, TAny* aClientInfo)
       
   332     {
       
   333     if (aClientType.Type() & TCFClientType::EData)
       
   334         {
       
   335         return new (ELeave) RIPDataClientNodeInterface();
       
   336         }
       
   337     return CCoreSubConnectionProvider::NewClientInterfaceL(aClientType, aClientInfo);
       
   338     }
       
   339 
       
   340 
       
   341 //-=========================================================
       
   342 //
       
   343 // CIpDefaultBaseSubConnectionProvider methods
       
   344 //
       
   345 //-=========================================================
       
   346 CIpDefaultBaseSubConnectionProvider::~CIpDefaultBaseSubConnectionProvider()
       
   347     {
       
   348     LOG_NODE_DESTROY(KIPDeftSCprTag, CIpDefaultBaseSubConnectionProvider);
       
   349     }
       
   350 
       
   351 CIpDefaultBaseSubConnectionProvider::CIpDefaultBaseSubConnectionProvider(ESock::CSubConnectionProviderFactoryBase& aFactory,
       
   352                              const MeshMachine::TNodeActivityMap& aActivityMap)
       
   353     : CIpSubConnectionProviderBase(aFactory, aActivityMap)
       
   354     {
       
   355     LOG_NODE_CREATE(KIPDeftSCprTag, CIpDefaultBaseSubConnectionProvider);
       
   356     }
       
   357 
       
   358 CIpDefaultBaseSubConnectionProvider* CIpDefaultBaseSubConnectionProvider::NewL(ESock::CSubConnectionProviderFactoryBase& aFactory)
       
   359     {
       
   360     CIpDefaultBaseSubConnectionProvider* provider = new (ELeave) CIpDefaultBaseSubConnectionProvider(aFactory, IPDeftBaseSCprActivities::ipdeftbasescprActivityMap::Self());
       
   361     CleanupStack::PushL(provider);
       
   362     provider->ConstructL(KIPDeftBaseSCPRPreallocatedActivityBufferSize);
       
   363 
       
   364     CleanupStack::Pop(provider);
       
   365     return provider;
       
   366     }
       
   367 
       
   368 void CIpDefaultBaseSubConnectionProvider::ReceivedL(const TRuntimeCtxId& aSender, const TNodeId& aRecipient, TSignatureBase& aMessage)
       
   369 	{
       
   370    	TNodeContext<CIpDefaultBaseSubConnectionProvider> ctx(*this, aMessage, aSender, aRecipient);
       
   371 	ESOCK_DEBUG_MESSAGE_INTERCEPT(aSender, aMessage, aRecipient);
       
   372 	CCoreSubConnectionProvider::ReceivedL(aSender, aRecipient, aMessage);
       
   373 	User::LeaveIfError(ctx.iReturn);
       
   374 	}
       
   375 
       
   376 TBool CIpDefaultBaseSubConnectionProvider::ImsFlag()
       
   377 	{
       
   378 	TBool imsFlagSet = EFalse;
       
   379 	if ( iParameterBundle.IsNull() )
       
   380 		{
       
   381 		return imsFlagSet;
       
   382 		}
       
   383 
       
   384 	RParameterFamily family=iParameterBundle.FindFamily(KSubConnContextDescrParamsFamily);
       
   385 	if( ! family.IsNull())
       
   386 		{
       
   387 		CSubConImsExtParamSet* imsExtGranted = static_cast<CSubConImsExtParamSet*>(
       
   388 			family.FindParameterSet(STypeId::CreateSTypeId(KSubCon3GPPExtParamsFactoryUid,KSubConImsExtParamsType),
       
   389 									 RParameterFamily::EGranted));
       
   390 
       
   391 		if (imsExtGranted)
       
   392 			imsFlagSet = imsExtGranted->GetImsSignallingIndicator();
       
   393 		}
       
   394 
       
   395 	return imsFlagSet;
       
   396 	}
       
   397