bluetoothcommsprofiles/btpan/panhelpersvr/panhelperremotesdp.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 15 Jul 2010 19:55:36 +0300
branchRCL_3
changeset 21 14e240312f6f
parent 0 29b1cd4cb562
permissions -rw-r--r--
Revision: 201025 Kit: 2010127

// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//

#include <bluetooth/logger.h>
#include "panhelperlog.h"
#include "panhelperremotesdp.h"

#ifdef __FLOG_ACTIVE
_LIT8(KLogComponent, LOG_COMPONENT_PAN_HELPERS);
#endif

using namespace PanHelper;

CPanHelperRemoteSdpQuerier* CPanHelperRemoteSdpQuerier::NewL()
/**
Return a newly constructed remote SDP querier
*/
	{
	CPanHelperRemoteSdpQuerier* self = new(ELeave) CPanHelperRemoteSdpQuerier();
	return(self);
	}

CPanHelperRemoteSdpQuerier::CPanHelperRemoteSdpQuerier() : iMatchesFound(EFalse)
/**
Do nothing
*/
	{	}

CPanHelperRemoteSdpQuerier::~CPanHelperRemoteSdpQuerier()
/**

*/
	{
	delete iSdpAgent;
	}
	
void CPanHelperRemoteSdpQuerier::QueryL(const TBTDevAddr& aAddr, TDes8& aSupportedRemoteRoles, TRequestStatus& aStatus)
/**
Perform an SDP query on the client
*/
	{
	if(iSdpAgent)
		{
		__ASSERT_DEBUG(EFalse, PanHelperPanic(ESecondQueryWhileFirstStillActive));
		User::Leave(KErrInUse);
		}
	iClientStatus = &aStatus;
	iSupportedRemoteRoles = &(STATIC_CAST(TPckg<PanHelper::TPanDeviceRolesList>&,aSupportedRemoteRoles)());
#ifdef __FLOG_ACTIVE
	TBuf<KMaxBtAddrSize> tempDevAddrBuf;
	aAddr.GetReadable(tempDevAddrBuf, KNullDesC, KBtAddrSeparator, KNullDesC);
	LOG2(_L("CPanHelperRemoteSdpQuerier[%x]: Performing remote SDP query on %S..."), this, &tempDevAddrBuf);
#endif	
	CSdpAgent* sdpAgent = CSdpAgent::NewL(*this, aAddr);
	CleanupStack::PushL(sdpAgent);
	
	// create the attribute ID list to match against
	CSdpSearchPattern* searchPattern = CSdpSearchPattern::NewL();
	CleanupStack::PushL(searchPattern);
	
	// search for BNEP, as it's the common field in all PAN records
	searchPattern->AddL(KBnepUUID);
	
	// Set Record Filter copies searchPattern
	sdpAgent->SetRecordFilterL(*searchPattern);
	CleanupStack::PopAndDestroy(searchPattern);

	sdpAgent->NextRecordRequestL();

	// Now we have successfully issued the request we know that it will later be
	// completed, so we can keep sdpAgent and it will be deleted on request
	// completion.
	CleanupStack::Pop(sdpAgent);
	iSdpAgent = sdpAgent;
	}
	
void CPanHelperRemoteSdpQuerier::CancelQuery()
/**
Cancel any queries in progress
*/
	{
	if(iSdpAgent)
		{
		iSdpAgent->Cancel();
		}

	delete iSdpAgent;
	iSdpAgent = NULL;
	User::RequestComplete(iClientStatus, KErrCancel);
	}

