networkcontrol/ipcprshim/src/shimcpr.cpp
branchRCL_3
changeset 58 8d540f55e491
parent 57 abbed5a4b42a
child 59 e36178c55292
child 63 425d8f4f7fa5
equal deleted inserted replaced
57:abbed5a4b42a 58:8d540f55e491
     1 // Copyright (c) 2005-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 //
       
    15 
       
    16 #include <comms-infras/nifif.h>
       
    17 #include <esockmessages.h>
       
    18 #include <nifman.h>
       
    19 #include "shimcpr.h"
       
    20 #include "shimconnsettings.h"
       
    21 #include "es_prot.h"
       
    22 #include "shimnifmansconn.h"
       
    23 #include "ss_glob.h"
       
    24 #include "connectionSelectorShim.h"
       
    25 
       
    26 using namespace ESock;
       
    27 
       
    28 //PREQ399_REMOVE
       
    29 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
    30 #include <networking/umtsgprs_subconnprovfactory.h>
       
    31 #endif
       
    32 //SYMBIAN_NETWORKING_3GPPDEFAULTQOS //PREQ399_REMOVE
       
    33 
       
    34 
       
    35 CConnectionProviderShim* CConnectionProviderShim::NewL(CConnectionProviderFactoryBase& aFactory)
       
    36 	{
       
    37 	CConnectionProviderShim* self = new (ELeave) CConnectionProviderShim(aFactory);
       
    38 	CleanupStack::PushL(self);
       
    39 	self->ConstructL();
       
    40 	CleanupStack::Pop(self);
       
    41 	return self;
       
    42 	}
       
    43 
       
    44 void CConnectionProviderShim::ConstructL()
       
    45 	{
       
    46 	__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tConstructL"), this));
       
    47 	// Do nothing, atleast for now;	
       
    48 	}
       
    49 
       
    50 CConnectionProviderShim::~CConnectionProviderShim()
       
    51 	{
       
    52 	delete iConnectionSettings;
       
    53 	
       
    54 	// As soon as the provider has a valid iProvider pointer the ownership has passed to this provider
       
    55    	delete iProvider;
       
    56 
       
    57 	iSelectors.Close();
       
    58 	iConnections.Close();
       
    59 	iNifManSubConnections.Close();
       
    60 	__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\t~CConnectionProviderShim"), this));
       
    61 	}
       
    62 	
       
    63 void CConnectionProviderShim::AddRefL(CConnectionSelectorShim* aSelector)
       
    64 	{
       
    65 	TInt index = iSelectors.Find(aSelector);
       
    66 	if (-1 == index)
       
    67 		{
       
    68 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tAddRef(aSelector %x) adding selector"), this, aSelector));	
       
    69 		iSelectors.AppendL(aSelector);
       
    70 		}
       
    71 	else
       
    72 		{
       
    73 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tAddRef(aSelector %x) selector already known"), this, aSelector));	
       
    74 		}
       
    75 	}
       
    76 	
       
    77 
       
    78 void CConnectionProviderShim::ReleaseRef(CConnectionSelectorShim* aSelector)
       
    79 	{	
       
    80 	TInt index = iSelectors.Find(aSelector);
       
    81 	if (-1 != index)
       
    82 		{		
       
    83 		iSelectors[index]->SetProviderNull();
       
    84 		iSelectors.Remove(index);
       
    85 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tReleaseRef(aSelector %x) removng selector"), this, aSelector));
       
    86 		}
       
    87 	else
       
    88 		{
       
    89 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tReleaseRef(aSelector %x) selector not known"), this, aSelector));
       
    90 		}
       
    91 	
       
    92 	if (ShouldIDeleteNow())
       
    93 		{
       
    94 		DeleteMeNow();
       
    95 		}
       
    96 	}
       
    97 	
       
    98 // CConnectionProviderBase virtuals
       
    99 TBool CConnectionProviderShim::ShouldIDeleteNow()
       
   100 	{		
       
   101 	TInt selectors = iSelectors.Count();
       
   102 	if (0 == selectors && !iHasAnyControlClientJoined)
       
   103 		{
       
   104 		return ETrue;
       
   105 		}
       
   106 		
       
   107 	return EFalse;	
       
   108 	}
       
   109 
       
   110 void CConnectionProviderShim::DoStartL(Meta::SMetaData& aParams, const RMessagePtr2* aMessage)
       
   111 	{
       
   112 #ifdef _DEBUG
       
   113 	Meta::STypeId tid = aParams.GetTypeId();
       
   114 	ASSERT( tid.iUid == TUid::Uid( KESockMessagesImplementationUid ) && tid.iType == EESockMessageConnStart);
       
   115 #endif
       
   116 	
       
   117 	CConnStart& p = static_cast<CConnStart&>(aParams);
       
   118 	if ( p.ConnPrefs() )
       
   119 		{
       
   120 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tDoStartL() with prefs"), this));
       
   121 		iProvider->StartL(p.StartType(), *p.ConnPrefs(), aMessage);
       
   122 		}
       
   123 	else
       
   124 		{
       
   125 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tDoStartL() without prefs"), this));
       
   126 		iProvider->StartL(p.StartType(), aMessage);
       
   127 		}
       
   128 	}
       
   129    
       
   130 void CConnectionProviderShim::DoDataClientJoiningL(MConnectionDataClient& aDataClient)
       
   131 	{
       
   132 	(void)aDataClient;
       
   133 	__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tDoDataClientJoiningL(aDataClient %x) [iDataClients.Count()=%d]"), this, &aDataClient, iDataClients.Count()));
       
   134 	}
       
   135 	
       
   136 void CConnectionProviderShim::DoDataClientLeaving(MConnectionDataClient& aDataClient)
       
   137 	{
       
   138 	(void)aDataClient;
       
   139 	__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tDoDataClientLeaving(aDataClient %x) [iDataClients.Count()=%d]"), this, &aDataClient, iDataClients.Count()));
       
   140 	}
       
   141 	
       
   142 void CConnectionProviderShim::DoControlClientJoiningL(MConnectionControlClient& aControlClient)
       
   143 	{
       
   144 	(void)aControlClient;
       
   145 	__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tDoControlClientJoiningL(aControlClient %x) [iControlClients.Count()=%d]"), this, &aControlClient, iControlClients.Count()));
       
   146 	}
       
   147 	
       
   148 void CConnectionProviderShim::DoControlClientLeaving(MConnectionControlClient& aControlClient)
       
   149 	{
       
   150 	(void)aControlClient;
       
   151 	__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tDoControlClientLeaving(aControlClient %x) [iControlClients.Count()=%d]"), this, &aControlClient, iControlClients.Count()));
       
   152 	}
       
   153 	
       
   154 TInt CConnectionProviderShim::DoStop(TInt aError, const RMessagePtr2* aMessage)
       
   155 	{
       
   156 #ifdef SYMBIAN_NETWORKING_UMTSR5
       
   157 	// when RConn::Stop() happens, that means one is releasing the connection, so the IAP associated with
       
   158 	// the Lock should go away. The code below will set the status of IAP locked to false, so that any further
       
   159 	// Start can lock it 			
       
   160 	iFactoryShim->SetIAPLockStatus(EFalse,-1);
       
   161 #endif // SYMBIAN_NETWORKING_UMTSR5			
       
   162 	return iProvider->Stop( aError, aMessage );
       
   163 	}
       
   164    
       
   165 void CConnectionProviderShim::DoProgressL(Meta::SMetaData& aParams) const
       
   166 	{
       
   167 #ifdef _DEBUG
       
   168 	Meta::STypeId tid = aParams.GetTypeId();
       
   169 #endif
       
   170 	ASSERT( tid.iUid == TUid::Uid( KESockMessagesImplementationUid ) && tid.iType == EESockMessageCommsNifBuffer);
       
   171 	TMetaNifProgressBuf& p = static_cast<TMetaNifProgressBuf&>(aParams);
       
   172 	iProvider->ProgressL( p.iNifProgressBuf );
       
   173 	}
       
   174    
       
   175 void CConnectionProviderShim::DoLastProgressError(Meta::SMetaData& aBuffer)
       
   176 	{
       
   177 #ifdef _DEBUG
       
   178 	Meta::STypeId tid = aBuffer.GetTypeId();
       
   179 #endif
       
   180 	ASSERT( tid.iUid == TUid::Uid( KESockMessagesImplementationUid ) && tid.iType == EESockMessageCommsNifBuffer);
       
   181 	TMetaNifProgressBuf& p = static_cast<TMetaNifProgressBuf&>(aBuffer);
       
   182 	iProvider->LastProgressError( p.iNifProgressBuf );
       
   183 	}
       
   184    
       
   185 void CConnectionProviderShim::DoRequestServiceChangeNotificationL()
       
   186 	{
       
   187 	iProvider->RequestServiceChangeNotificationL();
       
   188 	}
       
   189    
       
   190 void CConnectionProviderShim::DoCancelServiceChangeNotification()
       
   191 	{
       
   192 	iProvider->CancelServiceChangeNotification();
       
   193 	}
       
   194    
       
   195 void CConnectionProviderShim::DoControlL(TUint aOptionLevel, TUint aOptionName, Meta::SMetaData& aOption, const RMessagePtr2* aMessage)
       
   196 	{
       
   197 #ifdef _DEBUG
       
   198 	Meta::STypeId tid = aOption.GetTypeId();
       
   199 #endif
       
   200 	ASSERT( tid.iUid == TUid::Uid( KESockMessagesImplementationUid ) && tid.iType == EESockMessageCommsDes8);
       
   201 	::TMetaDes8& p = static_cast< ::TMetaDes8& >(aOption);
       
   202 	ASSERT(p.iDes);
       
   203 	iProvider->ControlL(aOptionLevel, aOptionName, *((TDes8*)(p.iDes)), aMessage);
       
   204 	}
       
   205    
       
   206 TInt CConnectionProviderShim::DoAllSubConnectionNotificationEnable()
       
   207 	{
       
   208 	return iProvider->AllSubConnectionNotificationEnable();
       
   209 	}
       
   210    
       
   211 TInt CConnectionProviderShim::DoCancelAllSubConnectionNotification()
       
   212 	{
       
   213 	return iProvider->CancelAllSubConnectionNotification();
       
   214 	}
       
   215 
       
   216 void CConnectionProviderShim::DoSendIoctlMessageL(const RMessage2& aMessage)
       
   217 	{
       
   218 	iProvider->SendIoctlMessageL(aMessage);
       
   219 	}
       
   220    
       
   221 void CConnectionProviderShim::DoSendCancelIoctl()
       
   222 	{
       
   223    	iProvider->SendCancelIoctl();	
       
   224 	}
       
   225 
       
   226 TInt CConnectionProviderShim::DoEnumerateSubConnectionsL(TUint& aCount)
       
   227 	{
       
   228 	return iProvider->EnumerateSubConnections(aCount);
       
   229 	}
       
   230 
       
   231 TUint CConnectionProviderShim::DoEnumerateClientsL(HBufC8*& /*aClientInfoBuffer*/, TEnumClients /*aClientType*/)
       
   232 	{
       
   233 	return 0;
       
   234 	}
       
   235 
       
   236 CConnectionSettings& CConnectionProviderShim::DoSettingsAccessL()
       
   237 	{
       
   238 	ASSERT(iProvider);
       
   239 	if (iConnectionSettings == NULL)
       
   240     	{
       
   241     	iConnectionSettings = new (ELeave)CConnectionSettingsShim(*iProvider);	    
       
   242     	}
       
   243 	return *iConnectionSettings;
       
   244 	}
       
   245 	
       
   246 void CConnectionProviderShim::ConnectionJoiningL( const CConnection& aConnection )
       
   247 	{
       
   248 	if (iConnections.Find(&aConnection) < 0)
       
   249 		{
       
   250 		iConnections.AppendL(&aConnection);
       
   251 		}
       
   252 	TInt count = iNifManSubConnections.Count();
       
   253 	for ( TInt n = 0; n < count; n++ )
       
   254 		{//here we exactly know what we are dealing with hence the cast
       
   255 		CNifManSubConnectionShim* c = static_cast<CNifManSubConnectionShim*>(iNifManSubConnections[n]);
       
   256 		MSubInterfaceShim* subint = static_cast<MSubInterfaceShim*>(c);
       
   257 		subint->ConnectionJoiningL(aConnection);
       
   258 		}
       
   259 	}
       
   260 	
       
   261 void CConnectionProviderShim::ConnectionLeaving( const CConnection& aConnection )
       
   262 	{
       
   263 	TInt count = iNifManSubConnections.Count();
       
   264 	for ( TInt n = 0; n < count; n++ )
       
   265 		{//here we exactly know what we are dealing with hence the cast
       
   266 		CNifManSubConnectionShim* c = static_cast<CNifManSubConnectionShim*>(iNifManSubConnections[n]);
       
   267 		MSubInterfaceShim* subint = static_cast<MSubInterfaceShim*>(c);
       
   268 		subint->ConnectionLeaving(aConnection);
       
   269 		}
       
   270 	TInt n = iConnections.Find(&aConnection);
       
   271 	if (n >= 0)
       
   272 		{
       
   273 		iConnections.Remove(n);
       
   274 		}
       
   275 	}
       
   276 
       
   277 void CConnectionProviderShim::DoConnectionControlActivityL( TControlActivity aControlActivity, const Meta::SMetaData* aData, const RMessagePtr2* aMessage )
       
   278 	{
       
   279 	switch (aControlActivity)
       
   280 		{
       
   281 		case EAttachNormal:
       
   282 		case EAttachMonitor:
       
   283 			iProvider->AttachToConnectionL(iConnectionInfo.Right(KConnInfoPart), aControlActivity == EAttachMonitor, aMessage);
       
   284 			if ( aData == NULL )
       
   285 				{
       
   286 				break;
       
   287 				}
       
   288 			aControlActivity = EConnJoin; //and fall through
       
   289 		case EConnJoin:
       
   290 			if ( !aData || !aData->IsTypeOf( STypeId::CreateSTypeId(KShimCommsUid, Meta::KNetMetaTypeAny) ) )
       
   291 				{
       
   292 				User::Leave(KErrArgument);
       
   293 				}
       
   294 			ConnectionJoiningL(static_cast<const TShimConnectionInfo*>(aData)->iConnection);
       
   295 			break;
       
   296 		case EConnLeave:
       
   297 			if ( !aData || !aData->IsTypeOf( STypeId::CreateSTypeId(KShimCommsUid, Meta::KNetMetaTypeAny) ) )
       
   298 				{
       
   299 				User::Leave(KErrArgument);
       
   300 				}
       
   301 			ConnectionLeaving(static_cast<const TShimConnectionInfo*>(aData)->iConnection);
       
   302 			break;
       
   303 		case ESetUsageProfile:
       
   304 			{
       
   305 			ASSERT(aData);
       
   306 	#ifdef _DEBUG
       
   307 			Meta::STypeId tid = aData->GetTypeId();
       
   308 	#endif
       
   309 			ASSERT( tid.iUid == TUid::Uid( KESockMessagesImplementationUid ) && tid.iType == EESockMessageCommsDes8);
       
   310 			const ::TMetaDes8* p = static_cast<const ::TMetaDes8*>(aData);
       
   311 			ASSERT(p->iDes);
       
   312 			const TUint* profile = reinterpret_cast<const TUint*>(p->iDes->Ptr());
       
   313 			if (iUsageProfile != *profile)
       
   314 				{
       
   315 				__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tSetting usage profile %x -> %x"),
       
   316 						this, iUsageProfile & 0xff, *profile & 0xff));
       
   317 				iUsageProfile = *profile;
       
   318 				iProvider->SetUsageProfile(*profile);
       
   319 				}
       
   320 			break;
       
   321 			}
       
   322 		};
       
   323 	}
       
   324 	
       
   325 CNifManSubConnectionShim* CConnectionProviderShim::FindSubConnection( TSubConnectionUniqueId aId )
       
   326 	{
       
   327 	CNifManSubConnectionShim* client = NULL;
       
   328 	TInt count = iNifManSubConnections.Count();
       
   329 	for ( TInt n = 0; n < count; n++ )
       
   330 		{//here we exactly know what we are dealing with hence the cast
       
   331 		CNifManSubConnectionShim* c = static_cast<CNifManSubConnectionShim*>(iNifManSubConnections[n]);
       
   332 		MSubInterfaceShim* subint = static_cast<MSubInterfaceShim*>(c);
       
   333 		if (subint->Id() == aId )
       
   334 			{
       
   335 			client = c;
       
   336 			break;
       
   337 			}
       
   338 		}
       
   339 	return client;
       
   340 	}
       
   341 	
       
   342 // Define methods from the interface specified by MConnectionNotify
       
   343 void CConnectionProviderShim::ProgressNotification(TInt aStage, TInt aError)
       
   344 	{
       
   345 	__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tProgressNotification(%d, %d)"), this, aStage, aError));
       
   346 	
       
   347 	TInt max = iControlClients.Count();
       
   348 	for (TInt n = max - 1 ; n >= 0 ; n--)
       
   349 		{
       
   350 		MConnectionControlClient* client = iControlClients[n];
       
   351 		client->ProgressNotification(aStage, aError);
       
   352 		//check whether the client dissapeared or not
       
   353 		if ( n < iControlClients.Count() && client == iControlClients[n] )
       
   354 			{
       
   355 			if (aStage == KLinkLayerOpen)
       
   356 				{
       
   357 				iControlClients[n]->LayerUp(aError);
       
   358 				}
       
   359 			else if (aError != KErrNone)
       
   360 				{
       
   361 				iControlClients[n]->ConnectionError(aStage, aError);
       
   362 				}
       
   363 			}
       
   364 		}
       
   365 	if (aStage == KConnectionUninitialised && !iIsAlreadyUninitialised /* Guard against receiving KConnectionUninitialised multiple times*/)
       
   366 		{						
       
   367 		iIsAlreadyUninitialised = ETrue;
       
   368 		TInt selectors = iSelectors.Count();
       
   369 		for (TInt i = 0; i < selectors; ++i)
       
   370 			{
       
   371 			iSelectors[i]->SetProviderNull();
       
   372 			}		
       
   373 		DeleteMeNow();		
       
   374 		}
       
   375 	}
       
   376 
       
   377 void CConnectionProviderShim::LinkLayerOpen(TInt /*aError*/)
       
   378 /**
       
   379 Notification from the connection provider - ignored.
       
   380 
       
   381 */
       
   382 	{	
       
   383 	}
       
   384    
       
   385 void CConnectionProviderShim::LinkLayerClosed(TInt /*aError*/)
       
   386 /**
       
   387 Notification from the connection provider - not currently used.
       
   388 
       
   389 */
       
   390 	{
       
   391 	User::Invariant();
       
   392 	}
       
   393 
       
   394 void CConnectionProviderShim::SelectionComplete(TInt aError, const TDesC8& /*aSelectionInfo*/)
       
   395 	{//obsolete call selection done by factories this could happen only on Attach
       
   396 	__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tSelectionComplete(%d)"), this, aError));
       
   397 	ProgressNotification(KFinishedSelection, aError);
       
   398 	}
       
   399    
       
   400 void CConnectionProviderShim::ConnectionError(TInt /*aError*/)
       
   401 /**
       
   402 Notification from the connection provider - not currently used.
       
   403 
       
   404 */
       
   405 	{
       
   406 	User::Invariant();
       
   407 	}
       
   408    
       
   409 void CConnectionProviderShim::ProgressNotification(TSubConnectionUniqueId aSubConnectionUniqueId, TInt aStage, TInt aError)
       
   410 	{
       
   411 	MSubInterfaceShim* subint = static_cast<MSubInterfaceShim*>(FindSubConnection(aSubConnectionUniqueId));
       
   412 	if (subint)
       
   413 		{//here we exactly know what we are dealing with hence the cast
       
   414 		subint->ProgressNotification(aStage, aError, KNullDesC8);
       
   415 		}
       
   416 	else
       
   417 		{
       
   418 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tProgressNotification(subConnectionId %d, %d, %d) subconnection ID lookup error occured"),
       
   419 					 this, aSubConnectionUniqueId, aStage, aError));
       
   420 		}
       
   421 	}
       
   422    
       
   423 void CConnectionProviderShim::ServiceChangeNotification(TUint32 aId, const TDesC& aType)
       
   424 	{
       
   425 	TInt max = iControlClients.Count();
       
   426 	for (TInt i = max - 1 ; i >= 0 ; i--)
       
   427 		{
       
   428 		iControlClients[i]->ServiceChangeNotification(aId, aType);
       
   429 		}
       
   430 	}
       
   431    
       
   432 void CConnectionProviderShim::InterfaceStateChangeNotification(TDesC8& /*aInfo*/)
       
   433 	{//served through factories
       
   434 	ASSERT( NULL );
       
   435 	}
       
   436    
       
   437 void CConnectionProviderShim::NotifyDataSent(TSubConnectionUniqueId aSubConnectionUniqueId, TUint aUplinkVolume)
       
   438 	{//here we exactly know what we are dealing with hence the cast
       
   439 	MSubInterfaceShim* subint = static_cast<MSubInterfaceShim*>(FindSubConnection(aSubConnectionUniqueId));
       
   440 	if (subint)
       
   441 		{
       
   442 		subint->NotifyDataSent(aUplinkVolume,0);
       
   443 		}
       
   444 	else
       
   445 		{
       
   446 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tNotifyDataSent(subConnectionId %d, aUplinkVolume %d) subconnection ID lookup error %d occured"),
       
   447 					 this, aSubConnectionUniqueId, aUplinkVolume, KErrNotFound));
       
   448 		}
       
   449 	}
       
   450    
       
   451 void CConnectionProviderShim::NotifyDataReceived(TSubConnectionUniqueId aSubConnectionUniqueId, TUint aDownlinkVolume)
       
   452 	{//here we exactly know what we are dealing with hence the cast
       
   453 	MSubInterfaceShim* subint = static_cast<MSubInterfaceShim*>(FindSubConnection(aSubConnectionUniqueId));
       
   454 	if (subint)
       
   455 		{
       
   456 		subint->NotifyDataReceived(aDownlinkVolume,0);
       
   457 		}
       
   458 	else
       
   459 		{
       
   460 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tNotifyDataReceived(SubConnectionId %d, aDownLinkVolume %d); subconnection ID lookup error %d occured"),
       
   461 					 this, aSubConnectionUniqueId, aDownlinkVolume, KErrNotFound));
       
   462 		}
       
   463 	}
       
   464 
       
   465 void CConnectionProviderShim::SubConnectionEvent(const TSubConnectionEvent& aSubConnectionEvent)
       
   466 /**
       
   467 Upcall from connection provider indicating that a subconnection event has occured
       
   468 
       
   469 @param aSubConnectionEvent The event that occured
       
   470 @note Even if the not client is listening for subconnection events, we still need them to manage the array of subconnections by listening for started and stopped events on each subconnection
       
   471 @note Events are not handled on a per-subconnection basis - all events are distributed to anyone who uses the AllSubConnectionNotification() method, so no subconnection/subinterface involvement is necessary
       
   472 */
       
   473 	{
       
   474 	TSubConnectionEventType eventType(aSubConnectionEvent.iEventType);
       
   475 	TInt ret = KErrNone;
       
   476 	
       
   477 	TSockManData* sockManData = SockManGlobals::Get();
       
   478 	ASSERT(sockManData != NULL);
       
   479 	
       
   480 	CNifManSubConnectionShim* c = NULL;
       
   481 	switch(eventType)
       
   482 		{
       
   483 		case ESubConnectionOpened:
       
   484 		    {			
       
   485 			__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tSubConnectionEvent() ESubConnectionOpened"), this));
       
   486 			c = FindSubConnection(aSubConnectionEvent.iSubConnectionUniqueId);
       
   487 			if (c == NULL)
       
   488 				{
       
   489 				// no instance yet for particular Id, create one
       
   490 				TRAP(ret,c = new (ELeave)CNifManSubConnectionShim(*this));
       
   491 				if(ret!=KErrNone)	// nothing we can do here, no point in throwing error back to event source - nothing they can do about it
       
   492 					{
       
   493 					// Array integrity will be broken here - may cause errors later with events on this subconnection if we recover
       
   494 					__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tERROR: Subconnection opened event; could not create CSubInterface - possible OOM condition - subconnection ID %d, error %d - subinterface array integrity failure"),
       
   495 							    this, aSubConnectionEvent.iSubConnectionUniqueId, ret));
       
   496 					break;
       
   497 					}
       
   498 				ret = iNifManSubConnections.Append(c);
       
   499 				if (ret != KErrNone)
       
   500 					{
       
   501 						__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tERROR: could not append CNifManSubConnectionShim to the list - subconnection ID %d, error %d - subinterface array integrity failure"),
       
   502 							    this, aSubConnectionEvent.iSubConnectionUniqueId, ret));
       
   503 						c->DeleteAsync();
       
   504 						break;
       
   505 					}
       
   506 				}
       
   507 			MSubInterfaceShim* subint = static_cast<MSubInterfaceShim*>(c);
       
   508 			subint->SetSubConnectionUniqueId(aSubConnectionEvent.iSubConnectionUniqueId);
       
   509 			
       
   510 			TInt count = iConnections.Count();
       
   511 			for (TInt i = count - 1; i >= 0; i--)
       
   512 				{
       
   513 				TRAP(ret,c->ConnectionJoiningL(*iConnections[i]));
       
   514 				if(ret!=KErrNone)	// nothing we can do here, no point in throwing error back to event source - nothing they can do about it
       
   515 					{
       
   516 					// Array integrity will be broken here - may cause errors later with events on this subconnection if we recover
       
   517 					__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tERROR: connection joining subconnection opened event; - possible OOM condition - subconnection ID %d, error %d - subinterface array integrity failure"),
       
   518 								 this, aSubConnectionEvent.iSubConnectionUniqueId, ret));
       
   519 					break;
       
   520 					}
       
   521 				}
       
   522 		    }
       
   523 			break;
       
   524 
       
   525 		case ESubConnectionClosed:
       
   526 			__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tSubConnectionEvent() ESubConnectionClosed"), this));
       
   527 			c = FindSubConnection(aSubConnectionEvent.iSubConnectionUniqueId);
       
   528 			if(!c)		// then there was an error (probably that we couldn't find the object in the array) - write error to log - not much else we can do
       
   529 				{
       
   530 				__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tERROR: Subconnection closed event; could not find subconnection ID %d, lookup error %d occured"),
       
   531 						    this, aSubConnectionEvent.iSubConnectionUniqueId, KErrNotFound));
       
   532 				}
       
   533 			else
       
   534 				{
       
   535 				iDeleteAsynchOnly = ETrue;
       
   536 				TInt n = iNifManSubConnections.Find(c);
       
   537 				if (n >= 0)
       
   538 					{
       
   539 					iNifManSubConnections.Remove(n);
       
   540 					}
       
   541 				c->DeleteAsync();
       
   542 				}
       
   543 			break;
       
   544 
       
   545 		default:
       
   546 			// do nothing; we only care about open and close events
       
   547 			break;
       
   548 		}	
       
   549 	
       
   550 	// Rebroadcast all events to all attached control clients
       
   551 	TInt max = iControlClients.Count();
       
   552 	for (TInt i = max - 1; i >= 0 ; i--)
       
   553 		{
       
   554 		iControlClients[i]->SubConnectionEvent(NULL, aSubConnectionEvent);
       
   555 		}
       
   556 
       
   557 	CheckDeleteThis();
       
   558 
       
   559 	}
       
   560 
       
   561 CConnectionProvdBase* CConnectionProviderShim::GetNifSession()
       
   562     {
       
   563     return iProvider;
       
   564     }
       
   565     
       
   566 void CConnectionProviderShim::InitialiseL(CConnectionProvdBase* aStarterSession)
       
   567 	{
       
   568 	ASSERT(aStarterSession);
       
   569 	//
       
   570 	//can't set the provider twice
       
   571 	//
       
   572 	ASSERT(iProvider == NULL);	
       
   573 	iProvider = Nif::NewConnectionL(this, 0);	
       
   574 	__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tInitialiseL(aStarterSession %x) iProvider %x"), this, aStarterSession, iProvider));
       
   575 	//
       
   576 	// After creating the new nif session (iProvider) we also need to transfer the connection attempt count
       
   577 	// from the old nif session (aStarterSession) to the new one, since it was the one that initially 
       
   578 	// started the interface and connection attempt count was incremented in StartL of nif session
       
   579 	//
       
   580 	TPckg<TInt> connectionAttempt(-1);
       
   581 	aStarterSession->ControlL(KCOLProvider, KNifSessionGetConnectionAttempt, connectionAttempt, NULL);
       
   582 	ASSERT(connectionAttempt() != -1);			
       
   583 	iProvider->ControlL(KCOLProvider, KNifSessionSetConnectionAttempt, connectionAttempt, NULL);
       
   584 	//
       
   585 	// Finally, call ConnectionControlActivityL to ensure that the provider is attached to the connection
       
   586 	// and progress notifications from the provider end up in the connection object too
       
   587 	//		
       
   588 	DoConnectionControlActivityL(EAttachNormal, NULL, NULL);
       
   589 	
       
   590 //PREQ399_REMOVE
       
   591 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
   592 	_LIT(KIfNameField, "IfName");
       
   593 	TBuf<KCommsDbSvrMaxFieldLength> nifname;
       
   594 	iProvider->GetDes16SettingL(KIfNameField(), nifname);
       
   595     if (nifname.CompareF (KSpudName) == 0)
       
   596         {
       
   597         iSubConnectionType = KUmtsGprsSubConnectionProviderFactoryId;
       
   598         }
       
   599 #endif //SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
   600 	iHasAnyControlClientJoined = ETrue;
       
   601     }
       
   602     
       
   603 void CConnectionProviderShim::SetBlockProgressesL(CConnectionProvdBase* aStarterSession)
       
   604 /**
       
   605 Ensure that the "blocked progress" status of aStarterSession is copied across to iProvider session.
       
   606 
       
   607 @param aStarterSession session from which to copy "blocked progress" status.
       
   608 */
       
   609 	{
       
   610 	TPckg<TBool> blockProgresses(EFalse);
       
   611 	aStarterSession->ControlL(KCOLProvider, KNifSessionGetBlockProgresses, blockProgresses, NULL);
       
   612 	iProvider->ControlL(KCOLProvider, KNifSessionSetBlockProgresses, blockProgresses, NULL);
       
   613 	}
       
   614 
       
   615 void CConnectionProviderShim::DoJoinNextLayerL(CConnectionProviderBase* aNextLayer)
       
   616 	{
       
   617 	(void)aNextLayer;
       
   618 	if ( !iProvider )
       
   619 		{
       
   620 		ASSERT( !aNextLayer );
       
   621 //		AddRef(); 	//The AddRef needs to be here since it follows the logic in the selector shim. 	
       
   622 		iProvider = Nif::NewConnectionL(this, 0);
       
   623 		__CFLOG_VAR((KShimCprTag, KShimCprSubTag, _L8("CConnectionProviderShim %08x:\tDoJoinNextLayerL(aNextLayer %x) iProvider %x"), this, aNextLayer, iProvider));
       
   624 		}
       
   625 	}
       
   626 	
       
   627 CConnectionProviderBase* CConnectionProviderShim::DoNextLayer() const
       
   628     {
       
   629     //This is (by design) the last layer.
       
   630     return NULL;
       
   631     }
       
   632     
       
   633     
       
   634 TInt CConnectionProviderShim::DoCanDoSubConnection(RSubConnection::TSubConnType aSubConnType) const
       
   635 	{
       
   636 	(void)aSubConnType;
       
   637 #ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
   638 	return iSubConnectionType;
       
   639 #else	
       
   640   	return 0;
       
   641 #endif
       
   642 // SYMBIAN_NETWORKING_3GPPDEFAULTQOS
       
   643   	}
       
   644 
       
   645 /**
       
   646 Find particular CSubConnectionLinkShimClient object with the pointer to given aConnection
       
   647 
       
   648 @param aTypeId Id of CNifManSubConnectionShim
       
   649 @param aConnection aConnection pointer 
       
   650 @return CSubConnectionLinkShimClient* or NULL
       
   651 */
       
   652 CSubConnectionLinkShimClient* CConnectionProviderShim::QuerySubSessions(TInt32 aTypeId,const CConnection* aConnection)
       
   653 	{
       
   654 	 TInt count = iNifManSubConnections.Count();
       
   655 	 CNifManSubConnectionShim *nifManSubConnection;
       
   656 	 CSubConnectionLinkShimClient *linkShimClient = NULL;
       
   657 	 for (TInt i = count - 1; i >= 0; i--)
       
   658 	 	{
       
   659 		nifManSubConnection = iNifManSubConnections[i];
       
   660 		if (nifManSubConnection && nifManSubConnection->Id() == aTypeId)	
       
   661 			{
       
   662 			TInt n = 0;
       
   663 			do
       
   664 				{
       
   665 				 linkShimClient = nifManSubConnection->ShimClient(n++);			
       
   666 				}
       
   667 			while (linkShimClient && !linkShimClient->Match(*aConnection));
       
   668 			}
       
   669 	 	}
       
   670 	 		
       
   671 	return linkShimClient;
       
   672 	}
       
   673 	
       
   674 #ifdef SYMBIAN_NETWORKING_UMTSR5
       
   675 void CConnectionProviderShim::SetFactoryIfactory(CConnectionProviderFactoryShim *aFactoryShim)
       
   676 	{
       
   677 	iFactoryShim = aFactoryShim;	
       
   678 	}
       
   679 #endif // SYMBIAN_NETWORKING_UMTSR5	
       
   680 
       
   681