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