www.pudn.com > Bluetooth_PMP_Example_v1_0.zip > Listener.cpp


/* 
* ============================================================================ 
*  Name     : CListener from Listener.h 
*  Part of  : BluetoothPMPExample 
*  Created  : 14.01.2004 by Forum Nokia 
*  Implementation notes: 
*     Initial content was generated by Series 60 AppWizard. 
*  Version  : 
*  Copyright: Nokia Corporation 
* ============================================================================ 
*/ 
 
// INCLUDE FILES 
#include "Listener.h" 
 
 
CListener* CListener::NewL(MListenerObserver* aObserver,  
						   RSocketServ *aSocketServ) 
	{ 
	CListener* self = CListener::NewLC(aObserver, aSocketServ); 
    CleanupStack::Pop(self); 
	return self; 
	} 
 
 
CListener* CListener::NewLC(MListenerObserver* aObserver, 
							RSocketServ *aSocketServ) 
	{ 
	CListener* self = new (ELeave) CListener(aObserver, aSocketServ); 
	CleanupStack::PushL(self); 
	self->ConstructL(); 
	return self; 
	} 
 
 
void CListener::ConstructL() 
	{ 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::CListener(MListernetObserver* aObserver, 
//						RSocketServ *aSocketServ) 
// 
// constructor 
// ---------------------------------------------------------------------------- 
CListener::CListener(MListenerObserver* aObserver,  
					 RSocketServ *aSocketServ): 
	CActive(CActive::EPriorityStandard), 
	iObserver(aObserver), 
	iSocketServ(aSocketServ), 
	iIsConnected(EFalse), 
	iState(ENone) 
	{ 
	CActiveScheduler::Add(this); 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::~CListener() 
// 
// destructor 
// ---------------------------------------------------------------------------- 
CListener::~CListener() 
	{ 
	// cancel active object 
	Cancel(); 
	// close sockets 
	StopListenerL(); 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::StartListenerL() 
// 
// start listener.  listener will open a listening socket on a channel (port) 
// gotten from GetOpt() call.   
// ---------------------------------------------------------------------------- 
TInt CListener::StartListenerL() 
	{ 
	// get out if we're already running.. 
	if ( iState!=ENone ) 
		return -1; 
 
	// set this active object to connecting state 
	iState=EConnecting; 
 
	// load protocol, RFCOMM 
	TProtocolDesc pdesc; 
	User::LeaveIfError(iSocketServ->FindProtocol(_L("RFCOMM"), pdesc)); 
 
	// open a socket 
	iListenSock.Open(*iSocketServ,pdesc.iAddrFamily,pdesc.iSockType,KRFCOMM); 
 
	// get listening channel 
	TInt channel; 
    User::LeaveIfError(iListenSock.GetOpt(KRFCOMMGetAvailableServerChannel,  
		KSolBtRFCOMM, channel)); 
 
	// bluetooth socket address object 
	TBTSockAddr btsockaddr; 
	btsockaddr.SetPort(channel); 
	// bind socket 
	User::LeaveIfError(iListenSock.Bind(btsockaddr)); 
	// listen on port 
	iListenSock.Listen(5); 
 
	// set channel security 
	SetSecurityL(channel); 
 
	// close old accepted socket if open 
	iSock.Close(); 
 
	// open blank socket and pass it to accept to be assigned a proper 
	// socket upon completion of Accept() 
	User::LeaveIfError(iSock.Open(*iSocketServ)); 
 
	// set to accept incoming connections, active object will handle 
	iListenSock.Accept(iSock,iStatus); 
	SetActive(); 
	 
	return channel; 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::SetSecurityL(TInt aChannel) 
// 
// sets the security of given bluetooth channel.  these settings will turn 
// off authentication, authorisation and encryption on given channel. 
// ---------------------------------------------------------------------------- 
void CListener::SetSecurityL(TInt aChannel) 
	{ 
	// setup channel security 
	TRequestStatus status; 
    RBTMan secManager; 
    RBTSecuritySettings secDatabase; 
	TBTServiceSecurity secSettings; 
	// connect to security manager 
	User::LeaveIfError(secManager.Connect()); 
    CleanupClosePushL(secManager); 
	User::LeaveIfError(secDatabase.Open(secManager)); 
    CleanupClosePushL(secDatabase); 
	// setup security 
	TUid settingsUID; 
	settingsUID.iUid = KBT_serviceID; 
	secSettings.SetUid(settingsUID); 
	secSettings.SetChannelID(aChannel); 
	secSettings.SetProtocolID(KSolBtRFCOMM); 
	secSettings.SetAuthentication(EFalse); 
	secSettings.SetAuthorisation(EFalse); 
	secSettings.SetEncryption(EFalse); 
	// register settings with security 
	secDatabase.RegisterService(secSettings, status); 
	User::WaitForRequest(status); 
    CleanupStack::PopAndDestroy();  //  secManager 
    CleanupStack::PopAndDestroy();  //  secSettings	 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::StopListenerL() 
// 
// stops the listener by closing the listening socket 
// ---------------------------------------------------------------------------- 
void CListener::StopListenerL() 
	{ 
	// kill sockets 
	if ( iState!=ENone ) 
		{		 
		iSock.Close(); 
		iListenSock.Close(); 
		iState=ENone; 
		} 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::ReceiveData() 
// 
// receive more data from listening socket, asynchronously.   
// ---------------------------------------------------------------------------- 
void CListener::ReceiveData() 
    { 
	// set state to waiting - for RunL() 
    iState = EWaiting; 
	// make async request 
	iSock.RecvOneOrMore(iBuffer, 0, iStatus, iLen); 
	// set as active to get the async req response (iState) in RunL() 
    SetActive(); 
    } 
 
 
// ---------------------------------------------------------------------------- 
// CListener::SendDataL(const TDesC8& aData) 
// 
// send data to remote device, write data to socket. 
// ---------------------------------------------------------------------------- 
void CListener::SendDataL(const TDesC8& aData) 
	{ 
	if ( iState!=EWaiting ) 
		return; 
	// cancel any read requests on socket 
	Cancel(); 
	// try to send message by writing to socket 
	// - set the state of this active object to "sending" 
	iState=ESending; 
	// - make async socket write request 
	iSock.Write(aData, iStatus); 
	// - start waiting async req response (iState) from active scheduler 
	SetActive(); 
	} 
 
 
void CListener::RunL() 
	{ 
	if ( iStatus==KErrDisconnected ) 
		{ 
		StopListenerL(); 
		HandleListenerDisconnectedL(); 
		} 
 
	if ( iStatus!=KErrNone ) 
		return; 
	 
	switch (iState) 
		{ 
        case EConnecting: 
			{ 
            // connected listening socket! 
			HandleListenerConnectedL(); 
            ReceiveData(); 
            break; 
			} 
        case EWaiting: 
            { 
			// returned from receiving data 
			if(iState!=KErrNone) 
				{ 
					// add the error handling / re-reading code here.. 
					// not needed in this example 
				} 
 
            HBufC* text = HBufC::NewLC(iBuffer.Length()); 
            text->Des().Copy(iBuffer); 
			// observer will handle data 
			HandleListenerDataReceivedL(*text); 
            CleanupStack::PopAndDestroy(text); 
			// start expecting next data to be read 
			ReceiveData(); 
            break; 
			} 
		case ESending: 
			{ 
			// returned from sending the date, check the state 
			if(iState!=KErrNone) 
				{ 
					// add the error handling / re-sending code here.. 
					// not needed in this example 
				} 
 
			// start expecting next data to be read 
			ReceiveData(); 
			break; 
			} 
        default: 
            break; 
        } 
	} 
 
 
void CListener::DoCancel() 
	{ 
	// cancel all pending socket operations 
	iSock.CancelAll(); 
	iListenSock.CancelAll(); 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::IsConnected() 
// 
// returns true if listener has been connected to 
// ---------------------------------------------------------------------------- 
TBool CListener::IsConnected() 
	{ 
	return iIsConnected; 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::HandleListenerDataReceivedL(TDesC& aData) 
// 
// a callback to observer indicating that listener has received data 
// ---------------------------------------------------------------------------- 
void CListener::HandleListenerDataReceivedL(TDesC& aData) 
	{ 
	iObserver->HandleListenerDataReceivedL(aData); 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::HandleListenerConnectedL() 
// 
// a callback to observer indicating that listener has been connected to 
// ---------------------------------------------------------------------------- 
void CListener::HandleListenerConnectedL() 
	{ 
	iIsConnected=ETrue; 
	iObserver->HandleListenerConnectedL(); 
	} 
 
 
// ---------------------------------------------------------------------------- 
// CListener::HandleListenerDisconnectedL() 
// 
// a callback to observer indicating that listener has been disconnected 
// ---------------------------------------------------------------------------- 
void CListener::HandleListenerDisconnectedL() 
	{ 
	iIsConnected=EFalse; 
	iObserver->HandleListenerDisconnectedL(); 
	}