www.pudn.com > ExampleBluetoothChat.rar > BluetoothServiceSearcher.cpp


/** 
* 
* @brief Definition of CBluetoothServiceSearcher 
* 
* Copyright (c) EMCC Software Ltd 2003 
* @version 1.0 
*/ 
 
// System includes 
#include  
#include  
 
// User includes 
#include "BluetoothDefinitions.h" 
#include "BluetoothServiceSearcher.h" 
#include "TBluetoothAttributeParser.h" 
 
/** 
* Factory Constructor. 
* Only available way to construct class. 
* This function can leave L, returning value is on Cleanup Stack C 
* @param aPort pass by reference integer which will be populated with the correct port number. 
* @return new instance of the CBluetoothServiceSearcher on Cleanup stack 
*/ 
CBluetoothServiceSearcher* CBluetoothServiceSearcher::NewLC(TInt& aPort) 
	{ 
	CBluetoothServiceSearcher* self = new (ELeave) CBluetoothServiceSearcher(aPort); 
	CleanupStack::PushL(self); 
	self->ConstructL(); 
	return self; 
	} 
/** 
* Factory Constructor. 
* Only available way to construct class. 
* This function can leave L 
* @param aPort pass by reference integer which will be populated with the correct port number. 
* @return new instance of the CBluetoothServiceSearcher 
*/ 
CBluetoothServiceSearcher* CBluetoothServiceSearcher::NewL(TInt& aPort) 
	{ 
	CBluetoothServiceSearcher* self = CBluetoothServiceSearcher::NewLC(aPort); 
	CleanupStack::Pop( self ); 
	return self; 
	} 
 
/** 
* Constructor. 
* 
* Pass through Port variable to be populated, and initialise the Searcher State to be Not Found. 
* private constructor 
* 
* @see NewL 
* @see NewLC 
* 
* @param aPort to be populated with the port available port number. 
* @returns none 
**/ 
CBluetoothServiceSearcher::CBluetoothServiceSearcher(TInt& aPort) 
: iPort(aPort),iSearcherState(KErrNotFound) 
  	{ 
	} 
 
/** 
* Destructor 
* 
* Pass through Port variable to be populated, and initialise the Searcher State to be Not Found 
* Delete the Service Discovery Protocol Agent, Search Pattern, Match List and Progress Dialog 
* @param none 
* @return none 
**/ 
CBluetoothServiceSearcher::~CBluetoothServiceSearcher() 
	{ 
	if (iAgent) 
		{ 
		delete iAgent; 
		iAgent = NULL; 
		} 
 
	delete iSdpSearchPattern; 
	iSdpSearchPattern = NULL; 
 
	delete iMatchList; 
	iMatchList = NULL; 
 
	delete iWaitDialog; 
	iWaitDialog = NULL; 
	} 
 
/** 
* ConstructL - Second Stage constructor. 
* 
* Create and prepare the Search Pattern to be used in finding Service Records 
* Create and prepare the Match List to be used in finding attributes of Service Records 
* 
* @see NewL 
* @see NewLC 
* @param none 
* @return none 
**/ 
void CBluetoothServiceSearcher::ConstructL() 
	{ 
	iSdpSearchPattern = CSdpSearchPattern::NewL(); 
	iSdpSearchPattern->AddL( KServiceClass ); 
 
	iMatchList = CSdpAttrIdMatchList::NewL(); 
	iMatchList->AddL( KSdpAttrIdServiceAvailability ); // Availability 
	iMatchList->AddL( KSdpAttrIdProtocolDescriptorList ); // Port Number, RFCOMM, L2CAP 
	} 
 
/** 
* Close. 
* 
* Public function for closing down the Searcher 
* 
* @param none 
* @return none 
**/ 
void CBluetoothServiceSearcher::CloseL() 
	{ 
	RemoveProgressDialogL(); 
	} 
 
/** 
* Find a Service. 
* 
* Create a new Service Discovery Protocol Agent, add a Search Pattern to it and request the next record that matches the 
* Search Pattern. 
* Display a progress dialog, so that the process may be cancelled by the User 
* 
* @param aDeviceAddress the address of the device to search for services on 
* @return TInt returns the current serarcher state 
**/ 
TInt CBluetoothServiceSearcher::FindServiceL(const TBTDevAddr& aDeviceAddress) 
	{ 
	delete iAgent; 
	iAgent = NULL; 
 
	iAgent = CSdpAgent::NewL(*this, aDeviceAddress); 
	iAgent->SetRecordFilterL(*iSdpSearchPattern); 
	iAgent->NextRecordRequestL(); 
	DisplayProgressDialogL(); 
 
	return iSearcherState; 
	} 
 
/** 
* Progress Dialog. 
* 
* Dialog visible whilst searching for a service. This is a modal dialog, so execution waits in the ExecuteLD call. 
* Execution continues when the user cancels the dialog via Softkey, or the Service search completes 
* 
* @param none 
* @return none 
**/ 
void CBluetoothServiceSearcher::DisplayProgressDialogL() 
	{ 
	if (!iWaitDialog) 
		{ 
		iWaitDialog = new (ELeave) CAknWaitDialog(NULL, ETrue); 
		TInt retVal = iWaitDialog->ExecuteLD(R_BLUETOOTH_CONNECTION_WAIT_DIALOG); 
		iWaitDialog = NULL; 
 
		if (retVal != EAknSoftkeyDone) 
			{ 
			iSearcherState = KErrCancel; 
			} 
		} 
	} 
 
