accessoryservices/remotecontrolfw/server/src/server.cpp
changeset 70 653a8b91b95e
parent 35 f7565e9c9ce8
equal deleted inserted replaced
64:61992147389a 70:653a8b91b95e
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    24 #include <remcon/remcontargetselectorplugin.h>
    24 #include <remcon/remcontargetselectorplugin.h>
    25 #include <remcon/remcontargetselectorplugininterface.h>
    25 #include <remcon/remcontargetselectorplugininterface.h>
    26 #include <remcon/remconbearerinterface.h>
    26 #include <remcon/remconbearerinterface.h>
    27 #include <remcon/remconbearerbulkinterface.h>
    27 #include <remcon/remconbearerbulkinterface.h>
    28 #include "server.h"
    28 #include "server.h"
    29 #include "session.h"
    29 #include "targetclientprocess.h"
       
    30 #include "controllersession.h"
       
    31 #include "targetsession.h"
    30 #include "serversecuritypolicy.h"
    32 #include "serversecuritypolicy.h"
    31 #include "utils.h"
    33 #include "utils.h"
    32 #include "bearermanager.h"
    34 #include "bearermanager.h"
    33 #include "messagequeue.h"
    35 #include "messagequeue.h"
    34 #include "convertermanager.h"
    36 #include "convertermanager.h"
    42 #endif
    44 #endif
    43 
    45 
    44 PANICCATEGORY("server");
    46 PANICCATEGORY("server");
    45 
    47 
    46 #ifdef __FLOG_ACTIVE
    48 #ifdef __FLOG_ACTIVE
    47 #define LOGSESSIONS							LogSessions()
    49 #define LOGCONTROLLERSESSIONS				LogControllerSessions()
       
    50 #define LOGTARGETSESSIONS					LogTargetSessions()
    48 #define LOGREMOTES							LogRemotes()
    51 #define LOGREMOTES							LogRemotes()
    49 #define LOGCONNECTIONHISTORYANDINTEREST		LogConnectionHistoryAndInterest()
    52 #define LOGCONNECTIONHISTORYANDINTEREST		LogConnectionHistoryAndInterest()
    50 #define LOGOUTGOINGCMDPENDINGTSP			LogOutgoingCmdPendingTsp()
    53 #define LOGOUTGOINGCMDPENDINGTSP			LogOutgoingCmdPendingTsp()
    51 #define LOGOUTGOINGNOTIFYCMDPENDINGTSP		LogOutgoingNotifyCmdPendingTsp()
    54 #define LOGOUTGOINGNOTIFYCMDPENDINGTSP		LogOutgoingNotifyCmdPendingTsp()
    52 #define LOGOUTGOINGRSPPENDINGTSP			LogOutgoingRspPendingTsp()
    55 #define LOGOUTGOINGRSPPENDINGTSP			LogOutgoingRspPendingTsp()
    56 #define LOGINCOMINGNOTIFYCMDPENDINGADDRESS		LogIncomingNotifyCmdPendingAddress()
    59 #define LOGINCOMINGNOTIFYCMDPENDINGADDRESS		LogIncomingNotifyCmdPendingAddress()
    57 #define LOGINCOMINGNOTIFYCMDPENDINGREADDRESS	LogIncomingNotifyCmdPendingReAddress()
    60 #define LOGINCOMINGNOTIFYCMDPENDINGREADDRESS	LogIncomingNotifyCmdPendingReAddress()
    58 #define LOGINCOMINGPENDINGDELIVERY			LogIncomingPendingDelivery()
    61 #define LOGINCOMINGPENDINGDELIVERY			LogIncomingPendingDelivery()
    59 #define LOGINCOMINGDELIVERED				LogIncomingDelivered()
    62 #define LOGINCOMINGDELIVERED				LogIncomingDelivered()
    60 #else
    63 #else
    61 #define LOGSESSIONS
    64 #define LOGCONTROLLERSESSIONS
       
    65 #define LOGTARGETSESSIONS
    62 #define LOGREMOTES
    66 #define LOGREMOTES
    63 #define LOGCONNECTIONHISTORYANDINTEREST
    67 #define LOGCONNECTIONHISTORYANDINTEREST
    64 #define LOGOUTGOINGCMDPENDINGTSP
    68 #define LOGOUTGOINGCMDPENDINGTSP
    65 #define LOGOUTGOINGNOTIFYCMDPENDINGTSP
    69 #define LOGOUTGOINGNOTIFYCMDPENDINGTSP
    66 #define LOGOUTGOINGRSPPENDINGTSP
    70 #define LOGOUTGOINGRSPPENDINGTSP
    72 #define LOGINCOMINGPENDINGDELIVERY
    76 #define LOGINCOMINGPENDINGDELIVERY
    73 #define LOGINCOMINGDELIVERED
    77 #define LOGINCOMINGDELIVERED
    74 #endif // __FLOG_ACTIVE
    78 #endif // __FLOG_ACTIVE
    75 
    79 
    76 TInt BulkMain(TAny* aParam);
    80 TInt BulkMain(TAny* aParam);
       
    81 TBool ControllerSessionCompare(const TUint* aSessionId, const CRemConControllerSession& aSession)
       
    82 	{
       
    83 	return *aSessionId == aSession.Id();
       
    84 	}
       
    85 
       
    86 TBool TargetClientCompareUsingSessionId(const TUint* aClientId, const CRemConTargetClientProcess& aClient)
       
    87 	{
       
    88 	return *aClientId == aClient.Id();
       
    89 	}
       
    90 
       
    91 TBool TargetClientCompareUsingProcessId(const TProcessId* aProcessId, const CRemConTargetClientProcess& aClient)
       
    92 	{
       
    93 	return *aProcessId == aClient.ClientInfo().ProcessId();
       
    94 	}
    77 
    95 
    78 CRemConServer* CRemConServer::NewLC()
    96 CRemConServer* CRemConServer::NewLC()
    79 	{
    97 	{
    80 	LOG_STATIC_FUNC;
    98 	LOG_STATIC_FUNC;
    81 	CRemConServer* self = new(ELeave) CRemConServer();
    99 	CRemConServer* self = new(ELeave) CRemConServer();
    95 	delete iShutdownTimer;
   113 	delete iShutdownTimer;
    96 	
   114 	
    97 	// There should be no watcher as there should be no bulk thread running
   115 	// There should be no watcher as there should be no bulk thread running
    98 	ASSERT_DEBUG(!iBulkThreadWatcher);
   116 	ASSERT_DEBUG(!iBulkThreadWatcher);
    99 
   117 
   100 	iSessionsLock.Wait();
   118 	iControllerSessions.Close();
   101 	iSessions.Close();
   119 
   102 	iSessionsLock.Close();
   120 	iTargetClientsLock.Wait();
       
   121 	iTargetClients.Close();
       
   122 	iTargetClientsLock.Close();
   103 
   123 
   104 	// Destroy TSP before iIncomingPendingAddress in case the TSP is 
   124 	// Destroy TSP before iIncomingPendingAddress in case the TSP is 
   105 	// addressing a message on it at the time.
   125 	// addressing a message on it at the time.
   106 	// The TSP should not be handling outgoing commands or responses as all the sessions 
   126 	// The TSP should not be handling outgoing commands or responses as all the sessions 
   107 	// have gone, and they clean up their outgoing messages when they close.
   127 	// have gone, and they clean up their outgoing messages when they close.
   176 void CRemConServer::ConstructL()
   196 void CRemConServer::ConstructL()
   177 	{
   197 	{
   178 	LOG_FUNC;
   198 	LOG_FUNC;
   179 	// Open ECOM session.
   199 	// Open ECOM session.
   180 	iEcom = &(REComSession::OpenL());
   200 	iEcom = &(REComSession::OpenL());
   181 	LEAVEIFERRORL(iSessionsLock.CreateLocal());
   201 	LEAVEIFERRORL(iTargetClientsLock.CreateLocal());
   182 
   202 
   183 	iShutdownTimer = CPeriodic::NewL(CActive::EPriorityStandard);
   203 	iShutdownTimer = CPeriodic::NewL(CActive::EPriorityStandard);
   184 
   204 
   185 	// Make the connection history holder before creating the bearer manager, 
   205 	// Make the connection history holder before creating the bearer manager, 
   186 	// as some bearers might call the bearer manager back synchronously with a 
   206 	// as some bearers might call the bearer manager back synchronously with a 
   228 	LOG(KNullDesC8);
   248 	LOG(KNullDesC8);
   229 	LOG_FUNC;
   249 	LOG_FUNC;
   230 	LOG3(_L("\taVersion = (%d,%d,%d)"), aVersion.iMajor, aVersion.iMinor, aVersion.iBuild);
   250 	LOG3(_L("\taVersion = (%d,%d,%d)"), aVersion.iMajor, aVersion.iMinor, aVersion.iBuild);
   231 		
   251 		
   232 	// Version number check...
   252 	// Version number check...
   233 	TVersion v(KRemConSrvMajorVersionNumber,
   253 	if ( aVersion.iMajor != KRemConSrvMajorVersionNumber || aVersion.iMinor != KRemConSrvMinorVersionNumber )
   234 		KRemConSrvMinorVersionNumber,
       
   235 		KRemConSrvBuildNumber);
       
   236 
       
   237 	if ( !User::QueryVersionSupported(v, aVersion) )
       
   238 		{
   254 		{
   239 		LEAVEIFERRORL(KErrNotSupported);
   255 		LEAVEIFERRORL(KErrNotSupported);
   240 		}
   256 		}
   241 
   257 
       
   258 	// We need a non-const copy of ourself so that:
       
   259 	// (a) New target clients may be added to iTargetClients (controller sessions are added to 
       
   260 	// iControllerSessions when ControllerClientOpened() is invoked).
       
   261 	// (b) We may provide new sessions/clients with a non-const pointer to ourself.
   242 	CRemConServer* ncThis = const_cast<CRemConServer*>(this);
   262 	CRemConServer* ncThis = const_cast<CRemConServer*>(this);
   243 	
   263 
   244 	CRemConSession* sess = NULL;
   264 	CRemConSession* sess = NULL;
   245 	ASSERT_DEBUG(iBearerManager);
   265 	ASSERT_DEBUG(iBearerManager);
   246 	TRAPD(err, sess = CRemConSession::NewL(*ncThis, 
   266 
   247 				*iBearerManager, 
   267 	TInt err = KErrNotSupported;	
   248 				aMessage, 
   268 	if (aVersion.iBuild == KRemConSrvControllerSession)
   249 				(ncThis->iSessionId)++)
   269 		{
   250 			);
   270 		TRAP(err, sess = ncThis->CreateControllerSessionL(aMessage));
   251 	if ( err != KErrNone )
   271 		}
       
   272 	else if(aVersion.iBuild == KRemConSrvTargetSession)
       
   273 		{
       
   274 		TRAP(err, sess = ncThis->CreateTargetSessionL(aMessage));
       
   275 		}
       
   276 	
       
   277 	if ( err != KErrNone)
   252 		{
   278 		{
   253 		// Session creation might have failed- if it has we need to check if 
   279 		// Session creation might have failed- if it has we need to check if 
   254 		// we need to shut down again.
   280 		// we need to shut down again.
   255 		const_cast<CRemConServer*>(this)->StartShutdownTimerIfNoSessionsOrBulkThread();
   281 		const_cast<CRemConServer*>(this)->StartShutdownTimerIfNoClientsOrBulkThread();
   256 		LEAVEIFERRORL(err);
   282 		LEAVEIFERRORL(err);
   257 		}
   283 		}
   258 
   284 
   259 	LOG1(_L("\tsess = 0x%08x"), sess);
   285 	LOG1(_L("\tsess = 0x%08x"), sess);
   260 	return sess;
   286 	return sess;
   261 	}
   287 	}
   262 
   288 
   263 void CRemConServer::StartShutdownTimerIfNoSessionsOrBulkThread()
   289 CRemConControllerSession* CRemConServer::CreateControllerSessionL(const RMessage2& aMessage)
   264 	{
   290 	{
   265 	LOG_FUNC;
   291 	LOG_FUNC;
   266 	iSessionsLock.Wait();
   292 
   267 	if ( iSessions.Count() == 0 && !iBulkThreadOpen)
   293 	CRemConControllerSession* sess=NULL;
       
   294 
       
   295 	// Obtain client process ID.
       
   296 	TClientInfo clientInfo;
       
   297 	ClientProcessAndSecureIdL(clientInfo, aMessage);
       
   298 
       
   299 	// Create the session and return
       
   300 	sess = CRemConControllerSession::NewL(*this, *iBearerManager, clientInfo, iSessionOrClientId++);
       
   301 	return sess;
       
   302 	}
       
   303 
       
   304 CRemConTargetSession* CRemConServer::CreateTargetSessionL(const RMessage2& aMessage)
       
   305 	{
       
   306 	LOG_FUNC;
       
   307 
       
   308 	CRemConTargetSession* sess=NULL;
       
   309 	
       
   310 	// Obtain client process ID and search for clients server-side process representation.
       
   311 	TClientInfo clientInfo;
       
   312 	ClientProcessAndSecureIdL(clientInfo, aMessage);
       
   313 
       
   314 	// We search for the client ourselves here as we need to know where it
       
   315 	// is in the array if we end up needing to destroy it.
       
   316 	iTargetClientsLock.Wait();	
       
   317 	CleanupSignalPushL(iTargetClientsLock);
       
   318 
       
   319 	TInt clientIndex = iTargetClients.Find(clientInfo.ProcessId(), TargetClientCompareUsingProcessId);
       
   320 
       
   321 	if (clientIndex == KErrNotFound)
       
   322 		{
       
   323 		// Client is new, create process representation for client and add to iTargetClients 
       
   324 		CRemConTargetClientProcess* newClient = CRemConTargetClientProcess::NewLC(clientInfo, iSessionOrClientId++, *this, *iBearerManager);
       
   325 
       
   326 		iTargetClients.AppendL(newClient);
       
   327 
       
   328 		// Set clientIndex to point to the new client.
       
   329 		clientIndex = iTargetClients.Count()-1;
       
   330 
       
   331 		CleanupStack::Pop(newClient);
       
   332 		}
       
   333 
       
   334 	// Create session on client and return.
       
   335 	// On error, remove the clients process representation if client has no other sessions.
       
   336 	TRAPD(err, sess = iTargetClients[clientIndex]->NewSessionL(iSessionOrClientId++));
       
   337 	if (err)
       
   338 		{
       
   339 		TryToDropClientProcess(clientIndex);
       
   340 		LEAVEL(err);
       
   341 		}
       
   342 
       
   343 	CleanupStack::PopAndDestroy(&iTargetClientsLock);
       
   344 
       
   345 	return sess;
       
   346 	}
       
   347 
       
   348 void CRemConServer::ClientProcessAndSecureIdL(TClientInfo& aClientInfo, const RMessage2& aMessage) const
       
   349 	{
       
   350 	LOG_FUNC;
       
   351 
       
   352 	RThread thread;
       
   353 	LEAVEIFERRORL(aMessage.Client(thread));
       
   354 	CleanupClosePushL(thread);
       
   355 	RProcess process;
       
   356 	LEAVEIFERRORL(thread.Process(process));
       
   357 	aClientInfo.ProcessId() = process.Id();
       
   358 	process.Close();
       
   359 	aClientInfo.SecureId() = thread.SecureId();
       
   360 	CleanupStack::PopAndDestroy(&thread);
       
   361 	}
       
   362 
       
   363 void CRemConServer::StartShutdownTimerIfNoClientsOrBulkThread()
       
   364 	{
       
   365 	LOG_FUNC;
       
   366 	iTargetClientsLock.Wait();
       
   367 	if ( iControllerSessions.Count() == 0 && iTargetClients.Count() == 0 && !iBulkThreadOpen)
   268 		{
   368 		{
   269 		LOG(_L("\tno remaining sessions- starting shutdown timer"));
   369 		LOG(_L("\tno remaining sessions- starting shutdown timer"));
   270 		// Should have been created during our construction.
   370 		// Should have been created during our construction.
   271 		ASSERT_DEBUG(iShutdownTimer);
   371 		ASSERT_DEBUG(iShutdownTimer);
   272 		// Start the shutdown timer. It's actually a CPeriodic- the first 
   372 		// Start the shutdown timer. It's actually a CPeriodic- the first 
   289 		else
   389 		else
   290 			{
   390 			{
   291 			LOG(_L("\tshutdown timer was already active"));
   391 			LOG(_L("\tshutdown timer was already active"));
   292 			}
   392 			}
   293 		}
   393 		}
   294 	iSessionsLock.Signal();
   394 	iTargetClientsLock.Signal();
       
   395 	}
       
   396 
       
   397 void CRemConServer::CancelShutdownTimer()
       
   398 	{
       
   399 	// Should have been created during our construction.		
       
   400 	ASSERT_DEBUG(iShutdownTimer);
       
   401 	iShutdownTimer->Cancel();
       
   402 	}
       
   403 
       
   404 void CRemConServer::TryToDropClientProcess(TUint aClientIndex)
       
   405 	{
       
   406 	ASSERT_DEBUG(iTargetClients.Count() > aClientIndex);
       
   407 	
       
   408 	iTargetClientsLock.Wait();
       
   409 	
       
   410 	CRemConTargetClientProcess* client = iTargetClients[aClientIndex]; 
       
   411 	if (client->TargetSessionCount() == 0)
       
   412 		{
       
   413 		// No sessions held by this client process representation, OK to destroy.
       
   414 		// The destructor of CRemConTargetClientProcess will call back to us, after which we will
       
   415 		// handle the client close.
       
   416 		delete client;
       
   417 		}
       
   418 	
       
   419 	iTargetClientsLock.Signal();
   295 	}
   420 	}
   296 
   421 
   297 TInt CRemConServer::TimerFired(TAny* aThis)
   422 TInt CRemConServer::TimerFired(TAny* aThis)
   298 	{
   423 	{
   299 	LOG_STATIC_FUNC
   424 	LOG_STATIC_FUNC;
   300 	static_cast<void>(aThis);
   425 	static_cast<void>(aThis);
   301 	
   426 	
   302 #if defined(__FLOG_ACTIVE) || defined(_DEBUG)
   427 #if defined(__FLOG_ACTIVE) || defined(_DEBUG)
   303 	CRemConServer* self = static_cast<CRemConServer*>(aThis);
   428 	CRemConServer* self = static_cast<CRemConServer*>(aThis);
   304 	// We should have sent 'this' to this callback. 
   429 	// We should have sent 'this' to this callback. 
   314 	return KErrNone;
   439 	return KErrNone;
   315 	}
   440 	}
   316 
   441 
   317 void CRemConServer::InitialiseBulkServerThreadL()
   442 void CRemConServer::InitialiseBulkServerThreadL()
   318 	{
   443 	{
   319 	LOG_FUNC
   444 	LOG_FUNC;
   320 	// Set up the configuration of the thread
   445 	// Set up the configuration of the thread
   321 	iBulkServerThread.SetPriority(EPriorityLess);
   446 	iBulkServerThread.SetPriority(EPriorityLess);
   322 	
   447 	
   323 	iBulkThreadWatcher = new(ELeave) CBulkThreadWatcher(*this);
   448 	iBulkThreadWatcher = new(ELeave) CBulkThreadWatcher(*this);
   324 	CleanupDeleteAndNullPushL(iBulkThreadWatcher);
   449 	CleanupDeleteAndNullPushL(iBulkThreadWatcher);
   359 	}
   484 	}
   360 
   485 
   361 
   486 
   362 TInt CRemConServer::BulkServerRequired()
   487 TInt CRemConServer::BulkServerRequired()
   363 	{
   488 	{
   364 	LOG_FUNC
   489 	LOG_FUNC;
   365 	// If the bulk server is required then try to create it
   490 	// If the bulk server is required then try to create it
   366 	TThreadFunction bulkServerThreadFunction(BulkMain);
   491 	TThreadFunction bulkServerThreadFunction(BulkMain);
   367 	_LIT(KBulkServerThreadName, "RemConBulkServerThread");
   492 	_LIT(KBulkServerThreadName, "RemConBulkServerThread");
   368 	const TInt KMaxBulkServerThreadHeapSize = 0x100000;
   493 	const TInt KMaxBulkServerThreadHeapSize = 0x100000;
   369 	
   494 	
   381 			}
   506 			}
   382 		}
   507 		}
   383 	return err;
   508 	return err;
   384 	}
   509 	}
   385 
   510 
   386 TInt CRemConServer::ClientOpened(CRemConSession& aSession)
   511 TInt CRemConServer::ControllerClientOpened(CRemConControllerSession& aSession)
   387 	{
   512 	{
   388 	LOG_FUNC;
   513 	LOG_FUNC;
   389 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   514 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   390 	LOGSESSIONS;
   515 	LOGCONTROLLERSESSIONS;
   391 
   516 
   392 	// Register the session by appending it to our array, and also making an 
   517 	// Register the session by appending it to our array, and also making an 
   393 	// item for it in the record of which points in the connection history 
   518 	// item for it in the record of which points in the connection history 
   394 	// sessions are interested in.
   519 	// sessions are interested in.
   395 	iSessionsLock.Wait();
   520 	TInt ret = iControllerSessions.Append(&aSession);
   396 	TInt ret = iSessions.Append(&aSession);
       
   397 	if ( ret == KErrNone )
   521 	if ( ret == KErrNone )
   398 		{
   522 		{
   399 		TSessionPointerToConnectionHistory item;
   523 		TSessionPointerToConnectionHistory item;
   400 		item.iSessionId = aSession.Id();
   524 		item.iSessionId = aSession.Id();
   401 		item.iIndex = 0; // there is always at least one item in the connection history
   525 		item.iIndex = 0; // there is always at least one item in the connection history
   402 		ret = iSession2ConnHistory.Append(item);
   526 		ret = iSession2ConnHistory.Append(item);
   403 		if ( ret != KErrNone )
   527 		if ( ret != KErrNone )
   404 			{
   528 			{
   405 			iSessions.Remove(iSessions.Count() - 1);
   529 			iControllerSessions.Remove(iControllerSessions.Count() - 1);
   406 			}
   530 			}
   407 		}
   531 		}
   408 	iSessionsLock.Signal();
       
   409 
   532 
   410 	if ( ret == KErrNone )
   533 	if ( ret == KErrNone )
   411 		{
   534 		{
   412 		// Should have been created during our construction.
   535 		// Should have been created during our construction.
   413 		ASSERT_DEBUG(iShutdownTimer);
   536 		ASSERT_DEBUG(iShutdownTimer);
   414 		iShutdownTimer->Cancel();
   537 		iShutdownTimer->Cancel();
   415 		}
   538 		}
   416 
   539 
   417 	LOGSESSIONS;
   540 	LOGCONTROLLERSESSIONS;
   418 	LOG1(_L("\tret = %d"), ret);
   541 	LOG1(_L("\tret = %d"), ret);
   419 	return ret;
   542 	return ret;
   420 	}
   543 	}
   421 
   544 
   422 // this function is called by the session when the session type is set
   545 TInt CRemConServer::RegisterTargetSessionPointerToConnHistory(const CRemConTargetSession& aSession)
   423 void CRemConServer::ClientTypeSet(CRemConSession& aSession)
   546 	{
   424 	{
   547 	LOG_FUNC;
   425 	LOG_FUNC;
   548 
   426 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   549 	TSessionPointerToConnectionHistory item;
   427 	LOGSESSIONS;
   550 	item.iSessionId = aSession.Id();
   428 
   551 	item.iIndex = 0; // there is always at least one item in the connection history
   429 	/* When a client (session) has its type set (controller or target) then 
   552 	TInt ret = iSession2ConnHistory.Append(item);
   430 	   it will still have a bearer uid of NullUid. In this case we want to 
   553 
   431 	   update any bearers which now have a controller or target count moving 
   554 	return ret;
   432 	   (from 0) to 1. */
   555 	}
   433 
   556 
   434 	/* tell the bearer manager that someones set a client type
   557 
   435 	   The bearer manager maintains controller and target counts for all bearers
   558 // this function is called by the client when it has registered its features
   436 	   and will tell bearers when they need to know things have changed */
   559 void CRemConServer::TargetClientAvailable(const CRemConTargetClientProcess& aClient)
       
   560 	{
       
   561 	LOG_FUNC;
       
   562 	LOG1(_L("\t&aClient = 0x%08x"), &aClient);
       
   563 	LOGTARGETSESSIONS;
       
   564 
   437 	ASSERT_DEBUG(iBearerManager);
   565 	ASSERT_DEBUG(iBearerManager);
   438 	iBearerManager->ClientTypeSet(aSession.Type() == ERemConClientTypeController);
   566 	iBearerManager->TargetClientAvailable(aClient.Id(), aClient.PlayerType(), aClient.PlayerSubType(), aClient.Name());
   439 
   567 	if(iTspIf5)
   440 	LOGSESSIONS;
   568 		{
   441 	}
   569 		iTspIf5->TargetClientAvailable(aClient.ClientInfo());
   442 
   570 		}
   443 // this function is called by the session when the client has registered its features
   571 
   444 void CRemConServer::TargetClientAvailable(CRemConSession& aSession)
   572 	LOGTARGETSESSIONS;
   445 	{
   573 	}
   446 	LOG_FUNC;
   574 
   447 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   575 void CRemConServer::TargetFeaturesUpdated(CRemConTargetClientProcess& aClient)
   448 	LOGSESSIONS;
   576 	{
       
   577 	LOG_FUNC;
       
   578 	LOG1(_L("\t&aClient = 0x%08x"), &aClient);
       
   579 	LOGTARGETSESSIONS;
   449 
   580 
   450 	ASSERT_DEBUG(iBearerManager);
   581 	ASSERT_DEBUG(iBearerManager);
   451 	iBearerManager->TargetClientAvailable(aSession.Id(), aSession.PlayerType(), aSession.PlayerSubType(), aSession.Name());
   582 	iBearerManager->TargetFeaturesUpdated(aClient.Id(), aClient.PlayerType(), aClient.PlayerSubType(), aClient.Name());
   452 	if(iTspIf5)
   583 
   453 		{
   584 	LOGTARGETSESSIONS;
   454 		iTspIf5->TargetClientAvailable(aSession.ClientInfo());
       
   455 		}
       
   456 
       
   457 	LOGSESSIONS;
       
   458 	}
   585 	}
   459 
   586 
   460 // this function is called by the session when the client has registered its features
   587 // this function is called by the session when the client has registered its features
   461 void CRemConServer::ControllerClientAvailable()
   588 void CRemConServer::ControllerClientAvailable()
   462 	{
   589 	{
   463 	LOG_FUNC;
   590 	LOG_FUNC;
   464 	LOGSESSIONS;
   591 	LOGCONTROLLERSESSIONS;
   465 
   592 
   466 	ASSERT_DEBUG(iBearerManager);
   593 	ASSERT_DEBUG(iBearerManager);
   467 	iBearerManager->ControllerClientAvailable();
   594 	iBearerManager->ControllerClientAvailable();
   468 	
   595 	
   469 	LOGSESSIONS;
   596 	LOGCONTROLLERSESSIONS;
   470 	}
   597 	}
   471 
   598 
   472 // this function is called by the session when it goes connection oriented
   599 // this function is called by the session when it goes connection oriented
   473 void CRemConServer::ClientGoConnectionOriented(CRemConSession& aSession, TUid aUid)
   600 void CRemConServer::ClientGoConnectionOriented(CRemConControllerSession& aSession, TUid aUid)
   474 	{
   601 	{
   475 	LOG_FUNC;
   602 	LOG_FUNC;
   476 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   603 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   477 	LOGSESSIONS;
   604 	LOGCONTROLLERSESSIONS;
   478 
   605 
   479 	(void)&aSession; // get rid of unused warning.
   606 	(void)&aSession; // get rid of unused warning. We keep the param to enforce usage only
   480 	
   607 					 // by controller sessions
   481 	ASSERT_DEBUG(aSession.Type() == ERemConClientTypeController);
       
   482 
   608 
   483 	/* now tell the bearer manager that someones went connection oriented
   609 	/* now tell the bearer manager that someones went connection oriented
   484 	   The bearer manager maintains controller and target counts for all bearers
   610 	   The bearer manager maintains controller and target counts for all bearers
   485 	   and will tell bearers when they need to know things have changed */
   611 	   and will tell bearers when they need to know things have changed */
   486 	ASSERT_DEBUG(iBearerManager);
   612 	ASSERT_DEBUG(iBearerManager);
   487 	iBearerManager->ClientConnectionOriented(aUid);
   613 	iBearerManager->ClientConnectionOriented(aUid);
   488 
   614 
   489 	LOGSESSIONS;
   615 	LOGCONTROLLERSESSIONS;
   490 	}
   616 	}
   491 
   617 
   492 // this is called by the session when the client goes connectionless
   618 // this is called by the session when the client goes connectionless
   493 void CRemConServer::ClientGoConnectionless(CRemConSession& aSession, TUid aUid)
   619 void CRemConServer::ClientGoConnectionless(CRemConControllerSession& aSession, TUid aUid)
   494 	{
   620 	{
   495 	LOG_FUNC;
   621 	LOG_FUNC;
   496 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   622 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   497 	LOGSESSIONS;
   623 	LOGCONTROLLERSESSIONS;
   498 
   624 
   499 	(void)&aSession; // get rid of unused warning.
   625 	(void)&aSession; // get rid of unused warning. We keep the param to enforce usage only
   500 	
   626 					 // by controller sessions
   501 	ASSERT_DEBUG(aSession.Type() == ERemConClientTypeController);
   627 
   502 	/* now tell the bearer manager that someones went connection less
   628 	/* now tell the bearer manager that someones went connection less
   503 	   The bearer manager maintains controller and target counts for all bearers
   629 	   The bearer manager maintains controller and target counts for all bearers
   504 	   and will tell bearers when they need to know things have changed */
   630 	   and will tell bearers when they need to know things have changed */
   505 	ASSERT_DEBUG(iBearerManager);
   631 	ASSERT_DEBUG(iBearerManager);
   506 	iBearerManager->ClientConnectionless(aUid);
   632 	iBearerManager->ClientConnectionless(aUid);
   507 
   633 
   508 	LOGSESSIONS;
   634 	LOGCONTROLLERSESSIONS;
   509 	}
   635 	}
   510 
   636 
   511 // called by session when session is closed.
   637 // called by controller session when closed.
   512 void CRemConServer::ClientClosed(CRemConSession& aSession, TUid aUid)
   638 void CRemConServer::ControllerClientClosed(CRemConControllerSession& aSession, TUid aUid)
   513 	{
   639 	{
   514 	LOG_FUNC;
   640 	LOG_FUNC;
   515 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   641 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
   516 	LOGSESSIONS;
   642 	LOGCONTROLLERSESSIONS;
   517 
   643 
   518 	iSessionsLock.Wait();
       
   519 	// Find this session in the array and remove it (if it's there).
   644 	// Find this session in the array and remove it (if it's there).
   520 	const TUint sessCount = iSessions.Count();
   645 	TInt index = iControllerSessions.Find(&aSession);
   521 	for ( TUint ii = 0 ; ii < sessCount ; ++ii )
   646 	if(index >= 0)
   522 		{
   647 		{
   523 		if ( iSessions[ii] == &aSession )
   648 		// We've found the session in our array.
   524 			{
   649 		// 1. Remove the session from our array.
   525 			// We've found the session in our array.
   650 		iControllerSessions.Remove(index);
   526 
   651 		
   527 			// 1. Remove the session from our array.
   652 		// 2. Tell the bearers about the session going away, if it was the 
   528 			iSessions.Remove(ii);
   653 		// last controller.
   529 
   654 		// If the session hasn't already set its type, then it doesn't 
   530 			// 2a. Tell the TSP if the session that has gone away is a target
   655 		// count (we won't have told the bearers about it to begin with).
   531 			if((aSession.Type() == ERemConClientTypeTarget) && iTspIf5)
   656 		// The bearer manager maintains controller and target counts for all bearers
   532 				{
   657 		// and will tell bearers when they need to know things have changed 
   533 				iTspIf5->TargetClientUnavailable(aSession.ClientInfo());
   658 		if (aSession.ClientAvailable())
   534 				}
   659 			{
       
   660 			ASSERT_DEBUG(iBearerManager);
       
   661 			iBearerManager->ClientClosed(ETrue, aUid, aSession.Id());
       
   662 			}
       
   663 
       
   664 		// 3. Remove queued messages belonging to this session that: 
       
   665 		// (a) are outgoing, awaiting access to the TSP 
       
   666 		// (OutgoingPendingTsp, OutgoingNotifyPendingTsp), 
       
   667 		// (b) are outgoing, awaiting a bearer connection 
       
   668 		// (OutgoingPendingSend), 
       
   669 		// (c) have been sent (OutgoingSent)
       
   670 		// (d) are pending delivery to this session 
       
   671 		// (IncomingPendingDelivery)
       
   672 
       
   673 		// (3)(a) Outgoing, waiting access to the TSP:
       
   674 		TSglQueIter<CRemConMessage>& cmdIter = OutgoingCmdPendingTsp().SetToFirst();
       
   675 		CRemConMessage* msg;
       
   676 		TBool first = ETrue;
       
   677 		while ( ( msg = cmdIter++ ) != NULL )
       
   678 			{
       
   679 			if ( msg->SessionId() == aSession.Id() )
       
   680 				{
       
   681 				// If the message is currently being worked on by the 
       
   682 				// TSP, cancel the TSP before destroying it.
       
   683 				if ( iTspHandlingOutgoingCommand && first )
       
   684 					{
       
   685 					ASSERT_DEBUG(iTspIf);
       
   686 					iTspIf->CancelOutgoingCommand();
       
   687 					iTspHandlingOutgoingCommand = EFalse;
       
   688 					}
       
   689 				OutgoingCmdPendingTsp().RemoveAndDestroy(*msg);
       
   690 				}
       
   691 			first = EFalse;
       
   692 			}
       
   693 		
       
   694 		cmdIter = OutgoingNotifyCmdPendingTsp().SetToFirst();
       
   695 		first = ETrue;
       
   696 		while ( ( msg = cmdIter++ ) != NULL )
       
   697 			{
       
   698 			if ( msg->SessionId() == aSession.Id() )
       
   699 				{
       
   700 				// If the message is currently being worked on by the 
       
   701 				// TSP, cancel the TSP before destroying it.
       
   702 				if ( iTspHandlingOutgoingNotifyCommand && first )
       
   703 					{
       
   704 					ASSERT_DEBUG(iTspIf3);
       
   705 					iTspIf3->CancelOutgoingNotifyCommand();
       
   706 					iTspHandlingOutgoingNotifyCommand = EFalse;
       
   707 					}
       
   708 				OutgoingNotifyCmdPendingTsp().RemoveAndDestroy(*msg);
       
   709 				}
       
   710 			first = EFalse;
       
   711 			}
       
   712 
       
   713 		// (3)(b) Outgoing, awaiting a bearer connection:
       
   714 		TSglQueIter<CRemConMessage>& sendIter = OutgoingPendingSend().SetToFirst();
       
   715 		while ( ( msg = sendIter++ ) != NULL )
       
   716 			{
       
   717 			if ( msg->SessionId() == aSession.Id() )
       
   718 				{
       
   719 				// Only commands are sent by controllers
       
   720 				ASSERT_DEBUG(msg->MsgType() == ERemConCommand || msg->MsgType() == ERemConNotifyCommand);
       
   721 				OutgoingPendingSend().RemoveAndDestroy(*msg);
       
   722 				}
       
   723 			}
       
   724 
       
   725 		// (3)(c) Have been sent:
       
   726 		OutgoingSent().RemoveAndDestroy(aSession.Id());
       
   727 		
       
   728 		// (3)(d) Are pending delivery to this session:
       
   729 		TSglQueIter<CRemConMessage>& pendingDeliveryIter = IncomingPendingDelivery().SetToFirst();
       
   730 		while ( ( msg = pendingDeliveryIter++ ) != NULL )
       
   731 			{
       
   732 			if ( msg->SessionId() == aSession.Id() )
       
   733 				{
       
   734 				// Only responses or rejects are received by controllers
       
   735 				ASSERT_DEBUG(msg->MsgType() == ERemConResponse || msg->MsgType() == ERemConReject);
       
   736 				IncomingPendingDelivery().RemoveAndDestroy(*msg);
       
   737 				}
       
   738 			}
       
   739 
       
   740 		// (3)(e) Have been delivered to this session and are awaiting responses:
       
   741 		TSglQueIter<CRemConMessage>& deliveredIter = IncomingDelivered().SetToFirst();
       
   742 		while ( ( msg = deliveredIter++ ) != NULL )
       
   743 			{
       
   744 			if ( msg->SessionId() == aSession.Id() )
       
   745 				{
       
   746 				// Only responses or rejects are received by controllers
       
   747 				ASSERT_DEBUG(msg->MsgType() == ERemConResponse || msg->MsgType() == ERemConReject);
       
   748 				IncomingDelivered().RemoveAndDestroy(*msg);
       
   749 				}
       
   750 			}
       
   751 		}
       
   752 
       
   753 	// Also remove its record from the connection history record.
       
   754 	RemoveSessionFromConnHistory(aSession);
       
   755 	
       
   756 	StartShutdownTimerIfNoClientsOrBulkThread();
       
   757 
       
   758 	LOGCONTROLLERSESSIONS;
       
   759 	}
       
   760 
       
   761 /**
       
   762 Called by CRemConTargetClientProcess when a session is closing.
       
   763 We have some work to do here as we need to remove the messages pertaining to
       
   764 that session.
       
   765 **/
       
   766 void CRemConServer::TargetSessionClosed(CRemConTargetClientProcess& aClient, CRemConTargetSession& aSession)
       
   767 	{
       
   768 	LOG_FUNC;
       
   769 	LOG1(_L("\t&aSession = 0x%08x"), &aSession);
       
   770 	LOGTARGETSESSIONS;
       
   771 	
       
   772 	iTargetClientsLock.Wait();
       
   773 
       
   774 	// Find the client in our array (required for later removal)
       
   775 	TInt clientIndex = iTargetClients.Find(aClient.ClientInfo().ProcessId(), TargetClientCompareUsingProcessId);
       
   776 
       
   777 	// We should always find the client.
       
   778 	ASSERT_DEBUG(clientIndex > KErrNotFound);
       
   779 
       
   780 	// 1. Remove queued messages belonging to this session that:
       
   781 	// (a) are outgoing, awaiting access to the TSP 
       
   782 	// (OutgoingRspPendingTsp)
       
   783 	// (b) are outgoing, awaiting a bearer connection 
       
   784 	// (OutgoingPendingSend), 
       
   785 	// (c) have been sent (OutgoingSent)
       
   786 	// (d) are pending delivery to this session 
       
   787 	// (IncomingPendingDelivery)
       
   788 	// (e) have been delivered to this session and are awaiting 
       
   789 	// responses (IncomingDelivered).
       
   790 		
       
   791 	// (1)(a) Outgoing, awaiting access to the TSP
       
   792 	// First remove the client pertaining to this session from the message recipients list.
       
   793 	ASSERT_DEBUG(iMessageRecipientsList);
       
   794 	TSglQueIter<CMessageRecipients>& messageRecipientsIter = iMessageRecipientsList->Iter();
       
   795 	
       
   796 	messageRecipientsIter.SetToFirst();
       
   797 	CMessageRecipients* message;
       
   798 	while ((message = messageRecipientsIter++) != NULL)
       
   799 		{
       
   800 		// First we need to find the message - it could be in
       
   801 		// OutgoingRspPendingTsp, IncomingDelivered or IncomingPendingDelivery
       
   802 		CRemConMessage* msg;
       
   803 		msg = OutgoingRspPendingTsp().Message(message->TransactionId());
   535 			
   804 			
   536 			// 2b. Tell the bearers about the session going away, if it was the 
   805 		if (!msg)
   537 			// last controller or last target.
   806 			{
   538 			// If the session hasn't already set its type, then it doesn't 
   807 			msg = IncomingDelivered().Message(message->TransactionId());
       
   808 			}
       
   809 		if (!msg)
       
   810 			{
       
   811 			msg = IncomingPendingDelivery().Message(message->TransactionId());
       
   812 			}
       
   813 			
       
   814 		if(msg)
       
   815 			{
       
   816 			// Try to remove this client from the message (this does nothing if we were not a recipient).
       
   817 			message->RemoveAndDestroyClient(aSession.ClientInfo());
       
   818 			if (message->Clients().IsEmpty())
       
   819 				{
       
   820 				iMessageRecipientsList->Messages().Remove(*message);
       
   821 				// Inform bearer that it won't be getting a response
       
   822 				SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
       
   823 
       
   824 				delete message;
       
   825 				}
       
   826 			}
       
   827 		}
       
   828 
       
   829 	TSglQueIter<CRemConMessage>& rspIter = OutgoingRspPendingTsp().SetToFirst();
       
   830 	CRemConMessage* msg;
       
   831 	TBool first = ETrue;
       
   832 	while ( ( msg = rspIter++ ) != NULL )
       
   833 		{
       
   834 		if ( aClient.Id() == msg->SessionId() && aSession.SupportedMessage(*msg) )
       
   835 			{
       
   836 			// If the message is currently being worked on by the 
       
   837 			// TSP, cancel the TSP before destroying it.
       
   838 			if (iTspIf2 && iTspHandlingOutgoingResponse && first )
       
   839 				{
       
   840 				iTspIf2->CancelOutgoingResponse();
       
   841 				iTspHandlingOutgoingResponse = EFalse;
       
   842 				}
       
   843 			OutgoingRspPendingTsp().RemoveAndDestroy(*msg);
       
   844 			}
       
   845 		first = EFalse;
       
   846 		}
       
   847 
       
   848 	// (1)(b) Outgoing, awaiting a bearer connection:
       
   849 	TSglQueIter<CRemConMessage>& sendIter = OutgoingPendingSend().SetToFirst();
       
   850 	while ( ( msg = sendIter++ ) != NULL )
       
   851 		{
       
   852 		if ( aClient.Id() == msg->SessionId() && aSession.SupportedMessage(*msg) )
       
   853 			{
       
   854 			if (msg->MsgType() == ERemConResponse)
       
   855 				{
       
   856 				SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
       
   857 				}
       
   858 			OutgoingPendingSend().RemoveAndDestroy(*msg);
       
   859 			}
       
   860 		}
       
   861 
       
   862 	// (1)(c) Have been sent:
       
   863 	TSglQueIter<CRemConMessage>& haveSentIter = OutgoingSent().SetToFirst();
       
   864 	while ( ( msg = haveSentIter++ ) != NULL)
       
   865 		{
       
   866 		if ( aClient.Id() == msg->SessionId() && aSession.SupportedMessage(*msg) )
       
   867 			{
       
   868 			OutgoingSent().RemoveAndDestroy(*msg);
       
   869 			}
       
   870 		}
       
   871 	
       
   872 	// (1)(d) Are pending delivery to this session:
       
   873 	TSglQueIter<CRemConMessage>& pendingDeliveryIter = IncomingPendingDelivery().SetToFirst();
       
   874 	while ( ( msg = pendingDeliveryIter++ ) != NULL )
       
   875 		{
       
   876 		if ( aClient.Id() == msg->SessionId() && aSession.SupportedMessage(*msg) )
       
   877 			{
       
   878 			if (msg->MsgType() == ERemConNotifyCommand)
       
   879 				{
       
   880 				SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
       
   881 				}
       
   882 			IncomingPendingDelivery().RemoveAndDestroy(*msg);
       
   883 			}
       
   884 		}
       
   885 
       
   886 	// (1)(e) Have been delivered to this session and are awaiting responses:
       
   887 	TSglQueIter<CRemConMessage>& deliveredIter = IncomingDelivered().SetToFirst();
       
   888 	while ( ( msg = deliveredIter++ ) != NULL )
       
   889 		{
       
   890 		if ( aClient.Id() == msg->SessionId() && aSession.SupportedMessage(*msg) )
       
   891 			{
       
   892 			if (msg->MsgType() == ERemConNotifyCommand)
       
   893 				{
       
   894 				SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
       
   895 				}
       
   896 			IncomingDelivered().RemoveAndDestroy(*msg);
       
   897 			}
       
   898 		}
       
   899 
       
   900 	// Remove the session's record from the connection history record.
       
   901 	RemoveSessionFromConnHistory(aSession);
       
   902 
       
   903 	// Finally, try to delete client process representation if it now has no sessions
       
   904 	TryToDropClientProcess(clientIndex);
       
   905 
       
   906 	iTargetClientsLock.Signal();
       
   907 	
       
   908 	LOGTARGETSESSIONS;
       
   909 	}
       
   910 
       
   911 void CRemConServer::RemoveSessionFromConnHistory(const CRemConSession& aSession)
       
   912 	{
       
   913 	LOG_FUNC;
       
   914 
       
   915 	const TUint count = iSession2ConnHistory.Count();
       
   916 	for ( TUint ii = 0 ; ii < count ; ++ii )
       
   917 		{
       
   918 		if ( iSession2ConnHistory[ii].iSessionId == aSession.Id() )
       
   919 			{
       
   920 			iSession2ConnHistory.Remove(ii);
       
   921 			UpdateConnectionHistoryAndPointers();
       
   922 			break;
       
   923 			}
       
   924 		}
       
   925 	}
       
   926 
       
   927 // called by client process representation on close.
       
   928 void CRemConServer::TargetClientClosed(CRemConTargetClientProcess& aClient)
       
   929 	{
       
   930 	LOG_FUNC;
       
   931 	LOG1(_L("\t&aClient = 0x%08x"), &aClient);
       
   932 	LOGTARGETSESSIONS;
       
   933 
       
   934 	iTargetClientsLock.Wait();
       
   935 	// Find this client in the array and remove it (if it's there).
       
   936 	const TUint clientCount = iTargetClients.Count();
       
   937 	for ( TUint ii = 0 ; ii < clientCount ; ++ii )
       
   938 		{
       
   939 		if ( iTargetClients[ii] == &aClient )
       
   940 			{
       
   941 			// We've found the client in our array.
       
   942 
       
   943 			// 1. Remove the client from our array.
       
   944 			iTargetClients.Remove(ii);
       
   945 
       
   946 			// 2a. Tell the TSP the client has gone away 
       
   947 			if(iTspIf5)
       
   948 				{
       
   949 				iTspIf5->TargetClientUnavailable(aClient.ClientInfo());
       
   950 				}
       
   951 			
       
   952 			// 2b. Tell the bearers about the client going away, if it was the 
       
   953 			// last target.
       
   954 			// If the client hasn't already set its type, then it doesn't 
   539 			// count (we won't have told the bearers about it to begin with).
   955 			// count (we won't have told the bearers about it to begin with).
   540 			// The bearer manager maintains controller and target counts for all bearers
   956 			// The bearer manager maintains controller and target counts for all bearers
   541 			// and will tell bearers when they need to know things have changed */
   957 			// and will tell bearers when they need to know things have changed 
   542 			if ( aSession.Type() != ERemConClientTypeUndefined )
   958 			if (aClient.ClientAvailable())
   543 				{
   959 				{
   544 				ASSERT_DEBUG(iBearerManager);
   960 				ASSERT_DEBUG(iBearerManager);
   545 				iBearerManager->ClientClosed(aSession.Type() == ERemConClientTypeController, aUid, aSession.Id());
   961 				iBearerManager->ClientClosed(EFalse, KNullUid, aClient.Id());
   546 				}
       
   547 
       
   548 			// 3. Remove queued messages belonging to this session that: 
       
   549 			// (a) are outgoing, awaiting access to the TSP 
       
   550 			// (OutgoingPendingTsp, OutgoingNotifyPendingTsp), 
       
   551 			// (b) are outgoing, awaiting a bearer connection 
       
   552 			// (OutgoingPendingSend), 
       
   553 			// (c) have been sent (OutgoingSent)
       
   554 			// (d) are pending delivery to this session 
       
   555 			// (IncomingPendingDelivery)
       
   556 			// (e) have been delivered to this session and are awaiting 
       
   557 			// responses (IncomingDelivered).
       
   558 			TSglQueIter<CRemConMessage>& cmdIter = OutgoingCmdPendingTsp().SetToFirst();
       
   559 			CRemConMessage* msg;
       
   560 			TBool first = ETrue;
       
   561 			while ( ( msg = cmdIter++ ) != NULL )
       
   562 				{
       
   563 				if ( msg->SessionId() == aSession.Id() )
       
   564 					{
       
   565 					// If the message is currently being worked on by the 
       
   566 					// TSP, cancel the TSP before destroying it.
       
   567 					if ( iTspHandlingOutgoingCommand && first )
       
   568 						{
       
   569 						ASSERT_DEBUG(iTspIf);
       
   570 						iTspIf->CancelOutgoingCommand();
       
   571 						iTspHandlingOutgoingCommand = EFalse;
       
   572 						}
       
   573 					OutgoingCmdPendingTsp().RemoveAndDestroy(*msg);
       
   574 					}
       
   575 				first = EFalse;
       
   576 				}
       
   577 			
       
   578 			cmdIter = OutgoingNotifyCmdPendingTsp().SetToFirst();
       
   579 			first = ETrue;
       
   580 			while ( ( msg = cmdIter++ ) != NULL )
       
   581 				{
       
   582 				if ( msg->SessionId() == aSession.Id() )
       
   583 					{
       
   584 					// If the message is currently being worked on by the 
       
   585 					// TSP, cancel the TSP before destroying it.
       
   586 					if ( iTspHandlingOutgoingNotifyCommand && first )
       
   587 						{
       
   588 						ASSERT_DEBUG(iTspIf3);
       
   589 						iTspIf3->CancelOutgoingNotifyCommand();
       
   590 						iTspHandlingOutgoingNotifyCommand = EFalse;
       
   591 						}
       
   592 					OutgoingNotifyCmdPendingTsp().RemoveAndDestroy(*msg);
       
   593 					}
       
   594 				first = EFalse;
       
   595 				}
       
   596 
       
   597 			if ( aSession.Type() == ERemConClientTypeTarget )
       
   598 				{
       
   599 				// Remove the clients from the DeliveredMessageClients list
       
   600 				ASSERT_DEBUG(iMessageRecipientsList);
       
   601 				TSglQueIter<CMessageRecipients>& messageRecipientsIter = iMessageRecipientsList->Iter();
       
   602 				
       
   603 				messageRecipientsIter.SetToFirst();
       
   604 				CMessageRecipients* message;
       
   605 				while ((message = messageRecipientsIter++) != NULL)
       
   606 					{
       
   607 					message->RemoveAndDestroyClient(aSession.ClientInfo());
       
   608 					if (message->Clients().IsEmpty())
       
   609 						{
       
   610 						iMessageRecipientsList->Messages().Remove(*message);
       
   611 						// Inform bearer that it won't be getting a response
       
   612 						
       
   613 						// First we need to find the command - it could be in
       
   614 						// OutgoingRspPendingTsp, IncomingDelivered or IncomingPendingDelivery
       
   615 						
       
   616 						CRemConMessage* msg;
       
   617 						
       
   618 						msg = OutgoingRspPendingTsp().Message(message->TransactionId());
       
   619 						
       
   620 						if (!msg)
       
   621 							{
       
   622 							msg = IncomingDelivered().Message(message->TransactionId());
       
   623 							}
       
   624 						if (!msg)
       
   625 							{
       
   626 							msg = IncomingPendingDelivery().Message(message->TransactionId());
       
   627 							}
       
   628 						
       
   629 						if(msg)
       
   630 							{
       
   631 							// As this is the last message with this transaction ID, it should have this session ID
       
   632 							ASSERT_DEBUG(msg->SessionId() == aSession.Id());
       
   633 	
       
   634 							// Now we've found the message, we can pass the reject to the bearer
       
   635 							// Send reject to the bearer
       
   636 							SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
       
   637 							}
       
   638 						delete message;
       
   639 						}
       
   640 					TSglQueIter<CRemConMessage>& rspIter = OutgoingRspPendingTsp().SetToFirst();
       
   641 	
       
   642 					CRemConMessage* msg;
       
   643 					TBool first = ETrue;
       
   644 					while ( ( msg = rspIter++ ) != NULL )
       
   645 						{
       
   646 						if ( msg->SessionId() == aSession.Id() )
       
   647 							{
       
   648 							// If the message is currently being worked on by the 
       
   649 							// TSP, cancel the TSP before destroying it.
       
   650 							if (iTspIf2 && iTspHandlingOutgoingResponse && first )
       
   651 								{
       
   652 								iTspIf2->CancelOutgoingResponse();
       
   653 								iTspHandlingOutgoingResponse = EFalse;
       
   654 								}
       
   655 							OutgoingRspPendingTsp().RemoveAndDestroy(*msg);
       
   656 							}
       
   657 						first = EFalse;
       
   658 						}
       
   659 					
       
   660 					}
       
   661 				}
       
   662 
       
   663 			TSglQueIter<CRemConMessage>& sendIter = OutgoingPendingSend().SetToFirst();
       
   664 			while ( ( msg = sendIter++ ) != NULL )
       
   665 				{
       
   666 				if ( msg->SessionId() == aSession.Id() )
       
   667 					{
       
   668 					if (msg->MsgType() == ERemConResponse)
       
   669 						{
       
   670 						SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
       
   671 						}
       
   672 					OutgoingPendingSend().RemoveAndDestroy(*msg);
       
   673 					}
       
   674 				}
       
   675 
       
   676 			OutgoingSent().RemoveAndDestroy(aSession.Id());
       
   677 			
       
   678 			TSglQueIter<CRemConMessage>& pendingDeliveryIter = IncomingPendingDelivery().SetToFirst();
       
   679 			while ( ( msg = pendingDeliveryIter++ ) != NULL )
       
   680 				{
       
   681 				if ( msg->SessionId() == aSession.Id() )
       
   682 					{
       
   683 					if (msg->MsgType() == ERemConNotifyCommand)
       
   684 						{
       
   685 						SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
       
   686 						}
       
   687 					IncomingPendingDelivery().RemoveAndDestroy(*msg);
       
   688 					}
       
   689 				}
       
   690 
       
   691 			TSglQueIter<CRemConMessage>& deliveredIter = IncomingDelivered().SetToFirst();
       
   692 			while ( ( msg = deliveredIter++ ) != NULL )
       
   693 				{
       
   694 				if ( msg->SessionId() == aSession.Id() )
       
   695 					{
       
   696 					if (msg->MsgType() == ERemConNotifyCommand)
       
   697 						{
       
   698 						SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
       
   699 						}
       
   700 					IncomingDelivered().RemoveAndDestroy(*msg);
       
   701 					}
       
   702 				}
   962 				}
   703 					
   963 					
   704 			break;
   964 			break;
   705 			} // End found session in our array
   965 			} // End found session in our array
   706 		}
   966 		}
   707 	iSessionsLock.Signal();
   967 	iTargetClientsLock.Signal();
   708 
   968 
   709 	// Also remove its record from the connection history record.
   969 	StartShutdownTimerIfNoClientsOrBulkThread();
   710 	const TUint count = iSession2ConnHistory.Count();
   970 
       
   971 	LOGTARGETSESSIONS;
       
   972 	}
       
   973 
       
   974 #ifdef __FLOG_ACTIVE
       
   975 
       
   976 void CRemConServer::LogControllerSessions() const 
       
   977 	{
       
   978 	const TUint count = iControllerSessions.Count();
       
   979 	LOG1(_L("\tNumber of controller sessions = %d"), count);
   711 	for ( TUint ii = 0 ; ii < count ; ++ii )
   980 	for ( TUint ii = 0 ; ii < count ; ++ii )
   712 		{
   981 		{
   713 		if ( iSession2ConnHistory[ii].iSessionId == aSession.Id() )
   982 		CRemConSession* const session = iControllerSessions[ii];
   714 			{
       
   715 			iSession2ConnHistory.Remove(ii);
       
   716 			UpdateConnectionHistoryAndPointers();
       
   717 			break;
       
   718 			}
       
   719 		}
       
   720 
       
   721 	StartShutdownTimerIfNoSessionsOrBulkThread();
       
   722 
       
   723 	LOGSESSIONS;
       
   724 	}
       
   725 
       
   726 TBool CRemConServer::TargetClientWithSameProcessId(TProcessId aProcId) const
       
   727 	{
       
   728 	LOG_FUNC;
       
   729 	LOG1(_L("\taProcId = %d"), static_cast<TUint>(aProcId));
       
   730 
       
   731 	TBool ret = EFalse;
       
   732 
       
   733 	const CRemConSession* const sess = TargetSession(aProcId);
       
   734 	if ( sess )
       
   735 		{
       
   736 		ret = ETrue;
       
   737 		}
       
   738 
       
   739 	LOG1(_L("\tret = %d"), ret);
       
   740 	return ret;
       
   741 	}
       
   742 
       
   743 #ifdef __FLOG_ACTIVE
       
   744 void CRemConServer::LogSessions() const
       
   745 	{
       
   746 	iSessionsLock.Wait();
       
   747 	const TUint count = iSessions.Count();
       
   748 	LOG1(_L("\tNumber of sessions = %d"), count);
       
   749 	for ( TUint ii = 0 ; ii < count ; ++ii )
       
   750 		{
       
   751 		CRemConSession* const session = iSessions[ii];
       
   752 		ASSERT_DEBUG(session);
   983 		ASSERT_DEBUG(session);
   753 		LOG5(_L("\t\tsession %d [0x%08x], Id = %d, Type = %d, ProcessId = %d"), 
   984 		LOG4(_L("\t\tsession %d [0x%08x], Id = %d, ProcessId = %d"), 
   754 			ii, 
   985 			ii, 
   755 			session,
   986 			session,
   756 			session->Id(),
   987 			session->Id(),
   757 			session->Type(),
       
   758 			static_cast<TUint>(session->ClientInfo().ProcessId())
   988 			static_cast<TUint>(session->ClientInfo().ProcessId())
   759 			);
   989 			);
   760 		}
   990 		}
   761 	iSessionsLock.Signal();
   991 	}
       
   992 
       
   993 void CRemConServer::LogTargetSessions() const 
       
   994 	{
       
   995 	iTargetClientsLock.Wait();
       
   996 	
       
   997 	const TUint count = iTargetClients.Count();
       
   998 	LOG1(_L("\tNumber of target clients = %d"), count);
       
   999 	for ( TUint ii = 0 ; ii < count ; ++ii )
       
  1000 		{
       
  1001 		CRemConTargetClientProcess* const client = iTargetClients[ii];
       
  1002 		ASSERT_DEBUG(client);
       
  1003 		LOG5(_L("\t\tclient %d [0x%08x], Id = %d, ProcessId = %d, SessionCount = %d"), 
       
  1004 			ii, 
       
  1005 			client,
       
  1006 			client->Id(),
       
  1007 			static_cast<TUint>(client->ClientInfo().ProcessId()),
       
  1008 			client->TargetSessionCount()
       
  1009 			);
       
  1010 		}
       
  1011 	iTargetClientsLock.Signal();
   762 	}
  1012 	}
   763 
  1013 
   764 void CRemConServer::LogRemotes() const
  1014 void CRemConServer::LogRemotes() const
   765 	{
  1015 	{
   766 	// Called from dtor- this may not have been made yet.
  1016 	// Called from dtor- this may not have been made yet.
   805 	ASSERT_DEBUG(iTspHandlingOutgoingNotifyCommand);
  1055 	ASSERT_DEBUG(iTspHandlingOutgoingNotifyCommand);
   806 	iTspHandlingOutgoingNotifyCommand = EFalse;
  1056 	iTspHandlingOutgoingNotifyCommand = EFalse;
   807 
  1057 
   808 	CRemConMessage& msg = OutgoingNotifyCmdPendingTsp().First();
  1058 	CRemConMessage& msg = OutgoingNotifyCmdPendingTsp().First();
   809 	ASSERT_DEBUG(msg.Addr().IsNull());
  1059 	ASSERT_DEBUG(msg.Addr().IsNull());
   810 	CRemConSession* const sess = Session(msg.SessionId());
  1060 	MRemConMessageSendObserver* const observer = ControllerSession(msg.SessionId());
   811 	// Session closure removes messages from the outgoing queue and cancels 
  1061 	// Session closure removes messages from the outgoing queue and cancels 
   812 	// the TSP request if relevant. If sess is NULL here, then this processing 
  1062 	// the TSP request if relevant. If observer is NULL here, then this processing 
   813 	// has gone wrong.
  1063 	// has gone wrong.
   814 	ASSERT_DEBUG(sess);
  1064 	ASSERT_DEBUG(observer);
   815 	
  1065 	
   816 	sess->SendError() = KErrNone;
       
   817 	if ( (aError != KErrNone) || !aConnection)
  1066 	if ( (aError != KErrNone) || !aConnection)
   818 		{
  1067 		{
   819 		sess->SendError() = aError;
  1068 		observer->MrcmsoMessageSendResult(msg, aError);
   820 		sess->CompleteSendNotify();
       
   821 		}
  1069 		}
   822 	else
  1070 	else
   823 		{
  1071 		{
   824 		// Message addressed OK.
  1072 		// Message addressed OK.
   825 		if ( aConnection != NULL )
  1073 		if ( aConnection != NULL )
   826 			{
  1074 			{
   827 			TBool sync = EFalse;
  1075 			TBool sync = EFalse;
   828 			TRAPD(err, SendCmdToRemoteL(msg, *aConnection, sync));
  1076 			TRAPD(err, SendCmdToRemoteL(msg, *aConnection, sync));
   829 			if ( err || sync )
  1077 			if ( err || sync )
   830 				{
  1078 				{
   831 				sess->SendError() = err;
  1079 				observer->MrcmsoMessageSendResult(msg, err);
   832 				sess->CompleteSendNotify();
       
   833 				}
  1080 				}
   834 			
  1081 			
   835 			delete aConnection;
  1082 			delete aConnection;
   836 			aConnection = NULL;
  1083 			aConnection = NULL;
   837 			}
  1084 			}
   886 	CRemConMessage& msg = OutgoingCmdPendingTsp().First();
  1133 	CRemConMessage& msg = OutgoingCmdPendingTsp().First();
   887 	// Check that the message isn't addressed already. If this fails, it's 
  1134 	// Check that the message isn't addressed already. If this fails, it's 
   888 	// possible that the TSP has called OutgoingCommandAddressed in response 
  1135 	// possible that the TSP has called OutgoingCommandAddressed in response 
   889 	// to a PermitOutgoingCommand request.
  1136 	// to a PermitOutgoingCommand request.
   890 	ASSERT_DEBUG(msg.Addr().IsNull());
  1137 	ASSERT_DEBUG(msg.Addr().IsNull());
   891 	CRemConSession* const sess = Session(msg.SessionId());
  1138 	// The observer is the session which generated the message.
       
  1139 	MRemConMessageSendObserver* const observer = ControllerSession(msg.SessionId());
   892 	// Session closure removes messages from the outgoing queue and cancels 
  1140 	// Session closure removes messages from the outgoing queue and cancels 
   893 	// the TSP request if relevant. If sess is NULL here, then this processing 
  1141 	// the TSP request if relevant. If observer is NULL here, then this processing 
   894 	// has gone wrong.
  1142 	// has gone wrong.
   895 	ASSERT_DEBUG(sess);
  1143 	ASSERT_DEBUG(observer);
   896 	// The number of remotes the command was sent to.
  1144 
   897 	sess->NumRemotes() = 0;
  1145 	TInt numRemotesToTry = 0;
   898 	sess->SendError() = KErrNone;
  1146 
   899 	if ( aError != KErrNone )
  1147 	if ( aError != KErrNone )
   900 		{
  1148 		{
   901 		sess->SendError() = aError;
  1149 		// Error prevented message send attempt from being made.
   902 		sess->NumRemotesToTry() = 0;
  1150 		observer->MrcmsoMessageSendOneOrMoreAttemptFailed(msg, aError);
   903 		}
  1151 		}
   904 	else
  1152 	else
   905 		{
  1153 		{
   906 		// Message addressed OK.
  1154 		// Message addressed OK.
   907 		// Work out how many remotes the TSP said to send to.
  1155 		// Work out how many remotes the TSP said to send to.
   908 		TSglQueIter<TRemConAddress> iter(iTspConnections);
  1156 		TSglQueIter<TRemConAddress> iter(iTspConnections);
   909 		while ( iter++ )
  1157 		while ( iter++ )
   910 			{
  1158 			{
   911 			++sess->NumRemotesToTry();
  1159 			++numRemotesToTry;
   912 			}
  1160 			}
       
  1161 		// Notify session of send attempt.
       
  1162 		observer->MrcmsoMessageSendOneOrMoreAttempt(msg, numRemotesToTry);
   913 		iter.SetToFirst();
  1163 		iter.SetToFirst();
   914 		// Try to connect and send a message to each specified remote.
  1164 		// Try to connect and send a message to each specified remote.
   915 		TRemConAddress* conn;
  1165 		TRemConAddress* conn;
   916 		while ( ( conn = iter++ ) != NULL )
  1166 		while ( ( conn = iter++ ) != NULL )
   917 			{
  1167 			{
   918 			LOG2(_L("\tsending message to remote [0x%08x] BearerUid = 0x%08x"), 
  1168 			LOG2(_L("\tsending message to remote [0x%08x] BearerUid = 0x%08x"), 
   919 				conn, conn->BearerUid());
  1169 				conn, conn->BearerUid());
   920 
  1170 
   921 			// We send to as many of the remotes as we can. We remember 
  1171 			// We send to as many of the remotes as we can. The observer remembers 
   922 			// how many remotes got sent to successfully, and complete the 
  1172 			// how many remotes got sent to successfully, and completes the 
   923 			// client's request with either KErrNone or _one of_ the 
  1173 			// client's request with either KErrNone or _one of_ the 
   924 			// errors that were raised. 
  1174 			// errors that were raised. 
   925 			TBool sync = EFalse;
  1175 			TBool sync = EFalse;
   926 			TRAPD(err, SendCmdToRemoteL(msg, *conn, sync));
  1176 			TRAPD(err, SendCmdToRemoteL(msg, *conn, sync));
   927 			if ( err || sync )
  1177 			if ( err || sync )
   928 				{
  1178 				{
   929 				// We have finished trying to process this (copy of this) 
  1179 				// We have finished trying to process this (copy of this) 
   930 				// message, so we can adjust our 'remotes' counter / 
  1180 				// message, so we can adjust our 'remotes' counter / 
   931 				// completion error.
  1181 				// completion error.
   932 				if ( err == KErrNone )
  1182 				observer->MrcmsoMessageSendOneOrMoreResult(msg, err);
   933 					{
       
   934 					++sess->NumRemotes();
       
   935 					}
       
   936 				else
       
   937 					{
       
   938 					sess->SendError() = err;
       
   939 					}
       
   940 				--sess->NumRemotesToTry();
       
   941 				}
  1183 				}
   942 			// else we didn't actually make a send attempt because conn was 
  1184 			// else we didn't actually make a send attempt because conn was 
   943 			// down. This particular message will undergo an actual 
  1185 			// down. This particular message will undergo an actual 
   944 			// (bearer-level) send attempt later on when the connection comes 
  1186 			// (bearer-level) send attempt later on when the connection comes 
   945 			// up. For now, however, we cannot legally complete the client's 
  1187 			// up. For now, however, we cannot legally complete the client's 
   947 
  1189 
   948 			iTspConnections.Remove(*conn);
  1190 			iTspConnections.Remove(*conn);
   949 			delete conn;
  1191 			delete conn;
   950 			} // End while 
  1192 			} // End while 
   951 		} // End if TSP addressed command OK
  1193 		} // End if TSP addressed command OK
   952 	if ( sess->NumRemotesToTry() == 0 )
       
   953 		{
       
   954 		sess->CompleteSend();
       
   955 		}
       
   956 
  1194 
   957 	// We've now finished with the addressed message, so destroy it.
  1195 	// We've now finished with the addressed message, so destroy it.
   958 	OutgoingCmdPendingTsp().RemoveAndDestroy(msg);
  1196 	OutgoingCmdPendingTsp().RemoveAndDestroy(msg);
   959 
  1197 
   960 	// Check for more commands to address.
  1198 	// Check for more commands to address.
   993 	CRemConMessage& msg = OutgoingCmdPendingTsp().First();
  1231 	CRemConMessage& msg = OutgoingCmdPendingTsp().First();
   994 	// Check that the message is addressed already. If this fails, it's 
  1232 	// Check that the message is addressed already. If this fails, it's 
   995 	// possible that the TSP has called OutgoingCommandPermitted in response 
  1233 	// possible that the TSP has called OutgoingCommandPermitted in response 
   996 	// to a AddressOutgoingCommand request.
  1234 	// to a AddressOutgoingCommand request.
   997 	ASSERT_DEBUG(!msg.Addr().IsNull());
  1235 	ASSERT_DEBUG(!msg.Addr().IsNull());
   998 	CRemConSession* const sess = Session(msg.SessionId());
  1236 	// The session is the observer
       
  1237 	MRemConMessageSendObserver* const observer = ControllerSession(msg.SessionId());
   999 	// Session closure removes messages from the outgoing queue and cancels 
  1238 	// Session closure removes messages from the outgoing queue and cancels 
  1000 	// the TSP request if relevant. If sess is NULL here, then this processing 
  1239 	// the TSP request if relevant. If observer is NULL here, then this processing 
  1001 	// has gone wrong.
  1240 	// has gone wrong.
  1002 	ASSERT_DEBUG(sess);
  1241 	ASSERT_DEBUG(observer);
  1003 	TInt err = KErrPermissionDenied;
  1242 	TInt err = KErrPermissionDenied;
  1004 	if ( aIsPermitted )
  1243 	if ( aIsPermitted )
  1005 		{
  1244 		{
  1006 		TBool sync = EFalse;
  1245 		TBool sync = EFalse;
  1007 		TRAP(err, SendCmdToRemoteL(msg, msg.Addr(), sync));
  1246 		TRAP(err, SendCmdToRemoteL(msg, msg.Addr(), sync));
  1008 		if ( err || sync )
  1247 		if ( err || sync )
  1009 			{
  1248 			{
  1010 			// We made a send attempt at the bearer level. Complete the 
  1249 			// We made a send attempt at the bearer level, notify observer.
  1011 			// client's message according to err.
  1250 			observer->MrcmsoMessageSendOneOrMoreResult(msg, err);
  1012 			--sess->NumRemotesToTry();
       
  1013 			sess->NumRemotes() = ( err == KErrNone ) ? 1 : 0;
       
  1014 			sess->SendError() = err;
       
  1015 			sess->CompleteSend();
       
  1016 			}
  1251 			}
  1017 		// else the message is waiting until a bearer-level connection 
  1252 		// else the message is waiting until a bearer-level connection 
  1018 		// comes up. Only then can we complete the client's message.
  1253 		// comes up. Only then can we complete the client's message.
  1019 		}
  1254 		}
  1020 	else
  1255 	else
  1021 		{
  1256 		{
  1022 		// The send wasn't permitted, so complete the client's message.
  1257 		// The send wasn't permitted, notify observer.
  1023 		// This was a connection-oriented send, so we know the number of 
  1258 		// This should complete the client's message, as we're connection oriented
  1024 		// remotes it was sent to is 0.
  1259 		// (so only one remote to send to).
  1025 		--sess->NumRemotesToTry();
  1260 		observer->MrcmsoMessageSendOneOrMoreResult(msg, KErrPermissionDenied);
  1026 		sess->NumRemotes() = 0;
       
  1027 		sess->SendError() = KErrPermissionDenied;
       
  1028 		sess->CompleteSend();
       
  1029 		}
  1261 		}
  1030 
  1262 
  1031 	// We've now finished with the message, so destroy it.
  1263 	// We've now finished with the message, so destroy it.
  1032 	OutgoingCmdPendingTsp().RemoveAndDestroy(msg);
  1264 	OutgoingCmdPendingTsp().RemoveAndDestroy(msg);
  1033 
  1265 
  1067 	CRemConMessage& msg = OutgoingNotifyCmdPendingTsp().First();
  1299 	CRemConMessage& msg = OutgoingNotifyCmdPendingTsp().First();
  1068 	// Check that the message is addressed already. If this fails, it's 
  1300 	// Check that the message is addressed already. If this fails, it's 
  1069 	// possible that the TSP has called OutgoingCommandPermitted in response 
  1301 	// possible that the TSP has called OutgoingCommandPermitted in response 
  1070 	// to a AddressOutgoingCommand request.
  1302 	// to a AddressOutgoingCommand request.
  1071 	ASSERT_DEBUG(!msg.Addr().IsNull());
  1303 	ASSERT_DEBUG(!msg.Addr().IsNull());
  1072 	CRemConSession* const sess = Session(msg.SessionId());
  1304 	MRemConMessageSendObserver* const observer = ControllerSession(msg.SessionId());
  1073 	// Session closure removes messages from the outgoing queue and cancels 
  1305 	// Session closure removes messages from the outgoing queue and cancels 
  1074 	// the TSP request if relevant. If sess is NULL here, then this processing 
  1306 	// the TSP request if relevant. If observer is NULL here, then this processing 
  1075 	// has gone wrong.
  1307 	// has gone wrong.
  1076 	ASSERT_DEBUG(sess);
  1308 	ASSERT_DEBUG(observer);
  1077 	TInt err = KErrPermissionDenied;
  1309 	TInt err = KErrPermissionDenied;
  1078 	if ( aIsPermitted )
  1310 	if ( aIsPermitted )
  1079 		{
  1311 		{
  1080 		TBool sync = EFalse;
  1312 		TBool sync = EFalse;
  1081 		TRAP(err, SendCmdToRemoteL(msg, msg.Addr(), sync));
  1313 		TRAP(err, SendCmdToRemoteL(msg, msg.Addr(), sync));
  1082 		if ( err || sync )
  1314 		if ( err || sync )
  1083 			{
  1315 			{
  1084 			sess->SendError() = err;
  1316 			observer->MrcmsoMessageSendResult(msg, err);
  1085 			sess->CompleteSendNotify();
       
  1086 			}
  1317 			}
  1087 		// else the message is waiting until a bearer-level connection 
  1318 		// else the message is waiting until a bearer-level connection 
  1088 		// comes up. Only then can we complete the client's message.
  1319 		// comes up. Only then can we complete the client's message.
  1089 		}
  1320 		}
  1090 	else
  1321 	else
  1091 		{
  1322 		{
  1092 		sess->SendError() = KErrPermissionDenied;
  1323 		observer->MrcmsoMessageSendResult(msg, KErrPermissionDenied);
  1093 		sess->CompleteSendNotify();
       
  1094 		}
  1324 		}
  1095 
  1325 
  1096 	// We've now finished with the message, so destroy it.
  1326 	// We've now finished with the message, so destroy it.
  1097 	OutgoingNotifyCmdPendingTsp().RemoveAndDestroy(msg);
  1327 	OutgoingNotifyCmdPendingTsp().RemoveAndDestroy(msg);
  1098 
  1328 
  1117 	ASSERT_DEBUG(iOutgoingRspPendingTsp);
  1347 	ASSERT_DEBUG(iOutgoingRspPendingTsp);
  1118 	CRemConMessage& msg = iOutgoingRspPendingTsp->First();
  1348 	CRemConMessage& msg = iOutgoingRspPendingTsp->First();
  1119 	
  1349 	
  1120 	iOutgoingRspPendingTsp->Remove(msg);
  1350 	iOutgoingRspPendingTsp->Remove(msg);
  1121 	
  1351 	
  1122 	CRemConSession* const sess = Session(msg.SessionId());	
  1352 	CRemConTargetClientProcess* const client = TargetClient(msg.SessionId());
  1123 	// Session closure removes messages from the outgoing queue and cancels 
  1353 	// Session closure removes messages from the outgoing queue and cancels 
  1124 	// the TSP request if relevant. If sess is NULL here, then this processing 
  1354 	// the TSP request if relevant. If client is NULL here, then this processing 
  1125 	// has gone wrong.
  1355 	// has gone wrong.
  1126 	ASSERT_DEBUG(sess);
  1356 	ASSERT_DEBUG(client);
  1127 
  1357 
  1128 	if (aIsPermitted)
  1358 	if (aIsPermitted)
  1129 		{
  1359 		{
  1130 		ASSERT_DEBUG(iMessageRecipientsList);
  1360 		ASSERT_DEBUG(iMessageRecipientsList);
  1131 		iMessageRecipientsList->RemoveAndDestroyMessage(msg.TransactionId());
  1361 		iMessageRecipientsList->RemoveAndDestroyMessage(msg.TransactionId());
  1132 		CompleteSendResponse(msg, *sess); // Ownership of msg is always taken
  1362 		CompleteSendResponse(msg, *client); // Ownership of msg is always taken
  1133 		}
  1363 		}
  1134 	else
  1364 	else
  1135 		{
  1365 		{
  1136 		CMessageRecipients* messageClients = iMessageRecipientsList->Message(msg.TransactionId());
  1366 		CMessageRecipients* messageClients = iMessageRecipientsList->Message(msg.TransactionId());
  1137 		if (messageClients)
  1367 		if (messageClients)
  1138 			{
  1368 			{
  1139 			messageClients->RemoveAndDestroyClient(sess->ClientInfo()); // Remove the current client info from the list
  1369 			messageClients->RemoveAndDestroyClient(client->ClientInfo()); // Remove the current client info from the list
  1140 			if (messageClients->Clients().IsEmpty())
  1370 			if (messageClients->Clients().IsEmpty())
  1141 				{
  1371 				{
  1142 				iMessageRecipientsList->RemoveAndDestroyMessage(msg.TransactionId());
  1372 				iMessageRecipientsList->RemoveAndDestroyMessage(msg.TransactionId());
  1143 				// The bearer won't be getting a response
  1373 				// The bearer won't be getting a response
  1144 				
  1374 				
  1145 				SendReject(msg.Addr(), msg.InterfaceUid(), msg.OperationId(), msg.TransactionId());
  1375 				SendReject(msg.Addr(), msg.InterfaceUid(), msg.OperationId(), msg.TransactionId());
  1146 				}
  1376 				}
  1147 			}
  1377 			}
  1148 		--sess->NumRemotesToTry();
  1378 
  1149 		sess->SendError() = KErrNone;
  1379 		// Notify client that a send attempt to a remote was abandoned.
  1150 		if (sess->NumRemotesToTry() == 0)
  1380 		client->MrcmsoMessageSendOneOrMoreAbandoned(msg);
  1151 			{
       
  1152 			sess->CompleteSend();
       
  1153 			}
       
  1154 		delete &msg;
  1381 		delete &msg;
  1155 		}
  1382 		}
  1156 	if (!iOutgoingRspPendingTsp->IsEmpty())
  1383 	if (!iOutgoingRspPendingTsp->IsEmpty())
  1157 		{
  1384 		{
  1158 		PermitOutgoingResponse();
  1385 		PermitOutgoingResponse();
  1191 		
  1418 		
  1192 			// If the TSP errored, can't complete to any clients.
  1419 			// If the TSP errored, can't complete to any clients.
  1193 			if ( aError == KErrNone && aClientInfo)
  1420 			if ( aError == KErrNone && aClientInfo)
  1194 				{
  1421 				{
  1195 				LOG1(_L("\t\tprocess ID %d"), static_cast<TUint>(aClientInfo->ProcessId()));
  1422 				LOG1(_L("\t\tprocess ID %d"), static_cast<TUint>(aClientInfo->ProcessId()));
  1196 				// Get the corresponding session.
  1423 				// Get the corresponding client.
  1197 				CRemConSession* const sess = TargetSession(aClientInfo->ProcessId());
  1424 				CRemConTargetClientProcess* const client = TargetClient(aClientInfo->ProcessId());
  1198 				// NB The set of open sessions may have changed while the request 
  1425 				// NB The set of open clients may have changed while the request 
  1199 				// was out on the TSP. If the TSP indicates a session that has 
  1426 				// was out on the TSP. If the TSP indicates a client that has 
  1200 				// gone away, then ignore that session. 
  1427 				// gone away, then ignore that client. 
  1201 				if ( sess )
  1428 				if ( client )
  1202 					{
  1429 					{
  1203 					TRAPD(err, DeliverCmdToClientL(msg, *sess));
  1430 					TRAPD(err, DeliverCmdToClientL(msg, *client));
  1204 					if (err == KErrNone)
  1431 					if (err == KErrNone)
  1205 						{
  1432 						{
  1206 						cmdDelivered = ETrue;
  1433 						cmdDelivered = ETrue;
  1207 						}
  1434 						}
  1208 					// If we couldn't deliver an instance of the command to a 
  1435 					// If we couldn't deliver an instance of the command to a 
  1237 			{
  1464 			{
  1238 			CRemConMessage& msg = IncomingNotifyCmdPendingReAddress().First();
  1465 			CRemConMessage& msg = IncomingNotifyCmdPendingReAddress().First();
  1239 			if(aError == KErrNone && aClientInfo)
  1466 			if(aError == KErrNone && aClientInfo)
  1240 				{
  1467 				{
  1241 				LOG1(_L("\t\tprocess ID %d"), static_cast<TUint>(aClientInfo->ProcessId()));
  1468 				LOG1(_L("\t\tprocess ID %d"), static_cast<TUint>(aClientInfo->ProcessId()));
  1242 				// Get the corresponding session.
  1469 				// Get the corresponding client.
  1243 				CRemConSession* const sess = TargetSession(aClientInfo->ProcessId());
  1470 				CRemConTargetClientProcess* const client = TargetClient(aClientInfo->ProcessId());
  1244 				if (sess)
  1471 				if (client)
  1245 					{
  1472 					{
  1246 					if (sess->Id() == msg.SessionId())
  1473 					if (client->Id() == msg.SessionId())
  1247 						{
  1474 						{
  1248 						// Don't do anything - it's already on IncomingDelivered
  1475 						// Don't do anything - it's already on IncomingDelivered
  1249 						}
  1476 						}
  1250 					else
  1477 					else
  1251 						{
  1478 						{
  1258 								{
  1485 								{
  1259 								// We need to update the subtype now, in case the client has sent an interim response while the notify
  1486 								// We need to update the subtype now, in case the client has sent an interim response while the notify
  1260 								// was being readdressed.
  1487 								// was being readdressed.
  1261 								msg.MsgSubType() = deliveredMsg->MsgSubType();
  1488 								msg.MsgSubType() = deliveredMsg->MsgSubType();
  1262 								// Deliver to the client
  1489 								// Deliver to the client
  1263 								TRAPD(err, DeliverCmdToClientL(msg, *sess));
  1490 								TRAPD(err, DeliverCmdToClientL(msg, *client));
  1264 								if (err == KErrNone)
  1491 								if (err == KErrNone)
  1265 									{
  1492 									{
  1266 									// Only remove the current message if the delivery to the new client suceeded.
  1493 									// Only remove the current message if the delivery to the new client suceeded.
  1267 									IncomingDelivered().RemoveAndDestroy(*deliveredMsg);
  1494 									IncomingDelivered().RemoveAndDestroy(*deliveredMsg);
  1268 									}
  1495 									}
  1330 	LOGINCOMINGNOTIFYCMDPENDINGREADDRESS;
  1557 	LOGINCOMINGNOTIFYCMDPENDINGREADDRESS;
  1331 	}
  1558 	}
  1332 
  1559 
  1333 void CRemConServer::MrctspoDoIncomingCommandPermitted(TBool aIsPermitted)
  1560 void CRemConServer::MrctspoDoIncomingCommandPermitted(TBool aIsPermitted)
  1334 	{
  1561 	{
  1335 	LOG_FUNC
  1562 	LOG_FUNC;
  1336 	
  1563 	
  1337 	MrctspoDoIncomingCommandAddressed(aIsPermitted ? KErrNone : KErrAccessDenied);
  1564 	MrctspoDoIncomingCommandAddressed(aIsPermitted ? KErrNone : KErrAccessDenied);
  1338 	}
  1565 	}
  1339 
  1566 
  1340 void CRemConServer::MrctspoDoIncomingNotifyPermitted(TBool aIsPermitted)
  1567 void CRemConServer::MrctspoDoIncomingNotifyPermitted(TBool aIsPermitted)
  1341 	{
  1568 	{
  1342 	LOG_FUNC
  1569 	LOG_FUNC;
  1343 	
  1570 	
  1344 	if(aIsPermitted)
  1571 	if(aIsPermitted)
  1345 		{
  1572 		{
  1346 		TClientInfo* clientInfo = ClientIdToClientInfo(IncomingNotifyCmdPendingAddress().First().Client());
  1573 		TClientInfo* clientInfo = TargetClientIdToClientInfo(IncomingNotifyCmdPendingAddress().First().Client());
  1347 		MrctspoDoIncomingNotifyAddressed(clientInfo, KErrNone);
  1574 		MrctspoDoIncomingNotifyAddressed(clientInfo, KErrNone);
  1348 		}
  1575 		}
  1349 	else
  1576 	else
  1350 		{
  1577 		{
  1351 		MrctspoDoIncomingNotifyAddressed(NULL, KErrAccessDenied);
  1578 		MrctspoDoIncomingNotifyAddressed(NULL, KErrAccessDenied);
  1365 	// Work out whether the next command to deal with is awaiting (a) 
  1592 	// Work out whether the next command to deal with is awaiting (a) 
  1366 	// addressing or (b) permission.
  1593 	// addressing or (b) permission.
  1367 	// The head item is at index 0. This function should only be called if the 
  1594 	// The head item is at index 0. This function should only be called if the 
  1368 	// queue is not empty.
  1595 	// queue is not empty.
  1369 	CRemConMessage& msg = OutgoingCmdPendingTsp().First();
  1596 	CRemConMessage& msg = OutgoingCmdPendingTsp().First();
  1370 	CRemConSession* const sess = Session(msg.SessionId());
  1597 	CRemConControllerSession* const sess = ControllerSession(msg.SessionId());
  1371 	// The session should exist- if it closed after asking to send this 
  1598 	// The session should exist- if it closed after asking to send this 
  1372 	// message, then the message should have been removed from the outgoing 
  1599 	// message, then the message should have been removed from the outgoing 
  1373 	// pending TSP queue at that time.
  1600 	// pending TSP queue at that time.
  1374 	ASSERT_DEBUG(sess);
  1601 	ASSERT_DEBUG(sess);
  1375 	iTspHandlingOutgoingCommand = ETrue;
  1602 	iTspHandlingOutgoingCommand = ETrue;
  1388 				iBearerManager->BearerSecurityPolicies());	
  1615 				iBearerManager->BearerSecurityPolicies());	
  1389 		}
  1616 		}
  1390 	else
  1617 	else
  1391 		{
  1618 		{
  1392 		// Non-null address means it's awaiting permission to send.
  1619 		// Non-null address means it's awaiting permission to send.
  1393 		sess->NumRemotesToTry() = 1;
  1620 		sess->MrcmsoMessageSendOneOrMoreAttempt(msg, 1);
  1394 		iTspIf->PermitOutgoingCommand(
  1621 		iTspIf->PermitOutgoingCommand(
  1395 			msg.InterfaceUid(),
  1622 			msg.InterfaceUid(),
  1396 			msg.OperationId(), 
  1623 			msg.OperationId(), 
  1397 			sess->ClientInfo(),
  1624 			sess->ClientInfo(),
  1398 			msg.Addr());
  1625 			msg.Addr());
  1412 	// Work out whether the next command to deal with is awaiting (a) 
  1639 	// Work out whether the next command to deal with is awaiting (a) 
  1413 	// addressing or (b) permission.
  1640 	// addressing or (b) permission.
  1414 	// The head item is at index 0. This function should only be called if the 
  1641 	// The head item is at index 0. This function should only be called if the 
  1415 	// queue is not empty.
  1642 	// queue is not empty.
  1416 	CRemConMessage& msg = OutgoingNotifyCmdPendingTsp().First();
  1643 	CRemConMessage& msg = OutgoingNotifyCmdPendingTsp().First();
  1417 	CRemConSession* const sess = Session(msg.SessionId());
  1644 	CRemConControllerSession* const sess = ControllerSession(msg.SessionId());
  1418 	// The session should exist- if it closed after asking to send this 
  1645 	// The session should exist- if it closed after asking to send this 
  1419 	// message, then the message should have been removed from the outgoing 
  1646 	// message, then the message should have been removed from the outgoing 
  1420 	// pending TSP queue at that time.
  1647 	// pending TSP queue at that time.
  1421 	ASSERT_DEBUG(sess);
  1648 	ASSERT_DEBUG(sess);
  1422 	iTspHandlingOutgoingNotifyCommand = ETrue;
  1649 	iTspHandlingOutgoingNotifyCommand = ETrue;
  1431 				iBearerManager->BearerSecurityPolicies());
  1658 				iBearerManager->BearerSecurityPolicies());
  1432 		}
  1659 		}
  1433 	else
  1660 	else
  1434 		{
  1661 		{
  1435 		// Non-null address means it's awaiting permission to send.
  1662 		// Non-null address means it's awaiting permission to send.
  1436 		sess->NumRemotesToTry() = 1;
  1663 		// As this is a notify command, we don't need to adjust NumRemotes() or 
       
  1664 		// NumRemotesToTry() on the session.
  1437 		iTspIf3->PermitOutgoingNotifyCommand(
  1665 		iTspIf3->PermitOutgoingNotifyCommand(
  1438 			msg.InterfaceUid(),
  1666 			msg.InterfaceUid(),
  1439 			msg.OperationId(), 
  1667 			msg.OperationId(), 
  1440 			sess->ClientInfo(),
  1668 			sess->ClientInfo(),
  1441 			msg.Addr());
  1669 			msg.Addr());
  1464 	iTspAddressingIncomingCommand = ETrue;
  1692 	iTspAddressingIncomingCommand = ETrue;
  1465 	
  1693 	
  1466 	if(msg.Client() == KNullClientId)
  1694 	if(msg.Client() == KNullClientId)
  1467 		{
  1695 		{
  1468 		// Prepare the array of target process IDs for the TSP.
  1696 		// Prepare the array of target process IDs for the TSP.
  1469 		iSessionsLock.Wait();
  1697 		iTargetClientsLock.Wait();
  1470 		const TUint count = iSessions.Count();
  1698 		const TUint count = iTargetClients.Count();
  1471 		for ( TUint ii = 0 ; ii < count ; ++ii )
  1699 		for ( TUint ii = 0 ; ii < count ; ++ii )
  1472 			{
  1700 			{
  1473 			CRemConSession* const sess = iSessions[ii];
  1701 			CRemConTargetClientProcess* const client = iTargetClients[ii];
  1474 			ASSERT_DEBUG(sess);
  1702 			ASSERT_DEBUG(client);
  1475 			if ( sess->Type() == ERemConClientTypeTarget )
  1703 			iTspIncomingCmdClients.AddLast(client->ClientInfo());
  1476 				{
  1704 			}
  1477 				iTspIncomingCmdClients.AddLast(sess->ClientInfo());
  1705 		iTargetClientsLock.Signal();
  1478 				}
       
  1479 			}
       
  1480 		iSessionsLock.Signal();
       
  1481 		
  1706 		
  1482 		iTspIf->AddressIncomingCommand(
  1707 		iTspIf->AddressIncomingCommand(
  1483 			msg.InterfaceUid(),
  1708 			msg.InterfaceUid(),
  1484 			msg.OperationId(),
  1709 			msg.OperationId(),
  1485 			iTspIncomingCmdClients);
  1710 			iTspIncomingCmdClients);
  1486 		}
  1711 		}
  1487 	else
  1712 	else
  1488 		{
  1713 		{
  1489 		iTspIncomingCmdClients.AddLast(*ClientIdToClientInfo(msg.Client()));
  1714 		iTspIncomingCmdClients.AddLast(*TargetClientIdToClientInfo(msg.Client()));
  1490 		ASSERT_DEBUG(iTspIf4);
  1715 		ASSERT_DEBUG(iTspIf4);
  1491 		iTspIf4->PermitIncomingCommand(
  1716 		iTspIf4->PermitIncomingCommand(
  1492 			msg.InterfaceUid(),
  1717 			msg.InterfaceUid(),
  1493 			msg.OperationId(),
  1718 			msg.OperationId(),
  1494 			*iTspIncomingCmdClients.First());
  1719 			*iTspIncomingCmdClients.First());
  1519 	if(!FindDuplicateNotify(msg))
  1744 	if(!FindDuplicateNotify(msg))
  1520 		{
  1745 		{
  1521 		if(msg.Client() == KNullClientId)
  1746 		if(msg.Client() == KNullClientId)
  1522 			{
  1747 			{
  1523 			// Prepare the array of target process IDs for the TSP.
  1748 			// Prepare the array of target process IDs for the TSP.
  1524 			iSessionsLock.Wait();
  1749 			iTargetClientsLock.Wait();
  1525 			const TUint count = iSessions.Count();
  1750 			const TUint count = iTargetClients.Count();
  1526 			for ( TUint ii = 0 ; ii < count ; ++ii )
  1751 			for ( TUint ii = 0 ; ii < count ; ++ii )
  1527 				{
  1752 				{
  1528 				CRemConSession* const sess = iSessions[ii];
  1753 				CRemConTargetClientProcess* const client = iTargetClients[ii];
  1529 				ASSERT_DEBUG(sess);
  1754 				ASSERT_DEBUG(client);
  1530 				if ( sess->Type() == ERemConClientTypeTarget )
  1755 				iTspIncomingNotifyCmdClients.AddLast(client->ClientInfo());
  1531 					{
  1756 				}
  1532 					iTspIncomingNotifyCmdClients.AddLast(sess->ClientInfo());
  1757 			iTargetClientsLock.Signal();
  1533 					}
       
  1534 				}
       
  1535 			iSessionsLock.Signal();
       
  1536 			
  1758 			
  1537 			// Only send the notify to the TSP if there isn't an identical one on either incomingpendingdelivery or incomingdelivered
  1759 			// Only send the notify to the TSP if there isn't an identical one on either incomingpendingdelivery or incomingdelivered
  1538 			iTspIf2->AddressIncomingNotify(
  1760 			iTspIf2->AddressIncomingNotify(
  1539 					msg.InterfaceUid(),
  1761 					msg.InterfaceUid(),
  1540 					msg.OperationId(),
  1762 					msg.OperationId(),
  1541 					iTspIncomingNotifyCmdClients);
  1763 					iTspIncomingNotifyCmdClients);
  1542 			}
  1764 			}
  1543 		else
  1765 		else
  1544 			{
  1766 			{
  1545 			iTspIncomingNotifyCmdClients.AddLast(*ClientIdToClientInfo(msg.Client()));
  1767 			iTspIncomingNotifyCmdClients.AddLast(*TargetClientIdToClientInfo(msg.Client()));
  1546 			ASSERT_DEBUG(iTspIf4);
  1768 			ASSERT_DEBUG(iTspIf4);
  1547 			iTspIf4->PermitIncomingNotify(
  1769 			iTspIf4->PermitIncomingNotify(
  1548 				msg.InterfaceUid(),
  1770 				msg.InterfaceUid(),
  1549 				msg.OperationId(),
  1771 				msg.OperationId(),
  1550 				*iTspIncomingNotifyCmdClients.First());
  1772 				*iTspIncomingNotifyCmdClients.First());
  1566 	// For TSPs which complete this request synchronously this will become 
  1788 	// For TSPs which complete this request synchronously this will become 
  1567 	// recursive, but the depth is not expected to be great (== number of 
  1789 	// recursive, but the depth is not expected to be great (== number of 
  1568 	// messages awaiting addressing).
  1790 	// messages awaiting addressing).
  1569 	// Prepare the array of target process IDs for the TSP.
  1791 	// Prepare the array of target process IDs for the TSP.
  1570 	iTspIncomingNotifyCmdClients.Reset();
  1792 	iTspIncomingNotifyCmdClients.Reset();
  1571 	iSessionsLock.Wait();
  1793 	iTargetClientsLock.Wait();
  1572 	const TUint count = iSessions.Count();
  1794 	const TUint count = iTargetClients.Count();
  1573 	for ( TUint ii = 0 ; ii < count ; ++ii )
  1795 	for ( TUint ii = 0 ; ii < count ; ++ii )
  1574 		{
  1796 		{
  1575 		CRemConSession* const sess = iSessions[ii];
  1797 		CRemConTargetClientProcess* const client = iTargetClients[ii];
  1576 		ASSERT_DEBUG(sess);
  1798 		ASSERT_DEBUG(client);
  1577 		if ( sess->Type() == ERemConClientTypeTarget )
  1799 		iTspIncomingNotifyCmdClients.AddLast(client->ClientInfo());
  1578 			{
  1800 		}
  1579 			iTspIncomingNotifyCmdClients.AddLast(sess->ClientInfo());
  1801 	iTargetClientsLock.Signal();
  1580 			}
       
  1581 		}
       
  1582 	iSessionsLock.Signal();
       
  1583 	
  1802 	
  1584 	// This function should only be called if we know this queue is not 
  1803 	// This function should only be called if we know this queue is not 
  1585 	// empty.
  1804 	// empty.
  1586 	CRemConMessage& msg = IncomingNotifyCmdPendingReAddress().First();
  1805 	CRemConMessage& msg = IncomingNotifyCmdPendingReAddress().First();
  1587 	iTspIf2->AddressIncomingNotify(
  1806 	iTspIf2->AddressIncomingNotify(
  1599 	ASSERT_DEBUG(iTspHandlingOutgoingResponse == EFalse);
  1818 	ASSERT_DEBUG(iTspHandlingOutgoingResponse == EFalse);
  1600 	ASSERT_DEBUG(!OutgoingRspPendingTsp().IsEmpty());
  1819 	ASSERT_DEBUG(!OutgoingRspPendingTsp().IsEmpty());
  1601 	while (!iTspHandlingOutgoingResponse && !OutgoingRspPendingTsp().IsEmpty())
  1820 	while (!iTspHandlingOutgoingResponse && !OutgoingRspPendingTsp().IsEmpty())
  1602 		{
  1821 		{
  1603 		CRemConMessage& msg = OutgoingRspPendingTsp().First();
  1822 		CRemConMessage& msg = OutgoingRspPendingTsp().First();
  1604 		CRemConSession* session = Session(msg.SessionId());
  1823 		CRemConTargetClientProcess* client = TargetClient(msg.SessionId());
  1605 		// The session should exist- if it closed after asking to send this 
  1824 		// The client should exist- if it closed after asking to send this 
  1606 		// message, then the message should have been removed from the outgoing 
  1825 		// message, then the message should have been removed from the outgoing 
  1607 		// pending TSP queue at that time.		
  1826 		// pending TSP queue at that time.		
  1608 		ASSERT_DEBUG(session);
  1827 		ASSERT_DEBUG(client);
  1609 		ASSERT_DEBUG(iMessageRecipientsList);
  1828 		ASSERT_DEBUG(iMessageRecipientsList);
  1610 		CMessageRecipients* message = iMessageRecipientsList->Message(msg.TransactionId());
  1829 		CMessageRecipients* message = iMessageRecipientsList->Message(msg.TransactionId());
  1611 
  1830 
  1612 		if (message) // If we aren't returned a client list, this means that the message has been delivered elsewhere
  1831 		if (message) // If we aren't returned a client list, this means that the message has been delivered elsewhere
  1613 			{
  1832 			{
  1615 			if (iTspIf2)
  1834 			if (iTspIf2)
  1616 				{
  1835 				{
  1617 				iTspIf2->PermitOutgoingResponse(
  1836 				iTspIf2->PermitOutgoingResponse(
  1618 						msg.InterfaceUid(),
  1837 						msg.InterfaceUid(),
  1619 						msg.OperationId(),
  1838 						msg.OperationId(),
  1620 						session->ClientInfo(),
  1839 						client->ClientInfo(),
  1621 						message->ConstIter()
  1840 						message->ConstIter()
  1622 						);
  1841 						);
  1623 				}
  1842 				}
  1624 			else
  1843 			else
  1625 				{
  1844 				{
  1626 				OutgoingResponsePermitted(ETrue);
  1845 				OutgoingResponsePermitted(ETrue);
  1627 				}
  1846 				}
  1628 			}
  1847 			}
  1629 		else
  1848 		else
  1630 			{
  1849 			{
  1631 			session->NumRemotes() = 0;
  1850 			client->MrcmsoMessageSendOneOrMoreAbandoned(msg);
  1632 			--session->NumRemotesToTry();
       
  1633 			session->SendError() = KErrNone;
       
  1634 			session->CompleteSend();
       
  1635 			OutgoingRspPendingTsp().RemoveAndDestroy(msg);
  1851 			OutgoingRspPendingTsp().RemoveAndDestroy(msg);
  1636 			}
  1852 			}
  1637 		}
  1853 		}
  1638 	LOGOUTGOINGRSPPENDINGTSP;
  1854 	LOGOUTGOINGRSPPENDINGTSP;
  1639 	}
  1855 	}
  1718 		}
  1934 		}
  1719 
  1935 
  1720 	LOG1(_L("\taSync = %d"), aSync);
  1936 	LOG1(_L("\taSync = %d"), aSync);
  1721 	}
  1937 	}
  1722 
  1938 
  1723 void CRemConServer::DeliverCmdToClientL(const CRemConMessage& aMsg, CRemConSession& aSess)
  1939 void CRemConServer::DeliverCmdToClientL(const CRemConMessage& aMsg, CRemConTargetClientProcess& aClient)
  1724 	{
  1940 	{
  1725 	LOG_FUNC;
  1941 	LOG_FUNC;
  1726 
  1942 
  1727 	ASSERT_DEBUG((aMsg.MsgType() == ERemConCommand) || (aMsg.MsgType() == ERemConNotifyCommand)); 
  1943 	ASSERT_DEBUG((aMsg.MsgType() == ERemConCommand) || (aMsg.MsgType() == ERemConNotifyCommand)); 
  1728 	// Take a copy of the message and set the right session ID (important to 
  1944 	// Take a copy of the message and set the right client ID (important to 
  1729 	// set the selected session's ID because this is how we match up the 
  1945 	// set the selected client's ID because this is how we match up the 
  1730 	// client's response, if aMsg is a command). 
  1946 	// client's response, if aMsg is a command). 
  1731 	CRemConMessage* const newMsg = CRemConMessage::CopyL(aMsg);
  1947 	CRemConMessage* const newMsg = CRemConMessage::CopyL(aMsg);
  1732 	newMsg->SessionId() = aSess.Id();
  1948 	newMsg->SessionId() = aClient.Id();
  1733 	LEAVEIFERRORL(DeliverMessageToClient(*newMsg, aSess));
  1949 	LEAVEIFERRORL(DeliverMessageToClient(*newMsg, aClient));
  1734 	}
  1950 	}
  1735 
  1951 
  1736 TInt CRemConServer::DeliverMessageToClient(CRemConMessage& aMsg, CRemConSession& aSess)
  1952 TInt CRemConServer::DeliverMessageToClient(CRemConMessage& aMsg, CRemConControllerSession& aSess)
  1737 	{
  1953 	{
  1738 	LOG_FUNC;
  1954 	LOG_FUNC;
  1739 	LOGINCOMINGPENDINGDELIVERY;
  1955 	LOGINCOMINGPENDINGDELIVERY;
  1740 	LOGINCOMINGDELIVERED;
  1956 	LOGINCOMINGDELIVERED;
       
  1957 
       
  1958 	// Controller clients only receive responses or rejects
       
  1959 	ASSERT_DEBUG(aMsg.MsgType() == ERemConResponse || aMsg.MsgType() == ERemConReject);
       
  1960 
  1741 	TInt err = KErrNone;
  1961 	TInt err = KErrNone;
  1742 
  1962 
  1743 	// First off check if the client supports this
  1963 	// First off check if the client supports this
  1744 	if(!aSess.SupportedMessage(aMsg))
  1964 	if(!aSess.SupportedMessage(aMsg))
  1745         {
  1965 		{
  1746         err = KErrArgument;
  1966 		err = KErrArgument;
  1747         
  1967         
  1748         // 'Take ownership' of it by destroying it- it's finished with.
  1968 		// 'Take ownership' of it by destroying it- it's finished with.
  1749         delete &aMsg;
  1969 		delete &aMsg;
  1750         }
  1970 		}
  1751 	else if ( aSess.CurrentReceiveMessage().Handle() )
  1971 	else if ( aSess.CurrentReceiveMessage().Handle() )
  1752 		{
  1972 		{
  1753 		// If the client can take the message now put it on the right queue.
       
  1754 
       
  1755 		err = aSess.WriteMessageToClient (aMsg);
  1973 		err = aSess.WriteMessageToClient (aMsg);
  1756 		// If the message was a command, and it was delivered with no error, 
  1974 
       
  1975 		// 'Take ownership' of it by destroying it- it's finished with.			
       
  1976 		delete &aMsg;
       
  1977 		}
       
  1978 	else
       
  1979 		{
       
  1980 		IncomingPendingDelivery().Append(aMsg);
       
  1981 		}
       
  1982 	
       
  1983 	LOGINCOMINGPENDINGDELIVERY;
       
  1984 	LOGINCOMINGDELIVERED;
       
  1985 	return err;
       
  1986 	}
       
  1987 
       
  1988 TInt CRemConServer::DeliverMessageToClient(CRemConMessage& aMsg, CRemConTargetClientProcess& aClient)
       
  1989 	{
       
  1990 	LOG_FUNC;
       
  1991 	LOGINCOMINGPENDINGDELIVERY;
       
  1992 	LOGINCOMINGDELIVERED;
       
  1993 
       
  1994 	TInt err = KErrNone;
       
  1995 
       
  1996 	// Target clients only receive commands
       
  1997 	ASSERT_DEBUG(aMsg.MsgType() == ERemConCommand || aMsg.MsgType() == ERemConNotifyCommand);
       
  1998 
       
  1999 	// Pass message to client
       
  2000 	err = aClient.ReceiveMessage(aMsg);
       
  2001 
       
  2002 	if (err == KErrArgument)
       
  2003 		{
       
  2004 		// Message not supported.
       
  2005 		// 'Take ownership' of it by destroying it- it's finished with.
       
  2006 		delete &aMsg;
       
  2007 		}
       
  2008 	else if (err == KErrNotReady)
       
  2009 		{
       
  2010 		err = KErrNone;
       
  2011 		// Client cannot receive this message at the moment.
       
  2012 		IncomingPendingDelivery().Append(aMsg);	
       
  2013 		}
       
  2014 	else 
       
  2015 		{
       
  2016 		// If the message was delivered with no error, 
  1757 		// then put it in the 'incoming delivered' log. Otherwise, delete it 
  2017 		// then put it in the 'incoming delivered' log. Otherwise, delete it 
  1758 		// because it's finished with.
  2018 		// because it's finished with.
  1759 		if ((aMsg.MsgType() == ERemConCommand) || (aMsg.MsgType() == ERemConNotifyCommand))
  2019 		if (err == KErrNone)
  1760 			{
  2020 			{
  1761 			if (err == KErrNone )
  2021 			// We'll need to remember it for the response coming back.
  1762 				{
  2022 			IncomingDelivered().Append(aMsg); 
  1763 				// We'll need to remember it for the response coming back.
       
  1764 				IncomingDelivered().Append(aMsg); 
       
  1765 				}
       
  1766 			else
       
  1767 				{
       
  1768 				// 'Take ownership' of it by destroying it- it's finished with.
       
  1769 				delete &aMsg;
       
  1770 				}
       
  1771 			}
  2023 			}
  1772 		else
  2024 		else
  1773 			{
  2025 			{
  1774 			// 'Take ownership' of it by destroying it- it's finished with.			
  2026 			// 'Take ownership' of it by destroying it- it's finished with.
  1775 			delete &aMsg;
  2027 			delete &aMsg;
  1776 			}
  2028 			}
  1777 		}
       
  1778 	else
       
  1779 		{
       
  1780 		IncomingPendingDelivery().Append(aMsg);
       
  1781 		}
  2029 		}
  1782 	
  2030 	
  1783 	LOGINCOMINGPENDINGDELIVERY;
  2031 	LOGINCOMINGPENDINGDELIVERY;
  1784 	LOGINCOMINGDELIVERED;
  2032 	LOGINCOMINGDELIVERED;
  1785 	return err;
  2033 	return err;
  1835 			if (canDeliver)
  2083 			if (canDeliver)
  1836 				{
  2084 				{
  1837 				while ( ( procId = iter++ ) != NULL )
  2085 				while ( ( procId = iter++ ) != NULL )
  1838 					{
  2086 					{
  1839 					LOG1(_L("\t\tprocess ID %d"), static_cast<TUint>(procId->ProcessId()));
  2087 					LOG1(_L("\t\tprocess ID %d"), static_cast<TUint>(procId->ProcessId()));
  1840 					// Get the corresponding session.
  2088 					// Get the corresponding client.
  1841 					CRemConSession* const sess = TargetSession(procId->ProcessId());
  2089 					CRemConTargetClientProcess* const client = TargetClient(procId->ProcessId());
  1842 					// NB The set of open sessions may have changed while the request 
  2090 					// NB The set of open clients may have changed while the request 
  1843 					// was out on the TSP. If the TSP indicates a session that has 
  2091 					// was out on the TSP. If the TSP indicates a client that has 
  1844 					// gone away, then ignore that session. 
  2092 					// gone away, then ignore that client. 
  1845 					if ( sess )
  2093 					if ( client )
  1846 						{
  2094 						{
  1847 						TInt err = KErrNone;
  2095 						TInt err = KErrNone;
  1848 						TClientInfo* clientInfo = NULL;
  2096 						TClientInfo* clientInfo = NULL;
  1849 						TRAP(err, clientInfo = new (ELeave) TClientInfo);
  2097 						TRAP(err, clientInfo = new (ELeave) TClientInfo);
  1850 						if (err == KErrNone)
  2098 						if (err == KErrNone)
  1851 							{
  2099 							{
  1852 							// If we didn't manage to create the TClientInfo, we shouldn't deliver to the client
  2100 							// If we didn't manage to create the TClientInfo, we shouldn't deliver to the client
  1853 							TRAP(err, DeliverCmdToClientL(msg, *sess));
  2101 							TRAP(err, DeliverCmdToClientL(msg, *client));
  1854 							}
  2102 							}
  1855 						if (err == KErrNone)
  2103 						if (err == KErrNone)
  1856 							{
  2104 							{
  1857 							cmdDelivered = ETrue;
  2105 							cmdDelivered = ETrue;
  1858 							// Add to the delivered information queue
  2106 							// Add to the delivered information queue
  1933 TInt CRemConServer::MrctspoSetLocalAddressedClient(const TUid& aBearerUid, const TClientInfo& aClientInfo)
  2181 TInt CRemConServer::MrctspoSetLocalAddressedClient(const TUid& aBearerUid, const TClientInfo& aClientInfo)
  1934 	{
  2182 	{
  1935 	LOG_FUNC;
  2183 	LOG_FUNC;
  1936 	
  2184 	
  1937 	TRemConClientId id = KNullClientId;
  2185 	TRemConClientId id = KNullClientId;
  1938 	iSessionsLock.Wait();
  2186 	iTargetClientsLock.Wait();
  1939 	const TUint count = iSessions.Count();
  2187 	const TUint count = iTargetClients.Count();
  1940 	for(TUint i=0; i<count; i++)
  2188 	for(TUint i=0; i<count; i++)
  1941 		{
  2189 		{
  1942 		CRemConSession* const sess = iSessions[i];
  2190 		CRemConTargetClientProcess* const client = iTargetClients[i];
  1943 		ASSERT_DEBUG(sess);
  2191 		ASSERT_DEBUG(client);
  1944 		if(sess->ClientInfo().ProcessId() == aClientInfo.ProcessId())
  2192 		if(client->ClientInfo().ProcessId() == aClientInfo.ProcessId())
  1945 			{
  2193 			{
  1946 			id = sess->Id();
  2194 			id = client->Id();
  1947 			break;
  2195 			break;
  1948 			}
  2196 			}
  1949 		}
  2197 		}
  1950 	iSessionsLock.Signal();
  2198 	iTargetClientsLock.Signal();
  1951 	
  2199 	
  1952 	if(id != KNullClientId)
  2200 	if(id != KNullClientId)
  1953 		{
  2201 		{
  1954 		ASSERT_DEBUG(iBearerManager);
  2202 		ASSERT_DEBUG(iBearerManager);
  1955 		return iBearerManager->SetLocalAddressedClient(aBearerUid, id);
  2203 		return iBearerManager->SetLocalAddressedClient(aBearerUid, id);
  2055 				TspOutgoingNotifyCommand();
  2303 				TspOutgoingNotifyCommand();
  2056 				}
  2304 				}
  2057 			}
  2305 			}
  2058 		else
  2306 		else
  2059 			{
  2307 			{
  2060 			CRemConSession* const sess = Session(aMsg.SessionId());
  2308 			CRemConControllerSession* const sess = ControllerSession(aMsg.SessionId());
  2061 			delete &aMsg;
  2309 			delete &aMsg;
  2062 			ASSERT_DEBUG(sess);
  2310 			ASSERT_DEBUG(sess);
  2063 			sess->SendError() = KErrNotSupported;
  2311 			sess->SendError() = KErrNotSupported;
  2064 			sess->CompleteSend();
  2312 			sess->CompleteSend();
  2065 			}
  2313 			}
  2066 		}
  2314 		}
  2067 	
  2315 	
  2068 	}
  2316 	}
  2069 
  2317 
  2070 void CRemConServer::SendResponse(CRemConMessage& aMsg, CRemConSession& aSess)
  2318 void CRemConServer::SendResponse(CRemConMessage& aMsg, CRemConTargetClientProcess& aClient)
  2071 	{
  2319 	{
  2072 	LOG_FUNC;
  2320 	LOG_FUNC;
  2073 	LOGINCOMINGDELIVERED;
  2321 	LOGINCOMINGDELIVERED;
  2074 	LOGOUTGOINGRSPPENDINGTSP;
  2322 	LOGOUTGOINGRSPPENDINGTSP;
  2075 	LOGOUTGOINGPENDINGSEND;
  2323 	LOGOUTGOINGPENDINGSEND;
  2082 	// we're sending, and send the response to the same address that John came 
  2330 	// we're sending, and send the response to the same address that John came 
  2083 	// from.
  2331 	// from.
  2084 	TSglQueIter<CRemConMessage>& iter = IncomingDelivered().SetToFirst();
  2332 	TSglQueIter<CRemConMessage>& iter = IncomingDelivered().SetToFirst();
  2085 	CRemConMessage* msg;
  2333 	CRemConMessage* msg;
  2086 	TBool found = EFalse;
  2334 	TBool found = EFalse;
       
  2335 	
  2087 	while ( ( msg = iter++ ) != NULL )
  2336 	while ( ( msg = iter++ ) != NULL )
  2088 		{
  2337 		{
  2089 		if (	msg->SessionId() == aSess.Id()
  2338 		if (	msg->SessionId() == aClient.Id()
  2090 			&&	msg->InterfaceUid() == response->InterfaceUid()
  2339 			&&	msg->InterfaceUid() == response->InterfaceUid()
  2091 			&&	msg->OperationId() == response->OperationId()
  2340 			&&	msg->OperationId() == response->OperationId()
  2092 			&&  (
  2341 			&&  (
  2093 					(msg->MsgSubType() == ERemConMessageDefault && response->MsgSubType() == ERemConMessageDefault)
  2342 					(msg->MsgSubType() == ERemConMessageDefault && response->MsgSubType() == ERemConMessageDefault)
  2094 				||  (msg->MsgSubType() == ERemConNotifyCommandAwaitingInterim && response->MsgSubType() == ERemConNotifyResponseInterim)
  2343 				||  (msg->MsgSubType() == ERemConNotifyCommandAwaitingInterim && response->MsgSubType() == ERemConNotifyResponseInterim)
  2096 				)
  2345 				)
  2097 			)
  2346 			)
  2098 			{
  2347 			{
  2099 			LOG1(_L("\tfound a matching item in the incoming delivered commands log: [0x%08x]"), msg);
  2348 			LOG1(_L("\tfound a matching item in the incoming delivered commands log: [0x%08x]"), msg);
  2100 			found = ETrue;
  2349 			found = ETrue;
  2101 			++aSess.NumRemotesToTry();
       
  2102 
  2350 
  2103 			// Set the right address and transaction id in the outgoing message
  2351 			// Set the right address and transaction id in the outgoing message
  2104 			response->Addr() = msg->Addr();
  2352 			response->Addr() = msg->Addr();
  2105 			response->TransactionId() = msg->TransactionId();
  2353 			response->TransactionId() = msg->TransactionId();
  2106 			
  2354 			
  2107 			if(msg->MsgType() == ERemConCommand)
  2355 			if(msg->MsgType() == ERemConCommand)
  2108 				{
  2356 				{
       
  2357 				// Notify client (this shall go to one remote)
       
  2358 				aClient.MrcmsoMessageSendOneOrMoreAttempt(*response, 1);
       
  2359 			
  2109 				// Check the normal command and response have the default subtype set
  2360 				// Check the normal command and response have the default subtype set
  2110 				ASSERT_DEBUG(msg->MsgSubType() == ERemConMessageDefault && response->MsgSubType() == ERemConMessageDefault);
  2361 				ASSERT_DEBUG(msg->MsgSubType() == ERemConMessageDefault && response->MsgSubType() == ERemConMessageDefault);
  2111 
  2362 
  2112 				// Remove the item from the 'incoming delivered' queue now we've 
  2363 				// Remove the item from the 'incoming delivered' queue now we've 
  2113 				// addressed a response using it.
  2364 				// addressed a response using it.
  2122 					PermitOutgoingResponse();
  2373 					PermitOutgoingResponse();
  2123 					}
  2374 					}
  2124 				}
  2375 				}
  2125 			else
  2376 			else
  2126 				{
  2377 				{
       
  2378 				// Notify client (this may be a series of messages to remotes)
       
  2379 				aClient.MrcmsoMessageSendOneOrMoreIncremental(*msg, 1);
       
  2380 
  2127 				// Check the command is a notify command
  2381 				// Check the command is a notify command
  2128 				ASSERT_DEBUG(msg->MsgType() == ERemConNotifyCommand);
  2382 				ASSERT_DEBUG(msg->MsgType() == ERemConNotifyCommand);
  2129 				
  2383 				
  2130 				// Check the command has a valid subtype for a notify command
  2384 				// Check the command has a valid subtype for a notify command
  2131 				ASSERT_DEBUG(msg->MsgSubType() == ERemConNotifyCommandAwaitingInterim || msg->MsgSubType() == ERemConNotifyCommandAwaitingChanged);
  2385 				ASSERT_DEBUG(msg->MsgSubType() == ERemConNotifyCommandAwaitingInterim || msg->MsgSubType() == ERemConNotifyCommandAwaitingChanged);
  2171 
  2425 
  2172 	TSglQueIter<CRemConMessage>& rspIter = OutgoingRspPendingSend().SetToFirst();
  2426 	TSglQueIter<CRemConMessage>& rspIter = OutgoingRspPendingSend().SetToFirst();
  2173 	while ((msg = rspIter++) != NULL)
  2427 	while ((msg = rspIter++) != NULL)
  2174 		{
  2428 		{
  2175 		OutgoingRspPendingSend().Remove(*msg);
  2429 		OutgoingRspPendingSend().Remove(*msg);
  2176 		CompleteSendResponse(*msg, aSess);
  2430 		CompleteSendResponse(*msg, aClient);
  2177 		}
  2431 		}
  2178 
  2432 
  2179 	
  2433 	
  2180 	// If the command was not found, then the app has sent a response to a
  2434 	// If the command was not found, then the app has sent a response to a
  2181 	// non-existant command.  It may do this in good intention if the server 
  2435 	// non-existant command.  It may do this in good intention if the server 
  2182 	// has transparently died and been restarted between the app's reception
  2436 	// has transparently died and been restarted between the app's reception
  2183 	// of the command and it sending its response, so we can't panic it.
  2437 	// of the command and it sending its response, so we can't panic it.
  2184 	// Just drop the message.
  2438 	// Just drop the message.
  2185 	if ( !found )
  2439 	if ( !found )
  2186 		{
  2440 		{
  2187 		// Complete the message with KErrNone.  We have done all we can with
  2441 		// Inform client that message should be completed with KErrNone We 
  2188 		// it.  Any other error may encourage retries from the application,
  2442 		// have done all we can with it.  Any other error may encourage 
  2189 		// which would be useless in this situation.
  2443 		// retries from the application, which would be useless in this situation.
  2190 		aSess.NumRemotes() = 0;
  2444 		aClient.MrcmsoMessageSendOneOrMoreAttemptFailed(aMsg, KErrNone);
  2191 		aSess.SendError() = KErrNone;
       
  2192 		delete &aMsg;
  2445 		delete &aMsg;
  2193 		}
  2446 		}
  2194 	
  2447 	
  2195 	if (aSess.NumRemotesToTry() == 0)
       
  2196 		{
       
  2197 		aSess.CompleteSend();
       
  2198 		}
       
  2199 
       
  2200 	LOGOUTGOINGRSPPENDINGTSP;
  2448 	LOGOUTGOINGRSPPENDINGTSP;
  2201 	LOGINCOMINGDELIVERED;
  2449 	LOGINCOMINGDELIVERED;
  2202 	LOGOUTGOINGPENDINGSEND;
  2450 	LOGOUTGOINGPENDINGSEND;
  2203 	}
  2451 	}
  2204 
  2452 
  2205 void CRemConServer::CompleteSendResponse(CRemConMessage& aMsg, CRemConSession& aSess)
  2453 void CRemConServer::CompleteSendResponse(CRemConMessage& aMsg, CRemConTargetClientProcess& aClient)
  2206 	{
  2454 	{
  2207 	LOG_FUNC;
  2455 	LOG_FUNC;
  2208 	LOGOUTGOINGPENDINGSEND;
  2456 	LOGOUTGOINGPENDINGSEND;
  2209 	// If the bearer-level connection exists, then send the message. 
  2457 	// If the bearer-level connection exists, then send the message. 
  2210 	// Otherwise, queue the message and request the connection to come 
  2458 	// Otherwise, queue the message and request the connection to come 
  2219 		case EConnected:
  2467 		case EConnected:
  2220 			{
  2468 			{
  2221 			// We're already connected
  2469 			// We're already connected
  2222 			// If the bearer couldn't send, we need to error the client.
  2470 			// If the bearer couldn't send, we need to error the client.
  2223 			TInt err = iBearerManager->Send(aMsg);
  2471 			TInt err = iBearerManager->Send(aMsg);
  2224 			// Complete client's message. Bearer-level error means the 
  2472 			
  2225 			// response got sent to zero remotes- bearer-level success 
  2473 			// Inform client that message should be completed with err. 
  2226 			// means it got sent to precisely 1.
  2474 			// Bearer-level error means the response got sent to zero remotes- 
  2227 			--aSess.NumRemotesToTry();
  2475 			// bearer-level success means it got sent to precisely 1.
  2228 			if (err == KErrNone)
  2476 			aClient.MrcmsoMessageSendOneOrMoreResult(aMsg, err);
  2229 				{
  2477 
  2230 				++aSess.NumRemotes();
       
  2231 				}
       
  2232 			aSess.SendError() = err;
       
  2233 			if (aSess.NumRemotesToTry() == 0)
       
  2234 				{
       
  2235 				aSess.CompleteSend();
       
  2236 				}
       
  2237 			// We've now finished with the response.
  2478 			// We've now finished with the response.
  2238 			delete &aMsg;
  2479 			delete &aMsg;
  2239 			break;
  2480 			break;
  2240 			}
  2481 			}
  2241 		case EDisconnected:
  2482 		case EDisconnected:
  2246 			// ... and ask the bearer to establish a connection. If we 
  2487 			// ... and ask the bearer to establish a connection. If we 
  2247 			// couldn't then complete the client's message and clean up.
  2488 			// couldn't then complete the client's message and clean up.
  2248 			TInt err = iBearerManager->Connect(aMsg.Addr());
  2489 			TInt err = iBearerManager->Connect(aMsg.Addr());
  2249 			if ( err != KErrNone )
  2490 			if ( err != KErrNone )
  2250 				{
  2491 				{
       
  2492 				aClient.MrcmsoMessageSendOneOrMoreResult(aMsg, err);
  2251 				OutgoingPendingSend().RemoveAndDestroy(aMsg);
  2493 				OutgoingPendingSend().RemoveAndDestroy(aMsg);
  2252 				aSess.NumRemotes() = 0;
       
  2253 				--aSess.NumRemotesToTry();
       
  2254 				aSess.SendError() = err;
       
  2255 				aSess.CompleteSend();
       
  2256 				}
  2494 				}
  2257 			break;
  2495 			break;
  2258 			}
  2496 			}
  2259 		case EConnecting:
  2497 		case EConnecting:
  2260 		case EDisconnecting:
  2498 		case EDisconnecting:
  2347 			}
  2585 			}
  2348 		}
  2586 		}
  2349 	LOGOUTGOINGPENDINGSEND;
  2587 	LOGOUTGOINGPENDINGSEND;
  2350 	}
  2588 	}
  2351 
  2589 
  2352 void CRemConServer::SendCancel(CRemConSession& aSess)
  2590 void CRemConServer::SendCancel(CRemConControllerSession& aSess)
  2353 	{
  2591 	{
  2354 	LOG_FUNC;
  2592 	LOG_FUNC;
  2355 	LOGOUTGOINGCMDPENDINGTSP;
  2593 	LOGOUTGOINGCMDPENDINGTSP;
  2356 	
  2594 	
  2357 	TSglQueIter<CRemConMessage>& iter = OutgoingCmdPendingTsp().SetToFirst();
  2595 	TSglQueIter<CRemConMessage>& iter = OutgoingCmdPendingTsp().SetToFirst();
  2358 	CRemConMessage* msg;
  2596 	CRemConMessage* msg;
  2359 	TBool first = ETrue;
  2597 	TBool first = ETrue;
  2360 	while ( ( msg = iter++ ) != NULL )
  2598 	while ( ( msg = iter++ ) != NULL )
  2361 		{
  2599 		{
  2362 		// A client can only have one send outstanding at once, so there can 
  2600 		// A session can only have one send outstanding at once, so there can 
  2363 		// only be one message on the queue belonging to it.
  2601 		// only be one message on the queue belonging to it.
  2364 		if ( msg->SessionId() == aSess.Id() )
  2602 		if ( msg->SessionId() == aSess.Id() )
  2365 			{
  2603 			{
  2366 			ASSERT_DEBUG(msg->MsgType() == ERemConCommand);
  2604 			ASSERT_DEBUG(msg->MsgType() == ERemConCommand);
  2367 			LOG1(_L("\tfound a command belonging to this client in the outgoing pending TSP queue: [0x%08x]"), msg);
  2605 			LOG1(_L("\tfound a command belonging to this client in the outgoing pending TSP queue: [0x%08x]"), msg);
  2407 			&&	cmd->TransactionId() == aMsg.TransactionId()
  2645 			&&	cmd->TransactionId() == aMsg.TransactionId()
  2408 			)
  2646 			)
  2409 			{
  2647 			{
  2410 			LOG1(_L("\tfound a matching item in the sent commands log: [0x%08x]"), cmd);
  2648 			LOG1(_L("\tfound a matching item in the sent commands log: [0x%08x]"), cmd);
  2411 			sentCommandFound = ETrue;
  2649 			sentCommandFound = ETrue;
  2412 			CRemConSession* const session = Session(cmd->SessionId());
  2650 			CRemConControllerSession* const session = ControllerSession(cmd->SessionId());
  2413 			// When sessions close, their messages are removed from the logs, 
  2651 			// When sessions close, their messages are removed from the logs, 
  2414 			// so the session here _should_ exist.
  2652 			// so the session here _should_ exist.
  2415 			ASSERT_DEBUG(session);
  2653 			ASSERT_DEBUG(session);
  2416 			aMsg.SessionId() = cmd->SessionId();
  2654 			aMsg.SessionId() = cmd->SessionId();
  2417 			(void) DeliverMessageToClient(aMsg, *session);
  2655 			(void) DeliverMessageToClient(aMsg, *session);
  2460 			&&	cmd->TransactionId() == aMsg.TransactionId()
  2698 			&&	cmd->TransactionId() == aMsg.TransactionId()
  2461 			)
  2699 			)
  2462 			{
  2700 			{
  2463 			LOG1(_L("\tfound a matching item in the sent commands log: [0x%08x]"), cmd);
  2701 			LOG1(_L("\tfound a matching item in the sent commands log: [0x%08x]"), cmd);
  2464 			sentCommandFound = ETrue;
  2702 			sentCommandFound = ETrue;
  2465 			CRemConSession* const session = Session(cmd->SessionId());
  2703 			CRemConControllerSession* const session = ControllerSession(cmd->SessionId());
  2466 			// When sessions close, their messages are removed from the logs, 
  2704 			// When sessions close, their messages are removed from the logs, 
  2467 			// so the session here _should_ exist.
  2705 			// so the session here _should_ exist.
  2468 			ASSERT_DEBUG(session);
  2706 			ASSERT_DEBUG(session);
  2469 			aMsg.SessionId() = cmd->SessionId();			
  2707 			aMsg.SessionId() = cmd->SessionId();			
  2470 			(void) DeliverMessageToClient(aMsg, *session);
  2708 			(void) DeliverMessageToClient(aMsg, *session);
  2593 	LOG(_L("Logging incoming delivered commands"));
  2831 	LOG(_L("Logging incoming delivered commands"));
  2594 	FTRACE(const_cast<CRemConServer*>(this)->IncomingDelivered().LogQueue();)
  2832 	FTRACE(const_cast<CRemConServer*>(this)->IncomingDelivered().LogQueue();)
  2595 	}
  2833 	}
  2596 #endif // __FLOG_ACTIVE
  2834 #endif // __FLOG_ACTIVE
  2597 
  2835 
  2598 CRemConSession* CRemConServer::Session(TUint aSessionId) const
  2836 CRemConControllerSession* CRemConServer::ControllerSession(TUint aSessionId) const
  2599 	{
  2837 	{
  2600 	CRemConSession* sess = NULL;
  2838 	LOG_FUNC;
  2601 
  2839 
  2602 	iSessionsLock.Wait();
  2840 	CRemConControllerSession* sess = NULL;
  2603 	const TUint count = iSessions.Count();
  2841 	
  2604 	for ( TUint ii = 0 ; ii < count ; ++ii )
  2842 	TInt index = iControllerSessions.Find(aSessionId, ControllerSessionCompare);
  2605 		{
  2843 	
  2606 		CRemConSession* const temp = iSessions[ii];
  2844 	if(index >= 0)
  2607 		ASSERT_DEBUG(temp);
  2845 		{
  2608 		if ( temp->Id() == aSessionId )
  2846 		sess = iControllerSessions[index];
  2609 			{
  2847 		}
  2610 			sess = temp;
       
  2611 			break;
       
  2612 			}
       
  2613 		}
       
  2614 	iSessionsLock.Signal();
       
  2615 
  2848 
  2616 	return sess;
  2849 	return sess;
  2617 	}
  2850 	}
  2618 
  2851 
  2619 CRemConSession* CRemConServer::TargetSession(TProcessId aProcessId) const
  2852 CRemConTargetClientProcess* CRemConServer::TargetClient(TUint aClientId) const
  2620 	{
  2853 	{
  2621 	CRemConSession* sess = NULL;
  2854 	LOG_FUNC;
  2622 
  2855 
  2623 	iSessionsLock.Wait();
  2856 	CRemConTargetClientProcess* client = NULL;
  2624 	const TUint count = iSessions.Count();
  2857 
  2625 	for ( TUint ii = 0 ; ii < count ; ++ii )
  2858 	iTargetClientsLock.Wait();
  2626 		{
  2859 	
  2627 		CRemConSession* const temp = iSessions[ii];
  2860 	TInt index = iTargetClients.Find(aClientId, TargetClientCompareUsingSessionId);
  2628 		ASSERT_DEBUG(temp);
  2861 	
  2629 		if (	temp->ClientInfo().ProcessId() == aProcessId 
  2862 	if(index >= 0)
  2630 			&&	temp->Type() == ERemConClientTypeTarget )
  2863 		{
  2631 			{
  2864 		client = iTargetClients[index];
  2632 			sess = temp;
  2865 		}
  2633 			break;
  2866 
  2634 			}
  2867 	iTargetClientsLock.Signal();
  2635 		}
  2868 
  2636 	iSessionsLock.Signal();
  2869 	return client;
  2637 
  2870 	}
  2638 	return sess;
  2871 
       
  2872 CRemConTargetClientProcess* CRemConServer::TargetClient(TProcessId aProcessId) const
       
  2873 	{
       
  2874 	LOG_FUNC;
       
  2875 
       
  2876 	CRemConTargetClientProcess* client = NULL;
       
  2877 
       
  2878 	iTargetClientsLock.Wait();
       
  2879 	
       
  2880 	TInt index = iTargetClients.Find(aProcessId, TargetClientCompareUsingProcessId);
       
  2881 	
       
  2882 	if(index >= 0)
       
  2883 		{
       
  2884 		client = iTargetClients[index];
       
  2885 		}
       
  2886 	
       
  2887 	iTargetClientsLock.Signal();
       
  2888 
       
  2889 	return client;
  2639 	}
  2890 	}
  2640 
  2891 
  2641 MRemConConverterInterface* CRemConServer::Converter(TUid aInterfaceUid, 
  2892 MRemConConverterInterface* CRemConServer::Converter(TUid aInterfaceUid, 
  2642 							   TUid aBearerUid) const
  2893 							   TUid aBearerUid) const
  2643 	{
  2894 	{
  2650 	{
  2901 	{
  2651 	ASSERT_DEBUG(iConverterManager);
  2902 	ASSERT_DEBUG(iConverterManager);
  2652 	return iConverterManager->Converter(aInterfaceData, aBearerUid);
  2903 	return iConverterManager->Converter(aInterfaceData, aBearerUid);
  2653 	}
  2904 	}
  2654 
  2905 
  2655 void CRemConServer::ReceiveRequest(CRemConSession& aSession)
  2906 void CRemConServer::ReceiveRequest(CRemConControllerSession& aSession)
  2656 	{
  2907 	{
  2657 	LOG_FUNC;
  2908 	LOG_FUNC;
  2658 	LOGINCOMINGPENDINGDELIVERY;
  2909 	LOGINCOMINGPENDINGDELIVERY;
  2659 	LOGINCOMINGDELIVERED;
  2910 	LOGINCOMINGDELIVERED;
  2660 
  2911 
  2663 	CRemConMessage* msg;
  2914 	CRemConMessage* msg;
  2664 	while ( ( msg = iter++ ) != NULL )
  2915 	while ( ( msg = iter++ ) != NULL )
  2665 		{
  2916 		{
  2666 		if ( msg->SessionId() == aSession.Id() )
  2917 		if ( msg->SessionId() == aSession.Id() )
  2667 			{
  2918 			{
       
  2919 			// Controllers receive responses or rejects only.
       
  2920 			ASSERT_DEBUG(msg->MsgType() == ERemConResponse || msg->MsgType() == ERemConReject);
       
  2921 
  2668 			TInt err = aSession.WriteMessageToClient(*msg);
  2922 			TInt err = aSession.WriteMessageToClient(*msg);
  2669 			IncomingPendingDelivery().Remove(*msg);
  2923 			IncomingPendingDelivery().Remove(*msg);
  2670 			if ( msg->MsgType() == ERemConCommand || msg->MsgType() == ERemConNotifyCommand)
  2924 			
  2671 				{
  2925 			// 'Take ownership' of it by destroying it- it's finished with.
       
  2926 			delete msg;				
       
  2927 			
       
  2928 			break;
       
  2929 			}
       
  2930 		}
       
  2931 
       
  2932 	LOGINCOMINGPENDINGDELIVERY;
       
  2933 	LOGINCOMINGDELIVERED;
       
  2934 	}
       
  2935 
       
  2936 void CRemConServer::ReceiveRequest(CRemConTargetClientProcess& aClient)
       
  2937 	{
       
  2938 	LOG_FUNC;
       
  2939 	LOGINCOMINGPENDINGDELIVERY;
       
  2940 	LOGINCOMINGDELIVERED;
       
  2941 
       
  2942 	// Messages are addressed to the client. Ask client to deliver any pending
       
  2943 	// messages. For each delivered message, update ourselves accordingly.
       
  2944 	
       
  2945 	// Find the first message in IncomingPendingDelivery for this session.
       
  2946 	TSglQueIter<CRemConMessage>& iter = IncomingPendingDelivery().SetToFirst();
       
  2947 	CRemConMessage* msg;
       
  2948 	while ( ( msg = iter++ ) != NULL )
       
  2949 		{
       
  2950 		if (msg->SessionId() == aClient.Id())
       
  2951 			{
       
  2952 			// Targets receive commands only.
       
  2953 			ASSERT_DEBUG(msg->MsgType() == ERemConCommand || msg->MsgType() == ERemConNotifyCommand);
       
  2954 
       
  2955 			TInt err = aClient.ReceiveMessage(*msg);
       
  2956 
       
  2957 			if (err == KErrArgument)
       
  2958 				{
       
  2959 				// Message not supported by this client.
       
  2960 				// 'Take ownership' of it by destroying it- it's finished with.
       
  2961 				IncomingPendingDelivery().Remove(*msg);
       
  2962 				delete msg;
       
  2963 				}
       
  2964 			else if (err == KErrNotReady)
       
  2965 				{
       
  2966 				// Client cannot receive this message at the moment, skip for now
       
  2967 				// (message is already on the pemding queue).
       
  2968 				}
       
  2969 			else 
       
  2970 				{
       
  2971 				// Message delivered, remove from pending queue.
       
  2972 				IncomingPendingDelivery().Remove(*msg);
       
  2973 				
  2672 				if (err == KErrNone )
  2974 				if (err == KErrNone )
  2673 					{
  2975 					{
  2674 					// We'll need to remember it for the response coming back.
  2976 					// We'll need to remember it for the response coming back.
  2675 					IncomingDelivered().Append(*msg); 
  2977 					IncomingDelivered().Append(*msg); 
  2676 					}
  2978 					}
  2680 					CMessageRecipients* messageRecipients = iMessageRecipientsList->Message (msg->TransactionId ());
  2982 					CMessageRecipients* messageRecipients = iMessageRecipientsList->Message (msg->TransactionId ());
  2681 
  2983 
  2682 					// If we aren't returned a client list, this means that the message has been delivered elsewhere
  2984 					// If we aren't returned a client list, this means that the message has been delivered elsewhere
  2683 					if (messageRecipients)
  2985 					if (messageRecipients)
  2684 						{
  2986 						{
  2685 						messageRecipients->RemoveAndDestroyClient (aSession.ClientInfo ());
  2987 						messageRecipients->RemoveAndDestroyClient (aClient.ClientInfo ());
  2686 
  2988 
  2687 						if ( messageRecipients->Clients().IsEmpty ())
  2989 						if ( messageRecipients->Clients().IsEmpty ())
  2688 							{
  2990 							{
  2689 							iMessageRecipientsList->Messages().Remove (*messageRecipients);
  2991 							iMessageRecipientsList->Messages().Remove (*messageRecipients);
  2690 							delete messageRecipients;
  2992 							delete messageRecipients;
  2691 
  2993 
  2692 							SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
  2994 							SendReject(msg->Addr(), msg->InterfaceUid(), msg->OperationId(), msg->TransactionId());
  2693 							}
  2995 							}
  2694 						}
  2996 						}
  2695 					
  2997 
  2696 					// 'Take ownership' of it by destroying it- it's finished with.
  2998 					// 'Take ownership' of it by destroying it- it's finished with.
  2697 					delete msg;
  2999 					delete msg;
  2698 					}
  3000 					}
  2699 				}
  3001 				}
  2700 			else
  3002 			}
  2701 				{
  3003 		}
  2702 				// 'Take ownership' of it by destroying it- it's finished with.
  3004 	
  2703 				delete msg;				
       
  2704 				}
       
  2705 			
       
  2706 			break;
       
  2707 			}
       
  2708 		}
       
  2709 
       
  2710 	LOGINCOMINGPENDINGDELIVERY;
  3005 	LOGINCOMINGPENDINGDELIVERY;
  2711 	LOGINCOMINGDELIVERED;
  3006 	LOGINCOMINGDELIVERED;
  2712 	}
  3007 	}
  2713 
  3008 
  2714 TBool CRemConServer::FindDuplicateNotify(CRemConMessage& aMsg)
  3009 TBool CRemConServer::FindDuplicateNotify(CRemConMessage& aMsg)
  2767 		imply that every session's interfaces were able to be retrieved.
  3062 		imply that every session's interfaces were able to be retrieved.
  2768 		KErrNoMemory if no interfaces could be retrived.
  3063 		KErrNoMemory if no interfaces could be retrived.
  2769 */
  3064 */
  2770 TInt CRemConServer::ControllerSupportedInterfaces(RArray<TUid>& aSupportedInterfaces)
  3065 TInt CRemConServer::ControllerSupportedInterfaces(RArray<TUid>& aSupportedInterfaces)
  2771 	{
  3066 	{
  2772 	LOG_FUNC
  3067 	LOG_FUNC;
  2773 	ASSERT_DEBUG(aSupportedInterfaces.Count() == 0);
  3068 	ASSERT_DEBUG(aSupportedInterfaces.Count() == 0);
  2774 	
  3069 	
  2775 	TLinearOrder<TUid> uidCompare(&UidCompare);
  3070 	TLinearOrder<TUid> uidCompare(&UidCompare);
  2776 	RArray<TUid> sessionFeatures;
  3071 	RArray<TUid> sessionFeatures;
  2777 	TInt err = KErrNone;
  3072 	TInt err = KErrNone;
  2778 	for(TInt i=0; i<iSessions.Count(); i++)
  3073 	for(TInt i=0; i<iControllerSessions.Count(); i++)
  2779 		{
  3074 		{
  2780 		ASSERT_DEBUG(iSessions[i]);
  3075 		ASSERT_DEBUG(iControllerSessions[i]);
  2781 		if(iSessions[i]->Type() == ERemConClientTypeController)
  3076 		err = iControllerSessions[i]->SupportedInterfaces(sessionFeatures);
  2782 			{
  3077 		ASSERT_DEBUG(err == KErrNone || err == KErrNoMemory);
  2783 			err = iSessions[i]->SupportedInterfaces(sessionFeatures);
  3078 		
  2784 			ASSERT_DEBUG(err == KErrNone || err == KErrNoMemory);
  3079 		if(!err)
  2785 			
  3080 			{
  2786 			if(!err)
  3081 			for(TInt j=0; j<sessionFeatures.Count(); j++)
  2787 				{
  3082 				{
  2788 				for(TInt j=0; j<sessionFeatures.Count(); j++)
  3083 				// Ignore failure here, we're trying this best effort
  2789 					{
  3084 				// InsertInOrder is used rather than just bunging the
  2790 					// Ignore failure here, we're trying this best effort
  3085 				// interface on the end as we want no duplicates 
  2791 					// InsertInOrder is used rather than just bunging the
  3086 				(void)aSupportedInterfaces.InsertInOrder(sessionFeatures[j], uidCompare);
  2792 					// interface on the end as we want no duplicates 
  3087 				}
  2793 					(void)aSupportedInterfaces.InsertInOrder(sessionFeatures[j], uidCompare);
  3088 			}
  2794 					}
  3089 		sessionFeatures.Reset();
  2795 				}
       
  2796 			sessionFeatures.Reset();
       
  2797 			}
       
  2798 		}
  3090 		}
  2799 	
  3091 	
  2800 	if(aSupportedInterfaces.Count() > 0)
  3092 	if(aSupportedInterfaces.Count() > 0)
  2801 		{
  3093 		{
  2802 		return KErrNone;
  3094 		return KErrNone;
  2933 
  3225 
  2934 	// If we have a real new connection and we could handle it, aError is 
  3226 	// If we have a real new connection and we could handle it, aError is 
  2935 	// now KErrNone. In this case, sessions' notifications need completing.
  3227 	// now KErrNone. In this case, sessions' notifications need completing.
  2936 	if ( aError == KErrNone )
  3228 	if ( aError == KErrNone )
  2937 		{
  3229 		{
  2938 		iSessionsLock.Wait();
  3230 		TUint count = iControllerSessions.Count();
  2939 		const TUint count = iSessions.Count();
       
  2940 		for ( TUint ii = 0 ; ii < count ; ++ii )
  3231 		for ( TUint ii = 0 ; ii < count ; ++ii )
  2941 			{
  3232 			{
  2942 			ASSERT_DEBUG(iSessions[ii]);
  3233 			ASSERT_DEBUG(iControllerSessions[ii]);
  2943 			iSessions[ii]->ConnectionsChanged();
  3234 			iControllerSessions[ii]->ConnectionsChanged();
  2944 			}
  3235 			}
  2945 		iSessionsLock.Signal();
  3236 		
       
  3237 		iTargetClientsLock.Wait();
       
  3238 		count = iTargetClients.Count();
       
  3239 		for ( TUint ii = 0 ; ii < count ; ++ii )
       
  3240 			{
       
  3241 			ASSERT_DEBUG(iTargetClients[ii]);
       
  3242 			iTargetClients[ii]->ConnectionsChanged();
       
  3243 			}
       
  3244 		iTargetClientsLock.Signal();
  2946 		}
  3245 		}
  2947 
  3246 
  2948 	// Complete the specific client request(s) that caused a ConnectRequest on 
  3247 	// Complete the specific client request(s) that caused a ConnectRequest on 
  2949 	// the bearer. Tell all sessions- they remember the address they wanted to 
  3248 	// the bearer. Tell all sessions- they remember the address they wanted to 
  2950 	// connect to, and will filter on the address we give them. NB This 
  3249 	// connect to, and will filter on the address we give them. NB This 
  2951 	// function is called by ConnectIndicate as well as by ConnectConfirm, but 
  3250 	// function is called by ConnectIndicate as well as by ConnectConfirm, but 
  2952 	// the client doesn't care which end brought the connection up. 
  3251 	// the client doesn't care which end brought the connection up. 
  2953 	const TUint count = Sessions().Count();
  3252 	const TUint count = iControllerSessions.Count();
  2954 	for ( TUint ii = 0 ; ii < count ; ++ii )
  3253 	for ( TUint ii = 0 ; ii < count ; ++ii )
  2955 		{
  3254 		{
  2956 		ASSERT_DEBUG(Sessions()[ii]);
  3255 		ASSERT_DEBUG(iControllerSessions[ii]);
  2957 		Sessions()[ii]->CompleteConnect(aAddr, aError);
  3256 		iControllerSessions[ii]->CompleteConnect(aAddr, aError);
  2958 		}
  3257 		}
  2959 
  3258 
  2960 	// Any messages waiting on OutgoingPendingSend for this connection need to 
  3259 	// Any messages waiting on OutgoingPendingSend for this connection need to 
  2961 	// be handled.
  3260 	// be handled.
  2962 	TSglQueIter<CRemConMessage>& iter = OutgoingPendingSend().SetToFirst();
  3261 	TSglQueIter<CRemConMessage>& iter = OutgoingPendingSend().SetToFirst();
  2964 	TBool moveToSent = EFalse;
  3263 	TBool moveToSent = EFalse;
  2965 	while ( ( msg = iter++ ) != NULL )
  3264 	while ( ( msg = iter++ ) != NULL )
  2966 		{
  3265 		{
  2967 		if ( msg->Addr() == aAddr )
  3266 		if ( msg->Addr() == aAddr )
  2968 			{
  3267 			{
  2969 			CRemConSession* const sess = Session(msg->SessionId());
  3268 			MRemConMessageSendObserver* observer  = TargetClient(msg->SessionId());
  2970 			// The session should exist- if it doesn't then this message 
  3269 			if(!observer)
       
  3270 				{
       
  3271 				observer = ControllerSession(msg->SessionId());
       
  3272 				}
       
  3273 #ifdef __DEBUG
       
  3274 			else
       
  3275 				{
       
  3276 				// Message has matched to a target session, so it should not also match
       
  3277 				// a controller session (we know the vice-versa is already true).
       
  3278 				ASSERT_DEBUG(!ControllerSession(msg->SessionId()));
       
  3279 				}
       
  3280 #endif
       
  3281 
       
  3282 			// The session or client should exist- if it doesn't then this message 
  2971 			// wasn't cleaned from OutgoingPendingSend correctly when the 
  3283 			// wasn't cleaned from OutgoingPendingSend correctly when the 
  2972 			// session closed. The exceptions are Reject, which can be put
  3284 			// session closed. The exceptions are Reject, which can be put
  2973 			// on the queue without a session, and notify changed responses when they are being
  3285 			// on the queue without a session, and notify changed responses when they are being
  2974 			// delivered to multiple controllers
  3286 			// delivered to multiple controllers
  2975 			ASSERT_DEBUG(sess || msg->MsgType() == ERemConReject || msg->MsgSubType() == ERemConNotifyResponseChanged);
  3287 			ASSERT_DEBUG(observer || msg->MsgType() == ERemConReject || msg->MsgSubType() == ERemConNotifyResponseChanged);
  2976 
  3288 
  2977 			if ( aError == KErrNone)
  3289 			if ( aError == KErrNone)
  2978 				{
  3290 				{
  2979 				// We have a connection!
  3291 				// We have a connection!
  2980 				ASSERT_DEBUG(iBearerManager);
  3292 				ASSERT_DEBUG(iBearerManager);
  2985 					// If the send succeeded and it was a command, we move the 
  3297 					// If the send succeeded and it was a command, we move the 
  2986 					// message to the 'sent' log. Otherwise, it's simply 
  3298 					// message to the 'sent' log. Otherwise, it's simply 
  2987 					// deleted because we've finished with it.
  3299 					// deleted because we've finished with it.
  2988 					moveToSent = ETrue;
  3300 					moveToSent = ETrue;
  2989 					}
  3301 					}
  2990 				if ( sess)
  3302 				if ( observer && msg->MsgType() != ERemConReject )
  2991 					{
  3303 					{
  2992 					if ( err == KErrNone)
  3304 					observer->MrcmsoMessageSendOneOrMoreResult(*msg, err);
       
  3305 					}
       
  3306 				}
       
  3307 			else
       
  3308 				{
       
  3309 				// No connection, remember the error.
       
  3310 				if ( observer )
       
  3311 					{
       
  3312 					if (msg->MsgType() != ERemConReject)
  2993 						{
  3313 						{
  2994 						++sess->NumRemotes();
  3314 						observer->MrcmsoMessageSendOneOrMoreResult(*msg, aError);
  2995 						}
  3315 						}
  2996 					else
       
  2997 						{
       
  2998 						sess->SendError ()= err;
       
  2999 						}
       
  3000 					}
       
  3001 				}
       
  3002 			else
       
  3003 				{
       
  3004 				// No connection, remember the error.
       
  3005 				if ( sess)
       
  3006 					{
       
  3007 					sess->SendError ()= aError;
       
  3008 					}
       
  3009 				}
       
  3010 			if ( sess)
       
  3011 				{
       
  3012 				--sess->NumRemotesToTry();
       
  3013 
       
  3014 				// If we have now dealt with all the messages on the 
       
  3015 				// OutgoingPendingSend queue for this session, we can complete 
       
  3016 				// their send. In this case we should by now have collected the 
       
  3017 				// number of remotes and the send error. (NB A client can only 
       
  3018 				// have one send outstanding at any one time; a client may have 
       
  3019 				// more than one message on the 'pending send' queue if the TSP 
       
  3020 				// said to send to more than one remote.)
       
  3021 				// If the message is a notify then it can only have been sent to
       
  3022 				// one Remote so the NumRemotesToTry is not used
       
  3023 				if(msg->MsgType() == ERemConNotifyCommand)
       
  3024 					{
       
  3025 					sess->CompleteSendNotify();
       
  3026 					}
       
  3027 				else if ( sess->NumRemotesToTry ()== 0)
       
  3028 					{
       
  3029 					sess->CompleteSend ();
       
  3030 					}
  3316 					}
  3031 				}
  3317 				}
  3032 
  3318 
  3033 			if ( moveToSent)
  3319 			if ( moveToSent)
  3034 				{
  3320 				{
  3047 	LOGOUTGOINGSENT;
  3333 	LOGOUTGOINGSENT;
  3048 	LOG1(_L("\taError = %d"), aError);
  3334 	LOG1(_L("\taError = %d"), aError);
  3049 	return aError;
  3335 	return aError;
  3050 	}
  3336 	}
  3051 
  3337 
  3052 void CRemConServer::RemoveConnection(const TRemConAddress& aAddr)
  3338 void CRemConServer::RemoveConnection(const TRemConAddress& aAddr, TInt aError)
  3053 	{
  3339 	{
  3054 	LOG_FUNC;
  3340 	LOG_FUNC;
  3055 	LOG1(_L("\taAddr.BearerUid = 0x%08x"), aAddr.BearerUid());
  3341 	LOG1(_L("\taAddr.BearerUid = 0x%08x"), aAddr.BearerUid());
  3056 	LOGREMOTES;
  3342 	LOGREMOTES;
  3057 
  3343 	
  3058 	// We make a new item in the connection history and inform the sessions so 
  3344 	if(aError == KErrNone)
  3059 	// they can complete outstanding connection status notifications.
  3345 		{
  3060 
  3346 		// The connection has gone away
  3061 	ASSERT_DEBUG(iConnectionHistory);
  3347 
  3062 	iConnectionHistory->Disconnection(aAddr);
  3348 		// We make a new item in the connection history and inform the sessions so 
  3063 	iSessionsLock.Wait();
  3349 		// they can complete outstanding connection status notifications.
  3064 	const TUint count = iSessions.Count();
  3350 	
       
  3351 		ASSERT_DEBUG(iConnectionHistory);
       
  3352 		iConnectionHistory->Disconnection(aAddr);
       
  3353 
       
  3354 		TUint count = iControllerSessions.Count();
       
  3355 		for ( TUint ii = 0 ; ii < count ; ++ii )
       
  3356 			{
       
  3357 			ASSERT_DEBUG(iControllerSessions[ii]);
       
  3358 			iControllerSessions[ii]->ConnectionsChanged();
       
  3359 			}
       
  3360 		
       
  3361 		iTargetClientsLock.Wait();
       
  3362 		count = iTargetClients.Count();
       
  3363 		for ( TUint ii = 0 ; ii < count ; ++ii )
       
  3364 			{
       
  3365 			ASSERT_DEBUG(iTargetClients[ii]);
       
  3366 			iTargetClients[ii]->ConnectionsChanged();
       
  3367 			}
       
  3368 		iTargetClientsLock.Signal();
       
  3369 		
       
  3370 		// If there are any messages waiting on OutgoingPendingSend for this connection,
       
  3371 		// we re-connect it - they'll be picked up in HandleConnection above.
       
  3372 	
       
  3373 		TSglQueIter<CRemConMessage> iter = OutgoingPendingSend().SetToFirst();
       
  3374 		CRemConMessage* msg;
       
  3375 		TBool needToReconnect = false;
       
  3376 		while ( ( msg = iter++ ) != NULL )
       
  3377 			{
       
  3378 			if (msg->Addr() == aAddr)
       
  3379 				{
       
  3380 				needToReconnect = true;
       
  3381 				break;
       
  3382 				}
       
  3383 			}
       
  3384 		
       
  3385 		if (needToReconnect)
       
  3386 			{
       
  3387 			ASSERT_DEBUG(iBearerManager);
       
  3388 			TInt err = iBearerManager->Connect(aAddr);
       
  3389 			if ( err != KErrNone )
       
  3390 				{
       
  3391 				// This fails if:
       
  3392 				// 1. we're already connecting (in which case, we don't care)
       
  3393 				// 2. we can't add aAddr to the connecting list
       
  3394 				// The semantics of this observer don't let us return an error or leave, so
       
  3395 				// we can't do much about it here. Log it, and the next command will
       
  3396 				// invoke Connect from a better situation.
       
  3397 				LOG1(_L("\tFailed to re-connect bearer after connection removed: %d"), err);
       
  3398 				}
       
  3399 			}
       
  3400 		}
       
  3401 	
       
  3402 	// Complete the specific request(s) that caused a DisconnectRequest on the 
       
  3403 	// bearer. Tell all sessions- they remember the address they wanted to 
       
  3404 	// connect to, and will filter on the address we give them.
       
  3405 	TInt count = iControllerSessions.Count();
  3065 	for ( TUint ii = 0 ; ii < count ; ++ii )
  3406 	for ( TUint ii = 0 ; ii < count ; ++ii )
  3066 		{
  3407 		{
  3067 		ASSERT_DEBUG(iSessions[ii]);
  3408 		ASSERT_DEBUG(iControllerSessions[ii]);
  3068 		iSessions[ii]->ConnectionsChanged();
  3409 		iControllerSessions[ii]->CompleteDisconnect(aAddr, aError);
  3069 		}
       
  3070 	iSessionsLock.Signal();
       
  3071 	
       
  3072 	// If there are any messages waiting on OutgoingPendingSend for this connection,
       
  3073 	// we re-connect it - they'll be picked up in HandleConnection above.
       
  3074 
       
  3075 	TSglQueIter<CRemConMessage> iter = OutgoingPendingSend().SetToFirst();
       
  3076 	CRemConMessage* msg;
       
  3077 	TBool needToReconnect = false;
       
  3078 	while ( ( msg = iter++ ) != NULL )
       
  3079 		{
       
  3080 		if (msg->Addr() == aAddr)
       
  3081 			{
       
  3082 			needToReconnect = true;
       
  3083 			break;
       
  3084 			}
       
  3085 		}
       
  3086 	
       
  3087 	if (needToReconnect)
       
  3088 		{
       
  3089 		ASSERT_DEBUG(iBearerManager);
       
  3090 		TInt err = iBearerManager->Connect(aAddr);
       
  3091 		if ( err != KErrNone )
       
  3092 			{
       
  3093 			// This fails if:
       
  3094 			// 1. we're already connecting (in which case, we don't care)
       
  3095 			// 2. we can't add aAddr to the connecting list
       
  3096 			// The semantics of this observer don't let us return an error or leave, so
       
  3097 			// we can't do much about it here. Log it, and the next command will
       
  3098 			// invoke Connect from a better situation.
       
  3099 			LOG1(_L("\tFailed to re-connect bearer after connection removed: %d"), err);
       
  3100 			}
       
  3101 		}
  3410 		}
  3102 
  3411 
  3103 	LOGREMOTES;
  3412 	LOGREMOTES;
  3104 	}
  3413 	}
  3105 
  3414 
  3106 void CRemConServer::SetConnectionHistoryPointer(TUint aSessionId)
  3415 void CRemConServer::SetConnectionHistoryPointer(TUint aSessionId)
  3107 	{
  3416 	{
  3108 	LOG_FUNC;
  3417 	LOG_FUNC;
  3109 	LOG1(_L("\taSessionId = %d"), aSessionId);
  3418 	LOG1(_L("\taSessionId = %d"), aSessionId);
  3110 	LOGSESSIONS;
  3419 	LOGCONTROLLERSESSIONS;
       
  3420 	LOGTARGETSESSIONS;
  3111 	LOGCONNECTIONHISTORYANDINTEREST;
  3421 	LOGCONNECTIONHISTORYANDINTEREST;
  3112 
  3422 
  3113 	// Update the record for this session.
  3423 	// Update the record for this session.
  3114 	const TUint count = iSession2ConnHistory.Count();
  3424 	const TUint count = iSession2ConnHistory.Count();
  3115 	for ( TUint ii = 0 ; ii < count ; ++ii )
  3425 	for ( TUint ii = 0 ; ii < count ; ++ii )
  3326 		}
  3636 		}
  3327 	ASSERT_DEBUG(iMessageRecipientsList);
  3637 	ASSERT_DEBUG(iMessageRecipientsList);
  3328 	iMessageRecipientsList->RemoveAndDestroyMessage(aTransactionId);
  3638 	iMessageRecipientsList->RemoveAndDestroyMessage(aTransactionId);
  3329 	}
  3639 	}
  3330 
  3640 
  3331 TClientInfo* CRemConServer::ClientIdToClientInfo(TRemConClientId aId)
  3641 TClientInfo* CRemConServer::TargetClientIdToClientInfo(TRemConClientId aId)
  3332 	{
  3642 	{
  3333 	TClientInfo* clientInfo = NULL;
  3643 	TClientInfo* clientInfo = NULL;
  3334 	
  3644 	
  3335 	iSessionsLock.Wait();
  3645 	iTargetClientsLock.Wait();
  3336 	const TUint count = iSessions.Count();
  3646 	const TUint count = iTargetClients.Count();
  3337 	for ( TUint ii = 0 ; ii < count ; ++ii )
  3647 	for ( TUint ii = 0 ; ii < count ; ++ii )
  3338 		{
  3648 		{
  3339 		CRemConSession* const sess = iSessions[ii];
  3649 		CRemConTargetClientProcess * const client = iTargetClients[ii];
       
  3650 		ASSERT_DEBUG(client);
       
  3651 		if (client->Id() == aId)
       
  3652 			{
       
  3653 			clientInfo = &client->ClientInfo();
       
  3654 			break;
       
  3655 			}
       
  3656 		}
       
  3657 	iTargetClientsLock.Signal();
       
  3658 	
       
  3659 	return clientInfo;
       
  3660 	}
       
  3661 
       
  3662 TInt CRemConServer::SupportedInterfaces(const TRemConClientId& aId, RArray<TUid>& aUids)
       
  3663 	{
       
  3664 	TUint count = iControllerSessions.Count();
       
  3665 	for ( TUint ii = 0 ; ii < count ; ++ii )
       
  3666 		{
       
  3667 		CRemConSession* const sess = iControllerSessions[ii];
  3340 		ASSERT_DEBUG(sess);
  3668 		ASSERT_DEBUG(sess);
  3341 		if (sess->Id() == aId)
  3669 		if (sess->Id() == aId)
  3342 			{
  3670 			{
  3343 			clientInfo = &sess->ClientInfo();
  3671 			return sess->SupportedInterfaces(aUids);
  3344 			break;
  3672 			}
  3345 			}
  3673 		}
  3346 		}
  3674 	
  3347 	iSessionsLock.Signal();
  3675 	iTargetClientsLock.Wait();
  3348 	
  3676 	count = iTargetClients.Count();
  3349 	return clientInfo;
       
  3350 	}
       
  3351 
       
  3352 TInt CRemConServer::SupportedInterfaces(const TRemConClientId& aId, RArray<TUid>& aUids)
       
  3353 	{
       
  3354 	iSessionsLock.Wait();
       
  3355 	const TUint count = iSessions.Count();
       
  3356 	for ( TUint ii = 0 ; ii < count ; ++ii )
  3677 	for ( TUint ii = 0 ; ii < count ; ++ii )
  3357 		{
  3678 		{
  3358 		CRemConSession* const sess = iSessions[ii];
  3679 		CRemConTargetClientProcess* const client = iTargetClients[ii];
       
  3680 		ASSERT_DEBUG(client);
       
  3681 		if (client->Id() == aId)
       
  3682 			{
       
  3683 			iTargetClientsLock.Signal();
       
  3684 			return client->SupportedInterfaces(aUids);
       
  3685 			}
       
  3686 		}
       
  3687 	iTargetClientsLock.Signal();
       
  3688 	
       
  3689 	return KErrNotFound;
       
  3690 	}
       
  3691 
       
  3692 TInt CRemConServer::SupportedOperations(const TRemConClientId& aId, TUid aInterfaceUid, RArray<TUint>& aOperations)
       
  3693 	{
       
  3694 	iTargetClientsLock.Wait();
       
  3695 	TUint count = iTargetClients.Count();
       
  3696 	for ( TUint ii = 0 ; ii < count ; ++ii )
       
  3697 		{
       
  3698 		CRemConTargetClientProcess* const client = iTargetClients[ii];
       
  3699 		ASSERT_DEBUG(client);
       
  3700 		if (client->Id() == aId)
       
  3701 			{
       
  3702 			iTargetClientsLock.Signal();
       
  3703 			return client->SupportedOperations(aInterfaceUid, aOperations);
       
  3704 			}
       
  3705 		}
       
  3706 	iTargetClientsLock.Signal();
       
  3707 
       
  3708 	count = iControllerSessions.Count();
       
  3709 	for ( TUint ii = 0 ; ii < count ; ++ii )
       
  3710 		{
       
  3711 		CRemConControllerSession* const sess = iControllerSessions[ii];
  3359 		ASSERT_DEBUG(sess);
  3712 		ASSERT_DEBUG(sess);
  3360 		if (sess->Id() == aId)
  3713 		if (sess->Id() == aId)
  3361 			{
  3714 			{
  3362 			iSessionsLock.Signal();
  3715 			return sess->SupportedOperations(aInterfaceUid, aOperations);
  3363 			return sess->SupportedInterfaces(aUids);
  3716 			}
  3364 			}
  3717 		}
  3365 		}
       
  3366 	iSessionsLock.Signal();
       
  3367 	
  3718 	
  3368 	return KErrNotFound;
  3719 	return KErrNotFound;
  3369 	}
  3720 	}
  3370 
  3721 
  3371 TInt CRemConServer::SupportedOperations(const TRemConClientId& aId, TUid aInterfaceUid, RArray<TUint>& aOperations)
       
  3372 	{
       
  3373 	iSessionsLock.Wait();
       
  3374 	const TUint count = iSessions.Count();
       
  3375 	for ( TUint ii = 0 ; ii < count ; ++ii )
       
  3376 		{
       
  3377 		CRemConSession* const sess = iSessions[ii];
       
  3378 		ASSERT_DEBUG(sess);
       
  3379 		if (sess->Id() == aId)
       
  3380 			{
       
  3381 			iSessionsLock.Signal();
       
  3382 			return sess->SupportedOperations(aInterfaceUid, aOperations);
       
  3383 			}
       
  3384 		}
       
  3385 	iSessionsLock.Signal();
       
  3386 	
       
  3387 	return KErrNotFound;
       
  3388 	}
       
  3389 
       
  3390 void CRemConServer::SetRemoteAddressedClient(const TUid& aBearerUid, const TRemConClientId& aId)
  3722 void CRemConServer::SetRemoteAddressedClient(const TUid& aBearerUid, const TRemConClientId& aId)
  3391 	{
  3723 	{
  3392 	LOG_FUNC
  3724 	LOG_FUNC;
  3393 	
  3725 	
  3394 	TClientInfo* clientInfo = ClientIdToClientInfo(aId);
  3726 	TClientInfo* clientInfo = TargetClientIdToClientInfo(aId);
  3395 	// Bearer must supply valid client id
  3727 	// Bearer must supply valid client id
  3396 	ASSERT_DEBUG(clientInfo);
  3728 	ASSERT_DEBUG(clientInfo);
  3397 
  3729 
  3398 	ASSERT_DEBUG(iTspIf4);
  3730 	ASSERT_DEBUG(iTspIf4);
  3399 	iTspIf4->SetRemoteAddressedClient(aBearerUid, *clientInfo);
  3731 	iTspIf4->SetRemoteAddressedClient(aBearerUid, *clientInfo);
  3409 	return iTspIf5 ? iTspIf5->UnregisterLocalAddressedClientObserver(aBearerUid) : KErrNotSupported;
  3741 	return iTspIf5 ? iTspIf5->UnregisterLocalAddressedClientObserver(aBearerUid) : KErrNotSupported;
  3410 	}
  3742 	}
  3411 
  3743 
  3412 TRemConClientId CRemConServer::ClientIdByProcessId(TProcessId aProcessId)
  3744 TRemConClientId CRemConServer::ClientIdByProcessId(TProcessId aProcessId)
  3413 	{
  3745 	{
  3414 	LOG_FUNC
  3746 	LOG_FUNC;
  3415 	TRemConClientId ret = KNullClientId;
  3747 	TRemConClientId ret = KNullClientId;
  3416 	iSessionsLock.Wait();
  3748 	iTargetClientsLock.Wait();
  3417 	CRemConSession* session = TargetSession(aProcessId);
  3749 	CRemConTargetClientProcess* client = TargetClient(aProcessId);
  3418 	if(session)
  3750 	if(client)
  3419 		{
  3751 		{
  3420 		ret = session->Id();
  3752 		ret = client->Id();
  3421 		}
  3753 		}
  3422 	iSessionsLock.Signal();
  3754 	iTargetClientsLock.Signal();
  3423 	return ret;
  3755 	return ret;
  3424 	}
  3756 	}
  3425 
  3757 
  3426 void CRemConServer::BulkInterfacesForClientL(TRemConClientId aId, RArray<TUid>& aUids)
  3758 void CRemConServer::BulkInterfacesForClientL(TRemConClientId aId, RArray<TUid>& aUids)
  3427 	{
  3759 	{
  3428 	LOG_FUNC
  3760 	LOG_FUNC;
  3429 	iSessionsLock.Wait();
  3761 	iTargetClientsLock.Wait();
  3430 	CleanupSignalPushL(iSessionsLock);
  3762 	CleanupSignalPushL(iTargetClientsLock);
  3431 	CRemConSession* session = Session(aId);
  3763 	CRemConTargetClientProcess* client = TargetClient(aId);
  3432 	if(!session)
  3764 	if(!client)
  3433 		{
  3765 		{
  3434 		LEAVEL(KErrNotFound);
  3766 		LEAVEL(KErrNotFound);
  3435 		}
  3767 		}
  3436 	LEAVEIFERRORL(session->SupportedBulkInterfaces(aUids));
  3768 	LEAVEIFERRORL(client->SupportedBulkInterfaces(aUids));
  3437 	CleanupStack::PopAndDestroy(&iSessionsLock);
  3769 	CleanupStack::PopAndDestroy(&iTargetClientsLock);
  3438 	}
  3770 	}
  3439 
  3771 
  3440 
  3772 
  3441 // Helper Active Objects
  3773 // Helper Active Objects
  3442 
  3774 
  3479 	LOG_FUNC;
  3811 	LOG_FUNC;
  3480 	LOG1(_L("\tiStatus.Int() = %d"), iStatus.Int());
  3812 	LOG1(_L("\tiStatus.Int() = %d"), iStatus.Int());
  3481 	// Thread is dead so kill handle.
  3813 	// Thread is dead so kill handle.
  3482 	iServer.iBulkServerThread.Close();
  3814 	iServer.iBulkServerThread.Close();
  3483 	iServer.iBulkThreadOpen = EFalse;
  3815 	iServer.iBulkThreadOpen = EFalse;
  3484 	iServer.StartShutdownTimerIfNoSessionsOrBulkThread();
  3816 	iServer.StartShutdownTimerIfNoClientsOrBulkThread();
  3485 	iServer.iBulkThreadWatcher = NULL;
  3817 	iServer.iBulkThreadWatcher = NULL;
  3486 	delete this; // end...
  3818 	delete this; // end...
  3487 	}
  3819 	}
  3488 
  3820 
  3489 void CBulkThreadWatcher::DoCancel()
  3821 void CBulkThreadWatcher::DoCancel()