bthci/hciextensioninterface/tsrc/tproxy.cpp
changeset 0 29b1cd4cb562
child 47 a1b8f5cc021e
--- /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 <e32test.h>
+#include <es_sock.h>
+#include <f32file.h>
+#include <bt_sock.h>
+#include <c32comm.h>
+#include "btmanclient.h"
+#include "debug.h"
+#include <btsdp.h>
+#include <hciproxy.h>
+
+#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<CDebugEventConsole*>(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;
+	}
+