|
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Test code for HCI Proxy class (adapted from TRFCOMM) |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32test.h> |
|
19 #include <es_sock.h> |
|
20 #include <f32file.h> |
|
21 #include <bt_sock.h> |
|
22 #include <c32comm.h> |
|
23 #include "btmanclient.h" |
|
24 #include "debug.h" |
|
25 #include <btsdp.h> |
|
26 #include <hciproxy.h> |
|
27 |
|
28 #if defined (__WINS__) |
|
29 #define PDD_NAME _L("ECDRV") |
|
30 #define LDD_NAME _L("ECOMM") |
|
31 #else // __GCC32__ |
|
32 #define PDD_NAME _L("EUART1") |
|
33 #define LDD_NAME _L("ECOMM") |
|
34 // #define ETNA_PDD_NAME _L("EUART2") // for debugging over com2 |
|
35 #endif |
|
36 |
|
37 // Test Ioctl definitions |
|
38 //const static TUint KRFCOMMFConIoctl = 0x7FFFFFFF; |
|
39 //const static TUint KRFCOMMFCoffIoctl = 0x7FFFFFFE; |
|
40 |
|
41 TBuf8<1024> buf; |
|
42 TBuf16<2048> display; |
|
43 |
|
44 GLDEF_D RTest test(_L("HCI Proxy module tests")); |
|
45 |
|
46 const TUint KEventTimeout = 5000000; |
|
47 |
|
48 |
|
49 void LoadLDD_PDD() |
|
50 { |
|
51 TInt r; |
|
52 r=StartC32(); |
|
53 if (r!=KErrNone && r!=KErrAlreadyExists) |
|
54 { |
|
55 test.Printf(_L("Failed %d!\n\r"),r); |
|
56 test(r==KErrNone); |
|
57 } |
|
58 else |
|
59 test.Printf(_L("Started C32\n")); |
|
60 test.Printf(_L("Loading PDD\n")); |
|
61 r=User::LoadPhysicalDevice(PDD_NAME); |
|
62 if (r!=KErrNone && r!=KErrAlreadyExists) |
|
63 { |
|
64 test.Printf(_L("Failed %d!\n\r"),r); |
|
65 test(r==KErrNone); |
|
66 } |
|
67 else |
|
68 test.Printf(_L("Loaded LDD\n")); |
|
69 test.Printf(_L("Loading LDD\n")); |
|
70 r=User::LoadLogicalDevice(LDD_NAME); |
|
71 if (r!=KErrNone && r!=KErrAlreadyExists) |
|
72 { |
|
73 test.Printf(_L("Failed %d!\n\r"),r); |
|
74 test(r==KErrNone); |
|
75 } |
|
76 else |
|
77 test.Printf(_L("Loaded PDD\n")); |
|
78 } |
|
79 |
|
80 |
|
81 |
|
82 void TestMenuL() |
|
83 { |
|
84 test.SetLogged(EFalse); |
|
85 test.Title(); |
|
86 test.Start(_L("Loading RFCOMM Protocol Module")); |
|
87 |
|
88 // This function is essential! |
|
89 LoadLDD_PDD(); |
|
90 // For some reason, you have to do the following to |
|
91 // ensure that the file server behaves properly. |
|
92 |
|
93 |
|
94 } |
|
95 |
|
96 CConsoleBase* AutoSizeNewL(const TDesC& aTitle, TSize aSize) |
|
97 { |
|
98 // Try to create a console of our preferred size, otherwise we |
|
99 // guess the screen is too small and use its entirety. |
|
100 CConsoleBase* console = NULL; |
|
101 TRAPD(err, console = Console::NewL(aTitle, aSize)); |
|
102 if (err != KErrNone) |
|
103 { |
|
104 // If we leave now it is not because of offscreen drawing. |
|
105 console = Console::NewL(aTitle, TSize(KConsFullScreen, KConsFullScreen)); |
|
106 } |
|
107 return console; |
|
108 } |
|
109 |
|
110 /******************************************************************/ |
|
111 class CVendorSpecificEventTimout; |
|
112 |
|
113 class CDebugEventConsole : public CBase, private MVendorSpecificHciConduit |
|
114 { |
|
115 friend class CVendorSpecificEventTimout; |
|
116 public: |
|
117 static CDebugEventConsole* NewL(); |
|
118 |
|
119 ~CDebugEventConsole(); |
|
120 |
|
121 private: |
|
122 void ConstructL(); |
|
123 CDebugEventConsole(); |
|
124 virtual void CommandCompleted(TInt aError); |
|
125 virtual TBool ReceiveEvent(TDesC8& aEvent, TInt aError); |
|
126 |
|
127 void KillTest(); |
|
128 void StartVdTestCase(); |
|
129 void VerifyVdTestCase(TUint aVdTcNum, const TDesC8& aData); |
|
130 |
|
131 static const TUint8 VendorDebugTC1[]; |
|
132 static const TUint8 VendorDebugTC2[]; |
|
133 static const TUint8 VendorDebugTC3[]; |
|
134 static const TUint8 VendorDebugTC4[]; |
|
135 |
|
136 typedef struct |
|
137 { |
|
138 const TUint8* iData; |
|
139 TUint iSize; |
|
140 } |
|
141 TVendorDebugTC; |
|
142 |
|
143 static const TVendorDebugTC VendorDebugTestCases[]; |
|
144 static const TUint KNumVdTestCases; |
|
145 |
|
146 static TInt NextVendorDebugTestCaseCallbackFun(TAny *aPtr); |
|
147 |
|
148 CAsyncCallBack iNextVdTcCallBack; |
|
149 |
|
150 // If true, CommandCompleted will start Vendor Debug test case n+1 when n completes. |
|
151 TBool iVdTestCasesRunChained; |
|
152 // The number of currently executing Vendor Debug test case. 1-based. |
|
153 TUint iVdTcNum; |
|
154 CConsoleBase* iConsole; |
|
155 CHciExtensionConduit* iConduit; |
|
156 CVendorSpecificEventTimout* iEventTimeout; |
|
157 }; |
|
158 |
|
159 NONSHARABLE_CLASS(CVendorSpecificEventTimout) : public CTimer |
|
160 { |
|
161 public: |
|
162 virtual ~CVendorSpecificEventTimout(); |
|
163 static CVendorSpecificEventTimout* NewL(CDebugEventConsole* aContext); |
|
164 virtual void CancelTimer(); |
|
165 virtual void StartTimer(); |
|
166 private: |
|
167 void RunL(); |
|
168 CVendorSpecificEventTimout(CDebugEventConsole* aContext); |
|
169 void ConstructL(); |
|
170 private: |
|
171 CDebugEventConsole* iClient; |
|
172 }; |
|
173 |
|
174 |
|
175 /******************************************************************/ |
|
176 |
|
177 |
|
178 const TUint KLastTestComplete = KMaxTUint; |
|
179 |
|
180 const TUint8 CDebugEventConsole::VendorDebugTC1[] = |
|
181 { |
|
182 1, 2, 3, |
|
183 }; |
|
184 |
|
185 const TUint8 CDebugEventConsole::VendorDebugTC2[] = |
|
186 { |
|
187 0 |
|
188 }; |
|
189 |
|
190 // 250 bytes. If you add 3 bytes of fixed parameters in the Command Completion Event, |
|
191 // you get 253 bytes of data. We should be able to handle 255 bytes of data, |
|
192 // but the conduit's ioctl buffer is too small for 255 bytes in Command Completion Events |
|
193 // - the buffer was meant for commands and then abused for returned completion events, |
|
194 // and it's 2 bytes too short for them (because you also get 2 bytes extra of packet headers). |
|
195 const TUint8 CDebugEventConsole::VendorDebugTC3[] = |
|
196 { |
|
197 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
198 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
199 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
200 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
201 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
202 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
203 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
204 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
205 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
206 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
207 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
208 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
209 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
210 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
211 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, |
|
212 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, //0xA, 0xB, 0xC, 0xD, 0xE |
|
213 }; |
|
214 |
|
215 const TUint8 CDebugEventConsole::VendorDebugTC4[] = |
|
216 { |
|
217 'i', 't', ' ', 'w', 'o', 'r', 'k', 's', '!' |
|
218 }; |
|
219 |
|
220 const CDebugEventConsole::TVendorDebugTC CDebugEventConsole::VendorDebugTestCases[] = |
|
221 { |
|
222 { VendorDebugTC1, sizeof VendorDebugTC1 }, |
|
223 { VendorDebugTC2, sizeof VendorDebugTC2 }, |
|
224 { VendorDebugTC3, sizeof VendorDebugTC3 }, |
|
225 { VendorDebugTC4, sizeof VendorDebugTC4 } |
|
226 }; |
|
227 |
|
228 const TUint CDebugEventConsole::KNumVdTestCases = |
|
229 sizeof CDebugEventConsole::VendorDebugTestCases / sizeof CDebugEventConsole::VendorDebugTestCases[0]; |
|
230 |
|
231 |
|
232 CDebugEventConsole* CDebugEventConsole::NewL() |
|
233 { |
|
234 CDebugEventConsole* self=new (ELeave)CDebugEventConsole(); |
|
235 CleanupStack::PushL(self); |
|
236 self->ConstructL(); |
|
237 CleanupStack::Pop(self); |
|
238 return self; |
|
239 } |
|
240 |
|
241 CDebugEventConsole::~CDebugEventConsole() |
|
242 { |
|
243 delete iConsole; |
|
244 delete iConduit; |
|
245 delete iEventTimeout; |
|
246 } |
|
247 |
|
248 void CDebugEventConsole::ConstructL() |
|
249 { |
|
250 |
|
251 TUint8 Extension[] = //returns response event |
|
252 { |
|
253 0x99 //...DUMMY VALUE: Insert extension byte sequence here... |
|
254 }; |
|
255 |
|
256 /* TUint8 ActivateInfo[] = //returns response event and couple of extension events |
|
257 { |
|
258 99 //...DUMMY VALUE: Insert activation byte sequence here... |
|
259 }; |
|
260 |
|
261 TUint8 DeActivateInfo[] = //returns response event and couple of extension events |
|
262 { |
|
263 99 //...DUMMY VALUE: Insert deactivation byte sequence here... |
|
264 }; |
|
265 |
|
266 TUint8 ActivateSequence[] = //HCI extension events sent once per second until deactivation |
|
267 { |
|
268 99 //...DUMMY VALUE: Insert sequence activation byte sequence here... |
|
269 }; |
|
270 |
|
271 TUint8 DeActivateSequence[] = //deactivate ActivateSequence - no more events! |
|
272 { |
|
273 99 //...DUMMY VALUE: Insert sequence deactivation byte sequence here... |
|
274 }; |
|
275 */ |
|
276 |
|
277 TBuf8<100> ExtensionCommand; |
|
278 ExtensionCommand.Append(Extension, sizeof(Extension)); |
|
279 |
|
280 // TPtrC8 ExtensionCommand(Extension, sizeof(Extension)); |
|
281 // TPtrC8 ExtensionCommand(ActivateInfo, 3); |
|
282 // TPtrC8 ExtensionCommand(DeActivateInfo, sizeof(DeActivateInfo)); |
|
283 // TPtrC8 ExtensionCommand(ActivateSequence, sizeof(ActivateSequence)); |
|
284 // TPtrC8 ExtensionCommand(DeActivateSequence, sizeof(DeActivateSequence)); |
|
285 |
|
286 iConsole=AutoSizeNewL(_L("listening for Events..."),TSize(50,40)); |
|
287 iConduit = CHciExtensionConduit::NewL(*this); |
|
288 iEventTimeout = CVendorSpecificEventTimout::NewL(this); |
|
289 |
|
290 // Get the VendorSpecificDebug Command test cases going. |
|
291 // They will run in chain, until each test case from VendorDebugTestCases[] has executed. |
|
292 iVdTestCasesRunChained = ETrue; |
|
293 iVdTcNum = 0; |
|
294 iConsole->Printf(_L("\"No Hardware Response\" Test Case\n")); |
|
295 _LIT8(KDummyString, "Dummy"); |
|
296 iConduit->IssueCommandL(KVendorDebugOGF | 0x00, KDummyString()); |
|
297 } |
|
298 |
|
299 CDebugEventConsole::CDebugEventConsole() |
|
300 : iNextVdTcCallBack(TCallBack(NextVendorDebugTestCaseCallbackFun, this), CActive::EPriorityStandard) |
|
301 { |
|
302 } |
|
303 |
|
304 void CDebugEventConsole::KillTest() |
|
305 { |
|
306 iConsole->Printf(_L("ALL TESTS HAVE COMPLETED!\nPRESS ANY KEY TO CLOSE TProxy\n")); |
|
307 iConsole->Getch(); |
|
308 CActiveScheduler::Stop(); |
|
309 return; |
|
310 } |
|
311 |
|
312 void CDebugEventConsole::StartVdTestCase() |
|
313 { |
|
314 TBuf8<256> CmdDsc; |
|
315 const TVendorDebugTC& tc = VendorDebugTestCases[iVdTcNum-1]; |
|
316 if (tc.iSize > 0) |
|
317 CmdDsc.Append(tc.iData, tc.iSize); |
|
318 iConsole->Printf(_L("Starting VendorDebug Test Case number %d\n"), iVdTcNum); |
|
319 TRAPD(err, iConduit->IssueCommandExpectingCompleteEventL(KVendorDebugOGF | iVdTcNum, CmdDsc)); |
|
320 if(err) |
|
321 { |
|
322 iConsole->Printf(_L("Starting VendorDebug Test Case returned error %d\n"),err); |
|
323 } |
|
324 |
|
325 } |
|
326 |
|
327 void CDebugEventConsole::VerifyVdTestCase(TUint aVdTcNum, const TDesC8& aData) |
|
328 { |
|
329 const TVendorDebugTC& tc = VendorDebugTestCases[aVdTcNum-1]; |
|
330 const TUint KMaxDataSize = 255; |
|
331 const TUint KCommandHeaderSize = 2; |
|
332 const TUint KFixedParamSize = 3; |
|
333 TUint sizeField = (tc.iSize + KFixedParamSize < KMaxDataSize) ? |
|
334 (tc.iSize + KFixedParamSize) : KMaxDataSize; |
|
335 |
|
336 for (int i = 0; i < aData.Length(); i++) |
|
337 { |
|
338 iConsole->Printf(_L("Received CCE: %x\n"), aData[i]); |
|
339 } |
|
340 for (int i = 0; i < tc.iSize; i++) |
|
341 { |
|
342 test(aData[i] == tc.iData[i]); |
|
343 } |
|
344 return; |
|
345 } |
|
346 |
|
347 TInt CDebugEventConsole::NextVendorDebugTestCaseCallbackFun(TAny* aPtr) |
|
348 { |
|
349 CDebugEventConsole* self = static_cast<CDebugEventConsole*>(aPtr); |
|
350 self->StartVdTestCase(); |
|
351 return 0; |
|
352 } |
|
353 |
|
354 void CDebugEventConsole::CommandCompleted(TInt aError) |
|
355 { |
|
356 iConsole->Printf(_L("Cmd Complete: %d\n"), aError); |
|
357 |
|
358 TPtrC8 data; |
|
359 iConduit->CommandCompleteEventData(data); |
|
360 |
|
361 VerifyVdTestCase(iVdTcNum, data); |
|
362 |
|
363 if (iVdTestCasesRunChained && iVdTcNum < KNumVdTestCases) |
|
364 { |
|
365 iVdTcNum++; |
|
366 iNextVdTcCallBack.CallBack(); |
|
367 } |
|
368 else |
|
369 { |
|
370 iVdTcNum = KLastTestComplete; |
|
371 iConduit->WaitForEvent(); //now see if we have any events queued |
|
372 iEventTimeout->StartTimer(); |
|
373 } |
|
374 } |
|
375 |
|
376 TBool CDebugEventConsole::ReceiveEvent(TDesC8& aEvent, TInt aError) |
|
377 { |
|
378 iConsole->Printf(_L("Rcvd Event!\n err %d Length %d\n"), aError, aEvent.Length()); |
|
379 for (int i = 0; i < aEvent.Length(); i++) |
|
380 { |
|
381 iConsole->Printf(_L("Received Dbg Evnt: %x\n"), aEvent[i]); |
|
382 } |
|
383 iEventTimeout->StartTimer(); // restart evnt timeout |
|
384 return ETrue; // Keep receiving events |
|
385 } |
|
386 |
|
387 /******************************************************************/ |
|
388 |
|
389 CVendorSpecificEventTimout::CVendorSpecificEventTimout(CDebugEventConsole* aContext) : CTimer(EPriorityStandard), |
|
390 iClient(aContext) |
|
391 { |
|
392 } |
|
393 |
|
394 CVendorSpecificEventTimout::~CVendorSpecificEventTimout() |
|
395 { |
|
396 CancelTimer(); |
|
397 } |
|
398 |
|
399 |
|
400 CVendorSpecificEventTimout* CVendorSpecificEventTimout::NewL(CDebugEventConsole* aContext) |
|
401 { |
|
402 CVendorSpecificEventTimout* self = new (ELeave) CVendorSpecificEventTimout(aContext); |
|
403 CleanupStack::PushL(self); |
|
404 self->ConstructL(); |
|
405 CleanupStack::Pop(); |
|
406 return self; |
|
407 } |
|
408 |
|
409 void CVendorSpecificEventTimout::ConstructL() |
|
410 { |
|
411 CTimer::ConstructL(); |
|
412 CActiveScheduler::Add(this); |
|
413 } |
|
414 |
|
415 void CVendorSpecificEventTimout::CancelTimer() |
|
416 { |
|
417 if(IsActive()) |
|
418 { |
|
419 CActive::Cancel(); |
|
420 } |
|
421 } |
|
422 |
|
423 void CVendorSpecificEventTimout::StartTimer() |
|
424 { |
|
425 if(IsActive()) |
|
426 { |
|
427 CActive::Cancel(); |
|
428 } |
|
429 After(KEventTimeout); |
|
430 } |
|
431 |
|
432 |
|
433 |
|
434 void CVendorSpecificEventTimout::RunL() |
|
435 { |
|
436 iClient->KillTest(); |
|
437 } |
|
438 |
|
439 |
|
440 /******************************************************************/ |
|
441 |
|
442 void DoEventListenerL() |
|
443 { |
|
444 CActiveScheduler *exampleScheduler = new (ELeave) CActiveScheduler(); |
|
445 CleanupStack::PushL(exampleScheduler); |
|
446 CActiveScheduler::Install(exampleScheduler); |
|
447 |
|
448 CleanupStack::PushL(CDebugEventConsole::NewL()); |
|
449 |
|
450 /* TInt count=0; |
|
451 while(ETrue) |
|
452 { |
|
453 User::After(1000000); |
|
454 myConsole->Printf(_L("Number %d\n"),++count); |
|
455 } |
|
456 */ |
|
457 CActiveScheduler::Start(); |
|
458 |
|
459 CleanupStack::PopAndDestroy(2); // active shed, myDebug |
|
460 } |
|
461 |
|
462 |
|
463 TInt AnotherThreadFunction(TAny*) |
|
464 { |
|
465 CTrapCleanup* cleanupStack=CTrapCleanup::New(); |
|
466 TRAPD(err,DoEventListenerL()); |
|
467 delete cleanupStack; |
|
468 return err; |
|
469 } |
|
470 |
|
471 TInt E32Main() |
|
472 { |
|
473 |
|
474 CTrapCleanup* cleanupStack=CTrapCleanup::New(); |
|
475 |
|
476 // RThread thread; |
|
477 // thread.Create(_L("Plim"),AnotherThreadFunction,KDefaultStackSize,KMinHeapSize,0x15000,(TAny*)0); |
|
478 // thread.Resume(); |
|
479 |
|
480 TRAP_IGNORE(TestMenuL()); // Ignore err |
|
481 TRAPD(err, DoEventListenerL()); |
|
482 |
|
483 // thread.Close(); |
|
484 |
|
485 delete cleanupStack; |
|
486 |
|
487 return err; |
|
488 } |
|
489 |