diff -r 000000000000 -r 29b1cd4cb562 bthci/hciextensioninterface/tsrc/tproxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bthci/hciextensioninterface/tsrc/tproxy.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,489 @@ +// 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: +// Test code for HCI Proxy class (adapted from TRFCOMM) +// +// + +#include +#include +#include +#include +#include +#include "btmanclient.h" +#include "debug.h" +#include +#include + +#if defined (__WINS__) +#define PDD_NAME _L("ECDRV") +#define LDD_NAME _L("ECOMM") +#else // __GCC32__ +#define PDD_NAME _L("EUART1") +#define LDD_NAME _L("ECOMM") +// #define ETNA_PDD_NAME _L("EUART2") // for debugging over com2 +#endif + +// Test Ioctl definitions +//const static TUint KRFCOMMFConIoctl = 0x7FFFFFFF; +//const static TUint KRFCOMMFCoffIoctl = 0x7FFFFFFE; + +TBuf8<1024> buf; +TBuf16<2048> display; + +GLDEF_D RTest test(_L("HCI Proxy module tests")); + +const TUint KEventTimeout = 5000000; + + +void LoadLDD_PDD() + { + TInt r; + r=StartC32(); + if (r!=KErrNone && r!=KErrAlreadyExists) + { + test.Printf(_L("Failed %d!\n\r"),r); + test(r==KErrNone); + } + else + test.Printf(_L("Started C32\n")); + test.Printf(_L("Loading PDD\n")); + r=User::LoadPhysicalDevice(PDD_NAME); + if (r!=KErrNone && r!=KErrAlreadyExists) + { + test.Printf(_L("Failed %d!\n\r"),r); + test(r==KErrNone); + } + else + test.Printf(_L("Loaded LDD\n")); + test.Printf(_L("Loading LDD\n")); + r=User::LoadLogicalDevice(LDD_NAME); + if (r!=KErrNone && r!=KErrAlreadyExists) + { + test.Printf(_L("Failed %d!\n\r"),r); + test(r==KErrNone); + } + else + test.Printf(_L("Loaded PDD\n")); + } + + + +void TestMenuL() + { + test.SetLogged(EFalse); + test.Title(); + test.Start(_L("Loading RFCOMM Protocol Module")); + + // This function is essential! + LoadLDD_PDD(); + // For some reason, you have to do the following to + // ensure that the file server behaves properly. + + + } + +CConsoleBase* AutoSizeNewL(const TDesC& aTitle, TSize aSize) + { + // Try to create a console of our preferred size, otherwise we + // guess the screen is too small and use its entirety. + CConsoleBase* console = NULL; + TRAPD(err, console = Console::NewL(aTitle, aSize)); + if (err != KErrNone) + { + // If we leave now it is not because of offscreen drawing. + console = Console::NewL(aTitle, TSize(KConsFullScreen, KConsFullScreen)); + } + return console; + } + +/******************************************************************/ +class CVendorSpecificEventTimout; + +class CDebugEventConsole : public CBase, private MVendorSpecificHciConduit + { + friend class CVendorSpecificEventTimout; +public: + static CDebugEventConsole* NewL(); + + ~CDebugEventConsole(); + +private: + void ConstructL(); + CDebugEventConsole(); + virtual void CommandCompleted(TInt aError); + virtual TBool ReceiveEvent(TDesC8& aEvent, TInt aError); + + void KillTest(); + void StartVdTestCase(); + void VerifyVdTestCase(TUint aVdTcNum, const TDesC8& aData); + + static const TUint8 VendorDebugTC1[]; + static const TUint8 VendorDebugTC2[]; + static const TUint8 VendorDebugTC3[]; + static const TUint8 VendorDebugTC4[]; + + typedef struct + { + const TUint8* iData; + TUint iSize; + } + TVendorDebugTC; + + static const TVendorDebugTC VendorDebugTestCases[]; + static const TUint KNumVdTestCases; + + static TInt NextVendorDebugTestCaseCallbackFun(TAny *aPtr); + + CAsyncCallBack iNextVdTcCallBack; + + // If true, CommandCompleted will start Vendor Debug test case n+1 when n completes. + TBool iVdTestCasesRunChained; + // The number of currently executing Vendor Debug test case. 1-based. + TUint iVdTcNum; + CConsoleBase* iConsole; + CHciExtensionConduit* iConduit; + CVendorSpecificEventTimout* iEventTimeout; + }; + +NONSHARABLE_CLASS(CVendorSpecificEventTimout) : public CTimer + { +public: + virtual ~CVendorSpecificEventTimout(); + static CVendorSpecificEventTimout* NewL(CDebugEventConsole* aContext); + virtual void CancelTimer(); + virtual void StartTimer(); +private: + void RunL(); + CVendorSpecificEventTimout(CDebugEventConsole* aContext); + void ConstructL(); +private: + CDebugEventConsole* iClient; + }; + + +/******************************************************************/ + + +const TUint KLastTestComplete = KMaxTUint; + +const TUint8 CDebugEventConsole::VendorDebugTC1[] = + { + 1, 2, 3, + }; + +const TUint8 CDebugEventConsole::VendorDebugTC2[] = + { + 0 + }; + +// 250 bytes. If you add 3 bytes of fixed parameters in the Command Completion Event, +// you get 253 bytes of data. We should be able to handle 255 bytes of data, +// but the conduit's ioctl buffer is too small for 255 bytes in Command Completion Events +// - the buffer was meant for commands and then abused for returned completion events, +// and it's 2 bytes too short for them (because you also get 2 bytes extra of packet headers). +const TUint8 CDebugEventConsole::VendorDebugTC3[] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, //0xA, 0xB, 0xC, 0xD, 0xE + }; + +const TUint8 CDebugEventConsole::VendorDebugTC4[] = + { + 'i', 't', ' ', 'w', 'o', 'r', 'k', 's', '!' + }; + +const CDebugEventConsole::TVendorDebugTC CDebugEventConsole::VendorDebugTestCases[] = + { + { VendorDebugTC1, sizeof VendorDebugTC1 }, + { VendorDebugTC2, sizeof VendorDebugTC2 }, + { VendorDebugTC3, sizeof VendorDebugTC3 }, + { VendorDebugTC4, sizeof VendorDebugTC4 } + }; + +const TUint CDebugEventConsole::KNumVdTestCases = + sizeof CDebugEventConsole::VendorDebugTestCases / sizeof CDebugEventConsole::VendorDebugTestCases[0]; + + +CDebugEventConsole* CDebugEventConsole::NewL() + { + CDebugEventConsole* self=new (ELeave)CDebugEventConsole(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CDebugEventConsole::~CDebugEventConsole() + { + delete iConsole; + delete iConduit; + delete iEventTimeout; + } + +void CDebugEventConsole::ConstructL() + { + + TUint8 Extension[] = //returns response event + { + 0x99 //...DUMMY VALUE: Insert extension byte sequence here... + }; + +/* TUint8 ActivateInfo[] = //returns response event and couple of extension events + { + 99 //...DUMMY VALUE: Insert activation byte sequence here... + }; + + TUint8 DeActivateInfo[] = //returns response event and couple of extension events + { + 99 //...DUMMY VALUE: Insert deactivation byte sequence here... + }; + + TUint8 ActivateSequence[] = //HCI extension events sent once per second until deactivation + { + 99 //...DUMMY VALUE: Insert sequence activation byte sequence here... + }; + + TUint8 DeActivateSequence[] = //deactivate ActivateSequence - no more events! + { + 99 //...DUMMY VALUE: Insert sequence deactivation byte sequence here... + }; +*/ + + TBuf8<100> ExtensionCommand; + ExtensionCommand.Append(Extension, sizeof(Extension)); + +// TPtrC8 ExtensionCommand(Extension, sizeof(Extension)); +// TPtrC8 ExtensionCommand(ActivateInfo, 3); +// TPtrC8 ExtensionCommand(DeActivateInfo, sizeof(DeActivateInfo)); +// TPtrC8 ExtensionCommand(ActivateSequence, sizeof(ActivateSequence)); +// TPtrC8 ExtensionCommand(DeActivateSequence, sizeof(DeActivateSequence)); + + iConsole=AutoSizeNewL(_L("listening for Events..."),TSize(50,40)); + iConduit = CHciExtensionConduit::NewL(*this); + iEventTimeout = CVendorSpecificEventTimout::NewL(this); + + // Get the VendorSpecificDebug Command test cases going. + // They will run in chain, until each test case from VendorDebugTestCases[] has executed. + iVdTestCasesRunChained = ETrue; + iVdTcNum = 0; + iConsole->Printf(_L("\"No Hardware Response\" Test Case\n")); + _LIT8(KDummyString, "Dummy"); + iConduit->IssueCommandL(KVendorDebugOGF | 0x00, KDummyString()); + } + +CDebugEventConsole::CDebugEventConsole() + : iNextVdTcCallBack(TCallBack(NextVendorDebugTestCaseCallbackFun, this), CActive::EPriorityStandard) + { + } + +void CDebugEventConsole::KillTest() + { + iConsole->Printf(_L("ALL TESTS HAVE COMPLETED!\nPRESS ANY KEY TO CLOSE TProxy\n")); + iConsole->Getch(); + CActiveScheduler::Stop(); + return; + } + +void CDebugEventConsole::StartVdTestCase() + { + TBuf8<256> CmdDsc; + const TVendorDebugTC& tc = VendorDebugTestCases[iVdTcNum-1]; + if (tc.iSize > 0) + CmdDsc.Append(tc.iData, tc.iSize); + iConsole->Printf(_L("Starting VendorDebug Test Case number %d\n"), iVdTcNum); + TRAPD(err, iConduit->IssueCommandExpectingCompleteEventL(KVendorDebugOGF | iVdTcNum, CmdDsc)); + if(err) + { + iConsole->Printf(_L("Starting VendorDebug Test Case returned error %d\n"),err); + } + + } + +void CDebugEventConsole::VerifyVdTestCase(TUint aVdTcNum, const TDesC8& aData) + { + const TVendorDebugTC& tc = VendorDebugTestCases[aVdTcNum-1]; + const TUint KMaxDataSize = 255; + const TUint KCommandHeaderSize = 2; + const TUint KFixedParamSize = 3; + TUint sizeField = (tc.iSize + KFixedParamSize < KMaxDataSize) ? + (tc.iSize + KFixedParamSize) : KMaxDataSize; + + for (int i = 0; i < aData.Length(); i++) + { + iConsole->Printf(_L("Received CCE: %x\n"), aData[i]); + } + for (int i = 0; i < tc.iSize; i++) + { + test(aData[i] == tc.iData[i]); + } + return; + } + +TInt CDebugEventConsole::NextVendorDebugTestCaseCallbackFun(TAny* aPtr) + { + CDebugEventConsole* self = static_cast(aPtr); + self->StartVdTestCase(); + return 0; + } + +void CDebugEventConsole::CommandCompleted(TInt aError) + { + iConsole->Printf(_L("Cmd Complete: %d\n"), aError); + + TPtrC8 data; + iConduit->CommandCompleteEventData(data); + + VerifyVdTestCase(iVdTcNum, data); + + if (iVdTestCasesRunChained && iVdTcNum < KNumVdTestCases) + { + iVdTcNum++; + iNextVdTcCallBack.CallBack(); + } + else + { + iVdTcNum = KLastTestComplete; + iConduit->WaitForEvent(); //now see if we have any events queued + iEventTimeout->StartTimer(); + } + } + +TBool CDebugEventConsole::ReceiveEvent(TDesC8& aEvent, TInt aError) + { + iConsole->Printf(_L("Rcvd Event!\n err %d Length %d\n"), aError, aEvent.Length()); + for (int i = 0; i < aEvent.Length(); i++) + { + iConsole->Printf(_L("Received Dbg Evnt: %x\n"), aEvent[i]); + } + iEventTimeout->StartTimer(); // restart evnt timeout + return ETrue; // Keep receiving events + } + +/******************************************************************/ + +CVendorSpecificEventTimout::CVendorSpecificEventTimout(CDebugEventConsole* aContext) : CTimer(EPriorityStandard), + iClient(aContext) + { + } + +CVendorSpecificEventTimout::~CVendorSpecificEventTimout() + { + CancelTimer(); + } + + +CVendorSpecificEventTimout* CVendorSpecificEventTimout::NewL(CDebugEventConsole* aContext) + { + CVendorSpecificEventTimout* self = new (ELeave) CVendorSpecificEventTimout(aContext); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +void CVendorSpecificEventTimout::ConstructL() + { + CTimer::ConstructL(); + CActiveScheduler::Add(this); + } + +void CVendorSpecificEventTimout::CancelTimer() + { + if(IsActive()) + { + CActive::Cancel(); + } + } + +void CVendorSpecificEventTimout::StartTimer() + { + if(IsActive()) + { + CActive::Cancel(); + } + After(KEventTimeout); + } + + + +void CVendorSpecificEventTimout::RunL() + { + iClient->KillTest(); + } + + +/******************************************************************/ + +void DoEventListenerL() + { + CActiveScheduler *exampleScheduler = new (ELeave) CActiveScheduler(); + CleanupStack::PushL(exampleScheduler); + CActiveScheduler::Install(exampleScheduler); + + CleanupStack::PushL(CDebugEventConsole::NewL()); + +/* TInt count=0; + while(ETrue) + { + User::After(1000000); + myConsole->Printf(_L("Number %d\n"),++count); + } +*/ + CActiveScheduler::Start(); + + CleanupStack::PopAndDestroy(2); // active shed, myDebug + } + + +TInt AnotherThreadFunction(TAny*) + { + CTrapCleanup* cleanupStack=CTrapCleanup::New(); + TRAPD(err,DoEventListenerL()); + delete cleanupStack; + return err; + } + +TInt E32Main() + { + + CTrapCleanup* cleanupStack=CTrapCleanup::New(); + +// RThread thread; +// thread.Create(_L("Plim"),AnotherThreadFunction,KDefaultStackSize,KMinHeapSize,0x15000,(TAny*)0); +// thread.Resume(); + + TRAP_IGNORE(TestMenuL()); // Ignore err + TRAPD(err, DoEventListenerL()); + +// thread.Close(); + + delete cleanupStack; + + return err; + } +