bluetooth/btsdp/server/protocol/pduhandler.cpp
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btsdp/server/protocol/pduhandler.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,199 @@
+// 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 <btsdp.h>
+#include "reqhandler.h"
+#include "pduhandler.h"
+#include "DataEncoder.h"
+#include "sdpconsts.h"
+
+
+CSdpSearchPattern* CSdpPDUHandler::UUIDListLC(const TDesC8& aPdu, const TInt aNextSize, TInt& aLen, TInt& aRem, TInt& aCount)
+/**
+	Unpack UUID list from request PDU and extracts a 16 bit value following.
+	Parameter format is
+ @verbatim
+		Search UUID list descriptor			DesC
+		Next chunk size						TInt (but always 2)
+		Descriptor length returned			TInt
+		Remaining length returned			TInt
+		Next 2 bytes are returned as		TInt
+ @endverbatim
+
+	Method will leave if there are parsing problems, or the remaining 
+	PDU is smaller than next size.
+	Returns :
+@verbatim
+		UUID list							CSdpSearchPattern object
+		total byte length					TInt
+		number of bytes unparsed			TInt
+		the 16 bit value extracted			TInt
+@endverbatim
+
+**/
+	{
+	CSdpSearchPattern* pattern = CSdpSearchPattern::NewL();
+	CleanupStack::PushL(pattern);
+
+	CElementParser* parser = CElementParser::NewL(pattern);
+	CleanupStack::PushL(parser);
+
+	aLen = aPdu.Length();
+	aRem = parser->ParseElementsL(aPdu);
+	CleanupStack::PopAndDestroy(/*parser*/);
+
+	if (aRem < aNextSize)
+		{
+		User::Leave(KErrArgument);
+		}
+	aCount = BigEndian::Get16(&aPdu[aLen-aRem]);
+	aRem -= aNextSize;
+	return pattern;
+	}
+
+
+
+ CSdpAttrIdMatchList* CSdpPDUHandler::AttrListLC(const TDesC8& aPdu, TInt& aRem)
+/**
+	Unpack attribute/range list from request PDU.
+	Parameter format is
+ @verbatim
+		Search attrib list descriptor		DesC
+		Remaining length returned			TInt
+ @endverbatim
+
+	Method will leave if the remaining PDU is smaller than next size.
+	Returns :
+ @verbatim
+		the attribute list					CSdpAttrIdMatchList object
+		number of bytes unparsed			TInt.
+ @endverbatim
+
+
+**/
+ {
+	CSdpAttrIdMatchList* attributeMatchList = CSdpAttrIdMatchList::NewL();
+	CleanupStack::PushL(attributeMatchList);
+
+	CElementParser* parser = CElementParser::NewL(attributeMatchList);
+	CleanupStack::PushL(parser);
+
+	aRem = parser->ParseElementsL(aPdu);
+	CleanupStack::PopAndDestroy(/*parser*/);
+	return attributeMatchList;
+
+ }
+
+
+TBool CSdpPDUHandler::ContinuationL(const TDesC8& aPdu, const TInt aLen, const TInt aRem)
+/**
+	Check the continuation. This code will change
+ @verbatim
+		Current request descriptor		DesC
+		Current request length			TInt
+		Unparsed length					TInt
+ @endverbatim
+
+	Method will leave if the remaining PDU is smaller than any continuation
+	Returns :
+ @verbatim
+		dummy continuation length			TInt.
+
+ @endverbatim
+**/
+{
+	if (aRem < KContStateHeader || 
+		aPdu[aLen-aRem] > KSdpContinuationStateLength ||
+		aPdu[aLen-aRem] + KContStateHeader != aRem)
+		{
+		User::Leave(KErrArgument);
+		}
+	TPtrC8 contState = aPdu.Right(aRem-KContStateHeader);
+	if(contState.Length() != 0)
+		{
+		if(contState.Length() != KSdpContinuationStateLength)
+			{
+			User::Leave(KErrUnknown); // Causes "Bad cont State" error
+			}
+		iContinuation = BigEndian::Get32(&contState[KContContOff]);
+		iLength = BigEndian::Get32(&contState[KContTotOff]);
+		iCRC = BigEndian::Get16(&contState[KContCrcOff]);
+		if (iLength < iContinuation)
+			{
+			User::Leave(KErrUnknown); // Causes "Bad cont State" error
+			}
+		return ETrue;	// we have a continuation situation
+		}
+	return 0;
+}
+
+
+void CSdpPDUHandler::CompleteOPL(TDes8& aPdu, const TDesC8& aWritePdu, const TInt aMaxAttrCount)
+/**
+	Verifies the size of the response parameters
+	and writes out correct length for the attributes.
+ @verbatim
+		response descriptor			DesC
+		written area (attributes)	DesC
+		maximum byte count			TInt
+ @endverbatim
+
+	Method will leave if response is bigger than requested or allowed for.
+	Returns nothing
+
+**/
+{
+	TUint16 finalLength = (TUint16)aWritePdu.Length();
+	if (finalLength > aMaxAttrCount) User::Leave(KErrNoMemory);
+	aPdu.SetLength(KRspAttributeCountSize + finalLength + KContStateHeader);
+	BigEndian::Put16(&aPdu[KRspAttrCountOffset], finalLength);
+// now need to update the DES size
+	if (iDesSize == 3)
+	{
+		BigEndian::Put16(&aPdu[KRspAttributeListOffset+1], (unsigned short)(finalLength-iDesSize));
+	}
+	else if (iDesSize == 2)
+	{
+		if (finalLength > 0xff) User::Leave(KErrNoMemory);
+		aPdu[KRspAttributeListOffset+1] = (unsigned char)((finalLength&0xff)-iDesSize);
+	}
+	else User::Leave(KErrUnknown);   // perhaps this should be a panic
+	aPdu[aPdu.Length()-1] = 0; // FIXME: Put contState here
+}
+
+TUint32 CSdpPDUHandler::ContinuationOffset()
+	{
+	return iContinuation;
+	}
+
+TUint32 CSdpPDUHandler::FullLength()
+	{
+	return iLength;
+	}
+
+TUint16 CSdpPDUHandler::ReqCRC()
+	{
+	return iCRC;
+	}
+
+// specific test for DES headers only
+TInt CSdpPDUHandler::DesSize(TUint aDataSize)
+	{
+	TInt lDesSize;
+	lDesSize = (aDataSize > KMaxTwoByteDESSize) ? KThreeByteDESSize : KTwoByteDESSize;
+	lDesSize = (aDataSize > KMaxThreeByteDESSize) ? KFiveByteDESSize : lDesSize;
+	return lDesSize;
+	}
+