--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/inc/ss_intsock.h Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,618 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#if !defined(__SS_INTSOCK_H__)
+#define __SS_INTSOCK_H__
+
+#define SYMBIAN_NETWORKING_UPS
+
+#include <es_enum.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <es_enum_internal.h>
+#endif
+
+#include <e32base.h>
+#include <comms-infras/ss_flowbinders.h>
+#include <comms-infras/ss_nodeinterfaces.h>
+#include <comms-infras/ss_nodemessages_dataclient.h>
+#include "ss_flowrequest.h"
+#include <es_mbufif.h>
+
+#ifdef SYMBIAN_NETWORKING_UPS
+#include <comms-infras/ss_platsec_apiext.h> // ASockSubSessionPlatsecApiExt
+#endif //SYMBIAN_NETWORKING_UPS
+
+class CWaitForMBufs;
+class CProtocolBase;
+class ProtocolManager;
+class CInternalSocketImpl;
+
+namespace ESock
+{
+
+class AMessage
+{
+public:
+ virtual void AcquireMessage ( AMessage* aMessage ) =0;
+
+ virtual TInt ReadDes(TInt aSrcParamIndex,TDes8 &aDes,TInt anOffset=0) = 0;
+ virtual TInt ReadInt(TInt aSrcParamIndex) = 0;
+ virtual TInt ReadMBuf(TInt aSrcParamIndex, RMBufChain& aBufChain) =0;
+ virtual void InitMBuf(TInt aParamIndex) =0;
+ virtual TInt WriteDes(TInt aDstParamIndex,const TDesC8& aDes,TInt anOffset=0) = 0;
+ virtual TInt WriteMBuf(TInt aDstParamIndex,RMBufChain& aBufChain) = 0;
+
+ virtual void CompleteMessage(TInt anError) = 0;
+ virtual TBool IsNull (TInt aParamIndex) =0;
+
+#ifdef SYMBIAN_NETWORKING_UPS
+ virtual TInt GetProcessAndThreadId(TProcessId& /*aProcessId*/, TThreadId& /*aThreadId*/) const;
+#endif
+
+ virtual ~AMessage() {}
+};
+
+NONSHARABLE_CLASS(ASocket) : public Messages::ASimpleNodeIdBase,
+ public MSessionControlNotify, public MSessionDataNotify,
+ public AIPCFlowRequester
+#ifdef SYMBIAN_NETWORKING_UPS
+ , private ASockSubSessionPlatsecApiExt
+#endif
+/**
+Represents binder-facing part of socket.
+Implements ESOCK client socket binder and flow specific handling.
+It's meant to be agregated with the apropriet client-facing part to implement
+full socket functionality
+@see CSocket
+@internalTechnology
+*/
+ {
+ friend class ::ProtocolManager;
+
+protected:
+ enum TSocketState
+ {
+ ESStateNull=-1,
+ ESStateCreated=0,
+ ESStateOpeningActive,
+ ESStateOpeningPassive,
+ ESStateOpen,
+ ESStateConnected,
+ ESStateDisconnected,
+ ESStateClosing,
+ ESStateShuttingDown,
+ ESStateDead,
+ ESStateError,
+ ESStateAccepting,
+ ESStateBinding
+ };
+
+protected:
+ //Messages::ANode
+ virtual void ReceivedL(
+ const Messages::TRuntimeCtxId& aSender,
+ const Messages::TNodeId& aRecipient,
+ Messages::TSignatureBase& aMessage
+ );
+ //messages
+ void BindToL(const TCFDataClient::TBindTo& aBindTo);
+
+public:
+ virtual ~ASocket();
+
+ virtual const Messages::RNodeInterface* ServiceProvider() const;
+ TBool GetFlowAndSCPR(Messages::TNodeId& aFlow, Messages::TNodeId& aSCPR) const;
+
+ TInt GetConnectionSocketInfo(TConnectionSocketInfo& aInfo) const;
+
+ // Request service routines.
+ void ConnectL(TBool aConnectData);
+ void ShutdownL(RSocket::TShutdown aType, TBool aDisconnectData);
+ virtual TBool CloseSocket();
+ void ListenL(TInt aQlen, TBool aConnectionData);
+ void Accept();
+
+ void AutoBind();
+ void BindL();
+ void RemoteNameL();
+ void LocalNameL();
+ void SetLocalName();
+
+ void SetSockOptionL(TInt aOptionName, TInt aOptionLength, TInt aOptionLevel);
+ void GetSockOptionL(TInt aOptionName, TInt aOptionLength, TInt aOptionLevel, TInt aWriteBack);
+ void IoctlL(TInt aOptionName, TInt aOptionLength, TInt aOptionLevel, TBool aReadOption);
+ void GetDisconnectDataL( ) const;
+//
+ void SendL(TInt aXferLenArg, TInt aAddrArg, TInt aSendByteCount, TInt aSendFlags, TBool aUseMBufs);
+ void RecvL(TInt aXferLenArg, TInt aAddrArg, TInt aReadByteCount, TInt aReadFlags, TBool aUseMBufs, TInt aRecvOneOrMore);
+//
+ inline void CancelSend();
+ inline void CancelRecv();
+ void CancelConnect();
+ void CancelAccept();
+ void CancelIoctl();
+ void CancelAll();
+
+ void GetInfoL();
+
+ void CommunicateOwner();
+
+ TPtr8 IoctlBuffer();
+
+ // SSP Upcalls - from MSessionControlNotify
+ void NewData(TUint aCount);
+ void CanSend();
+ void ConnectComplete();
+ void ConnectComplete(const TDesC8& aConnectData);
+ void ConnectComplete(CSubConnectionFlowBase& anSSP);
+ void ConnectComplete(CSubConnectionFlowBase& anSSP,const TDesC8& aConnectData);
+ void CanClose(MSessionControlNotify::TDelete aDelete=MSessionControlNotify::EDelete);
+ void CanClose(const TDesC8& aDisconnectData,MSessionControlNotify::TDelete aDelete=MSessionControlNotify::EDelete);
+ TInt Error(TInt anError,TUint anOperationMask);
+ void Disconnect( );
+ void Disconnect(TDesC8& aDisconnectData);
+ void IoctlComplete(TDesC8* aBuf);
+ void SetLocalNameComplete();
+ void DisconnectFromListener(CSubConnectionFlowBase& aSSP);
+
+ // Utitlity functions for testing state and capabilities
+ inline TUint IsConnectionOriented() const;
+ inline TUint IsConnectionLess()const;
+ inline TUint IsDataGram() const;
+ inline TUint IsStream() const;
+ inline TUint IsPseudoStream() const;
+ inline TUint IsReliable() const;
+ inline TUint DeliversInOrder() const;
+ inline TUint IsMessageBased() const;
+ inline TUint CanSendUrgentData() const;
+ inline TUint CanSendConnectData() const;
+ inline TUint CanSendDisconnectData() const;
+ inline TUint CanBroadcast() const;
+ inline TUint SupportsMultiPoint() const;
+ inline TUint SupportsQOS() const;
+ inline TUint IsWriteOnly() const;
+ inline TUint IsReadOnly() const;
+ inline TUint SupportsGracefulClose() const;
+ inline TUint CanReconnect() const;
+ inline TUint SupportsPeek() const;
+ inline TUint RequiresOwnerInfo() const;
+ inline TUint StateCanProcessData() const;
+
+ virtual void InitiateDestruction();
+ inline void SetFlowRequestPending(TBool aPending);
+
+ enum
+ {
+ KNoXferLen = -1,
+ KNoAddrArg = -1,
+ KWriteNoAddrArg = -2 // for legacy compatibility reasons we tolerate ESoWrite on a non-connected datagram socket
+ };
+
+protected:
+ explicit ASocket(TInt aSocketType);
+ void Create(TServerProtocolDesc* aServiceInfo);
+
+ TBool CheckRunningAndSetReturn();
+ // Utility functions for handling blocked messages.
+ enum EBlockingFlags
+ {EBlockedClose=0x01,
+ EBlockedConnect=0x02,
+ EBlockedIoctl=0x04,
+ EBlockedRead=0x08,
+ EBlockedWrite=0x10,
+ EWriteFlowedOff=0x20,
+ EReadStopped=0x40,
+ EWriteStopped=0x80
+ , EBlockedSetLocalName=0x100
+ };
+
+ inline void SetBlockedReadFlag();
+ inline void SetBlockedWriteFlag();
+ inline void SetBlockedCloseFlag();
+ inline void SetBlockedIoctlFlag();
+ inline void SetBlockedConnectFlag();
+
+ inline void SetBlockedRead();
+ inline void SetBlockedWrite();
+ inline void SetBlockedClose();
+ inline void SetBlockedIoctl();
+ inline void SetBlockedConnect();
+ inline void SetBlockedSetLocalName();
+ inline TBool IsBlockedSetLocalName() const;
+ void CompleteSetLocalName(TInt anErr);
+
+ virtual void SetClosing() =0;
+
+ inline TBool IsBlockedRead() const;
+ inline TBool IsBlockedWrite() const;
+ inline TBool IsBlockedConnect() const;
+ inline TBool IsBlockedClose() const;
+ inline TBool IsBlockedIoctl() const;
+ virtual TBool IsClosing() =0;
+
+ TBool CompleteRead(TInt anError);
+ TBool CompleteWrite(TInt anError);
+ void CompleteConnect(TInt anErr);
+ TBool CompleteClose(TInt anErr);
+ void CompleteIoctl(TInt anErr);
+
+ virtual void DontCompleteCurrentRequest() = 0;
+ virtual ASocket* InitiateAcceptingSocket() = 0;
+ virtual ASocket* GetAcceptingSocket() = 0;
+ virtual void DoCompleteAccept();
+ void AcceptSetupL(const ASocket& aParentSocket, CSubConnectionFlowBase& aFlow);
+
+ virtual void PanicSocketClient(TESockPanic aPanic) =0;
+ virtual void SetReturn(TInt aReturnValue) const = 0;
+
+ inline TSocketState State() const;
+ inline void SetState(TSocketState aState);
+
+ virtual TDes8* BorrowTemporaryBuffer(TInt aSize) = 0;
+ virtual TDes8* BorrowTemporaryBufferL(TInt aSize) = 0;
+
+ TInt DrainStreamProtocol(AMessage* aMsg);
+ void DoRecv(TBool aInitialRequest);
+ TInt FillStreamProtocol(AMessage* aMsg);
+ void DoSend(TBool aInitialRequest);
+
+ TUint SelectConditionsReady();
+ TBool CheckReadStopped();
+ void TryToCompleteSelectIoctl();
+ void DoError(TInt aError, TUint aOperationMask, TBool aDeleteInterface = ETrue);
+ inline void ClearErrorIfNotFatal();
+
+ TInt RequestAsyncMBufAllocation(TInt aSignalType, TUint aSize);
+
+
+ enum TSocketMessage
+ {
+ ESocketCurrentMessage,
+ ESocketReadMessage,
+ ESocketWriteMessage,
+ ESocketCloseMessage,
+ ESocketIoCtlMessage,
+ ESocketConnectMessage
+ ,ESocketSetLocalNameMessage
+
+ };
+
+ void ReadParamL(TSocketMessage aMessage, TInt aSrcParamIndex,TDes8 &aDes,TInt anOffset=0);
+ void ReadParamL(TSocketMessage aMessage, TInt aSrcParamIndex, RMBufChain& aBufChain);
+ void WriteParamL(TSocketMessage aMessage, TInt aDstParamIndex,const TDesC8& aDes,TInt anOffset=0);
+ void WriteParamL(TSocketMessage aMessage, TInt aDstParamIndex, RMBufChain& aBufChain);
+
+
+ AMessage* GetUserMessage( TSocketMessage aMessage ) const;
+ void SetUserMessage ( TSocketMessage aMessageType, AMessage* aMessage );
+
+ virtual void GetOwnerInfo(TProcessId& aProcId, TSoOwnerInfo& aInfo, TThreadId& aThreadId) = 0;
+ virtual TInt SecurityCheck() = 0;
+
+ virtual void CompleteFlowRequestMessage(TInt err) =0;
+ inline TBool FlowRequestPending();
+
+#ifdef SYMBIAN_NETWORKING_UPS
+ TInt GetProcessAndThreadId(TProcessId& aProcessId, TThreadId& aThreadId) const;
+#endif
+
+protected:
+ MSessionControl* iSSP; // NULL-ness well controlled
+ AMessage* iCurrentMsg;
+ TSockXfrLength iXferLength; // used to write transfer lengths back to client; kept in scope with socket to avoid repeated construction cost
+private:
+ MSessionData* iSSPData;
+ MFlowBinderControl* iFlowBinder;
+ Messages::RNodeInterface iServiceProvider;
+
+ TProtocolDesc* iProtocolInfo;
+ TInt iSocketType;
+
+
+ TSocketState iState;
+ TInt iDataAvailable;
+ TInt iSendOffset;
+ TInt iRecOffset;
+ TInt iSendByteCount;
+ TInt iRecByteCount;
+ TInt iSendFlags;
+ TInt iRecvFlags;
+
+ TSockAddr iRecvFromAddr;
+//
+ TUint iBlockedOperations;
+
+ TInt iError;
+ TUint iErrorOperationMask; // stored aOperationMask from last MSessionControlNotify::Error() call
+
+
+ TUint iOptions;
+
+ enum { KMaxStreamChunk = 32 * 1024 };
+//
+ TInt iRecBufSize;
+ TInt iSendBufSize;
+ RMBufChain iSendData;
+ HBufC8* iDisconnectData;
+ TInt iDisconnectDataError;
+ RMBufChain iDatagramTail;
+//
+ CWaitForMBufs* iAllocAsync;
+//
+ CCirBuf<TAcceptQEntry>* iAcceptQ; //lint -esym(613, ASocket::iAcceptQ) // NULL-ness well controlled
+ CCirBuf<TAcceptQEntry>* iNextAcceptQ; //lint -esym(613, CSocket::iAcceptQ) // NULL-ness well controlled
+ TInt iSelectFlags;
+
+ TSecurityPolicy iTransferSecPolicy; // used for security check during ProtocolManager::TransferSocketL()
+
+ TBool iIsBound:1;
+ TBool iRecvOneOrMore:1;
+ TBool iSecTransferEnabled:1; // flag, indicating that iTransferSecPolicy is initialized and socket transfer is enabled
+ TBool iIsFlowRequestPending:1;
+ TBool iSendUseMBufs:1;
+ TBool iRecvUseMBufs:1;
+ TInt8 iSendXferLenIdx;
+ TInt8 iRecvXferLenIdx;
+ TInt8 iSendToAddrIdx;
+ TInt8 iRecvFromAddrIdx;
+ TInt8 iBlockOnPeekReadCnt; // recursion level counter for NewData().
+
+ AMessage* iReadMsg;
+ AMessage* iWriteMsg;
+ AMessage* iBlockedCloseMsg;
+ AMessage* iBlockedConnectMsg;
+ AMessage* iBlockedIoctlMsg;
+ AMessage* iBlockedSetLocalNameMsg;
+
+ TSocketState iNextState; // Next state to enter after binding state exits.
+ TBool iConnectData; // Used to indicate if connect data is present.
+
+
+ RMBufAllocator iAllocator; // To speed up the RMBufChain allocation
+ };
+
+inline TUint ASocket::IsConnectionOriented() const
+ {
+ return !(iProtocolInfo->iServiceInfo & KSIConnectionLess);
+ }
+
+inline TUint ASocket::IsConnectionLess() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIConnectionLess);
+ }
+
+inline TUint ASocket::IsDataGram() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIDatagram);
+ }
+
+inline TUint ASocket::IsStream() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIStreamBased);
+ }
+
+inline TUint ASocket::IsPseudoStream() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIPseudoStream);
+ }
+
+inline TUint ASocket::IsReliable() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIReliable);
+ }
+
+inline TUint ASocket::CanReconnect() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSICanReconnect);
+ }
+
+inline TUint ASocket::SupportsPeek() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIPeekData);
+ }
+
+inline TUint ASocket::DeliversInOrder() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIInOrder);
+ }
+
+inline TUint ASocket::IsMessageBased() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIMessageBased);
+ }
+
+inline TUint ASocket::CanSendUrgentData() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIUrgentData);
+ }
+
+inline TUint ASocket::CanSendConnectData() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIConnectData);
+ }
+
+inline TUint ASocket::CanSendDisconnectData() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIDisconnectData);
+ }
+
+inline TUint ASocket::CanBroadcast() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIBroadcast);
+ }
+
+inline TUint ASocket::SupportsMultiPoint() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIMultiPoint);
+ }
+
+inline TUint ASocket::SupportsQOS() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIQOS);
+ }
+
+inline TUint ASocket::IsWriteOnly() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIWriteOnly);
+ }
+
+inline TUint ASocket::IsReadOnly() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIReadOnly);
+ }
+
+inline TUint ASocket::SupportsGracefulClose() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIGracefulClose);
+ }
+
+inline TUint ASocket::RequiresOwnerInfo() const
+ {
+ return (iProtocolInfo->iServiceInfo & KSIRequiresOwnerInfo);
+ }
+
+inline void ASocket::SetBlockedReadFlag()
+ {
+ __ASSERT_DEBUG(!IsBlockedRead(),Fault(ETwoReads));
+ iBlockedOperations|=EBlockedRead;
+ }
+
+inline void ASocket::SetBlockedWriteFlag()
+ {
+ __ASSERT_DEBUG(!IsBlockedWrite(),Fault(ETwoWrites));
+ iBlockedOperations|=EBlockedWrite;
+ }
+
+inline void ASocket::SetBlockedConnectFlag()
+ {
+ __ASSERT_DEBUG(!IsBlockedConnect(),Fault(ETwoConnects));
+ iBlockedOperations|=EBlockedConnect;
+ }
+
+inline void ASocket::SetBlockedCloseFlag()
+ {
+ __ASSERT_DEBUG(!IsBlockedClose(),Fault(ETwoClose));
+ iBlockedOperations|=EBlockedClose;
+ }
+
+inline void ASocket::SetBlockedIoctlFlag()
+ {
+ __ASSERT_DEBUG(!IsBlockedIoctl(),Fault(ETwoIoctl));
+ iBlockedOperations|=EBlockedIoctl;
+ }
+
+inline void ASocket::SetBlockedSetLocalName()
+ {
+ iBlockedOperations |= EBlockedSetLocalName;
+ iBlockedSetLocalNameMsg->AcquireMessage( iCurrentMsg );
+ }
+
+ inline TBool ASocket::IsBlockedSetLocalName() const
+ {
+ return iBlockedOperations & EBlockedSetLocalName;
+ }
+
+
+inline void ASocket::SetBlockedRead()
+ {
+ SetBlockedReadFlag ();
+ }
+
+inline void ASocket::SetBlockedWrite()
+ {
+ SetBlockedWriteFlag ();
+ }
+
+inline void ASocket::SetBlockedClose()
+ {
+ SetBlockedCloseFlag ();
+ iBlockedCloseMsg->AcquireMessage(iCurrentMsg);
+ }
+
+inline void ASocket::SetBlockedIoctl()
+ {
+ SetBlockedIoctlFlag ();
+ iBlockedIoctlMsg->AcquireMessage(iCurrentMsg);
+ }
+
+inline void ASocket::SetBlockedConnect()
+ {
+ SetBlockedConnectFlag ();
+ iBlockedConnectMsg->AcquireMessage(iCurrentMsg);
+ }
+
+
+inline TBool ASocket::IsBlockedClose() const
+ {return iBlockedOperations&EBlockedClose;}
+
+inline TBool ASocket::IsBlockedConnect() const
+ {return iBlockedOperations&EBlockedConnect;}
+
+inline TBool ASocket::IsBlockedIoctl() const
+ {return iBlockedOperations&EBlockedIoctl;}
+
+inline TBool ASocket::IsBlockedRead() const
+ {return iBlockedOperations&EBlockedRead;}
+
+inline TBool ASocket::IsBlockedWrite() const
+ {return iBlockedOperations&EBlockedWrite;}
+
+void ASocket::CancelSend()
+ { CompleteWrite(KErrCancel); }
+
+void ASocket::CancelRecv()
+ { CompleteRead(KErrCancel); }
+
+inline void ASocket::ClearErrorIfNotFatal()
+ {
+ if (State() != ESStateError)
+ {
+ iError = KErrNone;
+ }
+ };
+
+
+inline ASocket::TSocketState ASocket::State() const
+ {
+ return iState;
+ }
+
+inline void ASocket::SetState(TSocketState aState)
+ {
+ iState = aState;
+ // If we've requested notification of available MBufs for a Recv or Send
+ // operation and now are entering some inappropriate state then we cancel this
+ if(iAllocAsync && iState != ESStateConnected && iState != ESStateOpen)
+ {
+ delete iAllocAsync;
+ iAllocAsync = NULL;
+ }
+ }
+
+inline void ASocket::SetFlowRequestPending(TBool aPending)
+ {
+ iIsFlowRequestPending = aPending;
+ }
+
+inline TBool ASocket::FlowRequestPending()
+ {
+ return iIsFlowRequestPending;
+ }
+
+} //namespace ESock
+
+#endif
+// __SS_INTSOCK_H__
+