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

📄 tcpipmultihomingexengine.cpp

📁 symbian 第二版
💻 CPP
字号:
/**
*
* @brief Definition of CTcpipMultiHomingExEngine
*
* Copyright (c) EMCC Software Ltd 2003
* @version 1.0
*/

// INCLUDE FILES

// Class include
#include "TcpipMultiHomingExEngine.h"

#include <eikgted.h>
#include <cdbcols.h>
#include <commdb.h>
#include <es_sock.h>
#include <eikenv.h>
#include <commdbconnpref.h>
#include <StringLoader.h>    // StringLoader
#include <TcpipMultiHomingEx.rsg>

#include "TcpipMultiHomingExAppui.h"
#include "TcpipMultiHomingExTimer.h"
#include "TcpipMultiHomingEx.pan"

const TInt KTextMaxLength = 30;
const TInt KTimeOut = 30000000; // 30 seconds time-out
const TInt KDefaultPortNumber = 13;

// default values to acces daytime server
_LIT(KDefaultServerName, "time-a.nist.gov");


CTcpipMultiHomingExEngine* CTcpipMultiHomingExEngine::NewL(MTcpipMultiHomingExEngineObserver& aObserver)
{
    CTcpipMultiHomingExEngine* self = CTcpipMultiHomingExEngine::NewLC(aObserver);
    CleanupStack::Pop(self);
    return self;
}


CTcpipMultiHomingExEngine* CTcpipMultiHomingExEngine::NewLC(MTcpipMultiHomingExEngineObserver& aObserver)
{
    CTcpipMultiHomingExEngine* self = new (ELeave) CTcpipMultiHomingExEngine(aObserver);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
}


CTcpipMultiHomingExEngine::CTcpipMultiHomingExEngine(MTcpipMultiHomingExEngineObserver& aObserver)
: CActive(EPriorityStandard),
  iObserver(aObserver),
  iPort(KDefaultPortNumber),
  iServerName(KDefaultServerName)
{
}


CTcpipMultiHomingExEngine::~CTcpipMultiHomingExEngine()
{
    iEngineStatus = EDestroyed;
    Cancel();

    delete iTimer;

    if (iSocketServ.Handle() != 0)
    {
        iSocketServ.Close();
    }
}


void CTcpipMultiHomingExEngine::ConstructL()
{
    ChangeStatus(ENotConnected);

    // Start a timer
    iTimer = CTcpipMultiHomingExTimer::NewL(EPriorityHigh, *this);
    CActiveScheduler::Add(this);

    // Open channel to Socket Server
    User::LeaveIfError(iSocketServ.Connect());
}


void CTcpipMultiHomingExEngine::ConnectL()
{
    // Initiate connection process
    if (iEngineStatus == ENotConnected)
    {

        //Open an RConnection on the Socket Server
        User::LeaveIfError(iRConn.Open(iSocketServ));

        // Start the Connection
        iRConn.Start(iStatus);
        ChangeStatus(ERConnStarting);
        iTimer->After(KTimeOut);
        SetActive();
    }
}


void CTcpipMultiHomingExEngine::ConnectL(TUint32 aAddr)
{
    // Initiate attempt to connect to a socket by IP address
    if (iEngineStatus == ENotConnected)
    {
        // Open a TCP socket
        User::LeaveIfError(iSocket.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, iRConn));

        // Set up address information
        iAddress.SetPort(iPort);
        iAddress.SetAddress(aAddr);

        // Initiate socket connection
        iSocket.Connect(iAddress, iStatus);
        ChangeStatus(EConnecting);

        // Start a timeout
        iTimer->After(KTimeOut);

        SetActive();
    }
}


void CTcpipMultiHomingExEngine::Disconnect()
{
    // cancel all outstanding operations
    Cancel();
    iSocket.Close();
    ChangeStatus(ENotConnected);
}


// from CActive
void CTcpipMultiHomingExEngine::DoCancel()
{
    iTimer->Cancel();

    TEngineState state = ENotConnected;
    // Cancel appropriate request to socket
    switch (iEngineStatus)
    {
        case EDestroyed:
            state = EDestroyed;
        case ENotConnected:
        case ERConnStarting:
        case EConnecting:
        case EConnected:
        case ELookingUp:
        case EReading:
            if (iRConn.SubSessionHandle() != 0)
            {
                iRConn.Close();
            }
            if (iResolver.SubSessionHandle() != 0)
            {
                iResolver.Cancel();
                iResolver.Close();
            }
              if (iSocket.SubSessionHandle() != 0)
            {
                iSocket.CancelAll();
                iSocket.Close();
            }
            break;
        default:
            User::Panic(KPanicTcpipMultiHomingExEngine, ETcpipMultiHomingExBadStatus);
            break;
    }

    ChangeStatus(state);
}


void CTcpipMultiHomingExEngine::Read()
{
    // Initiate read of data from socket
    if (iEngineStatus == EConnected)
    {
        // Initiate a new read from socket into iBuffer
        __ASSERT_ALWAYS(!IsActive(), User::Panic(KPanicTcpipMultiHomingExEngineRead, ETcpipMultiHomingExBadState));
        iSocket.RecvOneOrMore(iBuffer, 0, iStatus, iLength);
        ChangeStatus(EReading);
        SetActive();
    }
}