/** 
* Remove Progress Dialog. 
* 
* Makes waiting dialog stop waiting via call to ProcessFinishedL 
* 
* @param none 
* @return none 
**/ 
void CBluetoothServiceSearcher::RemoveProgressDialogL() 
	{ 
	if (iWaitDialog) 
		{ 
		iWaitDialog->ProcessFinishedL(); 
		iWaitDialog = NULL; 
		} 
	} 
 
/**********************************************/ 
// Call back functions from MSdpAgentNotifier // 
/**********************************************/ 
/** 
 * Call back function. 
 * Called by OS when processing an SDP entry. 
 * This function is not called by the user. 
 * 
 * @param aError error code indiacator 
 * @param aHandle the service record handle 
 * @param aTotalRecordsCount the number of records to be processed 
 * @see NextRecordRequestCompleteL 
 */ 
void CBluetoothServiceSearcher::NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount) 
	{ 
	TRAPD(error, NextRecordRequestCompleteL(aError, aHandle, aTotalRecordsCount);); 
	} 
 
/** 
* Record Request Complete. 
* 
* If aError parameter is KErrNone and aTotalRecordsCount > 0 then process the record found 
* aHandle parameter will contain a valid handle on a Service Record in this scenario. 
* Obtain attributes from this record. A Match List is provided in order to search for more than one Attribute 
* 
* @param aError error code indiacator 
* @param aHandle the service record handle 
* @param aTotalRecordsCount the number of records to be processed 
* @see NextRecordRequestComplete 
**/ 
void CBluetoothServiceSearcher::NextRecordRequestCompleteL(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount) 
	{ 
	if (aError == KErrNone && aTotalRecordsCount > 0) 
		{ 
		iContinueSearching = ETrue; // Reset for this record 
 
		iAgent->AttributeRequestL(aHandle, *iMatchList); 
		} 
	else 
		{ 
		RemoveProgressDialogL(); 
		} 
	} 
 
/** 
 * Call back function. 
 * Called by OS when processing an SDP entry. 
 * This function is not called by the user. 
 * 
 * @param aHandle the current service record handle 
 * @param aAttrID the current attribute ID 
 * @param aAttrValue the value of the current attribute 
 * @see AttributeRequestResultL 
 * @return none 
 */ 
void CBluetoothServiceSearcher::AttributeRequestResult(TSdpServRecordHandle aHandle, TSdpAttributeID aAttrID, CSdpAttrValue* aAttrValue) 
	{ 
	TRAPD(error, AttributeRequestResultL(aHandle, aAttrID, aAttrValue)); 
	} 
 
/** 
* Attribute Request Result 
* 
* Called for every attribute requested 
* 
* @see AttributeResquestResult 
* @param aHandle the current service record handle 
* @param aAttrID the current attribute ID 
* @param aAttrValue holds attribute information 
* @return none 
* 
**/ 
void CBluetoothServiceSearcher::AttributeRequestResultL(TSdpServRecordHandle /*aHandle*/, TSdpAttributeID aAttrID, CSdpAttrValue* aAttrValue) 
	{ 
	if (aAttrID == KSdpAttrIdProtocolDescriptorList) 
		{ 
		// Validate the attribute value, and extract the RFCOMM channel 
		// iContinueSearching flag will show ETrue if this parse is successful 
		TBluetoothAttributeParser parser(*this, iContinueSearching); 
		aAttrValue->AcceptVisitorL(parser); 
		} 
	else if (iContinueSearching && aAttrID == KSdpAttrIdServiceAvailability) 
		{ 
		if (aAttrValue->Type() == ETypeUint) 
			{ 
			iAvailable = static_cast(aAttrValue->Uint()); 
			if (iAvailable) 
				{ 
				// SUCCESS ! 
				iSearcherState = KErrNone;	// Successful Search for EMCC Chat Completed 
				} 
			} 
		} 
	delete aAttrValue;	// Ownership has been transferred 
	} 
/* 
 * Call back function. 
 * Called by OS when processing an SDP entry. 
 * This function is not called by the user. 
 * 
 * @see AttributeRequestComplete 
 * @param aHandle the SDP service handle 
 * @param aError error code 
 * @return none 
 */ 
void CBluetoothServiceSearcher::AttributeRequestComplete(TSdpServRecordHandle aHandle, TInt aError) 
	{ 
	TRAPD(error, AttributeRequestCompleteL(aHandle, aError);); 
	} 
 
/** 
* Attribute Request Complete 
* 
* Called when all attribute requests are complete 
* If no error and record has not been found, then request the next record 
* If error occurs, or service is found then remove the progress dialog to return from this Service Searcher 
* 
* @see AttributeRequestComplete 
* @param aHandle the SDP service handle 
* @param aError error code 
* @return none 
* 
**/ 
void CBluetoothServiceSearcher::AttributeRequestCompleteL(TSdpServRecordHandle /*aHandle*/, TInt aError) 
	{ 
	if (aError != KErrNone) 
		{ 
		RemoveProgressDialogL(); 
		return; 
		} 
	else if (iSearcherState != KErrNone) 
		{ 
		// have not found a suitable record so request another 
		iAgent->NextRecordRequestL(); 
		} 
	else 
		{ 
		RemoveProgressDialogL(); 
		} 
	} 
 
/** 
* Set Port to communicate on 
* 
* Observer function called by the TBluetoothAttributeParser if valid Port is found 
* 
* @param aPort port number that's been found 
* @return none 
**/ 
void CBluetoothServiceSearcher::SetPort(TInt aPort) 
	{ 
	iPort = aPort; 
	}