|
1 /* |
|
2 * Copyright (c) 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 * |
|
16 */ |
|
17 #include <test/testexecutestepbase.h> |
|
18 #include <test/testexecuteserverbase.h> |
|
19 |
|
20 #include <e32def_private.h> |
|
21 |
|
22 #ifdef SYMBIAN_OLD_EXPORT_LOCATION |
|
23 #include <comms-infras/zerocopy_loopback_driver.h> |
|
24 #else |
|
25 //this header is not exported, needs to be a user include |
|
26 #include "zerocopy_loopback_driver.h" |
|
27 #endif |
|
28 |
|
29 #include <comms-infras/commsbuf.h> |
|
30 #include <comms-infras/commsbufpond.h> |
|
31 #include <comms-infras/commsbufpondop.h> |
|
32 |
|
33 _LIT8(KTestSendData,"abcdefghijklmnopqrstuvwxyz"); |
|
34 static const TInt KMBuf_MaxAvail = 393216; |
|
35 static const TInt KMBuf_MBufSize = 128; |
|
36 static const TInt KMBuf_MBufSizeBig = 1600; |
|
37 static const TInt KMBuf_InitialAllocation = 128; |
|
38 static const TInt KMBuf_MinGrowth = 64; |
|
39 static const TInt KMBuf_GrowthThreshold = 40; |
|
40 |
|
41 static const TInt KOneSecond = 1000000; |
|
42 |
|
43 |
|
44 class CZCDriverTestServer : public CTestServer |
|
45 { |
|
46 public: |
|
47 static CZCDriverTestServer* NewL(); |
|
48 ~CZCDriverTestServer(); |
|
49 |
|
50 protected: |
|
51 const TPtrC ServerName() const; |
|
52 CTestStep* CreateTestStep(const TDesC& aStepName); |
|
53 }; |
|
54 |
|
55 |
|
56 _LIT(KZCDriverTestName, "zc_driver_test"); |
|
57 |
|
58 class CZCDriverTestStep : public CTestStep |
|
59 { |
|
60 public: |
|
61 |
|
62 CZCDriverTestStep() |
|
63 { |
|
64 SetTestStepName(KZCDriverTestName); |
|
65 } |
|
66 |
|
67 protected: |
|
68 enum TVerdict doTestStepL(); |
|
69 |
|
70 enum TVerdict doTestStepPreambleL() |
|
71 { |
|
72 SetTestStepResult(EPass); |
|
73 return TestStepResult(); |
|
74 } |
|
75 }; |
|
76 |
|
77 #define TEST_VERDICT(test) if(test) {SetTestStepResult(EFail);} |
|
78 |
|
79 enum TVerdict CZCDriverTestStep::doTestStepL() |
|
80 { |
|
81 CActiveScheduler* activeScheduler = new(ELeave) CActiveScheduler; |
|
82 CleanupStack::PushL(activeScheduler); |
|
83 CActiveScheduler::Install(activeScheduler); |
|
84 |
|
85 SetTestStepResult(EFail); |
|
86 |
|
87 // Start of testing |
|
88 INFO_PRINTF1(_L("Load Physical Device")); |
|
89 TInt r; |
|
90 r=User::LoadPhysicalDevice(KZeroCopyLoopbackPddFileName); |
|
91 TEST_VERDICT(r==KErrNone || r==KErrAlreadyExists); |
|
92 |
|
93 INFO_PRINTF1(_L("Load Logical Device")); |
|
94 r=User::LoadLogicalDevice(KZeroCopyLoopbackLddFileName); |
|
95 TEST_VERDICT(r==KErrNone || r==KErrAlreadyExists); |
|
96 |
|
97 // Initialize a commsbuf pond |
|
98 RCommsBufPondOp commsBufPond; |
|
99 RArray<TCommsBufPoolCreateInfo> createInfos; |
|
100 TCommsBufPoolCreateInfo poolInfoForLargeBufs; |
|
101 poolInfoForLargeBufs.iBufSize = KMBuf_MBufSizeBig; |
|
102 poolInfoForLargeBufs.iInitialBufs = KMBuf_InitialAllocation; |
|
103 poolInfoForLargeBufs.iGrowByBufs = KMBuf_MinGrowth; |
|
104 poolInfoForLargeBufs.iMinFreeBufs = KMBuf_GrowthThreshold; |
|
105 poolInfoForLargeBufs.iCeiling = (KMBuf_MaxAvail/2) / KMBuf_MBufSize; |
|
106 createInfos.AppendL(poolInfoForLargeBufs); |
|
107 TCommsBufPoolCreateInfo poolInfoForSmallBufs; |
|
108 poolInfoForSmallBufs.iBufSize = KMBuf_MBufSize; |
|
109 poolInfoForSmallBufs.iInitialBufs = KMBuf_InitialAllocation; |
|
110 poolInfoForSmallBufs.iGrowByBufs = KMBuf_MinGrowth; |
|
111 poolInfoForSmallBufs.iMinFreeBufs = KMBuf_GrowthThreshold; |
|
112 poolInfoForSmallBufs.iCeiling = (KMBuf_MaxAvail/2) / KMBuf_MBufSize; |
|
113 createInfos.AppendL(poolInfoForSmallBufs); |
|
114 User::LeaveIfError(commsBufPond.Open(createInfos)); |
|
115 createInfos.Close(); |
|
116 |
|
117 __KHEAP_MARK; |
|
118 |
|
119 INFO_PRINTF1(_L("Open Device")); |
|
120 RDevice device; |
|
121 r=device.Open(RZeroCopyLoopbackDriver::Name()); |
|
122 TEST_VERDICT(r==KErrNone); |
|
123 |
|
124 INFO_PRINTF1(_L("Get Device Capabilities")); |
|
125 RZeroCopyLoopbackDriver::TCaps caps; |
|
126 TPckg<RZeroCopyLoopbackDriver::TCaps>capsPckg(caps); |
|
127 capsPckg.FillZ(); // Zero 'caps' so we can tell if GetCaps has really filled it |
|
128 device.GetCaps(capsPckg); |
|
129 TVersion expectedVer(RZeroCopyLoopbackDriver::VersionRequired()); |
|
130 TEST_VERDICT(caps.iVersion.iMajor==expectedVer.iMajor); |
|
131 TEST_VERDICT(caps.iVersion.iMinor==expectedVer.iMinor); |
|
132 TEST_VERDICT(caps.iVersion.iBuild==expectedVer.iBuild); |
|
133 |
|
134 INFO_PRINTF1(_L("Close Device")); |
|
135 device.Close(); |
|
136 |
|
137 INFO_PRINTF1(_L("Open Logical Channel")); |
|
138 RZeroCopyLoopbackDriver ldd; |
|
139 r=ldd.Open(); |
|
140 TEST_VERDICT(r==KErrNone); |
|
141 |
|
142 INFO_PRINTF1(_L("GetConfig")); |
|
143 RZeroCopyLoopbackDriver::TConfigBuf configBuf; |
|
144 configBuf.FillZ(); // Zero 'config' so we can tell if GetConfig has really filled it |
|
145 r=ldd.GetConfig(configBuf); |
|
146 TEST_VERDICT(r==KErrNone); |
|
147 |
|
148 RZeroCopyLoopbackDriver::TConfig& config=configBuf(); |
|
149 TEST_VERDICT(config.iPddBufferSize!=0); |
|
150 TEST_VERDICT(config.iMaxSendDataSize!=0); |
|
151 TEST_VERDICT(config.iMaxReceiveDataSize!=0); |
|
152 |
|
153 INFO_PRINTF1(_L("SetConfig")); |
|
154 TInt speed = configBuf().iSpeed+1; |
|
155 configBuf().iSpeed = speed; |
|
156 r=ldd.SetConfig(configBuf); // Use SetConfig to change speed |
|
157 TEST_VERDICT(r==KErrNone); |
|
158 |
|
159 configBuf.FillZ(); |
|
160 r=ldd.GetConfig(configBuf); |
|
161 TEST_VERDICT(r==KErrNone); |
|
162 TEST_VERDICT(configBuf().iSpeed==speed); |
|
163 TRequestStatus status; |
|
164 |
|
165 INFO_PRINTF1(_L("Check access by wrong client")); |
|
166 RZeroCopyLoopbackDriver ldd2=ldd; |
|
167 r=ldd2.Duplicate(RThread(),EOwnerProcess); |
|
168 TEST_VERDICT(r==KErrAccessDenied); |
|
169 |
|
170 INFO_PRINTF1(_L("Check handle duplication")); |
|
171 ldd2=ldd; |
|
172 r=ldd2.Duplicate(RThread(),EOwnerThread); |
|
173 TEST_VERDICT(r==KErrNone); |
|
174 ldd2.Close(); |
|
175 |
|
176 INFO_PRINTF1(_L("Load pond")); |
|
177 r = ldd.LoadPond(commsBufPond); |
|
178 TEST_VERDICT(r == KErrNone); |
|
179 |
|
180 INFO_PRINTF1(_L("Unload pond")); |
|
181 r = ldd.UnloadPond(); |
|
182 TEST_VERDICT(r == KErrNone); |
|
183 |
|
184 INFO_PRINTF1(_L("Reload pond")); |
|
185 r = ldd.LoadPond(commsBufPond); |
|
186 TEST_VERDICT(r == KErrNone); |
|
187 |
|
188 INFO_PRINTF1(_L("SendData")); |
|
189 TCommsBufAllocator allocator = commsBufPond.Allocator(); |
|
190 RCommsBuf* buf = RCommsBuf::Alloc(KTestSendData().Length(), allocator); |
|
191 TEST_VERDICT(buf != NULL); |
|
192 buf->Reset(); |
|
193 buf->Append(KTestSendData); |
|
194 ldd.SendData(status, *buf); |
|
195 User::WaitForRequest(status); |
|
196 r = status.Int(); |
|
197 TEST_VERDICT(r == KErrNone); |
|
198 buf = NULL; |
|
199 |
|
200 INFO_PRINTF1(_L("SendData")); |
|
201 buf = RCommsBuf::Alloc(KTestSendData().Length(), allocator); |
|
202 TEST_VERDICT(buf != NULL); |
|
203 buf->Reset(); |
|
204 buf->Append(KTestSendData); |
|
205 ldd.SendData(status, *buf); |
|
206 User::WaitForRequest(status); |
|
207 r=status.Int(); |
|
208 TEST_VERDICT(r == KErrNone); |
|
209 buf = NULL; |
|
210 |
|
211 INFO_PRINTF1(_L("ReceiveData")); |
|
212 RCommsBuf* rxbuf; |
|
213 ldd.ReceiveData(status); |
|
214 User::WaitForRequest(status); |
|
215 r=status.Int(); |
|
216 TEST_VERDICT(r > 0); |
|
217 rxbuf = commsBufPond.FromHandle(r); |
|
218 TEST_VERDICT(rxbuf != 0); |
|
219 TEST_VERDICT(rxbuf->Length() == KTestSendData().Size()); |
|
220 TEST_VERDICT(rxbuf->DesC8() == KTestSendData); |
|
221 TBuf8<256> bufdata; |
|
222 rxbuf->Read(bufdata); |
|
223 TEST_VERDICT(bufdata == KTestSendData); |
|
224 rxbuf->Free(); |
|
225 rxbuf = NULL; |
|
226 |
|
227 INFO_PRINTF1(_L("ReceiveData")); |
|
228 ldd.ReceiveData(status); |
|
229 User::WaitForRequest(status); |
|
230 r=status.Int(); |
|
231 TEST_VERDICT(r > 0); |
|
232 rxbuf = commsBufPond.FromHandle(r); |
|
233 TEST_VERDICT(rxbuf != 0); |
|
234 TEST_VERDICT(rxbuf->Length() == KTestSendData().Size()); |
|
235 TEST_VERDICT(rxbuf->DesC8() == KTestSendData); |
|
236 rxbuf->Read(bufdata); |
|
237 TEST_VERDICT(bufdata == KTestSendData); |
|
238 rxbuf->Free(); |
|
239 rxbuf = NULL; |
|
240 |
|
241 INFO_PRINTF1(_L("ReceiveDataCancel")); |
|
242 ldd.ReceiveData(status); |
|
243 User::After(KOneSecond); |
|
244 ldd.ReceiveDataCancel(); |
|
245 User::WaitForRequest(status); |
|
246 r=status.Int(); |
|
247 TEST_VERDICT(r == KErrCancel); |
|
248 |
|
249 #if 0 |
|
250 INFO_PRINTF1(_L("SendDataCancel")); |
|
251 ldd.SendDataCancel(); |
|
252 User::WaitForRequest(status); |
|
253 r=status.Int(); |
|
254 TEST_VERDICT(r == KErrNone); |
|
255 buf = NULL; |
|
256 #endif |
|
257 |
|
258 INFO_PRINTF1(_L("Unload pond")); |
|
259 r = ldd.UnloadPond(); |
|
260 TEST_VERDICT(r == KErrNone); |
|
261 |
|
262 INFO_PRINTF1(_L("Close Logical Channel")); |
|
263 ldd.Close(); |
|
264 |
|
265 __KHEAP_MARKEND; |
|
266 |
|
267 INFO_PRINTF1(_L("Unload Logical Device")); |
|
268 r=User::FreeLogicalDevice(RZeroCopyLoopbackDriver::Name()); |
|
269 TEST_VERDICT(r==KErrNone); |
|
270 |
|
271 INFO_PRINTF1(_L("Unload Physical Device")); |
|
272 TName pddName(RZeroCopyLoopbackDriver::Name()); |
|
273 _LIT(KVariantExtension,".template"); |
|
274 pddName.Append(KVariantExtension); |
|
275 r=User::FreePhysicalDevice(pddName); |
|
276 TEST_VERDICT(r==KErrNone); |
|
277 |
|
278 // Close the pond |
|
279 commsBufPond.Close(); |
|
280 |
|
281 // End of testing |
|
282 CleanupStack::PopAndDestroy(activeScheduler); |
|
283 |
|
284 SetTestStepResult(EPass); |
|
285 return TestStepResult(); |
|
286 } |
|
287 |
|
288 |
|
289 CZCDriverTestServer* CZCDriverTestServer::NewL() |
|
290 /** |
|
291 * @return - Instance of the test server |
|
292 * Same code for Secure and non-secure variants |
|
293 * Called inside the MainL() function to create and start the |
|
294 * CTestServer derived server. |
|
295 */ |
|
296 { |
|
297 CZCDriverTestServer* server = new (ELeave) CZCDriverTestServer(); |
|
298 CleanupStack::PushL(server); |
|
299 server->StartL(server->ServerName()); |
|
300 CleanupStack::Pop(server); |
|
301 return server; |
|
302 } |
|
303 |
|
304 |
|
305 CZCDriverTestServer::~CZCDriverTestServer() |
|
306 { |
|
307 } |
|
308 |
|
309 |
|
310 // Secure variants much simpler |
|
311 // For EKA2, just an E32Main and a MainL() |
|
312 LOCAL_C void MainL() |
|
313 /** |
|
314 * Secure variant |
|
315 * Much simpler, uses the new Rendezvous() call to sync with the client |
|
316 */ |
|
317 { |
|
318 // Leave the hooks in for platform security |
|
319 #if (defined __DATA_CAGING__) |
|
320 RProcess().DataCaging(RProcess::EDataCagingOn); |
|
321 RProcess().DataCaging(RProcess::ESecureApiOn); |
|
322 #endif |
|
323 CActiveScheduler* sched=NULL; |
|
324 sched=new(ELeave) CActiveScheduler; |
|
325 CActiveScheduler::Install(sched); |
|
326 |
|
327 CZCDriverTestServer* server = NULL; |
|
328 |
|
329 // Create the CTestServer derived server |
|
330 TRAPD(err,server = CZCDriverTestServer::NewL()); |
|
331 if(!err) |
|
332 { |
|
333 // Sync with the client and enter the active scheduler |
|
334 RProcess::Rendezvous(KErrNone); |
|
335 sched->Start(); |
|
336 } |
|
337 |
|
338 delete server; |
|
339 delete sched; |
|
340 } |
|
341 |
|
342 |
|
343 GLDEF_C TInt E32Main() |
|
344 /** |
|
345 * @return - Standard Epoc error code on process exit |
|
346 * Secure variant only |
|
347 * Process entry point. Called by client using RProcess API |
|
348 */ |
|
349 { |
|
350 __UHEAP_MARK; |
|
351 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
352 if(cleanup == NULL) |
|
353 { |
|
354 return KErrNoMemory; |
|
355 } |
|
356 TRAPD(err,MainL()); |
|
357 delete cleanup; |
|
358 __UHEAP_MARKEND; |
|
359 return err; |
|
360 } |
|
361 |
|
362 |
|
363 CTestStep* CZCDriverTestServer::CreateTestStep(const TDesC& aStepName) |
|
364 /** |
|
365 * @return - A CTestStep derived instance |
|
366 * Implementation of CTestServer pure virtual |
|
367 */ |
|
368 { |
|
369 CTestStep* testStep = NULL; |
|
370 if(aStepName.Compare(KZCDriverTestName) == 0) |
|
371 testStep =new CZCDriverTestStep(); |
|
372 |
|
373 return testStep; |
|
374 } |
|
375 |
|
376 const TPtrC CZCDriverTestServer::ServerName() const |
|
377 { |
|
378 #if (!defined EKA2) |
|
379 // On EKA1 our test server is loaded as a dll. |
|
380 // So we cannot rely on the process name |
|
381 return KServerName(); |
|
382 #else |
|
383 // On EKA2, test server runs in its own process. |
|
384 // So we arrive at the server name using the exe from which it is loaded. |
|
385 // This is useful when doing cap tests, as we create duplicate exe's using setcap then. |
|
386 TParsePtrC serverName(RProcess().FileName()); |
|
387 return serverName.Name(); |
|
388 #endif |
|
389 } |
|
390 |