www.pudn.com > Example_BluetoothChat.rar > BluetoothClient.cpp


/** 
* 
* @brief Definition of CBluetoothClient 
* 
* Copyright (c) EMCC Software Ltd 2003 
* @version 1.0 
*/ 
 
// System include 
#include  
 
// User include 
#include "BluetoothClient.h" 
#include "BluetoothDefinitions.h" 
#include "BluetoothObserver.h" 
 
/** 
* Constructor. 
* 
* Private - must use factory constructor 
* Set observer and flag to indicate not connected 
* Add this active object to the scheduler 
* 
* @see NewL 
* @param aObserver a reference to the "mix-in" class MBluetoothObserver. 
* 
**/ 
CBluetoothClient::CBluetoothClient(MBluetoothObserver& aObserver) 
: CActive(CActive::EPriorityStandard), 
  iObserver(aObserver), 
  iState(EDisconnected) 
	{ 
	CActiveScheduler::Add(this); 
	} 
 
/** 
* Destructor 
* 
* Cancel this active object, and disconnect the Client 
* 
**/ 
CBluetoothClient::~CBluetoothClient() 
	{ 
	Cancel(); 
	Disconnect(); 
	} 
 
 
/** 
* Factory Constructor. 
* Only available way to construct class. 
* This function can leave L 
* 
* @see ConstructL 
* @param  aObserver reference to the observer to notify 
* @return new instance of the CBluetoothClient 
*/ 
CBluetoothClient* CBluetoothClient::NewL(MBluetoothObserver& aObserver) 
	{ 
	CBluetoothClient* self = new (ELeave) CBluetoothClient(aObserver); 
	CleanupStack::PushL(self); 
	self->ConstructL(); 
	CleanupStack::Pop(self); 
	return self; 
	} 
 
 
/** 
* Second Stage Constructor. 
* This function can leave L 
* @param none 
* @see NewL 
* @see NewLC 
* @param none 
* @return none 
*/ 
void CBluetoothClient::ConstructL() 
	{ 
	} 
 
/** 
* Disconnect when tidying up this active object. 
* @param none 
* @return none 
**/ 
void CBluetoothClient::DoCancel() 
	{ 
	Disconnect(); 
	} 
 
/** 
* ConnectToServerL. 
* Set up Socket Address from the Bluetooth Address and Port number passed through as parameters. 
* Connect to Socket Server 
* Open a socket on the Server on the RFCOMM protocol (KServerTransportName) 
* Issue an asynchronous Connect on the socket, utilising the remote device address information 
* 
* @param aBTDevAddr address of the bluetooth device to connect to. 
* @param aPort the port to connect to on the device specified 
* @return none 
**/ 
void CBluetoothClient::ConnectToServerL(const TBTDevAddr& aBTDevAddr, const TInt aPort) 
	{ 
	iState = EConnecting; 
 
	iSocketAddress.SetBTAddr(aBTDevAddr); 
	iSocketAddress.SetPort(aPort); 
 
	User::LeaveIfError(iSocketServer.Connect()); 
	User::LeaveIfError(iSendingSocket.Open(iSocketServer, KServerTransportName)); 
 
	iSendingSocket.Connect(iSocketAddress, iStatus); 
 
#ifdef __WINS__ 
	User::After(1); // Fix to allow emulator client to connect to server 
#endif 
 
	SetActive(); 
	} 
 
/** 
* SendL. 
* 
* Issue an asynchronous Write on the socket, passing through the message to send 
* 
* @param aMessage the message to send 
* @return none 
**/ 
void CBluetoothClient::Send(const TDesC& aMessage) 
	{ 
	TRAPD(err, SendL(aMessage)); 
	} 
 
void CBluetoothClient::SendL(const TDesC& aMessage) 
	{ 
	iMessage.Zero(); 
	TDesBuf buffer;	 
	buffer.Set (iMessage); 
	 
	RWriteStream stream(&buffer); 
	CleanupClosePushL(stream); 
 
	stream << aMessage; 
	 
	CleanupStack::PopAndDestroy(); 
 
	iState = ESendData; 
	iSendingSocket.Write(iMessage, iStatus); 
	SetActive(); 
	} 
 
/** 
* RequestData. 
* 
* Issue an asynchronous receive function on the socket, passing through a buffer to be populated. 
* 
* @param none 
* @return none 
**/ 
void CBluetoothClient::RequestData() 
	{ 
	iMessage.Zero(); 
 
	iState = EWaitingForMessage; 
	iSendingSocket.RecvOneOrMore(iMessage, 0, iStatus, iLen); 
	SetActive(); 
	} 
 
/** 
* RunL 
* 
* Called when an asynchronous request completes. 
* iStatus variable indicates error conditions 
* iState indicates present state of the Client 
* 
* @param none 
* @return none 
**/ 
void CBluetoothClient::RunL() 
	{ 
	if (iStatus.Int() == KErrNone) 
		{ 
		switch (iState) 
			{ 
			case EConnecting: 
				{ 
				iObserver.ConnectedL(); 
				iState = EConnected; 
				break; 
				} 
 
			case EWaitingForMessage: 
				{ 
				iState = EConnected; 
 
				TDesBuf buffer;	 
				buffer.Set (iMessage); 
 
				RReadStream stream (&buffer); 
				CleanupClosePushL(stream); 
 
				TBuf rxBuf; 
 
				stream >> rxBuf; 
 
				CleanupStack::PopAndDestroy(); 
				 
				iObserver.DataReceivedL(rxBuf); 
				break; 
				} 
 
			case ESendData: 
				{ 
				RequestData(); 
				break; 
				} 
 
			default: 
				Panic(EInvalidClientState); 
				break; 
			} 
		} 
	else 
		{ 
		Disconnect(); 
		iObserver.HandleErrorL(iStatus.Int()); 
		} 
	} 
 
/** 
* Disconnect 
* 
* Cancel any outstanding requests. 
* Close the socket 
* Close the connection to the socket server 
* 
* @param none 
* @return none 
**/ 
void CBluetoothClient::Disconnect() 
	{ 
	if (iState != EDisconnected) 
		{ 
		iSendingSocket.CancelAll(); 
		iSendingSocket.Close(); 
		iSocketServer.Close(); 
		} 
 
	iState = EDisconnected; 
	} 
/** 
 * Returns connected state. 
 * 
 * @param none 
 * @retval boolean, true if client is connected. 
 */ 
TBool CBluetoothClient::IsConnected() 
	{ 
	return !(iState == EDisconnected); 
	} 
 
/** 
 * Returns information on connected state. 
 * 
 * @param none 
 * @retval boolean, true if the client is connected and can send data. 
 */ 
TBool CBluetoothClient::AvailableToSend() 
	{ 
	return (iState == EConnected); 
	}