--- /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;
+ }
+