// from CActive
void CTcpipMultiHomingExEngine::RunL()
{
    // Active object request complete handler.
    // iEngineStatus flags what request was made, so its
    // completion can be handled appropriately
    iTimer->Cancel(); // Cancel TimeOut timer before completion

    switch(iEngineStatus)
    {

        case ERConnStarting:
            // need to look up name using dns
            // Initiate DNS
            User::LeaveIfError(iResolver.Open(iSocketServ, KAfInet, KProtocolInetUdp, iRConn));
            // DNS request for name resolution
            iResolver.GetByName(iServerName, iNameEntry, iStatus);

            ChangeStatus(ELookingUp);
            // Request time out
            iTimer->After(KTimeOut);
            SetActive();
            break;

        case ELookingUp:
            iResolver.Close();
            if (iStatus == KErrNone)
            {
                // DNS look up successful
                iNameRecord = iNameEntry();

                ChangeStatus(ENotConnected);
                ConnectL(TInetAddr::Cast(iNameRecord.iAddr).Address());
            }
            else
            {
                // DNS lookup failed
                Cancel();
                ReportErrorL(EDNSLookupFailed, iStatus.Int());
            }
            break;

        case EConnecting:
            // IP connection request
            if (iStatus == KErrNone)
                // Connection completed successfully
            {
                ChangeStatus(EConnected);
                // Get the time
                Read();
            }
            else
            {
                Cancel();
                ReportErrorL(EConnectionFailed, iStatus.Int());
            }
            break;
        case EReading:
        {
            switch (iStatus.Int())
            {
                case KErrNone:
                {
                    // Character has been read from socket
                    TBuf<KReadBufferSize> unicodeBuf;
                    unicodeBuf.Copy(iBuffer);
                    iObserver.ResponseReceivedL(unicodeBuf);
                    Disconnect();
                }
                    break;
                case KErrDisconnected:
                {
                    Cancel();
                    ReportErrorL(EDisconnected, iStatus.Int());
                }
                    break;
                default:
                {
                    Cancel();
                    ReportErrorL(EGeneralReadError,iStatus.Int());
                }
                    break;
            }
            break;
        }

        default:
            User::Panic(KPanicTcpipMultiHomingExEngine, ETcpipMultiHomingExBadStatus);
            break;

    };
}


void CTcpipMultiHomingExEngine::TimerExpiredL()
{
    Cancel();
    ReportErrorL(ETimedOut,KErrTimedOut);
}


void CTcpipMultiHomingExEngine::ReportErrorL(TErrorType aErrorType, TInt aErrorCode)
{
    // No recovery or retries are attempted in this example so we just
    // disconnect and inform the user
    Disconnect();
    TBuf<KTextMaxLength> text;

    switch (aErrorType)
    {
        case EDisconnected:
            StringLoader::Load(text, R_DISCONNECTED_TEXT);
            iObserver.ErrorL(text, aErrorCode);
            break;
        case EGeneralReadError:
            StringLoader::Load(text, R_READ_ERROR_TEXT);
            iObserver.ErrorL(text, aErrorCode);
            break;
        case EConnectionFailed:
            StringLoader::Load(text, R_CONN_FAILED_TEXT);
            iObserver.ErrorL(text, aErrorCode);
            break;
        case EDNSLookupFailed:
            StringLoader::Load(text, R_DNS_ERROR_TEXT);
            iObserver.ErrorL(text, aErrorCode);
            break;
        case ETimedOut:
            StringLoader::Load(text, R_TIMED_OUT);
            iObserver.ErrorL(text, KErrTimedOut);
            break;
        default:
            User::Panic(KPanicTcpipMultiHomingExEngine, ETcpipMultiHomingExBadStatus);
            break;
    }
}


void CTcpipMultiHomingExEngine::ChangeStatus(TEngineState aNewStatus)
{
    TBuf<KTextMaxLength> text;

    // Update the status (and the status display)
    switch (aNewStatus)
    {
        case ENotConnected:
            StringLoader::Load(text, R_NOT_CONNECTED_TEXT);
            iObserver.SetStatus(text);
            break;
        case ERConnStarting:
            StringLoader::Load(text, R_RCONNECTING_TEXT);
            iObserver.SetStatus(text);
            break;
        case EConnecting:
            StringLoader::Load(text, R_CONNECTING_TEXT);
            iObserver.SetStatus(text);
            break;
        case EConnected:
            StringLoader::Load(text, R_CONNECTED_TEXT);
            iObserver.SetStatus(text);
            break;
        case ELookingUp:
            StringLoader::Load(text, R_LOOKINGUP_TEXT);
            iObserver.SetStatus(text);
            break;
        case EReading:
            StringLoader::Load(text, R_READING_TEXT);
            iObserver.SetStatus(text);
            break;
        case EDestroyed:
            break;
        default:
            User::Panic(KPanicTcpipMultiHomingExEngine, ETcpipMultiHomingExBadStatus);
            break;
    }

    iEngineStatus = aNewStatus;
}

⌨️ 快捷键说明

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