datacommsserver/esockserver/ssock/ss_connLegacy.cpp
changeset 0 dfb7c4ff071f
child 4 928ed51ddc43
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     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 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include "ss_connlegacy.h"
       
    22 #include <ss_std.h>
       
    23 #include "ss_connstates.h"
       
    24 #include <comms-infras/sockmes.h>
       
    25 #include <cdblen.h>
       
    26 #include <ss_glob.h>
       
    27 #include <comms-infras/ss_log.h>
       
    28 #include "SS_rslv.H"
       
    29 #include <ss_sock.h>
       
    30 #include <comms-infras/ss_sapshim.h>
       
    31 #include <comms-infras/ss_connsettings.h>
       
    32 #include "ss_subconn.h"
       
    33 #include <comms-infras/esockmessages.h>
       
    34 
       
    35 #include <comms-infras/ss_datamonitoringprovider.h>
       
    36 #include <comms-infras/nifif.h>
       
    37 #include "SS_conn.H"
       
    38 #include <comms-infras/ss_datamon_apiext.h>
       
    39 #include <comms-infras/ss_roles.h>
       
    40 #include <commdbconnpref.h> //TCommDbConnPref
       
    41 #include <comms-infras/ss_nodemessages_serviceprovider.h>
       
    42 #include <elements/nm_messages_child.h>
       
    43 #include "ss_internal_activities.h"
       
    44 
       
    45 
       
    46 #ifdef _DEBUG
       
    47 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    48 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    49 _LIT(KSpecAssert_ESockSSockscnLgc, "ESockSSockscnLgc");
       
    50 #endif
       
    51 
       
    52 using namespace ESock;
       
    53 using namespace Messages;
       
    54 using namespace MeshMachine;
       
    55 using namespace Factories;
       
    56 using namespace Den;
       
    57 
       
    58 
       
    59 //************************************* old stuff ********************************//
       
    60 
       
    61 
       
    62 
       
    63 //const TInt KNumberOfEmulatedSubConnections = 2;
       
    64 
       
    65 const Factories::TAnyFn AConnectionLegacy::iInterfaceVTableF[] =
       
    66 	{
       
    67 	(Factories::TAnyFn)1,
       
    68 	(Factories::TAnyFn)(TFactoryNotify<AConnectionLegacy>::Notification)
       
    69 	};
       
    70 
       
    71 AConnectionLegacy::~AConnectionLegacy()
       
    72     {
       
    73    	TSubConnectionEvent* subConnectionEvent;
       
    74 	while (iSubConnectionEventQueue.Deque(subConnectionEvent))
       
    75 		{
       
    76 		LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tDequeuing and deleting subconnection event(%08x)"), this, subConnectionEvent));
       
    77 		delete subConnectionEvent;
       
    78 		subConnectionEvent = NULL;
       
    79 		}
       
    80 
       
    81 	iConnectionSocketBuf.Close();
       
    82 	iConnectionClientBuf.Close();
       
    83 	iConnectionInfoPtrArray.ResetAndDestroy();
       
    84 	FinalCompleteAllBlockedMessages(KErrCancel);
       
    85 	for (TInt i = 0; i < iSubConnections.Count(); ++i)
       
    86 		{
       
    87 		iSubConnections.Close();
       
    88 		}
       
    89 	}
       
    90 
       
    91 void AConnectionLegacy::CancelProviderRequests()
       
    92 	{
       
    93 //	CancelServiceChangeNotification();
       
    94 	}
       
    95 
       
    96 void AConnectionLegacy::FinalCompleteAllBlockedMessages(TInt /* aReason */)
       
    97 	{
       
    98 	// If the all interface notification worker is running then post a
       
    99 	// destroy to it.
       
   100 	if(!iAllInterfaceNotificationWorker.IsNull())
       
   101 		{
       
   102 		TNodeCtxId dest(ECFActivityConnectionAllInterfaceNotification, iAllInterfaceNotificationWorker);
       
   103 		RNodeInterface::OpenPostMessageClose(iConnection.Id(), dest, TEBase::TCancel().CRef());
       
   104 		iAllInterfaceNotificationWorker.SetNull();
       
   105 		}
       
   106 	}
       
   107 
       
   108 
       
   109 
       
   110 namespace ESock
       
   111 {
       
   112 class XConnectionFactoryAPQuery : public Factories::MFactoryQuery
       
   113 	{
       
   114 public:
       
   115 	XConnectionFactoryAPQuery(TInt aAp)
       
   116 	:iAp( aAp ) {}
       
   117 
       
   118 protected:
       
   119 	TInt iAp;
       
   120 
       
   121 public:
       
   122 	virtual TMatchResult Match(TFactoryObjectInfo& aConnectionInfo);
       
   123 	};
       
   124 }
       
   125 
       
   126 MFactoryQuery::TMatchResult XConnectionFactoryAPQuery::Match(TFactoryObjectInfo& aConnectionInfo)
       
   127 	{
       
   128 	CConnectionProviderBase* connProv = static_cast<CConnectionProviderBase*>(aConnectionInfo.iInfo.iFactoryObject);
       
   129 	return connProv->ProviderInfo().APId() == iAp ? MFactoryQuery::EMatch : MFactoryQuery::EContinue;
       
   130 	}
       
   131 
       
   132 
       
   133 static const TUid K_CIPProtoConnectionProviderFactory_iUid = {0x10281DD3};
       
   134 
       
   135 void AConnectionLegacy::CompleteAttachL(ESock::TSelectionPrefs& aPrefs)
       
   136 	{
       
   137 	//We have built the new top (legacy) Cpr and now we need to make sure that
       
   138 	//it is properly joined to the layer directly below it (i.e. IpProto).
       
   139 	TConnPref& cp = aPrefs.Prefs();
       
   140 	__ASSERT_DEBUG(cp.ExtensionId()==TConnPref::EConnPrefCommDb, User::Panic(KSpecAssert_ESockSSockscnLgc, 1)); //Must be legacy now
       
   141 
       
   142 	__ASSERT_DEBUG(iConnection.ServiceProvider(), User::Panic(KSpecAssert_ESockSSockscnLgc, 2)); //The CConnection has been already joined
       
   143 	RNodeInterface* sp = iConnection.ServiceProvider();
       
   144 	Messages::ANode& connProvNode = sp->RecipientId().Node();
       
   145     MeshMachine::AMMNodeBase* cpr = reinterpret_cast<MeshMachine::AMMNodeBase*>(connProvNode.FetchNodeInterfaceL(AMMNodeBase::KInterfaceId));
       
   146     __ASSERT_DEBUG(cpr->GetFirstClient<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EServProvider))==NULL, User::Panic(KSpecAssert_ESockSSockscnLgc, 3)); //This is why we are "legacy"
       
   147 
       
   148 	CConnectionFactoryContainer& container = *static_cast<CPlayer&>(iConnection.Player()).SockManGlobals()->iConnectionFactories;
       
   149 	CCommsFactoryBase* factory = static_cast<CCommsFactoryBase*>(container.FindFactory(K_CIPProtoConnectionProviderFactory_iUid));
       
   150     User::LeaveIfError(factory? KErrNone : KErrArgument);
       
   151 
       
   152     XConnectionFactoryAPQuery query(static_cast<const TCommDbConnPref&>(cp).IapId());
       
   153     CConnectionProviderBase* ipProtoCpr = static_cast<CConnectionProviderBase*>(factory->Find(query));
       
   154     User::LeaveIfError(ipProtoCpr? KErrNone : KErrArgument);
       
   155 
       
   156 	cpr->AddClientL(ipProtoCpr->Id(),TClientType(TCFClientType::EServProvider, TCFClientType::EActive));
       
   157 	TUint clientFlags = 0;
       
   158 	if (aPrefs.Flags()&TSelectionPrefs::EMonitor)
       
   159 		{
       
   160 		__ASSERT_DEBUG(iConnection.IsMonitor(), User::Panic(KSpecAssert_ESockSSockscnLgc, 4)); //Well, we are attaching as a monitor, must be consistent!
       
   161 		clientFlags = TCFClientType::EMonitor;
       
   162 		}
       
   163 
       
   164 	TRAPD(error,ipProtoCpr->AddClientL(cpr->Id(),TClientType(TCFClientType::ECtrl,clientFlags)));
       
   165 	if (error!=KErrNone)
       
   166 		{
       
   167 		iConnection.ServiceProvider()->PostMessage(ipProtoCpr->Id(), TEChild::TLeft().CRef());
       
   168 		User::Leave(error);
       
   169 		}
       
   170 
       
   171 	iConnection.ServiceProvider()->SetFlags(TCFClientType::EStarted);
       
   172 	}
       
   173 
       
   174 /**
       
   175 Process RConnection messages
       
   176 @exception Leaves on any error processing the request
       
   177 */
       
   178 TInt AConnectionLegacy::ProcessMessageL(const RMessage2& aMessage)
       
   179 	{
       
   180 	LOG_DETAILED( ESockLog::Printf(KESockConnectionTag, _L("AConnectionLegacy %08x:\tCommand %d"), this, aMessage.Function()) );
       
   181 	switch (aMessage.Function())
       
   182 		{
       
   183 		case ECNAllSubConnectionNotification:
       
   184 			AllSubConnectionNotificationL();
       
   185 			break;
       
   186 
       
   187 		case ECNCancelAllSubConnectionNotification:
       
   188 			CancelAllSubConnectionNotification();
       
   189 			break;
       
   190 
       
   191 		case ECNEnumerateSubConnections:
       
   192 			EnumerateSubConnectionsL(iConnection.SafeMessage());
       
   193 			break;
       
   194 
       
   195 		case ECNAllInterfaceNotification:
       
   196 			AllInterfaceNotificationL(aMessage);
       
   197 			break;
       
   198 
       
   199 		case ECNCancelAllInterfaceNotification:
       
   200 			CancelAllInterfaceNotification();
       
   201 			break;
       
   202 			
       
   203 		case ECNGetConnectionInfo:
       
   204 			GetConnectionInfoL(aMessage);
       
   205 			break;
       
   206 
       
   207 		case ECNServiceChangeNotification:
       
   208 			RequestServiceChangeNotificationL(iConnection.SafeMessage());
       
   209 			break;
       
   210 
       
   211 		case ECNCancelServiceChangeNotification:
       
   212 			CancelServiceChangeNotification(iConnection.SafeMessage());
       
   213 			break;
       
   214 
       
   215 		case ECNGetIntSetting:
       
   216 			GetIntSettingL(iConnection.SafeMessage());
       
   217 			break;
       
   218 
       
   219 		case ECNGetBoolSetting:
       
   220 			GetBoolSettingL(iConnection.SafeMessage());
       
   221 			break;
       
   222 
       
   223 		case ECNGetDes8Setting:
       
   224 			GetDes8SettingL(iConnection.SafeMessage());
       
   225 			break;
       
   226 
       
   227 		case ECNGetDes16Setting:
       
   228 			GetDes16SettingL(iConnection.SafeMessage());
       
   229 			break;
       
   230 
       
   231 		case ECNGetLongDesSetting:
       
   232 			GetLongDesSettingL(iConnection.SafeMessage());
       
   233 			break;
       
   234 
       
   235 		case ESCPSProgressNotification:
       
   236 			iConnection.SetReturn(KErrNotSupported);
       
   237 			break;
       
   238 
       
   239 		case ESCPSCancelProgressNotification:
       
   240 			break;
       
   241 
       
   242 		case ESCPSDataTransferred:
       
   243 			DataTransferredL(iConnection.SafeMessage());
       
   244 			break;
       
   245 
       
   246 		case ESCPSDataTransferredCancel:
       
   247 			break;
       
   248 
       
   249 		case ESCPSDataSentNotificationRequest:
       
   250 			DataSentNotificationRequestL(iConnection.SafeMessage());
       
   251 			break;
       
   252 
       
   253 		case ESCPSDataSentNotificationCancel:
       
   254 			DataSentNotificationCancel(iConnection.SafeMessage());
       
   255 			break;
       
   256 
       
   257 		case ESCPSDataReceivedNotificationRequest:
       
   258 			DataReceivedNotificationRequestL(iConnection.SafeMessage());
       
   259 			break;
       
   260 
       
   261 		case ESCPSDataReceivedNotificationCancel:
       
   262 			DataReceivedNotificationCancel(iConnection.SafeMessage());
       
   263 			break;
       
   264 
       
   265 		case ESCPSIsSubConnectionActiveRequest:
       
   266 			IsSubConnectionActiveRequestL(iConnection.SafeMessage());
       
   267 			break;
       
   268 
       
   269 		case ESCPSIsSubConnectionActiveCancel:
       
   270 			IsSubConnectionActiveCancel(iConnection.SafeMessage());
       
   271 			break;
       
   272 
       
   273 		case ESCPSGetSubConnectionInfo:
       
   274 			GetSubConnectionInfoL(iConnection.SafeMessage());
       
   275 			break;
       
   276 
       
   277 		default:
       
   278 			iConnection.SetReturn(KErrNotSupported);
       
   279 			LOG(ESockLog::Printf(KESockConnectionTag, _L8("CConnectionLegacy(%08x)::ProcessMessageL - unsupported IPC %d received"), this, aMessage.Function()));
       
   280 		}
       
   281 		return KErrNone;
       
   282 	}
       
   283 
       
   284 /**
       
   285 Control method to send a general command towards the interface.
       
   286 */
       
   287 void AConnectionLegacy::ControlL(TUint aOptionName, TUint aMessageId)
       
   288 	{
       
   289 	if (aMessageId == KCOLConnection)
       
   290 		{
       
   291 		switch(aOptionName)
       
   292 			{
       
   293 			case KCoEnumerateConnectionClients:
       
   294 				EnumerateConnectionClientsL();
       
   295 				return;
       
   296 			case KCoGetConnectionClientInfo:
       
   297 				GetConnectionClientInfoL();
       
   298 				return;
       
   299 			case KCoEnumerateConnectionSockets:
       
   300 				EnumerateConnectionSocketsL();
       
   301 				return;
       
   302 			case KCoGetConnectionSocketInfo:
       
   303 				GetConnectionSocketInfoL();
       
   304 				return;
       
   305 			default:
       
   306 				User::Leave(KErrNotSupported);
       
   307 			}
       
   308 		}
       
   309 	}
       
   310 
       
   311 
       
   312 /**
       
   313 Get the number of currently active subconnections
       
   314 @see RConnection::EnumerateSubConnections for notes on the difference in behaviour between this function and EnumerateConnectionsL()
       
   315 */
       
   316 void AConnectionLegacy::EnumerateSubConnectionsL(const Den::RSafeMessage& aMessage)
       
   317 	{
       
   318 	RNodeInterface* sp = iConnection.ServiceProvider();
       
   319     if(!sp || !(sp->Flags() & TCFClientType::EStarted))
       
   320 		{
       
   321 		LOG(ESockLog::Printf(KESockConnectionTag, _L8("CConnection (AConnectionLegacy) [this=%08x] EnumerateSubConnectionsL KErrNotReady(-18)"), &iConnection));
       
   322         iConnection.SetReturn(KErrNotReady);
       
   323         return;
       
   324 		}
       
   325 
       
   326 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), TLegacyEnumerateSubConnections(aMessage));
       
   327 	iConnection.DontCompleteCurrentRequest();
       
   328 	}
       
   329 
       
   330 
       
   331 void AConnectionLegacy::AllInterfaceNotificationL(const RMessage2& aMessage)
       
   332 	{
       
   333 	if(!iAllInterfaceNotificationMessage.IsNull() || iConnection.ServiceProvider())
       
   334 		{
       
   335 		iConnection.SetReturn(KErrInUse);
       
   336 		return;
       
   337 		}
       
   338 
       
   339 	iAllInterfaceNotificationMessage = aMessage;
       
   340 	iConnection.DontCompleteCurrentRequest();
       
   341 
       
   342 	if(iAllInterfaceNotificationWorker.IsNull())
       
   343 		{
       
   344 		CAllInterfaceNotificationWorker* worker = new(ELeave) CAllInterfaceNotificationWorker(iConnection);
       
   345 		iAllInterfaceNotificationWorker = worker->Id();
       
   346 
       
   347 		TNodeCtxId dest(ECFActivityConnectionAllInterfaceNotification, iAllInterfaceNotificationWorker);
       
   348 		RNodeInterface::OpenPostMessageClose(iConnection.Id(), dest, TCFServiceProvider::TStart().CRef());
       
   349 		}
       
   350 
       
   351 	CompleteAllInterfaceNotificationL(KErrNone);
       
   352 	}
       
   353 
       
   354 void AConnectionLegacy::CompleteAllInterfaceNotificationL(TInt aError)
       
   355 	{
       
   356 	LOG(ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy [this=%08x] CompleteAllInterfaceNotificationL message (%08X) with %d"), &iConnection, iAllInterfaceNotificationMessage.Handle(), aError));
       
   357 
       
   358 	if(!iAllInterfaceNotificationMessage.IsNull())
       
   359 		{
       
   360 		if(aError == KErrNone)
       
   361 			{
       
   362 			if(!iNotificationQueue.IsEmpty())
       
   363 				{
       
   364 				TInterfaceNotification notification;
       
   365 				iNotificationQueue.Deque(notification);
       
   366 
       
   367 				TInterfaceNotificationBuf buf(notification);
       
   368 
       
   369 				// Write the buffer to the client
       
   370 				iAllInterfaceNotificationMessage.WriteL(0, buf);
       
   371 				iAllInterfaceNotificationMessage.Complete(KErrNone);
       
   372 				iAllInterfaceNotificationMessage = RMessage2();
       
   373 				}
       
   374 			}
       
   375 		else
       
   376 			{
       
   377 			iAllInterfaceNotificationMessage.Complete(aError);
       
   378 			iAllInterfaceNotificationMessage = RMessage2();
       
   379 			}
       
   380 		}
       
   381 	}
       
   382 
       
   383 void AConnectionLegacy::CancelAllInterfaceNotification()
       
   384 	{
       
   385 	if(!iAllInterfaceNotificationMessage.IsNull())
       
   386 		{
       
   387 		iAllInterfaceNotificationMessage.Complete(KErrCancel);
       
   388 		}
       
   389 	}
       
   390 
       
   391 void AConnectionLegacy::RequestServiceChangeNotificationL(const Den::RSafeMessage& aMessage)
       
   392 	{
       
   393 	RNodeInterface* currServiceProvider = iConnection.ServiceProvider();
       
   394     if (!currServiceProvider)
       
   395         {
       
   396 		LOG(ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy [this=%08x] RequestServiceChangeNotificationL KErrNotReady"), &iConnection));
       
   397         iConnection.SetReturn(KErrNotReady);
       
   398         return;
       
   399         }
       
   400 
       
   401 	if(iServiceChangeNotificationPending)
       
   402 		{
       
   403 		iConnection.SetReturn(KErrInUse);
       
   404 		return;
       
   405 		}
       
   406 
       
   407     // This message needs to be directed towards the MCpr - Service change notification occurs
       
   408     // during reconnection. We violate the principle of left hand nodes not instructing right
       
   409     // hand nodes. Since this is for legacy support its ok for now. The CPr that implements
       
   410     // the Api is expected to forward this message to its MCpr
       
   411 	iServiceChangeNotificationPending = ETrue;
       
   412 
       
   413 	TCprRequestServiceNotification msg(iConnection.Id(), aMessage);
       
   414 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), msg);
       
   415 
       
   416 	iConnection.DontCompleteCurrentRequest();
       
   417 	}
       
   418 
       
   419 void AConnectionLegacy::CancelServiceChangeNotification(const Den::RSafeMessage& aMessage)
       
   420 	{
       
   421     // This message needs to be directed towards the MCpr - Service change notification occurs
       
   422     // during reconnection. We violate the principle of left hand nodes not instructing right
       
   423     // hand nodes. Since this is for legacy support its ok for now. The CPr that implements
       
   424     // the Api is expected to forward this message to its MCpr
       
   425 	LOG(ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy [this=%08x] CancelServiceChangeNotification KErrCancel"), &iConnection));	
       
   426 	const RPointerArray<CNodeActivityBase>& activities = iConnection.Activities();
       
   427 	for (TInt i = 0; i < activities.Count(); i++)
       
   428 		{
       
   429 		if (activities[i]->ActivitySigId() == ESock::ECFActivityConnectionLegacyRMessage2Handler)
       
   430 			{
       
   431 			ConnActivities::CConnLegacyRMessage2Activity* act = static_cast<ConnActivities::CConnLegacyRMessage2Activity*>(activities[i]);
       
   432 			if (act->iSafeMessage.Function() == ECNServiceChangeNotification)
       
   433 				{
       
   434 				act->SetCancelRequest(aMessage);
       
   435 				iConnection.CMMSockSubSession::ReceivedL(act->iSafeMessage.Function(), TEBase::TCancel().CRef());
       
   436 				iConnection.DontCompleteCurrentRequest();
       
   437 				}
       
   438 			}
       
   439 		}
       
   440 	iServiceChangeNotificationPending = EFalse;
       
   441 	}
       
   442 
       
   443 
       
   444 /**
       
   445 Return information about a single connection that was previously
       
   446 enumerated using EnumerateConnectionsL
       
   447 
       
   448 This is the server-side implementation of the RConnection
       
   449 function TInt GetConnectionInfo(TUint aIndex, TDes8& aConnectionInfo).
       
   450 */
       
   451 void AConnectionLegacy::GetConnectionInfoL(const RMessage2& aMessage)
       
   452 	{
       
   453 	TUint index = aMessage.Int0();
       
   454 
       
   455 	// Make sure the client isn't using an invalid argument (*client* connection numbering starts from 1)
       
   456 	if(index == 0)
       
   457 		{
       
   458 		iConnection.SetReturn(KErrArgument);
       
   459 		return;
       
   460 		}
       
   461 
       
   462 	// Make sure the client isn't trying to access a connection that doesn't exist
       
   463 	if(index > static_cast<TUint>(iConnectionInfoPtrArray.Count()))
       
   464 		{
       
   465 		iConnection.SetReturn(KErrNotFound);
       
   466 		return;
       
   467 		}
       
   468 
       
   469 	index = index - 1;	// alter the client-provided index (indexed from one) to act as a index for the array (indexed from zero)
       
   470 
       
   471 	// check the client argument's version to see which one it's using
       
   472 	TConnArgBase clientArg;
       
   473 	TPckg<TConnArgBase> argPckg(clientArg);
       
   474 	aMessage.ReadL(1, argPckg);
       
   475 	TUint8 clientVersion = clientArg.Version();
       
   476 
       
   477 	// Translate between versions of TConnectionInfo depending on what client passes in
       
   478 	__ASSERT_DEBUG(iConnectionInfoPtrArray[index]->Version() == KConnArgVersion2, User::Panic(KSpecAssert_ESockSSockscnLgc, 5));	// check that the connection provider has put TConnectionInfoV2's in the queue
       
   479 
       
   480 	if(clientVersion == KConnArgVersion1)
       
   481 		{
       
   482 		TConnectionInfo connectionInfoV1;
       
   483 		connectionInfoV1.iIapId = iConnectionInfoPtrArray[index]->iIapId;
       
   484 		connectionInfoV1.iNetId = iConnectionInfoPtrArray[index]->iNetId;
       
   485 		TPckg<TConnectionInfo> info(connectionInfoV1);
       
   486 		LOG( ESockLog::Printf(KESockConnectionTag, _L("AConnectionLegacy: Client called GetConnectionInfo (client ver=%d, esock ver=%d), writing [%S](%d bytes) to client side"), clientArg.Version(), iConnectionInfoPtrArray[index]->Version(), &info, info.Size()); )
       
   487 
       
   488 		aMessage.WriteL(1, info);
       
   489 		}
       
   490 	else
       
   491 		{
       
   492 		if(clientVersion == KConnArgVersion2)
       
   493 			{
       
   494 			// downcast from TConnectionInfo pointer to TConnectionInfoV2 pointer; we can do this safely because the earlier ASSERT() checked that these were TConnectionInfoV2s
       
   495 			TPckg<TConnectionInfoV2> info(*(static_cast<TConnectionInfoV2*>(iConnectionInfoPtrArray[index])));
       
   496 			LOG( ESockLog::Printf(KESockConnectionTag, _L("AConnectionLegacy: Client called GetConnectionInfo (client ver=%d, esock ver=%d), writing [%S](%d bytes) to client side"), clientArg.Version(), iConnectionInfoPtrArray[index]->Version(), &info, info.Size()); )
       
   497 			aMessage.WriteL(1, info);
       
   498 			}
       
   499 		else
       
   500 			{
       
   501 			LOG( ESockLog::Printf(KESockConnectionTag, _L("AConnectionLegacy: Invalid version of argument to GetConnectionInfo (client ver=%d, esock ver=%d)"), clientArg.Version(), iConnectionInfoPtrArray[index]->Version()); )
       
   502 			iConnection.SetReturn(KErrArgument);
       
   503 			}
       
   504 		}
       
   505 	}
       
   506 
       
   507 
       
   508 /**
       
   509 Extract a single enumeration information element from a buffer of elements
       
   510 
       
   511 @param aBuffer the buffer from which to extract the information element
       
   512 @param aCount the total number of elements in the buffer
       
   513 @param aSize the size of each information element
       
   514 @param aIndex the position of the element to retrieve in the buffer. Index is 1-based.
       
   515 @param aPckg the TPckg<> in which to return the information element
       
   516 @exception leaves with KErrOverflow if the index given is past the end of the buffer
       
   517 */
       
   518 void AConnectionLegacy::ExtractEnumInfoL(RBuf8& aBuffer, TUint aCount, TInt aSize, TUint aIndex, TDes8& aPckg)
       
   519 	{
       
   520 	if (aBuffer.Length() == 0)
       
   521 		{
       
   522 		LOG( ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy %08x ExtractEnumInfoL KErrNotReady"), this) );
       
   523 		User::Leave(KErrNotReady);
       
   524 		}
       
   525 	else if (aIndex < 1)
       
   526 		{
       
   527 		User::Leave(KErrArgument);
       
   528 		}
       
   529 	else if (aIndex > aCount)
       
   530 		{
       
   531 		User::Leave(KErrNotFound);
       
   532 		}
       
   533 
       
   534 	__ASSERT_DEBUG((TUint) aBuffer.Length() == (aCount * aSize), User::Panic(KSpecAssert_ESockSSockscnLgc, 6));
       
   535 
       
   536 	const TUint8* ptr = aBuffer.Ptr();
       
   537 
       
   538 	TInt start = aSize * (aIndex-1);
       
   539 	ptr += start;
       
   540 
       
   541 	aPckg.Copy(ptr, aSize);
       
   542 	}
       
   543 
       
   544 /**
       
   545 Gather information on the number of clients of a particular connection
       
   546 
       
   547 This is the server-side implementation of the RConnection
       
   548 function TInt EnumerateConnectionClients(TUint aIndex, TUint& aCount).
       
   549 */
       
   550 void AConnectionLegacy::EnumerateConnectionClientsL()
       
   551 	{
       
   552 	LOG(ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy::EnumerateConnectionClientsL()")));
       
   553 	// Cover the remote case that another client thread is already enumerating the connection in a similar way - when it all
       
   554 	// completed synchronously in the same thread there was no possibility of this problem. Attempting the same queue behaviour
       
   555 	// here seems pointless: it's a very rare case of a rare case of a deprecated API which was never documented as working
       
   556 	// that way. So instead we complete the client with KErrBusy
       
   557 	if(!iEnumConnMsg.IsNull())
       
   558 		{
       
   559 		User::Leave(KErrServerBusy);
       
   560 		}
       
   561 
       
   562 	iConnectionClientCount = 0;
       
   563 	iDPEnumCount = &iConnectionClientCount;
       
   564 	iConnectionClientBuf.Close();
       
   565 	
       
   566 	iDPEnumBuf = &iConnectionClientBuf;
       
   567 	RequestDataPlaneEnumerationL(EAll);
       
   568 	}
       
   569 
       
   570 
       
   571 /**
       
   572 Returns information about a single connection client that was previously
       
   573 enumerated using EnumerateConnectionClientsL
       
   574 
       
   575 This is the server-side implementation of the RConnection
       
   576 function TInt GetConnectionClientInfo(TUint aIndex, TDes8& aClientInfo).
       
   577 */
       
   578 void AConnectionLegacy::GetConnectionClientInfoL()
       
   579 	{
       
   580 	LOG(ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy::GetConnectionClientInfoL()")));
       
   581 	TConnectionGetClientInfoArg args;
       
   582 	TUint8 ourVersion = args.Version();
       
   583 
       
   584 	const RSafeMessage& message(iConnection.SafeMessage());
       
   585 	TPckg<TConnectionGetClientInfoArg> argsPckg(args);
       
   586 	message.ReadL(2, argsPckg);
       
   587 
       
   588 	// check that the client argument's version is the same as the one we're using
       
   589 	if(args.Version() != ourVersion)
       
   590 		{
       
   591 		LOG( ESockLog::Printf(KESockConnectionTag, _L("AConnectionLegacy: Invalid version of argument to GetConnectionClientInfo (client ver=%d, esock ver=%d)"), args.Version(), ourVersion) );
       
   592 		User::Leave(KErrArgument);
       
   593 		}
       
   594 
       
   595 	TConnectionClientInfo clientInfo;
       
   596 	TPckg<TConnectionClientInfo> info(clientInfo);
       
   597 	ExtractEnumInfoL(iConnectionClientBuf, iConnectionClientCount, sizeof(TConnectionClientInfo), argsPckg().iIndex, info);
       
   598 
       
   599 	argsPckg().iClientInfo = info();
       
   600 	message.WriteL(2, argsPckg);
       
   601 	LOG(ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy [this=%08x] GetConnectionClientInfoL message (%08X) with KErrNone"), &iConnection, message.Handle()));
       
   602 	message.Complete(KErrNone);
       
   603 	}
       
   604 
       
   605 /**
       
   606 Gather information on the number of sockets of a particular connection
       
   607 
       
   608 This is the server-side implementation of the RConnection
       
   609 function TInt EnumerateConnectionSockets(TUint aIndex, TUint& aCount).
       
   610 */
       
   611 void AConnectionLegacy::EnumerateConnectionSocketsL()
       
   612 	{
       
   613 	LOG(ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy::EnumerateConnectionSocketsL")));
       
   614 	// Cover the remote case that another client thread is already enumerating the connection in a similar way - when it all
       
   615 	// completed synchronously in the same thread there was no possibility of this problem. Attempting the same queue behaviour
       
   616 	// here seems pointless: it's a very rare case of a rare case of a deprecated API which was never documented as working
       
   617 	// that way. So instead we complete the client with KErrServerBusy
       
   618 	if(!iEnumConnMsg.IsNull())
       
   619 		{
       
   620 		User::Leave(KErrServerBusy);
       
   621 		}
       
   622 
       
   623 	// delete any previous connection client enumeration info
       
   624 	iConnectionSocketCount = 0;
       
   625 	iDPEnumCount = &iConnectionSocketCount;
       
   626 	iConnectionSocketBuf.Close();
       
   627 	
       
   628 	iDPEnumBuf = &iConnectionSocketBuf;
       
   629 	RequestDataPlaneEnumerationL(ESocket);
       
   630 	}
       
   631 
       
   632 /**
       
   633 Returns information about a socket associated with this connection that has
       
   634 been previously enumerated using EnumerateConnectionSocketsL
       
   635 
       
   636 This is the server-side implementation of the RConnection
       
   637 function TInt GetConnectionSocketInfo(TUint aIndex, TDes8& aSockettInfo).
       
   638 */
       
   639 void AConnectionLegacy::GetConnectionSocketInfoL()
       
   640 	{
       
   641 	LOG(ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy::GetConnectionSocketInfoL()")));
       
   642 	TConnectionGetSocketInfoArg args;
       
   643 	TUint8 ourVersion = args.Version();
       
   644 
       
   645 	const RSafeMessage& message(iConnection.SafeMessage());
       
   646 	TPckg<TConnectionGetSocketInfoArg> argsPckg(args);
       
   647 	message.ReadL(2, argsPckg);
       
   648 
       
   649 	if(args.Version() != ourVersion)
       
   650 		{
       
   651 		LOG( ESockLog::Printf(KESockConnectionTag, _L("AConnectionLegacy: Invalid version of argument to GetConnectionSocketInfo (client ver=%d, esock ver=%d)"), args.Version(), ourVersion) );
       
   652 		User::Leave(KErrArgument);
       
   653 		}
       
   654 
       
   655 	TConnectionSocketInfo socketInfo;
       
   656 	TPckg<TConnectionSocketInfo> info(socketInfo);
       
   657 	ExtractEnumInfoL(iConnectionSocketBuf, iConnectionSocketCount, sizeof(TConnectionSocketInfo), argsPckg().iIndex, info);
       
   658 
       
   659 	argsPckg().iSocketInfo = info();
       
   660 	message.WriteL(2, argsPckg);
       
   661 	LOG(ESockLog::Printf(KESockConnectionTag, _L8("AConnectionLegacy [this=%08x] GetConnectionSocketInfoL message (%08X) with KErrNone"), &iConnection, message.Handle()));
       
   662 	message.Complete(KErrNone);
       
   663 	}
       
   664 
       
   665 /**
       
   666 Requests the Data plane to enumerate its subsessions checking for flows belonging to the set of SCPR ids
       
   667 furnished in this request, returning either socket or client info. This is specifically to support the
       
   668 legacy enumerations; no expectation that a more general scheme will ever be needed
       
   669 */
       
   670 void AConnectionLegacy::RequestDataPlaneEnumerationL(TLegacyConnEnumClients aClientType)
       
   671 	{
       
   672 	iEnumConnSockCandidateSCPRs.Reset();
       
   673 	TConnectionEnumArg args;
       
   674 	TUint8 ourVersion = args.Version();
       
   675 
       
   676 	TPckg<TConnectionEnumArg> argsPckg(args);
       
   677 	const RSafeMessage& message(iConnection.SafeMessage());
       
   678 	message.ReadL(2, argsPckg);
       
   679 
       
   680 	if(args.Version() != ourVersion)
       
   681 		{
       
   682 		LOG( ESockLog::Printf(KESockConnectionTag, _L("AConnectionLegacy: Invalid version of argument to EnumerateConnectionSockets (client ver=%d, esock ver=%d)"), args.Version(), ourVersion) );
       
   683 		User::Leave(KErrArgument);
       
   684 		}
       
   685 
       
   686 	TInt index = args.iIndex;
       
   687 
       
   688 	if(index <= 0 || index > iConnectionInfoPtrArray.Count())
       
   689 		{
       
   690 		User::Leave(KErrArgument);
       
   691 		}
       
   692 
       
   693 	index -= 1; // convert from client index (starting from 1) to server index (starting from 0)
       
   694 
       
   695 	TSourcedConnectionInfo* connInfo;
       
   696 	connInfo = iConnectionInfoPtrArray[index];
       
   697 
       
   698 	/**
       
   699 	   For each CSockSubSession which is a connection, check if it uses the cpr identified in conninfo. If so add that connection as
       
   700 	   a client (for EAll) and add any scprs to the scpr candidate list to be sent to the data plane.
       
   701 
       
   702 	   Then query the data plane for CSockets and CHostResolvers. These are matched to the connection by the scprs in the candidate list
       
   703 	*/	   
       
   704 	CPlayer::TSubSessionContainer& subSess = iConnection.Player().SubSessions();
       
   705 	for(TInt idx = subSess.Count() - 1; idx >=0; --idx)
       
   706 		{
       
   707 		TBool isClient = EFalse;
       
   708 		
       
   709 		const CSockSubSession* ss = static_cast<const CSockSubSession*>(subSess[idx]);
       
   710 		if(ss->Type().iType == TCFSubSessInfo::EConnection)
       
   711 			{
       
   712 			const CConnection* conn = static_cast<const CConnection*>(ss);
       
   713 			
       
   714 			RNodeInterface* ipcprItf = conn->ServiceProvider();
       
   715 			
       
   716 			if(ipcprItf != NULL)
       
   717 				{
       
   718 				ACFMMNodeIdBase& ipcpr = static_cast<ACFMMNodeIdBase&>(ipcprItf->RecipientId().Node());
       
   719 
       
   720 				RNodeInterface* lowerCprItf = ipcpr.ServiceProvider();
       
   721 				while (lowerCprItf)
       
   722 					{
       
   723 					if(lowerCprItf->RecipientId() == connInfo->Provider())
       
   724 						{
       
   725 						isClient = ETrue;
       
   726 						break;
       
   727 						}
       
   728 					
       
   729 					ACFMMNodeIdBase& lowerCpr = static_cast<ACFMMNodeIdBase&>(lowerCprItf->RecipientId().Node());
       
   730 					lowerCprItf = lowerCpr.ServiceProvider();
       
   731 					}
       
   732 				
       
   733 				if (isClient)
       
   734 					{
       
   735 					// Add to client list
       
   736 					if (aClientType == EAll)
       
   737 						{
       
   738 						TConnectionClientInfo info;
       
   739 						TUidType uidType;
       
   740 						ss->GetOwnerInfo(info.iProcessId, uidType, info.iThreadId);
       
   741 						info.iUid = uidType.MostDerived();
       
   742 						RBuf8& resDes = *iDPEnumBuf;
       
   743 						
       
   744 						if (!AConnectionLegacy::DoesConnectionInfoExist(resDes, info))
       
   745 							{
       
   746 							const TUint KEntrySize = sizeof(TConnectionClientInfo);
       
   747 							if (resDes.Length() + KEntrySize > resDes.MaxLength())
       
   748 								{
       
   749 								resDes.ReAllocL(resDes.Length() + KEntrySize);
       
   750 								}
       
   751 
       
   752 							resDes.Append(reinterpret_cast<TUint8*>(&info), sizeof(info));
       
   753 							++(*iDPEnumCount);
       
   754 							}
       
   755 						}
       
   756 
       
   757 					// Build the list of candidate SCPR ids for the data plane to check against
       
   758 					TClientIter<TDefaultClientMatchPolicy> scprIter = ipcpr.GetClientIter<TDefaultClientMatchPolicy>(TClientType(TCFClientType::EData, 0));
       
   759 					RNodeInterface* scpr;
       
   760 					while((scpr = scprIter++) != NULL)
       
   761 						{
       
   762 						iEnumConnSockCandidateSCPRs.AppendL(scpr->RecipientId());
       
   763 						}
       
   764 					}
       
   765 				}
       
   766 			}
       
   767 		}
       
   768 
       
   769 	if(!iEnumConnSockCandidateSCPRs.Count())
       
   770 		{
       
   771 		// Failed to find the lower CPR; most likely it was torn down since the enumeration
       
   772 		User::Leave(KErrNotReady);
       
   773 		}
       
   774 
       
   775 	iEnumConnMsg.Adopt(static_cast<Den::RSafeMessage&>(const_cast<RSafeMessage&>(iConnection.SafeMessage())));
       
   776 
       
   777 	RNodeInterface::OpenPostMessageClose(iConnection.Id(), SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::EDataPlane)),
       
   778 		TLegacyConnectionEnumRequest(iEnumConnSockCandidateSCPRs, aClientType));
       
   779 	}
       
   780 
       
   781 /**
       
   782 Called when the Data plane returns the result of a flow enumeration, requested through RequestDataPlaneEnumerationL()
       
   783 */
       
   784 void AConnectionLegacy::CompleteDataPlaneEnumeration(const TNodeId& aPeer, TInt aCount, HBufC8* aInfo, TInt aError)
       
   785 	{
       
   786 	iEnumConnSockCandidateSCPRs.Reset();
       
   787 	if(aError == KErrNone)
       
   788 		{
       
   789 		__ASSERT_DEBUG(iDPEnumBuf, User::Panic(KSpecAssert_ESockSSockscnLgc, 7));
       
   790 
       
   791 		/**
       
   792 		   Merge the results from the dataplane with the results from
       
   793 		   this plane if we are enumerating all connection clients.
       
   794 		*/		
       
   795 		if (iEnumConnMsg.Int1() == KCoEnumerateConnectionClients)
       
   796 			{
       
   797 			RBuf8& resDes = *iDPEnumBuf;
       
   798 			TConnectionClientInfo info;
       
   799 			TPckg<TConnectionClientInfo> des(info);
       
   800 			
       
   801 			const TUint KEntrySize = sizeof(TConnectionClientInfo);
       
   802 			ASSERT((aCount * KEntrySize) == aInfo->Length());
       
   803 			const TUint8* ptr = aInfo->Ptr();
       
   804 			for (TInt i = 0; i < aCount && aError == KErrNone; i++)
       
   805 				{
       
   806 				des.Copy(ptr, KEntrySize);
       
   807 				if (!DoesConnectionInfoExist(resDes, info))
       
   808 					{
       
   809 					aError = resDes.ReAlloc(resDes.Length()+KEntrySize);
       
   810 					if (aError == KErrNone)
       
   811 						{
       
   812 						resDes.Append(des);
       
   813 						(*iDPEnumCount)++;
       
   814 						}
       
   815 					}
       
   816 				ptr += KEntrySize;
       
   817 				}
       
   818 			}
       
   819 		else
       
   820 			{
       
   821 			*iDPEnumCount += aCount;
       
   822 			aError = iDPEnumBuf->ReAlloc(iDPEnumBuf->Length() + aInfo->Length());
       
   823 			iDPEnumBuf->Append(*aInfo);
       
   824 			}
       
   825 		}
       
   826 	if(aError == KErrNone)
       
   827 		{
       
   828 		TConnectionEnumArg args;
       
   829 		args.iCount = *iDPEnumCount;
       
   830 		TPckg<TConnectionEnumArg> argsPckg(args);
       
   831 		aError = iEnumConnMsg.Read(2, argsPckg);
       
   832 		if (aError == KErrNone)
       
   833 			{
       
   834 			
       
   835 			argsPckg().iCount = *iDPEnumCount;
       
   836 			aError = iEnumConnMsg.Write(2, argsPckg);
       
   837 			}
       
   838 		}
       
   839 
       
   840 	iEnumConnMsg.Complete(aError);
       
   841 	THeapSwitcher switcher(SockManGlobals::Get()->SelfWorker()->PitBoss(), aPeer);
       
   842 	delete aInfo;
       
   843 	}
       
   844 
       
   845 
       
   846 /**
       
   847 Retrieve a TBool parameter setting.
       
   848 */
       
   849 void AConnectionLegacy::GetBoolSettingL(const Den::RSafeMessage& aMessage)
       
   850 	{
       
   851 	TMCprGetConnectionSetting msg(TMCprGetConnectionSetting::EBoolSetting, aMessage);
       
   852 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), msg);
       
   853 	iConnection.DontCompleteCurrentRequest();
       
   854 	}
       
   855 
       
   856 
       
   857 /**
       
   858 Retrieve a TUint32 parameter setting.
       
   859 */
       
   860 void AConnectionLegacy::GetIntSettingL(const Den::RSafeMessage& aMessage)
       
   861 	{
       
   862 	TMCprGetConnectionSetting msg(TMCprGetConnectionSetting::EIntSetting, aMessage);
       
   863 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), msg);
       
   864 	iConnection.DontCompleteCurrentRequest();
       
   865 	}
       
   866 
       
   867 
       
   868 /**
       
   869 Retrieve a TDes8 parameter setting.
       
   870 */
       
   871 void AConnectionLegacy::GetDes8SettingL(const Den::RSafeMessage& aMessage)
       
   872 	{
       
   873 	TMCprGetConnectionSetting msg(TMCprGetConnectionSetting::EDes8Setting, aMessage);
       
   874 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), msg);
       
   875 	iConnection.DontCompleteCurrentRequest();
       
   876 	}
       
   877 
       
   878 
       
   879 /**
       
   880 Retrieve a TDes16 parameter setting.
       
   881 */
       
   882 void AConnectionLegacy::GetDes16SettingL(const Den::RSafeMessage& aMessage)
       
   883 	{
       
   884 	TMCprGetConnectionSetting msg(TMCprGetConnectionSetting::EDes16Setting, aMessage);
       
   885 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), msg);
       
   886 	iConnection.DontCompleteCurrentRequest();
       
   887 	}
       
   888 
       
   889 
       
   890 /**
       
   891 Retrieve a Long TDes parameter setting.
       
   892 */
       
   893 void AConnectionLegacy::GetLongDesSettingL(const Den::RSafeMessage& aMessage)
       
   894 	{
       
   895 	TMCprGetConnectionSetting msg(TMCprGetConnectionSetting::ELongDesSetting, aMessage);
       
   896 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), msg);
       
   897 	iConnection.DontCompleteCurrentRequest();
       
   898 	}
       
   899 
       
   900 
       
   901 
       
   902 void AConnectionLegacy::InterfaceStateChangeNotification(TDesC8& /*aInfo*/)
       
   903 	{
       
   904 	//[399TODO] implement InterfaceStateChangeNotification
       
   905 	LOG(ESockLog::Printf(KESockConnectionTag, _L8("TODO: implement InterfaceStateChangeNotification - KErrNotSupported")));
       
   906 #if TODO_IMPLEMENT_THIS
       
   907 	TInterfaceNotification& interfaceNotification = ((TInterfaceNotificationBuf&)aInfo)();
       
   908 
       
   909 	if(iAllInterfaceNotificationMessage.IsNull())
       
   910 		{
       
   911 		iInterfaceChangeQueue.Enque(interfaceNotification);
       
   912 		return;
       
   913 		}
       
   914 	else // request is outstanding
       
   915 		{
       
   916 		if(!iInterfaceChangeQueue.IsEmpty())
       
   917 			{
       
   918 			// can this situation ever happen?
       
   919 			// - new requests fullfilled from queue before becoming outstanding
       
   920 			// - no queued items when request outstanding
       
   921 
       
   922 			// But in case we do...
       
   923 			// should we get oldest change first in case this new one overwrites it
       
   924 			iInterfaceChangeQueue.Enque(interfaceNotification);
       
   925 			iInterfaceChangeQueue.Deque(interfaceNotification);
       
   926 			}
       
   927 
       
   928 		TInt ret = iAllInterfaceNotificationMessage.Write(0, aInfo);
       
   929 		CompleteMessage(iAllInterfaceNotificationMessage, ret);
       
   930 		}
       
   931 #endif
       
   932 	}
       
   933 
       
   934 void AConnectionLegacy::SubConnectionEvent(const TSubConnectionEvent& aSubConnectionEvent)
       
   935 	{
       
   936 	// Pass the message onto the client if possible, or buffer if necessary
       
   937 	if(!iAllSubConnectionNotificationMessage.IsNull())
       
   938 		{
       
   939 		LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tdelivering new subconnection event to client (subconnection id: %d, event: %d)"), this, aSubConnectionEvent.iSubConnectionUniqueId, aSubConnectionEvent.iEventType));
       
   940 
       
   941 		TPtrC8 tempDes(reinterpret_cast<const TUint8*>(&aSubConnectionEvent), aSubConnectionEvent.Length());
       
   942 		TSubConnectionNotificationBuf subConnectionEventBuf(tempDes);
       
   943 		TInt ret = iAllSubConnectionNotificationMessage.Write(0, subConnectionEventBuf);
       
   944 		iConnection.CompleteMessage(iAllSubConnectionNotificationMessage,ret);
       
   945 		}
       
   946 	else	// no outstanding client messages - just buffer it
       
   947 		{
       
   948 		LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tbuffering new subconnection event (subconnection id: %d, event: %d)"), this, aSubConnectionEvent.iSubConnectionUniqueId, aSubConnectionEvent.iEventType));
       
   949 
       
   950 		// Create copy of event on heap
       
   951 		TSubConnectionEvent* subConnectionEvent = 0;
       
   952 		TRAPD(ret, subConnectionEvent = aSubConnectionEvent.CloneL());
       
   953 
       
   954 		if(ret)	// if there's an error, write a message to the log - not much else we can do
       
   955 			{
       
   956 			LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tERROR - could not enque new subconnection event, error %d (subconnection id: %d, event: %d)"), this, ret, aSubConnectionEvent.iSubConnectionUniqueId, aSubConnectionEvent.iEventType));
       
   957 			}
       
   958 		else
       
   959 			{
       
   960 			if (iSubConnectionEventQueue.IsFull())
       
   961 			    {
       
   962 			    TSubConnectionEvent*& oldestSubConnectionEvent = iSubConnectionEventQueue.GetTheOldestElem();
       
   963 			    LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tSubConnectionEvent - removing oldest subconnection event: %08x)"), this, oldestSubConnectionEvent));
       
   964 			    delete oldestSubConnectionEvent;
       
   965 			    }
       
   966 			LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tSubConnectionEvent - enquing new subconnection event: %08x)"), this, subConnectionEvent));
       
   967 			iSubConnectionEventQueue.Enque(subConnectionEvent);
       
   968 			}
       
   969 		}
       
   970 	}
       
   971 
       
   972 void AConnectionLegacy::AllSubConnectionNotificationL()
       
   973 /**
       
   974 Request for notification of subconnection events
       
   975 @exception Leaves with KErrInUse if there is already an outstanding RMessage for all subconnection notification
       
   976 */
       
   977 	{
       
   978 	LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tClient requested all subconnection notification..."), this));
       
   979 
       
   980 	if(!iAllSubConnectionNotificationMessage.IsNull())
       
   981 		{
       
   982 		iConnection.SetReturn(KErrInUse);
       
   983 		return;
       
   984 		}
       
   985 
       
   986 	if(iSubConnectionEventQueue.IsEmpty())	// if there is nothing in the queue, keep the RMessage
       
   987 		{
       
   988 		LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection[%08x]:\tqueueing request."), this));
       
   989 		iAllSubConnectionNotificationMessage = iConnection.Message();
       
   990     	iConnection.DontCompleteCurrentRequest();
       
   991 		}
       
   992 	else	// otherwise, send back the first item in the queue
       
   993 		{
       
   994 		LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection[%08x]:\tsending back first event from queue."), this));
       
   995 
       
   996 		TSubConnectionEvent* subConnectionEvent = NULL;
       
   997 		iSubConnectionEventQueue.Deque(subConnectionEvent);
       
   998 		LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tAllSubConnectionNotificationL - dequing subconnection event: %08x)"), this, subConnectionEvent));
       
   999 		TPtrC8 tempDes(reinterpret_cast<const TUint8*>(subConnectionEvent), subConnectionEvent->Length());
       
  1000 		TSubConnectionNotificationBuf subConnectionEventBuf(tempDes);
       
  1001 		TInt err = iConnection.Message().Write(0, subConnectionEventBuf);
       
  1002 
       
  1003 		// Delete original copy of event from heap
       
  1004 		delete subConnectionEvent;
       
  1005 		subConnectionEvent=NULL;
       
  1006 
       
  1007 		if(err != KErrNone)
       
  1008 			{
       
  1009 			iConnection.SetReturn(err);
       
  1010 			}
       
  1011 		}
       
  1012 	}
       
  1013 
       
  1014 void AConnectionLegacy::CancelAllSubConnectionNotification()
       
  1015 /**
       
  1016 Complete any outstanding subconnection notification message
       
  1017 */
       
  1018 	{
       
  1019 	LOG(ESockLog::Printf(KESockConnectionTag, _L("CConnection %08x:\tClient cancelled all subconnection notification"), this));
       
  1020 	iDeferredSubConnectionNotificationEnable = EFalse;	// Just in case
       
  1021 	iConnection.CompleteMessage(iAllSubConnectionNotificationMessage, KErrCancel);
       
  1022 	}
       
  1023 
       
  1024 void AConnectionLegacy::GetSubConnectionInfoL(const Den::RSafeMessage& aMessage)
       
  1025 	{
       
  1026 	RNodeInterface* sp = iConnection.ServiceProvider();
       
  1027     if(!sp)
       
  1028 		{
       
  1029 		LOG(ESockLog::Printf(KESockConnectionTag, _L8("CConnection (AConnectionLegacy) [this=%08x] GetSubConnectionInfo KErrNotReady"), &iConnection));
       
  1030         iConnection.SetReturn(KErrNotReady);
       
  1031         return;
       
  1032 		}
       
  1033 
       
  1034 	TInt subConnIdx = static_cast<TInt>(aMessage.Int0());
       
  1035 
       
  1036    	// Find the size of the client's descriptor
       
  1037    	TInt sizeOfSubConnInfo = aMessage.GetDesLengthL(1);
       
  1038 
       
  1039    	// Create an appropriately sized descriptor server-side
       
  1040    	HBufC8* subConnInfoBuf;
       
  1041    	subConnInfoBuf = HBufC8::NewL(sizeOfSubConnInfo);
       
  1042    	CleanupStack::PushL(subConnInfoBuf);
       
  1043 
       
  1044    	TPtr8 subConnInfoPtr(subConnInfoBuf->Des());
       
  1045 
       
  1046    	// Read the client data across
       
  1047 	aMessage.ReadL(1, subConnInfoPtr);
       
  1048 
       
  1049 	TSubConnectionInfo& subConnInfo = *(reinterpret_cast<TSubConnectionInfo*>(const_cast<TUint8*>(subConnInfoBuf->Ptr())));
       
  1050 
       
  1051 	if(subConnInfo.iConnectionType != EConnectionGeneric)
       
  1052 		{
       
  1053 		CleanupStack::PopAndDestroy(subConnInfoBuf);
       
  1054 		iConnection.SetReturn(KErrArgument);
       
  1055 		return;
       
  1056 		}
       
  1057 
       
  1058 	switch(subConnIdx)
       
  1059 		{
       
  1060 		case KNifEMCompatibilityLayerEntireSubConnectionUid:
       
  1061 			if(subConnInfo.iSubConnectionUniqueId != KNifEMCompatibilityLayerEntireSubConnectionUid &&
       
  1062 			   subConnInfo.iSubConnectionUniqueId != KNifEMCompatibilityLayerFakeSubConnectionId)
       
  1063 				{
       
  1064 				CleanupStack::PopAndDestroy(subConnInfoBuf);
       
  1065 				iConnection.SetReturn(KErrArgument);
       
  1066 				return;
       
  1067 				}			
       
  1068 			break;
       
  1069 
       
  1070 		case KNifEMCompatibilityLayerFakeSubConnectionId:
       
  1071 		default:
       
  1072 			subConnInfo.iSubConnectionUniqueId = KNifEMCompatibilityLayerFakeSubConnectionId;
       
  1073 
       
  1074 			break;
       
  1075 		}
       
  1076 
       
  1077 	TLegacyGetSubConnectionInfo msg(iConnection.UniqueId(), subConnInfo, aMessage);
       
  1078 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), msg);
       
  1079 	iConnection.DontCompleteCurrentRequest();
       
  1080 
       
  1081 	CleanupStack::PopAndDestroy(subConnInfoBuf);
       
  1082 	}
       
  1083 
       
  1084 void AConnectionLegacy::DataTransferredL(const RSafeMessage& aMessage)
       
  1085 	{
       
  1086 	TLegacyDataMonitoringTransferredRequest dmReq(iConnection.UniqueId(), aMessage);
       
  1087 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), dmReq);
       
  1088 	iConnection.DontCompleteCurrentRequest();
       
  1089 	}
       
  1090 
       
  1091 void AConnectionLegacy::DataSentNotificationRequestL(const RSafeMessage& aMessage)
       
  1092 	{
       
  1093 	DataMonitoringNotificationRequestL(aMessage, ESent);
       
  1094 	}
       
  1095 
       
  1096 void AConnectionLegacy::DataReceivedNotificationRequestL(const RSafeMessage& aMessage)
       
  1097 	{
       
  1098 	DataMonitoringNotificationRequestL(aMessage, EReceived);
       
  1099 	}
       
  1100 
       
  1101 void AConnectionLegacy::DataMonitoringNotificationRequestL(const RSafeMessage& aMessage, TDataMonitoringDirection aDirection)
       
  1102 	{
       
  1103 	TLegacyDataMonitoringNotificationRequest dmReq(aDirection, iConnection.UniqueId(), aMessage);
       
  1104 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), dmReq);
       
  1105 	iConnection.DontCompleteCurrentRequest();
       
  1106 	}
       
  1107 
       
  1108 
       
  1109 void AConnectionLegacy::DataSentNotificationCancel(const Den::RSafeMessage& aMessage)
       
  1110 	{
       
  1111 	DataMonitoringNotificationCancel(aMessage, ESent);
       
  1112 	}
       
  1113 
       
  1114 void AConnectionLegacy::DataReceivedNotificationCancel(const Den::RSafeMessage& aMessage)
       
  1115 	{
       
  1116 	DataMonitoringNotificationCancel(aMessage, EReceived);
       
  1117 	}
       
  1118 
       
  1119 void AConnectionLegacy::DataMonitoringNotificationCancel(const Den::RSafeMessage& aMessage, TDataMonitoringDirection aDirection)
       
  1120 	{
       
  1121 	const RPointerArray<CNodeActivityBase>& activities = iConnection.Activities();
       
  1122 	TBool cancelled = EFalse;
       
  1123 	for (TInt i = 0; i < activities.Count(); i++)
       
  1124 		{
       
  1125 		if (activities[i]->ActivitySigId() == ESock::ECFActivityConnectionLegacyRMessage2Handler)
       
  1126 			{
       
  1127 			ConnActivities::CConnLegacyRMessage2Activity* act = static_cast<ConnActivities::CConnLegacyRMessage2Activity*>(activities[i]);
       
  1128 
       
  1129 			ASSERT(act->Message().IsTypeOf(Meta::STypeId::CreateSTypeId(TCFSigLegacyRMessage2Ext::EUid, TCFSigLegacyRMessage2Ext::ETypeId)));
       
  1130 			ESock::TCFSigLegacyRMessage2Ext& msg = static_cast<TCFSigLegacyRMessage2Ext&>(act->Message());
       
  1131 
       
  1132 			if (act->iSafeMessage.Function() == ESCPSDataSentNotificationRequest
       
  1133 				|| act->iSafeMessage.Function() == ESCPSDataReceivedNotificationRequest)
       
  1134 				{
       
  1135 				TLegacyDataMonitoringNotificationRequest& dmmsg = static_cast<TLegacyDataMonitoringNotificationRequest&>(msg);
       
  1136 
       
  1137 				if (act->iSafeMessage.Int0() == aMessage.Int0()
       
  1138 					&& dmmsg.iDirection == aDirection)
       
  1139 					{
       
  1140 					ASSERT(iConnection.UniqueId() == dmmsg.iClientId);
       
  1141 					act->SetCancelRequest(aMessage);
       
  1142 					iConnection.CMMSockSubSession::ReceivedL(act->iSafeMessage.Function(), TEBase::TCancel().CRef());
       
  1143 					iConnection.DontCompleteCurrentRequest();
       
  1144 					cancelled = ETrue;
       
  1145 					}
       
  1146 				}
       
  1147 			}
       
  1148 		}
       
  1149 	if (!cancelled)
       
  1150 		{
       
  1151 		if (aMessage.Int0() == KNifEMCompatibilityLayerEntireSubConnectionUid && !iConnection.ServiceProvider())
       
  1152 			{
       
  1153 			iConnection.SetReturn(KErrNotReady);
       
  1154 			}
       
  1155 		else if (aMessage.Int0() == KNifEMCompatibilityLayerFakeSubConnectionId && !iConnection.DefaultSubConnectionServiceProvider())
       
  1156 			{
       
  1157 			iConnection.SetReturn(KErrNotReady);
       
  1158 			}
       
  1159 		else
       
  1160 			{
       
  1161 			LOG(ESockLog::Printf(KESockConnectionTag,
       
  1162 					_L8("CConnectionLegacy(%08x)::DataMonitoringNotificationCancel - direction %d - client return set to %d. Bad subconnection id. (%d) specified."),
       
  1163 					this, aDirection, KErrArgument, aMessage.Int0()));
       
  1164 			
       
  1165 			iConnection.SetReturn(KErrArgument);
       
  1166 			}
       
  1167 		}
       
  1168 	}
       
  1169 
       
  1170 void AConnectionLegacy::IsSubConnectionActiveRequestL(const Den::RSafeMessage& aMessage)
       
  1171 	{
       
  1172 	TInt subConnUniqueId = aMessage.Int0();
       
  1173 	
       
  1174 	switch(subConnUniqueId)
       
  1175 		{
       
  1176 	case KNifEMCompatibilityLayerEntireSubConnectionUid:
       
  1177 		if(!iConnection.ServiceProvider())
       
  1178 			{
       
  1179 			iConnection.SetReturn(KErrNotReady);
       
  1180 			return;
       
  1181 			}
       
  1182 		break;
       
  1183 	case KNifEMCompatibilityLayerFakeSubConnectionId:
       
  1184 		if(!iConnection.DefaultSubConnectionServiceProvider())
       
  1185 			{
       
  1186 			iConnection.SetReturn(KErrNotReady);
       
  1187 			return;
       
  1188 			}
       
  1189 		break;
       
  1190     default:
       
  1191 		iConnection.SetReturn(KErrArgument);
       
  1192 		return;
       
  1193 		}
       
  1194 
       
  1195 	const RPointerArray<CNodeActivityBase>& activities = iConnection.Activities();
       
  1196 	for (TInt i = 0; i < activities.Count(); i++)
       
  1197 		{
       
  1198 		if (activities[i]->ActivitySigId() == ESock::ECFActivityConnectionLegacyRMessage2Handler)
       
  1199 			{
       
  1200 			ConnActivities::CConnLegacyRMessage2Activity* act = static_cast<ConnActivities::CConnLegacyRMessage2Activity*>(activities[i]);
       
  1201 			
       
  1202 			if (act->iSafeMessage.Function() == ESCPSIsSubConnectionActiveRequest
       
  1203 				&& act->iSafeMessage.Int0() == aMessage.Int0())
       
  1204 				{
       
  1205 				iConnection.SetReturn(KErrInUse);
       
  1206 				return;
       
  1207 				}
       
  1208 			}
       
  1209 		}
       
  1210 
       
  1211 	TLegacySubConnectionActiveRequest msg(iConnection.UniqueId(), aMessage);
       
  1212 	iConnection.CMMSockSubSession::ReceivedL(aMessage.Function(), msg);
       
  1213 	iConnection.DontCompleteCurrentRequest();
       
  1214 	}
       
  1215 
       
  1216 void AConnectionLegacy::IsSubConnectionActiveCancel(const Den::RSafeMessage& aMessage)
       
  1217 	{
       
  1218 	const RPointerArray<CNodeActivityBase>& activities = iConnection.Activities();
       
  1219 	TBool cancelled = EFalse;
       
  1220 	for (TInt i = 0; i < activities.Count(); i++)
       
  1221 		{
       
  1222 		if (activities[i]->ActivitySigId() == ESock::ECFActivityConnectionLegacyRMessage2Handler)
       
  1223 			{
       
  1224 			ConnActivities::CConnLegacyRMessage2Activity* act = static_cast<ConnActivities::CConnLegacyRMessage2Activity*>(activities[i]);
       
  1225 			
       
  1226 			if (act->iSafeMessage.Function() == ESCPSIsSubConnectionActiveRequest
       
  1227 				&& act->iSafeMessage.Int0() == aMessage.Int0())
       
  1228 				{
       
  1229 				act->SetCancelRequest(aMessage);
       
  1230 				iConnection.CMMSockSubSession::ReceivedL(act->iSafeMessage.Function(), TEBase::TCancel().CRef());
       
  1231 				iConnection.DontCompleteCurrentRequest();
       
  1232 				cancelled = ETrue;
       
  1233 				}
       
  1234 			}
       
  1235 		}
       
  1236 	if (!cancelled)
       
  1237 		{
       
  1238 		iConnection.SetReturn(KErrArgument);
       
  1239 		}	
       
  1240 	}
       
  1241 
       
  1242 TBool AConnectionLegacy::DoesConnectionInfoExist(const TDesC8& aInfoBuf, const TConnectionClientInfo& aInfo)
       
  1243 	{
       
  1244 	TConnectionClientInfo info;
       
  1245 	TPckg<TConnectionClientInfo> des(info);
       
  1246 	const TUint KEntrySize = sizeof(TConnectionClientInfo);
       
  1247 	const TUint8* ptr = aInfoBuf.Ptr();
       
  1248 	const TUint8* end = ptr + aInfoBuf.Length();
       
  1249 	while(ptr < end)
       
  1250 		{
       
  1251 		__ASSERT_DEBUG((end - ptr) >= KEntrySize, User::Panic(KSpecAssert_ESockSSockscnLgc, 8));	// array size is multiple of element size
       
  1252 		des.Copy(ptr, KEntrySize);
       
  1253 		if(info.iProcessId == aInfo.iProcessId && info.iUid == aInfo.iUid && info.iThreadId == aInfo.iThreadId)
       
  1254 			{
       
  1255 			return ETrue;
       
  1256 			}
       
  1257 		ptr += KEntrySize;
       
  1258 		}
       
  1259 	return EFalse;
       
  1260 	}
       
  1261