--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linklayerprotocols/ethernetnif/IRLAN/INTSOCK.CPP Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,1055 @@
+// Copyright (c) 1997-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:
+// Internal Sockets API
+// Written by Mal, September 1997
+// Based on work by AdamG
+//
+//
+
+/**
+ @file
+*/
+
+#include <e32std.h>
+#include <e32base.h>
+#include <es_prot.h>
+#include <es_mbuf.h>
+#include <es_prot_internal.h>
+#include "INTSOCK.H"
+#include "IRLANUTL.H"
+#include "irlantimer.h"
+
+#ifdef __TRACEWIN__
+ #include <log.h>
+#else
+ #define LOG(a)
+#endif
+
+/**
+Constructor.
+*/
+CInternalSocket::CInternalSocket():iSendBufPtr(NULL,0)
+{
+ __DECLARE_NAME(_S("CInternalSocket"));
+ iState = ENew;
+}
+
+/**
+Only needed when cloning an accept from a listen socket.
+
+@param aSock A pointer to CServProviderBase object
+@param aNotify A pointer to MSocketNotify object.
+@return A pointer to CInternalSocket object.
+*/
+CInternalSocket *CInternalSocket::NewL(CServProviderBase *aSock,MSocketNotify *aNotify)
+{
+ CInternalSocket *is=new (ELeave) CInternalSocket;
+ // Need to set up send buffer for
+ is->iSendBufLength=KInternalMaxBufSize;
+ is->iSendBuffer=HBufC8::NewMaxL(is->iSendBufLength);
+ TPtr8 temp=is->iSendBuffer->Des();
+ is->iSendBufPtr.Set(temp);
+
+ is->SetNotify(aNotify);
+ is->iCServSocket=aSock;
+ is->iCServSocket->SetNotify(is);
+ is->iState = EOpen;
+ return is;
+}
+
+/**
+Destructor.
+*/
+CInternalSocket::~CInternalSocket()
+{
+#ifdef __TRACEWIN__
+ LOG(Log::Printf(_L("IRLAN: ~CInternalSocket %x\r\n"),this));
+#endif
+ delete iSendBuffer;
+ delete iTimers;
+ __ASSERT_DEBUG(iState==EClosing,IrlanUtil::Panic(EIrlanBadState));
+ delete iCServSocket; // underlying CServProviderBase
+ if (iProtocol)
+ iProtocol->Close();
+}
+
+/**
+Opens a socket of the required type and protocol.
+@param aProtocolName A Protocol Name.
+@param aNotify A pointer to MSocketNotify object.
+@return KErrNone if succesfull otherwise any error code.
+*/
+TInt CInternalSocket::OpenL(const TDesC& aProtocolName,MSocketNotify* aNotify)
+{
+ // Assert a new socket
+ if (iState!=ENew)
+ return KErrAlreadyExists;
+ TInt err = KErrNone;
+ // Ensure protocol is loaded
+ TRAP(err, iProtocol = SocketServExt::FindAndLoadProtocolL(aProtocolName));
+ if (err!=KErrNone)
+ return err;
+ iProtocol->Open();
+ // Cache some protocol information
+ TServerProtocolDesc info;
+ info.iName=aProtocolName;
+ iProtocol->Identify(&info);
+ if (!(info.iServiceTypeInfo & ESocketSupport))
+ {
+ iProtocol->Close();
+ iProtocol = NULL;
+ return KErrNotSupported;
+ }
+ if (info.iServiceTypeInfo & EUseCanSend)
+ iFlags |= KSoUseCanSend;
+ if (info.iServiceInfo & KSIConnectionLess)
+ iFlags |= KSoConnectionless;
+ if (info.iServiceInfo & KSIGracefulClose)
+ iFlags |= KSoGracefulClose;
+
+ // Create the SAP
+ TRAP(err, iCServSocket = iProtocol->NewSAPL(info.iSockType));
+ if (err!=KErrNone)
+ {
+ iProtocol->Close();
+ iProtocol = NULL;
+ return err;
+ }
+ // Need to set up send buffer for
+ iSendBufLength=KInternalMaxBufSize;
+ iSendBuffer=HBufC8::NewMaxL(iSendBufLength);
+ TPtr8 temp=iSendBuffer->Des();
+ iSendBufPtr.Set(temp);
+
+ // Set state to OPEN
+ iCServSocket->SetNotify(this);
+ this->SetNotify(aNotify);
+ iState = EOpen;
+ iCServSocket->Start();
+ return KErrNone;
+}
+
+/**
+Need to construct the TIrdaSockAddr with the appropriate port number.
+Note that this is a real simple connect - no notion of connect data or
+select or a blocking socket.
+@param aAddr A reference to TSockAddr class.
+@return KErrNone if succesfull otherwise any error code.
+*/
+TInt CInternalSocket::Connect(TSockAddr& aAddr)
+{
+ TInt ret=iCServSocket->SetRemName(aAddr);
+ if (ret!=KErrNone)
+ return ret;
+ iState=EConnecting;
+ iCServSocket->ActiveOpen();
+ return ret;
+}
+
+/**
+Does the work of listen and accept together.
+@param aQSize No of clients to be done passive open.
+@return KErrNone if succesfull.
+*/
+TInt CInternalSocket::WaitForConnect(TUint aQSize)
+{
+ iCServSocket->PassiveOpen(aQSize);
+ iState=EListening;
+ return KErrNone;
+}
+
+/**
+Gets the local address of a socket.
+@param aAddr Local address which is filled..
+*/
+void CInternalSocket::LocalName(TSockAddr& anAddr)const
+{
+ iCServSocket->LocalName(anAddr);
+}
+
+/**
+Gets the remote name (address) of the socket service provider entity. The format of the data
+in the TSockAddr object is defined by individual protocols.
+@param aAddr The address to be filled in.
+*/
+void CInternalSocket::RemName(TSockAddr& /*aAddr*/)const
+{
+}
+
+/**
+Sets the local name (address) of the socket service provider entity. The format of the data
+in the TSockAddr object is defined by individual protocols.
+@param aAddr The address .
+@return KErrNone if the local name is correctly set or, if this is not the case, an
+ informative error number.
+*/
+TInt CInternalSocket::SetLocalName(TSockAddr& aAddr)
+{
+ return iCServSocket->SetLocalName(aAddr);
+}
+
+/**
+Sets some protocol specific option when called by the socket server on behalf of a client. A
+protocol may pass the request down a protocol stack (to protocols it is bound to) using the
+SetOption() function of CProtocolBase.
+@param aLevel Option level
+@param aName Option Name
+@param aDes Option data.
+@return KErrNone if succesfull otherwise any error code.
+*/
+TInt CInternalSocket::SetOption(TUint aLevel,TUint aName,const TDesC8& aDes)
+{
+ return iCServSocket->SetOption(aLevel,aName,aDes);
+}
+
+/**
+Sets the remote name (address) of the socket service provider entity. The format of the data in the TSockAddr object is defined by individual protocols.
+@param The address
+@return Returns KErrNone if the remote name is correctly set or, if this is not the case, an informative error number.
+*/
+TInt CInternalSocket::SetRemName(TSockAddr &aAddr)
+{
+ return iCServSocket->SetRemName(aAddr);
+}
+
+/**
+Create a Socket.
+*/
+void CInternalSocket::Start(void)
+{
+ iCServSocket->Start();
+}
+
+/**
+Gets some protocol specific option when called by the socket server on behalf of a client.
+A protocol may pass the request down a protocol stack (to protocols it is bound to) using
+the GetOption() function of CInternalSocket.
+@param aLevel Option level
+@param aName Option Name
+@param anOption Option data.
+@return KErrNone if succesfull otherwise any error code.
+*/
+TInt CInternalSocket::GetOption(TUint aLevel,TUint aName,TDes8& anOption)const
+{
+ return iCServSocket->GetOption(aLevel,aName,anOption);
+}
+
+/**
+Performs some protocol specific IO control.
+@param aLevel IOCTL level
+@param aName IOCTL Name
+@param aDes IOCTL option
+*/
+void CInternalSocket::Ioctl(TUint aLevel,TUint aName,TDes8* aDes)
+{
+ iCServSocket->Ioctl(aLevel,aName,aDes);
+}
+
+/**
+Cancels an outstanding Ioctl call. You are guaranteed only to have one outstanding at once.
+@param aLevel IOCTL level
+@param aName IOCTL Name
+*/
+void CInternalSocket::CancelIoctl(TUint aLevel,TUint aName)
+{
+ iCServSocket->CancelIoctl(aLevel,aName);
+}
+
+/**
+Sends data onto the network via the protocol. Connection-oriented sockets must be in a connected
+state (that is ConnectComplete() has been called on their MSocketNotify) before Write() is
+called.
+@param aDes The data to be sent
+@param aFlag Protocol specific options
+@param aAddr Address to write the data to
+@return For stream-oriented protocols, the return value is the number of bytes actually written.
+ If this is less than the length of the descriptor, then the protocol should call CanSend()
+ when it is ready to send more data. For datagram-oriented protocols, the write should return
+ either 0 if the write cannot be completed, or the length of the descriptor if the write succeeds -
+ no other values are valid. If the Write() must return 0, then it should call CanSend() when
+ it is ready to send more data. If the Write() fails due to some error, then it should call
+ Error() with an informative error number,
+*/
+TUint CInternalSocket::Write(const TDesC8& aDes,TUint aFlag,TSockAddr *aAddr)
+{
+ return iCServSocket->Write(aDes,aFlag,aAddr);
+}
+
+/**
+Gets data which the protocol has indicated is waiting in its buffers using the NewData up-call
+on the MSocketNotify.
+@param The buffer for data
+@param Protocol specific options
+@param Where the data came from
+*/
+void CInternalSocket::GetData(TDes8 &,TUint,TSockAddr *)
+{
+}
+
+/**
+Initiates a connection operation - this means that it tells the protocol to attempt to connect
+to a peer. It is called by the socket server in response to a connect request from a client.
+@param If the protocol supports user specified connection data, then it will be held in this buffer
+*/
+void CInternalSocket::ActiveOpen(const class TDesC8 &)
+{
+}
+
+/**
+Initiates a connection operation - this means that it tells the protocol to attempt to connect
+to a peer. It is called by the socket server in response to a connect request from a client.
+*/
+void CInternalSocket::ActiveOpen(void)
+{
+}
+
+/**
+Tells the protocol to start waiting for an incoming connection request on this socket (i.e.
+port). It is called by the socket server in response to a listen request from a client.
+@param aNum size of connect queue
+@param aDes if the protocol supports user specified connection data, then it will be held in this buffer
+@return KErrNone if succesfull otherwise any error code.
+*/
+TInt CInternalSocket::PassiveOpen(TUint aNum,const TDesC8 &aDes)
+{
+ return iCServSocket->PassiveOpen(aNum,aDes);
+}
+
+/**
+Tells the protocol to start waiting for an incoming connection request on this socket (i.e.
+port). It is called by the socket server in response to a listen request from a client.
+@param aNum size of connect queue
+@return KErrNone if succesfull otherwise any error code.
+*/
+TInt CInternalSocket::PassiveOpen(TUint aNum)
+{
+ return iCServSocket->PassiveOpen(aNum);
+}
+
+/**
+Terminates a connection (or closes a non connection-oriented socket down).
+@param The shutdown type
+@param If the protocol supports disconnect data, any such data required will be held in this
+ buffer
+*/
+void CInternalSocket::Shutdown(enum CServProviderBase::TCloseType,const TDesC8 &)
+{
+}
+
+/**
+Terminates a connection (or closes a non connection-oriented socket down).
+@param The shutdown type
+*/
+void CInternalSocket::Shutdown(enum CServProviderBase::TCloseType)
+{
+}
+
+/**
+Specifies that the protocol should choose a local address for the service access point itself.
+*/
+void CInternalSocket::AutoBind(void)
+{
+ iCServSocket->AutoBind();
+}
+
+/**
+Close the socket - causes connection closure if required
+*/
+void CInternalSocket::Close()
+{
+ // If allready closing or closed, ignore the call
+ switch (iState)
+ {
+ case ENew:
+ case EClosing:
+ case EClosed:
+ case EFault:
+ return;
+ case EOpen:
+ case EConnecting:
+ case EConnected:
+ case EListening:
+ // attempting graceful closure of SAP
+ if (iCServSocket)
+ iCServSocket->Shutdown(CServProviderBase::ENormal);
+ TRAPD(ret,iTimers=CInternalSocketTimers::NewL(this));
+ if (ret!=KErrNone)
+ {
+ delete this;
+ break;
+ }
+ else
+ {
+ TCallBack callback(CInternalSocket::InternalSocketTimerExpired,this);
+ iTimers->StartInternalSocketTimer(callback,1500000L); // 1.5 secs
+ }
+ iState=EClosing;
+ break;
+ default:
+ IrlanUtil::Panic(EIrlanBadState);
+ break;
+ }
+}
+
+TInt CInternalSocket::InternalSocketTimerExpired(TAny *aCIntSock)
+{
+ CInternalSocket *ss=(CInternalSocket *)aCIntSock;
+
+ ss->iTimers->DoInternalSocketTimerExpired();
+ delete ss;
+ return 0;
+}
+
+/**
+Recv into descriptor via internal socket RecvFrom.
+@param aDes A descriptor where data read will be placed
+@param anAddr @param aAddr Address to write the data to
+@param aStat On completion, KErrNone if successful, KErrEof if a remote connection is
+ closed and there is no more data, KErrNotReady if called when an operation
+ is still outstanding, or a system-wide error code
+@param anOptions Option data.
+@return KErrNone if successful, KErrEof if a remote connection is closed and there is no more
+ data, KErrNotReady if called when an operation is still outstanding, or a system-wide error code
+*/
+TUint CInternalSocket::Recv(TDes8& aDes,TSockAddr* anAddr,TRequestStatus& aStat,TUint aOptions)
+{
+ RecvFrom(aDes,*anAddr,aOptions,aStat);
+ return KErrNone;
+}
+
+/**
+Recv datagram and source address. ASYNCHRONOUS FUNCTION.
+@param aDes A descriptor where data read will be placed
+@param aAddr A remote source address for unconnected receives
+@param aFlags Flags which are passed through to protocol
+@param aStatus On completion, will contain an error code: see the system-wide error codes.
+ Note that KErrEof indicates either that a remote connection is closed, and
+ that no more data is available for reading, or the socket has been shutdown
+ with option RSocket::EStopInput.
+@return On completion, will contain an error code: see the system-wide error codes.
+ Note that KErrEof indicates either that a remote connection is closed, and
+ that no more data is available for reading, or the socket has been shutdown
+ with option RSocket::EStopInput.
+*/
+void CInternalSocket::RecvFrom(TDes8& aDes, TSockAddr& aAddr, TUint aFlags,
+ TRequestStatus& aStatus)
+{
+ // Check if recv allready pending
+ __ASSERT_ALWAYS(!(iFlags & KSoRecvPending), Panic(EPanic_InUse));
+ // Check if state allows recv
+ __ASSERT_ALWAYS((!(iFlags&KSoConnectionless) && iState==EConnected) || iState==EOpen, Panic(EPanic_NotReady));
+
+ iRecvDes = &aDes;
+ iRecvFlags = aFlags;
+ iRecvAddr = &aAddr;
+ iRecvStat = &aStatus;
+ __ASSERT_ALWAYS(iRecvStat!=0,Panic(EPanic_StatusRecv));
+// iRecvOffset = 0;
+ *iRecvStat = KRequestPending;
+ iFlags |= KSoRecvPending;
+ DoRecv();
+}
+
+/**
+Unpack RMBufChain and send the descriptor via internal socket SendTo.
+@param aPdu A reference to the packet to be sent (really an RMBufPkt)
+@param aOptions Protocol specific options
+@param aStat On completion, will contain an error code: see the system-wide error codes.
+ Note that KErrEof indicates either that a remote connection is closed, and
+ that no more data is available for reading, or the socket has been shutdown
+ with option RSocket::EStopInput.
+@param aAddr Address to write the data to
+@return For stream-oriented protocols, the return value is the number of bytes actually written.
+ If this is less than the length of the descriptor, then the protocol should call CanSend()
+ when it is ready to send more data. For datagram-oriented protocols, the write should return
+ either 0 if the write cannot be completed, or the length of the descriptor if the write succeeds -
+ no other values are valid. If the Write() must return 0, then it should call CanSend() when
+ it is ready to send more data. If the Write() fails due to some error, then it should call
+ Error() with an informative error number,
+*/
+TUint CInternalSocket::Write(RMBufChain& aPdu,TUint aOptions,TRequestStatus& aStat,TSockAddr* anAddr)
+{
+ RMBuf *mbuf;
+ TInt bptr=0;
+ TMBufIter iter=aPdu;
+ while ((mbuf=iter++)!=NULL)
+ {// Process each individual MBuf in chain.
+ TUint8* mptr=mbuf->Ptr();
+ TInt len=mbuf->Length();
+ while (len--) // Byte-stuffing algorithm applied to each mbuf byte
+ iSendBufPtr[bptr++]=*mptr++;
+ }
+ iSendBufPtr.SetLength(bptr);
+#ifdef __TRACEWIN__
+ LOG(Log::Printf(_L("IRLAN: CInternalSocket::Write\r\n")));
+ LOG(Log::HexDump(_S("IRLAN "),_S("IRLAN "),
+ (TUint8 *)&iSendBufPtr[0],iSendBufPtr.Length()));
+#endif
+ SendTo(iSendBufPtr,*anAddr,aOptions,aStat);
+ return KErrNone;
+}
+
+/**
+Send datagram to host/network. ASYNCHRONOUS FUNCTION.
+@param aDes A constant descriptor
+@param aAddr A remote destination address for unconnected sends
+@param aFlags Flags which are passed through to protocol
+@param aStatus On completion, will contain an error code: see the system-wide error codes.
+ Note that KErrEof indicates that the socket has been shutdown with option
+ EStopOutput
+*/
+void CInternalSocket::SendTo(const TDesC8& aDes, const TSockAddr& aAddr, TUint aFlags, TRequestStatus& aStatus)
+{
+ // Check if send already pending
+ __ASSERT_ALWAYS(!(iFlags & KSoSendPending), Panic(EPanic_InUse));
+ // Check if state allows send
+ __ASSERT_ALWAYS((!(iFlags&KSoConnectionless) && iState==EConnected) || iState==EOpen, Panic(EPanic_NotReady));
+
+ iSendDes = &aDes;
+ iSendFlags = aFlags;
+ iSendAddr = (TSockAddr*)&aAddr;
+ iSendStat = &aStatus;
+// iSendOffset = 0;
+ *iSendStat = KRequestPending;
+ iFlags |= KSoSendPending;
+ DoSend();
+}
+
+/**
+Abort a recv request
+Cancels an outstanding Recv() operation
+*/
+void CInternalSocket::CancelRecv()
+{
+ if (iFlags & KSoRecvPending)
+ CompleteRecv(KErrCancel);
+}
+
+/**
+Abort a send request
+Cancels an outstanding Send() operation.
+*/
+void CInternalSocket::CancelSend()
+{
+ if (iFlags & KSoSendPending)
+ CompleteSend(KErrCancel);
+}
+
+/**
+Upcall from SAP - more data arrived
+Indicates that new data is available on a service access point
+*/
+void CInternalSocket::NewData(TUint aCount)
+{
+ if (aCount==KNewDataEndofData)
+ // End of data indication
+ iFlags |= KSoCantRecvMore;
+ else
+ iRecvNotifyCount += aCount;
+
+ DoRecv();
+}
+
+/**
+Upcall from SAP - flow control on
+Indicates that new buffer space is available on a service
+*/
+void CInternalSocket::CanSend()
+{
+ iFlags &= ~KSoSendFlowOff;
+ iNotify->CanSend();
+ DoSend();
+}
+
+/**
+Upcall from SAP - can now delete or detach to SAP.
+Indicates that the SAP has finished closing down.
+*/
+void CInternalSocket::CanClose(TDelete aDelete)
+{
+#ifdef __TRACEWIN__
+ LOG(Log::Printf(_L("IRLAN: CInternalSocket::CanClose - deleting CServProvdBase\r\n")));
+#endif
+ switch (iState)
+ {
+ case EClosing:
+ // leave things alone
+ break;
+ default:
+ delete iCServSocket;
+ iCServSocket=NULL;
+ if (aDelete==EDelete && iProtocol)
+ iProtocol->Close();
+ iProtocol=NULL;
+ break;
+ }
+}
+
+/**
+Upcall from SAP - Error notification.
+@param aError The error code
+@param aOpMask A bitmask of TOperationBitmasks values specifying which pending operations are
+ affected by the Error up-call
+*/
+void CInternalSocket::Error(TInt aError, TUint aOpMask)
+{
+ if ((iFlags & KSoRecvPending) && (aOpMask & MSocketNotify::EErrorSend))
+ CompleteRecv(aError);
+ if ((iFlags & KSoSendPending) && (aOpMask & MSocketNotify::EErrorSend))
+ CompleteSend(aError);
+}
+
+/**
+Upcall from SAP - Not supported
+Indicates that the other end of a connection has disconnected.
+*/
+void CInternalSocket::Disconnect(void)
+{
+}
+
+/**
+Upcall from SAP. Notify layer above
+Indicates that a connection attempt has completed successfully
+*/
+void CInternalSocket::ConnectComplete()
+{
+}
+
+/**
+Upcall from SAP. Notify layer above
+Indicates that the currently pending Ioctl has completed
+
+@param aBuf Any data requested by the Ioctl operation.
+*/
+void CInternalSocket::IoctlComplete(TDesC8* aBuf)
+{
+ iNotify->IoctlComplete(aBuf);
+}
+
+/**
+Upcall from SAP. Notify layer above
+Indicates that a connection attempt has completed successfully
+@param aSSP The new SSP for passive opens
+*/
+void CInternalSocket::ConnectComplete(CServProviderBase& aSSP)
+{
+ iState = EConnected;
+ iNotify->ConnectComplete(aSSP);
+}
+
+/**
+Upcall from SAP. Notify layer above
+Indicates that a connection attempt has completed successfully
+@param aConnectData Connect data (if supported)
+*/
+void CInternalSocket::ConnectComplete(const TDesC8& aConnectData)
+{
+ iState = EConnected;
+ iNotify->ConnectComplete(aConnectData);
+}
+
+/**
+Upcall from SAP. Notify layer above
+Indicates that a connection attempt has completed successfully
+@param aSSP The new SSP for passive opens
+@param aConnectData Connect data (if supported)
+*/
+void CInternalSocket::ConnectComplete(CServProviderBase& aSSP,const TDesC8& aConnectData)
+{
+ iState = EConnected;
+ iNotify->ConnectComplete(aSSP,aConnectData);
+}
+
+/**
+Indicates that the other end of a connection has disconnected
+@param aDisconnectData User data in the disconnect frame.
+*/
+void CInternalSocket::Disconnect(TDesC8& /*aDisconnectData*/)
+{
+}
+
+/**
+Upcall from SAP. Notify layer above.
+Indicates that the SAP has finished closing down
+@param aDisconnectData Any user data carried on the disconnect frame
+@param aDelete Delete SAP
+*/
+void CInternalSocket::CanClose(const TDesC8& /*aDisconnectData*/,TDelete /*aDelete*/)
+{
+}
+
+/**
+Receive processing
+*/
+void CInternalSocket::DoRecv()
+{
+ if (!(iFlags & KSoRecvPending))
+ return;
+ if (iRecvNotifyCount==0)
+ return;
+ iRecvNotifyCount -= 1;
+ iCServSocket->GetData(*iRecvDes, iRecvFlags, iRecvAddr);
+// iRecvOffset = iRecvDes->Length();
+ CompleteRecv(KErrNone);
+}
+
+/**
+Complete the pending receive updating the length
+@param aStatus Sets the status after completely receiving the data.
+*/
+void CInternalSocket::CompleteRecv(TInt aStatus)
+{
+ iFlags &= ~KSoRecvPending;
+// iRecvDes->SetLength(iRecvOffset);
+// if (iRecvXferLen)
+// {
+// TSockXfrLength len;
+// len() = iRecvOffset;
+// *iRecvXferLen = len;
+// }
+ __ASSERT_ALWAYS(iRecvStat!=NULL,Panic(EPanic_StatusComplete));
+ User::RequestComplete(iRecvStat, aStatus);
+}
+
+/**
+Send processing
+*/
+void CInternalSocket::DoSend()
+{
+ if (!(iFlags & KSoSendPending))
+ return;
+ if (iCServSocket->Write(*iSendDes, iSendFlags, iSendAddr))
+ {
+// iSendOffset = iSendDes->Length();
+ CompleteSend(KErrNone);
+ }
+ else
+ iFlags |= KSoSendFlowOff;
+}
+
+/**
+Complete the pending send updating the length
+@param aStatus On Completion sets the status.
+*/
+void CInternalSocket::CompleteSend(TInt aStatus)
+{
+ iFlags &= ~KSoSendPending;
+// if (iSendXferLen)
+// {
+// TSockXfrLength len;
+// len() = iSendOffset;
+// *iSendXferLen = len;
+// }
+ iSendBufPtr.SetLength(iSendBufLength);
+ User::RequestComplete(iSendStat, aStatus);
+}
+
+void CInternalSocket::NoBearer(const TDesC8& /*aConnectionParams*/)
+{
+}
+
+void CInternalSocket::Bearer(const TDesC8& /*aConnectionInfo*/)
+{
+}
+
+/**
+Panics.
+@param aPanic The panic number.
+*/
+void CInternalSocket::Panic(TPanicCode aPanic)
+{
+ __DEBUGGER();
+ User::Panic(_L("CInSock"), aPanic);
+}
+
+//**********************************************************************
+
+/**
+Constructor
+*/
+CInternalHostResolver::CInternalHostResolver()
+{
+ __DECLARE_NAME(_S("CInternalHostResolver"));
+}
+
+/**
+Destructor.
+*/
+CInternalHostResolver::~CInternalHostResolver()
+{
+ delete iHostResolver;
+ if (iProtocol)
+ iProtocol->Close();
+}
+
+/**
+Create a new CInternalHostResolver object.
+*/
+CInternalHostResolver *CInternalHostResolver::NewL()
+{
+ return new (ELeave) CInternalHostResolver;
+}
+
+/**
+Opens a socket of the required type and protocol.
+@param aProtocolName A Protocol Name.
+@param aNotify A pointer to MResolverNotify object.
+@return KErrNone if succesfull otherwise any error code.
+*/
+TInt CInternalHostResolver::OpenL(const TDesC& aProtocolName,MResolverNotify *aEngine)
+{
+ // Assert a new host resolver
+ if (iState!=ENew)
+ return KErrAlreadyExists;
+ TInt err = KErrNone;
+ // Ensure protocol is loaded
+ TRAP(err, iProtocol = SocketServExt::FindAndLoadProtocolL(aProtocolName));
+ if (err!=KErrNone)
+ return err;
+ iProtocol->Open();
+ // Create the host resolver
+ TRAP(err, iHostResolver = iProtocol->NewHostResolverL());
+ if (err!=KErrNone)
+ {
+ iProtocol->Close();
+ iProtocol = NULL;
+ return err;
+ }
+ // Set state to OPEN
+ iHostResolver->SetNotify(this);
+ this->SetNotify(aEngine);
+ iState = EConnected;
+ return KErrNone;
+}
+
+/**
+Notifier call back from IrDA PRT
+This is where the request completes - it has already filled
+in the name record passed through to GetByName so leave that.
+@param aErr Error code.
+*/
+void CInternalHostResolver::QueryComplete(TInt aErr)
+{
+ iBusy=EFalse;
+ iNotify->QueryComplete(aErr);
+}
+
+/**
+Resolves a machine name to a TSockAddress asynchronously
+@param aName Name of the service to get
+*/
+TInt CInternalHostResolver::GetByName(TNameRecord& aName)
+{
+ if (iBusy)
+ return KErrInUse;
+ iBusy=ETrue;
+ iHostResolver->GetByName(aName);
+ return KErrNone;
+}
+
+/**
+Gets the name of a host from its address asynchronously
+@param aName Address of the service to get
+*/
+void CInternalHostResolver::GetByAddress(TNameRecord& /*aName*/)
+{
+}
+
+/**
+Sets the name of the local host
+@param aNameBuf The local host name.
+*/
+void CInternalHostResolver::SetHostName(TDes8& /*aNameBuf*/)
+{
+}
+
+/**
+Gets the name of the local host.
+@param aNameBuf The buffer passed in should have a minimum length of 256 characters,
+*/
+void CInternalHostResolver::GetHostName(TDes8& /*aNameBuf*/)
+{
+}
+
+//***********************************************************************
+
+/**
+Constructor.
+*/
+CInternalNetDB::CInternalNetDB()
+{
+}
+
+/**
+Destructor.
+*/
+CInternalNetDB::~CInternalNetDB()
+{
+ delete iNetDatabase;
+ if (iProtocol)
+ iProtocol->Close();
+}
+
+/**
+Create a new CInternalNetDB object
+*/
+CInternalNetDB *CInternalNetDB::NewL()
+{
+ return new (ELeave) CInternalNetDB;
+}
+
+/**
+Opens a socket of the required type and protocol.
+@param aProtocolName A Protocol Name.
+@param aNotify A pointer to MResolverNotify object.
+@return KErrNone if succesfull otherwise any error code.
+*/
+TInt CInternalNetDB::OpenL(const TDesC& aProtocolName,MResolverNotify *aEngine)
+{
+ // Assert a new net database
+ if (iState!=ENew)
+ return KErrAlreadyExists;
+ TInt err = KErrNone;
+ // Ensure protocol is loaded
+ TRAP(err, iProtocol = SocketServExt::FindAndLoadProtocolL(aProtocolName));
+ if (err!=KErrNone)
+ return err;
+ iProtocol->Open();
+ // Create the net database
+ TRAP(err, iNetDatabase = iProtocol->NewNetDatabaseL());
+ if (err!=KErrNone)
+ {
+ iProtocol->Close();
+ iProtocol = NULL;
+ return err;
+ }
+ // Set state to OPEN
+ iNetDatabase->SetNotify(this);
+ this->SetNotify(aEngine);
+ iState = EOpen;
+ return KErrNone;
+}
+
+/**
+Notifier call back from IrDA PRT
+This function is called when an operation querying the processing ability of a peer device
+completes
+@param aError Error code.
+*/
+void CInternalNetDB::QueryComplete(TInt aError)
+{
+ if (iBusy)
+ {
+ iBusy=EFalse;
+ iNotify->QueryComplete(aError);
+ }
+ // else we assume that it's an Add or Remove.
+}
+
+/**
+Remember that results are returned in this buffer too.
+Makes a query to the database
+@param aBuffer The query to perform
+*/
+TInt CInternalNetDB::Query(TDes8& aBuffer)
+{
+ if (iBusy)
+ return KErrInUse;
+ iBusy=ETrue;
+ iNetDatabase->Query(aBuffer);
+ return KErrNone;
+}
+
+/**
+Adds a record to the database
+@param aBuffer The record to add
+*/
+void CInternalNetDB::Add(TDes8& aBuffer)
+{
+ iNetDatabase->Add(aBuffer);
+}
+
+/**
+Removes a record from the database
+@param aBuffer The record to remove
+*/
+void CInternalNetDB::Remove(TDes8& aBuffer)
+{
+ iNetDatabase->Add(aBuffer);
+}
+
+//***********************************************************************
+
+/**
+Constructor.
+*/
+CInternalSocketTimers::CInternalSocketTimers(CInternalSocket *aCIntSock)
+{
+ __DECLARE_NAME(_S("CInternalSocketTimers"));
+ iInternalSocket=aCIntSock;
+ iInternalSocketTimerH=NULL;
+}
+
+/**
+Destructor.
+*/
+CInternalSocketTimers::~CInternalSocketTimers()
+{
+ if (iInternalSocketTimerH)
+ StopInternalSocketTimer();
+}
+
+/**
+Initialise the value of iInternalSocket for static member functions
+@param aCIntSock A pointer to CInternalSocket object.
+*/
+CInternalSocketTimers *CInternalSocketTimers::NewL(CInternalSocket *aCIntSock)
+{
+ return new (ELeave) CInternalSocketTimers(aCIntSock);
+}
+
+/**
+Invoked to start the Internal Socket timer
+Can either complete as a call back to the
+static CInternalSocket::InternalSocketTimerExpired or can cancel.
+@param aCallBack Encapsulates a general call-back function.
+@param aTimeout Time out period
+*/
+void CInternalSocketTimers::StartInternalSocketTimer(TCallBack aCallBack,TInt aTimeout)
+{
+ if (iInternalSocketTimerH)
+ StopInternalSocketTimer();
+ iInternalSocketTimer.Set(aCallBack);
+ iInternalSocketTimerH=&iInternalSocketTimer;
+ IrlanTimer::Queue(aTimeout,iInternalSocketTimer);
+}
+
+/**
+Invoked to stop a previously queued Internal Socket timer
+*/
+void CInternalSocketTimers::StopInternalSocketTimer()
+{
+ if (iInternalSocketTimerH)
+ IrlanTimer::Remove(iInternalSocketTimer);
+ iInternalSocketTimerH=NULL;
+}
+
+void CInternalSocketTimers::DoInternalSocketTimerExpired()
+{
+ iInternalSocketTimerH=NULL;
+}
+
+
+
+