|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <ss_std.h> |
|
17 #include <comms-infras/sockmes.h> |
|
18 #include <ss_glob.h> |
|
19 #include "ss_msgs.h" |
|
20 #include <nifman.h> |
|
21 #include <comms-infras/ss_log.h> |
|
22 #include <comms-infras/ss_roles.h> |
|
23 #include "ss_subconn.h" |
|
24 #include <ss_sock.h> |
|
25 #include "SS_rslv.H" |
|
26 #include "SS_conn.H" |
|
27 #include "ss_connectionsession.h" |
|
28 #include <comms-infras/ss_api_ext.h> |
|
29 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
30 #include <es_sock_internal.h> |
|
31 #endif |
|
32 |
|
33 #include "ss_apiext_messages.h" |
|
34 #include <comms-infras/ss_tiermanagerutils.h> |
|
35 |
|
36 #include <comms-infras/ss_nodemessages_internal_esock.h> |
|
37 |
|
38 #include <comms-infras/esockdebugmessages.h> |
|
39 #ifdef SYMBIAN_ZERO_COPY_NETWORKING |
|
40 #include <comms-infras/commsbufpondop.h> |
|
41 #include <comms-infras/commsbufponddbg.h> |
|
42 #else |
|
43 #include <es_mbman.h> |
|
44 #endif // SYMBIAN_ZERO_COPY_NETWORKING |
|
45 #ifdef _DEBUG |
|
46 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
47 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
48 _LIT(KSpecAssert_ESockSSockS_SES, "ESockSSockS_SES."); |
|
49 #endif |
|
50 |
|
51 #define MSG_PRM(prmIndex) (prmIndex) |
|
52 |
|
53 using namespace NetInterfaces; |
|
54 using namespace ESock; |
|
55 //using namespace Elements; |
|
56 using namespace Messages; |
|
57 using namespace Den; |
|
58 using namespace CommsFW; |
|
59 |
|
60 class RNullableMessage : public RMessage2 |
|
61 { |
|
62 public: |
|
63 void NullHandle() const |
|
64 { |
|
65 // Although this casting away of const looks awful it's in keeping with the ability to Complete() const |
|
66 // messages - perhaps iHandle should have been mutable? |
|
67 const_cast<RNullableMessage&>(*this).iHandle = 0; |
|
68 } |
|
69 }; |
|
70 |
|
71 /** |
|
72 Constructor |
|
73 */ |
|
74 CSockSession::CSockSession(TUidType aUid, TSessionUniqueId aSessionUniqueId) |
|
75 : CWorkerSession(aUid, aSessionUniqueId) |
|
76 { |
|
77 LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tConstructor"), this) ); |
|
78 SocketServer::NewSession(); |
|
79 } |
|
80 |
|
81 /*static*/ CSockSession* CSockSession::NewL(TProcessId aProcessId, TUidType aUid, TSessionUniqueId aSessionUniqueId) |
|
82 { |
|
83 |
|
84 CSockSession* self = new (ELeave) CSockSession(aUid, aSessionUniqueId); |
|
85 CleanupStack::PushL(self); |
|
86 self->ConstructL(aProcessId); |
|
87 CleanupStack::Pop(self); |
|
88 return self; |
|
89 } |
|
90 |
|
91 void CSockSession::ConstructL(TProcessId aProcessId) |
|
92 { |
|
93 #ifdef SYMBIAN_TRACE_ENABLE |
|
94 // Document the owner of the session |
|
95 TLogTextBuf buf; |
|
96 buf.Format(_L8("CSockSession %08x:\tConstructL()"), this); |
|
97 RProcess cliProc; |
|
98 if (cliProc.Open(aProcessId) == KErrNone) |
|
99 { |
|
100 TName cliName = cliProc.Name(); |
|
101 TInt index = cliName.LocateReverse('['); |
|
102 if (index >= 1) |
|
103 { |
|
104 cliName.SetLength(index); |
|
105 } |
|
106 TUint processId = cliProc.Id(); |
|
107 iProcessName.Copy(cliName); |
|
108 buf.AppendFormatIgnoreOverflow(_L8(" pid=%x \"%S\""), processId, &iProcessName); |
|
109 // Remove the "...[nnn]nnn" clutter from the name stored in the session |
|
110 // (unless the name happens to begin with "["). |
|
111 cliProc.Close(); |
|
112 } |
|
113 LOG(ESockLog::Printf(KESockServerTag, buf) ); |
|
114 #endif |
|
115 CWorkerSession::ConstructL(aProcessId); |
|
116 } |
|
117 |
|
118 /** |
|
119 Destroy |
|
120 */ |
|
121 CSockSession::~CSockSession() |
|
122 { |
|
123 LOG( ESockLog::Printf(KESockServerTag, _L8("~CSockSession(%08x):\t\"%S\""), this, &iProcessName) ); |
|
124 |
|
125 if(iOptimalDealer) |
|
126 { |
|
127 iOptimalDealer->RemoveEligiblePid(iProcess.Id()); |
|
128 } |
|
129 |
|
130 SocketServer::SessionClosing(); |
|
131 } |
|
132 |
|
133 CSockManData* CSockSession::SockManGlobals() const |
|
134 { |
|
135 return WorkerThread().SockManGlobals(); |
|
136 } |
|
137 |
|
138 TInt CSockSession::CheckPolicy(const TSecurityPolicy& aPolicy, const char *aDiagnostic) |
|
139 /** |
|
140 Check the security policy of a process. |
|
141 Called from a socket or resolver provider to check whether the process conforms to the security policy passed as |
|
142 argument. |
|
143 @see MProvdSecurityChecker |
|
144 */ |
|
145 { |
|
146 return aPolicy.CheckPolicy(iProcess, aDiagnostic) ? KErrNone : KErrPermissionDenied; |
|
147 } |
|
148 |
|
149 |
|
150 /** |
|
151 Handle messages for this server. In a few cases the messages will be dealt with accordingly, |
|
152 but in most cases they will be 1) forwarded to seperate player or 2) be handled by ProcessMessageL |
|
153 if the Player is co-resident in this thread. |
|
154 @param aMessage Standard IPC request from client side |
|
155 */ |
|
156 void CSockSession::ServiceL(const RMessage2& aMessage) |
|
157 { |
|
158 LOG( |
|
159 TBuf8<64> messName; |
|
160 ESockLog::IPCMessName((TSockMess) aMessage.Function(), messName); |
|
161 ESockLog::Printf(KESockServerTag, _L8("CSockSession(%08x):\tServiceL, Message(%08x) [%S] \"%S\" int3=%08x"), |
|
162 this, aMessage.Handle(), &messName, &iProcessName, SubSessionFromHandle(aMessage.Int3(), TCFSubSessInfo(TCFSubSessInfo::EAny))); |
|
163 ); |
|
164 |
|
165 const CWorkerThread& owner=WorkerThread(); |
|
166 const CPitBoss& pitBoss = owner.PitBoss(); |
|
167 |
|
168 if(pitBoss.TestImmediateShutdownPresent()) |
|
169 { |
|
170 User::Leave(KErrServerTerminated); |
|
171 } |
|
172 |
|
173 iComplete=ETrue; // Whether to complete RMessage2 immediately |
|
174 iReturn=KErrNone; // Default return value if completing RMessage2 here |
|
175 iOurMessage = &aMessage; |
|
176 |
|
177 CWorkerSubSession* ss = NULL; |
|
178 |
|
179 TWorkerId worker=TWorkerThreadPublicInfo::ENullWorkerId; |
|
180 const TInt function = aMessage.Function(); |
|
181 |
|
182 #if defined(_DEBUG_SOCKET_FUNCTIONS) |
|
183 if(function != ESSDbgControl && iDebugParking.iNumOutstanding > 0) |
|
184 { |
|
185 // Weakness here; if it's a session request then the 4th arg may be random stack junk. Major mitigation is that almost certainly they're in UDEB which gives near-certainty |
|
186 // of it being the stack fill pattern (eg 0xCCCCCCCC) so a collision is very unlikely to be seen (and only in the few cases where debug parking is employed). To improve this |
|
187 // need to test whether it's a sub-session operation; reorganising the IPC list will help this |
|
188 if(iDebugParking.iSubSessHandle == 0 || iDebugParking.iSubSessHandle == aMessage.Int3()) |
|
189 { |
|
190 User::LeaveIfError(Dealer()->ParkRequest(this, aMessage, CCommonDealer::EDebugParking)); |
|
191 --iDebugParking.iNumOutstanding; |
|
192 DontCompleteCurrentRequest(); |
|
193 return; |
|
194 } |
|
195 } |
|
196 #endif |
|
197 switch(function) |
|
198 { |
|
199 /* Cases handled without a player */ |
|
200 case ESSRequestOptimalDealer: |
|
201 RequestOptimalDealerL(); |
|
202 break; |
|
203 |
|
204 case ESSInstallExtension: |
|
205 LOG(ESockLog::Printf(_L8("WARNING: unsupported function ESSInstallExtension called, CSockSession(%08x)"), this)); |
|
206 SetReturn(KErrNotSupported); |
|
207 break; |
|
208 |
|
209 case ESSExclusiveMode: |
|
210 LOG(ESockLog::Printf(_L8("WARNING: unsupported function ESSExclusiveMode called, CSockSession(%08x)"), this)); |
|
211 SetReturn(KErrNone); |
|
212 break; |
|
213 |
|
214 case ESSClearExclusiveMode: |
|
215 LOG(ESockLog::Printf(_L8("WARNING: unsupported function ESSClearExclusiveMode called, CSockSession(%08x)"), this)); |
|
216 SetReturn(KErrNone); |
|
217 break; |
|
218 |
|
219 case ESSNumProtocols: |
|
220 NumProtocolsL(); |
|
221 break; |
|
222 |
|
223 case ESSProtocolInfo: |
|
224 ProtocolInfoL(); |
|
225 break; |
|
226 |
|
227 case ESSProtocolInfoByName: |
|
228 ProtocolInfoByNameL(); |
|
229 break; |
|
230 |
|
231 /* Cases for a Player to deal with, protocol level */ |
|
232 case ESSProtocolStart: |
|
233 case ESSProtocolStop: |
|
234 case ESoCreate: |
|
235 case ESRCreate: |
|
236 if(pitBoss.GetWorkerForProtocol(aMessage.Int0(),aMessage.Int1(),aMessage.Int2(), worker)) |
|
237 { |
|
238 ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), worker); |
|
239 } |
|
240 else |
|
241 { |
|
242 ParkIfIndeterminateRequest(aMessage, KErrBadName); |
|
243 } |
|
244 break; |
|
245 |
|
246 case ESoCreateWithConnection: |
|
247 { |
|
248 TPckgBuf<TSockOpen> argPkg; |
|
249 SafeMessage().ReadL(MSG_PRM(0),argPkg); |
|
250 ss = CConnectionFromHandle(argPkg().iHandle); |
|
251 if(!ss) |
|
252 { |
|
253 PanicClient(ESockBadHandle); |
|
254 } |
|
255 else |
|
256 { |
|
257 // Forward the message to the connection's (control) thread. It's best placed to decide which of its data threads it really belongs in |
|
258 ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), ss->Player().WorkerId()); |
|
259 } |
|
260 } |
|
261 break; |
|
262 case ESoCreateWithSubConnection: |
|
263 { |
|
264 TPckgBuf<TSockOpen> argPkg; |
|
265 SafeMessage().ReadL(MSG_PRM(0),argPkg); |
|
266 ss = CSubConnectionFromHandle(argPkg().iHandle); |
|
267 if (!ss) |
|
268 { |
|
269 PanicClient(ESockBadHandle); |
|
270 } |
|
271 else |
|
272 { |
|
273 // Forward the message to the subconnection's (control) thread. It's best placed to decide which of its data threads it really belongs in |
|
274 ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), ss->Player().WorkerId()); |
|
275 } |
|
276 break; |
|
277 } |
|
278 case EHRCreateWithConnection: |
|
279 case EHRCreate: |
|
280 case ENDCreate: |
|
281 if(pitBoss.GetWorkerForProtocol(aMessage.Int0(), KUndefinedSockType, aMessage.Int1(), worker)) |
|
282 { |
|
283 ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), worker); |
|
284 } |
|
285 else |
|
286 { |
|
287 ParkIfIndeterminateRequest(aMessage, KErrBadName); |
|
288 } |
|
289 break; |
|
290 |
|
291 case ESoCreateNull: |
|
292 // Attempt to pass to co-resident player |
|
293 if(owner.Player()) |
|
294 { |
|
295 worker = WorkerId(); |
|
296 } |
|
297 else |
|
298 { // No co-resident player, pass to NullSocket handling player known to PitBoss |
|
299 VERIFY(pitBoss.GetWorkerForNullSocket(worker)); |
|
300 } |
|
301 ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), worker); |
|
302 break; |
|
303 |
|
304 case ECNCreate: |
|
305 ForwardTierRequestL(aMessage); |
|
306 break; |
|
307 |
|
308 // Connection Messages |
|
309 case ECNCreateWithName: |
|
310 { |
|
311 // The cloned connection must be created on the same [control] Player that owns the original |
|
312 TName name; |
|
313 aMessage.ReadL(0, name); |
|
314 User::LeaveIfError(CSockSubSession::FetchSubSessionFromName(name, TCFSubSessInfo(TCFSubSessInfo::EConnection), owner, ss)); |
|
315 ForwardMessageL(aMessage, *ss); // can't be indeterminate request; already created the clone source |
|
316 break; |
|
317 } |
|
318 |
|
319 /* All else (cases for a Player to deal with, subsession level) */ |
|
320 |
|
321 // socket messages |
|
322 |
|
323 case ESoClose: |
|
324 CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::ESocket)); |
|
325 break; |
|
326 |
|
327 case ESoConnect: |
|
328 case ESoShutdown: |
|
329 case ESoSendToNoLength: |
|
330 case ESoSendNoLength: |
|
331 case ESoSendTo: |
|
332 case ESoSend: |
|
333 case ESoWrite: |
|
334 case ESoRecvFromNoLength: |
|
335 case ESoRecvNoLength: |
|
336 case ESoRecvOneOrMore: |
|
337 case ESoRecvFrom: |
|
338 case ESoRecv: |
|
339 case ESoRead: |
|
340 case ESoBind: |
|
341 case ESoAccept: |
|
342 case ESoListen: |
|
343 case ESoSetOpt: |
|
344 case ESoGetOpt: |
|
345 case ESoIoctl: |
|
346 case ESoGetDiscData: |
|
347 case ESoGetLocalName: |
|
348 case ESoGetRemoteName: |
|
349 case ESoReference: |
|
350 ss=CSocketFromHandle(aMessage.Int3()); |
|
351 if (ss) |
|
352 { |
|
353 ForwardMessageL(aMessage, *ss); |
|
354 } |
|
355 else |
|
356 { |
|
357 PanicClient(ESockBadHandle); |
|
358 } |
|
359 break; |
|
360 case ESoCancelRecv: |
|
361 case ESoCancelSend: |
|
362 case ESoCancelIoctl: |
|
363 case ESoCancelConnect: |
|
364 case ESoCancelAccept: |
|
365 case ESoCancelAll: |
|
366 ss=CSocketFromHandle(aMessage.Int3()); |
|
367 if(ss) |
|
368 { |
|
369 ForwardMessageL(aMessage, *ss); |
|
370 } |
|
371 else |
|
372 { |
|
373 LOG(ESockLog::Printf(_L8("CSockSession::ServiceL: BAD ESoCancelAll"))); |
|
374 } |
|
375 break; |
|
376 |
|
377 case ESoSocketInfo: |
|
378 ss=CSocketFromHandle(aMessage.Int3()); |
|
379 if (ss) |
|
380 { |
|
381 ForwardMessageL(aMessage, *ss); |
|
382 } |
|
383 else |
|
384 { |
|
385 SetReturn(KErrBadHandle); |
|
386 } |
|
387 break; |
|
388 |
|
389 case ESoTransfer: |
|
390 TransferSocketL(); |
|
391 break; |
|
392 |
|
393 // Host resolver message types |
|
394 |
|
395 case EHRClose: |
|
396 CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::EHostResolver)); |
|
397 break; |
|
398 |
|
399 case EHRCancel: |
|
400 ss=CHostResolverFromHandle(aMessage.Int3()); |
|
401 if (ss) |
|
402 { |
|
403 ForwardMessageL(aMessage, *ss); |
|
404 } |
|
405 else |
|
406 { |
|
407 LOG( ESockLog::Printf(_L8("CSockSession::ServiceL: BAD EHRCancel")) ); |
|
408 } |
|
409 break; |
|
410 |
|
411 case EHRGetByName: |
|
412 case EHRNext: |
|
413 case EHRGetByAddress: |
|
414 case EHRGetHostName: |
|
415 case EHRSetHostName: |
|
416 case EHrQuery: |
|
417 case EHrQueryNext: |
|
418 case EHRSetOpt: |
|
419 ss=CHostResolverFromHandle(aMessage.Int3()); |
|
420 if (ss) |
|
421 { |
|
422 ForwardMessageL(aMessage, *ss); |
|
423 } |
|
424 else |
|
425 { |
|
426 PanicClient(ESockBadHandle); |
|
427 } |
|
428 break; |
|
429 |
|
430 // Service resolver message types |
|
431 |
|
432 case ESRClose: |
|
433 CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::EServiceResolver)); |
|
434 break; |
|
435 |
|
436 case ESRGetByName: |
|
437 case ESRGetByNumber: |
|
438 case ESRRegisterService: |
|
439 case ESRRemoveService: |
|
440 ss=CServiceResolverFromHandle(aMessage.Int3()); |
|
441 if (ss) |
|
442 { |
|
443 ForwardMessageL(aMessage, *ss); |
|
444 } |
|
445 else |
|
446 { |
|
447 PanicClient(ESockBadHandle); |
|
448 } |
|
449 break; |
|
450 case ESRCancel: |
|
451 ss=CServiceResolverFromHandle(aMessage.Int3()); |
|
452 if (ss) |
|
453 { |
|
454 ForwardMessageL(aMessage, *ss); |
|
455 } |
|
456 else |
|
457 { |
|
458 LOG( ESockLog::Printf(_L8("CSockSession::ServiceL: BAD ESRCancel")) ); |
|
459 } |
|
460 break; |
|
461 |
|
462 // Net database message types |
|
463 |
|
464 case ENDClose: |
|
465 CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::ENetDatabase)); |
|
466 break; |
|
467 |
|
468 case ENDQuery: |
|
469 case ENDAdd: |
|
470 case ENDRemove: |
|
471 ss=CNetDatabaseFromHandle(aMessage.Int3()); |
|
472 if (ss) |
|
473 { |
|
474 ForwardMessageL(aMessage, *ss); |
|
475 } |
|
476 else |
|
477 { |
|
478 PanicClient(ESockBadHandle); |
|
479 } |
|
480 break; |
|
481 case ENDCancel: |
|
482 ss=CNetDatabaseFromHandle(aMessage.Int3()); |
|
483 if (ss) |
|
484 { |
|
485 ForwardMessageL(aMessage, *ss); |
|
486 } |
|
487 else |
|
488 { |
|
489 LOG( ESockLog::Printf(_L8("CSockSession::ServiceL: BAD ENDCancel")) ); |
|
490 } |
|
491 break; |
|
492 case ECNClose: |
|
493 CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::EConnection)); |
|
494 break; |
|
495 case ECNStart: |
|
496 case ECNSetStartPrefs: |
|
497 case ECNStop: |
|
498 case ECNReference: |
|
499 case ECNProgress: |
|
500 case ECNProgressNotification: |
|
501 case ECNCancelProgressNotification: |
|
502 case ECNLastProgressError: |
|
503 case ECNServiceChangeNotification: |
|
504 case ECNCancelServiceChangeNotification: |
|
505 case ECNGetIntSetting: |
|
506 case ECNGetBoolSetting: |
|
507 case ECNGetDes8Setting: |
|
508 case ECNGetDes16Setting: |
|
509 case ECNGetLongDesSetting: |
|
510 case ECNEnumerateConnections: |
|
511 case ECNGetConnectionInfo: |
|
512 case ECNIoctl: |
|
513 case ECNCancelIoctl: |
|
514 case ECNControl: |
|
515 case ECNAttach: |
|
516 case ECNAllInterfaceNotification: |
|
517 case ECNCancelAllInterfaceNotification: |
|
518 case ECNCancelAllSubConnectionNotification: |
|
519 case ECNEnumerateSubConnections: |
|
520 case ECNAllSubConnectionNotification: |
|
521 case ECNWaitForIncoming: |
|
522 case ECNCancelWaitForIncoming: |
|
523 |
|
524 case ESCPSStop: |
|
525 case ESCPSProgressNotification: |
|
526 case ESCPSCancelProgressNotification: |
|
527 case ESCPSDataTransferred: |
|
528 case ESCPSDataTransferredCancel: |
|
529 case ESCPSDataSentNotificationRequest: |
|
530 case ESCPSDataSentNotificationCancel: |
|
531 case ESCPSDataReceivedNotificationRequest: |
|
532 case ESCPSDataReceivedNotificationCancel: |
|
533 case ESCPSIsSubConnectionActiveRequest: |
|
534 case ESCPSIsSubConnectionActiveCancel: |
|
535 |
|
536 case ESCPSGetSubConnectionInfo: |
|
537 ss=CConnectionFromHandle(aMessage.Int3()); |
|
538 if (ss) |
|
539 { |
|
540 ForwardMessageL(aMessage, *ss); |
|
541 } |
|
542 else |
|
543 { |
|
544 PanicClient(ESockBadHandle); |
|
545 } |
|
546 break; |
|
547 |
|
548 case ESCCreate: |
|
549 { |
|
550 TPckgBuf<TSubConnOpen> argPkg; |
|
551 SafeMessage().ReadL(MSG_PRM(0),argPkg); |
|
552 ss=CConnectionFromHandle(argPkg().iHandle); |
|
553 if (ss) |
|
554 { |
|
555 ForwardMessageL(aMessage, *ss); |
|
556 } |
|
557 else |
|
558 { |
|
559 PanicClient(ESockBadHandle); |
|
560 } |
|
561 break; |
|
562 } |
|
563 case ESCClose: |
|
564 CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::ESubConnection)); |
|
565 break; |
|
566 |
|
567 case ESCAddSocket: |
|
568 case ESCRemoveSocket: |
|
569 case ESCSetParameters: |
|
570 case ESCGetParameters: |
|
571 case ESCGetParametersLength: |
|
572 case ESCEventNotificationSetup: |
|
573 case ESCEventNotification: |
|
574 case ESCEventAllNotifications: |
|
575 case ESCEventNotificationCancel: |
|
576 case ESCControl: |
|
577 case ESCStart: |
|
578 case ESCStop: |
|
579 ss=CSubConnectionFromHandle(aMessage.Int3()); |
|
580 if (ss) |
|
581 { |
|
582 ForwardMessageL(aMessage, *ss); |
|
583 } |
|
584 else |
|
585 { |
|
586 PanicClient(ESockBadHandle); |
|
587 } |
|
588 break; |
|
589 |
|
590 // Server debug messages |
|
591 #if defined (_DEBUG_SOCKET_FUNCTIONS) |
|
592 case ESSDbgMarkHeap: |
|
593 case ESSDbgCheckHeap: |
|
594 case ESSDbgMarkEnd: |
|
595 case ESSDbgFailNext: |
|
596 case ESSDbgFailNextMbuf: |
|
597 case ESSDbgSetMbufPoolLimit: |
|
598 case ESSDbgCheckMbuf: |
|
599 case ESSDbgMbufFreeSpace: |
|
600 case ESSDbgMbufTotalSpace: |
|
601 case ESSDbgCheckFailNext: |
|
602 { |
|
603 if(!pitBoss.ModuleConfigurationComplete()) |
|
604 { |
|
605 if (Dealer()->ParkRequest(this, aMessage, CCommonDealer::EIndeterminateDuringBoot) != KErrNone) |
|
606 { |
|
607 //Something terrible has just happened. |
|
608 //We could not park the request. |
|
609 //Since this is a debug call it is probably a good idea to panic here, |
|
610 //hopefully providing a chance to see what is going wrong. |
|
611 __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockS_SES, 1)); |
|
612 } |
|
613 else |
|
614 { |
|
615 DontCompleteCurrentRequest(); |
|
616 } |
|
617 } |
|
618 else |
|
619 { |
|
620 SSDbgFunctionL(aMessage); |
|
621 } |
|
622 break; |
|
623 } |
|
624 #endif // _DEBUG_SOCKET_FUNCTIONS |
|
625 |
|
626 default: |
|
627 ss = SubSessionFromHandle(aMessage.Int3(), TCFSubSessInfo(TCFSubSessInfo::EAny)); |
|
628 |
|
629 if(ss) |
|
630 { |
|
631 ForwardMessageL(aMessage, *ss); |
|
632 } |
|
633 else |
|
634 { |
|
635 PanicClient(ESockBadHandle); |
|
636 } |
|
637 break; |
|
638 } |
|
639 |
|
640 // Message handlers can change the state of the iMessage if they want to hold onto the message. |
|
641 // They can also write a return value to iReturn. |
|
642 if (iComplete) |
|
643 { |
|
644 LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tServiceL, Complete message(%08x) with %d."), this, aMessage.Handle(), iReturn) ); |
|
645 aMessage.Complete(iReturn); |
|
646 } |
|
647 } |
|
648 |
|
649 #if defined (_DEBUG_SOCKET_FUNCTIONS) |
|
650 void CSockSession::DispatchDebugMessageL(const RMessage2& aMessage) |
|
651 { |
|
652 Elements::RResponseMsg responseMsg(aMessage, aMessage.Int0(), 1, 2); |
|
653 |
|
654 // Construct our message in place |
|
655 TBuf8<ESockDebug::KMaxIpcMsgLength> msgDst; |
|
656 ESockDebug::TControlMsg* msg = static_cast<ESockDebug::TControlMsg*>(responseMsg.ReadClientReqMsg(msgDst)); |
|
657 __ASSERT_ALWAYS(msg, Fault(EDebugSupport)); |
|
658 |
|
659 // Self dispatch our message and return any error code |
|
660 TPckgBuf<TInt> returnValue; |
|
661 TInt& debugStatus = returnValue(); |
|
662 debugStatus = msg->DispatchL(this); |
|
663 SafeMessage(aMessage).WriteL(MSG_PRM(0), returnValue); |
|
664 } |
|
665 |
|
666 |
|
667 #endif // _DEBUG_SOCKET_FUNCTIONS |
|
668 |
|
669 #if defined (_DEBUG_SOCKET_FUNCTIONS) |
|
670 void CSockSession::SSDbgFunctionL(const RMessage2& aMessage) |
|
671 { |
|
672 switch(aMessage.Function()) |
|
673 { |
|
674 case ESSDbgMarkHeap: |
|
675 __UHEAP_MARK; |
|
676 break; |
|
677 case ESSDbgCheckHeap: |
|
678 __UHEAP_CHECK(aMessage.Int0()); |
|
679 break; |
|
680 case ESSDbgMarkEnd: |
|
681 __UHEAP_MARKENDC(aMessage.Int0()); |
|
682 break; |
|
683 case ESSDbgFailNext: |
|
684 { |
|
685 const CWorkerThread& owner=WorkerThread(); |
|
686 CPitBoss& pitBoss = owner.PitBoss(); |
|
687 |
|
688 // We set the fail point for all heaps, rather than just the current Dealer. This could lead to a failure not related |
|
689 // directly to whatever the client test code is trying to exercise but it all helps find bugs |
|
690 pitBoss.SetFailNextForAllHeaps(aMessage.Int0()); |
|
691 break; |
|
692 } |
|
693 case ESSDbgCheckFailNext: |
|
694 { |
|
695 // Report whether any heap has ended "FailNext" mode set by ESSDbgFailNext, which generally indicates that some code |
|
696 // under test hasn't explored all allocation points |
|
697 const CWorkerThread& owner=WorkerThread(); |
|
698 CPitBoss& pitBoss = owner.PitBoss(); |
|
699 SetReturn(pitBoss.TestFailNextForAllHeaps()); |
|
700 break; |
|
701 } |
|
702 // MBuf specific allocation fails and checks. |
|
703 case ESSDbgFailNextMbuf: |
|
704 { |
|
705 #ifdef SYMBIAN_ZERO_COPY_NETWORKING |
|
706 RCommsBufPond pond=TCommsBufPondTLSOp::Get(); |
|
707 if (pond.IsNull()) |
|
708 { |
|
709 PanicClient(EMbufManagerNotLoaded); |
|
710 } |
|
711 else |
|
712 { |
|
713 TCommsBufPondDbg pondDbg(pond); |
|
714 pondDbg.__DbgSetFailAfter(aMessage.Int0()); |
|
715 } |
|
716 #else |
|
717 CMBufManager* mbufMan=CMBufManager::Context(); |
|
718 if (mbufMan==NULL) |
|
719 { |
|
720 PanicClient(EMbufManagerNotLoaded); |
|
721 } |
|
722 else |
|
723 { |
|
724 mbufMan->__DbgSetFailAfter(aMessage.Int0()); |
|
725 } |
|
726 #endif // SYMBIAN_ZERO_COPY_NETWORKING |
|
727 break; |
|
728 } |
|
729 case ESSDbgSetMbufPoolLimit: |
|
730 { |
|
731 #ifdef SYMBIAN_ZERO_COPY_NETWORKING |
|
732 RCommsBufPond pond=TCommsBufPondTLSOp::Get(); |
|
733 if (pond.IsNull()) |
|
734 { |
|
735 PanicClient(EMbufManagerNotLoaded); |
|
736 } |
|
737 else |
|
738 { |
|
739 TCommsBufPondDbg pondDbg(pond); |
|
740 pondDbg.__DbgSetPoolLimit(aMessage.Int0()); |
|
741 } |
|
742 #else |
|
743 CMBufManager* mbufMan=CMBufManager::Context(); |
|
744 if (mbufMan==NULL) |
|
745 { |
|
746 PanicClient(EMbufManagerNotLoaded); |
|
747 } |
|
748 else |
|
749 { |
|
750 mbufMan->__DbgSetPoolLimit(aMessage.Int0()); |
|
751 } |
|
752 |
|
753 #endif // SYMBIAN_ZERO_COPY_NETWORKING |
|
754 break; |
|
755 } |
|
756 case ESSDbgCheckMbuf: |
|
757 { |
|
758 #ifdef SYMBIAN_ZERO_COPY_NETWORKING |
|
759 RCommsBufPond pond=TCommsBufPondTLSOp::Get(); |
|
760 if (pond.IsNull()) |
|
761 { |
|
762 PanicClient(EMbufManagerNotLoaded); |
|
763 } |
|
764 else |
|
765 { |
|
766 TCommsBufPondDbg pondDbg(pond); |
|
767 if (pondDbg.__DbgGetBufTotal()-pondDbg.__DbgGetBufSpace()!=aMessage.Int0()) |
|
768 { |
|
769 Fault(EBadMbufCheck); |
|
770 } |
|
771 } |
|
772 #else |
|
773 CMBufManager* mbufMan=CMBufManager::Context(); |
|
774 if (mbufMan==NULL) |
|
775 { |
|
776 PanicClient(EMbufManagerNotLoaded); |
|
777 } |
|
778 else |
|
779 { |
|
780 if (mbufMan->__DbgGetBufTotal()-mbufMan->__DbgGetBufSpace()!=aMessage.Int0()) |
|
781 Fault(EBadMbufCheck); |
|
782 } |
|
783 #endif |
|
784 break; |
|
785 } |
|
786 case ESSDbgMbufFreeSpace: |
|
787 { |
|
788 #ifdef SYMBIAN_ZERO_COPY_NETWORKING |
|
789 RCommsBufPond pond=TCommsBufPondTLSOp::Get(); |
|
790 if (pond.IsNull()) |
|
791 { |
|
792 PanicClient(EMbufManagerNotLoaded); |
|
793 } |
|
794 else |
|
795 { |
|
796 TPckgBuf<TInt> c; |
|
797 TInt& space=c(); |
|
798 TCommsBufPondDbg pondDbg(pond); |
|
799 space=pondDbg.__DbgGetBufSpace(); |
|
800 SafeMessage().WriteL(MSG_PRM(0),c); |
|
801 } |
|
802 #else |
|
803 CMBufManager* mbufMan=CMBufManager::Context(); |
|
804 if (mbufMan==NULL) |
|
805 { |
|
806 PanicClient(EMbufManagerNotLoaded); |
|
807 } |
|
808 else |
|
809 { |
|
810 TPckgBuf<TInt> c; |
|
811 TInt& space=c(); |
|
812 space=mbufMan->__DbgGetBufSpace(); |
|
813 SafeMessage().WriteL(MSG_PRM(0),c); |
|
814 } |
|
815 #endif |
|
816 break; |
|
817 } |
|
818 case ESSDbgMbufTotalSpace: |
|
819 { |
|
820 #ifdef SYMBIAN_ZERO_COPY_NETWORKING |
|
821 RCommsBufPond pond=TCommsBufPondTLSOp::Get(); |
|
822 if (pond.IsNull()) |
|
823 { |
|
824 PanicClient(EMbufManagerNotLoaded); |
|
825 } |
|
826 else |
|
827 { |
|
828 TPckgBuf<TInt> c; |
|
829 TInt& size=c(); |
|
830 TCommsBufPondDbg pondDbg(pond); |
|
831 size=pondDbg.__DbgGetBufTotal(); |
|
832 SafeMessage().WriteL(MSG_PRM(0),c); |
|
833 } |
|
834 #else |
|
835 CMBufManager* mbufMan=CMBufManager::Context(); |
|
836 if (mbufMan==NULL) |
|
837 { |
|
838 PanicClient(EMbufManagerNotLoaded); |
|
839 } |
|
840 else |
|
841 { |
|
842 TPckgBuf<TInt> c; |
|
843 TInt& size=c(); |
|
844 size=mbufMan->__DbgGetBufTotal(); |
|
845 SafeMessage().WriteL(MSG_PRM(0),c); |
|
846 } |
|
847 #endif // SYMBIAN_ZERO_COPY_NETWORKING |
|
848 } |
|
849 break; |
|
850 |
|
851 // Bad message |
|
852 default: |
|
853 PanicClient(ESockBadHandle); |
|
854 } |
|
855 } |
|
856 #endif |
|
857 // _DEBUG_SOCKET_FUNCTIONS |
|
858 |
|
859 |
|
860 |
|
861 /** |
|
862 Return a CSocket given a client's handle |
|
863 */ |
|
864 CSocket* CSockSession::CSocketFromHandle(TUint aHandle) |
|
865 { |
|
866 return static_cast<CSocket*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::ESocket))); |
|
867 } |
|
868 |
|
869 /** |
|
870 Return a Flow and SCPR CommsIds given a socket's handle |
|
871 */ |
|
872 TBool CSockSession::FlowAndSCPRFromSocketHandle(TUint aHandle, Messages::TNodeId& aFlow, Messages::TNodeId& aSCPR) |
|
873 { |
|
874 SubSessions().Lock(); |
|
875 |
|
876 TInt found = EFalse; |
|
877 |
|
878 CSocket* sock = static_cast<CSocket*>(iSubSessions.At(aHandle, TCFSubSessInfo(TCFSubSessInfo::ESocket))); |
|
879 if (sock) |
|
880 { |
|
881 found = sock->GetFlowAndSCPR(aFlow, aSCPR); |
|
882 } |
|
883 |
|
884 SubSessions().Unlock(); |
|
885 |
|
886 return found; |
|
887 } |
|
888 |
|
889 /** |
|
890 Find a CNameResolver from a clients handle |
|
891 */ |
|
892 CHostResolver* CSockSession::CHostResolverFromHandle(TUint aHandle) |
|
893 { |
|
894 return static_cast<CHostResolver*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::EHostResolver))); |
|
895 } |
|
896 |
|
897 /** |
|
898 Find a CServiceresolver from a clients handle |
|
899 */ |
|
900 CServiceResolver* CSockSession::CServiceResolverFromHandle(TUint aHandle) |
|
901 { |
|
902 return static_cast<CServiceResolver*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::EServiceResolver))); |
|
903 } |
|
904 |
|
905 /** |
|
906 Find a CNetDatabase from a handle |
|
907 */ |
|
908 CNetDatabase* CSockSession::CNetDatabaseFromHandle(TUint aHandle) |
|
909 { |
|
910 return static_cast<CNetDatabase*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::ENetDatabase))); |
|
911 } |
|
912 |
|
913 /** |
|
914 Find a CConnection from a handle |
|
915 */ |
|
916 ESock::CConnection* CSockSession::CConnectionFromHandle(TUint aHandle) |
|
917 { |
|
918 return static_cast<ESock::CConnection*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::EConnection))); |
|
919 } |
|
920 |
|
921 /** |
|
922 find a CSubConnection from a handle |
|
923 |
|
924 */ |
|
925 CSubConnection* CSockSession::CSubConnectionFromHandle(TUint aHandle) |
|
926 { |
|
927 return static_cast<CSubConnection*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::ESubConnection))); |
|
928 } |
|
929 |
|
930 void CSockSession::CloseSubSessionL(const RMessage2& aMessage, TSubSessInfo aType) |
|
931 { |
|
932 CWorkerSubSession* subSess = NULL; |
|
933 |
|
934 { |
|
935 SubSessions().Lock(); |
|
936 |
|
937 subSess = iSubSessions.At(aMessage.Int3(), aType); |
|
938 LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tCloseSubSession(%08x, %d) - subSess %08x"), this, aMessage.Int3(), aType.iType, subSess)); |
|
939 if(subSess) |
|
940 { |
|
941 VERIFY_RESULT(iSubSessions.Remove(aMessage.Int3()), subSess); |
|
942 } |
|
943 |
|
944 SubSessions().Unlock(); |
|
945 } |
|
946 |
|
947 if(subSess) |
|
948 { |
|
949 ForwardMessageL(aMessage, *subSess); |
|
950 } |
|
951 else |
|
952 { |
|
953 SetReturn(KErrBadHandle); // Close() is always safe |
|
954 } |
|
955 } |
|
956 |
|
957 |
|
958 /** |
|
959 Search for an optimal dealer. If one is found set the iOptimalDealer member, register |
|
960 the requesting PID on the optimal dealer and return the dealer server name to the client. |
|
961 */ |
|
962 void CSockSession::RequestOptimalDealerL() |
|
963 { |
|
964 /* Wont accept this if we're shutting down or if we've |
|
965 already requested optimal dealer (successfully) before */ |
|
966 if(SocketServer::IsShuttingDown()) |
|
967 { |
|
968 User::Leave(KErrServerTerminated); |
|
969 } |
|
970 else if(iOptimalDealer) |
|
971 { |
|
972 PanicClient(EConnectingAlready); |
|
973 } |
|
974 else // Ok, find optimal dealer and register it with session, tell nice client... |
|
975 { |
|
976 TSessionPref pref; |
|
977 TPckg<TSessionPref> package(pref); |
|
978 SafeMessage().ReadL(MSG_PRM(0), package); |
|
979 if(PitBoss().FindOptimalDealer(pref, iOptimalDealer)) |
|
980 { |
|
981 // Add PID to table of authorised clients. |
|
982 iOptimalDealer->AddEligiblePidL(iProcess.Id()); |
|
983 SafeMessage().WriteL(MSG_PRM(1), iOptimalDealer->ServerName()); |
|
984 SetReturn(KErrNone); |
|
985 LOG(ESockLog::Printf(KESockSessDetailTag, _L("CSockSession(%08x):\tRequestOptimalDealerL %S for 0x%X"), this, &iOptimalDealer->ServerName(), static_cast<TUint>(iEligiblePid)) ); |
|
986 } |
|
987 else |
|
988 { |
|
989 LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tRequestOptimalDealerL KErrNotFound"), this) ); |
|
990 iOptimalDealer=NULL; |
|
991 // Optimal Dealer requests don't get parked during boot - there's a risk of creating a hard-to-debug startup deadlock |
|
992 // which outweighs the performance benefit |
|
993 SetReturn(KErrNotFound); |
|
994 } |
|
995 } |
|
996 } |
|
997 |
|
998 /** |
|
999 Determine the owning Player and forward the TransferSocket message to it. |
|
1000 */ |
|
1001 void CSockSession::TransferSocketL() |
|
1002 { |
|
1003 TName name; |
|
1004 SafeMessage().ReadL(MSG_PRM(0), name); |
|
1005 CWorkerSubSession* socket; |
|
1006 TInt err = CSocket::FetchSubSessionFromName(name, TCFSubSessInfo(TCFSubSessInfo::ESocket), WorkerThread(), socket); |
|
1007 if(err == KErrNone) |
|
1008 { |
|
1009 ForwardMessageL(*iOurMessage, *socket); |
|
1010 } |
|
1011 User::Leave(KErrNotFound); // name bad or Player exited |
|
1012 } |
|
1013 |
|
1014 /** |
|
1015 Handle a request for the number of loaded protocols. |
|
1016 */ |
|
1017 void CSockSession::NumProtocolsL(void) |
|
1018 { |
|
1019 if(!PitBoss().ModuleConfigurationComplete()) |
|
1020 { |
|
1021 ParkIfIndeterminateRequest(Message(), KErrNone); |
|
1022 } |
|
1023 else |
|
1024 { |
|
1025 TUint num=PitBoss().GetNumProtocols(); |
|
1026 TPtrC8 d((TUint8 *)&num,sizeof(num)); |
|
1027 if (SafeMessage().Write(MSG_PRM(0),d) != KErrNone) |
|
1028 { |
|
1029 DontCompleteCurrentRequest(); |
|
1030 } |
|
1031 } |
|
1032 } |
|
1033 |
|
1034 /** |
|
1035 Get info for a protocol by index. |
|
1036 */ |
|
1037 void CSockSession::ProtocolInfoL(void) |
|
1038 { |
|
1039 TWorkerId worker; |
|
1040 if(!PitBoss().GetWorkerForProtocol(Message().Int1(), worker)) |
|
1041 { |
|
1042 ParkIfIndeterminateRequest(Message(), KErrNotFound); |
|
1043 } |
|
1044 else |
|
1045 { |
|
1046 ForwardMessageL(Message(), TPlayerForwardRequestMsg::UnusedParam(), worker); |
|
1047 } |
|
1048 } |
|
1049 |
|
1050 /** |
|
1051 Get protocol info by name. |
|
1052 */ |
|
1053 void CSockSession::ProtocolInfoByNameL( ) |
|
1054 { |
|
1055 TProtocolName name; |
|
1056 SafeMessage().ReadL(MSG_PRM(1),name); |
|
1057 |
|
1058 TWorkerId worker; |
|
1059 if(!PitBoss().GetWorkerForProtocolByName(name, worker)) |
|
1060 { |
|
1061 ParkIfIndeterminateRequest(Message(), KErrNotFound); |
|
1062 } |
|
1063 else |
|
1064 { |
|
1065 ForwardMessageL(Message(), TPlayerForwardRequestMsg::UnusedParam(), worker); |
|
1066 } |
|
1067 } |
|
1068 |
|
1069 /** |
|
1070 Panic the client. |
|
1071 */ |
|
1072 void CSockSession::PanicClient(TESockPanic aPanic) |
|
1073 { |
|
1074 SafeMessage().PanicClient(KESockClientPanic, (TInt) aPanic); |
|
1075 DontCompleteCurrentRequest(); |
|
1076 } |
|
1077 |
|
1078 |
|
1079 #ifdef SYMBIAN_NETWORKING_PERFMETRICS |
|
1080 void CSockSession::IncludePerformanceData(TInt aDeltaClientRxBytes, TInt aDeltaClientRxBuffBytes, TInt aDeltaClientTxBytes) |
|
1081 { |
|
1082 SockManGlobals()->IncludePerformanceData(aDeltaClientRxBytes, aDeltaClientRxBuffBytes, aDeltaClientTxBytes); |
|
1083 } |
|
1084 #endif |
|
1085 |
|
1086 /** |
|
1087 Constructor |
|
1088 */ |
|
1089 CSockSubSession::CSockSubSession(CSockSession* aSession, CPlayer* aPlayer, const Den::TSubSessionUniqueId aSubSessionUniqueId) |
|
1090 : CWorkerSubSession(aSession, aPlayer, aSubSessionUniqueId) |
|
1091 { |
|
1092 } |
|
1093 |
|
1094 void CSockSubSession::ConstructL(CProtocolBase* aProtocol) |
|
1095 { |
|
1096 CWorkerSubSession::ConstructL(); |
|
1097 if(aProtocol) |
|
1098 { |
|
1099 CSockSessionProxy* sp = static_cast<CSockSessionProxy*>(SessionProxy()); |
|
1100 sp->AddProtocolL(aProtocol); |
|
1101 } |
|
1102 } |
|
1103 |
|
1104 CSockSession* CSockSubSession::Session() |
|
1105 { |
|
1106 return static_cast<CSockSession*>(Den::CWorkerSubSession::Session()); |
|
1107 } |
|
1108 |
|
1109 const CSockSession* CSockSubSession::Session() const |
|
1110 { |
|
1111 return static_cast<const CSockSession*>(Den::CWorkerSubSession::Session()); |
|
1112 } |
|
1113 |
|
1114 void CSockSubSession::DeleteMe() |
|
1115 { |
|
1116 LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSubSession %08x:\tDeleteMe() - iSubSessionUniqueId %08X, iType %d, iSession %08x"), this, iSubSessionUniqueId, Type().iType, iSession) ); |
|
1117 |
|
1118 switch(Type().iType) |
|
1119 { |
|
1120 case TCFSubSessInfo::ESocket: |
|
1121 static_cast<CSocket*>(this)->InitiateDestruction(); |
|
1122 break; |
|
1123 case TCFSubSessInfo::EHostResolver: |
|
1124 static_cast<CHostResolver*>(this)->InitiateDestruction(); |
|
1125 break; |
|
1126 case TCFSubSessInfo::EServiceResolver: |
|
1127 { |
|
1128 // Remove the subsession from the session's subsession list. |
|
1129 if(iSession) |
|
1130 { |
|
1131 iSession->SubSessions().Lock(); |
|
1132 |
|
1133 CSubSessionIx::TSubSessionHandle handle; |
|
1134 if(iSession->SubSessions().Find(this, handle) == KErrNone) |
|
1135 { |
|
1136 iSession->PitBoss().RemoveSubSession(handle, iSession); |
|
1137 } |
|
1138 |
|
1139 iSession->SubSessions().Unlock(); |
|
1140 } |
|
1141 |
|
1142 delete this; |
|
1143 } |
|
1144 break; |
|
1145 case TCFSubSessInfo::ENetDatabase: |
|
1146 { |
|
1147 // Remove the subsession from the session's subsession list. |
|
1148 if(iSession) |
|
1149 { |
|
1150 iSession->SubSessions().Lock(); |
|
1151 |
|
1152 CSubSessionIx::TSubSessionHandle handle; |
|
1153 if(iSession->SubSessions().Find(this, handle) == KErrNone) |
|
1154 { |
|
1155 iSession->PitBoss().RemoveSubSession(handle, iSession); |
|
1156 } |
|
1157 |
|
1158 iSession->SubSessions().Unlock(); |
|
1159 } |
|
1160 |
|
1161 delete this; |
|
1162 } |
|
1163 break; |
|
1164 case TCFSubSessInfo::EConnection: |
|
1165 //Mimic the client sending ECNClose (without RMessage2) |
|
1166 { |
|
1167 const TNodeId& c = static_cast<CConnection&>(*this).Id(); |
|
1168 RClientInterface::OpenPostMessageClose(TNodeCtxId(ECNClose, c), TNodeCtxId(ECNClose, c), ESock::TCFInternalEsock::TSubSess(ECNClose,RMessage2()).CRef()); |
|
1169 } |
|
1170 break; |
|
1171 case TCFSubSessInfo::ESubConnection: |
|
1172 //Mimic the client sending ESCClose (without RMessage2) |
|
1173 { |
|
1174 const TNodeId& sc = static_cast<CSubConnection&>(*this).Id(); |
|
1175 RClientInterface::OpenPostMessageClose(sc, TNodeCtxId(ESCClose, sc), ESock::TCFInternalEsock::TSubSess(ESCClose,RMessage2()).CRef()); |
|
1176 } |
|
1177 break; |
|
1178 default: |
|
1179 //Please support your new subsession type |
|
1180 __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockSSockS_SES, 2)); |
|
1181 } |
|
1182 |
|
1183 } |
|
1184 |
|
1185 CSockSubSession::~CSockSubSession() |
|
1186 { |
|
1187 LOG(ESockLog::Printf(KESockServerTag, _L8("CSockSubSession(%08x):\t~CSockSubSession Session(%08x)"), this, iSession) ); |
|
1188 |
|
1189 // A subsession has a session proxy unless OOM prevented it |
|
1190 if(SessionProxy()) |
|
1191 { |
|
1192 SessionProxy()->NotifySubSessionDestroyed(); |
|
1193 } |
|
1194 } |
|
1195 |
|
1196 //Default implementation - must be specialised if used |
|
1197 void CSockSubSession::CommsApiExtBindIfaceL(const RMessage2& /*aMessage*/) |
|
1198 { |
|
1199 User::Leave(KErrNotSupported); |
|
1200 } |
|
1201 |
|
1202 //Default implementation - must be specialised if used |
|
1203 void CSockSubSession::CommsApiExtIfaceSendReceiveL(const RMessage2& /*aMessage*/) |
|
1204 { |
|
1205 User::Leave(KErrNotSupported); |
|
1206 } |
|
1207 |
|
1208 //Default implementation - must be specialised if used |
|
1209 void CSockSubSession::CloseExtensionInterface(const RMessage2& /*aMessage*/) |
|
1210 { |
|
1211 } |
|
1212 |
|
1213 //Default implementation - must be specialised if used |
|
1214 void CSockSubSession::CancelAndCloseAllClientExtIfaces() |
|
1215 { |
|
1216 } |
|
1217 |
|
1218 /** Client request to forwarded to the thread of the tier manager for the given tier. Possibilities: |
|
1219 (1) Mapping of tier to worker thread already known; can forward directly |
|
1220 (2) Mapping unknown & mappings loaded; fail request |
|
1221 (3) Mapping unknown & mappings not yet loaded; park request and request tier resolver to load mappings |
|
1222 (4) Tier resolver not yet located (ie during boot); request parked as indeterminate |
|
1223 |
|
1224 Because only the main thread is guaranteed to have a binding to the tier resolver, the request for |
|
1225 mappings is always made by it, ie a secondary Dealer sends the request to load mappings to it. After |
|
1226 adding the mappings the main thread then messages all other workers to tell them to unpark any requests |
|
1227 awaiting the tier mappings. |
|
1228 |
|
1229 The last thing added is the dummy "tiers loaded" flag, which serves to indicate to Dealers that resolution |
|
1230 is complete. |
|
1231 */ |
|
1232 void CSockSession::ForwardTierRequestL(const RMessage2& aMessage) |
|
1233 { |
|
1234 TWorkerId worker; |
|
1235 TUint family = aMessage.Int0(); |
|
1236 TUint protocol = aMessage.Int2(); |
|
1237 TUid tierUid = TierManagerUtils::MapTierIdsL(TUid::Uid(family), protocol); |
|
1238 CPitBoss& pitBoss = PitBoss(); |
|
1239 if(pitBoss.GetWorkerForTier(tierUid.iUid, worker)) |
|
1240 { |
|
1241 //ForwardMessageL(aMessage, reinterpret_cast<CSockSubSession*>(tierUid.iUid), worker); |
|
1242 ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), worker); |
|
1243 } |
|
1244 else |
|
1245 { |
|
1246 // No mapping found; either it's a bad id or we've yet to load mappings |
|
1247 TInt err = KErrNone; |
|
1248 if(PitBoss().TierMappingsLoaded()) |
|
1249 { |
|
1250 err = KErrBadName; |
|
1251 } |
|
1252 else |
|
1253 { |
|
1254 err = Dealer()->ParkRequest(this, aMessage, CCommonDealer::EAwaitingTierToWorkerMapping); |
|
1255 } |
|
1256 if(err == KErrNone) |
|
1257 { |
|
1258 if(WorkerId() != TWorkerThreadPublicInfo::EMainThread) |
|
1259 { |
|
1260 TWorkerLoadTierMappings msg; |
|
1261 WorkerThread().PostMessage(TWorkerThreadPublicInfo::EMainThread, msg); |
|
1262 } |
|
1263 else |
|
1264 { |
|
1265 PitBoss().RequestLoadTierMapping(); |
|
1266 } |
|
1267 } |
|
1268 if(err == KErrNone) |
|
1269 { |
|
1270 DontCompleteCurrentRequest(); |
|
1271 } |
|
1272 else |
|
1273 { |
|
1274 SetReturn(err); |
|
1275 } |
|
1276 } |
|
1277 } |
|
1278 |
|
1279 CWorkerThread& CSockSession::WorkerThread() const |
|
1280 { |
|
1281 return static_cast<CWorkerThread&>(CWorkerSession::WorkerThread()); |
|
1282 } |
|
1283 |
|
1284 |
|
1285 CPitBoss& CSockSession::PitBoss() const |
|
1286 { |
|
1287 return static_cast<CPitBoss&>(CWorkerSession::PitBoss()); |
|
1288 } |
|
1289 |
|
1290 void CSockSession::Disconnect(const RMessage2& aMessage) |
|
1291 { |
|
1292 LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tDisconnect \"%S\""), this, &iProcessName) ); |
|
1293 CWorkerSession::Disconnect(aMessage); |
|
1294 } |