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

📄 messageclient.cpp

📁 Symbian下的p2p工程
💻 CPP
字号:
/* Copyright (c) 2004, Nokia. All rights reserved */


// INCLUDE FILES
#include <StringLoader.h>
#include <BTPointToPoint.rsg>
#include <coemain.h>

#include "MessageClient.h"
#include "MessageServiceSearcher.h"
#include "BTPointToPoint.pan"
#include "Log.h"

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

// ----------------------------------------------------------------------------
// CMessageClient::NewL()
// Two-phased constructor.
// ----------------------------------------------------------------------------
//
CMessageClient* CMessageClient::NewL( MLog& aLog )
    {
    CMessageClient* self = NewLC( aLog );
    CleanupStack::Pop( self );
    return self;
    }

// ----------------------------------------------------------------------------
// CMessageClient::NewLC()
// Two-phased constructor.
// ----------------------------------------------------------------------------
//
CMessageClient* CMessageClient::NewLC( MLog& aLog )
    {
    CMessageClient* self = new ( ELeave ) CMessageClient( aLog );
    CleanupStack::PushL( self );
    self->ConstructL ();
    return self;

    }

// ----------------------------------------------------------------------------
// CMessageClient::CMessageClient()
// Constructor.
// ----------------------------------------------------------------------------
//
CMessageClient::CMessageClient( MLog& aLog )
: CActive( CActive::EPriorityStandard ),
  iState( EWaitingToGetDevice ),
  iLog( aLog )
    {
    CActiveScheduler::Add( this );
    }

// ----------------------------------------------------------------------------
// CMessageClient::~CMessageClient()
// Destructor.
// ----------------------------------------------------------------------------
//
CMessageClient::~CMessageClient()
    {

    // Close() will wait forever for Read to complete
    if ( iState == EConnected )
    {
        iSendingSocket.CancelRead();
    }
    Cancel();

    iSendingSocket.Close();
    iSocketServer.Close();

    delete iMessage;
    iMessage = NULL;

    delete iServiceSearcher;
    iServiceSearcher = NULL;
    }

// ----------------------------------------------------------------------------
// CMessageClient::ConstructL()
// Perform second phase construction of this object.
// ----------------------------------------------------------------------------
//
void CMessageClient::ConstructL()
    {
    // Create 16-bit localized string containing the data to send
    HBufC* tempString = CCoeEnv::Static()->
                                    AllocReadResourceLC( R_BTPO_HELLO_MESSAGE );
    // Create 8-bit member variable which will be used for
    // sending the data over the bluetooth socket
    iMessage = HBufC8::NewL(tempString->Length());
    // Convert 16 bit => 8 bit by copying the 16-bit localized string to the 
    // 8-bit member variable. This will simply slice off the higher order bytes,
    // which is ok in this example.
    iMessage->Des().Copy(*tempString);
    CleanupStack::PopAndDestroy(); // tempString

    iServiceSearcher = CMessageServiceSearcher::NewL( iLog );
    User::LeaveIfError( iSocketServer.Connect() );
    }

// ----------------------------------------------------------------------------
// CMessageClient::DoCancel()
// Cancel any outstanding requests.
// ----------------------------------------------------------------------------
//
void CMessageClient::DoCancel()
    {
    // no implementation required
    }

