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

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