linklayerprotocols/ethernetnif/IRLAN/INTSOCK.CPP
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Internal Sockets API
       
    15 // Written by Mal, September 1997
       
    16 // Based on work by AdamG 
       
    17 // 
       
    18 //
       
    19 
       
    20 /**
       
    21  @file 
       
    22 */
       
    23 
       
    24 #include <e32std.h>
       
    25 #include <e32base.h>
       
    26 #include <es_prot.h>
       
    27 #include <es_mbuf.h>
       
    28 #include <es_prot_internal.h>
       
    29 #include "INTSOCK.H"
       
    30 #include "IRLANUTL.H"
       
    31 #include "irlantimer.h"
       
    32 
       
    33 #ifdef __TRACEWIN__
       
    34   #include <log.h>
       
    35 #else
       
    36   #define LOG(a)
       
    37 #endif
       
    38 
       
    39 /**
       
    40 Constructor.
       
    41 */
       
    42 CInternalSocket::CInternalSocket():iSendBufPtr(NULL,0)
       
    43 {
       
    44 	__DECLARE_NAME(_S("CInternalSocket"));
       
    45 	iState = ENew;
       
    46 }
       
    47 
       
    48 /**
       
    49 Only needed when cloning an accept from a listen socket.
       
    50 
       
    51 @param aSock   A pointer to CServProviderBase object
       
    52 @param aNotify A pointer to MSocketNotify object.
       
    53 @return A pointer to CInternalSocket object.
       
    54 */
       
    55 CInternalSocket *CInternalSocket::NewL(CServProviderBase *aSock,MSocketNotify *aNotify)
       
    56 {
       
    57 	CInternalSocket *is=new (ELeave) CInternalSocket;
       
    58 	// Need to set up send buffer for
       
    59 	is->iSendBufLength=KInternalMaxBufSize;
       
    60 	is->iSendBuffer=HBufC8::NewMaxL(is->iSendBufLength);
       
    61 	TPtr8 temp=is->iSendBuffer->Des();
       
    62 	is->iSendBufPtr.Set(temp);
       
    63 
       
    64 	is->SetNotify(aNotify);
       
    65 	is->iCServSocket=aSock;
       
    66 	is->iCServSocket->SetNotify(is);
       
    67 	is->iState = EOpen;
       
    68 	return is;
       
    69 }
       
    70 
       
    71 /**
       
    72 Destructor.
       
    73 */
       
    74 CInternalSocket::~CInternalSocket()
       
    75 {
       
    76 #ifdef __TRACEWIN__
       
    77 	LOG(Log::Printf(_L("IRLAN:	~CInternalSocket %x\r\n"),this));
       
    78 #endif
       
    79 	delete iSendBuffer;
       
    80 	delete iTimers;
       
    81 	__ASSERT_DEBUG(iState==EClosing,IrlanUtil::Panic(EIrlanBadState));
       
    82 	delete iCServSocket;   // underlying CServProviderBase
       
    83 	if (iProtocol)
       
    84 		iProtocol->Close();
       
    85 }
       
    86 
       
    87 /**
       
    88 Opens a socket of the required type and protocol.
       
    89 @param aProtocolName A Protocol Name.
       
    90 @param aNotify		 A pointer to MSocketNotify object.
       
    91 @return KErrNone if succesfull otherwise any error code.
       
    92 */
       
    93 TInt CInternalSocket::OpenL(const TDesC& aProtocolName,MSocketNotify* aNotify)
       
    94 {
       
    95 	// Assert a new socket
       
    96 	if (iState!=ENew)
       
    97 		return KErrAlreadyExists;
       
    98 	TInt err = KErrNone;
       
    99 	// Ensure protocol is loaded
       
   100 	TRAP(err, iProtocol = SocketServExt::FindAndLoadProtocolL(aProtocolName));
       
   101 	if (err!=KErrNone)
       
   102 		return err;
       
   103 	iProtocol->Open();
       
   104 	// Cache some protocol information	
       
   105 	TServerProtocolDesc info;
       
   106 	info.iName=aProtocolName;
       
   107 	iProtocol->Identify(&info);
       
   108 	if (!(info.iServiceTypeInfo & ESocketSupport))
       
   109 		{
       
   110 		iProtocol->Close();
       
   111 		iProtocol = NULL;
       
   112 		return KErrNotSupported;
       
   113 		}
       
   114 	if (info.iServiceTypeInfo & EUseCanSend)
       
   115 		iFlags |= KSoUseCanSend;
       
   116 	if (info.iServiceInfo & KSIConnectionLess)
       
   117 		iFlags |= KSoConnectionless;
       
   118 	if (info.iServiceInfo & KSIGracefulClose)
       
   119 		iFlags |= KSoGracefulClose;
       
   120 
       
   121 	// Create the SAP
       
   122 	TRAP(err, iCServSocket = iProtocol->NewSAPL(info.iSockType));
       
   123 	if (err!=KErrNone)
       
   124 		{
       
   125 		iProtocol->Close();
       
   126 		iProtocol = NULL;
       
   127 		return err;
       
   128 		}
       
   129 	// Need to set up send buffer for
       
   130 	iSendBufLength=KInternalMaxBufSize;
       
   131 	iSendBuffer=HBufC8::NewMaxL(iSendBufLength);
       
   132 	TPtr8 temp=iSendBuffer->Des();
       
   133 	iSendBufPtr.Set(temp);
       
   134 
       
   135 	// Set state to OPEN
       
   136 	iCServSocket->SetNotify(this);
       
   137 	this->SetNotify(aNotify);
       
   138 	iState = EOpen;
       
   139 	iCServSocket->Start();
       
   140 	return KErrNone;
       
   141 }
       
   142 
       
   143 /**
       
   144 Need to construct the TIrdaSockAddr with the appropriate port number.
       
   145 Note that this is a real simple connect - no notion of connect data or
       
   146 select or a blocking socket.
       
   147 @param aAddr A reference to TSockAddr class.
       
   148 @return KErrNone if succesfull otherwise any error code.
       
   149 */
       
   150 TInt CInternalSocket::Connect(TSockAddr& aAddr)
       
   151 {
       
   152 	TInt ret=iCServSocket->SetRemName(aAddr);
       
   153 	if (ret!=KErrNone)
       
   154 		return ret;
       
   155   	iState=EConnecting;
       
   156 	iCServSocket->ActiveOpen();
       
   157 	return ret;
       
   158 }
       
   159 
       
   160 /**
       
   161 Does the work of listen and accept together.
       
   162 @param aQSize	 No of clients to be done passive open.
       
   163 @return KErrNone if succesfull.
       
   164 */
       
   165 TInt CInternalSocket::WaitForConnect(TUint aQSize)
       
   166 {
       
   167 	iCServSocket->PassiveOpen(aQSize);
       
   168 	iState=EListening;
       
   169 	return KErrNone;
       
   170 }
       
   171 
       
   172 /**
       
   173 Gets the local address of a socket. 
       
   174 @param aAddr Local address which is filled..
       
   175 */
       
   176 void CInternalSocket::LocalName(TSockAddr& anAddr)const
       
   177 {
       
   178 	iCServSocket->LocalName(anAddr);
       
   179 }
       
   180 
       
   181 /**
       
   182 Gets the remote name (address) of the socket service provider entity. The format of the data 
       
   183 in the TSockAddr object is defined by individual protocols.
       
   184 @param aAddr The address to be filled in.
       
   185 */
       
   186 void CInternalSocket::RemName(TSockAddr& /*aAddr*/)const
       
   187 {
       
   188 }
       
   189 
       
   190 /**
       
   191 Sets the local name (address) of the socket service provider entity. The format of the data 
       
   192 in the TSockAddr object is defined by individual protocols.
       
   193 @param aAddr The address .
       
   194 @return KErrNone if the local name is correctly set or, if this is not the case, an 
       
   195 		informative error number.
       
   196 */
       
   197 TInt CInternalSocket::SetLocalName(TSockAddr& aAddr)
       
   198 {
       
   199 	return iCServSocket->SetLocalName(aAddr);
       
   200 }
       
   201 
       
   202 /**
       
   203 Sets some protocol specific option when called by the socket server on behalf of a client. A 
       
   204 protocol may pass the request down a protocol stack (to protocols it is bound to) using the 
       
   205 SetOption() function of CProtocolBase.
       
   206 @param aLevel Option level 
       
   207 @param aName  Option Name 
       
   208 @param aDes	  Option data.
       
   209 @return KErrNone if succesfull otherwise any error code.
       
   210 */
       
   211 TInt CInternalSocket::SetOption(TUint aLevel,TUint aName,const TDesC8& aDes)
       
   212 {
       
   213 	return iCServSocket->SetOption(aLevel,aName,aDes);
       
   214 }
       
   215 
       
   216 /**
       
   217 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.
       
   218 @param The address 
       
   219 @return Returns KErrNone if the remote name is correctly set or, if this is not the case, an informative error number.
       
   220 */
       
   221 TInt CInternalSocket::SetRemName(TSockAddr &aAddr)
       
   222 {	
       
   223 	return iCServSocket->SetRemName(aAddr);
       
   224 }
       
   225 
       
   226 /**
       
   227 Create a Socket.
       
   228 */
       
   229 void CInternalSocket::Start(void)
       
   230 {
       
   231 	iCServSocket->Start();
       
   232 }
       
   233 
       
   234 /**
       
   235 Gets some protocol specific option when called by the socket server on behalf of a client. 
       
   236 A protocol may pass the request down a protocol stack (to protocols it is bound to) using 
       
   237 the GetOption() function of CInternalSocket.
       
   238 @param aLevel	  Option level 
       
   239 @param aName	  Option Name 
       
   240 @param anOption	  Option data.
       
   241 @return KErrNone if succesfull otherwise any error code.
       
   242 */
       
   243 TInt CInternalSocket::GetOption(TUint aLevel,TUint aName,TDes8& anOption)const
       
   244 {
       
   245 	return iCServSocket->GetOption(aLevel,aName,anOption);
       
   246 }
       
   247 
       
   248 /**
       
   249 Performs some protocol specific IO control.
       
   250 @param aLevel IOCTL level 
       
   251 @param aName  IOCTL Name 
       
   252 @param aDes	  IOCTL option 
       
   253 */
       
   254 void CInternalSocket::Ioctl(TUint aLevel,TUint aName,TDes8* aDes)
       
   255 {
       
   256 	iCServSocket->Ioctl(aLevel,aName,aDes);
       
   257 }
       
   258 
       
   259 /**
       
   260 Cancels an outstanding Ioctl call. You are guaranteed only to have one outstanding at once. 
       
   261 @param aLevel IOCTL level 
       
   262 @param aName  IOCTL Name 
       
   263 */
       
   264 void CInternalSocket::CancelIoctl(TUint aLevel,TUint aName)
       
   265 {
       
   266 	iCServSocket->CancelIoctl(aLevel,aName);
       
   267 }
       
   268 
       
   269 /**
       
   270 Sends data onto the network via the protocol. Connection-oriented sockets must be in a connected 
       
   271 state (that is ConnectComplete() has been called on their MSocketNotify) before Write() is 
       
   272 called.
       
   273 @param aDes  The data to be sent
       
   274 @param aFlag Protocol specific options
       
   275 @param aAddr Address to write the data to 
       
   276 @return For stream-oriented protocols, the return value is the number of bytes actually written. 
       
   277 		If this is less than the length of the descriptor, then the protocol should call CanSend() 
       
   278 		when it is ready to send more data. For datagram-oriented protocols, the write should return 
       
   279 		either 0 if the write cannot be completed, or the length of the descriptor if the write succeeds - 
       
   280 		no other values are valid. If the Write() must return 0, then it should call CanSend() when 
       
   281 		it is ready to send more data. If the Write() fails due to some error, then it should call 
       
   282 		Error() with an informative error number,
       
   283 */
       
   284 TUint CInternalSocket::Write(const TDesC8& aDes,TUint aFlag,TSockAddr *aAddr)
       
   285 {
       
   286 	return iCServSocket->Write(aDes,aFlag,aAddr);
       
   287 }
       
   288 
       
   289 /**
       
   290 Gets data which the protocol has indicated is waiting in its buffers using the NewData up-call 
       
   291 on the MSocketNotify.
       
   292 @param The buffer for data 
       
   293 @param Protocol specific options 
       
   294 @param Where the data came from 
       
   295 */
       
   296 void CInternalSocket::GetData(TDes8 &,TUint,TSockAddr *)
       
   297 {
       
   298 }
       
   299 
       
   300 /**
       
   301 Initiates a connection operation - this means that it tells the protocol to attempt to connect 
       
   302 to a peer. It is called by the socket server in response to a connect request from a client. 
       
   303 @param If the protocol supports user specified connection data, then it will be held in this buffer
       
   304 */
       
   305 void CInternalSocket::ActiveOpen(const class TDesC8 &)
       
   306 {
       
   307 }
       
   308 
       
   309 /**
       
   310 Initiates a connection operation - this means that it tells the protocol to attempt to connect 
       
   311 to a peer. It is called by the socket server in response to a connect request from a client.
       
   312 */
       
   313 void CInternalSocket::ActiveOpen(void)
       
   314 {
       
   315 }
       
   316 
       
   317 /**
       
   318 Tells the protocol to start waiting for an incoming connection request on this socket (i.e. 
       
   319 port). It is called by the socket server in response to a listen request from a client.
       
   320 @param aNum size of connect queue 
       
   321 @param aDes if the protocol supports user specified connection data, then it will be held in 			this buffer
       
   322 @return KErrNone if succesfull otherwise any error code.
       
   323 */
       
   324 TInt CInternalSocket::PassiveOpen(TUint aNum,const TDesC8 &aDes)
       
   325 {
       
   326 	return iCServSocket->PassiveOpen(aNum,aDes);
       
   327 }
       
   328 
       
   329 /**
       
   330 Tells the protocol to start waiting for an incoming connection request on this socket (i.e. 
       
   331 port). It is called by the socket server in response to a listen request from a client.
       
   332 @param aNum size of connect queue 
       
   333 @return KErrNone if succesfull otherwise any error code.
       
   334 */
       
   335 TInt CInternalSocket::PassiveOpen(TUint aNum)
       
   336 {
       
   337 	return iCServSocket->PassiveOpen(aNum);
       
   338 }
       
   339 
       
   340 /**
       
   341 Terminates a connection (or closes a non connection-oriented socket down). 
       
   342 @param The shutdown type 
       
   343 @param If the protocol supports disconnect data, any such data required will be held in this 
       
   344 		buffer
       
   345 */
       
   346 void CInternalSocket::Shutdown(enum CServProviderBase::TCloseType,const TDesC8 &)
       
   347 {
       
   348 }
       
   349 
       
   350 /**
       
   351 Terminates a connection (or closes a non connection-oriented socket down). 
       
   352 @param The shutdown type 
       
   353 */
       
   354 void CInternalSocket::Shutdown(enum CServProviderBase::TCloseType)
       
   355 {
       
   356 }	
       
   357 
       
   358 /**
       
   359 Specifies that the protocol should choose a local address for the service access point itself.
       
   360 */
       
   361 void CInternalSocket::AutoBind(void)
       
   362 {	
       
   363 	iCServSocket->AutoBind();
       
   364 }
       
   365 
       
   366 /**
       
   367 Close the socket - causes connection closure if required
       
   368 */
       
   369 void CInternalSocket::Close()
       
   370 {
       
   371 	// If allready closing or closed, ignore the call
       
   372 	switch (iState)
       
   373 		{
       
   374 	case ENew:
       
   375 	case EClosing:
       
   376 	case EClosed:
       
   377 	case EFault:
       
   378 		return;
       
   379 	case EOpen:
       
   380 	case EConnecting:
       
   381 	case EConnected:
       
   382 	case EListening:
       
   383 		// attempting graceful closure of SAP
       
   384 		if (iCServSocket)
       
   385 			iCServSocket->Shutdown(CServProviderBase::ENormal);
       
   386 		TRAPD(ret,iTimers=CInternalSocketTimers::NewL(this));
       
   387 		if (ret!=KErrNone)
       
   388 			{
       
   389 			delete this;
       
   390 			break;
       
   391 			}
       
   392 		else
       
   393 			{
       
   394 			TCallBack callback(CInternalSocket::InternalSocketTimerExpired,this);
       
   395 			iTimers->StartInternalSocketTimer(callback,1500000L);  // 1.5 secs
       
   396 			}
       
   397 		iState=EClosing;
       
   398 		break;
       
   399 	default:
       
   400 		IrlanUtil::Panic(EIrlanBadState);
       
   401 		break;
       
   402 		}
       
   403 }
       
   404 
       
   405 TInt CInternalSocket::InternalSocketTimerExpired(TAny *aCIntSock)
       
   406 {
       
   407 	CInternalSocket *ss=(CInternalSocket *)aCIntSock;
       
   408 
       
   409 	ss->iTimers->DoInternalSocketTimerExpired();
       
   410 	delete ss;
       
   411 	return 0;
       
   412 }
       
   413 
       
   414 /**
       
   415 Recv into descriptor via internal socket RecvFrom.
       
   416 @param aDes		A descriptor where data read will be placed
       
   417 @param anAddr	@param aAddr Address to write the data to 
       
   418 @param aStat	On completion, KErrNone if successful, KErrEof if a remote connection is 
       
   419 				closed and there is no more data, KErrNotReady if called when an operation 
       
   420 				is still outstanding, or a system-wide error code
       
   421 @param anOptions Option data.
       
   422 @return KErrNone if successful, KErrEof if a remote connection is closed and there is no more 
       
   423 		data, KErrNotReady if called when an operation is still outstanding, or a system-wide error code
       
   424 */
       
   425 TUint CInternalSocket::Recv(TDes8& aDes,TSockAddr* anAddr,TRequestStatus& aStat,TUint aOptions)
       
   426 {
       
   427 	RecvFrom(aDes,*anAddr,aOptions,aStat);  
       
   428 	return KErrNone;
       
   429 }
       
   430 
       
   431 /**
       
   432 Recv datagram and source address.  ASYNCHRONOUS FUNCTION.
       
   433 @param aDes		A descriptor where data read will be placed
       
   434 @param aAddr	A remote source address for unconnected receives
       
   435 @param aFlags	Flags which are passed through to protocol
       
   436 @param aStatus	On completion, will contain an error code: see the system-wide error codes. 
       
   437 				Note that KErrEof indicates either that a remote connection is closed, and 
       
   438 				that no more data is available for reading, or the socket has been shutdown 
       
   439 				with option RSocket::EStopInput.
       
   440 @return On completion, will contain an error code: see the system-wide error codes. 
       
   441 		Note that KErrEof indicates either that a remote connection is closed, and 
       
   442 		that no more data is available for reading, or the socket has been shutdown 
       
   443 		with option RSocket::EStopInput.
       
   444 */
       
   445 void CInternalSocket::RecvFrom(TDes8& aDes, TSockAddr& aAddr, TUint aFlags, 
       
   446 							   TRequestStatus& aStatus)
       
   447 {
       
   448 	// Check if recv allready pending
       
   449 	__ASSERT_ALWAYS(!(iFlags & KSoRecvPending), Panic(EPanic_InUse));
       
   450 	// Check if state allows recv
       
   451 	__ASSERT_ALWAYS((!(iFlags&KSoConnectionless) && iState==EConnected) || iState==EOpen, Panic(EPanic_NotReady));
       
   452 
       
   453 	iRecvDes = &aDes;
       
   454 	iRecvFlags = aFlags;
       
   455 	iRecvAddr = &aAddr;
       
   456 	iRecvStat = &aStatus;
       
   457 	__ASSERT_ALWAYS(iRecvStat!=0,Panic(EPanic_StatusRecv));
       
   458 //	iRecvOffset = 0;
       
   459 	*iRecvStat = KRequestPending;	
       
   460 	iFlags |= KSoRecvPending;
       
   461 	DoRecv();
       
   462 }
       
   463 
       
   464 /**
       
   465 Unpack RMBufChain and send the descriptor via internal socket SendTo.
       
   466 @param aPdu     A reference to the packet to be sent (really an RMBufPkt)
       
   467 @param aOptions Protocol specific options
       
   468 @param aStat	On completion, will contain an error code: see the system-wide error codes. 
       
   469 				Note that KErrEof indicates either that a remote connection is closed, and 
       
   470 				that no more data is available for reading, or the socket has been shutdown 
       
   471 				with option RSocket::EStopInput.
       
   472 @param aAddr    Address to write the data to 
       
   473 @return For stream-oriented protocols, the return value is the number of bytes actually written. 
       
   474 		If this is less than the length of the descriptor, then the protocol should call CanSend() 
       
   475 		when it is ready to send more data. For datagram-oriented protocols, the write should return 
       
   476 		either 0 if the write cannot be completed, or the length of the descriptor if the write succeeds - 
       
   477 		no other values are valid. If the Write() must return 0, then it should call CanSend() when 
       
   478 		it is ready to send more data. If the Write() fails due to some error, then it should call 
       
   479 		Error() with an informative error number,
       
   480 */
       
   481 TUint CInternalSocket::Write(RMBufChain& aPdu,TUint aOptions,TRequestStatus& aStat,TSockAddr* anAddr)
       
   482 {
       
   483 	RMBuf *mbuf;
       
   484 	TInt bptr=0;
       
   485 	TMBufIter iter=aPdu;
       
   486 	while ((mbuf=iter++)!=NULL)
       
   487 		{// Process each individual MBuf in chain.
       
   488 		TUint8* mptr=mbuf->Ptr();
       
   489 		TInt len=mbuf->Length();
       
   490 		while (len--)	// Byte-stuffing algorithm applied to each mbuf byte
       
   491 			iSendBufPtr[bptr++]=*mptr++;
       
   492 		}
       
   493 	iSendBufPtr.SetLength(bptr);
       
   494 #ifdef __TRACEWIN__
       
   495 	LOG(Log::Printf(_L("IRLAN:	CInternalSocket::Write\r\n")));
       
   496 	LOG(Log::HexDump(_S("IRLAN	"),_S("IRLAN	"),
       
   497 	  (TUint8 *)&iSendBufPtr[0],iSendBufPtr.Length()));
       
   498 #endif
       
   499 	SendTo(iSendBufPtr,*anAddr,aOptions,aStat);  
       
   500 	return KErrNone;
       
   501 }
       
   502 
       
   503 /**
       
   504 Send datagram to host/network.  ASYNCHRONOUS FUNCTION.
       
   505 @param aDes		A constant descriptor
       
   506 @param aAddr	A remote destination address for unconnected sends
       
   507 @param aFlags	Flags which are passed through to protocol
       
   508 @param aStatus	On completion, will contain an error code: see the system-wide error codes. 
       
   509 				Note that KErrEof indicates that the socket has been shutdown with option 
       
   510 				EStopOutput
       
   511 */
       
   512 void CInternalSocket::SendTo(const TDesC8& aDes, const TSockAddr& aAddr, TUint aFlags, TRequestStatus& aStatus)
       
   513 {
       
   514 	// Check if send already pending
       
   515 	__ASSERT_ALWAYS(!(iFlags & KSoSendPending), Panic(EPanic_InUse));
       
   516 	// Check if state allows send
       
   517 	__ASSERT_ALWAYS((!(iFlags&KSoConnectionless) && iState==EConnected) || iState==EOpen, Panic(EPanic_NotReady));
       
   518 
       
   519 	iSendDes = &aDes;
       
   520 	iSendFlags = aFlags;
       
   521 	iSendAddr = (TSockAddr*)&aAddr;
       
   522 	iSendStat = &aStatus;
       
   523 //	iSendOffset = 0;
       
   524 	*iSendStat = KRequestPending;	
       
   525 	iFlags |= KSoSendPending;
       
   526 	DoSend();
       
   527 }
       
   528 
       
   529 /**
       
   530 Abort a recv request
       
   531 Cancels an outstanding Recv() operation
       
   532 */
       
   533 void CInternalSocket::CancelRecv()
       
   534 {
       
   535 	if (iFlags & KSoRecvPending)
       
   536 		CompleteRecv(KErrCancel);
       
   537 }
       
   538 
       
   539 /**
       
   540 Abort a send request
       
   541 Cancels an outstanding Send() operation.
       
   542 */
       
   543 void CInternalSocket::CancelSend()
       
   544 {
       
   545 	if (iFlags & KSoSendPending)
       
   546 		CompleteSend(KErrCancel);
       
   547 }
       
   548 
       
   549 /**
       
   550 Upcall from SAP - more data arrived
       
   551 Indicates that new data is available on a service access point
       
   552 */
       
   553 void CInternalSocket::NewData(TUint aCount)
       
   554 {
       
   555 	if (aCount==KNewDataEndofData)
       
   556 		// End of data indication
       
   557 		iFlags |= KSoCantRecvMore;
       
   558 	else
       
   559 		iRecvNotifyCount += aCount;
       
   560 
       
   561 	DoRecv();
       
   562 }
       
   563 
       
   564 /**
       
   565 Upcall from SAP - flow control on
       
   566 Indicates that new buffer space is available on a service 
       
   567 */
       
   568 void CInternalSocket::CanSend()
       
   569 {
       
   570 	iFlags &= ~KSoSendFlowOff;
       
   571 	iNotify->CanSend();
       
   572 	DoSend();
       
   573 }
       
   574 
       
   575 /**
       
   576 Upcall from SAP - can now delete or detach to SAP.
       
   577 Indicates that the SAP has finished closing down.
       
   578 */
       
   579 void CInternalSocket::CanClose(TDelete aDelete)
       
   580 {
       
   581 #ifdef __TRACEWIN__
       
   582 	LOG(Log::Printf(_L("IRLAN:	CInternalSocket::CanClose - deleting CServProvdBase\r\n")));
       
   583 #endif
       
   584 	switch (iState)
       
   585 		{
       
   586 	case EClosing:
       
   587 		// leave things alone
       
   588 		break;
       
   589 	default:
       
   590 		delete iCServSocket;
       
   591 		iCServSocket=NULL;
       
   592 		if (aDelete==EDelete && iProtocol)
       
   593 			iProtocol->Close();
       
   594 		iProtocol=NULL;
       
   595 		break;
       
   596 		}	
       
   597 }
       
   598 
       
   599 /**
       
   600 Upcall from SAP - Error notification.
       
   601 @param aError  The error code
       
   602 @param aOpMask A bitmask of TOperationBitmasks values specifying which pending operations are
       
   603 			   affected by the Error up-call
       
   604 */
       
   605 void CInternalSocket::Error(TInt aError, TUint aOpMask)
       
   606 {
       
   607 	if ((iFlags & KSoRecvPending) && (aOpMask & MSocketNotify::EErrorSend))
       
   608 		CompleteRecv(aError);
       
   609 	if ((iFlags & KSoSendPending) && (aOpMask & MSocketNotify::EErrorSend))
       
   610 		CompleteSend(aError);
       
   611 }
       
   612                                           
       
   613 /**
       
   614 Upcall from SAP - Not supported
       
   615 Indicates that the other end of a connection has disconnected. 
       
   616 */
       
   617 void CInternalSocket::Disconnect(void)
       
   618 {
       
   619 }
       
   620 
       
   621 /**
       
   622 Upcall from SAP.  Notify layer above
       
   623 Indicates that a connection attempt has completed successfully
       
   624 */
       
   625 void CInternalSocket::ConnectComplete()
       
   626 {
       
   627 }
       
   628 
       
   629 /**
       
   630 Upcall from SAP.  Notify layer above
       
   631 Indicates that the currently pending Ioctl has completed
       
   632 
       
   633 @param aBuf Any data requested by the Ioctl operation.
       
   634 */
       
   635 void CInternalSocket::IoctlComplete(TDesC8* aBuf)
       
   636 {
       
   637 	iNotify->IoctlComplete(aBuf);
       
   638 }
       
   639 
       
   640 /**
       
   641 Upcall from SAP.  Notify layer above
       
   642 Indicates that a connection attempt has completed successfully
       
   643 @param aSSP The new SSP for passive opens 
       
   644 */
       
   645 void CInternalSocket::ConnectComplete(CServProviderBase& aSSP)
       
   646 {
       
   647 	iState = EConnected;
       
   648 	iNotify->ConnectComplete(aSSP);
       
   649 }
       
   650 
       
   651 /**
       
   652 Upcall from SAP.  Notify layer above
       
   653 Indicates that a connection attempt has completed successfully
       
   654 @param aConnectData Connect data (if supported)  
       
   655 */
       
   656 void CInternalSocket::ConnectComplete(const TDesC8& aConnectData)
       
   657 {
       
   658 	iState = EConnected;
       
   659 	iNotify->ConnectComplete(aConnectData);
       
   660 }
       
   661 
       
   662 /**
       
   663 Upcall from SAP.  Notify layer above
       
   664 Indicates that a connection attempt has completed successfully
       
   665 @param aSSP The new SSP for passive opens 
       
   666 @param aConnectData Connect data (if supported)  
       
   667 */
       
   668 void CInternalSocket::ConnectComplete(CServProviderBase& aSSP,const TDesC8& aConnectData)
       
   669 {
       
   670 	iState = EConnected;
       
   671 	iNotify->ConnectComplete(aSSP,aConnectData);
       
   672 }
       
   673 
       
   674 /**
       
   675 Indicates that the other end of a connection has disconnected
       
   676 @param aDisconnectData User data in the disconnect frame.
       
   677 */
       
   678 void CInternalSocket::Disconnect(TDesC8& /*aDisconnectData*/)
       
   679 {
       
   680 }
       
   681 
       
   682 /**
       
   683 Upcall from SAP.  Notify layer above.
       
   684 Indicates that the SAP has finished closing down
       
   685 @param aDisconnectData Any user data carried on the disconnect frame 
       
   686 @param aDelete         Delete SAP 
       
   687 */
       
   688 void CInternalSocket::CanClose(const TDesC8& /*aDisconnectData*/,TDelete /*aDelete*/)
       
   689 {
       
   690 }
       
   691 
       
   692 /**
       
   693 Receive processing
       
   694 */
       
   695 void CInternalSocket::DoRecv()
       
   696 {
       
   697 	if (!(iFlags & KSoRecvPending))
       
   698 		return;
       
   699 	if (iRecvNotifyCount==0)
       
   700 		return;
       
   701 	iRecvNotifyCount -= 1;
       
   702 	iCServSocket->GetData(*iRecvDes, iRecvFlags, iRecvAddr);
       
   703 //	iRecvOffset = iRecvDes->Length();
       
   704 	CompleteRecv(KErrNone);
       
   705 }
       
   706 
       
   707 /**
       
   708 Complete the pending receive updating the length
       
   709 @param aStatus Sets the status after completely receiving the data.
       
   710 */
       
   711 void CInternalSocket::CompleteRecv(TInt aStatus)
       
   712 {
       
   713 	iFlags &= ~KSoRecvPending;
       
   714 //	iRecvDes->SetLength(iRecvOffset);
       
   715 //	if (iRecvXferLen)
       
   716 //		{
       
   717 //		TSockXfrLength len;
       
   718 //		len() = iRecvOffset;
       
   719 //		*iRecvXferLen = len;
       
   720 //		}
       
   721 	__ASSERT_ALWAYS(iRecvStat!=NULL,Panic(EPanic_StatusComplete));
       
   722 	User::RequestComplete(iRecvStat, aStatus);
       
   723 }
       
   724 
       
   725 /**
       
   726 Send processing
       
   727 */
       
   728 void CInternalSocket::DoSend()
       
   729 {
       
   730 	if (!(iFlags & KSoSendPending))
       
   731 		return;
       
   732 	if (iCServSocket->Write(*iSendDes, iSendFlags, iSendAddr))
       
   733 		{
       
   734 //		iSendOffset = iSendDes->Length();
       
   735 		CompleteSend(KErrNone);
       
   736 		}
       
   737 	else
       
   738 		iFlags |= KSoSendFlowOff;
       
   739 }
       
   740 
       
   741 /**
       
   742 Complete the pending send updating the length
       
   743 @param aStatus On Completion sets the status.
       
   744 */
       
   745 void CInternalSocket::CompleteSend(TInt aStatus)
       
   746 {
       
   747 	iFlags &= ~KSoSendPending;
       
   748 //	if (iSendXferLen)
       
   749 //		{
       
   750 //		TSockXfrLength len;
       
   751 //		len() = iSendOffset;
       
   752 //		*iSendXferLen = len;
       
   753 //		}
       
   754 	iSendBufPtr.SetLength(iSendBufLength);
       
   755 	User::RequestComplete(iSendStat, aStatus);
       
   756 }
       
   757 
       
   758 void CInternalSocket::NoBearer(const TDesC8& /*aConnectionParams*/)
       
   759 {
       
   760 }
       
   761 
       
   762 void CInternalSocket::Bearer(const TDesC8& /*aConnectionInfo*/)
       
   763 {
       
   764 }
       
   765 
       
   766 /**
       
   767 Panics.
       
   768 @param aPanic The panic number.
       
   769 */
       
   770 void CInternalSocket::Panic(TPanicCode aPanic)
       
   771 {
       
   772 	__DEBUGGER();
       
   773 	User::Panic(_L("CInSock"), aPanic);
       
   774 }
       
   775 
       
   776 //**********************************************************************
       
   777 
       
   778 /**
       
   779 Constructor
       
   780 */
       
   781 CInternalHostResolver::CInternalHostResolver()
       
   782 {
       
   783 	__DECLARE_NAME(_S("CInternalHostResolver"));
       
   784 }
       
   785 
       
   786 /**
       
   787 Destructor.
       
   788 */
       
   789 CInternalHostResolver::~CInternalHostResolver()
       
   790 {
       
   791 	delete iHostResolver;
       
   792 	if (iProtocol)
       
   793 		iProtocol->Close();
       
   794 }
       
   795 
       
   796 /**
       
   797 Create a new CInternalHostResolver object.
       
   798 */
       
   799 CInternalHostResolver *CInternalHostResolver::NewL()
       
   800 {
       
   801 	return new (ELeave) CInternalHostResolver;
       
   802 }
       
   803 
       
   804 /**
       
   805 Opens a socket of the required type and protocol.
       
   806 @param aProtocolName A Protocol Name.
       
   807 @param aNotify		 A pointer to MResolverNotify object.
       
   808 @return KErrNone if succesfull otherwise any error code.
       
   809 */
       
   810 TInt CInternalHostResolver::OpenL(const TDesC& aProtocolName,MResolverNotify *aEngine)
       
   811 {
       
   812 	// Assert a new host resolver
       
   813 	if (iState!=ENew)
       
   814 		return KErrAlreadyExists;
       
   815 	TInt err = KErrNone;
       
   816 	// Ensure protocol is loaded
       
   817 	TRAP(err, iProtocol = SocketServExt::FindAndLoadProtocolL(aProtocolName));
       
   818 	if (err!=KErrNone)
       
   819 		return err;
       
   820 	iProtocol->Open();
       
   821 	// Create the host resolver
       
   822 	TRAP(err, iHostResolver = iProtocol->NewHostResolverL());
       
   823 	if (err!=KErrNone)
       
   824 		{
       
   825 		iProtocol->Close();
       
   826 		iProtocol = NULL;
       
   827 		return err;
       
   828 		}
       
   829 	// Set state to OPEN
       
   830 	iHostResolver->SetNotify(this);
       
   831 	this->SetNotify(aEngine);
       
   832 	iState = EConnected;
       
   833 	return KErrNone;
       
   834 }
       
   835 
       
   836 /**
       
   837 Notifier call back from IrDA PRT
       
   838 This is where the request completes - it has already filled
       
   839 in the name record passed through to GetByName so leave that.
       
   840 @param aErr Error code.
       
   841 */
       
   842 void CInternalHostResolver::QueryComplete(TInt aErr)
       
   843 {
       
   844 	iBusy=EFalse;
       
   845 	iNotify->QueryComplete(aErr);
       
   846 }
       
   847 
       
   848 /**
       
   849 Resolves a machine name to a TSockAddress asynchronously
       
   850 @param aName Name of the service to get
       
   851 */
       
   852 TInt CInternalHostResolver::GetByName(TNameRecord& aName)
       
   853 {
       
   854 	if (iBusy)
       
   855 		return KErrInUse;
       
   856 	iBusy=ETrue;
       
   857 	iHostResolver->GetByName(aName);
       
   858 	return KErrNone;
       
   859 }			   
       
   860 
       
   861 /**
       
   862 Gets the name of a host from its address asynchronously
       
   863 @param aName Address of the service to get
       
   864 */
       
   865 void CInternalHostResolver::GetByAddress(TNameRecord& /*aName*/)
       
   866 {
       
   867 }
       
   868 
       
   869 /**
       
   870 Sets the name of the local host
       
   871 @param aNameBuf The local host name.
       
   872 */
       
   873 void CInternalHostResolver::SetHostName(TDes8& /*aNameBuf*/)
       
   874 {
       
   875 }
       
   876 
       
   877 /**
       
   878 Gets the name of the local host.
       
   879 @param aNameBuf The buffer passed in should have a minimum length of 256 characters, 
       
   880 */
       
   881 void CInternalHostResolver::GetHostName(TDes8& /*aNameBuf*/)
       
   882 {
       
   883 }
       
   884 
       
   885 //***********************************************************************
       
   886 
       
   887 /**
       
   888 Constructor.
       
   889 */
       
   890 CInternalNetDB::CInternalNetDB()
       
   891 {
       
   892 }
       
   893 
       
   894 /**
       
   895 Destructor.
       
   896 */
       
   897 CInternalNetDB::~CInternalNetDB()
       
   898 {
       
   899 	delete iNetDatabase;
       
   900 	if (iProtocol)
       
   901 		iProtocol->Close();
       
   902 }
       
   903 
       
   904 /**
       
   905 Create a new CInternalNetDB object
       
   906 */
       
   907 CInternalNetDB *CInternalNetDB::NewL()
       
   908 {
       
   909 	return new (ELeave) CInternalNetDB;
       
   910 }
       
   911 
       
   912 /**
       
   913 Opens a socket of the required type and protocol.
       
   914 @param aProtocolName A Protocol Name.
       
   915 @param aNotify		 A pointer to MResolverNotify object.
       
   916 @return KErrNone if succesfull otherwise any error code.
       
   917 */
       
   918 TInt CInternalNetDB::OpenL(const TDesC& aProtocolName,MResolverNotify *aEngine)
       
   919 {
       
   920 	// Assert a new net database
       
   921 	if (iState!=ENew)
       
   922 		return KErrAlreadyExists;
       
   923 	TInt err = KErrNone;
       
   924 	// Ensure protocol is loaded
       
   925 	TRAP(err, iProtocol = SocketServExt::FindAndLoadProtocolL(aProtocolName));
       
   926 	if (err!=KErrNone)
       
   927 		return err;
       
   928 	iProtocol->Open();
       
   929 	// Create the net database
       
   930 	TRAP(err, iNetDatabase = iProtocol->NewNetDatabaseL());
       
   931 	if (err!=KErrNone)
       
   932 		{
       
   933 		iProtocol->Close();
       
   934 		iProtocol = NULL;
       
   935 		return err;
       
   936 		}
       
   937 	// Set state to OPEN
       
   938 	iNetDatabase->SetNotify(this);
       
   939 	this->SetNotify(aEngine);
       
   940 	iState = EOpen;
       
   941 	return KErrNone;
       
   942 }
       
   943 
       
   944 /**
       
   945 Notifier call back from IrDA PRT
       
   946 This function is called when an operation querying the processing ability of a peer device 
       
   947 completes
       
   948 @param aError Error code.
       
   949 */
       
   950 void CInternalNetDB::QueryComplete(TInt aError)
       
   951 {
       
   952 	if (iBusy)
       
   953 		{
       
   954 		iBusy=EFalse;
       
   955 		iNotify->QueryComplete(aError);
       
   956 		}
       
   957 	// else we assume that it's an Add or Remove.
       
   958 }
       
   959 
       
   960 /**
       
   961 Remember that results are returned in this buffer too.
       
   962 Makes a query to the database
       
   963 @param aBuffer The query to perform 
       
   964 */
       
   965 TInt CInternalNetDB::Query(TDes8& aBuffer)
       
   966 {
       
   967 	if (iBusy)
       
   968 		return KErrInUse;
       
   969 	iBusy=ETrue;
       
   970 	iNetDatabase->Query(aBuffer);
       
   971 	return KErrNone;
       
   972 }
       
   973 
       
   974 /**
       
   975 Adds a record to the database
       
   976 @param aBuffer The record to add 
       
   977 */
       
   978 void CInternalNetDB::Add(TDes8& aBuffer)
       
   979 {
       
   980 	iNetDatabase->Add(aBuffer);
       
   981 }
       
   982 
       
   983 /**
       
   984 Removes a record from the database
       
   985 @param aBuffer The record to remove  
       
   986 */
       
   987 void CInternalNetDB::Remove(TDes8& aBuffer)
       
   988 {
       
   989 	iNetDatabase->Add(aBuffer);
       
   990 }
       
   991 
       
   992 //***********************************************************************
       
   993 
       
   994 /**
       
   995 Constructor.
       
   996 */
       
   997 CInternalSocketTimers::CInternalSocketTimers(CInternalSocket *aCIntSock)
       
   998 {
       
   999 	__DECLARE_NAME(_S("CInternalSocketTimers"));
       
  1000 	iInternalSocket=aCIntSock;
       
  1001 	iInternalSocketTimerH=NULL;	
       
  1002 }
       
  1003 
       
  1004 /**
       
  1005 Destructor.
       
  1006 */
       
  1007 CInternalSocketTimers::~CInternalSocketTimers()
       
  1008 {
       
  1009 	if (iInternalSocketTimerH)
       
  1010 		StopInternalSocketTimer();
       
  1011 }
       
  1012 
       
  1013 /**
       
  1014 Initialise the value of iInternalSocket for static member functions
       
  1015 @param aCIntSock A pointer to CInternalSocket object.
       
  1016 */
       
  1017 CInternalSocketTimers *CInternalSocketTimers::NewL(CInternalSocket *aCIntSock)
       
  1018 {
       
  1019 	return new (ELeave) CInternalSocketTimers(aCIntSock);
       
  1020 }
       
  1021 
       
  1022 /**
       
  1023 Invoked to start the Internal Socket timer
       
  1024 Can either complete as a call back to the
       
  1025 static CInternalSocket::InternalSocketTimerExpired or can cancel.
       
  1026 @param aCallBack Encapsulates a general call-back function.
       
  1027 @param aTimeout Time out period
       
  1028 */
       
  1029 void CInternalSocketTimers::StartInternalSocketTimer(TCallBack aCallBack,TInt aTimeout)
       
  1030 {
       
  1031 	if (iInternalSocketTimerH)
       
  1032 		StopInternalSocketTimer();
       
  1033 	iInternalSocketTimer.Set(aCallBack);
       
  1034 	iInternalSocketTimerH=&iInternalSocketTimer;
       
  1035 	IrlanTimer::Queue(aTimeout,iInternalSocketTimer);
       
  1036 }
       
  1037 
       
  1038 /**
       
  1039 Invoked to stop a previously queued Internal Socket timer
       
  1040 */
       
  1041 void CInternalSocketTimers::StopInternalSocketTimer()
       
  1042 {
       
  1043 	if (iInternalSocketTimerH)
       
  1044 		IrlanTimer::Remove(iInternalSocketTimer);
       
  1045 	iInternalSocketTimerH=NULL;
       
  1046 }
       
  1047 
       
  1048 void CInternalSocketTimers::DoInternalSocketTimerExpired()
       
  1049 { 
       
  1050 	iInternalSocketTimerH=NULL;
       
  1051 }
       
  1052 
       
  1053 
       
  1054 
       
  1055