// ----------------------------------------------------------------------------
// CMessageClient::RunL()
// Respond to an event.
// ----------------------------------------------------------------------------
//
void CMessageClient::RunL()
    {
	HBufC* textResource = NULL;
    if ( iStatus != KErrNone )
        {
        switch ( iState )
            {
            case EGettingDevice:
                if ( iStatus == KErrCancel )
                    {
                    textResource = StringLoader
                        ::LoadLC( R_BTPO_ERR_NO_DEVICE_SELECTED );
                    iLog.LogL( *textResource );
                    CleanupStack::PopAndDestroy( textResource );
                    }
                iState = EWaitingToGetDevice;
                break;
            case EGettingService:
            case EGettingConnection:
                textResource = StringLoader
                    ::LoadLC( R_BTPO_ERR_CONNECTION_ERROR );
                iLog.LogL( *textResource, iStatus.Int() );
                CleanupStack::PopAndDestroy( textResource );
                iState = EWaitingToGetDevice;
                break;
            case EConnected:
                textResource = StringLoader
                    ::LoadLC( R_BTPO_ERR_LOST_CONNECTION );
                iLog.LogL( *textResource, iStatus.Int() );
                DisconnectFromServerL();
                CleanupStack::PopAndDestroy( textResource );
                iState = EDisconnecting;
                break;
            case ESendingMessage:
                textResource = StringLoader
                    ::LoadLC( R_BTPO_ERR_MESSAGE_FAILED );
                iLog.LogL( *textResource, iStatus.Int() );
                CleanupStack::PopAndDestroy( textResource );
                DisconnectFromServerL();
                iState = EDisconnecting;
                break;
            case EDisconnecting:
                if ( iStatus == KErrDisconnected )
                {
                    textResource = StringLoader
                        ::LoadLC( R_BTPO_DISCONNECT_COMPLETE );
                    iLog.LogL( *textResource, iStatus.Int() );
                    CleanupStack::PopAndDestroy( textResource );

                    iSendingSocket.Close();
                    iState = EWaitingToGetDevice;
                }
                else
                {
                    textResource = StringLoader
                        ::LoadLC( R_BTPO_ERR_FAILED_TO_DISCONNECT );
                    iLog.LogL( *textResource, iStatus.Int() );
                    CleanupStack::PopAndDestroy( textResource );

                    Panic( EBTPointToPointUnableToDisconnect );
                }
                break;
            default:
                Panic( EBTPointToPointInvalidLogicState );
                break;
            }
        }
    else 
        {
        switch ( iState )
            {
            case EGettingDevice:
                // found a device now search for a suitable service
                iLog.LogL( iServiceSearcher->ResponseParams().DeviceName() );
                iState = EGettingService;
                iStatus = KRequestPending;  // this means that the RunL 
                                            // can not be called until
                                            // this program does something 
                                            // to iStatus
                iServiceSearcher->FindServiceL( iStatus );
                SetActive();
                break;
            case EGettingService:
                textResource = StringLoader
                    ::LoadLC( R_BTPO_FOUND_SERVICE );
                iLog.LogL( *textResource );
                CleanupStack::PopAndDestroy( textResource );
                iState = EGettingConnection;
                ConnectToServerL();
                break;
            case EGettingConnection:
                textResource = StringLoader
                    ::LoadLC( R_BTPO_CONNECTED );
                iLog.LogL( *textResource );
                CleanupStack::PopAndDestroy( textResource );

                iState = EConnected;
                // Catch disconnection event 
                // By waiting to read socket
                WaitOnConnectionL();
                break;
            case EConnected:
                textResource = StringLoader
                    ::LoadLC( R_BTPO_DATA_RECEIVED );
                iLog.LogL( *textResource );
                CleanupStack::PopAndDestroy( textResource );

                // Just dump data
                iDummyBuffer.Zero();
                // Catch disconnection event 
                // By waiting to read socket
                WaitOnConnectionL();
                break;
            case ESendingMessage:
                textResource = StringLoader
                    ::LoadLC( R_BTPO_SENT_MESSAGE );
                iLog.LogL( *textResource );
                CleanupStack::PopAndDestroy( textResource );

                iState = EConnected;
                // Catch disconnection event 
                // By waiting to read socket
                WaitOnConnectionL();
                break;
            case EDisconnecting:
                textResource = StringLoader
                    ::LoadLC( R_BTPO_DISCONNECT_COMPLETE );
                iLog.LogL( *textResource );
                CleanupStack::PopAndDestroy ( textResource );

                iSendingSocket.Close();
                iState = EWaitingToGetDevice;
                break;
            default:
                Panic( EBTPointToPointInvalidLogicState );
                break;
            };
        }
    }

// ----------------------------------------------------------------------------
// CMessageClient::ConnectL()
// Connect to a service.
// ----------------------------------------------------------------------------
//
void CMessageClient::ConnectL()
    {
    if ( iState == EWaitingToGetDevice && !IsActive() )
        {
        iState = EGettingDevice;
        iServiceSearcher->SelectDeviceByDiscoveryL( iStatus );
        SetActive();
        }
    else
        {
        HBufC* errClientBusy = StringLoader::LoadLC ( R_BTPO_CLIENT_BUSY );
        iLog.LogL( *errClientBusy );
        CleanupStack::PopAndDestroy( errClientBusy );

        User::Leave( KErrInUse );
        }
    }

// ----------------------------------------------------------------------------
// CMessageClient::DisconnectL()
// Disconnects from the remote machine.
// ----------------------------------------------------------------------------
//
void CMessageClient::DisconnectL()
    {
    if ( ( iState == EConnected )||( iState == ESendingMessage ) )
        {
            DisconnectFromServerL();
            iState = EDisconnecting;
        }
    else
        {
            HBufC* errNoConn = StringLoader::LoadLC ( R_BTPO_ERR_NO_CONN );
            iLog.LogL( *errNoConn );
            CleanupStack::PopAndDestroy( errNoConn );
            User::Leave( KErrDisconnected );
        }
    }

// ----------------------------------------------------------------------------
// CMessageClient::DisconnectFromServerL()
// Disconnects from the service
// ----------------------------------------------------------------------------
//
void CMessageClient::DisconnectFromServerL()
    {
    // Terminate all operations
    iSendingSocket.CancelAll();
    Cancel();

    HBufC* strReleasingConn = StringLoader
        ::LoadLC ( R_BTPO_STR_RELEASING_CONN );
    iLog.LogL( *strReleasingConn );
    CleanupStack::PopAndDestroy( strReleasingConn );
    iSendingSocket.Shutdown( RSocket::ENormal,iStatus );
    SetActive();
    }

// ----------------------------------------------------------------------------
// CMessageClient::ConnectToServerL()
// Connect to the server.
// ----------------------------------------------------------------------------
//
void CMessageClient::ConnectToServerL()
    {
    HBufC* strConnecting = StringLoader
        ::LoadLC ( R_BTPO_STR_CONNECTING );
    iLog.LogL( *strConnecting );
    CleanupStack::PopAndDestroy( strConnecting );

    User::LeaveIfError( iSendingSocket.Open( iSocketServer, KStrRFCOMM ) );

    TBTSockAddr address;
    address.SetBTAddr( iServiceSearcher->BTDevAddr() );
    address.SetPort( iServiceSearcher->Port() );

    iSendingSocket.Connect( address, iStatus );

#ifdef __WINS__
    User::After( 1 );     // Fix to allow emulator client to connect to server
#endif

    SetActive();
    }

// ----------------------------------------------------------------------------
// CMessageClient::WaitOnConnectionL()
// Wait for data or disconnection.
// ----------------------------------------------------------------------------
//
void CMessageClient::WaitOnConnectionL()
    {
    if ( iState != EConnected )
        {
        User::Leave( KErrDisconnected );
        }
        iSendingSocket.Read( iDummyBuffer, iStatus );
        SetActive();
    }

// ----------------------------------------------------------------------------
// CMessageClient::SendMessageL()
// Send a message to a service on a remote machine.
// ----------------------------------------------------------------------------
//
void CMessageClient::SendMessageL()
    {
    if ( iState != EConnected )
        {
        User::Leave( KErrDisconnected );
        }

    // Stop reading socket
    iSendingSocket.CancelRead();
    if ( IsActive() )
    {
        Cancel();
    }
    iState = ESendingMessage;
    iSendingSocket.Write( *iMessage, iStatus );
    SetActive();
    }

// ----------------------------------------------------------------------------
// CMessageClient::IsReadyToSendMessage()
// True if the client can send a message.
// ----------------------------------------------------------------------------
//
TBool CMessageClient::IsReadyToSendMessage()
    {
    return ( iState == EConnected );
    }

// ----------------------------------------------------------------------------
// CMessageClient::IsConnected()
// True if the client can send a message.
// ----------------------------------------------------------------------------
//
TBool CMessageClient::IsConnected()
    {
    return ( ( iState == EConnected )||( iState == ESendingMessage ) );
    }

// ----------------------------------------------------------------------------
// CMessageClient::IsConnecting()
// True if the client is establishing a connection to the server.
// ----------------------------------------------------------------------------
//
TBool CMessageClient::IsConnecting()
    {
    return ( ( iState == EGettingDevice )
            ||
            ( iState == EGettingService )
            ||
            ( iState == EGettingConnection ) );
    }

// ----------------------------------------------------------------------------
// CMessageClient::IsSendingMessage()
// True if the client is connected.
// ----------------------------------------------------------------------------
//
TBool CMessageClient::IsSendingMessage()
    {
    return ( iState == ESendingMessage );
    }

// End of File

⌨️ 快捷键说明

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