📄 irsocketsengine.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 + -