changeset 74 | 9d35fd98f273 |
parent 35 | f7565e9c9ce8 |
69:dc67b94625c5 | 74:9d35fd98f273 |
---|---|
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() |