void CPanHelperRemoteSdpQuerier::NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt /*aTotalRecordsCount*/)
/**
We've got another SDP record, so parse it to (eventually) find out what PAN role it's advertising
*/
	{
	TInt err = aError;

	if(err == KErrNone) //more results available
		{
		iMatchesFound = ETrue;
		// Check the attributes of the returned record to see if it's a U, GN, or NAP record	
		TRAP(err,iSdpAgent->AttributeRequestL(aHandle, KSdpAttrIdBluetoothProfileDescriptorList));
		if(err == KErrNone)
			{
			return; 
			}
		}
		
	//Request has completed or error has occured
	
	if(err != KErrEof)
		{
		// A 'real' error has occured, cancel the query
		if(iSdpAgent)
			{
			iSdpAgent->Cancel();
			}
		}
	else
		{
		// err == KErrEof when no more results available so complete the request
		// with KErrNone as KErrEof not a 'real' error
		err = iMatchesFound?KErrNone:KErrNotFound;
		}
		
	delete iSdpAgent;
	iSdpAgent = NULL;
	User::RequestComplete(iClientStatus, err);
	}
	
void CPanHelperRemoteSdpQuerier::AttributeRequestResult(TSdpServRecordHandle /*aHandle*/, TSdpAttributeID /*aAttrID*/, CSdpAttrValue* aAttrValue)
/**

*/
	{
	__ASSERT_ALWAYS(aAttrValue, PanHelperPanic(ENullSdpAttrValue));
	
	if(aAttrValue->Type()==ETypeDES)
		{
		CSdpAttrValueDES* sdpProfileDesList = static_cast<CSdpAttrValueDES*>(aAttrValue);
		
		// cycle through the contents of the DES to find the remote role
		TRAPD(err, sdpProfileDesList->AcceptVisitorL(*this));
		if(err)
			{
			LOG1(_L("CPanHelperRemoteSdpQuerier[%x]: attempting to read supplied DES failed, erroring client"), this);
			}
		}
	else		// we've been given a non-DES structure for an attribute that is supposed to be a DES
		{
		LOG1(_L("CPanHelperRemoteSdpQuerier[%x]: attribute request result passed back a non-DES attribute, erroring client"), this);
		}
	
	// Delete the attribute value now that we've finished with it	
	delete aAttrValue;

	// there shouldn't be another profile descriptor list, so we should now get AttributeRequestComplete() called	
	}
	
void CPanHelperRemoteSdpQuerier::AttributeRequestComplete(TSdpServRecordHandle, TInt /*aError*/)
/**

*/
	{
	// examine the next record returned
	TRAPD(err, iSdpAgent->NextRecordRequestL());
	if(err)
		{
		LOG2(_L("CPanHelperRemoteSdpQuerier[%x]: next record request failed with error %d"), this, err);
		}
	}


void CPanHelperRemoteSdpQuerier::StartListL(CSdpAttrValueList& /*aList*/)
/**

*/
	{
	// not interested in this
	}
	
void CPanHelperRemoteSdpQuerier::EndListL()
/**

*/
	{
	// not interested in this
	}

void CPanHelperRemoteSdpQuerier::VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType)
/**
Process an attribute from a DES - specifically attributes from the profile descriptor list
*/
	{
	if(aType==ETypeUUID)
		{
		//CSdpAttrValueUUID* sdpUuidValue = static_cast<CSdpAttrValueUUID*>(&aValue);
		if(aValue.UUID()==KPanUUUID)
			{
			LOG1(_L("CPanHelperRemoteSdpQuerier[%x]: ...remote device supports PAN-U role..."), this);
			iSupportedRemoteRoles->SetSupportsU();
			}
		else if(aValue.UUID()==KPanGnUUID)
			{
			LOG1(_L("CPanHelperRemoteSdpQuerier[%x]: ...remote device supports PAN-GN role..."), this);
			iSupportedRemoteRoles->SetSupportsGn();
			}
		else if(aValue.UUID()==KPanNapUUID)
			{
			LOG1(_L("CPanHelperRemoteSdpQuerier[%x]: ...remote device supports PAN-NAP role..."), this);
			iSupportedRemoteRoles->SetSupportsNap();
			}
		}
	// otherwise, it's just the version or something, and we don't care
	}