bluetooth/btstack/sdp/sdpnetdb.cpp
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/sdp/sdpnetdb.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,368 @@
+// Copyright (c) 2000-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 <bt_sock.h>
+#include "debug.h"
+#include <btsdp.h>
+#include "sdpnetdb.h"
+#include "sdp.h"
+#include "sdppdu.h"
+#include "sdpkey.h"
+#include "sdpstackutil.h"
+#include "sdpclient.h"
+
+#include "BTSec.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_SDP);
+#endif
+
+//Diagnostic string for security check failures, in builds without platsec
+//diagnostics this will be NULL.
+const char* const KBT_SDPNETDB_NAME_DIAG = __PLATSEC_DIAGNOSTIC_STRING("Bluetooth SDP Net Database");
+
+
+CSdpNetDbProvider::CSdpNetDbProvider(CSdpProtocol& aProtocol)
+: iProtocol(aProtocol)
+	{
+	LOG_FUNC
+	}
+
+void CSdpNetDbProvider::ConstructL()
+	{
+	LOG_FUNC
+	}
+
+CSdpNetDbProvider* CSdpNetDbProvider::NewL(CSdpProtocol& aProtocol)
+	{
+	LOG_STATIC_FUNC
+	CSdpNetDbProvider* self = new(ELeave) CSdpNetDbProvider(aProtocol);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+
+CSdpNetDbProvider::~CSdpNetDbProvider()
+	{
+	LOG_FUNC
+	if (iClient)
+		iClient->RemoveNetDbProvider(*this);
+	delete iResultBuf;
+	}
+
+void CSdpNetDbProvider::Query(TDes8& aBuffer)
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(!iQueryBuffer, Panic(ESdpTwoQuerys));
+	iQueryBuffer = &aBuffer;
+	if (iQueryBuffer->Length() < TInt(sizeof(TUint)))
+		{// Not big enough to hold the query type!!
+		Error(KErrSdpBadRequestBufferLength);
+		return;
+		}
+	TUint type = *reinterpret_cast<const TUint*>(aBuffer.Ptr());
+
+	switch(type & 0x7f)
+		{
+	case KSDPConnectQuery:
+		ConnectQuery();
+		break;
+	case KSDPServiceQuery:
+		ServiceQuery();
+		break;
+	case KSDPAttributeQuery:
+		AttributeQuery();
+		break;
+	case KSDPCancelQuery:
+		CancelCurrentOperation();
+		break;
+	case KSDPEncodedQuery:
+		EncodedQuery();
+		break;
+	case KSDPRetrieveResultQuery:
+		RetrieveResult();
+		break;
+	default:
+		Error(KErrNotSupported);
+		return;
+		};
+	}
+
+void CSdpNetDbProvider::Add(TDes8& /*aBuffer*/)
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(!iQueryBuffer, Panic(ESdpTwoQuerys));
+	iNotify->QueryComplete(KErrNotSupported);
+	}
+
+void CSdpNetDbProvider::Remove(TDes8& /*aBuffer*/)
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(!iQueryBuffer, Panic(ESdpTwoQuerys));
+	iNotify->QueryComplete(KErrNotSupported);
+	}
+
+void CSdpNetDbProvider::CancelCurrentOperation()
+	{
+	LOG_FUNC
+	iQueryBuffer = 0;
+	}
+
+void CSdpNetDbProvider::QueryComplete(const TDesC8& aData)
+	{
+	LOG_FUNC
+	if (!iQueryBuffer)
+		return;
+
+	TInt ret = KErrNone;
+	TUint type = *reinterpret_cast<const TUint*>(iQueryBuffer->Ptr());
+	if (type & 0x80)
+		{// Buffer result and Just send size back
+		delete iResultBuf;
+		iResultBuf = 0;
+		TRAP(ret, iResultBuf = aData.AllocL());
+		if (ret == KErrNone)
+			{
+			iQueryBuffer->Copy(TPckgC<TInt>(aData.Length()));
+			}
+		}
+	else
+		{// Copy the whole result back
+		ret = ReturnResult(aData);
+		}
+	iNotify->QueryComplete(ret);
+	iQueryBuffer = 0;
+	}
+
+TInt CSdpNetDbProvider::ReturnResult(const TDesC8& aData)
+	{
+	LOG_FUNC
+	if(!iQueryBuffer)
+		{
+		return KErrGeneral;
+		}
+
+	if (iQueryBuffer->MaxLength() < aData.Length())
+		{
+		return KErrArgument;
+		}
+	iQueryBuffer->Copy(aData);
+	return KErrNone;
+	}
+
+void CSdpNetDbProvider::ClientUp()
+	{
+	LOG_FUNC
+	if(!iQueryBuffer)
+		return;
+
+	iQueryBuffer->Zero();
+	QueryComplete(KNullDesC8);
+	}
+
+void CSdpNetDbProvider::ClientDown()
+	{
+	LOG_FUNC
+	if (iClient) 
+		iClient->RemoveNetDbProvider(*this);
+	iClient = 0;
+	Error(KErrDisconnected);
+	}
+
+void CSdpNetDbProvider::Error(TInt aErrorCode)
+	{
+	LOG_FUNC
+	LOG1(_L("SDP: Error encountered in SDP NetDb: %d\n"), aErrorCode);
+	if(!iQueryBuffer)
+		return;
+
+	iNotify->QueryComplete(aErrorCode);
+	iQueryBuffer = 0;
+	}
+	
+TInt CSdpNetDbProvider::SecurityCheck(MProvdSecurityChecker *aSecurityChecker)
+	{
+	LOG_FUNC	
+	__ASSERT_ALWAYS(aSecurityChecker, User::Panic(KSECURITY_PANIC, EBTPanicNullSecurityChecker));
+	
+	iSecurityChecker = aSecurityChecker;
+	return iSecurityChecker->CheckPolicy(KLOCAL_SERVICES, KBT_SDPNETDB_NAME_DIAG);			
+	}
+
+void CSdpNetDbProvider::ConnectQuery()
+	{
+	LOG_FUNC
+	if(iClient)
+		{
+		LOG(_L("SDP: ConnectQuery request from net db whilst already connected: REJECTED!\n"));
+		Error(KErrInUse);
+		return;
+		}
+	if (iQueryBuffer->Length() != sizeof(TSDPConnectQuery))
+		{
+		LOG(_L("SDP: ConnectQuery request from net db with bad query length: REJECTED!\n"));
+		Error(KErrSdpBadRequestBufferLength);
+		return;
+		}
+	LOG(_L("SDP: ConnectQuery request from net db\n"));
+	TSDPConnectQuery& queryKey = *(TSDPConnectQuery*)iQueryBuffer->Ptr();
+	iRemoteDev = queryKey.iAddr;
+	iProtocol.GetClient(*this);
+	}
+
+void CSdpNetDbProvider::ServiceQuery()
+	{
+	LOG_FUNC
+	if (!iClient)
+		{
+		Error(KErrSdpClientNotConnected);
+		return;
+		}
+	if (iQueryBuffer->Length() != sizeof(TSDPServiceSearchKey))
+		{
+		Error(KErrSdpBadRequestBufferLength);
+		return;
+		}
+	TSDPServiceSearchKey& queryKey = *(TSDPServiceSearchKey*)iQueryBuffer->Ptr();
+	// Ought to do this check, but can't because of esock defect EDNJDIN-4HPKJZ.
+//	if (iQueryBuffer->MaxLength() < (TInt)(queryKey.iMaxCount*sizeof(TUint)) + 21)
+//		{
+//		Error(KErrSdpBadResultBufferLength);
+//		return;
+//		}
+
+	if (queryKey.iStateLength > KSdpContinuationStateMaxLength)
+		{
+		Error(KErrSdpBadContinuationState);
+		return;
+		}
+
+	TPtrC8 contState(queryKey.iContinuationState, queryKey.iStateLength);
+
+	iClient->ServiceSearchRequest(*this, 
+		                          queryKey.iMaxCount, 
+								  queryKey.iUUID, 
+								  contState);
+	}
+
+void CSdpNetDbProvider::AttributeQuery()
+	{
+	LOG_FUNC
+	if (!iClient)
+		{
+		Error(KErrSdpClientNotConnected);
+		return;
+		}
+	if (iQueryBuffer->Length() != sizeof(TSDPAttributeKey))
+		{
+		Error(KErrSdpBadRequestBufferLength);
+		return;
+		}
+	TSDPAttributeKey& queryKey = *(TSDPAttributeKey*)iQueryBuffer->Ptr();
+
+	// Ought to do this check, but can't because of esock defect EDNJDIN-4HPKJZ.
+//	if (iQueryBuffer->MaxLength() < queryKey.iMaxLength + 19)
+//		{
+//		Error(KErrSdpBadResultBufferLength);
+//		return;
+//		}
+
+	if (queryKey.iStateLength > KSdpContinuationStateMaxLength)
+		{
+		Error(KErrSdpBadContinuationState);
+		return;
+		}
+
+	TPtrC8 contState(queryKey.iContinuationState, queryKey.iStateLength);
+	iClient->ServiceAttributeRequest(*this, 
+		                             queryKey.iServiceRecordHandle,
+		                             queryKey.iMaxLength,
+									 queryKey.iRange,
+									 queryKey.iAttribute,
+									 contState);
+	}
+
+void CSdpNetDbProvider::EncodedQuery()
+	{
+	LOG_FUNC
+	if (!iClient)
+		{
+		Error(KErrSdpClientNotConnected);
+		return;
+		}
+	if (iQueryBuffer->Length() <= STATIC_CAST(TInt,sizeof(TSDPEncodedKey/*Buf??*/)))
+		{
+		Error(KErrSdpBadRequestBufferLength);
+		return;
+		}
+	TSDPEncodedKey& queryKey = *(TSDPEncodedKey*)iQueryBuffer->Ptr();
+	const TUint8* pData = iQueryBuffer->Ptr();
+	pData += sizeof(TSDPEncodedKey/*Buf??*/);
+	TPtrC8 dataDesc(pData, iQueryBuffer->Length()-sizeof(TSDPEncodedKey));
+	//TPtrC8 dataDesc(iQueryBuffer->Mid(sizeof(TSDPEncodedKey)));
+
+	iClient->EncodedRequest(*this, 
+		                    queryKey.iPduId, 
+							dataDesc);
+	}
+
+
+#if 0
+void CSdpNetDbProvider::EncodedQuery()
+	{
+	LOG_FUNC
+	if (!iClient)
+		{
+		Error(KErrSdpClientNotConnected);
+		return;
+		}
+	if (iQueryBuffer->Length() < sizeof(TSDPEncodedKey/*Buf??*/))
+		{
+		Error(KErrSdpBadRequestBufferLength);
+		return;
+		}
+
+
+	TSDPEncodedKey& queryKey = *(TSDPEncodedKey*)iQueryBuffer->Ptr();
+	TPtrC8 dataDesc(iQueryBuffer->Mid(sizeof(TSDPEncodedKey)));
+
+	iClient->EncodedRequest(*this, 
+							queryKey.iPduId, 
+							dataDesc);
+	}
+#endif
+
+
+
+void CSdpNetDbProvider::RetrieveResult()
+	{
+	LOG_FUNC
+	TInt ret;
+	if (!iResultBuf)
+		{// No result to send
+		ret = KErrArgument;
+		}
+	else
+		{// Copy over the result
+		ret = ReturnResult(*iResultBuf);
+		delete iResultBuf;
+		iResultBuf = 0;
+		}
+	iNotify->QueryComplete(ret);
+	iQueryBuffer = 0;
+	}
+