bluetoothcommsprofiles/btpan/panhelpersvr/panhelperremotesdp.cpp
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothcommsprofiles/btpan/panhelpersvr/panhelperremotesdp.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,228 @@
+// 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
+	}