datacommsserver/esockserver/eintsock/ss_eintsockimpl.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // 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(&params, 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(&params, 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