|
1 // Copyright (c) 1997-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 the License "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 // e32test\device\t_modem1.cpp |
|
15 // Test program for PC Card Serial Port Driver - Requires Dacom GoldCard Modem. |
|
16 // |
|
17 // |
|
18 |
|
19 #include <e32std.h> |
|
20 #include <e32std_private.h> |
|
21 #include <e32test.h> |
|
22 #include <e32cons.h> |
|
23 #include <e32svr.h> |
|
24 #include <e32hal.h> |
|
25 #include <e32uid.h> |
|
26 #include <d32comm.h> |
|
27 #include <hal.h> |
|
28 |
|
29 class RComm : public RBusDevComm |
|
30 { |
|
31 public: |
|
32 TInt WriteS(const TDesC8& aDes); |
|
33 }; |
|
34 |
|
35 const TInt KBlockSize=256; |
|
36 // Block size Line rate |
|
37 const TInt KBlocksShort=4; // 4*256=1K - <1200 |
|
38 const TInt KBlocksMedium=12; // 12*256=3K - <4800 |
|
39 const TInt KBlocksLong=64; // 64*256=16K - <28800 |
|
40 const TInt KBlocksVeryLong=128; // 128*256=32K - 28800 |
|
41 |
|
42 enum TLineRate {EV21_300,EBell103_300,EV22_1200,EBell212_1200,EV22bis_2400, |
|
43 EV32_4800,EV32_9600,EV32bis_14400,EV34_28800,ELineRateEnd}; |
|
44 const TInt KMaxLineRates=ELineRateEnd; |
|
45 const TInt KStandardRxBufferSize=0x400; |
|
46 |
|
47 #if !defined (__WINS__) |
|
48 #define PDD_NAME _L("EUARTn") |
|
49 #define LDD_NAME _L("ECOMM") |
|
50 #else |
|
51 #define PDD_NAME _L("ECDRV.PDD") |
|
52 #define LDD_NAME _L("ECOMM.LDD") |
|
53 #endif |
|
54 |
|
55 LOCAL_D RTest test(_L("T_MODEM1")); |
|
56 LOCAL_D TInt LineModeData[KMaxLineRates]={0,64,1,69,2,9,9,10,11}; |
|
57 LOCAL_D TInt LineRateData[KMaxLineRates]={300,300,1200,1200,2400,4800,9600,14400,28800}; |
|
58 LOCAL_D TInt LineConnectData[KMaxLineRates]={1200,1200,1200,1200,2400,4800,9600,14400,28800}; |
|
59 LOCAL_D RComm *theSerialPort; |
|
60 |
|
61 |
|
62 TInt RComm::WriteS(const TDesC8& aDes) |
|
63 // |
|
64 // Syncronous write |
|
65 // |
|
66 { |
|
67 |
|
68 TRequestStatus s; |
|
69 Write(s,aDes,aDes.Length()); |
|
70 User::WaitForRequest(s); |
|
71 return(s.Int()); |
|
72 } |
|
73 |
|
74 LOCAL_C TPtrC BaudRateInText(TBps aRate) |
|
75 // |
|
76 // Convert into Baudrate text |
|
77 // |
|
78 { |
|
79 |
|
80 switch (aRate) |
|
81 { |
|
82 case EBps50: return(_L("50")); break; |
|
83 case EBps75: return(_L("75")); break; |
|
84 case EBps110: return(_L("110")); break; |
|
85 case EBps134: return(_L("134")); break; |
|
86 case EBps150: return(_L("150")); break; |
|
87 case EBps300: return(_L("300")); break; |
|
88 case EBps600: return(_L("600")); break; |
|
89 case EBps1200: return(_L("1200")); break; |
|
90 case EBps1800: return(_L("1800")); break; |
|
91 case EBps2000: return(_L("2000")); break; |
|
92 case EBps2400: return(_L("2400")); break; |
|
93 case EBps3600: return(_L("3600")); break; |
|
94 case EBps4800: return(_L("4800")); break; |
|
95 case EBps7200: return(_L("7200")); break; |
|
96 case EBps9600: return(_L("9600")); break; |
|
97 case EBps19200: return(_L("19200")); break; |
|
98 case EBps38400: return(_L("38400")); break; |
|
99 case EBps57600: return(_L("57600")); break; |
|
100 case EBps115200: return(_L("115000")); break; |
|
101 default: return(_L("Unknown")); break; |
|
102 } |
|
103 } |
|
104 |
|
105 LOCAL_C TInt TranslateCrLf(TDes8 &aDes) |
|
106 // |
|
107 // Search for CR/LF characters in a string and replace them with |
|
108 // '\r' '\n' format. Also replaces unprintable characters with "?" |
|
109 // |
|
110 { |
|
111 |
|
112 TText8 buf[KBlockSize]; |
|
113 TText8 *pS=(TText8*)aDes.Ptr(); |
|
114 TText8 *pSE=pS+aDes.Size(); |
|
115 TText8 *pT=&buf[0]; |
|
116 TText8 *pTMax=pT+(KBlockSize-1); |
|
117 for (;pS<pSE;pS++,pT++) |
|
118 { |
|
119 if (pT>=pTMax) |
|
120 return(KErrTooBig); |
|
121 if (*pS=='\xD'||*pS=='\xA') |
|
122 { |
|
123 *pT++='\\'; |
|
124 *pT=(*pS=='\xD')?'r':'n'; |
|
125 } |
|
126 else if (((TChar)*pS).IsPrint()) |
|
127 *pT=*pS; |
|
128 else |
|
129 *pT='\?'; |
|
130 } |
|
131 *pT=0; |
|
132 if ((pT-&buf[0])>aDes.MaxLength()) |
|
133 return(KErrTooBig); |
|
134 aDes.Copy(&buf[0]); |
|
135 return(KErrNone); |
|
136 } |
|
137 /* ??? |
|
138 LOCAL_C void PrintBuf(TDes8 &aBuf) |
|
139 // |
|
140 // Print the contents of a buffer |
|
141 // |
|
142 { |
|
143 |
|
144 TInt len=aBuf.Length(); |
|
145 for (TInt i=0;i<=len/8;i++) |
|
146 { |
|
147 test.Printf(_L("%4d: "),i*8); |
|
148 |
|
149 for (TInt j=0;j<8;j++) |
|
150 { |
|
151 if ((i*8)+j>=len) |
|
152 break; |
|
153 TInt v=aBuf[(i*8)+j]; |
|
154 test.Printf(_L("%02x "),v); |
|
155 } |
|
156 test.Printf(_L("\n\r")); |
|
157 } |
|
158 } |
|
159 */ |
|
160 LOCAL_C void testLoopBack(TLineRate aLineRate,TBps aBaudRate) |
|
161 // |
|
162 // Perform an analogue loopback test at the specified linerate |
|
163 // |
|
164 { |
|
165 |
|
166 TInt err; |
|
167 TBuf<64> b; |
|
168 TPtrC bd=BaudRateInText(aBaudRate); |
|
169 b.Format(_L("Loopback test(%S)"),&bd); |
|
170 test.Start(b); |
|
171 |
|
172 TBuf8<KBlockSize> txBuf; |
|
173 theSerialPort->ResetBuffers(); |
|
174 txBuf.Format(_L8("AT&F+MS=%d,0,%d,%d\\N0&K3&D2M0\r"),LineModeData[aLineRate],LineRateData[aLineRate],LineRateData[aLineRate]); |
|
175 test(theSerialPort->WriteS(txBuf)==KErrNone); |
|
176 |
|
177 TBuf8<KBlockSize> rxBuf; |
|
178 User::After(2000000); // 2Secs |
|
179 err=theSerialPort->QueryReceiveBuffer(); |
|
180 test(err>0); |
|
181 rxBuf.SetLength(err); |
|
182 TRequestStatus rxStat; |
|
183 theSerialPort->ReadOneOrMore(rxStat,rxBuf); |
|
184 User::WaitForRequest(rxStat); |
|
185 // test.Printf(_L(" Rx(%d):"),rxStat); // ??? |
|
186 test(rxStat==KErrNone); |
|
187 txBuf.Append(_L("\r\nOK\r\n")); |
|
188 err=rxBuf.Compare(txBuf); |
|
189 // test(TranslateCrLf(rxBuf)==KErrNone); // ??? |
|
190 // test.Printf(_L(" %S\r\n"),&rxBuf); // ??? |
|
191 test(err==0); |
|
192 |
|
193 test.Next(_L("Get loopback")); |
|
194 txBuf.Format(_L8("AT&T1\r")); |
|
195 test(theSerialPort->WriteS(txBuf)==KErrNone); |
|
196 User::After(5000000); // 5Secs |
|
197 err=theSerialPort->QueryReceiveBuffer(); |
|
198 test(err>0); |
|
199 rxBuf.SetLength(err); |
|
200 theSerialPort->ReadOneOrMore(rxStat,rxBuf); |
|
201 User::WaitForRequest(rxStat); |
|
202 test.Printf(_L(" Rx(%d):"),rxStat); |
|
203 test(rxStat==KErrNone); |
|
204 txBuf.AppendFormat(_L8("\r\nCONNECT %d\r\n"),LineConnectData[aLineRate]); |
|
205 err=rxBuf.Compare(txBuf); |
|
206 test(TranslateCrLf(rxBuf)==KErrNone); |
|
207 test.Printf(_L(" %S\r\n"),&rxBuf); // Print what we got back (without CR/LF etc). |
|
208 // Sometimes get extra character as modem goes on-line so just look for command echo + connect |
|
209 test(err>=0); |
|
210 User::After(2000000); // 2Secs |
|
211 |
|
212 TInt totalBlocksToTransfer; |
|
213 if (aBaudRate<EBps1200||aLineRate<EV22_1200) |
|
214 totalBlocksToTransfer=KBlocksShort; |
|
215 else if (aBaudRate<EBps4800||aLineRate<EV32_4800) |
|
216 totalBlocksToTransfer=KBlocksMedium; |
|
217 else if (aLineRate<EV34_28800) |
|
218 totalBlocksToTransfer=KBlocksLong; |
|
219 else |
|
220 totalBlocksToTransfer=KBlocksVeryLong; |
|
221 b.Format(_L("Transfering data(%dK)"),(totalBlocksToTransfer*KBlockSize)/1024); |
|
222 test.Next(b); |
|
223 TInt loopBackFail=KErrGeneral; |
|
224 TRequestStatus txStat; |
|
225 txBuf.SetLength(KBlockSize); |
|
226 TInt i; |
|
227 for (i=0;i<KBlockSize;i++) |
|
228 txBuf[i]=(TUint8)i; |
|
229 theSerialPort->Write(txStat,txBuf,KBlockSize); |
|
230 TInt txBlks=(totalBlocksToTransfer-1); |
|
231 rxBuf.Fill(0,KBlockSize); |
|
232 theSerialPort->Read(rxStat,rxBuf,KBlockSize); |
|
233 TInt rxBlks=0; |
|
234 TRequestStatus tStat; |
|
235 RTimer tim; |
|
236 test(tim.CreateLocal()==KErrNone); |
|
237 tim.After(tStat,40000000); // 40Secs |
|
238 test.Printf(_L(">")); |
|
239 FOREVER |
|
240 { |
|
241 User::WaitForAnyRequest(); |
|
242 if (tStat!=KRequestPending) |
|
243 { |
|
244 // test.Printf(_L("t")); // Timed out |
|
245 theSerialPort->ReadCancel(); // Cancel serial read |
|
246 User::WaitForRequest(rxStat); |
|
247 if (txBlks>0) |
|
248 { |
|
249 theSerialPort->WriteCancel(); // Cancel serial write |
|
250 User::WaitForRequest(txStat); |
|
251 } |
|
252 loopBackFail=KErrTimedOut; // Test failed |
|
253 break; |
|
254 } |
|
255 else if (rxStat!=KRequestPending) |
|
256 { |
|
257 // test.Printf(_L("r")); // Serial rx request complete |
|
258 if (rxStat!=0) |
|
259 { |
|
260 loopBackFail=rxStat.Int(); // Test failed |
|
261 goto endSerial; |
|
262 } |
|
263 for (i=0;i<KBlockSize;i++) |
|
264 { |
|
265 if (rxBuf[i]!=i) |
|
266 { |
|
267 loopBackFail=KErrCorrupt; // Test failed |
|
268 rxBuf[KBlockSize-1]=0; |
|
269 // PrintBuf(rxBuf); // ??? |
|
270 // goto endSerial; // !!!Ignore compare fails for now!!! |
|
271 } |
|
272 } |
|
273 test.Printf(_L("<")); |
|
274 if (++rxBlks<totalBlocksToTransfer) |
|
275 { |
|
276 rxBuf.Fill(0,KBlockSize); |
|
277 theSerialPort->Read(rxStat,rxBuf,KBlockSize); |
|
278 } |
|
279 else |
|
280 { |
|
281 loopBackFail=KErrNone; |
|
282 endSerial: |
|
283 tim.Cancel(); // Cancel timer request. |
|
284 User::WaitForRequest(tStat); |
|
285 if (txBlks>0) |
|
286 { |
|
287 theSerialPort->WriteCancel(); // Cancel serial write |
|
288 User::WaitForRequest(txStat); |
|
289 } |
|
290 break; |
|
291 } |
|
292 } |
|
293 else if (txStat!=KRequestPending) |
|
294 { |
|
295 // test.Printf(_L("s")); // Serial tx request complete |
|
296 if (txBlks>0) |
|
297 { |
|
298 theSerialPort->Write(txStat,txBuf,KBlockSize); |
|
299 test.Printf(_L(">")); |
|
300 txBlks--; |
|
301 } |
|
302 } |
|
303 else |
|
304 { |
|
305 // test.Printf(_L("?")); // Stray signal - cancel everything |
|
306 theSerialPort->ReadCancel(); // Cancel serial read |
|
307 User::WaitForRequest(rxStat); |
|
308 tim.Cancel(); // Cancel timer request. |
|
309 User::WaitForRequest(tStat); |
|
310 if (txBlks>0) |
|
311 { |
|
312 theSerialPort->WriteCancel(); // Cancel serial write |
|
313 User::WaitForRequest(txStat); |
|
314 } |
|
315 loopBackFail=KErrDied; |
|
316 break; |
|
317 } |
|
318 } |
|
319 test.Printf(_L(" (%d)\r\n"),loopBackFail); |
|
320 // !!! At this point RTS may or may not be asserted following the write cancel. The |
|
321 // following seems necessary to make sure RTS is asserted so any remaining Rx data |
|
322 // can be received.and thrown away |
|
323 User::After(2000000); |
|
324 theSerialPort->ResetBuffers(); |
|
325 User::After(1000000); // Wait 1Secs for any remaining Rx data |
|
326 tim.Close(); |
|
327 |
|
328 test.Next(_L("Disconnect")); |
|
329 theSerialPort->ResetBuffers(); // Through away any remaining Rx data. |
|
330 txBuf.Format(_L8("+++")); |
|
331 test(theSerialPort->WriteS(txBuf)==KErrNone); |
|
332 User::After(2000000); // 2Secs |
|
333 err=theSerialPort->QueryReceiveBuffer(); |
|
334 test(err>0); |
|
335 rxBuf.SetLength(err); |
|
336 theSerialPort->ReadOneOrMore(rxStat,rxBuf); |
|
337 User::WaitForRequest(rxStat); |
|
338 test(rxStat==KErrNone); |
|
339 txBuf.Append(_L("\r\nOK\r\n")); |
|
340 err=rxBuf.Compare(txBuf); |
|
341 // test(TranslateCrLf(rxBuf)==KErrNone); // ??? |
|
342 // test.Printf(_L(" %S\r\n"),&rxBuf); // ??? |
|
343 test(err==0); |
|
344 |
|
345 txBuf.Format(_L8("ATH0\r")); |
|
346 test(theSerialPort->WriteS(txBuf)==KErrNone); |
|
347 User::After(4000000); // 4Secs |
|
348 err=theSerialPort->QueryReceiveBuffer(); |
|
349 test(err>0); |
|
350 rxBuf.SetLength(err); |
|
351 theSerialPort->ReadOneOrMore(rxStat,rxBuf); |
|
352 User::WaitForRequest(rxStat); |
|
353 test(rxStat==KErrNone); |
|
354 txBuf.Append(_L("\r\nOK\r\n")); |
|
355 err=rxBuf.Compare(txBuf); |
|
356 // test(TranslateCrLf(rxBuf)==KErrNone); // ??? |
|
357 // test.Printf(_L(" %S\r\n"),&rxBuf); // ??? |
|
358 test(err==0); |
|
359 |
|
360 test.Next(_L("Check result")); |
|
361 test(loopBackFail==KErrNone || loopBackFail==KErrCorrupt); // !!!Ignore compare fails for now!!! |
|
362 // test(loopBackFail==KErrNone); |
|
363 |
|
364 test.End(); |
|
365 } |
|
366 |
|
367 LOCAL_C void testAllLineRates(TBps aRate) |
|
368 // |
|
369 // Perform loopback test at the specified baudrate in as many line modes that |
|
370 // are supported at this baudrate |
|
371 // |
|
372 { |
|
373 |
|
374 test.Start(_L("Setting baudrate")); |
|
375 TCommConfig cBuf; |
|
376 TCommConfigV01 &c=cBuf(); |
|
377 theSerialPort->Config(cBuf); |
|
378 c.iRate=aRate; |
|
379 c.iDataBits=EData8; |
|
380 c.iStopBits=EStop1; |
|
381 c.iParity=EParityNone; |
|
382 c.iHandshake=KConfigObeyCTS; |
|
383 // c.iHandshake=0; |
|
384 test(theSerialPort->SetConfig(cBuf)==KErrNone); |
|
385 |
|
386 if (aRate>=EBps38400) |
|
387 { |
|
388 test.Next(_L("Testing at V.34-28800")); |
|
389 testLoopBack(EV34_28800,aRate); |
|
390 } |
|
391 |
|
392 if (aRate>=EBps19200) |
|
393 { |
|
394 test.Next(_L("Testing at V.32bis-14400")); |
|
395 testLoopBack(EV32bis_14400,aRate); |
|
396 } |
|
397 |
|
398 if (aRate>=EBps9600) |
|
399 { |
|
400 test.Next(_L("Testing at V.32-9600")); |
|
401 testLoopBack(EV32_9600,aRate); |
|
402 } |
|
403 |
|
404 // if (aRate>=EBps4800) |
|
405 // { |
|
406 // test.Next(_L("Testing at V.32-4800")); |
|
407 // testLoopBack(EV32_4800,aRate); |
|
408 // } |
|
409 |
|
410 if (aRate>=EBps2400) |
|
411 { |
|
412 test.Next(_L("Testing at V.22bis-2400")); |
|
413 testLoopBack(EV22bis_2400,aRate); |
|
414 } |
|
415 |
|
416 // if (aRate>=EBps1200) |
|
417 // { |
|
418 // test.Next(_L("Testing at Bell212-1200")); |
|
419 // testLoopBack(EBell212_1200,aRate); |
|
420 // } |
|
421 |
|
422 // if (aRate>=EBps1200) |
|
423 // { |
|
424 // test.Next(_L("Testing at V.22-1200")); |
|
425 // testLoopBack(EV22_1200,aRate); |
|
426 // } |
|
427 |
|
428 // test.Next(_L("Testing at Bell103-300")); |
|
429 // testLoopBack(EBell103_300,aRate); |
|
430 |
|
431 test.Next(_L("Testing at V.21-300")); |
|
432 testLoopBack(EV21_300,aRate); |
|
433 |
|
434 test.End(); |
|
435 } |
|
436 |
|
437 GLDEF_C TInt E32Main() |
|
438 { |
|
439 // test.SetLogged(EFalse); // Turn off serial port debugging! |
|
440 |
|
441 TInt r; |
|
442 test.Title(); |
|
443 |
|
444 test.Start(_L("PC Card Modem Test Program")); |
|
445 |
|
446 RProcess proc; |
|
447 TBuf <0x100> cmd; |
|
448 proc.CommandLine(cmd); |
|
449 |
|
450 // First parameter (if present) sets the serial port number |
|
451 TInt port=0; |
|
452 if ((cmd.Length()>0) && (cmd[0]>='1' && cmd[0]<='4')) |
|
453 port=(TInt)(cmd[0]-'0'); |
|
454 |
|
455 // 2nd parameter (if present) sets the start speed |
|
456 // (4=115K,3=57600,2=38400,1=19200,0=9600) |
|
457 TInt startSpeed=4; |
|
458 if ((cmd.Length()>3) && (cmd[2]>='0' && cmd[2]<='4')) |
|
459 startSpeed=(TInt)(cmd[2]-'0'); |
|
460 |
|
461 test.Next(_L("Load Device Drivers")); |
|
462 TBuf<10> pddName=PDD_NAME; |
|
463 #if !defined (__WINS__) |
|
464 pddName[5]=(TText)('1'+port); |
|
465 TInt muid=0; |
|
466 if (HAL::Get(HAL::EMachineUid, muid)==KErrNone) |
|
467 { |
|
468 // Brutus uses EUART4 for both COM3 and COM4 |
|
469 if (muid==HAL::EMachineUid_Brutus && port==4) |
|
470 pddName[5]=(TText)'4'; |
|
471 } |
|
472 #endif |
|
473 r=User::LoadPhysicalDevice(pddName); |
|
474 test(r==KErrNone||r==KErrAlreadyExists); |
|
475 r=User::LoadLogicalDevice(LDD_NAME); |
|
476 test(r==KErrNone||r==KErrAlreadyExists); |
|
477 |
|
478 test.Next(_L("Open serial port")); |
|
479 theSerialPort=new RComm; |
|
480 test(theSerialPort!=NULL); |
|
481 r=theSerialPort->Open(port); |
|
482 test(r==KErrNone); |
|
483 // TCommCaps capsBuf; |
|
484 // TCommCapsV01& caps=capsBuf(); |
|
485 // theSerialPort->Caps(capsBuf); |
|
486 |
|
487 // Check that the driver powering sequence has completed successfully by |
|
488 // issueing a few simple driver control functions. |
|
489 test.Next(_L("Modem power tests")); |
|
490 test(theSerialPort->SetReceiveBufferLength(KStandardRxBufferSize)==KErrNone); |
|
491 r=theSerialPort->ReceiveBufferLength(); |
|
492 // test.Printf(_L("(%d)"),r); // ??? |
|
493 test(r==KStandardRxBufferSize); |
|
494 r=(TInt)theSerialPort->Signals(); |
|
495 // test.Printf(_L("(%d)"),r); // ??? |
|
496 test(r>=0); |
|
497 |
|
498 RTimer timer; |
|
499 TRequestStatus rs; |
|
500 test(timer.CreateLocal()==KErrNone); |
|
501 TTime tim; |
|
502 tim.HomeTime(); |
|
503 tim+=TTimeIntervalSeconds(8); |
|
504 timer.At(rs,tim); |
|
505 UserHal::SwitchOff(); |
|
506 User::WaitForRequest(rs); |
|
507 test(rs.Int()==KErrNone); |
|
508 |
|
509 r=theSerialPort->ReceiveBufferLength(); |
|
510 // test.Printf(_L("(%d)"),r); // ??? |
|
511 test(r==KStandardRxBufferSize); |
|
512 r=(TInt)theSerialPort->Signals(); |
|
513 // test.Printf(_L("(%d)"),r); // ??? |
|
514 test(r>=0); |
|
515 User::After(2000000); // 2Secs !!! |
|
516 |
|
517 if (startSpeed>=4) |
|
518 { |
|
519 test.Next(_L("Testing at 115K")); |
|
520 testAllLineRates(EBps115200); |
|
521 } |
|
522 |
|
523 if (startSpeed>=3) |
|
524 { |
|
525 test.Next(_L("Testing at 57600")); |
|
526 testAllLineRates(EBps57600); |
|
527 } |
|
528 |
|
529 if (startSpeed>=2) |
|
530 { |
|
531 test.Next(_L("Testing at 38400")); |
|
532 testAllLineRates(EBps38400); |
|
533 } |
|
534 |
|
535 if (startSpeed>=1) |
|
536 { |
|
537 test.Next(_L("Testing at 19200")); |
|
538 testAllLineRates(EBps19200); |
|
539 } |
|
540 |
|
541 test.Next(_L("Testing at 9600")); |
|
542 testAllLineRates(EBps9600); |
|
543 |
|
544 test.Next(_L("Close serial port")); |
|
545 theSerialPort->Close(); |
|
546 delete theSerialPort; |
|
547 test.End(); |
|
548 return(KErrNone); |
|
549 } |
|
550 |