⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irsocketsengine.cpp

📁 Symbian平台 套接字编程实例
💻 CPP
字号:
/**
*
* @brief Definition of CIrSocketsEngine
*
* Copyright (c) EMCC Software Ltd 2003
* @version 1.0
*/

// INCLUDE FILES

// Class include
#include "IrSocketsEngine.h"

// System includes
#include <e32def.h>
#include <aknnotewrappers.h>
#include <f32file.h>
#include <s32mem.h>

// User includes
#include "IrSocketsAppUi.h"

// Physical device driver names
#if defined (__WINS__)
_LIT (KPddName, "ECDRV");
#else
_LIT (KPddName, "EUART1");
#endif

// Logical device driver names
_LIT (KLddName, "ECOMM");

// Protocol to use
_LIT (KProtocol, "IrTinyTP");

// Port number
const TUint KPortNumber = 0x02;

// Number of devices to search for during discovery
const TUint KNumOfDevicesToDiscover = 1;

// Size of Listening Queue
const TUint KSizeOfListenQueue = 1;

// ================= MEMBER FUNCTIONS =======================

/**
* Symbian OS 2 phase constructor.
* Constructs the CIrSocketsEngine using the constructor and the ConstructL
* method.
* @param aPriority of the Active Object
* @param aAppUi for which the CIrSocketsEngine is constructed 
* @return The newly constructed CIrSocketsEngine
*/
CIrSocketsEngine* CIrSocketsEngine::NewL(MIrSocketsEngineObserver& aIrSocketsEngineObserver)
	{
	CIrSocketsEngine* self = new (ELeave) CIrSocketsEngine(aIrSocketsEngineObserver);
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

/**
* Destructor.
* Cancel any outstanding requests
*/
CIrSocketsEngine::~CIrSocketsEngine()
	{
	Cancel(); // This will close all subsessions

	// Close session on Sockets Server
    if (iSocketServer.Handle() != 0)
        {
        iSocketServer.Close();
        }
	}

/**
* constructor.
* */
CIrSocketsEngine::CIrSocketsEngine(MIrSocketsEngineObserver& aIrSocketsEngineObserver)
: CActive(0), iIrSocketsEngineObserver(aIrSocketsEngineObserver)
	{
	}

/**
* Symbian OS 2nd phase constructor.
* Set the inital state to Idle
* This adds the IrSocketsEngine active object to the active scheduler.
*/
void CIrSocketsEngine::ConstructL()
	{
	iState = EIdle;
	CActiveScheduler::Add(this);

	// Initialise connection to sockets server
	InitialiseL();
	}

/**
* Initialise method.
* Gets called when attempting a send or receive. If currently in receive mode and a send is requested,
* cancel the receive and set state to Idle.
* Load the physical and logical device drivers. Connect to the socket server.  
* Leve if any errors occur
* */
void CIrSocketsEngine::InitialiseL()
	{
	// If user attempts to send while in receive mode, cancel receive and set state to Idle
	if(iState == EAccepting)
		{
		Cancel();
		}

	// If in Idle state
	if(iState == EIdle)
		{
        // Connect to the socket server.
		TInt err = iSocketServer.Connect();
		if(err != KErrNone && err != KErrAlreadyExists)
			{
			User::Leave(err);
			}

		TUint numProtocols;
		// Number of protocols socket server is aware of
		err = iSocketServer.NumProtocols(numProtocols);
		User::LeaveIfError(err);
		
		// Find protocol by name and get description
		TProtocolName protocolName(KProtocol);
		err = iSocketServer.FindProtocol(protocolName, iProtocolInfo);
		User::LeaveIfError(err);
		}
	}

/**
* Open the socket
* */
void CIrSocketsEngine::OpenL()
	{
	TInt err;

	// Open socket
	err = iSocket.Open(iSocketServer, iProtocolInfo.iAddrFamily, iProtocolInfo.iSockType, iProtocolInfo.iProtocol);
	if(err != KErrNone && err != KErrAlreadyExists)
		{
		User::Leave(err);
		}
	}

/**
* Device discovery request function. 
* Search for IrDA device in range 
* */
void CIrSocketsEngine::DiscoverL()
	{
	TInt err;
	THostName hostname;

	// Set up socket for device discovery. Use 1 slot i.e search for 1 device.
	TPckgBuf<TUint> buf(KNumOfDevicesToDiscover);
	iSocket.SetOpt(KDiscoverySlotsOpt, KLevelIrlap, buf);

	// Open host resolver for device discovery
	err = iHostResolver.Open(iSocketServer, iProtocolInfo.iAddrFamily, iProtocolInfo.iProtocol);
	User::LeaveIfError(err);
	
	iState = EDiscovering;
	iHostResolver.GetByName(hostname, iNameEntry, iStatus);
	SetActive();
	}

/**
* Connect request function
* Connect to remote host
* */
void CIrSocketsEngine::ConnectL()
	{
	if(iState == EDiscovered)
		{
		iIrdaSockAddr.SetPort(KPortNumber);
		iState = EConnecting;
		iSocket.Connect(iIrdaSockAddr, iStatus);	
		SetActive();
		}
	}

/**
* Transmit request function
* The data specified in the aData parameter is first copied to the iSendBuffer member and then 
* sent to socket.
* @param aData is the data to be copied to the local tbuf and then sent to socket. 
* */
void CIrSocketsEngine::SendL(const TDesC& aData)
	{
	if (iState == ESending)
		{
		// Create a TDesBuf referring to iSendBuffer.
		// This will allow us to create a stream to stream data
		// into iSendBuffer.
		TDesBuf buffer;	
		buffer.Set(iSendBuffer);

		// Create a write stream
		RWriteStream stream(&buffer);
		CleanupClosePushL(stream);

		// Stream aData (the 16-bit descriptor argument)
		// into iSendBuffer
		stream << aData;
		
		// Clean up the stream
		CleanupStack::PopAndDestroy();

		// Now write the 8-bit descriptor iSendBuffer to the socket.
		// On the reading side this can then be read in, then
		// the 16-bit descriptor internalised from the 8-bit buffer.
		iSocket.Write(iSendBuffer, iStatus);
		SetActive();
		}
	}


/**
* Configure receiver.
* Create listener socket and bind it locally to listen for sender. 
* 
* */
void CIrSocketsEngine::ConfigureReceiverL()
	{
	// Set port
	iIrdaSockAddr.SetPort(KPortNumber);
	// Bind socket locally and set up listening queue on socket
	iSocket.Bind(iIrdaSockAddr);
	// Listen for connection from sender
	iSocket.Listen(KSizeOfListenQueue);
	// Create blank socket
	iServiceSocket.Open(iSocketServer);

	// Issue an accept
	iSocket.Accept(iServiceSocket, iStatus);
	iState = EAccepting;
	SetActive();
	}

/**
* Receive request function
* Receives data from remote host into local buffer
* */
void CIrSocketsEngine::ReceiveL()
	{
	if(iState == EAccepted)
		{
		iRecvBuffer.Zero();
		iState = EReceiving;
		iServiceSocket.Read(iRecvBuffer, iStatus);
		SetActive();
		}
	}

/**
* Cancel receive mode 
* */
void CIrSocketsEngine::CancelReceiveL()
	{
	Cancel();
	}

/**
* Cancel all requests and close socket. Close session with socket server.
* */
void CIrSocketsEngine::CloseSubSessions()
	{
    // Cancel and close host resolver
    if (iHostResolver.SubSessionHandle() != 0)
        {
        iHostResolver.Cancel();
        iHostResolver.Close();
        }

    // Cancel and close service socket
    if (iServiceSocket.SubSessionHandle() != 0)
        {
        iServiceSocket.CancelAll();
        iServiceSocket.Close();
        }

    // Cancel and close main socket
	if (iSocket.SubSessionHandle() != 0)
        {
        iSocket.CancelAll();
	    iSocket.Close();
        }

	// Set state to idle
	iState = EIdle;
	}

/**
* The Active object's request complete event.
* 
* */
void CIrSocketsEngine::RunL()
	{
	TInt status = iStatus.Int();

	switch (iState)
		{
		case EDiscovering:
			if(status == KErrNone) // Discover requested ok
				{
				iState = EDiscovered;
				iHostResolver.Close();
				// Store remote device address
				iIrdaSockAddr = TIrdaSockAddr(iNameEntry().iAddr);
				ConnectL();
				}
			else // Discover request failed
				{
				iIrSocketsEngineObserver.DisplayNoDevicesDiscoveredNoteL();
				CloseSubSessions();
				}
			break;

		case EConnecting:
			if(status == KErrNone) // Connect requested ok
				{
				//iState = EConnected;
				iState = ESending;
				iIrSocketsEngineObserver.ReadyToSendL();
				}
			else // Connect request failed
				{
				CloseSubSessions();
				}
			break;

		case ESending: // Send request ok
			iIrSocketsEngineObserver.DisplaySendResultNoteL(status);
			CloseSubSessions();
			break;

		case EAccepting:
			if(status == KErrNone) // Accept request ok
				{
				iState = EAccepted;
				ReceiveL(); 
				}
			else // Accept request failed
				{
				CloseSubSessions();
				}
			break;

		case EReceiving:
			if(status == KErrNone) // Receive request ok
				{
				iState = EReceived;

				// Create a TDesBuf object referring to iRecvBuffer
				TDesBuf desBuf;	
				desBuf.Set(iRecvBuffer);

				// Open a stream on iRecvBuffer using desBuf
				RReadStream stream(&desBuf);
				CleanupClosePushL(stream);

				// Stream the data into a Unicode buffer
				TBuf<EFormEdwinMaxLength> unicodeBuffer;
				stream >> unicodeBuffer;

				// Clean up the stream
				CleanupStack::PopAndDestroy();

				// Pass the Unicode descriptor to the UI
				iIrSocketsEngineObserver.DisplayReceivedDataL(unicodeBuffer);

				// Done reading, so close socket & other subsessions
				CloseSubSessions();
				}
			else // Receive request failed
				{
				CloseSubSessions();
				}
			break;

		default:
			break;
		}
	}

/**
* Cancel any pending operations.
* */
void CIrSocketsEngine::DoCancel()
	{
    CloseSubSessions();
	}

TBool CIrSocketsEngine::Accepting() const
    {
    return (iState == EAccepting);
    }


void CIrSocketsEngine::PrepareForSendingL()
	{
	OpenL();
	DiscoverL();
	}


void CIrSocketsEngine::PrepareForReceivingL()
	{
	OpenL();
	ConfigureReceiverL();
	}



// End of File

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -