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