bluetooth/btsdp/test/TSDPSAS.cpp
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btsdp/test/TSDPSAS.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,3569 @@
+// Copyright (c) 2005-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:
+// Bluetooth SDP verification tests
+// 
+//
+
+#include <e32test.h>
+#include <bluetooth/logger.h>
+#include "TSDPSAS.h"
+#include "MAttributeVisitor.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_TSDPSAS);
+#endif
+
+#ifdef _DEBUG
+PANICCATEGORY("tsdpsas");
+#endif
+
+#undef STOPPING_MODE
+#ifndef STOPPING_MODE
+	//#define STOPPING_MODE
+#endif
+
+#undef SEVEN_LAYERS_BUG
+#ifndef SEVEN_LAYERS_BUG
+	//#define SEVEN_LAYERS_BUG
+#endif
+
+#define ONLY_CONTINUATION_AND_BROWSE
+
+//If you want to see what actual attributes are coming back from an SAS query.
+//#define PRINT_BUILDER
+// constants
+const TUint KUselessRecordHandle=0xffffffff;
+const TUint KNonExistantUUID=0xffff;
+const TUint KAttributeTestsServiceUUID=0x0011;
+//const TInt KNumSdpVerificationTests=55;
+const TInt KServiceRequestTest = 0;	// Number of the first test
+const TInt KServiceAttributeRequestTest = 6;	// Number of the first test
+const TInt KServiceSearchAttributeRequestTest = 29;	// Number of the first test
+const TInt KSdpBrowseTest = 53;
+const TInt KSdpLastTest = KSdpBrowseTest + 1;
+const TInt KServiceRequestBITest = KServiceAttributeRequestTest - 2;
+const TInt KServiceAttributeRequestBITest = KServiceSearchAttributeRequestTest - 3;
+const TInt KServiceSearchAttributeRequestBITest = KSdpBrowseTest - 2;
+const TInt KMinResponseSize = 8; // This is the 5 byte header + 2 byte size (zero) + cont bytes(zero)
+const TInt KAttributeParamsSize = 11;
+const TInt KServiceParamsSize16 = 7;
+const TInt KServiceParamsSize32 = 9;
+const TInt KServiceParamsSize128 = 21;
+//const TInt KMaxCountSize = 2;
+//const TInt KUuidListHeaderSize = 2;
+const TInt KUuid16ParamSize = 3;
+const TInt KUuid32ParamSize = 5;
+const TInt KUuid128ParamSize = 17;
+const TInt KServiceAttributeParamsSize16 = 12;
+const TInt KServiceAttributeParamsSize32 = 14;
+const TInt KServiceAttributeParamsSize128 = 26;
+//const TInt KSdpSyncPointBase = 0x1000;
+
+const TInt KSdpAttributeBigRange = 0x00000202;
+// UUIDS (add to these as necessary) - see builddb.cpp
+// UUIDS (add to these as necessary)
+//const TUint32	KSdpContTestUUID = 0x100;
+
+
+// Offsets and constants
+const TInt KRecordHandleOffset = 9;
+const TInt KTotalCountOffset = 5;
+const TInt KCurrentCountOffset = 7;
+const TInt KErrorCodeOffset = 5;
+const TInt KAttributeByteCountOffset = 5;
+const TInt KAttributeListOffset = 7;
+
+
+GLREF_D TBTDevAddr devAddr;
+
+
+
+
+
+
+
+
+
+
+
+
+//
+// CSdpTestBase
+//
+CSdpTestBase::CSdpTestBase(CConsoleBase& aConsole)
+:iConsole(aConsole),iRawTransactionId(0x0000)
+	{
+	}
+	
+CSdpTestBase::~CSdpTestBase()
+	{
+		iRawSock.Close();
+	}
+
+void CSdpTestBase::StartSDPServerL()
+/**
+	Builds up a static DB, and copies it into the RSdpDatabase
+**/
+	{
+
+	}
+
+void CSdpTestBase::RegisterDatabaseInServerL (CSdpDatabase&)
+	{
+	}
+ 
+
+void CSdpTestBase::SendCloseL()
+/**
+Send info to remote device to indicate the tests have finished
+**/
+	{
+	}
+
+void CSdpTestBase::WaitForCloseL()
+/**
+Wait for input from the other side to show the tests have finished
+(We only need to read one byte).
+**/
+	{
+	}
+
+void CSdpTestBase::SdpConnectL()
+/**
+Connect to remote SDP server
+**/
+	{
+	TRequestStatus stat;
+	TL2CAPSockAddr addr;
+	addr.SetBTAddr(devAddr);
+	addr.SetPort(1);
+	iRawSock.Connect(addr, stat);
+	User::WaitForRequest(stat);
+	if(stat.Int())
+		{
+		iConsole.Printf(_L("Connection failed with error %d. Press any key.\r\n"), stat.Int());
+		iConsole.Getch();
+		}
+
+	User::LeaveIfError(stat.Int());
+	}
+
+
+//
+// TSDPHeader class
+//
+TSDPHeader::TSDPHeader()
+:iPduId(0), iTransactionId(0), iParamLen(0)
+	{
+	}
+
+TSDPHeader::TSDPHeader(TUint8 aPduId, TUint16 aTranId, TUint16 aLen)
+:iPduId(aPduId), iTransactionId(aTranId), iParamLen(aLen)
+	{
+	}
+
+void TSDPHeader::AppendHeader(TDes8& aBuf)
+	{
+	// Need to make sure endina-ness is OK (is this right)
+	//
+	TUint16 bigTranId = BigEndian::Get16((TUint8*)&iTransactionId);
+	TUint16 bigLen = BigEndian::Get16((TUint8*)&iParamLen);
+	aBuf.Append(&iPduId, 1);
+	aBuf.Append((TUint8*)&bigTranId, 2);
+	aBuf.Append((TUint8*)&bigLen, 2);
+	}
+
+
+//
+// TServiceRequest class
+//
+
+TServiceRequest::TServiceRequest()
+:iUuid(0), iSP(0), iMaxRecordCount(0), iUuidType(CSdpTestBase::EUuid16), iAutoDes(ETrue)
+	{
+	SetupDES();
+	}
+
+TServiceRequest::TServiceRequest(TUint8* aDes, 
+								 TUUID aUuid, 
+								 CSdpTestBase::TUuidType aUuidType,
+								 TUint16 aMaxRecordCount)
+:iUuid(0), iSP(0), iMaxRecordCount(0), iUuidType(CSdpTestBase::EUuid16), iAutoDes(EFalse)
+	{
+	Mem::Copy(iDes, aDes, 3);
+	iUuid = aUuid;
+	iUuidType = aUuidType;
+	iMaxRecordCount = aMaxRecordCount;
+	}
+
+TServiceRequest::TServiceRequest(TUint8* aDes, 
+								 CSdpSearchPattern& aSP, 
+								 CSdpTestBase::TUuidType aUuidType,
+								 TUint16 aMaxRecordCount)
+:iUuid(0), iSP(0), iMaxRecordCount(0), iUuidType(CSdpTestBase::EUuid16), iAutoDes(EFalse)
+	{
+	Mem::Copy(iDes, aDes, 3);
+	iSP = &aSP;
+	iUuidType = aUuidType;
+	iMaxRecordCount = aMaxRecordCount;
+	}
+
+TServiceRequest::TServiceRequest(TUUID aUuid, 
+								 CSdpTestBase::TUuidType aUuidType,
+								 TUint16 aMaxRecordCount)
+:iUuid(aUuid), iSP(0), iMaxRecordCount(aMaxRecordCount), iUuidType(aUuidType), iAutoDes(ETrue)  
+	{
+	SetupDES();
+	}
+
+TServiceRequest::TServiceRequest(CSdpSearchPattern& aSP, 
+								 CSdpTestBase::TUuidType aUuidType,
+								 TUint16 aMaxRecordCount)
+:iUuid(0), iSP(0), iMaxRecordCount(aMaxRecordCount), iUuidType(aUuidType), iAutoDes(ETrue)  
+	{
+	iSP = &aSP;
+	SetupDES();
+	}
+
+void TServiceRequest::SetupDES()
+	{
+	if(iSP)
+		//just set up first two bytes
+		{
+		iDes[0] = 0x35;
+		switch(iUuidType)
+			{
+			case CSdpTestBase::EUuid128:
+				iDes[1] = (TUint8)(KUuid128ParamSize*iSP->Count()); //take the length
+				break;
+			case CSdpTestBase::EUuid32:
+				iDes[1] = (TUint8)(KUuid32ParamSize*iSP->Count()); //take the length
+				break;
+			default:
+				iDes[1] = (TUint8)(KUuid16ParamSize*iSP->Count()); //take the length
+			}
+		}
+	else
+		{
+		TUint8 validDes16[] = {0x35, 0x03, 0x19};
+		TUint8 validDes32[] = {0x35, 0x05, 0x1a};
+		TUint8 validDes128[] = {0x35, 0x11, 0x1c};
+		switch(iUuidType)
+			{
+		case CSdpTestBase::EUuid16:
+			Mem::Copy(iDes, validDes16, 3);
+			break;
+		case CSdpTestBase::EUuid32:
+			Mem::Copy(iDes, validDes32, 3);
+			break;
+		default:
+			Mem::Copy(iDes, validDes128, 3);
+			}
+		}
+
+	}
+
+void TServiceRequest::SetUuidType(CSdpTestBase::TUuidType aUuidType)
+	{
+	iUuidType = aUuidType;
+	if(iAutoDes)
+		{
+		SetupDES();
+		}
+	}
+
+void TServiceRequest::AppendRequest(TDes8& aBuf)
+	{
+	if(iSP)
+		{
+		aBuf.Append(iDes, 2); //just take the list header bytes ..then...
+		for(TInt i = 0; i<iSP->Count(); i++)
+			{
+			TUUID uuid = iSP->At(i);
+			TPtrC8 ptr16 = uuid.ShortestForm();
+			TPtrC8 ptr32 = uuid.LongForm().Mid(0,4);
+			TPtrC8 ptr128 = uuid.LongForm();
+			switch(iUuidType)
+				{
+				case CSdpTestBase::EUuid128:
+					aBuf.Append(0x1c);
+					aBuf.Append(ptr128);
+					break;
+				case CSdpTestBase::EUuid32:
+					aBuf.Append(0x1a);
+					aBuf.Append(ptr32);
+					break;
+				default:
+					aBuf.Append(0x19);
+					aBuf.Append(ptr16);
+				}
+			}
+		TUint16 bigCount = BigEndian::Get16((TUint8*)&iMaxRecordCount);
+		aBuf.Append((TUint8*)&bigCount, 2);
+		}
+	else
+		{
+		TPtrC8 ptr16 = iUuid.ShortestForm();
+		TPtrC8 ptr32 = iUuid.LongForm().Mid(0,4);
+		TPtrC8 ptr128 = iUuid.LongForm();
+		TUint16 bigCount = BigEndian::Get16((TUint8*)&iMaxRecordCount);
+		aBuf.Append(iDes, 3); //....CHANGED
+		switch(iUuidType)
+			{
+			case CSdpTestBase::EUuid128:
+				aBuf.Append(ptr128);
+				break;
+			case CSdpTestBase::EUuid32:
+				aBuf.Append(ptr32);
+				break;
+			default:
+				aBuf.Append(ptr16);
+			}
+
+		aBuf.Append((TUint8*)&bigCount, 2);
+		}
+	}
+
+//
+// TAttributeRequest class
+//
+TAttributeRequest::TAttributeRequest()
+:iRecordHandle(0), iMaxByteCount(0), iAttributeId(0), iAttributeIdRange(0), iAutoDes(ETrue)
+	{
+	Mem::FillZ(iDes, 0); 
+	}
+TAttributeRequest::TAttributeRequest(TUint32 aRecordHandle, TUint16 aMaxByteCount, TUint8* aDes, TUint16 aAttributeId)
+:iRecordHandle(aRecordHandle), iMaxByteCount(aMaxByteCount), iAttributeId(aAttributeId), iAttributeIdRange(0), iAutoDes(EFalse)
+	{
+	Mem::Copy(iDes, aDes, 3);
+	}
+
+TAttributeRequest::TAttributeRequest(TUint32 aRecordHandle, TUint16 aMaxByteCount, TUint8* aDes, TUint32 aAttributeIdRange)
+:iRecordHandle(aRecordHandle), iMaxByteCount(aMaxByteCount), iAttributeId(0), iAttributeIdRange(aAttributeIdRange), iAutoDes(EFalse)
+	{
+	Mem::Copy(iDes, aDes, 3);
+	}
+
+TAttributeRequest::TAttributeRequest(TUint32 aRecordHandle, TUint16 aMaxByteCount, TUint16 aAttributeId)
+:iRecordHandle(aRecordHandle), iMaxByteCount(aMaxByteCount), iAttributeId(aAttributeId), iAttributeIdRange(0), iAutoDes(ETrue)
+	{
+	SetupDES();
+	}
+
+TAttributeRequest::TAttributeRequest(TUint32 aRecordHandle, TUint16 aMaxByteCount, TUint32 aAttributeIdRange)
+:iRecordHandle(aRecordHandle), iMaxByteCount(aMaxByteCount), iAttributeId(0), iAttributeIdRange(aAttributeIdRange), iAutoDes(ETrue)
+	{
+	SetupDES();
+	}
+
+void TAttributeRequest::SetupDES()
+	{
+	TUint8 validDesId[] = {0x35, 0x03, 0x09};
+	TUint8 validDesIdRange[] = {0x35, 0x05, 0x0a};
+	if(iAttributeIdRange)
+		{
+		Mem::Copy(iDes, validDesIdRange, 3);
+		}
+	else
+		{
+		Mem::Copy(iDes, validDesId, 3);
+		}
+	}
+
+void TAttributeRequest ::AppendRequest(TDes8& aBuf)
+	{
+	TUint32 bigHandle = BigEndian::Get32((TUint8*)&iRecordHandle);
+	TUint16 bigCount = BigEndian::Get16((TUint8*)&iMaxByteCount);
+	TUint16 bigId = BigEndian::Get16((TUint8*)&iAttributeId);;
+	TUint32 bigId32 = BigEndian::Get32((TUint8*)&iAttributeIdRange);;
+		
+	
+	aBuf.Append((TUint8*)&bigHandle, 4);
+	aBuf.Append((TUint8*)&bigCount, 2);
+	aBuf.Append(iDes, 3);
+	if(iAttributeIdRange)
+		aBuf.Append((TUint8*)&bigId32, 4);
+	else
+		aBuf.Append((TUint8*)&bigId, 2);
+	}
+
+//
+// TServiceAttributeRequest class
+//
+TServiceAttributeRequest::TServiceAttributeRequest()
+	{
+	}
+
+
+TServiceAttributeRequest::TServiceAttributeRequest(TUint8* aServiceDes, TUUID aServiceUuid, CSdpTestBase::TUuidType aUuidType, TUint16 aMaxByteCount, TUint8* aAttribDes, TUint16 aAttributeId)
+	{
+	iServiceRequest=TServiceRequest(aServiceDes, aServiceUuid, aUuidType, 0);
+	iAttributeRequest=TAttributeRequest(0, aMaxByteCount, aAttribDes, aAttributeId);
+	}
+
+TServiceAttributeRequest::TServiceAttributeRequest(TUUID aServiceUuid, CSdpTestBase::TUuidType aUuidType, TUint16 aMaxByteCount, TUint16 aAttributeId)
+	{
+	iServiceRequest=TServiceRequest(aServiceUuid, aUuidType, 0);
+	iAttributeRequest=TAttributeRequest(0, aMaxByteCount, aAttributeId);
+	}
+
+TServiceAttributeRequest::TServiceAttributeRequest(TUint8* aServiceDes, TUUID aServiceUuid, CSdpTestBase::TUuidType aUuidType, TUint16 aMaxByteCount, TUint8* aAttribDes, TUint32 aAttributeIdRange)
+	{
+	iServiceRequest=TServiceRequest(aServiceDes, aServiceUuid, aUuidType, 0);
+	iAttributeRequest=TAttributeRequest(0, aMaxByteCount, aAttribDes, aAttributeIdRange);
+	}
+
+TServiceAttributeRequest::TServiceAttributeRequest(TUUID aServiceUuid, CSdpTestBase::TUuidType aUuidType, TUint16 aMaxByteCount, TUint32 aAttributeIdRange)
+	{
+	iServiceRequest=TServiceRequest(aServiceUuid, aUuidType, 0);
+	iAttributeRequest=TAttributeRequest(0, aMaxByteCount, aAttributeIdRange);
+	}
+
+
+
+
+void TServiceAttributeRequest::SetUuidType(CSdpTestBase::TUuidType aUuidType)
+	{
+	iServiceRequest.SetUuidType(aUuidType);
+	}
+
+void TServiceAttributeRequest::AppendRequest(TDes8& aBuf)
+	{
+	TUint16 byteCount = iAttributeRequest.MaxByteCount();
+	TUint16 bigCount = BigEndian::Get16((TUint8*)&byteCount);
+	TUint attribId = 0;
+	TUint16 bigAttributeId = 0;
+	TUint32 bigAttributeIdRange = 0;
+
+	if((attribId = iAttributeRequest.AttributeIdRange())!=0)
+		{
+		bigAttributeIdRange = BigEndian::Get32((TUint8*)&attribId);
+		}
+	else
+		{
+		attribId = iAttributeRequest.AttributeId();
+		bigAttributeId = BigEndian::Get16((TUint8*)&attribId);
+		}
+
+	if(iServiceRequest.SP())
+		//WARNING-> THIS 'IF' HAS NOT BEEN TESTED!
+		{
+		aBuf.Append(iServiceRequest.Des(), 2); //just take the list header bytes..then...
+		for(TInt i = 0; i<iServiceRequest.SP()->Count(); i++)
+			{
+			TUUID uuid = iServiceRequest.SP()->At(i);
+			TPtrC8 ptr16 = uuid.ShortestForm();
+			TPtrC8 ptr32 = uuid.LongForm().Mid(0,4);
+			TPtrC8 ptr128 = uuid.LongForm();
+			switch(iServiceRequest.UuidType())
+				{
+				case CSdpTestBase::EUuid128:
+					aBuf.Append(0x1c);
+					aBuf.Append(ptr128);
+					break;
+				case CSdpTestBase::EUuid32:
+					aBuf.Append(0x1a);
+					aBuf.Append(ptr32);
+					break;
+				default:
+					aBuf.Append(0x19);
+					aBuf.Append(ptr16);
+				}
+			}
+		}
+	else
+		{
+		TUUID uuid = iServiceRequest.Uuid();
+		TPtrC8 ptr16 = uuid.ShortestForm();
+		TPtrC8 ptr32 = uuid.LongForm().Mid(0,4);
+		TPtrC8 ptr128 = uuid.LongForm();
+		aBuf.Append(iServiceRequest.Des(), 3);
+		switch(iServiceRequest.UuidType())
+			{
+			case CSdpTestBase::EUuid128:
+				aBuf.Append(ptr128);
+				break;
+			case CSdpTestBase::EUuid32:
+				aBuf.Append(ptr32);
+				break;
+			default:
+				aBuf.Append(ptr16);
+			}
+		}
+	
+	aBuf.Append((TUint8*)&bigCount, 2);
+	aBuf.Append(iAttributeRequest.Des(), 3);
+
+	if(bigAttributeIdRange)
+		{
+		aBuf.Append((TUint8*)&bigAttributeIdRange, 4);
+		}
+	else
+		{
+		aBuf.Append((TUint8*)&bigAttributeId, 2);
+		}
+	
+	}
+
+
+
+
+class CAttrPrintVisitor : public CBase, public MAttributeVisitor
+	{
+public:
+	CAttrPrintVisitor(CConsoleBase& aConsole) : iConsole(aConsole) {iIndent=0;}
+	~CAttrPrintVisitor() {/*iConsole.Getch();*/}
+    void VisitAttributeL(CSdpAttr &aAttribute)
+		{
+		Indent();
+		iConsole.Printf(_L("\nID:0x%x:"), aAttribute.AttributeID());
+		}
+	void HexDes(const TDesC8& aDes)
+	{
+	for (TInt i = 0; i < aDes.Length(); ++i)
+		iConsole.Printf(_L("%02x"), aDes[i]);
+		//iConsole.Printf(_L("\n"));
+	}
+	void VisitAttributeValueL(CSdpAttrValue & aValue, TSdpElementType aType)
+		{
+// FIXME need a new object like the match list that will just store the object in
+// FIXME an array, or perhaps just print it ? Is it a visitor ?
+//		CSdpSearchPattern* encAttrList = new (ELeave) CSdpSearchPattern;
+//		CleanupStack::PushL(encAttrList);
+
+//		CElementParser* parser = CElementParser::NewL(encAttrList);
+//		CleanupStack::PushL(parser);
+
+//		TInt rem;
+
+		TBuf16<0x64> iString;
+//		TInt iFound;
+		switch (aType)
+			{
+			case ETypeString:
+				{
+				TInt len = aValue.Des().Length();
+				if(len<0x60)
+					//cannot cope with strings longer than 100 bytes!
+					{
+					iString.Copy(aValue.Des());
+					iConsole.Printf(_L("\"%S\""),&iString);
+					}
+				else
+					{
+					iConsole.Printf(_L("String attribute too long for CONSOLE: Length %d\n"),len);
+					}
+				break;
+				}
+			case ETypeDES:
+				iConsole.Printf(_L(" DES"));
+				break;
+			case ETypeUint:
+				iConsole.Printf(_L(" UInt:0x%x"), aValue.Uint());
+				break;
+			case ETypeUUID:
+				iConsole.Printf(_L(" UUID:0x"));
+				HexDes(aValue.UUID().ShortestForm());
+				break;
+			case ETypeEncoded:
+				HexDes(aValue.Des());  // simplest
+//parse out the elements in this encoded attribute
+//				rem = parser->ParseElementsL(aValue.Des());
+//				CleanupStack::PopAndDestroy(/*parser*/);
+//				for (iFound=0 ; iFound++ ; (iFound < (encAttrList->Length())))
+//				{
+//					VisitAttributeValueL(encAttrList->At(iFound).Value, encAttrList->At(iFound).Type);
+//				}
+//				CleanupStack::PopAndDestroy(/*encAttrList*/);
+				break;
+			default:
+				iConsole.Printf(_L("type %d"), aType);
+			}
+		}
+	void StartListL(CSdpAttrValueList &/*aList*/)
+		{
+		++iIndent;
+		iConsole.Printf(_L("{"));
+		}
+    void EndListL()
+		{
+		if(iIndent<=0)
+			{
+			iConsole.Printf(_L("\nERROR! Unmatched EndList!\n"));
+			__DEBUGGER();
+			}
+		iConsole.Printf(_L("}"));
+		--iIndent;
+		}
+private:
+	void Indent() {/*test.SetPos(iIndent)*/;}
+	CConsoleBase &iConsole;
+	TInt iIndent;
+	};
+
+//
+// CSdpVerificationTests
+//
+
+void CSdpVerificationTests::RunTestL(CConsoleBase& aConsole)
+	{
+	CSdpVerificationTests* test=new(ELeave) CSdpVerificationTests(aConsole);
+	TRAPD(err,test->DoTestsL());
+	aConsole.Printf(_L("SAS tests completed with error code: %d\r\nPRESS ANY KEY.\r\n"), err);
+	aConsole.Getch();
+	delete test;
+	}
+
+CSdpVerificationTests::CSdpVerificationTests(CConsoleBase& aConsole)
+:CSdpTestBase(aConsole), iIndent(0), iUuidType(CSdpTestBase::EUuid16)
+	{
+	iSP = CSdpSearchPattern::NewL(); //naughty but time is short!
+
+	
+	SetUpServiceTestParams();
+	SetUpAttributeTestParams();
+	SetUpServiceAttributeTestParams();
+
+	Mem::FillZ( iContinuationBuffer,KSdpContinuationStateMaxLength);
+	
+	iType = EServiceRequest;
+	iQueryIndex = 0;
+	iQueryState = EServiceRequest;
+	iTestNum = 0;
+	iContinuationStore.SetLength(0);
+	iNeedAttributeId = ETrue;
+	iBuildingList = 0;
+	iBrowseIter = 0;
+	iRequestMaxCount = 0;
+	iRequestMaxCount1 = 0;
+	iRequestMaxCount2 = 0;
+	iRequestTransId = 0;
+	iRequestTransId1 = 0;
+	iRequestTransId2 = 0;
+	iNeedMoreRecordHandles = EFalse;
+	iBrowseTestNumRecordHandlesStored = 0;
+	for (TUint i = 0; i < KMaxNumRecordHandles; i ++)
+		{
+		iBrowseTestServiceRecordHandle[i] = KUselessRecordHandle; //we want test database NOT to need this handle!
+		}
+	}
+
+CSdpVerificationTests::~CSdpVerificationTests()
+	{
+	delete iSP;
+	}
+
+
+void CSdpVerificationTests::RunMasterTestL()
+	{
+	// Set the type
+	//
+	if(iTestNum<KServiceAttributeRequestTest)
+	{
+		iType=EServiceRequest;
+	}
+	if(iTestNum>=KServiceAttributeRequestTest)
+	{
+		iType=EServiceAttributeRequest;
+	}
+	if(iTestNum>=KServiceSearchAttributeRequestTest)
+	{
+		iType=EServiceSearchAttributeRequest;
+		iQueryState=EServiceSearchAttributeRequest;
+	}
+	SDPQueryL();
+	}
+
+void CSdpVerificationTests::DoTestsL()
+	{
+
+	// Initialisation stuff
+	//
+    RSocketServ ss;
+	TInt ret=ss.Connect();
+    if(ret!=KErrNone)
+		{
+		iConsole.Printf(_L("l2cap: no connection"));
+		return;
+		}
+
+	TUint numProtocols;
+	if(ss.NumProtocols(numProtocols)!=KErrNone)
+		{
+		iConsole.Printf(_L("l2cap: no protocols"));
+		return;
+		}
+ 	TProtocolDesc pInfo;
+
+	ret=ss.FindProtocol(_L("L2CAP"),pInfo);
+	if (ret!=KErrNone)										    
+		{
+		iConsole.Printf(_L("l2cap datagram protocol not loaded"));
+		return;
+		}
+
+
+	User::LeaveIfError(iRawSock.Open(ss,pInfo.iAddrFamily,pInfo.iSockType,pInfo.iProtocol));
+
+	WaitForStartSignalL();
+	SdpConnectL();
+
+	for(iTestNum=KServiceRequestTest;iTestNum<=KSdpLastTest;iTestNum++)
+		{
+		// Do any synching required here
+		//
+		// Reset the continuation buffer
+		iContinuationStore.SetLength(0);
+		if(AnotherQuery())
+		//These two query tests not reomoved from current spec
+			{
+			continue;
+			}
+		/*
+		//MASK UNWANTED TEST or SPECIFY WANTED TESTS HERE!
+		if(iTestNum!=1&&
+		   iTestNum!=8&&
+		   iTestNum!=34&&
+		   iTestNum!=53&&
+		   iTestNum!=54)
+			{
+			continue;
+			}
+		*/
+		if(iTestNum!=34) continue;
+
+		iConsole.Printf(_L("\r\n\r\n"));
+		FLOG(_L(""));
+		FLOG(_L(""));
+		if(/*iTestNum<KServiceRequestTest*/EFalse)
+			; //do nothing
+		else if(/*iTestNum>=KServiceRequestTest&&*/iTestNum<KServiceAttributeRequestTest)
+			{
+			iType = EServiceRequest; //allows skip of first SS test
+			iQueryState=EServiceRequest;
+			for(TUint j = 0;j < 3;j++)
+				{
+				switch(j)
+					{
+					case 0:
+					iUuidType = CSdpTestBase::EUuid16;
+					break;
+					case 1:
+					iUuidType = CSdpTestBase::EUuid32;
+					break;
+					default:
+					iUuidType = CSdpTestBase::EUuid128;
+					break;
+					}
+				UpdateTestString();
+				FTRACE(FPrint(_L("Starting %S..."), &iTestName));
+				FLOG(_L(""));
+				iConsole.Printf(_L("Starting %S...\r\n"), &iTestName);
+
+				TRAPD(err, RunMasterTestL());
+				FTRACE(FPrint(_L("%S returned with error %d. (0 => success!)"), &iTestName, err));
+				FTRACE(FPrint(_L("")));
+				FTRACE(FPrint(_L("")));
+				FTRACE(FPrint(_L("")));
+				iConsole.Printf(_L("%S returned with error %d. (0 => success!)\r\n"), &iTestName, err);
+				PromptedGetch();
+				}
+			}
+		else if(iTestNum>=KServiceAttributeRequestTest&&iTestNum<KServiceSearchAttributeRequestTest)
+			{
+			iType = EServiceAttributeRequest; //allows skip of first SA test
+			iQueryState=EServiceAttributeRequest;
+			iUuidType = CSdpTestBase::EUuid16;
+			UpdateTestString();
+			FTRACE(FPrint(_L("Starting %S..."), &iTestName));
+			FLOG(_L(""));
+			iConsole.Printf(_L("Starting %S...\r\n"), &iTestName);
+
+			TRAPD(err, RunMasterTestL());
+			FTRACE(FPrint(_L("%S returned with error %d. (0 => success!)"), &iTestName, err));
+			FTRACE(FPrint(_L("")));
+			FTRACE(FPrint(_L("")));
+			FTRACE(FPrint(_L("")));
+			iConsole.Printf(_L("%S returned with error %d. (0 => success!)\r\n"), &iTestName, err);
+			PromptedGetch();
+			}
+		else if(iTestNum>=KServiceSearchAttributeRequestTest && iTestNum<KSdpBrowseTest)
+			{
+			iType = EServiceSearchAttributeRequest; //allows skip of first SSA test
+			iQueryState=EServiceSearchAttributeRequest;
+#ifdef SEVEN_LAYERS_BUG
+			for(TUint j = 0;j < 1;j++)
+#else
+			for(TUint j = 0;j < 3;j++)
+#endif
+				{
+				switch(j)
+					{
+					case 0:
+						iUuidType = CSdpTestBase::EUuid16;
+						break;
+					case 1:
+						iUuidType = CSdpTestBase::EUuid32;
+						break;
+					default:
+						iUuidType = CSdpTestBase::EUuid128;
+						break;
+					}
+				UpdateTestString();
+				FTRACE(FPrint(_L("Starting %S..."), &iTestName));
+				FLOG(_L(""));
+				iConsole.Printf(_L("Starting %S...\r\n"), &iTestName);
+
+				TRAPD(err, RunMasterTestL());
+				FTRACE(FPrint(_L("%S returned with error %d. (0 => success!)"), &iTestName, err));
+				FTRACE(FPrint(_L("")));
+				FTRACE(FPrint(_L("")));
+				FTRACE(FPrint(_L("")));
+				iConsole.Printf(_L("%S returned with error %d. (0 => success!)\r\n"), &iTestName, err);
+				PromptedGetch();
+				}
+			}
+		else
+			{
+			TInt browseRet = KErrNone;
+			for(TUint j = 0;j < 3;j++)
+				{
+				switch(j)
+					{
+					case 0:
+						iUuidType = CSdpTestBase::EUuid16;
+						break;
+					case 1:
+						iUuidType = CSdpTestBase::EUuid32;
+						break;
+					default:
+						iUuidType = CSdpTestBase::EUuid128;
+						break;
+					}
+
+				UpdateTestString();
+				FTRACE(FPrint(_L("Starting %S..."), &iTestName));
+				FLOG(_L(""));
+				iConsole.Printf(_L("Starting %S...\r\n"), &iTestName);
+				while(iBrowseIter<3)
+					{
+					TRAPD(err, SDPBrowseTestL(iUuidType));
+					if(err)
+						{
+						iBrowseIter++; //for messages/logging - this would have been jumped!
+						}
+
+					FTRACE(FPrint(_L("%S: Stage %d - returned with error %d (0 => success!)"), &iTestName, iBrowseIter, err));
+					FTRACE(FPrint(_L("")));
+					FTRACE(FPrint(_L("")));
+					FTRACE(FPrint(_L("")));
+					iConsole.Printf(_L("%S: Stage %d: returned with error %d (0 => success!)\r\n"), &iTestName, iBrowseIter, err);
+					browseRet = err;
+					if(browseRet!=KErrNone)
+						{
+						break;
+						}
+					}
+				iBrowseIter = 0;
+				PromptedGetch();
+				}
+			}
+		
+		}//end of for loop
+	SendCloseL();
+	}
+
+void CSdpVerificationTests::SDPQueryL()
+	{
+	TRequestStatus stat1;
+	TRequestStatus stat2;
+	
+	// Buffers for sending/receiving requests
+	// (use 700 so it 3ill definitely be big enough).
+	TBuf8<700> queryResult1;
+	TBuf8<700> queryResult2;
+	
+	iQueryIndex = 0;
+	
+	// Continue round this loop until finished
+	// 
+	TBool bContinue = ETrue;
+	while(bContinue)
+	{
+		// Run the first query 
+		//
+		RunSDPSearchL();
+		// Do we have to do another query as well??
+		//
+		TBool anotherQuery = AnotherQuery();
+		if(anotherQuery)
+		{
+			iQueryIndex++;
+			RunSDPSearchL();
+		}
+		// Wait for reply(s)
+		//
+		iRawSock.Read(queryResult1, stat1);
+		User::WaitForRequest(stat1);
+		if (stat1!=KErrNone)
+		{
+			iConsole.Printf(_L("First query failed\n"));
+			User::Leave(stat1.Int());
+		}
+		FlogReadString(queryResult1);
+
+		if(anotherQuery)
+		{
+			iRawSock.Read(queryResult2, stat2);
+			User::WaitForRequest(stat2);
+			if (stat2!=KErrNone)
+			{
+				iConsole.Printf(_L("Second query failed\n"));
+				User::Leave(stat1.Int());
+			}
+			FlogReadString(queryResult2);
+		}
+		
+		// Now process the results
+		//
+		User::LeaveIfError(ProcessSearchResults(queryResult1, queryResult2));
+		// Reset stuff
+		iQueryIndex = 0;
+
+		bContinue=Continue();
+	}
+}
+
+
+void CSdpVerificationTests::RunSDPSearchL()
+	{
+	// Run the appropiate query
+	//
+	if(iQueryState==EServiceRequest)
+	{
+		SDPServiceSearchL();
+	}
+	else if(iQueryState==EServiceAttributeRequest)
+	{
+		SDPAttributeSearchL();
+	}
+	else 
+	{
+		SDPServiceAttributeSearch();
+	}
+
+	}
+
+
+ void CSdpVerificationTests::SDPServiceSearchL()
+	{
+	
+	// If aLoop == 1, the first and second tests need to be run concurrently
+	//
+	TInt paramsIndex = iTestNum;
+	if((iTestNum==1)&&(iQueryIndex==0))
+	{
+		paramsIndex = 0;
+	}	
+	// Set up the raw buffer.
+	// First create the SDP header
+	//
+	TUint16 paramsSize = TUint16(KServiceParamsSize16);
+	switch(iUuidType)
+		{
+	case CSdpTestBase::EUuid16:
+		paramsSize = KServiceParamsSize16;
+		break;
+	case CSdpTestBase::EUuid32:
+		paramsSize = KServiceParamsSize32;
+		break;
+	case CSdpTestBase::EUuid128:
+		paramsSize = KServiceParamsSize128;
+		break;
+	default:
+		break;
+		}
+	if(iTestNum==4)
+	{
+		// This is the invalid PDU length test
+		//
+		paramsSize+=1;
+	}
+	TSDPHeader header(0x02, iRawTransactionId++, TUint16(paramsSize + iContLength + 1));
+	 
+	//Now add these to the query
+	//
+	TRequestStatus writeStat;
+	TBuf8<100> request;
+	request.Zero();
+	header.AppendHeader(request);
+	iServiceTests[paramsIndex].SetUuidType(iUuidType); //update with current uuid type
+	iServiceTests[paramsIndex].AppendRequest(request);
+	request.Append(&iContLength, 1);
+	request.Append(iContinuationBuffer, iContLength);
+	FlogWriteString(request);
+	iRawSock.Write(request, writeStat);
+	User::WaitForRequest(writeStat);
+	}
+
+void CSdpVerificationTests::SDPAttributeSearchL()
+	{
+	TRequestStatus writeStat;
+	TBuf8<100> request;
+	TRequestStatus readStat;
+	TBuf8<700> queryResult1;
+	TBuf8<700> queryResult2;
+	request.Zero();
+	TUint8 loop = 1;
+	iNeedMoreRecordHandles = EFalse;
+	iAttributeTestServiceRecordHandle = KUselessRecordHandle;
+	TBool doSS = ETrue;
+	if(iTestNum==26||(iTestNum==7&&iQueryIndex!=0))
+		{
+		doSS = EFalse;
+		}
+	if(doSS)
+		{
+		while(loop)
+			{
+			TServiceRequest serviceRequest;
+			TSDPHeader header = TSDPHeader(0x02, iRawTransactionId++, TUint16(KServiceParamsSize16 + iContLength + 1));//cont length byte);
+			serviceRequest = TServiceRequest(KAttributeTestsServiceUUID, EUuid16, 1);
+			request.Zero();
+			header.AppendHeader(request);
+			serviceRequest.AppendRequest(request);
+			request.Append(&iContLength, 1);
+			request.Append(iContinuationBuffer, iContLength);
+			FlogWriteString(request);
+			iRawSock.Write(request, writeStat);
+			User::WaitForRequest(writeStat);
+			// Wait for reply
+			//
+			iRawSock.Read(queryResult1, readStat);
+			User::WaitForRequest(readStat);
+			User::LeaveIfError(readStat.Int());
+			// Process results (fills up browse record handle array)
+			//
+			FlogReadString(queryResult1);
+			User::LeaveIfError(ProcessServiceSearchResults(queryResult1, queryResult2));
+			loop = iContLength;
+			}
+		}
+	
+	
+	// If aLoop ==7 the first and second tests need to be run concurrently
+	//
+	iNeedAttributeId = ETrue;
+	TInt paramsIndex = iTestNum;
+	if((iTestNum==7)&&(iQueryIndex==0))
+	{
+		paramsIndex = 6;
+	}	
+	// Now take off the index of the service tests
+	//
+	paramsIndex -= KNumSDPServiceTests;
+
+	// Set up the raw buffer.
+	// First create the SDP header
+	//
+	TUint16 paramLen = TUint16(KAttributeParamsSize + iContLength + 1);//cont length byte
+	if(iTestNum==28)
+	{
+		// This is the invalid PDU length test
+		//
+		paramLen+=1;
+	}
+	TSDPHeader header(0x04, iRawTransactionId++, paramLen);
+	 
+	//Now add these to the query
+	//
+	request.Zero();
+	header.AppendHeader(request);
+	if(doSS)
+		{
+		if(iAttributeTestServiceRecordHandle==KUselessRecordHandle)
+			User::Leave(KErrGeneral);
+		//***********//
+		//overwrite requested record handle with result of 
+		//initial service search (required by spec)
+		iAttributeTests[paramsIndex].SetRecordHandle((TUint16)iAttributeTestServiceRecordHandle); 
+		}
+	//***********//
+	iAttributeTests[paramsIndex].AppendRequest(request);
+	request.Append(&iContLength, 1);
+	request.Append(iContinuationBuffer, iContLength);
+	FlogWriteString(request);
+	iRawSock.Write(request, writeStat);
+	User::WaitForRequest(writeStat);
+}
+
+void CSdpVerificationTests::SDPServiceAttributeSearch()
+	{
+	iNeedAttributeId = ETrue;
+	// If aLoop == 33 the first and second tests need to be run concurrently
+	//
+	TInt paramsIndex = iTestNum;
+	if((iTestNum==33)&&(iQueryIndex==0))
+	{
+		paramsIndex = 32;
+	}	
+	// Now take off the index of the Service and Attribute tests
+	//
+	paramsIndex -= (KNumSDPServiceTests + KNumSDPAttributeTests);
+
+	// Set up the raw buffer.
+	// First create the SDP header
+	//
+	TUint16 paramsSize = TUint16(KServiceAttributeParamsSize16);
+
+	switch(iUuidType)
+		{
+	case CSdpTestBase::EUuid16:
+		paramsSize = KServiceAttributeParamsSize16;
+		break;
+	case CSdpTestBase::EUuid32:
+		paramsSize = KServiceAttributeParamsSize32;
+		break;
+	case CSdpTestBase::EUuid128:
+		paramsSize = KServiceAttributeParamsSize128;
+		break;
+	default:
+		break;
+		}
+#ifdef SEVEN_LAYERS_BUG
+#else
+	if(iTestNum==34)
+		{
+		paramsSize += 2;	// This is the one test that uses an attr range parameter
+		}
+#endif
+
+	if(iTestNum==52)
+		{
+		paramsSize += 1;	// This is the invalid PDU length test
+		}
+
+	TSDPHeader header(0x06, iRawTransactionId++, TUint16(paramsSize + iContLength + 1));
+	 
+	//Now add these to the query
+	//
+	TRequestStatus writeStat;
+	TBuf8<100> request;
+	request.Zero();
+	header.AppendHeader(request);
+	iServiceAttributeTests[paramsIndex].SetUuidType(iUuidType); //update with current uuid type
+	iServiceAttributeTests[paramsIndex].AppendRequest(request);
+	request.Append(&iContLength, 1);
+	request.Append(iContinuationBuffer, iContLength);
+	FlogWriteString(request);
+	iRawSock.Write(request, writeStat);
+	User::WaitForRequest(writeStat);
+	}
+/*
+header = TSDPHeader(0x06, iRawTransactionId++, TUint16(ssaParamsSize + iContLength + 1));//cont length byte);
+servAttrRequest = TServiceAttributeRequest(iSP->At(j), aUuidType, 200, attrUUID);
+request.Zero();
+header.AppendHeader(request);
+servAttrRequest.AppendRequest(request);
+request.Append(&iContLength, 1);
+request.Append(iContinuationBuffer, iContLength);
+*/
+
+void CSdpVerificationTests::SDPBrowseTestL(CSdpTestBase::TUuidType aUuidType)
+	{
+	TSDPHeader header;
+	TUint16 serviceUUID = 0;
+	TUint16 attrUUID = 0;
+	TInt ssParamsSize = KServiceParamsSize16;
+	TInt ssaParamsSize = KServiceAttributeParamsSize16;
+
+	switch(aUuidType)
+		{
+	case CSdpTestBase::EUuid16:
+		ssParamsSize = KServiceParamsSize16;
+		ssaParamsSize = KServiceAttributeParamsSize16;
+		break;
+	case CSdpTestBase::EUuid32:
+		ssParamsSize = KServiceParamsSize32;
+		ssaParamsSize = KServiceAttributeParamsSize32;
+		break;
+	case CSdpTestBase::EUuid128:
+		ssParamsSize = KServiceParamsSize128;
+		ssaParamsSize = KServiceAttributeParamsSize128;
+		break;
+	default:
+		break;
+		}
+
+	
+	//Reset for next level browse query
+	iContLength = 0;
+	iContinuationStore.SetLength(0);
+	iBrowseTestNumRecordHandlesStored = 0;
+	for (TUint i = 0; i < KMaxNumRecordHandles; i ++)
+		{
+		iBrowseTestServiceRecordHandle[i] = KUselessRecordHandle; //we want test database NOT to need this handle!
+		}
+
+
+	TRequestStatus writeStat;
+	TBuf8<100> request;
+	TRequestStatus readStat;
+	TBuf8<700> queryResult1;
+	TBuf8<700> queryResult2;
+	if(iTestNum == KSdpBrowseTest)
+		{
+		// This pattern repeats the search/atrribute request pattern
+		//
+		switch(iBrowseIter)
+			{
+		case 0:
+			serviceUUID = 0x1002;	// Public browse group
+			FLOG(_L("***********FIRST PHASE SERVICE SEARCH TRANSACTION(S)**************"));
+			FTRACE(FPrint(_L("***********uses single UUID 0x%04x***********"), serviceUUID));
+			break;
+		case 1:	
+			iSP->Reset();
+			serviceUUID = 0x1001;	// Browse group descriptor class ID
+			FLOG(_L("***********SECOND PHASE SERVICE SEARCH TRANSACTION(S)**************"));
+			FTRACE(FPrint(_L("***********uses single UUID 0x%04x***********"), serviceUUID));
+			break;
+		case 2:
+			{
+			if(iSP->Count()<=0)
+				{
+				User::Leave(KErrGeneral);
+				}
+			TPtrC8 uuid = iBrowseUUID[0].ShortestForm();
+			serviceUUID = BigEndian::Get16(uuid.Ptr());
+			FLOG(_L("***********THIRD PHASE SERVICE SEARCH TRANSACTION(S)**************"));
+			FTRACE(FPrint(_L("***********uses single UUID 0x%04x***********"), serviceUUID));
+			}
+			break;
+		default:
+			User::Leave(KErrGeneral);
+			break;
+			}
+		TUint8 loop = 1;
+		iNeedMoreRecordHandles = EFalse;
+		while(loop)
+			{
+			TServiceRequest serviceRequest;
+			if(iBrowseIter==2)
+				{
+				iNeedMoreRecordHandles = ETrue;
+				TInt j = 0;
+				while(j<iSP->Count())
+					{
+					header = TSDPHeader(0x02, iRawTransactionId++, TUint16(ssParamsSize + iContLength + 1));//cont length byte);
+					serviceRequest = TServiceRequest(iSP->At(j), aUuidType, KMaxNumRecordHandles);
+					request.Zero();
+					header.AppendHeader(request);
+					serviceRequest.AppendRequest(request);
+					request.Append(&iContLength, 1);
+					request.Append(iContinuationBuffer, iContLength);
+					FlogWriteString(request);
+					iRawSock.Write(request, writeStat);
+					User::WaitForRequest(writeStat);
+					// Wait for reply
+					//
+					iRawSock.Read(queryResult1, readStat);
+					User::WaitForRequest(readStat);
+					User::LeaveIfError(readStat.Int());
+					// Process results (fills up browse record handle array)
+					//
+					FlogReadString(queryResult1);
+					User::LeaveIfError(ProcessServiceSearchResults(queryResult1, queryResult2));
+					if(!iContLength)
+						j++;
+					}
+				iNeedMoreRecordHandles = EFalse;
+				}
+			else
+				{
+				header = TSDPHeader(0x02, iRawTransactionId++, TUint16(ssParamsSize + iContLength + 1));//cont length byte);
+				serviceRequest = TServiceRequest(/*UuidDes, */serviceUUID, aUuidType, KMaxNumRecordHandles);
+				request.Zero();
+				header.AppendHeader(request);
+				serviceRequest.AppendRequest(request);
+				request.Append(&iContLength, 1);
+				request.Append(iContinuationBuffer, iContLength);
+				FlogWriteString(request);
+				iRawSock.Write(request, writeStat);
+				User::WaitForRequest(writeStat);
+				// Wait for reply
+				//
+				iRawSock.Read(queryResult1, readStat);
+				User::WaitForRequest(readStat);
+				User::LeaveIfError(readStat.Int());
+				// Process results (fills up browse record handle array)
+				//
+				FlogReadString(queryResult1);
+				User::LeaveIfError(ProcessServiceSearchResults(queryResult1, queryResult2));
+				}
+			loop = iContLength;
+			}
+		// the and attribute query on the first record handle for service class id list...
+		//
+		switch(iBrowseIter)
+			{
+		case 0:
+			attrUUID = KSdpAttrIdServiceClassIDList;
+			FLOG(_L("***********FIRST PHASE ATTRIBUTE SEARCH TRANSACTION(S)**************"));
+			FTRACE(FPrint(_L("***********uses single attr id 0x%04x***********"), attrUUID));
+			break;
+		case 1:
+			attrUUID = KSdpAttrIdSdpServerGroupID;
+			FLOG(_L("***********SECOND PHASE ATTRIBUTE SEARCH TRANSACTION(S)**************"));
+			FTRACE(FPrint(_L("***********uses single attr id 0x%04x***********"), attrUUID));
+			break;
+		case 2:
+			attrUUID = KSdpAttrIdServiceClassIDList;
+			FLOG(_L("***********THIRD PHASE ATTRIBUTE SEARCH TRANSACTION(S)**************"));
+			FTRACE(FPrint(_L("***********uses single attr id 0x%04x***********"), attrUUID));
+			break;
+		default:
+			User::Leave(KErrGeneral);
+			break;
+			}
+		TUint i = 0;
+		iContLength = 0; //make sure: new attribute request
+		iContinuationStore.SetLength(0);
+		for (TUint j = 0; j < KMaxNumBrowseUUIDs; j ++)
+			{
+			iBrowseUUID[i] = KUselessRecordHandle; //we want test database NOT to need this UUID!
+			}
+		iNumBrowseUUIDs = 0;
+		while(i < iBrowseTestNumRecordHandlesStored)
+			{
+			TAttributeRequest attrRequest;
+			if(iBrowseTestServiceRecordHandle[i]==KUselessRecordHandle)
+				{
+				i++;
+				continue;
+				}
+			header = TSDPHeader(0x04, iRawTransactionId++, TUint16(KAttributeParamsSize + iContLength + 1));//cont length byte);
+			attrRequest = TAttributeRequest(iBrowseTestServiceRecordHandle[i], 200, attrUUID);
+			writeStat = KRequestPending;
+			request.Zero();
+			header.AppendHeader(request);
+			attrRequest.AppendRequest(request);
+			request.Append(&iContLength, 1);
+			request.Append(iContinuationBuffer, iContLength);
+			FlogWriteString(request);
+			iRawSock.Write(request, writeStat);
+			User::WaitForRequest(writeStat);
+					
+			// Wait for reply
+			//
+			readStat = KRequestPending;
+			iRawSock.Read(queryResult1, readStat);
+			User::WaitForRequest(readStat);
+			User::LeaveIfError(readStat.Int());
+			// Process results
+			//
+			FlogReadString(queryResult1);
+			User::LeaveIfError(ProcessAttributeSearchResults(queryResult1, queryResult2));
+			if(!iContLength)
+				i++; //augment ready for next record handle only if no continuation.
+			}
+		// Increment tree level counter
+		//
+		iBrowseIter++;
+		
+		}
+	else
+		{
+		header = TSDPHeader(0x06, iRawTransactionId++, TUint16(ssaParamsSize + iContLength + 1));
+		switch(iBrowseIter)
+			{
+		case 0:
+			serviceUUID = 0x1002;	// Public browse group
+			attrUUID = KSdpAttrIdServiceClassIDList;
+			FLOG(_L("***********FIRST PHASE SERVICE SEARCH ATTRIBUTE TRANSACTION(S)**************"));
+			FTRACE(FPrint(_L("***********uses single UUID 0x%04x, and single attr id 0x%04x***********"), serviceUUID, attrUUID));
+			break;
+		case 1:	
+			serviceUUID = 0x1001;	// Browse group descriptor class ID
+			attrUUID = KSdpAttrIdSdpServerGroupID;
+			FLOG(_L("***********SECOND PHASE SERVICE SEARCH ATTRIBUTE TRANSACTION(S)**************"));
+			FTRACE(FPrint(_L("***********uses single UUID 0x%04x, and single attr id 0x%04x***********"), serviceUUID, attrUUID));
+			break;
+		case 2:
+			serviceUUID = (TUint16)KGenericNetworkingUUID;	// Generic networking
+			attrUUID = KSdpAttrIdServiceClassIDList;
+			FLOG(_L("***********THIRD PHASE SERVICE SEARCH ATTRIBUTE TRANSACTION(S)**************"));
+			FTRACE(FPrint(_L("***********uses single UUID 0x%04x, and single attr id 0x%04x***********"), serviceUUID, attrUUID));
+			break;
+		default:
+			User::Leave(KErrGeneral);
+			break;
+			}
+
+		TUint8 loop = 1;
+		iNeedMoreRecordHandles = EFalse;
+		while(loop)
+			{
+			TServiceAttributeRequest servAttrRequest;
+			if(iBrowseIter==2)
+				{
+				iNeedMoreRecordHandles = ETrue;
+				TInt j = 0;
+				while(j<iSP->Count())
+					{
+					header = TSDPHeader(0x06, iRawTransactionId++, TUint16(ssaParamsSize + iContLength + 1));//cont length byte);
+					servAttrRequest = TServiceAttributeRequest(iSP->At(j), aUuidType, 200, attrUUID);
+					request.Zero();
+					header.AppendHeader(request);
+					servAttrRequest.AppendRequest(request);
+					request.Append(&iContLength, 1);
+					request.Append(iContinuationBuffer, iContLength);
+					FlogWriteString(request);
+					iRawSock.Write(request, writeStat);
+					User::WaitForRequest(writeStat);
+					// Wait for reply
+					//
+					readStat = KRequestPending;
+					iRawSock.Read(queryResult1, readStat);
+					User::WaitForRequest(readStat);
+					User::LeaveIfError(readStat.Int());
+					// Process results
+					//
+					FlogReadString(queryResult1);
+					User::LeaveIfError(ProcessServiceAttributeSearchResults(queryResult1, queryResult2));
+					if(!iContLength)
+						j++;
+					}
+				iNeedMoreRecordHandles = EFalse;
+				}
+			else
+				{
+				header = TSDPHeader(0x06, iRawTransactionId++, TUint16(ssaParamsSize + iContLength + 1));//cont length byte);
+				servAttrRequest = TServiceAttributeRequest(serviceUUID, aUuidType, 200, attrUUID);
+				//Now add these to the query
+				//
+				TRequestStatus writeStat;
+				TRequestStatus readStat;
+				TBuf8<700> queryResult1;
+				TBuf8<700> queryResult2;
+				TBuf8<100> request;
+				request.Zero();
+				header.AppendHeader(request);
+				servAttrRequest.AppendRequest(request);
+				request.Append(&iContLength, 1);
+				request.Append(iContinuationBuffer, iContLength);
+				FlogWriteString(request);
+				iRawSock.Write(request, writeStat);
+				User::WaitForRequest(writeStat);
+				// Wait for reply
+				//
+				readStat = KRequestPending;
+				iRawSock.Read(queryResult1, readStat);
+				User::WaitForRequest(readStat);
+				User::LeaveIfError(readStat.Int());
+				// Process results
+				//
+				FlogReadString(queryResult1);
+				User::LeaveIfError(ProcessServiceAttributeSearchResults(queryResult1, queryResult2));
+				
+				}
+			loop = iContLength;
+			}
+		// Increment tree level counter
+		//
+		iBrowseIter++;
+		}
+	}
+
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+//--
+
+
+
+TInt CSdpVerificationTests::ProcessSearchResults(TDesC8& aResult1, TDesC8& aResult2)
+	{
+	// Process accordingly
+	//
+	TInt ret = KErrNone;
+	if(iQueryState==EServiceRequest)
+	{
+		ret = ProcessServiceSearchResults(aResult1, aResult2);
+	}
+	else if(iQueryState==EServiceAttributeRequest)
+	{
+		ret = ProcessAttributeSearchResults(aResult1, aResult2);
+	}
+	else
+	{
+		ASSERT_DEBUG(iQueryState==EServiceSearchAttributeRequest);
+		ret = ProcessServiceAttributeSearchResults(aResult1, aResult2);
+	}
+	return ret;
+	}
+
+TInt CSdpVerificationTests::ProcessServiceSearchResults(TDesC8& aResult1, TDesC8& aResult2)
+	{
+
+	TInt ret = KErrGeneral;
+
+	// Have we found any records?
+	//
+	TBool haveRecords = ETrue;
+	if (aResult1.Length() < KMinResponseSize)	
+	{
+		haveRecords = EFalse;
+	}
+	if(iTestNum == 1)
+	{
+		// Check the second result completed with records too
+		if((haveRecords) && (aResult2.Length() < 8))
+		{
+			haveRecords = EFalse;
+		}
+	}
+
+	// The test document dictates that size comparisons must be carried out.
+	//
+
+	TUint16 totalRecordCount = 0;
+	TUint16 currentRecordCount = 0;
+	TUint16 totalRecordCount2 = 0;
+	TUint16 currentRecordCount2 = 0;
+	if(haveRecords)
+	{
+		totalRecordCount = BigEndian::Get16(&aResult1[KTotalCountOffset]);
+		currentRecordCount = BigEndian::Get16(&aResult1[KCurrentCountOffset]);
+		/*
+		...now done in FlogParsedPDUHeader(..)
+
+		if(currentRecordCount > totalRecordCount)
+		{
+			return KErrGeneral;
+		}
+		TUint maxRecordCount = KMaxNumRecordHandles;
+		if(iTestNum<KSdpBrowseTest)
+		{
+			maxRecordCount = iServiceTests[iTestNum].MaxRecordCount();
+		}
+		if(totalRecordCount > maxRecordCount)
+		{
+			return KErrGeneral;
+		}
+		*/
+		// Check the second buffer as well if necessary
+		//
+		if(iTestNum==1)
+		{
+			totalRecordCount2 = BigEndian::Get16(&aResult2[KTotalCountOffset]);
+			currentRecordCount2 = BigEndian::Get16(&aResult2[KCurrentCountOffset]);
+			if(currentRecordCount2 > totalRecordCount2)
+			{
+				return KErrGeneral;
+			}
+			if(totalRecordCount2 > iServiceTests[iTestNum].MaxRecordCount())
+			{
+				return KErrGeneral;
+			}
+		}
+	}
+
+
+	// The rest depends on which tests is being run...
+	//
+	TInt recordHandleOffset = KRecordHandleOffset;
+	if(iType==EServiceAttributeRequest)
+		{
+		if(haveRecords)
+			{
+			iAttributeTestServiceRecordHandle = BigEndian::Get32(&aResult1[recordHandleOffset]);
+			}
+		}
+	switch(iTestNum)
+	{
+	case 1:
+	case 0:
+	case 6:
+	case 7:
+	case 8:
+	case 9:
+	case 10:
+	case 11:
+	case 12:
+	case 13:
+	case 14:
+	case 15:
+	case 16:
+	case 17:
+	case 18:
+	case 19:
+	case 20:
+	case 21:
+	case 22:
+	case 23:
+	case 24:
+	case 25:
+	case 26:
+	case 27:
+	case 28:
+		if(haveRecords)
+		{
+			// Check the returned record is correct 
+			// Should only return the 1st record
+			//
+			if(currentRecordCount==1)
+			{
+				TUint32 serviceRecordHandle = BigEndian::Get32(&aResult1[recordHandleOffset]);
+				if(serviceRecordHandle==KSdpMinServRecordHandle)
+				{
+					ret = KErrNone;
+				}
+				
+				// Now check the second result
+				if((iTestNum==1)&& (ret==KErrNone))
+				{
+					serviceRecordHandle = BigEndian::Get32(&aResult2[recordHandleOffset]);
+					if(serviceRecordHandle!=KSdpMinServRecordHandle+1)
+					{
+						ret = KErrGeneral;
+					}
+				}
+			}
+		}
+		break;
+	case 2:
+		if(haveRecords)
+		{
+			// This one should have the continuation state set
+			// Offset of continuation byte =
+			// (CurrentServiceRecordCount * 4) + 4 + HeaderSize
+			TUint16	partial = TUint16((currentRecordCount * 4) + 4 + KSdpPduHeaderSize); 
+			iContLength = aResult1[partial];
+			TBuf8<20> cont;
+			cont.SetLength(0);
+			cont.Append(aResult1.Mid(partial));
+			FlogContinuationString(cont);
+			if (iContLength == 0)
+			{
+				// No continuation set. Is this the end or is there an error?
+				// Are these handles correct?
+				ret=KErrNone;
+				for(TInt i=0; i<currentRecordCount; i++)
+				{
+					TUint32 serviceRecordHandle = BigEndian::Get32(&aResult1[recordHandleOffset]);
+					recordHandleOffset += 4;	//Move to next handle;
+					if(serviceRecordHandle<KSdpMinServRecordHandle+3)
+					{
+						ret = KErrGeneral;
+					}
+				}
+			}
+			else
+			{
+				// Check these UUIDs first
+				//
+				ret = KErrNone;
+				for(TInt i=0; i<currentRecordCount; i++)
+				{
+					TUint32 serviceRecordHandle = BigEndian::Get32(&aResult1[recordHandleOffset]);
+					recordHandleOffset += 4;	//Move to next handle;
+					if(serviceRecordHandle<KSdpMinServRecordHandle+3)
+					{
+						ret = KErrGeneral;
+					}
+				}
+				if(ret==KErrNone)
+				{
+					Mem::Copy(iContinuationBuffer, &aResult1[partial+1], KSdpContinuationStateMaxLength);
+					TRAP(ret, SDPQueryL());
+					// Clear out the continuation state buffer ready for next query
+					//
+					Mem::FillZ( iContinuationBuffer,KSdpContinuationStateMaxLength);
+					iContLength = 0;
+				}
+			}
+		}
+		break;
+	case 3:
+		// Should get no records back here
+		if(haveRecords)
+		{	
+			if((totalRecordCount==currentRecordCount) && (totalRecordCount==0))
+			{
+				ret=KErrNone;
+			}
+		}
+		break;
+	case 4:
+	case 5:
+		// This should be the SDP_ErrorResponse PDU 
+		//
+		if(!haveRecords)	// Should be no records here
+		{
+			if(aResult1[0] == 0x01)
+			{
+				// This is an error response.
+				// Check the error code. It must either be 
+				// an invalid size or invalid syntax.
+				//
+				TInt16 errorCode = BigEndian::Get16(&aResult1[KErrorCodeOffset]);
+				if(((errorCode==EInvalidPduSize) && (iTestNum==4))
+					||((errorCode==EInvalidRequestSyntax) && (iTestNum==5)))
+				{
+					ret = KErrNone;
+				}
+				// Otherwise, wrong response.
+			}
+		}
+		break;
+	case 53:
+		if(haveRecords)
+		{
+			// Check the returned record is correct.
+			//
+			TUint16	partial = TUint16((currentRecordCount * 4) + 4 + KSdpPduHeaderSize); 
+
+			if(iBrowseIter/*=*/<=2)
+			{
+				ret = KErrNone;
+			}
+
+			for (TUint i = iBrowseTestNumRecordHandlesStored; 
+				 i < iBrowseTestNumRecordHandlesStored + currentRecordCount; 
+				 i ++)
+			{
+				iBrowseTestServiceRecordHandle[i] = BigEndian::Get32(&aResult1[recordHandleOffset]);
+				recordHandleOffset += 4;
+				for(TUint j = 0; j<i; j++)
+					{
+					if(iBrowseTestServiceRecordHandle[i]==iBrowseTestServiceRecordHandle[j])
+						//Check we are not repeating a handle
+						//and if so set that handle to 'KUselessRecordHandle'
+						//so that we ignore it!
+						{
+						iBrowseTestServiceRecordHandle[i] = KUselessRecordHandle; //indicates useless handle
+						break;
+						}
+					}
+			}
+
+			if(iContLength)
+				{
+				Mem::Copy(iContinuationBuffer, &aResult1[partial+1], KSdpContinuationStateMaxLength);
+				}
+			iBrowseTestNumRecordHandlesStored += currentRecordCount;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+	}
+
+
+TInt CSdpVerificationTests::ProcessServiceAttributeSearchResults(TDesC8& aResult1, TDesC8& aResult2)
+	{
+	TInt ret = KErrGeneral;
+	// Have got a response?
+	//
+	TBool haveResult = ETrue;
+	if (aResult1.Length() < KMinResponseSize)	
+	{
+		haveResult = EFalse;
+	}
+	if(iTestNum == 33)
+	{
+		// Check the second result completed with records too
+		if((haveResult) && (aResult2.Length() < KMinResponseSize))
+		{
+			haveResult = EFalse;
+		}
+	}
+	// The test document dictates that size comparisons must be carried out.
+	//
+	TUint16 byteCount1 = 0;
+	TUint16 byteCount2 = 0;
+	if(haveResult)
+	{
+		TUint16 intendedByteCount = 200;
+		if(iTestNum<KSdpBrowseTest)
+		{
+			intendedByteCount = iServiceAttributeTests[iTestNum - KNumSDPServiceTests - KNumSDPServiceAttributeTests].MaxByteCount();
+		}
+		byteCount1 = BigEndian::Get16(&aResult1[KAttributeByteCountOffset]);
+		if(byteCount1 > intendedByteCount)
+		{
+			return KErrGeneral;
+		}
+		//Now check the second buffer if necessary
+		//
+		if(iTestNum==33)
+		{
+			byteCount2 = BigEndian::Get16(&aResult2[KAttributeByteCountOffset]);
+			if(byteCount2 > iServiceAttributeTests[iTestNum - KNumSDPServiceTests - KNumSDPServiceAttributeTests].MaxByteCount())
+			{
+				return KErrGeneral;
+			}
+		}
+	}
+	
+	// Now parse what we've got back
+	//
+	if(haveResult)
+	{
+		if(byteCount1==0)
+		{
+			if((iTestNum==29) || (iTestNum==30)	|| (iTestNum==31))
+			{
+				// the non-existing attribute/service test
+				ret = KErrNone;
+			}
+		}
+		else
+		{
+			#ifdef PRINT_BUILDER
+				TRAP(ret,MSdpElementBuilder* builder = (MSdpElementBuilder*)new(ELeave)CPrintBuilder(iConsole));
+				if (ret != KErrNone)
+					{
+					return ret;
+					}
+			#else
+				MSdpElementBuilder* builder = this;
+			#endif
+			
+			if(iTestNum>=KSdpBrowseTest)
+			{
+				TRAP(ret,builder = (MSdpElementBuilder*)new(ELeave)CBrowseResponseBuilder(iTestName,iBrowseIter/*,iTestNum - KSdpBrowseTest + 1, GetUuidSize()*/, *iSP));
+				if (ret != KErrNone)
+					{
+					return ret;
+					}
+			}
+			
+			CElementParser* parser = NULL;
+			TRAP(ret,parser = CElementParser::NewL(builder));
+			if (ret != KErrNone)
+				{
+				return ret;
+				}
+			TRAP(ret,CleanupStack::PushL(parser));
+			if (ret != KErrNone)
+				{
+				return ret;
+				}
+					
+			// Get the offset of the continuation state
+			TUint16	attributeListLength = BigEndian::Get16(&aResult1[KSdpPduHeaderSize]);
+			TUint16 partial = TUint16(attributeListLength + KSdpPduHeaderSize + 2);
+			iContLength = aResult1[partial];
+			TBuf8<20> cont;
+			cont.SetLength(0);
+			cont.Append(aResult1.Mid(partial));
+			FlogContinuationString(cont);
+
+			if (iTestNum == 34)
+			{
+				// This one should have the continuation state set so do another query.
+				iContinuationStore.Append(aResult1.Mid(KAttributeListOffset, attributeListLength));
+				if (iContLength != 0)
+				{
+					Mem::Copy(iContinuationBuffer, &aResult1[partial+1], KSdpContinuationStateMaxLength);
+					TRAPD(err, SDPQueryL());
+					ret = err;
+					// Clear out the continuation state buffer ready for next query
+					//
+					Mem::FillZ( iContinuationBuffer,KSdpContinuationStateMaxLength);
+					iContLength = 0;
+				}
+				else
+				{
+					TRAPD(err, parser->ParseElementsL(iContinuationStore));
+					ret = err;
+					iContinuationStore.SetLength(0);
+				}
+			}
+			else if(iTestNum>=KSdpBrowseTest)
+			{
+			// This one might have the continuation state set so prepare, 
+			// if necessary, for another query.
+				iContinuationStore.Append(aResult1.Mid(KAttributeListOffset, attributeListLength));
+				if (iContLength != 0)
+				{
+					Mem::Copy(iContinuationBuffer, &aResult1[partial+1], KSdpContinuationStateMaxLength);
+					ret = KErrNone;
+				}
+				else
+				{
+					TRAPD(err, parser->ParseElementsL(iContinuationStore));
+					ret = err;
+					iContinuationStore.SetLength(0);
+				}
+			}
+			else
+			{
+				TRAPD(err,parser->ParseElementsL(aResult1.Mid(KAttributeListOffset, attributeListLength)));
+				ret = err;
+			}
+
+			if((ret==KErrNone)&&(iTestNum == 33))
+			{
+				// We need to parse the second buffer as well.
+				//
+				if((byteCount2!=0))
+				{
+					iNeedAttributeId = ETrue;
+					TUint16	attributeListLength2 = BigEndian::Get16(&aResult2[KSdpPduHeaderSize]);
+					TRAPD(err,ret=parser->ParseElementsL(aResult2.Mid(KAttributeListOffset, attributeListLength2)));
+					if (err)
+						{
+						ret = err;
+						}
+				}
+			}
+			if(iTestNum>=KSdpBrowseTest)
+			{
+				delete (CBrowseResponseBuilder*)builder;
+				builder = 0;
+			}
+			#ifdef PRINT_BUILDER
+			delete (CPrintBuilder*)builder;
+			iConsole.Printf(_L("Press any key.\r\n"));
+			iConsole.Getch();
+			#endif
+			
+			CleanupStack::PopAndDestroy(parser);
+		}
+	}
+	else
+	{
+		// What's left should be invalid behaviour tests
+		// ie. the SDP_ErrorResponse PDU 
+		if(aResult1[0] == 0x01)
+		{
+			// This is an error response.
+			// Check the error code. It must either be 
+			// an invalid size, invalid syntax or invalid record handle.
+			//
+			TInt16 errorCode = BigEndian::Get16(&aResult1[KErrorCodeOffset]);
+				if(((errorCode==EInvalidPduSize) && (iTestNum==52))
+					||((errorCode==EInvalidRequestSyntax) && (iTestNum==51)))
+				{
+					ret = KErrNone;
+				}
+			// Otherwise, wrong response.
+		}
+	}
+	iContLength = 0; //reset
+	return ret;
+	}
+
+
+TInt CSdpVerificationTests::ProcessAttributeSearchResults(TDesC8& aResult1, TDesC8& aResult2)
+	{
+	TInt ret = KErrGeneral;
+	// Have got a response?
+	//
+	TBool haveResult = ETrue;
+	if (aResult1.Length() < KMinResponseSize)	
+	{
+		haveResult = EFalse;
+	}
+	if(iTestNum == 7)
+	{
+		// Check the second result completed with records too
+		if((haveResult) && (aResult2.Length() < KMinResponseSize))
+		{
+			haveResult = EFalse;
+		}
+	}
+	// The test document dictates that size comparisons must be carried out.
+	//
+	TUint16 byteCount1 = 0;
+	TUint16 byteCount2 = 0;
+	if(haveResult)
+	{
+		TUint16 intendedByteCount = 200;
+		if(iTestNum<KSdpBrowseTest)
+		{
+			intendedByteCount = iAttributeTests[iTestNum - KNumSDPServiceTests].MaxByteCount();
+		}	
+		byteCount1 = BigEndian::Get16(&aResult1[KAttributeByteCountOffset]);
+		if(byteCount1 > intendedByteCount)
+		{
+			return KErrGeneral;
+		}
+		// Check the second buffer as well if necessary
+		//
+		if(iTestNum==7)
+		{
+			byteCount2 = BigEndian::Get16(&aResult2[KAttributeByteCountOffset]);
+			if(byteCount2 > iAttributeTests[iTestNum - KNumSDPServiceTests].MaxByteCount())
+			{
+				return KErrGeneral;
+			}
+		}
+	}
+	
+	// Now Parse what we've got back
+	//
+	if(haveResult)
+	{
+		if(byteCount1!=0)
+		{
+			MSdpElementBuilder* builder = this;
+			if(iTestNum>=KSdpBrowseTest)
+			{
+				TRAP(ret,builder = (MSdpElementBuilder*)new(ELeave)CBrowseResponseBuilder(iTestName,iBrowseIter/*,iTestNum - KSdpBrowseTest + 1, GetUuidSize()*/, *iSP));
+				if (ret != KErrNone)
+					{
+					return ret;
+					}
+			}
+			
+			CElementParser* parser = NULL;
+			TRAP(ret,parser = CElementParser::NewL(builder));
+			if (ret != KErrNone)
+				{
+				return ret;
+				}
+			
+			TRAP(ret,CleanupStack::PushL(parser));			
+			if (ret != KErrNone)
+				{
+				return ret;
+				}
+			
+			// Get the offset of the continuation state
+			TUint16	attributeListLength = BigEndian::Get16(&aResult1[KSdpPduHeaderSize]);
+			TUint16 partial = TUint16(attributeListLength + KSdpPduHeaderSize + 2);
+			iContLength = aResult1[partial];
+			TBuf8<20> cont;
+			cont.SetLength(0);
+			cont.Append(aResult1.Mid(partial));
+			FlogContinuationString(cont);
+			if (iTestNum == 8)
+			{
+				// This one should have the continuation state set so do another query.
+				iContinuationStore.Append(aResult1.Mid(KAttributeListOffset, attributeListLength));
+				if (iContLength != 0)
+				{
+					Mem::Copy(iContinuationBuffer, &aResult1[partial+1], KSdpContinuationStateMaxLength);
+					TRAPD(err, SDPQueryL());
+					ret = err;
+					// Clear out the continuation state buffer ready for next query
+					//
+					Mem::FillZ( iContinuationBuffer,KSdpContinuationStateMaxLength);
+					iContLength = 0;
+					}
+				else
+				{
+					TRAPD(err, parser->ParseElementsL(iContinuationStore));
+					ret = err;
+					iContinuationStore.SetLength(0);
+				}
+			}
+			else if(iTestNum>=KSdpBrowseTest)
+			{
+			// This one might have the continuation state set so prepare, 
+			// if necessary, for another query.
+				iContinuationStore.Append(aResult1.Mid(KAttributeListOffset, attributeListLength));
+				if (iContLength != 0)
+				{
+					Mem::Copy(iContinuationBuffer, &aResult1[partial+1], KSdpContinuationStateMaxLength);
+					ret = KErrNone; //only error when (?) iContLength is zero
+				}
+				else
+				{
+					TRAPD(err, parser->ParseElementsL(iContinuationStore));
+					ret = err;
+					iContinuationStore.SetLength(0);
+				}
+			}
+			else
+			{
+				TRAPD(err, parser->ParseElementsL(aResult1.Mid(KAttributeListOffset, attributeListLength)));
+				ret = err;
+			}
+
+			if((ret==KErrNone)&&(iTestNum == 7))
+			{
+				// We need to parse the second buffer as well.
+				//
+				if(byteCount2!= 0)
+				{
+					iNeedAttributeId = ETrue;
+					TRAPD(err,ret=parser->ParseElementsL(aResult2.Mid(KAttributeListOffset)));
+					if (err)
+						{
+						ret = err;
+						}					
+				}
+			}
+			if(iTestNum>=KSdpBrowseTest)
+			{
+				delete (CBrowseResponseBuilder*)builder;
+				builder = 0;
+			}
+			CleanupStack::PopAndDestroy(parser);
+			parser = 0;		
+		}
+	}
+	else
+	{
+		// What's left should be invalid behaviour tests
+		// ie. the SDP_ErrorResponse PDU 
+		if(aResult1[0] == 0x01)
+		{
+			// This is an error response.
+			// Check the error code. It must either be 
+			// an invalid size, invalid syntax or invalid record handle.
+			//
+			TInt16 errorCode = BigEndian::Get16(&aResult1[KErrorCodeOffset]);
+			if(((errorCode==EInvalidServiceRecordHandle) && (iTestNum==26))
+				||((errorCode==EInvalidPduSize) && (iTestNum==28))
+				||((errorCode==EInvalidRequestSyntax) && (iTestNum==27)))
+			{
+				ret = KErrNone;
+			}
+			// Otherwise, wrong response.
+		}
+	}
+	return ret;
+	}
+
+
+void CSdpVerificationTests::SetUpServiceTestParams()
+/*
+	THE BIG SETUP.....
+*/
+	{
+	// Fill up the service test structure (see SetUpAttributeParams() for desription)
+/*	TUint8 validDes[3];
+	validDes[0] = 0x35;
+	validDes[1] = 0x03;
+	validDes[2] = 0x19;
+*/
+	TUint8 invalidDes[3];
+	invalidDes[0] = 0x35;
+	invalidDes[1] = 0x03;
+	invalidDes[2] = 0x09;
+
+	// TEST 0 - Dial up networking should return the first handle
+	iServiceTests[0] = TServiceRequest((TUint16)KDialUpNetworkingUUID, EUuid16, (TUint16)3);
+	
+	// TEST 1 - Search for 2 services (use test1 as well), should return the first 2 handles	
+	iServiceTests[1] = TServiceRequest((TUint16)KFaxUUID, EUuid16, (TUint16)3);
+
+	// TEST 2 - Search for Headset UUID can return any of the registered records. The max record
+	// handles param is large so that continuation occurs
+	iServiceTests[2] = TServiceRequest((TUint16)0x1108, EUuid16, (TUint16)200);
+	
+	// TEST 3 - SPP profile UUID has not been registered so should return with no records
+	iServiceTests[3] = TServiceRequest((TUint16)KNonExistantUUID, EUuid16, (TUint16)1);
+
+	// TEST 4 - UUID doesn't matter as size will be invalid.
+	iServiceTests[4] = TServiceRequest((TUint16)0x1101, EUuid16, (TUint16)1);
+
+	// TEST 5 - UUID doesn't matter as des will be invalid.
+	iServiceTests[5] = TServiceRequest(invalidDes, (TUint16)0x1101, EUuid16, (TUint16)1);
+
+	for(TInt i=KNumSDPServiceTests; i<25; i++)
+	{
+		iServiceTests[i] = TServiceRequest((TUint16)KDialUpNetworkingUUID, EUuid16, (TUint16)2);
+	}
+
+	// This one needs to return the second record handle
+	iServiceTests[25] = TServiceRequest((TUint16)KFaxUUID, EUuid16, (TUint16)2);
+	iServiceTests[26] = TServiceRequest((TUint16)KDialUpNetworkingUUID, EUuid16, (TUint16)2);
+	iServiceTests[27] = TServiceRequest((TUint16)KDialUpNetworkingUUID, EUuid16, (TUint16)2);
+	}
+
+void CSdpVerificationTests::SetUpAttributeTestParams()
+	{
+	// Fill in the attribute request params.
+	TUint8 validDes[3];
+	validDes[0] = 0x35; // Type = 6(DES), Size = 5(size is contained in next 8 bits).
+	validDes[1] = 0x03; // This is the next 8 bits: size = 3 
+	validDes[2] = 0x09;	// Type = 1 (Unsigned int), size = 1 (2Bytes).
+
+	TUint8 invalidDes[3];
+	invalidDes[0] = 0x35;// Type = 6(DES), Size = 5(size is ontained in next 8 bits).
+	invalidDes[1] = 0x03;// This is the next 8 bits: size = 3 
+	invalidDes[2] = 0x19;// Type = 3 (UUID), size = 1 (2Bytes).
+
+	// TEST 6 - Service for an existing attribute (0x0005) in the first record.
+	//  
+	iAttributeTests[0]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdBrowseGroupList); 
+	
+	// TEST 7 - Search for 2 attributes, see test 7 and also 0x0003 Service Id
+	iAttributeTests[1]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdServiceID);
+
+	// TEST 8 - Like test 1 but using continuation state (search for a very long URL).
+	iAttributeTests[2]=TAttributeRequest(KSdpMinServRecordHandle + 1, 200, validDes, KSdpAttrIdDocumentationURL);
+	
+	// TEST 9 - Service ID
+	iAttributeTests[3]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdServiceID);
+
+	// TEST 10 - Protocol descriptor list
+	iAttributeTests[4]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdProtocolDescriptorList);
+
+	// TEST 11 - Service record state
+	iAttributeTests[5]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdServiceRecordState);
+
+	// TEST 12 - ServiceInfoTimetoLive
+	iAttributeTests[6]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdServiceInfoTimeToLive);
+
+	// TEST 13 - BrowseGroupList
+	iAttributeTests[7]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdBrowseGroupList);
+
+	// TEST 14 - LanguageBaseAttributeId
+	iAttributeTests[8]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdLanguageBaseAttributeIDList);
+
+	// TEST 15 - ServiceAvailability
+	iAttributeTests[9]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdServiceAvailability);
+
+	// TEST 16 - IconURL
+	iAttributeTests[10]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdIconURL);
+
+	// TEST 17 - ServiceName (offset from LanguageBaseAttributeIDList).
+	iAttributeTests[11]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, (TUint16)(KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetServiceName));
+
+	// TEST 18 - Service Description
+	iAttributeTests[12]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, (TUint16)(KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetServiceDescription));
+
+	// TEST 19 - ProviderName
+	iAttributeTests[13]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, (TUint16)(KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetProviderName));
+
+	// TEST 20 - Version number list
+	iAttributeTests[14]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdSdpServerVersionNumberList);
+
+	// TEST 21 - Service Database State
+	iAttributeTests[15]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdSdpServerServiceDatabaseState);
+
+	// TEST 22 - Bluetooth Profile DescriptorList
+	iAttributeTests[16]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdBluetoothProfileDescriptorList);
+
+	// TEST 23 - Documentation URL
+	iAttributeTests[17]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdDocumentationURL);
+
+	// TEST 24 - Client Executable URL
+	iAttributeTests[18]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdClientExecutableURL);
+
+	// TEST 25 - Non-existing attribute
+	iAttributeTests[19]=TAttributeRequest(KSdpMinServRecordHandle+1, 200, validDes, KSdpAttrIdServiceRecordState);
+
+	//TEST 26 - Invalid service record handle
+	iAttributeTests[20]=TAttributeRequest(KSdpMinServRecordHandle-1, 200, validDes, KSdpAttrIdServiceRecordState);
+	
+	// TEST 27 - invalid syntax
+	iAttributeTests[21]=TAttributeRequest(KSdpMinServRecordHandle, 200, invalidDes, KSdpAttrIdServiceClassIDList);
+
+	// TEST 28 - invalid PDU size
+	iAttributeTests[22]=TAttributeRequest(KSdpMinServRecordHandle, 200, validDes, KSdpAttrIdServiceClassIDList);
+
+	}
+
+
+void CSdpVerificationTests::SetUpServiceAttributeTestParams()
+	{
+	// see SetUpAttributeParams() for desription
+	TUint8 validServiceDes[] = {0x35, 0x03, 0x19};
+	TUint8 validAttributeDes[3];
+
+	/*
+	TUint8 validUUID128[16];
+	validUUID128[0] = 0x0;
+	validUUID128[1] = 0x0;
+	validUUID128[2] = 0x0;
+	validUUID128[3] = 0x0;
+	//Bluetooth_Base_UUID
+	validUUID128[4] = 0x00;
+	validUUID128[5] = 0x00;
+	validUUID128[6] = 0x10;
+	validUUID128[7] = 0x00;
+	validUUID128[8] = 0x80;
+	validUUID128[9] = 0x00;
+	validUUID128[10] = 0x00;
+	validUUID128[11] = 0x80;
+	validUUID128[12] = 0x5f;
+	validUUID128[13] = 0x9b;
+	validUUID128[14] = 0x34;
+	validUUID128[15] = 0xfb;
+	*/
+
+	validAttributeDes[0] = 0x35;
+	validAttributeDes[1] = 0x03;
+	validAttributeDes[2] = 0x09;
+
+	// TEST 29 - non-existing service (SPP), existing attribute.
+	iServiceAttributeTests[0]=TServiceAttributeRequest((TUint16)0x1101, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdServiceClassIDList );
+
+	// TEST 30 - existing service, non-existing attribute
+	iServiceAttributeTests[1]=TServiceAttributeRequest((TUint16)KFaxUUID, EUuid16,  KMaxAttributeListByteCount, KSdpAttrIdServiceRecordState);
+	
+	// TEST 31 - non-existing service, non-existing attribute
+	iServiceAttributeTests[2]=TServiceAttributeRequest((TUint16)0x1101, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdServiceRecordState) ;
+	
+	// TEST 32 - existing service and attribute
+	iServiceAttributeTests[3]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdBrowseGroupList );
+	
+	// TEST 33 - two searches for existing services and attibutes (see test 33 as well).
+	iServiceAttributeTests[4]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdServiceID );
+	
+	// TEST 34 - continuation UUID16
+#ifdef SEVEN_LAYERS_BUG
+	iServiceAttributeTests[5]=TServiceAttributeRequest(
+				(TUint16)KPublicBrowseGroupUUID,
+				EUuid16,
+				0xffff,//0x1e,//0x30,//KMaxAttributeListByteCount, 
+				KSdpAttrIdServiceClassIDList);//(TUint32)0x0001);
+#else
+	iServiceAttributeTests[5]=TServiceAttributeRequest(
+				//(TUint16)KPublicBrowseGroupUUID,
+				0x1101,
+				EUuid16,
+				0x30,//KMaxAttributeListByteCount, 
+				(TUint32)KSdpAttributeBigRange);
+#endif
+	// TEST 35 - service record state 
+	iServiceAttributeTests[6]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdServiceRecordState);
+	
+	// Test 36 - Service database state
+	iServiceAttributeTests[7]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdSdpServerServiceDatabaseState);
+
+	// TEST 37 - service info time to live
+	iServiceAttributeTests[8]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdServiceInfoTimeToLive);
+	
+	// TEST 38 - Service Id
+	iServiceAttributeTests[9]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdServiceID);
+	
+	// TEST 39 - Protocol descriptor list
+	iServiceAttributeTests[10]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdProtocolDescriptorList);
+	
+	// TEST 40 - Browse group list
+	iServiceAttributeTests[11]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdBrowseGroupList);
+	
+	// TEST 41 - Language base attribute id
+	iServiceAttributeTests[12]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdLanguageBaseAttributeIDList);
+	
+	// TEST 42 - Service availability - 
+	iServiceAttributeTests[13]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdServiceAvailability);
+	
+	// TEST 43 - Icon URL
+	iServiceAttributeTests[14]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdIconURL);
+	
+	// TEST 44 - Service Name
+	iServiceAttributeTests[15]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, (TUint16)(KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetServiceName));
+	
+	// TEST 45 - Service description
+	iServiceAttributeTests[16]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, (TUint16)(KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetServiceDescription));
+	
+	// TEST 46 - Provider name
+	iServiceAttributeTests[17]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, (TUint16)(KSdpAttrIdBasePrimaryLanguage+KSdpAttrIdOffsetProviderName));
+	
+	// TEST 47 - version number list
+	iServiceAttributeTests[18]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdSdpServerVersionNumberList);
+	
+	// TEST 48 - Bluetooth profile descriptor list 
+	iServiceAttributeTests[19]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdBluetoothProfileDescriptorList);
+	
+	// TEST 49 - Documentation URL
+	iServiceAttributeTests[20]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdDocumentationURL);
+
+	// TEST 50 - Client executable URL
+	iServiceAttributeTests[21]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdClientExecutableURL);
+
+	// TEST 51 - invalid request syntax (swap round the des values).
+	iServiceAttributeTests[22]=TServiceAttributeRequest(validAttributeDes, (TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, validServiceDes, KSdpAttrIdClientExecutableURL);
+
+	// TEST 52 - invalid PDU size
+	iServiceAttributeTests[23]=TServiceAttributeRequest((TUint16)KDialUpNetworkingUUID, EUuid16, KMaxAttributeListByteCount, KSdpAttrIdServiceClassIDList);
+
+	}
+
+TBool CSdpVerificationTests::AnotherQuery()
+	{
+	if((iTestNum==1)||(iTestNum==7)||(iTestNum==33))
+	{
+		return ETrue;
+	}
+	return EFalse;
+	}
+
+TBool CSdpVerificationTests::Continue()
+	{
+	TBool ret = EFalse;
+	if(iType==EServiceRequest)
+	{
+		ret = EFalse;
+	}
+	else if((iType==EServiceAttributeRequest)&&(iQueryState!=EServiceAttributeRequest))
+	{
+		iQueryState = EServiceAttributeRequest;
+		ret = ETrue;
+	}
+	return ret;
+	}
+
+TInt CSdpVerificationTests::GetUuidSize()
+	{
+	switch(iUuidType)
+		{
+		case CSdpTestBase::EUuid16:
+			return 16;
+		case CSdpTestBase::EUuid32:
+			return 32;
+		case CSdpTestBase::EUuid128:
+			return 128;
+		default:
+			return 0;
+		}
+	}
+
+void CSdpVerificationTests::UpdateTestString()
+	{		
+	TInt uuidsize = GetUuidSize();
+	TBuf<4> uuidBuf;
+	uuidBuf.SetLength(0);
+	switch(uuidsize)
+		{
+		case 16:
+			uuidBuf.Append('1');
+			uuidBuf.Append('6');
+			break;
+		case 32:
+			uuidBuf.Append('3');
+			uuidBuf.Append('2');
+			break;
+		case 128:
+			uuidBuf.Append('1');
+			uuidBuf.Append('2');
+			uuidBuf.Append('8');
+			break;
+		default:
+			break;
+		}
+	TChar ch = 'V';
+	TInt num = 0;
+	iTestName.SetLength(0);
+	if(/*iTestNum>=KServiceRequestTest&&*/iTestNum<KServiceAttributeRequestTest)
+			{
+			num = iTestNum - KServiceRequestTest + 1;
+			if(iTestNum>=KServiceRequestBITest)
+				{
+				ch = 'I';
+				num = iTestNum - KServiceRequestBITest + 1;
+				}
+			iTestName.Append(_L("TC_SERVER_SS_UUID"));
+			iTestName.AppendNum(uuidsize);
+			iTestName.Append(_L("_B"));
+			}
+		else if(iTestNum>=KServiceAttributeRequestTest&&iTestNum<KServiceSearchAttributeRequestTest)
+			{
+			num = iTestNum - KServiceAttributeRequestTest + 1;
+			if(iTestNum>=KServiceAttributeRequestBITest)
+				{
+				ch = 'I';
+				num = iTestNum - KServiceAttributeRequestBITest + 1;
+				}
+			iTestName.Append(_L("TC_SERVER_SA_B"));
+			}
+		else if(iTestNum>=KServiceSearchAttributeRequestTest && iTestNum<KSdpBrowseTest)
+			{
+			num = iTestNum - KServiceSearchAttributeRequestTest + 1;
+			if(iTestNum>=KServiceSearchAttributeRequestBITest)
+				{
+				ch = 'I';
+				num = iTestNum - KServiceSearchAttributeRequestBITest + 1;
+				}
+			iTestName.Append(_L("TC_SERVER_SSA_UUID"));
+			iTestName.AppendNum(uuidsize);
+			iTestName.Append(_L("_B"));
+			}
+		else if(iTestNum>=KSdpBrowseTest && iTestNum<=KSdpLastTest)
+			{
+			num = iTestNum - KSdpBrowseTest + 1;
+			iTestName.Append(_L("TC_SERVER_BRW_UUID"));
+			iTestName.AppendNum(uuidsize);
+			iTestName.Append(_L("_B"));
+			}
+		else
+			{
+			; //print nothing
+			}
+		iTestName.Append(ch);
+		iTestName.Append('_');
+		if(num<10)
+			iTestName.Append('0');
+		iTestName.AppendNum(num);
+		iTestName.Append(_L("_C"));
+	}
+
+void CSdpVerificationTests::FlogTestId()
+	{
+	UpdateTestString();
+	FTRACE(FPrint(_L("")));
+	FTRACE(FPrint(_L("%S: "), &iTestName));
+	}
+
+#ifdef __FLOGGING__
+void CSdpVerificationTests::FlogString(const TText* aLineStart, TDesC8& aString)
+	{
+	TInt len = aString.Length();
+	TInt i = 0;
+	while(len-i>=6)
+		{
+		RFileLogger::HexDump(KLogDir, KLogFile, EFileLoggingModeAppend, aLineStart, 0, aString.Mid(i, 6).Ptr(), 6);
+		i+=6;
+		}
+	if(len-i>=0)
+		{
+		RFileLogger::HexDump(KLogDir, KLogFile, EFileLoggingModeAppend, aLineStart, 0, aString.Mid(i, len-i).Ptr(), len-i);
+		}
+	}
+#else
+void CSdpVerificationTests::FlogString(const TText* /*aLineStart*/, TDesC8& /*aString*/)
+	{
+	}
+#endif
+
+
+TInt CSdpVerificationTests::MaxCountFoundAfterServiceSearchPatternOrWhatYouWill(TDesC8& aString)
+	{
+	TInt ret = -1;
+	TUint32 pos = 0;
+	if(aString.Length()<7)
+		return ret;
+	TInt listType = aString[5];
+	switch(listType)
+		{
+		case 0x35:
+			if(aString.Length()<7)
+				return ret;
+			pos += 7+aString[6];
+			break;
+		case 0x36:
+			if(aString.Length()<8)
+				return ret;
+			pos += 8+aString[7]+256*aString[6];
+			break;
+		case 0x37:
+			if(aString.Length()<10)
+				return ret;
+			pos += 10+aString[9]+256*aString[8]+256*256*aString[7]+256*256*256*aString[6];
+			break;
+		default:
+			return ret;
+		}
+	ret = aString[pos+1]+256*aString[pos];
+	return ret;
+	}
+
+void CSdpVerificationTests::FlogParsedPDUHeader(TDesC8& aString)
+	{
+	TInt id = aString[2]+256*aString[1];
+	FTRACE(FPrint(_L("SDP_Transaction Id: 0x%02x"), id));
+	switch(aString[0])
+		{
+		case 1:
+			if(iRequestTransId != id)
+				{
+				FTRACE(FPrint(_L("Request and Error Response Transaction Ids DO NOT MATCH: 0x%02x != 0x%02x ... Error code still printed below"), id, iRequestTransId));
+				}
+			if(aString.Length()>=7)
+				{
+				TInt errorCode = aString[6]+256*aString[5];
+				switch(errorCode)
+					{
+					case 1:
+						FTRACE(FPrint(_L("SDP_ErrorResponse - Invalid/Unsupported SDP version")));
+						break;
+					case 2:
+						FTRACE(FPrint(_L("SDP_ErrorResponse - Invalid Srvice Record Handle")));
+						break;
+					case 3:
+						FTRACE(FPrint(_L("SDP_ErrorResponse - Invalid request syntax")));
+						break;
+					case 4:
+						FTRACE(FPrint(_L("SDP_ErrorResponse - Invalid PDU Size")));
+						break;
+					case 5:
+						FTRACE(FPrint(_L("SDP_ErrorResponse - Invalid Continuation State")));
+						break;
+					case 6:
+						FTRACE(FPrint(_L("SDP_ErrorResponse - Insufficient Resources to satisfy Request")));
+						break;
+					default:
+						FTRACE(FPrint(_L("SDP_ErrorResponse - Reserved Value 0x%04x"), errorCode));
+						break;
+					}
+				}
+			else
+				{
+				FTRACE(FPrint(_L("SDP_ErrorResponse sent without parameters!")));
+				User::Leave(KErrGeneral); //Qualified
+				}
+			if(iRequestTransId != id)
+				{
+				User::Leave(KErrGeneral); //Qualified
+				}
+			break;
+		case 2:
+			{
+			FTRACE(FPrint(_L("SDP_ServiceSearchRequest")));
+			iRequestTransId2 = iRequestTransId1;
+			iRequestMaxCount2 = iRequestMaxCount1;
+			iRequestTransId1 = id;
+			iRequestMaxCount1 = MaxCountFoundAfterServiceSearchPatternOrWhatYouWill(aString);
+			if(iTestNum==1)
+				{
+				iRequestTransId = iRequestTransId2;
+				iRequestMaxCount = iRequestMaxCount2;
+				}
+			else
+				{
+				iRequestTransId = iRequestTransId1;
+				iRequestMaxCount = iRequestMaxCount1;
+				}
+			if(iRequestMaxCount1>=0)
+				{
+				FTRACE(FPrint(_L("   MaximumServiceRecordCount = 0x%04x"), iRequestMaxCount1));
+				}
+			else
+				{
+				FTRACE(FPrint(_L("   .....sent without parameters!")));
+				User::Leave(KErrGeneral);
+				}
+			}
+			break;
+		case 3:
+			{
+			FTRACE(FPrint(_L("SDP_ServiceSearchResponse")));
+			if(iRequestTransId != id)
+				{
+				FTRACE(FPrint(_L("Request and Response Transaction Ids DO NOT MATCH: 0x%02x != 0x%02x ... ERROR!!!!!!!!"), id, iRequestTransId));
+				//break;
+				}
+			if(aString.Length()>=9)
+				{
+				TInt total = aString[6]+256*aString[5];
+				TInt current = aString[8]+256*aString[7];
+				FTRACE(FPrint(_L("   TotalServiceRecordCount = 0x%04x, CurrentRecordCount = 0x%04x "), total, current));
+				if(iRequestTransId == id)
+					{
+					if(iRequestMaxCount>=total&&total>=current)
+						{
+						FTRACE(FPrint(_L("       So: requested MaximumServiceRecordCount 0x%04x >= TotalServiceRecordCount, 0x%04x >= CurrentRecordCount, 0x%04x "), iRequestMaxCount, total, current));
+						}
+					else
+						{
+						FTRACE(FPrint(_L("       ERROR!!!! the following is NOT true: requested MaximumServiceRecordCount 0x%04x >= TotalServiceRecordCount, 0x%04x >= CurrentRecordCount, 0x%04x "), iRequestMaxCount, total, current));
+						User::Leave(KErrGeneral); //Qualified
+						}
+					}
+				}
+			else
+				{
+				FTRACE(FPrint(_L("   .....sent without parameters!")));
+				User::Leave(KErrGeneral); //Qualified
+				}
+			}
+			if(iRequestTransId != id)
+				{
+				User::Leave(KErrGeneral); //Qualified
+				}
+			if(iTestNum==1)
+				//Prepare for next response when we'll be looking 
+				//at the LAST request's values.
+				{
+				iRequestTransId = iRequestTransId1;
+				iRequestMaxCount = iRequestMaxCount1;
+				}
+			break;
+		case 4:
+			{
+			iRequestTransId2 = iRequestTransId1;
+			iRequestMaxCount2 = iRequestMaxCount1;
+			iRequestTransId1 = id;
+			FTRACE(FPrint(_L("SDP_ServiceAttributeRequest")));
+			if(aString.Length()>=11)
+				{
+				TInt handle = aString[8]+256*aString[7]+256*256*aString[6]+256*256*256*aString[5];
+				iRequestMaxCount1 = aString[10]+256*aString[9];
+				FTRACE(FPrint(_L("   Record Handle = 0x%08x, MaximumAttributByteCount = 0x%04x"), handle, iRequestMaxCount1));
+				if(iTestNum==7)
+					{
+					iRequestTransId = iRequestTransId2;
+					iRequestMaxCount = iRequestMaxCount2;
+					}
+				else
+					{
+					iRequestTransId = iRequestTransId1;
+					iRequestMaxCount = iRequestMaxCount1;
+					}
+				}
+			else
+				{
+				FTRACE(FPrint(_L("   ....sent without parameters!")));
+				User::Leave(KErrGeneral); //Qualified
+				}
+			}
+			break;
+		case 5:
+			{
+			FTRACE(FPrint(_L("SDP_ServiceAttributeResponse")));
+			if(iRequestTransId != id)
+				{
+				FTRACE(FPrint(_L("Request and Response Transaction Ids DO NOT MATCH: 0x%02x != 0x%02x ... ERROR!!!!!!!!"), id, iRequestTransId));
+				//break;
+				}
+			if(aString.Length()>=7)
+				{
+				TInt count = aString[6]+256*aString[5];
+				if(iRequestTransId != id)
+					{
+					FTRACE(FPrint(_L("   AttributeListByteCount = 0x%04x"), count));
+					}
+				else
+					{
+					if(count <= iRequestMaxCount)
+						{
+						FTRACE(FPrint(_L("   AttributeListsByteCount = 0x%04x (<= requested MaxiumumAttributeByteCount, 0x%04x"), count, iRequestMaxCount));
+						}
+					else
+						{
+						FTRACE(FPrint(_L("   ERROR!!!!!  AttributeListsByteCount = 0x%04x > requested MaxiumumAttributeByteCount, 0x%04x"), count, iRequestMaxCount));
+						User::Leave(KErrGeneral); //Qualified
+						}
+					}
+				}
+			else
+				{
+				FTRACE(FPrint(_L("   ....sent without parameters!")));
+				User::Leave(KErrGeneral); //Qualified
+				}
+			}
+			if(iRequestTransId != id)
+				{
+				User::Leave(KErrGeneral); //Qualified
+				}
+			if(iTestNum==7)
+				//Prepare for next response when we'll be looking 
+				//at the LAST request's values.
+				{
+				iRequestTransId = iRequestTransId1;
+				iRequestMaxCount = iRequestMaxCount1;
+				}
+			break;
+		case 6:
+			{
+			FTRACE(FPrint(_L("SDP_ServiceSearchAttributeRequest")));
+			FTRACE(FPrint(_L("SDP_ServiceSearchRequest")));
+			iRequestTransId2 = iRequestTransId1;
+			iRequestMaxCount2 = iRequestMaxCount1;
+			iRequestTransId1 = id;
+			iRequestMaxCount1 = MaxCountFoundAfterServiceSearchPatternOrWhatYouWill(aString);
+			if(iTestNum==33)
+				{
+				iRequestTransId = iRequestTransId2;
+				iRequestMaxCount = iRequestMaxCount2;
+				}
+			else
+				{
+				iRequestTransId = iRequestTransId1;
+				iRequestMaxCount = iRequestMaxCount1;
+				}
+			if(iRequestMaxCount1>=0)
+				{
+				FTRACE(FPrint(_L("   MaximumAttributeByteCount = 0x%04x"), iRequestMaxCount1));
+				}
+			else
+				{
+				FTRACE(FPrint(_L("   .....sent without parameters!")));
+				User::Leave(KErrGeneral); //Qualified
+				}
+			}
+			break;
+		case 7:
+			{
+			FTRACE(FPrint(_L("SDP_ServiceSearchAttributeResponse")));
+			if(iRequestTransId != id)
+				{
+				FTRACE(FPrint(_L("Request and Response Transaction Ids DO NOT MATCH: 0x%02x != 0x%02x ... ERROR!!!!!!!!"), id, iRequestTransId));
+				//break;
+				}
+			if(aString.Length()>=7)
+				{
+				TInt count = aString[6]+256*aString[5];
+				if(iRequestTransId != id)
+					{
+					FTRACE(FPrint(_L("   AttributeListByteCount = 0x%04x"), count));
+					}
+				else
+					{
+					if(count <= iRequestMaxCount)
+						{
+						FTRACE(FPrint(_L("   AttributeListsByteCount = 0x%04x (<= requested MaxiumumAttributeByteCount, 0x%04x"), count, iRequestMaxCount));
+						}
+					else
+						{
+						FTRACE(FPrint(_L("   ERROR!!!!!  AttributeListsByteCount = 0x%04x > requested MaxiumumAttributeByteCount, 0x%04x"), count, iRequestMaxCount));
+						User::Leave(KErrGeneral); //Qualified
+						}
+					}
+				}
+			else
+				{
+				FTRACE(FPrint(_L("   ....sent without parameters!")));
+				User::Leave(KErrGeneral); //Qualified
+				}
+			}
+			if(iRequestTransId != id)
+				{
+				User::Leave(KErrGeneral); //Qualified
+				}
+			if(iTestNum==33)
+				//Prepare for next response when we'll be looking 
+				//at the LAST request's values.
+				{
+				iRequestTransId = iRequestTransId1;
+				iRequestMaxCount = iRequestMaxCount1;
+				}
+			break;
+		default:
+			FTRACE(FPrint(_L("Reserved PDU Id: %02x"), aString[0]));
+			User::Leave(KErrGeneral); //Qualified
+			break;
+		}
+	}
+
+void CSdpVerificationTests::FlogReadString(TDesC8& aString)
+	{
+	if(!aString.Length())
+		return;
+	FLOG(_L(""));
+	;
+	FlogTestId();
+	FlogParsedPDUHeader(aString);
+	FLOG(_L("Raw data RECEIVED........."));
+	TPtrC start(_L("    Bytes READ - "));
+	FlogString(&start[0], aString);
+	FLOG(_L(""));
+	}
+
+void CSdpVerificationTests::FlogContinuationString(TDesC8& aString)
+	{
+	FLOG(_L("NB...."));
+	TPtrC start(_L("    Continuation Bytes - "));
+	FlogString(&start[0], aString);
+	}
+
+void CSdpVerificationTests::FlogWriteString(TDesC8& aString)
+	{
+	if(!aString.Length())
+		return;
+	FLOG(_L(""));
+	FlogTestId();
+	FlogParsedPDUHeader(aString);
+	FLOG(_L("Raw data SENT........."));
+	TPtrC start(_L("    Bytes WRITTEN - "));
+	FlogString(&start[0], aString);
+	TBuf8<20> contStr;
+	contStr.SetLength(0);
+	contStr.Append(&iContLength, 1);
+	contStr.Append(iContinuationBuffer, iContLength);
+	FlogContinuationString(contStr);
+	FLOG(_L(""));
+	}
+
+
+		
+void CSdpVerificationTests::WaitForStartSignalL()
+{
+	// Wait for sync info to be sent
+	//
+}
+
+void CSdpVerificationTests::SendStartSignalL()
+{
+	// Send sync info
+	//
+}
+
+void CSdpVerificationTests::PromptedGetch()
+{
+	// For putting stops between tests so user can check results as he goes
+	//
+	#ifdef STOPPING_MODE
+	iConsole.Printf(_L("Press any key.\r\n"));
+	iConsole.Getch();
+	#endif
+}
+
+
+
+// this is the nearest thing to a real database. 
+// originally for UPF4, but record 0 removed above.
+	
+CSdpDatabase* CSdpVerificationTests::BuildDbL()
+	{
+	//see builddb.cpp for copy of this
+	return 0;
+	}
+
+
+void CSdpVerificationTests::PrintDb(CSdpDatabase& aDb, CConsoleBase& aConsole)
+	{
+	aConsole.Printf(_L("Printing Database...\n"));
+
+	for(TServRecordIter recIter(aDb.RecordIter()); recIter; recIter++)
+		{// Iterate thru records in Db
+		aConsole.Printf(_L("\n...Printing Record 0x%x\n"), (*recIter).Handle());
+		for(TServAttrIter attrIter((*recIter).AttributeIter()); attrIter; attrIter++)
+			{// Iterate thru attributes in record
+			CAttrPrintVisitor* theVisitor = new CAttrPrintVisitor(aConsole);
+			(*attrIter).AcceptVisitorL(*theVisitor); //Qualified
+			delete theVisitor;
+			}
+		}
+	}
+
+
+MSdpElementBuilder* CSdpVerificationTests::BuildUintL(const TDesC8& aUint)
+	{
+	if(aUint.Length() != 2)
+	{
+		iNeedAttributeId = EFalse;
+	}
+	if (iNeedAttributeId)
+	{
+		iBuildingList = 0; //reset so only sublists are counted
+		iNeedAttributeId = EFalse;
+		// This is the Attribute ID level (the same for SA or SAS request)
+		// First check the length
+		//
+		if(aUint.Length() != 2)
+		{
+			User::Leave(KErrGeneral);
+		}
+		// Now check the value;
+		//
+		TUint16 id = BigEndian::Get16(aUint.Ptr());
+		FlogTestId();
+		FTRACE(FPrint(_L("   Attribute ID - %d"), id));
+	}
+	else 
+	{
+		// First, get the correct size integer
+//		TUint32 uint32 = 0;
+		TUint16 uint16a = 0;
+		TUint16 uint16b = 0;
+		TUint8 uint8 = 0;
+		if(iBuildingList<=0)
+			{
+			iNeedAttributeId = ETrue;
+			}
+		if(aUint.Length() == 4)
+		{
+//			uint32 = BigEndian::Get32(aUint.Ptr());
+			uint16a = BigEndian::Get16(aUint.Ptr());
+			TUint8* ptr = CONST_CAST(TUint8 *, aUint.Ptr());
+			ptr+=2;
+			uint16b = BigEndian::Get16(ptr);
+			FlogTestId();
+			FTRACE(FPrint(_L("   Attribute Uint32 Value - 0x%04x%04x"), uint16a, uint16b));
+		}
+		else if(aUint.Length() == 2)
+		{
+			uint16a = BigEndian::Get16(aUint.Ptr());
+			FlogTestId();
+			FTRACE(FPrint(_L("   Attribute Uint16 Value - 0x%x"), uint16a));
+		}
+		else if(aUint.Length() == 1)
+		{
+			uint8 = aUint[0];
+			FlogTestId();
+			FTRACE(FPrint(_L("   Attribute Uint8 Value - 0x%x"), uint8));
+		}
+		else
+		{
+			// We don't have 32, 16 or 8 bit Uint
+			User::Leave(KErrGeneral);
+		}
+		
+		(void)(uint16a != 0); // keep compiler happy by referencing uint16a as an r-value in urel
+		(void)(uint16b != 0); // keep compiler happy by referencing uint16b as an r-value in urel
+		(void)(uint8 != 0); // keep compiler happy by referencing uint8 as an r-value in urel
+	}
+	return this;
+	}
+
+
+MSdpElementBuilder* CSdpVerificationTests::BuildUUIDL(const TUUID& aUUID)
+	{
+	
+	TPtrC8 uuid = aUUID.ShortestForm();
+	TUint16 bigUuid = BigEndian::Get16(uuid.Ptr());
+	FlogTestId();
+	FTRACE(FPrint(_L("   Attribute UUID Value - 0x%x"), bigUuid));
+	if(iBuildingList<=0)
+		{
+		iNeedAttributeId = ETrue;
+		}
+	return this;	
+	}
+
+
+MSdpElementBuilder* CSdpVerificationTests::BuildStringL(const TDesC8& aString)
+	{
+	if(iBuildingList<=0)
+		{
+		iNeedAttributeId = ETrue;
+		}
+	FlogTestId();
+	FTRACE(FPrint(_L("   Attribute Value String - ")));
+	for(TInt i = 0; i < aString.Length(); i ++)
+	{
+		FTRACE(FPrint(_L("   %c"), aString[i]));
+	}
+	return this;
+	}
+
+MSdpElementBuilder* CSdpVerificationTests::BuildDESL()
+	{
+	return this;
+	}
+
+MSdpElementBuilder* CSdpVerificationTests::BuildURLL(const TDesC8& aURL)
+	{
+//	TInt ret = KErrNone;
+	TInt i = 0;
+	TBuf8<654> urlBuf;
+	if(iBuildingList<=0)
+		{
+		iNeedAttributeId = ETrue;
+		}
+	FlogTestId();
+	FTRACE(FPrint(_L("   Attribute Value URL - ")));
+	for(i = 0; i < aURL.Length(); i ++)
+	{
+		FTRACE(FPrint(_L("   %c"), aURL[i]));
+	}
+	
+	switch(iTestNum)
+		{
+	case 8:
+	case 34:
+	case 35:
+	case 36:
+		// This should be part of a very long URL. Append it to the buffer until continuation has finished
+		// Set up a  string to compare it to.
+		//
+		urlBuf.Append(_L8("http://"));
+		for(i = 0; i < 160; i ++)
+		{
+			urlBuf.Append(_L8("url/"));
+		}	
+		urlBuf.Append(_L8("url.doc"));
+		(void) aURL.Compare(urlBuf);
+
+		// Reset the continuation buffer
+		//??iContinuationStore.SetLength(0);
+		break;
+	default:
+		break;
+		}
+	return this;
+	}
+		
+MSdpElementBuilder* CSdpVerificationTests::StartListL()
+	{
+	FlogTestId();
+	FTRACE(FPrint(_L("   New List (DES)")));
+	iBuildingList++;
+	return this;
+	}
+
+MSdpElementBuilder* CSdpVerificationTests::EndListL()
+	{
+	FlogTestId();
+	FTRACE(FPrint(_L("   End Current List")));
+	iBuildingList--;
+	if(iBuildingList<=0)
+		iNeedAttributeId=ETrue;
+	return this;
+	}
+
+
+MSdpElementBuilder* CSdpVerificationTests::BuildNilL()
+	{
+	User::Leave(KErrGeneral);
+	return this;
+	}
+
+
+
+
+
+
+
+
+
+
+
+void CSdpVerificationTests::BuildBrowseDbL(CConsoleBase&  aConsole)
+	{
+	// First thing is to get rid of the old one
+	//
+	iTheDb = CSdpDatabase::NewL();
+	
+	TBuf8<2> attrId;
+	TBuf8<4> val;
+	TBuf8<2> val1;
+	CSdpServRecord *theRec = CSdpServRecord::NewL();
+// all attribute IDs are BIG ENDian 
+
+// First Record is the Public browse group service. 
+	attrId.FillZ(2);
+	val.FillZ(4);
+	val1.FillZ(2);
+	// Set Attr 0 (Record handle) to 0x00010000
+	val[0] = 0x00;
+	val[1] = 0x01;
+	val[2] = 0x00;
+	val[3] = 0x00;
+	theRec->BuildUintL(attrId)->BuildUintL(val);
+
+	// Set Attr 1 (service class list) to BrowseGroupDescriptor
+	attrId[0] = 0x00;
+	attrId[1] = 0x01;
+	theRec->BuildUintL(attrId)->BuildDESL()
+		->StartListL()
+			->BuildUUIDL(TUUID(0x1001))
+		->EndListL();
+
+		// Set Attr 0x005 (browse group list) to public root
+	attrId[0] = 0x00;
+	attrId[1] = 0x05;
+	theRec->BuildUintL(attrId)->BuildDESL()
+		->StartListL()
+			->BuildUUIDL(TUUID(TUint16(0x1002))) // publicBrowseRoot
+		->EndListL();
+
+	// Set Attr 0x200 (group ID) to 0x1201 (Generic networking).
+	attrId[0] = 0x02;
+	attrId[1] = 0x00;
+	theRec->BuildUintL(attrId)->BuildDESL()
+		->StartListL()
+			->BuildUUIDL(TUUID(TUint16((TUint16)KGenericNetworkingUUID))) 
+		->EndListL();
+
+	
+	// Add the record into the database
+	iTheDb->AddRecord(theRec);
+
+// Record 2 - a member of the Browse group 0x1201 (Generic networking)
+	theRec = CSdpServRecord::NewL();
+
+	attrId.FillZ(2);
+	// Set Attr 0 (Record handle) to 0x0001001
+	val[0] = 0x00;
+	val[1] = 0x01;
+	val[2] = 0x00;
+	val[3] = 0x01;
+	theRec->BuildUintL(attrId)->BuildUintL(val);
+
+
+	// Set Attr 1 (service class list) to 0x1201
+	attrId[0] = 0x00;
+	attrId[1] = 0x01;
+	theRec->BuildUintL(attrId)->BuildDESL()
+		->StartListL()
+			->BuildUUIDL(TUUID((TUint16)KDialUpNetworkingUUID))
+		->EndListL();
+
+	// Set Attr 0x005 (browse group list) to the generic networking browse group
+	attrId[0] = 0x00;
+	attrId[1] = 0x05;
+	theRec->BuildUintL(attrId)->BuildDESL()
+		->StartListL()
+			->BuildUUIDL(TUUID(TUint16((TUint16)KGenericNetworkingUUID))) 
+		->EndListL();
+
+	
+	// Add the record into the database
+	iTheDb->AddRecord(theRec);
+
+// Record 3 - a member of the Browse group 0x1201 (Generic networking)
+	theRec = CSdpServRecord::NewL();
+
+	attrId.FillZ(2);
+	// Set Attr 0 (Record handle) to 0x0001002
+	val[0] = 0x00;
+	val[1] = 0x01;
+	val[2] = 0x00;
+	val[3] = 0x02;
+	theRec->BuildUintL(attrId)->BuildUintL(val);
+
+	// Set Attr 1 (service class list) to LanAccessUsingPPP UUID (0x1102)
+	attrId[0] = 0x00;
+	attrId[1] = 0x01;
+	theRec->BuildUintL(attrId)->BuildDESL()
+		->StartListL()
+			->BuildUUIDL(TUUID(0x1102))
+		->EndListL();
+
+	// Set Attr 0x005 (browse group list) to the generic networking browse group
+	attrId[0] = 0x00;
+	attrId[1] = 0x05;
+	theRec->BuildUintL(attrId)->BuildDESL()
+		->StartListL()
+			->BuildUUIDL(TUUID(TUint16((TUint16)KGenericNetworkingUUID))) 
+		->EndListL();
+
+	
+	// Add the record into the database
+	iTheDb->AddRecord(theRec);
+
+	CSdpDatabase& db = *iTheDb;
+	PrintDb(db, aConsole);
+	}
+
+
+
+//
+// Browse builder implementation
+//
+CBrowseResponseBuilder::CBrowseResponseBuilder(TDes& aTestName, TInt aBrowseIter/*, TInt aBrowseTest, TInt aUuidSize*/, CSdpSearchPattern& aBrowseSP)
+
+:iTestName(aTestName),iBrowseIter(aBrowseIter),/*iBrowseTest(aBrowseTest),iUuidSize(aUuidSize),*/iNeedAttributeId(ETrue),iBuildingList(0),iBrowseSP(aBrowseSP)
+	{
+	
+	}
+
+CBrowseResponseBuilder::~CBrowseResponseBuilder()
+	{
+	}
+
+MSdpElementBuilder* CBrowseResponseBuilder::BuildUintL(const TDesC8& aUint)
+	{
+
+	if(iNeedAttributeId)
+	{	
+		iNeedAttributeId = EFalse;
+		if(aUint.Length() != 2)
+		{
+			User::Leave(KErrGeneral);
+		}
+		// Now check the value;
+		//
+		TUint16 id = BigEndian::Get16(aUint.Ptr());
+		FTRACE(FPrint(_L("")));
+		FTRACE(FPrint(_L("%S:"), &iTestName));
+		FTRACE(FPrint(_L("	Browse Iter %d: Attribute ID - %d"),iBrowseIter + 1, id));
+
+		switch(iBrowseIter)
+		{
+		case 0:
+		case 2:
+			if(id!=KSdpAttrIdServiceClassIDList)
+			{	
+				User::Leave(KErrGeneral);
+			}
+			break;
+		case 1:
+			if(id!=KSdpAttrIdSdpServerGroupID)
+			{	
+				User::Leave(KErrGeneral);
+			}
+			
+			break;
+		default:
+			User::Leave(KErrGeneral);
+			break;
+		}
+	
+	}
+	else
+	{
+		// Get the appropriate size uint
+		//
+		// First, get the correct size integer
+//		TUint32 uint32 = 0;
+		TUint16 uint16a = 0;
+		TUint16 uint16b = 0;
+		TUint8 uint8 = 0;
+		if(iBuildingList<=0)
+			{
+			iNeedAttributeId = ETrue;
+			}
+		if(aUint.Length() == 4)
+		{
+//			uint32 = BigEndian::Get32(aUint.Ptr());
+			uint16a = BigEndian::Get16(aUint.Ptr());
+			TUint8* ptr = CONST_CAST(TUint8 *, aUint.Ptr());
+			ptr+=2;
+			uint16b = BigEndian::Get16(ptr);
+			FTRACE(FPrint(_L("")));
+			FTRACE(FPrint(_L("%S:"), &iTestName));
+			FTRACE(FPrint(_L("	Browse Iter %d: Attribute Uint32 Value - 0x%04x%04x"), iBrowseIter + 1, uint16a, uint16b));
+		}
+		else if(aUint.Length() == 2)
+		{
+			uint16a = BigEndian::Get16(aUint.Ptr());
+			FTRACE(FPrint(_L("")));
+			FTRACE(FPrint(_L("%S:"), &iTestName));
+			FTRACE(FPrint(_L("	Browse Iter %d: Attribute Uint32 Value - 0x%x"), iBrowseIter + 1, uint16a));
+		}
+		else if(aUint.Length() == 1)
+		{
+			uint8 = aUint[0];
+			FTRACE(FPrint(_L("")));
+			FTRACE(FPrint(_L("%S:"), &iTestName));
+			FTRACE(FPrint(_L("	Browse Iter %d: Attribute Uint32 Value - 0x%x"), iBrowseIter + 1, uint8));
+		}
+		else
+		{
+			// We don't have 32, 16 or 8 bit Uint
+			User::Leave(KErrGeneral);
+		}
+
+		(void)(uint16a != 0); // keep compiler happy by referencing uint16a as an r-value in urel
+		(void)(uint16b != 0); // keep compiler happy by referencing uint16b as an r-value in urel
+		(void)(uint8 != 0); // keep compiler happy by referencing uint8 as an r-value in urel
+	}
+	return this;
+	}
+
+MSdpElementBuilder* CBrowseResponseBuilder::BuildUUIDL(const TUUID& aUUID)
+	{
+	// Extract the underlying integer
+	//
+	TPtrC8 uuid = aUUID.ShortestForm();
+	TUint16 bigUuid = BigEndian::Get16(uuid.Ptr());
+	FTRACE(FPrint(_L("")));
+	FTRACE(FPrint(_L("%S:"), &iTestName));
+	FTRACE(FPrint(_L("   Browse Iter %d: Attribute UUID Value - 0x%x"), iBrowseIter + 1, bigUuid));
+	if(iBuildingList<=0)
+		{
+		iNeedAttributeId = ETrue;
+		}
+
+
+	switch(iBrowseIter)
+	{
+	case 0:
+		// Browse group list
+		if(bigUuid==0x1001)
+		{
+		FTRACE(FPrint(_L("")));
+		FTRACE(FPrint(_L("%S:"), &iTestName));
+		FTRACE(FPrint(_L("   Browse Iter %d.... Browse Group Record Found!"), iBrowseIter + 1));
+		}
+		break;
+	case 1:
+		iBrowseSP.AddL(aUUID);
+		FTRACE(FPrint(_L("")));
+		FTRACE(FPrint(_L("%S:"), &iTestName));
+		FTRACE(FPrint(_L("   Browse Iter %d.... Browse Group ID (0x%x) found!"), iBrowseIter + 1, bigUuid));
+		break;
+	default:
+		break;
+	}
+	return this;
+	}
+
+MSdpElementBuilder* CBrowseResponseBuilder::BuildDESL()
+	{
+	return this;
+	}
+
+MSdpElementBuilder* CBrowseResponseBuilder::StartListL()
+	{
+	FTRACE(FPrint(_L("")));
+	FTRACE(FPrint(_L("%S:   New List (DES)...."), &iTestName));
+	iBuildingList++;
+	return this;
+	}
+
+MSdpElementBuilder* CBrowseResponseBuilder::EndListL()
+	{
+	FTRACE(FPrint(_L("%S:   End Current List"), &iTestName));
+	iBuildingList--;
+	if(iBuildingList<=0)
+		iNeedAttributeId=ETrue;
+	return this;
+	}
+
+//
+// Print out builder implementation
+//
+CPrintBuilder::CPrintBuilder(CConsoleBase& aConsole)
+: iIndent(0), iConsole(aConsole)
+	{
+	
+	}
+
+CPrintBuilder::~CPrintBuilder()
+	{
+	}
+
+
+void CPrintBuilder::HexDumpVT(const TDesC8& aDes)
+	{
+	for (TInt i = 0; i < aDes.Length(); ++i)
+		{
+		if (i%8 == 0)
+			iConsole.Printf(_L("0x%04x:   "), i);
+		iConsole.Printf(_L("0x%02x "), aDes[i]);
+		if (i%8 == 7 || i == aDes.Length() - 1)
+			iConsole.Printf(_L("\n"));
+		}
+	}
+
+
+
+MSdpElementBuilder* CPrintBuilder::BuildUnknown(TUint8 aType, TUint8 aSizeDesc, const TDesC8& aData)
+	{
+	iConsole.SetPos(iIndent);
+	iConsole.Printf(_L("Got Unknown: <type %d, sizedesc %d, length %d>\n"), aType, aSizeDesc, aData.Length());
+	HexDumpVT(aData);
+	return this;
+	};
+MSdpElementBuilder* CPrintBuilder::BuildNilL()
+	{
+	iConsole.SetPos(iIndent);
+	iConsole.Printf(_L("Got Nil: <>\n"));
+	return this;
+	};
+
+MSdpElementBuilder* CPrintBuilder::BuildUintL(const TDesC8& aLongUint)
+	{
+	iConsole.SetPos(iIndent);
+	iConsole.Printf(_L("Got Long Uint: <Length %d>\n"), aLongUint.Length());
+	HexDumpVT(aLongUint);
+	return this;
+	};
+MSdpElementBuilder* CPrintBuilder::BuildIntL(const TDesC8& aLongInt)
+	{
+	iConsole.SetPos(iIndent);
+	iConsole.Printf(_L("Got Long Int: <Length %d>\n"), aLongInt.Length());
+	HexDumpVT(aLongInt);
+	return this;
+	};
+MSdpElementBuilder* CPrintBuilder::BuildUUIDL(const TUUID& aUUID)
+	{
+	iConsole.SetPos(iIndent);
+	iConsole.Printf(_L("Got UUID: <length %d>\n"), aUUID.ShortestForm().Length());
+	HexDumpVT(aUUID.ShortestForm());
+	return this;
+	};
+MSdpElementBuilder* CPrintBuilder::BuildBooleanL(TBool aBool)
+	{
+	iConsole.SetPos(iIndent);
+	iConsole.Printf(_L("Got Boolean: <%d>\n"), aBool);
+	return this;
+	};
+MSdpElementBuilder* CPrintBuilder::BuildStringL(const TDesC8& aString)
+	{
+	TBuf<512> ustr;
+	ustr.Copy(aString.Left(Min(aString.Length(), ustr.MaxLength())));
+	iConsole.SetPos(iIndent);
+	iConsole.Printf(_L("Got String: <length %d, Contents %S>\n"), ustr.Length(), &ustr);
+	return this;
+	};
+MSdpElementBuilder* CPrintBuilder::BuildDESL()
+	{
+	return StartListL();
+	};
+
+MSdpElementBuilder* CPrintBuilder::BuildDEAL()
+	{
+	return StartListL();
+	};
+
+MSdpElementBuilder* CPrintBuilder::StartListL(/*prob want list type here*/)
+	{
+	iConsole.SetPos(iIndent);
+	iConsole.Printf(_L("<START LIST>\n"));
+	iIndent += 2;
+	return this;
+	};
+MSdpElementBuilder* CPrintBuilder::EndListL()
+	{
+	if (iIndent > 0)
+		{
+		iIndent-=2;
+		iConsole.SetPos(iIndent);
+		iConsole.Printf(_L("<END LIST>\n"));
+		}
+	else
+		{
+		iConsole.Printf(_L("WARNING: UNMATCHED END LIST!"));
+		}
+	return this;
+	};
+MSdpElementBuilder* CPrintBuilder::BuildURLL(const TDesC8& aString)
+	{
+	iConsole.SetPos(iIndent);
+	iConsole.Printf(_L("Got URL: \n"));
+	HexDumpVT(aString);
+	return this;
+	};
+
+
+
+