|
1 /* |
|
2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * This program executes all the tests in the ACM CSY Test Specification v 0.1 |
|
16 * on the host, and is to be used in conjunction with the device-side application (t_acm). |
|
17 * |
|
18 */ |
|
19 |
|
20 // Includes //////////////////////////////////////////////////////////////////// |
|
21 |
|
22 /* Symbian OS includes */ |
|
23 #include <e32base.h> |
|
24 #include <e32cons.h> |
|
25 #include <e32math.h> |
|
26 |
|
27 #define WIN32_LEAN_AND_MEAN |
|
28 |
|
29 /* Windows i/o for serial device */ |
|
30 #include <windows.h> |
|
31 #include <wchar.h> |
|
32 |
|
33 // Defines and enumerations ///////////////////////////////////////////////////// |
|
34 |
|
35 #define _printf console->Printf |
|
36 #define _getch console->Getch |
|
37 #define LEAVE(_x) VerboseLeaveL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x)) |
|
38 #define LEAVEIFERROR(_x) VerboseLeaveIfErrorL(_x, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x)) |
|
39 #define CHECK(_x) if (! (_x)) VerboseLeaveL(KErrGeneral, __LINE__, TPtrC8((const TUint8*)__FILE__), _L8(#_x)) |
|
40 |
|
41 #define MAX_BUFFER_SIZE 1024 |
|
42 |
|
43 // Flow control constants |
|
44 enum FlowControl_Modes {KFLOW_NONE, KFLOW_RTSCTS, KFLOW_DTRDSR}; |
|
45 |
|
46 // Global Variables ///////////////////////////////////////////////////////////// |
|
47 |
|
48 HANDLE hSerial; // An MS Windows handle for the serial port |
|
49 DCB OldDcb; // for storing the original serial device context |
|
50 DCB newDcb; |
|
51 |
|
52 // For holding our new serial port parameteres |
|
53 struct SerialParameters |
|
54 { |
|
55 char *comport; // which port |
|
56 unsigned long pktsize, pktcount, maxwait; // packet config |
|
57 unsigned long baud, bits, stop; // serial parameters |
|
58 unsigned char parity; |
|
59 enum FlowControl_Modes flowcontrol; // flow control handshaking |
|
60 } SerialParams; |
|
61 |
|
62 LOCAL_D CConsoleBase* console; // A Symbian command console |
|
63 |
|
64 _LIT(KPortName, "COM3"); // Windows serial port name |
|
65 |
|
66 RTimer timer; // A timer for use by several of the tests |
|
67 |
|
68 // Some buffers allocated on the heap for functions with large |
|
69 // stack usage so we don't get a __chkstk error. |
|
70 char writeBufbig[MAX_BUFFER_SIZE]; |
|
71 char readBufbig[MAX_BUFFER_SIZE]; |
|
72 |
|
73 // Functions ////////////////////////////////////////////////////////////////// |
|
74 |
|
75 void VerboseLeaveL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode) |
|
76 /** |
|
77 * For bombing out usefully. |
|
78 */ |
|
79 { |
|
80 TInt filenameOffset = aFileName.LocateReverse('\\') + 1; |
|
81 if (filenameOffset < 0) filenameOffset = 1; |
|
82 TPtrC8 shortFileName = aFileName.Mid(filenameOffset); |
|
83 TBuf<64> fName, code; |
|
84 fName.Copy(shortFileName.Left(64)); |
|
85 code.Copy(aCode.Left(64)); |
|
86 _printf(_L("ERROR (%d) on line %d of file %S\n"), aError, aLineNum, &fName); |
|
87 _printf(_L("Code: %S\n\n"), &code); |
|
88 _printf(_L("[ press any key ]")); |
|
89 _getch(); |
|
90 User::Leave(aError); |
|
91 } |
|
92 |
|
93 void VerboseLeaveIfErrorL(TInt aError, TInt aLineNum, const TDesC8& aFileName, const TDesC8& aCode) |
|
94 /** |
|
95 * For bombing out usefully if there's an error. |
|
96 */ |
|
97 { |
|
98 if (aError) |
|
99 VerboseLeaveL(aError, aLineNum, aFileName, aCode); |
|
100 } |
|
101 |
|
102 void SetWindowsSerialParams() |
|
103 /** |
|
104 * Set up the new serial parameters with which to run the tests. |
|
105 */ |
|
106 { |
|
107 // parameter 1 is port name |
|
108 // read in COM port name (this parameter must be specified!) |
|
109 SerialParams.comport = new char[10]; |
|
110 strcpy(SerialParams.comport, "COM3"); |
|
111 |
|
112 // default packet size |
|
113 SerialParams.pktsize = 1024; |
|
114 |
|
115 // default no of packets |
|
116 SerialParams.pktcount = 1; |
|
117 |
|
118 // default wait for data return |
|
119 SerialParams.maxwait = 30; |
|
120 |
|
121 // default flow control |
|
122 SerialParams.flowcontrol = KFLOW_RTSCTS; |
|
123 |
|
124 // default data rate |
|
125 // baud rate 0 (port's default) standard rates 300 -> 115200 |
|
126 SerialParams.baud = 0; |
|
127 |
|
128 // default bits per char |
|
129 SerialParams.bits = 8; |
|
130 |
|
131 // default parity |
|
132 SerialParams.parity = 'N'; |
|
133 |
|
134 // default 9 is stop bits |
|
135 SerialParams.stop = 1; |
|
136 } |
|
137 |
|
138 static int InitializePort() |
|
139 /** |
|
140 * Store the old state of the serial port and set it up for our tests. |
|
141 */ |
|
142 { |
|
143 DCB dcb; |
|
144 COMMTIMEOUTS CommsTimeouts; |
|
145 |
|
146 // Setup comms device receive & transmit buffers |
|
147 if(SetupComm(hSerial, 16384, 16384) == 0) |
|
148 { |
|
149 LEAVE(-1); |
|
150 } |
|
151 |
|
152 // Purge all characters from the output and input buffers |
|
153 // and terminate any pending read or write operations |
|
154 if(PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) == 0) |
|
155 { |
|
156 LEAVE(-1); |
|
157 } |
|
158 |
|
159 dcb.DCBlength = sizeof(DCB); |
|
160 if(GetCommState(hSerial, &dcb) == 0) |
|
161 { |
|
162 // not a serial device |
|
163 LEAVE(-1); |
|
164 } |
|
165 |
|
166 memcpy(&OldDcb, &dcb, sizeof(DCB)); |
|
167 |
|
168 // General initialization for both transmitted and received bytes |
|
169 // using port's default baud rate etc..., so read it |
|
170 SerialParams.baud = dcb.BaudRate; // Get baud rate |
|
171 SerialParams.bits = dcb.ByteSize; // Get number of bits |
|
172 if(dcb.StopBits == 2) // Get number of stop bits to be used |
|
173 SerialParams.stop = 2; |
|
174 else |
|
175 SerialParams.stop = 1; |
|
176 |
|
177 // Get parity scheme |
|
178 if((dcb.fParity == FALSE) || (dcb.Parity == 0)) |
|
179 { |
|
180 SerialParams.parity = 'N'; |
|
181 } |
|
182 else |
|
183 { |
|
184 switch(dcb.Parity) |
|
185 { |
|
186 case 1: SerialParams.parity = 'O'; break; |
|
187 case 2: SerialParams.parity = 'E'; break; |
|
188 case 3: SerialParams.parity = 'M'; break; |
|
189 case 4: SerialParams.parity = 'S'; break; |
|
190 default: SerialParams.parity = 'N'; break; // shouldn't happen |
|
191 } |
|
192 } |
|
193 dcb.fBinary = TRUE; // Set binary mode |
|
194 |
|
195 // Setup hardware flow control |
|
196 if(SerialParams.flowcontrol == KFLOW_RTSCTS) |
|
197 { |
|
198 dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; // Specify the type of RTS flow control |
|
199 dcb.fOutxCtsFlow = 1; // Specify whether the CTS signal is monitored |
|
200 |
|
201 dcb.fDtrControl = DTR_CONTROL_ENABLE; // Specify the type of DTR flow control |
|
202 dcb.fOutxDsrFlow = 0; // Specify whether the DSR signal is monitored |
|
203 } |
|
204 else if(SerialParams.flowcontrol == KFLOW_DTRDSR) |
|
205 { |
|
206 dcb.fRtsControl = RTS_CONTROL_ENABLE; // Specify the type of RTS flow control |
|
207 dcb.fOutxCtsFlow = 0; // Specify whether the CTS signal is monitored |
|
208 |
|
209 dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;// Specify the type of DTR flow control |
|
210 dcb.fOutxDsrFlow = 1; // Specify whether the DSR signal is monitored |
|
211 } |
|
212 else // KFLOW_NONE |
|
213 { |
|
214 dcb.fRtsControl = RTS_CONTROL_ENABLE; // Specify the type of RTS flow control |
|
215 dcb.fOutxCtsFlow = 0; // Specify whether the CTS signal is monitored |
|
216 |
|
217 dcb.fDtrControl = DTR_CONTROL_ENABLE; // Specify the type of DTR flow control |
|
218 dcb.fOutxDsrFlow = 0; // Specify whether the DSR signal is monitored |
|
219 } |
|
220 |
|
221 dcb.fInX = dcb.fOutX = 0; |
|
222 dcb.fDsrSensitivity = 0; |
|
223 dcb.fErrorChar = 0; |
|
224 dcb.fNull = 0; |
|
225 dcb.fAbortOnError = 1; |
|
226 |
|
227 // Configure the communications device according |
|
228 // to the specifications in the device-control block |
|
229 // The function reinitializes all hardware and control settings, |
|
230 // but does not empty output or input queues |
|
231 if(SetCommState(hSerial, &dcb) == 0) |
|
232 { |
|
233 LEAVE(-1); |
|
234 } |
|
235 |
|
236 // Set timeout parameters for comms device |
|
237 /* A value of MAXDWORD, combined with zero values for both the |
|
238 * ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, |
|
239 * specifies that the read operation is to return immediately with |
|
240 * the characters that have already been received, even if no characters |
|
241 * have been received. |
|
242 */ |
|
243 |
|
244 CommsTimeouts.ReadIntervalTimeout = 0xFFFFFFFF; |
|
245 CommsTimeouts.ReadTotalTimeoutMultiplier = 0; |
|
246 CommsTimeouts.ReadTotalTimeoutConstant = 1000; |
|
247 |
|
248 // CBR_9600 is approximately 1byte/ms. For our purposes be generous |
|
249 // & allow double the expected time per character |
|
250 if(SerialParams.maxwait > 1) |
|
251 { |
|
252 CommsTimeouts.WriteTotalTimeoutMultiplier = 0; |
|
253 CommsTimeouts.WriteTotalTimeoutConstant = (SerialParams.maxwait - 1) * 1000; |
|
254 } |
|
255 else |
|
256 { |
|
257 CommsTimeouts.WriteTotalTimeoutMultiplier = 2*CBR_9600/dcb.BaudRate; |
|
258 CommsTimeouts.WriteTotalTimeoutConstant = 1000; |
|
259 } |
|
260 |
|
261 if(0 == SetCommTimeouts(hSerial, &CommsTimeouts)) |
|
262 { |
|
263 LEAVE(-1); |
|
264 } |
|
265 |
|
266 if(0 == SetCommMask(hSerial, EV_RXCHAR | EV_ERR /* | EV_TXEMPTY */)) |
|
267 { |
|
268 LEAVE(-1); |
|
269 } |
|
270 |
|
271 return 0; |
|
272 } |
|
273 |
|
274 void OpenComPort() |
|
275 /** |
|
276 * Create a Windows com port for our serial device. |
|
277 */ |
|
278 { |
|
279 hSerial = INVALID_HANDLE_VALUE; |
|
280 wchar_t *fullname = new wchar_t[50]; |
|
281 |
|
282 // Open comms device |
|
283 wcscpy(fullname, L"\\\\.\\com3"); |
|
284 hSerial = CreateFile(fullname, |
|
285 GENERIC_READ | GENERIC_WRITE, |
|
286 0, // exclusive access |
|
287 NULL, // no security attrs |
|
288 OPEN_EXISTING, |
|
289 FILE_ATTRIBUTE_NORMAL, |
|
290 NULL ) ; |
|
291 |
|
292 // return if handle for comms device is invalid |
|
293 if (hSerial == INVALID_HANDLE_VALUE) |
|
294 { |
|
295 delete[] fullname; |
|
296 LEAVE(GetLastError()); |
|
297 } |
|
298 else |
|
299 { |
|
300 if(InitializePort()) |
|
301 { |
|
302 // Close comms device and event handles for overlapped read and write |
|
303 CloseHandle(hSerial); |
|
304 hSerial = INVALID_HANDLE_VALUE; |
|
305 } |
|
306 } |
|
307 delete[] fullname; |
|
308 } |
|
309 |
|
310 void FillBuffer(char *buffer, int size) |
|
311 /** |
|
312 * Fills the buffer with incrementing data |
|
313 */ |
|
314 { |
|
315 for (TInt i=0; i<size; i++) |
|
316 { |
|
317 // Need the & 0xff to remove the truncation warning |
|
318 buffer[i] = (char)((i%256) & 0xff); |
|
319 } |
|
320 } |
|
321 |
|
322 bool CheckBuffer(char *buffer, int size) |
|
323 /** |
|
324 * Checks the buffer is filled with incrementing data |
|
325 */ |
|
326 { |
|
327 for (TInt i=0; i<size; i++) |
|
328 { |
|
329 if (buffer[i] != i%256) |
|
330 return FALSE; |
|
331 } |
|
332 |
|
333 return TRUE; |
|
334 } |
|
335 |
|
336 void ReadData(char *RxBuffer, int size) |
|
337 /** |
|
338 * Read the given amount of data into a buffer from the serial port. |
|
339 */ |
|
340 { |
|
341 unsigned long Count; |
|
342 long total = 0; |
|
343 |
|
344 while (total < size) { |
|
345 if(ReadFile(hSerial, RxBuffer, size, &Count, NULL) == 0) |
|
346 { |
|
347 _printf(_L("ReadFile() returned error code: %d.\n"), GetLastError()); |
|
348 } |
|
349 else |
|
350 { |
|
351 total += Count; |
|
352 } |
|
353 } |
|
354 |
|
355 } |
|
356 |
|
357 void WriteData(char *TxBuffer, int size) |
|
358 /** |
|
359 * Write the given data over the serial port. |
|
360 */ |
|
361 { |
|
362 unsigned long TxCount; |
|
363 |
|
364 if(WriteFile(hSerial, TxBuffer, size, &TxCount, NULL) == 0) |
|
365 { |
|
366 _printf(_L("WriteFile() returned error code: %d.\n"), GetLastError()); |
|
367 } |
|
368 } |
|
369 |
|
370 |
|
371 //////////////////////////////////////////////////////////////////////////////// |
|
372 |
|
373 void DataStress_SizeVary_TestL() |
|
374 /** |
|
375 * Perform a single test. |
|
376 */ |
|
377 { |
|
378 _printf(_L("\n----------------------------------\n")); |
|
379 _printf(_L("This test performs varying size read\n")); |
|
380 _printf(_L("and writes to and from the device.\n")); |
|
381 _printf(_L("------------------------------------\n\n")); |
|
382 |
|
383 // Purge all characters from the output and input buffers |
|
384 // and terminate any pending read or write operations |
|
385 if(PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) == 0) |
|
386 { |
|
387 CloseHandle(hSerial); |
|
388 LEAVE(-1); |
|
389 } |
|
390 |
|
391 _printf(_L("Writing data\n")); |
|
392 for (int i = 1; i<MAX_BUFFER_SIZE; i*=2) |
|
393 { |
|
394 FillBuffer(writeBufbig, i); |
|
395 WriteData(writeBufbig, i); |
|
396 } |
|
397 |
|
398 _printf(_L("Writing more data\n")); |
|
399 for (int i = 1; i<MAX_BUFFER_SIZE; i*=2) |
|
400 { |
|
401 FillBuffer(writeBufbig, i); |
|
402 WriteData(writeBufbig, i); |
|
403 } |
|
404 |
|
405 _printf(_L("Reading data\n")); |
|
406 for (int i = 1; i<MAX_BUFFER_SIZE; i*=2) |
|
407 { |
|
408 memset(readBufbig, 0, MAX_BUFFER_SIZE); |
|
409 ReadData(readBufbig, i); |
|
410 _printf(_L("%d "), i); |
|
411 } |
|
412 |
|
413 _printf(_L("\nTest complete.\n")); |
|
414 } |
|
415 |
|
416 |
|
417 void DataStress_RateVary_TestL() |
|
418 /** |
|
419 * Perform a single test. |
|
420 */ |
|
421 { |
|
422 TInt i; |
|
423 |
|
424 _printf(_L("\n----------------------------------\n")); |
|
425 _printf(_L("This test performs varying speed read\n")); |
|
426 _printf(_L("and writes to and from the host.\n")); |
|
427 _printf(_L("Press any key to quit.\n")); |
|
428 _printf(_L("------------------------------------\n\n")); |
|
429 |
|
430 _printf(_L("Setting handshaking & receive buffer length\n")); |
|
431 |
|
432 _printf(_L("Writing data\n")); |
|
433 for (i = 1; i<100; i++) |
|
434 { |
|
435 FillBuffer(writeBufbig, MAX_BUFFER_SIZE); |
|
436 WriteData(writeBufbig, MAX_BUFFER_SIZE); |
|
437 } |
|
438 |
|
439 _printf(_L("Writing more data\n")); |
|
440 for (i = 1; i<20; i++) |
|
441 { |
|
442 FillBuffer(writeBufbig, MAX_BUFFER_SIZE); |
|
443 WriteData(writeBufbig, MAX_BUFFER_SIZE); |
|
444 } |
|
445 |
|
446 _printf(_L("Reading data\n")); |
|
447 for (i = 1; i<100; i++) |
|
448 { |
|
449 memset(readBufbig, 0, MAX_BUFFER_SIZE); |
|
450 ReadData(readBufbig, MAX_BUFFER_SIZE); |
|
451 CheckBuffer(readBufbig, MAX_BUFFER_SIZE); |
|
452 |
|
453 } |
|
454 |
|
455 _printf(_L("\nTest complete\n")); |
|
456 } |
|
457 |
|
458 void TimeOut_TestL() |
|
459 /** |
|
460 * Perform a single test. |
|
461 */ |
|
462 { |
|
463 _printf(_L("\n---------------------------\n")); |
|
464 _printf(_L("This test exercises the read\n")); |
|
465 _printf(_L("and write timeouts on the device.\n")); |
|
466 _printf(_L("Press any key to quit.\n")); |
|
467 _printf(_L("-----------------------------\n\n")); |
|
468 |
|
469 |
|
470 _printf(_L("In this test the host sits around while the device times out.\n")); |
|
471 _printf(_L("Press a key when finished.\n")); |
|
472 _getch(); |
|
473 |
|
474 _printf(_L("\nTest complete\n")); |
|
475 } |
|
476 |
|
477 void CancelTx_TestL() |
|
478 /** |
|
479 * Perform a single test. |
|
480 */ |
|
481 { |
|
482 _printf(_L("\n----------------------------------------\n")); |
|
483 _printf(_L("This tests the read/write cancel feature\n")); |
|
484 _printf(_L("Press any key to quit.\n")); |
|
485 _printf(_L("------------------------------------------\n\n")); |
|
486 |
|
487 _printf(_L("In this test the host sits around while the device cancels.\n")); |
|
488 _printf(_L("Press a key when finished.\n")); |
|
489 _getch(); |
|
490 |
|
491 _printf(_L("\nTest complete\n")); |
|
492 } |
|
493 |
|
494 void InterruptTx_TestL() |
|
495 /** |
|
496 * Perform a single test. |
|
497 */ |
|
498 { |
|
499 _printf(_L("\n--------------------------------\n")); |
|
500 _printf(_L("This tests the read/write cancel\n")); |
|
501 _printf(_L("when the USB cable is pulled\n")); |
|
502 _printf(_L("----------------------------------\n\n")); |
|
503 |
|
504 // Close the handle. If we don't do this before the device operator starts |
|
505 // pulling the cable out and plugging it in again then we'll never be able |
|
506 // to open it again afterwards. (This is also seen in HyperTerminal- |
|
507 // solution: reboot HyperTerminal.) |
|
508 CloseHandle(hSerial); |
|
509 |
|
510 // The device will attempt to read, then the cable will be pulled. |
|
511 _printf(_L("Press any key when the device reports\n")); |
|
512 _printf(_L("that the test is complete.\n")); |
|
513 _getch(); |
|
514 |
|
515 // restart the serial device |
|
516 OpenComPort(); |
|
517 |
|
518 _printf(_L("\nTest complete\n")); |
|
519 } |
|
520 |
|
521 void Shutdown_TestL() |
|
522 /** |
|
523 * Perform a single test. |
|
524 */ |
|
525 { |
|
526 _printf(_L("\n-----------------------------------\n")); |
|
527 _printf(_L("This tests the USB Manager shutdown\n")); |
|
528 _printf(_L("during reads and writes.\n")); |
|
529 _printf(_L("Press any key to quit.\n")); |
|
530 _printf(_L("-------------------------------------\n\n")); |
|
531 |
|
532 _printf(_L("In this test the host sits around while\n")); |
|
533 _printf(_L(" the device shuts down the USB manager.\n")); |
|
534 _printf(_L("Press a key when finished.\n")); |
|
535 _getch(); |
|
536 |
|
537 _printf(_L("\nTest complete\n")); |
|
538 } |
|
539 |
|
540 void BufferOverrun_TestL() |
|
541 /** |
|
542 * Test updated from that in the ACM unit test specification to |
|
543 * read/write messages bigger than the receive and transmit buffers. |
|
544 * Changed as previous test was no longer valid. |
|
545 */ |
|
546 { |
|
547 #define MAX_BIG_BUFFER_SIZE (1024*8) |
|
548 char bigBuf[MAX_BIG_BUFFER_SIZE]; |
|
549 |
|
550 _printf(_L("\n--------------------------------\n")); |
|
551 _printf(_L("This tests read/writes which are\n")); |
|
552 _printf(_L("bigger than the buffer length.\n")); |
|
553 _printf(_L("----------------------------------\n\n")); |
|
554 |
|
555 _printf(_L("Writing data.\nBuffer length: %d"), MAX_BIG_BUFFER_SIZE); |
|
556 FillBuffer(bigBuf, MAX_BIG_BUFFER_SIZE); |
|
557 WriteData(bigBuf, MAX_BIG_BUFFER_SIZE); |
|
558 |
|
559 _printf(_L("done.\nReading data\nBuffer length: %d"), MAX_BIG_BUFFER_SIZE); |
|
560 ReadData(bigBuf, MAX_BIG_BUFFER_SIZE); |
|
561 |
|
562 _printf(_L(" done.\nTest complete\n")); |
|
563 } |
|
564 |
|
565 void Break_TestL() |
|
566 /** |
|
567 * Perform a single test. |
|
568 */ |
|
569 { |
|
570 _printf(_L("\n--------------------------------\n")); |
|
571 _printf(_L("This tests break and break cancel.\n")); |
|
572 _printf(_L("----------------------------------\n\n")); |
|
573 |
|
574 _printf(_L("In this test the host sits around while\n")); |
|
575 _printf(_L("the device issues some breaks.\n")); |
|
576 _printf(_L("Press a key when finished.\n")); |
|
577 _getch(); |
|
578 |
|
579 // TODO: should also do host-requested breaks. And NotifyBreaks. |
|
580 _printf(_L("\nTest complete\n")); |
|
581 } |
|
582 |
|
583 void SignalChange_TestL() |
|
584 /** |
|
585 * Perform a single test. |
|
586 */ |
|
587 { |
|
588 _printf(_L("\n---------------------------------------\n")); |
|
589 _printf(_L("This tests signal change notifications.\n")); |
|
590 _printf(_L("---------------------------------------\n\n")); |
|
591 |
|
592 |
|
593 _printf(_L("Press any key to send a signal change.\n")); |
|
594 _getch(); |
|
595 |
|
596 newDcb.DCBlength = sizeof(DCB); |
|
597 memcpy(&OldDcb, &newDcb, sizeof(DCB)); |
|
598 |
|
599 newDcb.fRtsControl = RTS_CONTROL_HANDSHAKE; |
|
600 |
|
601 (void) SetCommState(hSerial, &newDcb); |
|
602 |
|
603 _printf(_L("\nTest complete\n")); |
|
604 } |
|
605 |
|
606 void FlowControl_TestL() |
|
607 /** |
|
608 * Perform a single test. |
|
609 */ |
|
610 { |
|
611 _printf(_L("\n-------------------------------------------\n")); |
|
612 _printf(_L("This tests flow control change notifications.\n")); |
|
613 _printf(_L("---------------------------------------------\n\n")); |
|
614 |
|
615 _printf(_L("Host side does nothing in this test. Press any key.\n")); |
|
616 _getch(); |
|
617 |
|
618 _printf(_L("\nTest complete\n")); |
|
619 } |
|
620 |
|
621 void ConfigChange_TestL() |
|
622 /** |
|
623 * Perform a single test. |
|
624 */ |
|
625 { |
|
626 DCB dcb; |
|
627 |
|
628 _printf(_L("\n------------------------------- -----\n")); |
|
629 _printf(_L("This tests config change notifications.\n")); |
|
630 _printf(_L("---------------------------------------\n\n")); |
|
631 |
|
632 |
|
633 _printf(_L("Press any key to send a new configuration.\n")); |
|
634 _getch(); |
|
635 |
|
636 dcb.DCBlength = sizeof(DCB); |
|
637 memcpy(&OldDcb, &dcb, sizeof(DCB)); |
|
638 dcb.BaudRate=38400; |
|
639 |
|
640 (void) SetCommState(hSerial, &dcb); |
|
641 |
|
642 _printf(_L("\nTest complete\n")); |
|
643 } |
|
644 |
|
645 |
|
646 void SecondClient_TestL() |
|
647 /** |
|
648 * Perform a single test. |
|
649 */ |
|
650 { |
|
651 _printf(_L("\n---------------------------------------\n")); |
|
652 _printf(_L("This tests that we can have a second\n")); |
|
653 _printf(_L("client with non-exclusive access.\n")); |
|
654 _printf(_L("Press any key to quit.\n")); |
|
655 _printf(_L("---------------------------------------\n\n")); |
|
656 |
|
657 _printf(_L("Writing data\n")); |
|
658 FillBuffer(writeBufbig, MAX_BUFFER_SIZE); |
|
659 WriteData(writeBufbig, MAX_BUFFER_SIZE); |
|
660 WriteData(writeBufbig, MAX_BUFFER_SIZE); |
|
661 |
|
662 _printf(_L("Reading data\n")); |
|
663 memset(readBufbig, 0, 256); |
|
664 ReadData(readBufbig, 256); |
|
665 CheckBuffer(readBufbig, 256); |
|
666 |
|
667 _printf(_L("\nTest complete\n")); |
|
668 } |
|
669 |
|
670 |
|
671 // ****************************************************************** |
|
672 // The following are placholders for the ACMRq tests. |
|
673 // These tests need no support on the platform end, as yet. |
|
674 // The functions are left here incase someday some support is needed. |
|
675 // ****************************************************************** |
|
676 |
|
677 void ACMRq_EncapCommand_TestL() |
|
678 { |
|
679 // Not needed to support this here |
|
680 } |
|
681 |
|
682 void ACMRq_Break_TestL() |
|
683 { |
|
684 // TODO: can we check for break status here ? |
|
685 } |
|
686 |
|
687 void ACMRq_SetFeature_TestL() |
|
688 { |
|
689 // TODO: Test doesn't make sense. |
|
690 } |
|
691 |
|
692 void ACMRq_ClearFeature_TestL() |
|
693 { |
|
694 // TODO: Test doesn't make sense. |
|
695 } |
|
696 |
|
697 void ACMRq_SetCoding_TestL() |
|
698 { |
|
699 // TODO: Can we check the line codeing here ? |
|
700 } |
|
701 |
|
702 void ACMRq_CtrlState_TestL() |
|
703 { |
|
704 // TODO: Test doesn't make sense. |
|
705 } |
|
706 |
|
707 void ACMRq_EncapResp_TestL() |
|
708 { |
|
709 // Not needed to support this here. |
|
710 } |
|
711 |
|
712 void ACMRq_CommsFeature_TestL() |
|
713 { |
|
714 // Not needed to support this here. |
|
715 } |
|
716 |
|
717 void ACMRq_GetCoding_TestL() |
|
718 { |
|
719 // Not needed to support this here. |
|
720 } |
|
721 |
|
722 |
|
723 void ACMNtf_SendState_TestL() |
|
724 { |
|
725 // TODO: SendSerialState() ??? |
|
726 } |
|
727 |
|
728 void ACMNtf_Status_TestL() |
|
729 { |
|
730 // TODO: SendNetworkConnection() ??? |
|
731 } |
|
732 |
|
733 void ACMNtf_RespAvail_TestL() |
|
734 { |
|
735 // Test not supported. |
|
736 } |
|
737 |
|
738 void Loopback_TestL() |
|
739 /** |
|
740 * Perform a single test. |
|
741 */ |
|
742 { |
|
743 _printf(_L("\n---------------------------------------------\n")); |
|
744 _printf(_L("This test writes data out of the USB ACM port\n")); |
|
745 _printf(_L("and check that it is correctly echoed back.\n")); |
|
746 _printf(_L("---------------------------------------------\n\n")); |
|
747 |
|
748 // Purge all characters from the output and input buffers |
|
749 // and terminate any pending read or write operations |
|
750 if(PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) == 0) |
|
751 { |
|
752 LEAVE(GetLastError()); |
|
753 } |
|
754 |
|
755 for (char i=0; i<100; i++) |
|
756 { |
|
757 memset(readBufbig, 0, MAX_BUFFER_SIZE); // clear the read buffer |
|
758 memset(writeBufbig, i, MAX_BUFFER_SIZE); // fill the write buffer with known data |
|
759 _printf(_L("%d: "), (TInt)i); |
|
760 WriteData(writeBufbig, 64); |
|
761 //FlushFileBuffers(hSerial); |
|
762 ReadData(readBufbig, 64); |
|
763 for (int j=0; j<64; j++) |
|
764 { |
|
765 if (readBufbig[j] != i) |
|
766 { |
|
767 _printf(_L("Buffer contents error.\n")); |
|
768 for (int k=0; k<64; k++) |
|
769 { |
|
770 _printf(_L("%d "), readBufbig[k]); |
|
771 } |
|
772 _printf(_L("\n")); |
|
773 return; |
|
774 } |
|
775 } |
|
776 } |
|
777 } |
|
778 |
|
779 void mainL() |
|
780 /** |
|
781 * This function controls test execution as directed by the user. |
|
782 */ |
|
783 { |
|
784 TRequestStatus status; |
|
785 |
|
786 memset(&SerialParams, 0, sizeof(struct SerialParameters)); |
|
787 SetWindowsSerialParams(); |
|
788 |
|
789 OpenComPort(); |
|
790 |
|
791 _printf(_L("Opened com port. [press any key]")); _getch(); |
|
792 |
|
793 TBool noExit = ETrue; |
|
794 while (noExit) |
|
795 { |
|
796 _printf(_L("\nAvailable tests:\n\n")); |
|
797 _printf(_L("1. Data stress, size varies (test 2.1.1)\n")); |
|
798 _printf(_L("2. Data stress, rate varies (test 2.1.2)\n")); |
|
799 _printf(_L("3. Timeout (test 2.2)\n")); |
|
800 _printf(_L("4. Cancel Transfer (test 2.3)\n")); |
|
801 _printf(_L("5. Interrupt Transfer (test 2.4)\n")); |
|
802 _printf(_L("6. Shutdown (test 2.5)\n")); |
|
803 _printf(_L("7. Buffer overrun (test 2.6)\n")); |
|
804 _printf(_L("8. Break (test 2.7)\n")); |
|
805 _printf(_L("9. Event notification, signal change (test 2.8.1)\n")); |
|
806 _printf(_L("a. Event notification, flow control (test 2.8.2)\n")); |
|
807 _printf(_L("b. Event notification, config change (test 2.8.3)\n")); |
|
808 _printf(_L("c. Second client (test 2.9)\n")); |
|
809 /* _printf(_L("d. ACM request, encapsulated command (test 2.10.1)\n")); |
|
810 _printf(_L("e. ACM request, break (test 2.10.2)\n")); |
|
811 _printf(_L("f. ACM request, setting feature (test 2.10.3)\n")); |
|
812 _printf(_L("g. ACM request, clearing feature (test 2.10.4)\n")); |
|
813 _printf(_L("h. ACM request, setting line coding (test 2.10.5)\n")); |
|
814 _printf(_L("i. ACM request, control line state (test 2.10.6)\n")); |
|
815 _printf(_L("j. ACM request, encapsualted response (test 2.10.7)\n")); |
|
816 _printf(_L("k. ACM request, comms feature (test 2.10.8)\n")); |
|
817 _printf(_L("l. ACM request, getting line coding (test 2.10.9)\n")); |
|
818 _printf(_L("m. ACM Notifications, send serial state (test 2.11.1)\n")); |
|
819 _printf(_L("n. ACM Notifications, network status (test 2.11.2)\n")); |
|
820 _printf(_L("o. ACM Notifications, response available (test 2.11.3)\n")); |
|
821 */ _printf(_L("p. Loopback test (test 2.12)\n")); |
|
822 _printf(_L("\n")); |
|
823 _printf(_L("\nSelection (x to exit): ")); |
|
824 |
|
825 char ch = (char) _getch(); |
|
826 _printf(_L("\n")); |
|
827 switch (ch) |
|
828 { |
|
829 case '1': DataStress_SizeVary_TestL(); break; |
|
830 case '2': DataStress_RateVary_TestL(); break; |
|
831 case '3': TimeOut_TestL(); break; |
|
832 case '4': CancelTx_TestL(); break; |
|
833 case '5': InterruptTx_TestL(); break; |
|
834 case '6': Shutdown_TestL(); break; |
|
835 case '7': BufferOverrun_TestL(); break; |
|
836 case '8': Break_TestL(); break; |
|
837 case '9': SignalChange_TestL(); break; |
|
838 case 'A': |
|
839 case 'a': FlowControl_TestL(); break; |
|
840 case 'B': |
|
841 case 'b': ConfigChange_TestL(); break; |
|
842 case 'C': |
|
843 case 'c': SecondClient_TestL(); break; |
|
844 case 'D': |
|
845 case 'd': ACMRq_EncapCommand_TestL(); break; |
|
846 case 'E': |
|
847 case 'e': ACMRq_Break_TestL(); break; |
|
848 case 'F': |
|
849 case 'f': ACMRq_SetFeature_TestL(); break; |
|
850 case 'G': |
|
851 case 'g': ACMRq_ClearFeature_TestL(); break; |
|
852 case 'H': |
|
853 case 'h': ACMRq_SetCoding_TestL(); break; |
|
854 case 'I': |
|
855 case 'i': ACMRq_CtrlState_TestL(); break; |
|
856 case 'J': |
|
857 case 'j': ACMRq_EncapResp_TestL(); break; |
|
858 case 'K': |
|
859 case 'k': ACMRq_CommsFeature_TestL(); break; |
|
860 case 'L': |
|
861 case 'l': ACMRq_GetCoding_TestL(); break; |
|
862 case 'M': |
|
863 case 'm': ACMNtf_SendState_TestL(); break; |
|
864 case 'N': |
|
865 case 'n': ACMNtf_Status_TestL(); break; |
|
866 case 'O': |
|
867 case 'o': ACMNtf_RespAvail_TestL(); break; |
|
868 case 'P': |
|
869 case 'p': Loopback_TestL(); break; |
|
870 case 'x': |
|
871 case 'X': |
|
872 noExit = EFalse; |
|
873 break; |
|
874 default: |
|
875 _printf(_L("\nInvalid key\n")); |
|
876 break; |
|
877 } |
|
878 |
|
879 if (noExit) |
|
880 { |
|
881 _printf(_L("Test Complete. Press a key.\n")); |
|
882 _getch(); |
|
883 } |
|
884 } |
|
885 |
|
886 (void) SetCommState(hSerial, &OldDcb); |
|
887 CloseHandle(hSerial); |
|
888 delete[] SerialParams.comport; |
|
889 } |
|
890 |
|
891 void consoleMainL() |
|
892 /** |
|
893 * Create a console and run mainL(). |
|
894 */ |
|
895 { |
|
896 console=Console::NewL(_L("T_ACM"),TSize(KConsFullScreen,KConsFullScreen)); |
|
897 CleanupStack::PushL(console); |
|
898 mainL(); |
|
899 CleanupStack::PopAndDestroy(); |
|
900 } |
|
901 |
|
902 GLDEF_C TInt E32Main() |
|
903 /** |
|
904 * Standard Symbian entry point. Sets stuff up and deals with the cleanup stack. |
|
905 */ |
|
906 { |
|
907 __UHEAP_MARK; |
|
908 CTrapCleanup* cleanupStack=CTrapCleanup::New(); |
|
909 |
|
910 // create the timer for use during some of the tests |
|
911 timer.CreateLocal(); |
|
912 |
|
913 TRAP_IGNORE(consoleMainL()); |
|
914 delete cleanupStack; |
|
915 timer.Close(); |
|
916 __UHEAP_MARKEND; |
|
917 return 0; |
|
918 } |
|
919 |
|
920 |