|
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // eintsockimpl.cpp |
|
15 // @file |
|
16 // @internalTechnology |
|
17 // |
|
18 // |
|
19 |
|
20 #include "ss_eintsocklog.h" |
|
21 #include <comms-infras/eintsock.h> |
|
22 #include "ss_eintsockimpl.h" |
|
23 #include <in_sock.h> |
|
24 #include <ss_pman.h> |
|
25 #include <ss_glob.h> |
|
26 #include <comms-infras/ss_roles.h> |
|
27 #include <comms-infras/ss_thread.h> |
|
28 #include <comms-infras/cfmacro.h> |
|
29 |
|
30 |
|
31 #ifdef _DEBUG |
|
32 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
33 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
34 _LIT(KSpecAssert_ESockEIntSocksnt, "ESockEIntSocksnt"); |
|
35 #endif |
|
36 |
|
37 using namespace CommsFW; |
|
38 using namespace ESock; |
|
39 using namespace Messages; |
|
40 using namespace Den; |
|
41 |
|
42 #define MSG_PRM(prmIndex) (prmIndex) |
|
43 |
|
44 // |
|
45 // CInternalSocketImpl |
|
46 // |
|
47 |
|
48 // |
|
49 // Replacement for RSocket::Open gubbins - need to do it slightly differently since we're in the esock thread |
|
50 // |
|
51 |
|
52 CInternalSocketImpl* CInternalSocketImpl::NewL(const CInternalSockSubSession::TParameters& aParams) |
|
53 /** |
|
54 Create a new (blank) internal socket for use in socket Accept() call |
|
55 @note This will Open() the protocol as part of the Accept() call |
|
56 */ |
|
57 { |
|
58 CInternalSocketImpl* self = new(ELeave) CInternalSocketImpl(aParams, KUndefinedSockType); |
|
59 CleanupStack::PushL(self); |
|
60 self->ConstructL(aParams, NULL, NULL); |
|
61 CleanupStack::Pop(self); |
|
62 return(self); |
|
63 } |
|
64 |
|
65 CInternalSocketImpl* CInternalSocketImpl::NewL ( const CInternalSockSubSession::TParameters& aParams, TServerProtocolDesc* aServiceInfo, CProtocolBase* aProt ) |
|
66 { |
|
67 CInternalSocketImpl* self = new (ELeave) CInternalSocketImpl ( aParams, aServiceInfo->iSockType ); |
|
68 CleanupStack::PushL(self); |
|
69 self->ConstructL ( aParams, aServiceInfo, aProt ); |
|
70 CleanupStack::Pop(self); |
|
71 return(self); |
|
72 } |
|
73 |
|
74 CInternalSocketImpl::CInternalSocketImpl(const CInternalSockSubSession::TParameters& aParams, TUint aSockType) |
|
75 : CInternalSockSubSession(aParams), |
|
76 ASocket (aSockType) |
|
77 /** |
|
78 Just some random bits and pieces of setup |
|
79 */ |
|
80 { |
|
81 LOG_NODE_CREATE(KESockFlowTag, CInternalSocketImpl) |
|
82 } |
|
83 |
|
84 |
|
85 void CInternalSocketImpl::ConstructL ( const TParameters& aParams, TServerProtocolDesc* aServiceInfo, CProtocolBase* aProt) |
|
86 { |
|
87 LOG(Log::Printf(_L("CInternalSocketImpl[%x]: ConstructL() called."), this)); |
|
88 CInternalSockSubSession::ConstructL(aParams); |
|
89 ASocket::Create (aServiceInfo); |
|
90 |
|
91 // Open a reference to the protocol we using |
|
92 __ASSERT_DEBUG(iProtocol == NULL, User::Panic(KSpecAssert_ESockEIntSocksnt, 1)); |
|
93 iProtocol = aProt; |
|
94 if(iProtocol) |
|
95 { |
|
96 iProtocol->Open(); |
|
97 } |
|
98 |
|
99 InitUserMessageL (ESocketCurrentMessage); |
|
100 InitUserMessageL (ESocketReadMessage); |
|
101 InitUserMessageL (ESocketWriteMessage); |
|
102 InitUserMessageL (ESocketCloseMessage); |
|
103 InitUserMessageL (ESocketIoCtlMessage); |
|
104 InitUserMessageL (ESocketConnectMessage); |
|
105 InitUserMessageL (ESocketSetLocalNameMessage); |
|
106 |
|
107 // Post a request to bind to a flow. |
|
108 if ( aServiceInfo ) |
|
109 { |
|
110 TFlowParams flowParams( |
|
111 aServiceInfo->iAddrFamily, |
|
112 aServiceInfo->iSockType, |
|
113 aServiceInfo->iProtocol, |
|
114 TFlowParams::EImplicit, |
|
115 NULL |
|
116 ); |
|
117 |
|
118 RClientInterface::OpenPostMessageClose( |
|
119 Id(), //socket is the sender |
|
120 SockManGlobals::Get()->GetPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)), //phoney recipient - we only care the recipient is on the control plane so that this message is dispatched on the correct thread |
|
121 TCFImplicitFlowRequest(flowParams) |
|
122 ); |
|
123 |
|
124 SetFlowRequestPending(ETrue); |
|
125 AdoptFlowRequest(*(aParams.iRequest)); |
|
126 DontCompleteCurrentRequest(); |
|
127 } |
|
128 } |
|
129 |
|
130 /** |
|
131 Cleanup various objects that we own and/or use. |
|
132 */ |
|
133 CInternalSocketImpl::~CInternalSocketImpl() |
|
134 { |
|
135 // Close the reference to the protocol we have open |
|
136 if(iProtocol) |
|
137 { |
|
138 iProtocol->Close(); |
|
139 } |
|
140 |
|
141 LOG(Log::Printf(_L("CInternalSocketImpl[%x]: destructor called."), this)); |
|
142 iLink.Deque (); |
|
143 FinalCompleteAllBlockedMessages(KErrAbort); |
|
144 LOG_NODE_DESTROY(KESockFlowTag, CInternalSocketImpl) |
|
145 } |
|
146 |
|
147 void CInternalSocketImpl::FinalCompleteAllBlockedMessages(TInt aResult) |
|
148 { |
|
149 // We don't check for whether the socket is orphaned as opposed to CSocket. |
|
150 // Our internal subsession exists. Just complete everything. |
|
151 CompleteConnect(aResult); |
|
152 CompleteClose(aResult); |
|
153 CompleteRead(aResult); |
|
154 CompleteWrite(aResult); |
|
155 CompleteIoctl(aResult); |
|
156 CompleteSetLocalName(aResult); |
|
157 } |
|
158 |
|
159 /** |
|
160 Cleanup the resources used by the socket. This may close the socket immediately, or, if the |
|
161 protocol supports graceful close, may wait for the protocol to call CanClose(). |
|
162 */ |
|
163 TBool CInternalSocketImpl::CloseSocket() |
|
164 { |
|
165 LOG(Log::Printf(_L("CInternalSocketImpl[%x]: CloseSocket() called..."), this)); |
|
166 TBool immediate = ASocket::CloseSocket (); |
|
167 if ( immediate ) |
|
168 { |
|
169 // We have to do the destruction when ASocket::CloseSocket has returned ETrue. |
|
170 // It returns ETrue only when you need to really delete the implementation else |
|
171 // it will return EFalse |
|
172 InitiateDestruction(); |
|
173 } |
|
174 return immediate; |
|
175 } |
|
176 |
|
177 void CInternalSocketImpl::SetClosing() |
|
178 { |
|
179 iClosing = ETrue; |
|
180 } |
|
181 |
|
182 TBool CInternalSocketImpl::IsClosing() |
|
183 { |
|
184 return iClosing; |
|
185 } |
|
186 |
|
187 void CInternalSocketImpl::CompleteCurrentRequest ( TBool aValue ) |
|
188 { |
|
189 iComplete = aValue; |
|
190 } |
|
191 |
|
192 void CInternalSocketImpl::DontCompleteCurrentRequest() |
|
193 { |
|
194 CompleteCurrentRequest ( EFalse ); |
|
195 } |
|
196 |
|
197 TBool CInternalSocketImpl::ShouldCompleteCurrentRequest () const |
|
198 { |
|
199 return iComplete; |
|
200 } |
|
201 |
|
202 |
|
203 ASocket* CInternalSocketImpl::InitiateAcceptingSocket() |
|
204 { |
|
205 RInternalSocket* blankSocket = reinterpret_cast < RInternalSocket* > ( iCurrentMsg->ReadInt(1) ); |
|
206 |
|
207 CInternalSocketImpl* nullSocket = blankSocket->Implementation(); |
|
208 if(!nullSocket) |
|
209 { |
|
210 PanicSocketClient(ESockBadHandle); |
|
211 return NULL; |
|
212 } |
|
213 if (nullSocket->State() != ESStateNull) |
|
214 { |
|
215 PanicSocketClient(EAcceptTwice); |
|
216 return NULL; |
|
217 } |
|
218 //We need to ensure that the socket does not get accepted onto twice |
|
219 nullSocket->SetState(ESStateAccepting); |
|
220 return nullSocket; |
|
221 |
|
222 } |
|
223 |
|
224 ASocket* CInternalSocketImpl::GetAcceptingSocket() |
|
225 { |
|
226 RInternalSocket* blankSocket = reinterpret_cast < RInternalSocket* > ( GetUserMessage(ESocketConnectMessage)->ReadInt(1) ); |
|
227 return blankSocket->Implementation (); |
|
228 } |
|
229 |
|
230 void CInternalSocketImpl::SetReturn(TInt aReturnValue) const |
|
231 { |
|
232 iReturn = aReturnValue; |
|
233 } |
|
234 |
|
235 void CInternalSocketImpl::GetOwnerInfo(TProcessId& aProcId, TSoOwnerInfo& aInfo, TThreadId& aThreadId) |
|
236 { |
|
237 const RThread& thread = iFlowRequest.PeerThread (); |
|
238 aThreadId = thread.Id (); |
|
239 RProcess process; |
|
240 thread.Process ( process ); |
|
241 aProcId = process.Id (); |
|
242 aInfo.iUid = process.Type (); |
|
243 } |
|
244 |
|
245 TInt CInternalSocketImpl::SecurityCheck() |
|
246 { |
|
247 return iSSP->SecurityCheck(this); |
|
248 } |
|
249 |
|
250 void CInternalSocketImpl::SetCurrentMessage ( TEIntSockOpMsgWrapper& aIntSockMsg ) |
|
251 { |
|
252 (static_cast<CIntSocketMessage*>(iCurrentMsg))->SetMessage(aIntSockMsg); |
|
253 } |
|
254 |
|
255 void CInternalSocketImpl::AdoptFlowRequest ( TRequestWrapper& aRequest ) |
|
256 { |
|
257 iFlowRequest = aRequest; |
|
258 } |
|
259 |
|
260 void CInternalSocketImpl::CompleteFlowRequestMessage(TInt aErr ) |
|
261 { |
|
262 // We are erroring. So we have to set the RInternalSocket iImplementation pointer |
|
263 // as NULL. Otherwise it will hold the pointer even after the deletion. |
|
264 if ( aErr != KErrNone && !IsClosing() ) |
|
265 *iImpl = NULL; |
|
266 iFlowRequest.RequestComplete ( aErr ); |
|
267 } |
|
268 |
|
269 |
|
270 void CInternalSocketImpl::InitiateDestruction() |
|
271 { |
|
272 LOG(Log::Printf(_L("CInternalSocketImpl[%x]: InitiateDestruction() called..."), this)); |
|
273 ASocket::InitiateDestruction(); |
|
274 |
|
275 if (!FlowRequestPending()) |
|
276 { |
|
277 delete this; |
|
278 } |
|
279 } |
|
280 |
|
281 void CInternalSocketImpl::InitUserMessageL ( TSocketMessage aMessage ) |
|
282 { |
|
283 CIntSocketMessage* msg = new (ELeave)CIntSocketMessage; |
|
284 SetUserMessage ( aMessage, msg ); |
|
285 } |
|
286 |
|
287 |
|
288 void CInternalSocketImpl::PanicSocketClient(TESockPanic aPanic) |
|
289 { |
|
290 InternalSocketPanic( aPanic ); |
|
291 } |
|
292 |
|
293 void CInternalSocketImpl::SendL ( TSockMess aWriteFunction, TEIntSockOpMsgWrapper& aMsg ) |
|
294 { |
|
295 TInt xferLenIdx = ASocket::KNoXferLen; |
|
296 TInt addrIdx = ASocket::KNoAddrArg; |
|
297 TInt sendFlags = 0; |
|
298 switch(aWriteFunction) |
|
299 { |
|
300 case ESoSendTo: |
|
301 addrIdx = MSG_PRM(1); |
|
302 // fall-through |
|
303 case ESoSend: |
|
304 { |
|
305 xferLenIdx = 0; |
|
306 TSockXfrLength xferLen; |
|
307 User::LeaveIfError(aMsg.ReadDes(MSG_PRM(0), xferLen, 0)); |
|
308 sendFlags = xferLen(); |
|
309 } |
|
310 break; |
|
311 case ESoSendToNoLength: |
|
312 addrIdx = MSG_PRM(1); |
|
313 // fall-through |
|
314 case ESoSendNoLength: |
|
315 sendFlags = aMsg.ReadInt(0); |
|
316 break; |
|
317 case ESoWrite: |
|
318 addrIdx = ASocket::KWriteNoAddrArg; |
|
319 break; |
|
320 default: |
|
321 ASSERT(0); |
|
322 } |
|
323 TBool sendMBuf = aMsg.ReadInt( 3 ); |
|
324 TInt sendByteCount = ( sendMBuf ? aMsg.GetMBufChainLength( 2 ) : aMsg.GetDesLength ( 2 ) ); |
|
325 ASocket::SendL( xferLenIdx, addrIdx, sendByteCount, sendFlags, sendMBuf ); |
|
326 } |
|
327 |
|
328 void CInternalSocketImpl::RecvL ( TSockMess aReadFunction, TEIntSockOpMsgWrapper& aMsg ) |
|
329 { |
|
330 TInt xferLenIdx = ASocket::KNoXferLen; |
|
331 TInt addrIdx = ASocket::KNoAddrArg; |
|
332 TInt recvFlags = 0; |
|
333 TBool recvMBuf = aMsg.ReadInt( 3 ); |
|
334 TBool recvOneOrMore = (aReadFunction == ESoRecvOneOrMore) || (aReadFunction == ESoRecvOneOrMoreNoLength) || (IsStream() && recvMBuf); |
|
335 |
|
336 switch(aReadFunction) |
|
337 { |
|
338 case ESoRecvFrom: |
|
339 addrIdx = MSG_PRM(1); |
|
340 // fall-through |
|
341 case ESoRecv: |
|
342 case ESoRecvOneOrMore: |
|
343 { |
|
344 xferLenIdx = 0; |
|
345 TSockXfrLength xferLen; |
|
346 User::LeaveIfError(aMsg.ReadDes(MSG_PRM(0), xferLen, 0)); |
|
347 recvFlags = xferLen(); |
|
348 break; |
|
349 } |
|
350 case ESoRecvFromNoLength: |
|
351 addrIdx = MSG_PRM(1); |
|
352 // fall-through |
|
353 case ESoRecvNoLength: |
|
354 case ESoRecvOneOrMoreNoLength: |
|
355 recvFlags = aMsg.ReadInt(0); |
|
356 break; |
|
357 case ESoRead: |
|
358 break; |
|
359 default: |
|
360 ASSERT(0); |
|
361 } |
|
362 TInt readByteCount = ( recvMBuf ? KSocketDefaultBufferSize : aMsg.GetDesMaxLength ( 2 ) ); |
|
363 ASocket::RecvL(xferLenIdx, addrIdx, readByteCount, recvFlags, recvMBuf, recvOneOrMore ); |
|
364 } |
|
365 |
|
366 void CInternalSocketImpl::CancelOpen () |
|
367 { |
|
368 if ( FlowRequestPending() ) |
|
369 { |
|
370 SetClosing (); |
|
371 } |
|
372 } |
|
373 |
|
374 void CInternalSocketImpl::SetImpl ( CInternalSocketImpl*& aImpl ) |
|
375 { |
|
376 iImpl = &aImpl; |
|
377 } |
|
378 |
|
379 TDes8* CInternalSocketImpl::BorrowTemporaryBuffer(TInt aSize) |
|
380 { |
|
381 return static_cast<CPlayer*>(iOwnerThread->Player())->BorrowTemporaryBuffer(aSize); |
|
382 } |
|
383 |
|
384 TDes8* CInternalSocketImpl::BorrowTemporaryBufferL(TInt aSize) |
|
385 { |
|
386 return static_cast<TDes8*>(User::LeaveIfNull(static_cast<CPlayer*>(iOwnerThread->Player())->BorrowTemporaryBuffer(aSize))); |
|
387 } |
|
388 |
|
389 // |
|
390 // CInternalSockSubSession |
|
391 // |
|
392 |
|
393 CInternalSockSubSession::TGlobals::TGlobals() |
|
394 : iSubSessions(CInternalSockSubSession::LinkOffset()) |
|
395 { |
|
396 } |
|
397 |
|
398 CInternalSockSubSession::TParameters::TParameters(TWorkerId aClientWorkerId, MCommsTransportSender* aSender, TTransportUserStorage& aStorage, const TNodeId& aServerCookie, TRequestWrapper* aRequest) |
|
399 : iStorage(aStorage), |
|
400 iClientWorkerId(aClientWorkerId), |
|
401 iServerCookie(aServerCookie), |
|
402 iSender(aSender), |
|
403 iRequest(aRequest) |
|
404 { |
|
405 } |
|
406 |
|
407 CInternalSockSubSession::CInternalSockSubSession(const TParameters& aParams) |
|
408 : iAccessCount(1), |
|
409 iServerCookie(aParams.iServerCookie), |
|
410 iSender(aParams.iSender) |
|
411 { |
|
412 } |
|
413 |
|
414 void CInternalSockSubSession::ConstructL(const TParameters& aParams) |
|
415 { |
|
416 if(aParams.iStorage.Ptr() == NULL) |
|
417 { |
|
418 aParams.iStorage.RefPtr() = new(ELeave) TGlobals; |
|
419 } |
|
420 AddSubsession(aParams.iStorage, this); |
|
421 iOwnerThread = SockManGlobals::Get()->SelfWorker(); // using globals is ugly, but reduced coupling |
|
422 } |
|
423 |
|
424 CInternalSockSubSession::TSubSessions& CInternalSockSubSession::SubSessions(TTransportUserStorage& aStorage) |
|
425 { |
|
426 TGlobals* globals = Globals(aStorage); |
|
427 __ASSERT_DEBUG(globals, User::Panic(KSpecAssert_ESockEIntSocksnt, 2)); |
|
428 return globals->iSubSessions; |
|
429 } |
|
430 |
|
431 void CInternalSockSubSession::AddSubsession(TTransportUserStorage& aStorage, CInternalSockSubSession* aSubSession) |
|
432 { |
|
433 __ASSERT_DEBUG(aSubSession, User::Panic(KSpecAssert_ESockEIntSocksnt, 3)); |
|
434 SubSessions(aStorage).AddFirst(*aSubSession); |
|
435 } |
|
436 |
|
437 TInt CInternalSockSubSession::PerformOperationL(const TEIntSockMsg& aMsg, TRequestWrapper& aRequest) |
|
438 { |
|
439 CInternalSocketImpl* sock = aMsg.ImplPtr (); |
|
440 __ASSERT_DEBUG (sock, User::Invariant()); |
|
441 |
|
442 TInt ret = KRequestPending; |
|
443 sock->CompleteCurrentRequest (ETrue); // Mark the current request as completed |
|
444 TEIntSockOpMsgWrapper opMsg = aMsg.OpMsg (); |
|
445 opMsg.SetRequest ( aRequest ); // Set the current request status |
|
446 sock->SetCurrentMessage ( opMsg ); // Make it as the current request |
|
447 sock->SetReturn(KErrNone); |
|
448 |
|
449 switch(aMsg.Operation()) |
|
450 { |
|
451 case ESoClose: |
|
452 { |
|
453 if ( sock->CloseSocket () ) // Immediate close. so we have to signal it. |
|
454 { |
|
455 // Need to return now to skip over code that calls into socket at |
|
456 // end of function - the socket has been deleted so we must not do |
|
457 // this. |
|
458 return KErrNone; |
|
459 } |
|
460 // Protocol expects a graceful close |
|
461 break; |
|
462 } |
|
463 case ESoCancelAll: |
|
464 { |
|
465 sock->CancelAll (); |
|
466 break; |
|
467 } |
|
468 case ESoSendNoLength: |
|
469 case ESoSend: |
|
470 case ESoWrite: |
|
471 case ESoSendTo: |
|
472 case ESoSendToNoLength: |
|
473 { |
|
474 sock->SendL ( aMsg.Operation(), opMsg ); |
|
475 break; |
|
476 } |
|
477 |
|
478 case ESoCancelSend: |
|
479 { |
|
480 sock->CancelSend(); |
|
481 break; |
|
482 } |
|
483 case ESoRecvNoLength: |
|
484 case ESoRecv: |
|
485 case ESoRead: |
|
486 case ESoRecvFrom: |
|
487 case ESoRecvFromNoLength: |
|
488 case ESoRecvOneOrMore: |
|
489 { |
|
490 sock->RecvL ( aMsg.Operation(), opMsg ); |
|
491 break; |
|
492 } |
|
493 case ESoCancelRecv: |
|
494 { |
|
495 sock->CancelRecv(); |
|
496 break; |
|
497 } |
|
498 case ESoConnect: |
|
499 { |
|
500 sock->ConnectL (opMsg.ReadInt ( 1 ) != NULL); |
|
501 break; |
|
502 } |
|
503 case ESoCancelConnect: |
|
504 { |
|
505 sock->CancelConnect(); |
|
506 break; |
|
507 } |
|
508 |
|
509 case ESoBind: |
|
510 { |
|
511 sock->BindL (); |
|
512 break; |
|
513 } |
|
514 |
|
515 case ESoListen: |
|
516 { |
|
517 TInt qlen = opMsg.ReadInt ( 0 ) > 0 ? opMsg.ReadInt ( 0 ) : 1; |
|
518 sock->ListenL (qlen, opMsg.ReadInt ( 1 ) != NULL ); |
|
519 break; |
|
520 } |
|
521 case ESoAccept: |
|
522 { |
|
523 sock->Accept (); |
|
524 break; |
|
525 } |
|
526 case ESoCancelAccept: |
|
527 { |
|
528 sock->CancelAccept(); |
|
529 break; |
|
530 } |
|
531 |
|
532 case ESoSetOpt: |
|
533 { |
|
534 sock->SetSockOptionL (opMsg.ReadInt(0), opMsg.GetDesLength(1), opMsg.ReadInt(2)); |
|
535 break; |
|
536 } |
|
537 |
|
538 case ESoGetOpt: |
|
539 { |
|
540 TInt optionLength = opMsg.GetDesMaxLength ( 1 ); |
|
541 sock->GetSockOptionL(opMsg.ReadInt (0), optionLength, opMsg.ReadInt (2), optionLength != 0 ); |
|
542 break; |
|
543 } |
|
544 case ESoIoctl: |
|
545 { |
|
546 TInt optionLength = ( opMsg.ReadInt (1) != NULL ) ? opMsg.GetDesMaxLength ( 1 ) : 0; |
|
547 sock->IoctlL(opMsg.ReadInt (0), optionLength, opMsg.ReadInt (2), (opMsg.ReadInt (1) != NULL)); |
|
548 break; |
|
549 } |
|
550 case ESoCancelIoctl: |
|
551 { |
|
552 sock->CancelIoctl(); |
|
553 break; |
|
554 } |
|
555 case ESoGetDiscData: |
|
556 { |
|
557 sock->GetDisconnectDataL (); |
|
558 break; |
|
559 } |
|
560 case ESoGetLocalName: |
|
561 { |
|
562 sock->LocalNameL(); |
|
563 break; |
|
564 } |
|
565 case ESoGetRemoteName: |
|
566 { |
|
567 sock->RemoteNameL(); |
|
568 break; |
|
569 } |
|
570 |
|
571 case ESoShutdown: |
|
572 { |
|
573 sock->ShutdownL(RSocket::TShutdown(opMsg.ReadInt(0)), (opMsg.ReadInt(1) != NULL)); |
|
574 break; |
|
575 } |
|
576 case ESoSocketInfo: |
|
577 { |
|
578 sock->GetInfoL (); |
|
579 break; |
|
580 } |
|
581 default: |
|
582 __ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockEIntSocksnt, 4)); |
|
583 } |
|
584 |
|
585 if ( ret == KRequestPending && sock->ShouldCompleteCurrentRequest() ) |
|
586 ret = sock->Return (); |
|
587 return ret; |
|
588 } |
|
589 |
|
590 void CInternalSockSubSession::ProcessMessageL(const TWorkerTransportMsg& aMsg, TRequestWrapper& aRequest, TTransportUserStorage& aStorage, TWorkerId aPeerWorkerId) |
|
591 { |
|
592 const TEIntSockMsgExt& eisMsgExt = static_cast<const TEIntSockMsgExt&>(aMsg); |
|
593 LOG(Log::Printf(_L("CISSS::ProcessMessage() msgId=%d, status=%08x, storage=%x, peerId=%d"), eisMsgExt.Operation(), eisMsgExt.GetStatusPtr(), aStorage.Ptr(), aPeerWorkerId)); |
|
594 |
|
595 CInternalSocketImpl* sock = NULL; |
|
596 TInt ret = KRequestPending; |
|
597 |
|
598 switch (eisMsgExt.Operation()) |
|
599 { |
|
600 case KSoOpenByName: |
|
601 { |
|
602 TWorkerId selfWorkerId; |
|
603 VERIFY_RESULT(CWorkerThread::CurrentWorkerId(selfWorkerId), KErrNone); |
|
604 CInternalSockSubSession::TParameters params (aPeerWorkerId, eisMsgExt.Sender(), aStorage, eisMsgExt.ImplCookie(), &aRequest); |
|
605 eisMsgExt.ImplPtrRef() = sock = ProtocolManager::NewInternalSocketL(¶ms, eisMsgExt.OpMsg().GetDesc(0)); // Name is on 0th index |
|
606 sock->SetImpl (eisMsgExt.ImplPtrRef()); |
|
607 break; |
|
608 } |
|
609 case ESoCreate: |
|
610 { |
|
611 TWorkerId selfWorkerId; |
|
612 VERIFY_RESULT(CWorkerThread::CurrentWorkerId(selfWorkerId), KErrNone); |
|
613 CInternalSockSubSession::TParameters params (aPeerWorkerId, eisMsgExt.Sender(), aStorage, eisMsgExt.ImplCookie(), &aRequest); |
|
614 eisMsgExt.ImplPtrRef() = sock = ProtocolManager::NewInternalSocketL(¶ms, eisMsgExt.OpMsg().ReadInt(0), eisMsgExt.OpMsg().ReadInt(1), eisMsgExt.OpMsg().ReadInt(2)); |
|
615 sock->SetImpl (eisMsgExt.ImplPtrRef()); |
|
616 break; |
|
617 } |
|
618 case ESoCreateNull: |
|
619 { |
|
620 TWorkerId selfWorkerId; |
|
621 VERIFY_RESULT(CWorkerThread::CurrentWorkerId(selfWorkerId), KErrNone); |
|
622 eisMsgExt.ImplPtrRef() = CInternalSocketImpl::NewL(CInternalSockSubSession::TParameters(aPeerWorkerId, eisMsgExt.Sender(), aStorage, eisMsgExt.ImplCookie(), NULL)); |
|
623 ret = KErrNone; |
|
624 break; |
|
625 } |
|
626 default: |
|
627 ret = CInternalSockSubSession::PerformOperationL (eisMsgExt, aRequest); |
|
628 break; |
|
629 } |
|
630 |
|
631 if(ret != KRequestPending) |
|
632 { |
|
633 aRequest.RequestComplete(ret); |
|
634 } |
|
635 } |
|
636 |
|
637 EXPORT_C void CInternalSockSubSession::ProcessMessage(const TWorkerTransportMsg& aMsg, TRequestWrapper& aRequest, TTransportUserStorage& aStorage, TWorkerId aPeerWorkerId) |
|
638 { |
|
639 __ASSERT_DEBUG(aMsg.Code() == KEIntSockTransportPluginImplementationUid, User::Panic(KSpecAssert_ESockEIntSocksnt, 5)); |
|
640 TInt ret = KErrNone; |
|
641 |
|
642 TRAP ( ret, CInternalSockSubSession::ProcessMessageL ( aMsg, aRequest, aStorage, aPeerWorkerId ) ); |
|
643 if(ret != KErrNone) |
|
644 { |
|
645 aRequest.RequestComplete(ret); |
|
646 } |
|
647 |
|
648 } |
|
649 |
|
650 EXPORT_C void CInternalSockSubSession::OnPeerDeath(TWorkerId aPeer, TTransportUserStorage& aStorage) |
|
651 { |
|
652 // Close any subsessions belonging to the dead peer, ie mimic their missing closes |
|
653 TDblQueIter<CInternalSockSubSession> iter(SubSessions(aStorage)); |
|
654 CInternalSockSubSession* subSess; |
|
655 while((subSess = iter++) != NULL) |
|
656 { |
|
657 if(subSess->ClientWorkerId() == aPeer) |
|
658 { |
|
659 delete subSess; |
|
660 } |
|
661 } |
|
662 } |
|
663 |
|
664 EXPORT_C void CInternalSockSubSession::Shutdown(TBool aAlreadyDead, TTransportUserStorage& aStorage) |
|
665 { |
|
666 // Complete all blocked messages |
|
667 TDblQueIter<CInternalSockSubSession> iter(SubSessions(aStorage)); |
|
668 CInternalSockSubSession* subSess; |
|
669 while((subSess = iter++) != NULL) |
|
670 { |
|
671 subSess->FinalCompleteAllBlockedMessages(KErrServerTerminated); |
|
672 if(!aAlreadyDead) |
|
673 { |
|
674 delete subSess; |
|
675 } |
|
676 } |
|
677 if(!aAlreadyDead) |
|
678 { |
|
679 TGlobals* globals = Globals(aStorage); |
|
680 delete globals; |
|
681 } |
|
682 } |
|
683 |
|
684 TInt CInternalSockSubSession::SendReceiveMsg(TWorkerTransportMsg& aMsg, MCommsTransportSender* aSender, const TNodeId& aServerCookie) |
|
685 { |
|
686 TRequestStatus status(KRequestPending); |
|
687 aMsg.SetStatusPtr(&status); |
|
688 TCFLegacyMessagePacker::PackForPostage(aServerCookie.Thread(), aMsg); |
|
689 aSender->SendMessageSync(aMsg); |
|
690 User::WaitForRequest(status); |
|
691 return status.Int(); |
|
692 } |
|
693 |
|
694 void CInternalSockSubSession::SendMsg(TWorkerTransportMsg& aMsg, MCommsTransportSender* aSender, const TNodeId& aServerCookie) |
|
695 { |
|
696 TCFLegacyMessagePacker::PackForPostage(aServerCookie.Thread(), aMsg); |
|
697 aSender->SendMessageSync(aMsg); |
|
698 } |
|
699 |
|
700 TInt CInternalSockSubSession::SendReceiveMsgAsync( TWorkerTransportMsg& aMsg, MCommsTransportSender* aSender, const TNodeId& aServerCookie ) |
|
701 { |
|
702 CAsyncWaiter* waiter = CAsyncWaiter::New (); |
|
703 if ( !waiter ) |
|
704 return KErrNoMemory; |
|
705 waiter->iStatus = KRequestPending; |
|
706 aMsg.SetStatusPtr(&(waiter->iStatus)); |
|
707 TCFLegacyMessagePacker::PackForPostage(aServerCookie.Thread(), aMsg); |
|
708 aSender->SendMessageSync(aMsg); |
|
709 TInt err = waiter->StartAndWait(); |
|
710 delete waiter; |
|
711 return err; |
|
712 } |
|
713 // ------------------------ |
|
714 |
|
715 CAsyncWaiter* CAsyncWaiter::New () |
|
716 { |
|
717 CAsyncWaiter* self = new CAsyncWaiter; |
|
718 return self; |
|
719 } |
|
720 |
|
721 CAsyncWaiter::~CAsyncWaiter () |
|
722 { |
|
723 Cancel(); |
|
724 } |
|
725 |
|
726 TInt CAsyncWaiter::StartAndWait () |
|
727 { |
|
728 SetActive (); |
|
729 CActiveScheduler::Start (); |
|
730 return iStatus.Int(); |
|
731 } |
|
732 |
|
733 CAsyncWaiter::CAsyncWaiter () |
|
734 : CActive ( EPriorityStandard ) |
|
735 { |
|
736 CActiveScheduler::Add(this); |
|
737 } |
|
738 |
|
739 void CAsyncWaiter::RunL () |
|
740 { |
|
741 CActiveScheduler::Stop (); |
|
742 } |
|
743 |
|
744 void CAsyncWaiter::DoCancel () |
|
745 { |
|
746 CActiveScheduler::Stop (); |
|
747 } |
|
748 |
|
749 // ------------------------------ |
|
750 |
|
751 void CIntSocketMessage::AcquireMessage ( AMessage* aMessage ) |
|
752 { |
|
753 CIntSocketMessage* msg = (static_cast<CIntSocketMessage*>(this)); |
|
754 CIntSocketMessage* msg2 = (static_cast<CIntSocketMessage*>(aMessage)); |
|
755 msg->SetMessage(msg2->Message()); |
|
756 } |
|
757 |
|
758 TInt CIntSocketMessage::ReadDes(TInt aSrcParamIndex,TDes8 &aDes,TInt aOffset) |
|
759 { |
|
760 return iMessage.ReadDes(aSrcParamIndex, aDes, aOffset); |
|
761 } |
|
762 |
|
763 TInt CIntSocketMessage::ReadInt(TInt aSrcParamIndex) |
|
764 { |
|
765 return iMessage.ReadInt(aSrcParamIndex); |
|
766 } |
|
767 |
|
768 TInt CIntSocketMessage::ReadMBuf(TInt aSrcParamIndex, RMBufChain& aBufChain) |
|
769 { |
|
770 return iMessage.ReadBufChain(aSrcParamIndex, aBufChain); |
|
771 } |
|
772 |
|
773 void CIntSocketMessage::InitMBuf(TInt aParamIndex) |
|
774 { |
|
775 iMessage.InitBufChain ( aParamIndex ); |
|
776 } |
|
777 |
|
778 TInt CIntSocketMessage::WriteDes(TInt aDstParamIndex,const TDesC8& aDes,TInt anOffset) |
|
779 { |
|
780 return iMessage.WriteDesc ( aDstParamIndex, aDes, anOffset ); |
|
781 } |
|
782 |
|
783 TInt CIntSocketMessage::WriteMBuf(TInt aDstParamIndex,RMBufChain& aBufChain) |
|
784 { |
|
785 return iMessage.WriteBufChain(aDstParamIndex, aBufChain); |
|
786 } |
|
787 |
|
788 void CIntSocketMessage::CompleteMessage(TInt anError) |
|
789 { |
|
790 iMessage.CompleteMessage(anError); |
|
791 } |
|
792 |
|
793 TBool CIntSocketMessage::IsNull (TInt aParamIndex) |
|
794 { |
|
795 return (iMessage.ReadInt(aParamIndex) == NULL); |
|
796 } |
|
797 |
|
798 |
|
799 |
|
800 |
|
801 |