|
1 // Copyright (c) 2007-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 // Implements the basic test step for the Streaming CAF test harness |
|
15 // |
|
16 // |
|
17 |
|
18 #include "tscafstep.h" |
|
19 #ifdef INTERNALLY_ENABLE_UPWARD_DEPENDENCY |
|
20 #include <sdpconnectionfield.h> |
|
21 #include <sdporiginfield.h> |
|
22 #endif |
|
23 |
|
24 TSdpAttribute::TSdpAttribute() |
|
25 { |
|
26 } |
|
27 |
|
28 CTestDecoderConfiguration* CTestDecoderConfiguration::NewLC() |
|
29 { |
|
30 CTestDecoderConfiguration* self = new (ELeave) CTestDecoderConfiguration(); |
|
31 CleanupStack::PushL(self); |
|
32 return self; |
|
33 } |
|
34 |
|
35 CTestDecoderConfiguration::~CTestDecoderConfiguration() |
|
36 { |
|
37 iAttributeArray.Close(); |
|
38 } |
|
39 |
|
40 CTestDecoderConfiguration::CTestDecoderConfiguration() |
|
41 { |
|
42 } |
|
43 |
|
44 TExpectedKeyStreamDecoderAttributes::TExpectedKeyStreamDecoderAttributes() |
|
45 { |
|
46 } |
|
47 |
|
48 CScafStep::CScafStep(CScafServer& aParent) |
|
49 /** |
|
50 Constructor. |
|
51 */ |
|
52 : iParent(aParent), iThreadId(0), iOOMTest(EFalse) |
|
53 { |
|
54 //empty |
|
55 } |
|
56 |
|
57 CScafStep::~CScafStep() |
|
58 /** |
|
59 Destructor. |
|
60 */ |
|
61 { |
|
62 //empty |
|
63 } |
|
64 |
|
65 |
|
66 TVerdict CScafStep::doTestStepPreambleL() |
|
67 /** |
|
68 From CTestStep. Creates an active scheduler for the test step. |
|
69 */ |
|
70 { |
|
71 __UHEAP_MARK; |
|
72 INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells()); |
|
73 |
|
74 iActiveScheduler = new (ELeave) CActiveScheduler; |
|
75 CActiveScheduler::Install(iActiveScheduler); |
|
76 |
|
77 ReadTestConfigurationL(); |
|
78 |
|
79 SetTestStepResult(EPass); |
|
80 return TestStepResult(); |
|
81 } |
|
82 |
|
83 TVerdict CScafStep::doTestStepL() |
|
84 /** |
|
85 * From CTestStep. Default behaviour of doTestStepL() allows for the test case to be run both |
|
86 * under 'Normal' and 'Out of Memory' Conditions. |
|
87 * |
|
88 * Implementation of the test case itself is called from the doTestL() of the derived test step. |
|
89 * |
|
90 * The state of the iOOMTest member variable determines the type of test conditons: |
|
91 * EFalse - Normal Test |
|
92 * ETrue - Out of Memory Test |
|
93 */ |
|
94 { |
|
95 if (!iOOMTest) |
|
96 { |
|
97 doTestL(); |
|
98 } |
|
99 else |
|
100 { |
|
101 doOOMTestL(); |
|
102 } |
|
103 |
|
104 return TestStepResult(); |
|
105 } |
|
106 |
|
107 TVerdict CScafStep::doTestStepPostambleL() |
|
108 /** |
|
109 From CTestStep. Destroys the active scheduler of the test step. |
|
110 */ |
|
111 { |
|
112 CActiveScheduler::Install(NULL); |
|
113 delete iActiveScheduler; |
|
114 |
|
115 iDecoderConfigurationArray.ResetAndDestroy(); |
|
116 iExpectedKeyStreamDecoderData.Close(); |
|
117 |
|
118 INFO_PRINTF2(_L("HEAP CELLS: %d"),User::CountAllocCells()); |
|
119 __UHEAP_MARKEND; |
|
120 |
|
121 return TestStepResult(); |
|
122 } |
|
123 |
|
124 #ifdef INTERNALLY_ENABLE_UPWARD_DEPENDENCY |
|
125 // We need this dummy function because TCleanupItem c'tor (see below) does not accept functions without parameters |
|
126 void CloseSdpCodecPool(TAny *) |
|
127 { |
|
128 SdpCodecStringPool::Close(); |
|
129 } |
|
130 |
|
131 CSdpDocument* CScafStep::CreateSdpDocumentLC() |
|
132 /** |
|
133 Creates an SDP document object which is a collection of all media fields and session attributes. |
|
134 @return A pointer to the SDP document object. |
|
135 The ownership is transferred. Please note that |
|
136 the returned object must be deleted by DeleteSdpAndCloseCodecPool method. |
|
137 */ |
|
138 { |
|
139 // Open the string pool to access all predefined SDP constants |
|
140 SdpCodecStringPool::OpenL(); |
|
141 CleanupStack::PushL(TCleanupItem(CloseSdpCodecPool,this)); //Pass the class pointer to make armv5 compiler (for urel) happy |
|
142 |
|
143 // Create the CSdpDocument object |
|
144 CSdpDocument* sdpDocument = CSdpDocument::NewLC(); |
|
145 |
|
146 // Define the session name |
|
147 sdpDocument->SetSessionNameL(_L8("ScafTest")); |
|
148 |
|
149 // Set the origin field. The values are not important. |
|
150 // Because they are not used in our tests. |
|
151 TInt64 sessionId(TUint(2055478987)); |
|
152 TInt64 sessionVersion(TUint(2027813655)); |
|
153 TInetAddr address; |
|
154 const TUint32 KInetAddr = INET_ADDR(192,168,0,3); |
|
155 address.SetAddress( KInetAddr ); |
|
156 CSdpOriginField* originField = CSdpOriginField::NewLC(_L8("scafuser"), sessionId, sessionVersion, address); |
|
157 sdpDocument->SetOriginField(originField); |
|
158 CleanupStack::Pop(originField); |
|
159 |
|
160 CleanupStack::Pop(); // Pop the temporary guard on SDP Codec string pool close |
|
161 CleanupStack::Pop(); // Pop sdpDocument object |
|
162 CleanupStack::PushL(TCleanupItem(CScafStep::DeleteSdpDocAndCloseCodecPool, reinterpret_cast<TAny *>(sdpDocument))); |
|
163 |
|
164 return sdpDocument; |
|
165 } |
|
166 |
|
167 void CScafStep::AddMediaFieldL(CSdpDocument& aSdpDoc, const CSdpMediaField* aSdpKeyStream) |
|
168 /** |
|
169 Adds an SDP media field object to a given SDP document object. |
|
170 @param aSdpDoc The SDP document object |
|
171 @param aSdpKeyStream Sdp media field which will be appended to the SDP document object. |
|
172 This object should be popped from the cleanupstack after this function runs successfully. |
|
173 */ |
|
174 { |
|
175 // Set the key stream field given |
|
176 User::LeaveIfError(aSdpDoc.MediaFields().Append(aSdpKeyStream)); |
|
177 } |
|
178 |
|
179 CSdpMediaField* CScafStep::CreateSdpLC(TInt aSdpNum) |
|
180 /** |
|
181 Creates a simple SDP media field object. |
|
182 @param aSdpNum An integer representing the accessor to the SDP parameter |
|
183 array and the required data |
|
184 @return A pointer to the SDP media field object. |
|
185 The ownership is transferred. Please note that |
|
186 the returned object must be deleted by DeleteSdpAndCloseCodecPool method. |
|
187 @see CScafStep::DeleteSdp |
|
188 */ |
|
189 { |
|
190 TPtrC pMedia; |
|
191 pMedia.Set(iDecoderConfigurationArray[aSdpNum]->iMedia); |
|
192 |
|
193 TInt mIndex = 0; |
|
194 if(!pMedia.CompareF(KSdpMediaAudio)) |
|
195 { |
|
196 mIndex = SdpCodecStringConstants::EMediaAudio; |
|
197 } |
|
198 else if(!pMedia.CompareF(KSdpMediaVideo)) |
|
199 { |
|
200 mIndex = SdpCodecStringConstants::EMediaVideo; |
|
201 } |
|
202 else if(!pMedia.CompareF(KSdpMediaData)) |
|
203 { |
|
204 mIndex = SdpCodecStringConstants::EMediaData; |
|
205 } |
|
206 else |
|
207 { |
|
208 ERR_PRINTF2(_L("Unsupported media type: '%S'"),&pMedia); |
|
209 SetTestStepResult(EFail); |
|
210 User::Leave(KErrNotFound); |
|
211 } |
|
212 |
|
213 TPtrC pProtocol; |
|
214 pProtocol.Set(iDecoderConfigurationArray[aSdpNum]->iProtocol); |
|
215 |
|
216 TInt mProtocol = 0; |
|
217 if(!pProtocol.CompareF(KSdpProtocolUdp)) |
|
218 { |
|
219 mProtocol = SdpCodecStringConstants::EProtocolUdp; |
|
220 } |
|
221 else if(!pProtocol.CompareF(KSdpProtocolTcp)) |
|
222 { |
|
223 mProtocol = SdpCodecStringConstants::EProtocolTcp; |
|
224 } |
|
225 else if(!pProtocol.CompareF(KSdpProtocolRtp)) |
|
226 { |
|
227 mProtocol = SdpCodecStringConstants::EProtocolRtpAvp; |
|
228 } |
|
229 else |
|
230 { |
|
231 ERR_PRINTF2(_L("Unsupported protocol type: '%S'"),mProtocol); |
|
232 SetTestStepResult(EFail); |
|
233 User::Leave(KErrNotFound); |
|
234 } |
|
235 |
|
236 TInt port = iDecoderConfigurationArray[aSdpNum]->iPort; |
|
237 |
|
238 TPtrC pFormat; |
|
239 pFormat.Set(iDecoderConfigurationArray[aSdpNum]->iFormat); |
|
240 |
|
241 //Convert 16-bit to 8-bit |
|
242 TPtr8 ptrFormat(Convert16To8LC(pFormat)); |
|
243 |
|
244 RStringPool pool = SdpCodecStringPool::StringPoolL(); |
|
245 RStringF mediaData = pool.StringF(mIndex, SdpCodecStringPool::StringTableL()); |
|
246 CleanupClosePushL(mediaData); |
|
247 RStringF protocol = pool.StringF(mProtocol, SdpCodecStringPool::StringTableL()); |
|
248 CleanupClosePushL(protocol); |
|
249 |
|
250 CSdpMediaField* sdp = CSdpMediaField::NewL(mediaData, port, protocol, ptrFormat); |
|
251 CleanupStack::PopAndDestroy(3); |
|
252 CleanupStack::PushL(sdp); |
|
253 |
|
254 //If a connection address is defined, create an SDP connection field and add it to the SDP media field |
|
255 if(iDecoderConfigurationArray[aSdpNum]->iConnAddr.Length()>0) |
|
256 { |
|
257 //The only supported network type is ENetType |
|
258 RStringF netType = pool.StringF(SdpCodecStringConstants::ENetType, SdpCodecStringPool::StringTableL()); |
|
259 CleanupClosePushL(netType); |
|
260 //The only supported address type is IP v4 |
|
261 RStringF addressType = pool.StringF(SdpCodecStringConstants::EAddressTypeIP4, SdpCodecStringPool::StringTableL()); |
|
262 CleanupClosePushL(addressType); |
|
263 //Create the connection field |
|
264 CSdpConnectionField* connField = CSdpConnectionField::NewL(netType, addressType, Convert16To8LC(iDecoderConfigurationArray[aSdpNum]->iConnAddr)); |
|
265 CleanupStack::PushL(connField); |
|
266 //Set the connection field into the SDP media field |
|
267 sdp->ConnectionFields().AppendL(connField); |
|
268 CleanupStack::Pop(connField); |
|
269 CleanupStack::PopAndDestroy(3, &netType); //netType, addressType, Convert16To8LC |
|
270 } |
|
271 |
|
272 //Add atrributes |
|
273 AddAttributes2SdpL(*sdp, aSdpNum); |
|
274 |
|
275 return sdp; |
|
276 } |
|
277 #endif |
|
278 |
|
279 CKeyStreamSink* CScafStep::CreateKeyStreamSinkLC(const TDesC& aFileName, const TDesC& aPrivPath) |
|
280 /** |
|
281 Creates a test key stream sink object. |
|
282 @param aFilePath The output file name of the test key stream sink. |
|
283 @param aPrivPath Stream Agents Private Folder Path |
|
284 @return A pointer to the test key stream sink object. |
|
285 The ownership is transferred. |
|
286 */ |
|
287 { |
|
288 HBufC* privFolder = GetFullPathLC(aPrivPath, aFileName); |
|
289 CTestKeyStreamSink* sink = CTestKeyStreamSink::NewL(*privFolder); |
|
290 CleanupStack::PopAndDestroy(privFolder); |
|
291 CleanupStack::PushL(sink); |
|
292 return sink; |
|
293 } |
|
294 |
|
295 void CScafStep::CleanAgentsPrivateFolderL(const TDesC& aPrivatePath) |
|
296 /** |
|
297 Delete all files and folders under the private directory of the test agent. |
|
298 */ |
|
299 { |
|
300 HBufC* agentPrivFol = GetFullPathLC(aPrivatePath, _L("*.*")); |
|
301 CFileMan *fm = CFileMan::NewL(iParent.Fs()); |
|
302 CleanupStack::PushL(fm); |
|
303 |
|
304 TInt ret = fm->Delete(*agentPrivFol,0); |
|
305 if((ret != KErrNone)&&(ret != KErrNotFound)&&(ret != KErrPathNotFound)) |
|
306 { |
|
307 User::Leave(ret); |
|
308 } |
|
309 CleanupStack::PopAndDestroy(2, agentPrivFol); |
|
310 } |
|
311 |
|
312 |
|
313 void CScafStep::DeleteSdpDocAndCloseCodecPool(TAny* aSdpDoc) |
|
314 /** |
|
315 Delete the SDP document object and close the codec pool |
|
316 @param aSdp The SDP object which will be deleted. |
|
317 */ |
|
318 { |
|
319 #ifdef INTERNALLY_ENABLE_UPWARD_DEPENDENCY |
|
320 delete reinterpret_cast<CSdpDocument *>(aSdpDoc); |
|
321 SdpCodecStringPool::Close(); |
|
322 #else |
|
323 (void) aSdpDoc; |
|
324 #endif |
|
325 } |
|
326 |
|
327 void CScafStep::CopyFile2AgentsPrivateFolderL(RFs& aFs, const TDesC& aFileName, const TDesC& aPrivPath) |
|
328 /** |
|
329 Copy a test file from Z drive to the private folder of the test agent server. |
|
330 @param aFs File Server session. |
|
331 @param aPrivPath Stream Agents Private Folder Path |
|
332 @param aFileName The name of the file which lives in the folder of Z drive. |
|
333 */ |
|
334 { |
|
335 //Gets the target file path |
|
336 HBufC* fTarget = GetFullPathLC(aPrivPath, aFileName); |
|
337 //Make sure that the path exists |
|
338 TInt err = aFs.MkDirAll(*fTarget); |
|
339 if(err != KErrNone && err != KErrAlreadyExists) |
|
340 { |
|
341 User::Leave(err); |
|
342 } |
|
343 |
|
344 //Get the file source path |
|
345 TFileName fSource(KDataFilesPath); |
|
346 fSource.Append(aFileName); |
|
347 |
|
348 //Create a file manager |
|
349 CFileMan *fm = CFileMan::NewL(aFs); |
|
350 CleanupStack::PushL(fm); |
|
351 |
|
352 //Copy the source file to the target |
|
353 User::LeaveIfError(fm->Copy(fSource, *fTarget)); |
|
354 // Make the file writeable |
|
355 User::LeaveIfError(fm->Attribs(*fTarget, 0, KEntryAttReadOnly, TTime(0), 0)); |
|
356 CleanupStack::PopAndDestroy(2, fTarget); |
|
357 } |
|
358 |
|
359 #ifdef INTERNALLY_ENABLE_UPWARD_DEPENDENCY |
|
360 void CScafStep::AddAttributes2SdpL(CSdpMediaField& aSdp, TInt aSdpNum) |
|
361 /** |
|
362 * Add attributes from the instance within the CSdpConfiguration array, where |
|
363 * the attribute information is stored, into the SDP object being constructed. |
|
364 * @param aSdp The SDP object where the attribute is added. |
|
365 */ |
|
366 { |
|
367 TInt attrCount = iDecoderConfigurationArray[aSdpNum]->iAttributeArray.Count(); |
|
368 |
|
369 RStringPool pool = SdpCodecStringPool::StringPoolL(); |
|
370 |
|
371 for(TInt i=0; i < attrCount; ++i) |
|
372 { |
|
373 TPtrC pAttrType; |
|
374 pAttrType.Set(iDecoderConfigurationArray[aSdpNum]->iAttributeArray[i].iAttributeType); |
|
375 |
|
376 TPtrC pAttrName; |
|
377 pAttrName.Set(iDecoderConfigurationArray[aSdpNum]->iAttributeArray[i].iAttributeName); |
|
378 |
|
379 //Convert 16-bit to 8-bit |
|
380 TPtr8 ptrAttrName(Convert16To8LC(pAttrName)); |
|
381 |
|
382 TPtrC pAttrValue; |
|
383 pAttrValue.Set(iDecoderConfigurationArray[aSdpNum]->iAttributeArray[i].iAttributeValue); |
|
384 |
|
385 //Convert 16-bit to 8-bit |
|
386 TPtr8 ptrAttrValue(Convert16To8LC(pAttrValue)); |
|
387 |
|
388 if(pAttrType.Compare(_L("Format"))) |
|
389 { |
|
390 RStringF attrName = pool.OpenFStringL(ptrAttrName); |
|
391 CleanupClosePushL(attrName); |
|
392 CSdpAttributeField *attribute = CSdpAttributeField::NewLC(attrName, ptrAttrValue); |
|
393 User::LeaveIfError((aSdp.AttributeFields()).Append(attribute)); |
|
394 CleanupStack::Pop(attribute); |
|
395 } |
|
396 else |
|
397 { |
|
398 RStringF fmtpStr = pool.StringF(SdpCodecStringConstants::EAttributeFmtp, SdpCodecStringPool::StringTableL()); |
|
399 CleanupClosePushL(fmtpStr); |
|
400 CSdpFmtAttributeField* fmtpAttribute = CSdpFmtAttributeField::NewLC(fmtpStr, ptrAttrName, ptrAttrValue); |
|
401 User::LeaveIfError(aSdp.FormatAttributeFields().Append(fmtpAttribute)); |
|
402 CleanupStack::Pop(fmtpAttribute); |
|
403 } |
|
404 CleanupStack::PopAndDestroy(3); |
|
405 }//for |
|
406 }//End of function |
|
407 #endif |
|
408 |
|
409 void CScafStep::PrintErrorAndLeaveL(TDesC& aKey) |
|
410 /** |
|
411 Prints an error message and then leaves with not found error. |
|
412 @param aKey The name of the key which is not found. |
|
413 */ |
|
414 { |
|
415 ERR_PRINTF2(_L("Failed to read '%S' key of configuration"), &aKey); |
|
416 SetTestStepResult(EFail); |
|
417 User::Leave(KErrNotFound); |
|
418 } |
|
419 |
|
420 TPtr8 CScafStep::Convert16To8LC(TDesC& aDes) |
|
421 /** |
|
422 Convert a 16-bit descriptor into 8-bit. |
|
423 @param aVal The 16-bit descriptor. |
|
424 @return The descriptor converted to 8-bit. |
|
425 */ |
|
426 { |
|
427 HBufC8* buf = HBufC8::NewLC(aDes.Size()); |
|
428 TPtr8 ptr(buf->Des()); |
|
429 ptr.Copy(aDes); |
|
430 return ptr; |
|
431 } |
|
432 |
|
433 HBufC* CScafStep::GetFullPathLC(const TDesC& aPath, const TDesC& aFileName) |
|
434 /** |
|
435 Create a fully qualified file path. |
|
436 @param aPath The folder path of the file. |
|
437 @param aFileName The name of the file. |
|
438 @return A pointer to the fully qualified file path. |
|
439 */ |
|
440 { |
|
441 HBufC* fullPath = HBufC::NewLC(aPath.Length()+aFileName.Length()+1); |
|
442 TPtr ptr(fullPath->Des()); |
|
443 ptr.Copy(aPath); |
|
444 ptr[0] = iParent.Fs().GetSystemDriveChar(); |
|
445 if(aFileName.Length()>0) |
|
446 { |
|
447 ptr.Append(aFileName); |
|
448 } |
|
449 return fullPath; |
|
450 } |
|
451 |
|
452 CSraRightsObject* CScafStep::GetRightsObjectLC(const TDesC& aName, const TDesC& aPrivPath) |
|
453 /** |
|
454 Reads the given RO file and creates a RO object. |
|
455 @param aName The name of the RO file. |
|
456 @param aPrivPath Stream Agents Private Folder Path |
|
457 @return The RO object. |
|
458 */ |
|
459 { |
|
460 RFile f; |
|
461 HBufC* path = GetFullPathLC(aPrivPath, aName); |
|
462 User::LeaveIfError(f.Open(iParent.Fs(), *path, EFileRead)); |
|
463 CleanupStack::PopAndDestroy(path); |
|
464 CleanupClosePushL(f); |
|
465 RFileReadStream stream(f); |
|
466 CleanupClosePushL(stream); |
|
467 CSraRightsObject* ro = CSraRightsObject::NewL(stream); |
|
468 CleanupStack::PopAndDestroy(2, &f); |
|
469 CleanupStack::PushL(ro); |
|
470 return ro; |
|
471 } |
|
472 |
|
473 TVerdict CScafStep::doOOMTestL() |
|
474 /** |
|
475 * Runs the test step under OOM Conditions checking that each heap allocation is fail safe |
|
476 */ |
|
477 { |
|
478 // Pre and Post test heap cell allocation counts |
|
479 TInt cellCountAfter = 0; |
|
480 TInt cellCountBefore = 0; |
|
481 |
|
482 /** |
|
483 * The loop tests each heap allocation under out of memory conditions to determine whether |
|
484 * the framework cleans up correctly without leaking memory. |
|
485 * |
|
486 * The 'for' loop does not have any completion criteria, so the loop breaks out as soon |
|
487 * as any of the following events occur: |
|
488 * a) The pre and post heap cell counts mismatch signalling a memory leakage |
|
489 * b) An unexpected leave (any leave with an error code other than 'KErrNoMemory') |
|
490 * c) All heap allocations have been tested and the test returns 'KErrNone' |
|
491 */ |
|
492 for (TInt testCount = 0; ; ++testCount) |
|
493 { |
|
494 __UHEAP_MARK; |
|
495 __UHEAP_SETFAIL(RHeap::EDeterministic, testCount+1); |
|
496 cellCountBefore = User::CountAllocCells(); |
|
497 TRAPD(err, doTestL()); |
|
498 cellCountAfter = User::CountAllocCells(); |
|
499 __UHEAP_MARKEND; |
|
500 |
|
501 INFO_PRINTF3(_L("OOM Test %d: Status = %d"),testCount,err); |
|
502 |
|
503 if (err == KErrNone) |
|
504 { |
|
505 INFO_PRINTF1(_L("OOM Test Finished")); |
|
506 break; |
|
507 } |
|
508 else if(err == KErrNoMemory) |
|
509 { |
|
510 if (cellCountBefore != cellCountAfter) |
|
511 { |
|
512 ERR_PRINTF2(_L("OOM Test Result: Failed - Memory leakage on iteration %d"), testCount); |
|
513 ERR_PRINTF2(_L("Pre-Test Heap Cell Count: %d"), cellCountBefore); |
|
514 ERR_PRINTF2(_L("Post-Test Heap Cell Count: %d"), cellCountAfter); |
|
515 SetTestStepResult(EFail); |
|
516 break; |
|
517 } |
|
518 } |
|
519 else |
|
520 { |
|
521 User::Leave(err); |
|
522 break; |
|
523 } |
|
524 } |
|
525 |
|
526 return TestStepResult(); |
|
527 } |
|
528 |
|
529 TVerdict CScafStep::doTestL() |
|
530 { |
|
531 return TestStepResult(); |
|
532 } |
|
533 |
|
534 void CScafStep::ReadTestConfigurationL() |
|
535 { |
|
536 TInt baseIndex=0; |
|
537 |
|
538 // Read SDP Configuration Data |
|
539 TName fMedia; |
|
540 TName fProtocol; |
|
541 TName fPort; |
|
542 TName fFormat; |
|
543 TName fConnAddr; |
|
544 |
|
545 fMedia.Format(KSdpMedia, baseIndex); |
|
546 fProtocol.Format(KSdpProtocol, baseIndex); |
|
547 fPort.Format(KSdpPort, baseIndex); |
|
548 fFormat.Format(KSdpFormat, baseIndex); |
|
549 fConnAddr.Format(KSdpConnAddr, baseIndex); |
|
550 |
|
551 TPtrC mediaData; |
|
552 TPtrC protocolData; |
|
553 TInt portData; |
|
554 TPtrC formatData; |
|
555 TPtrC connAddrData; |
|
556 |
|
557 while (GetStringFromConfig(ConfigSection(), fMedia, mediaData) && |
|
558 GetStringFromConfig(ConfigSection(), fProtocol, protocolData) && |
|
559 GetIntFromConfig(ConfigSection(), fPort, portData) && |
|
560 GetStringFromConfig(ConfigSection(), fFormat, formatData)) |
|
561 { |
|
562 |
|
563 CTestDecoderConfiguration* newSdpConfig = CTestDecoderConfiguration::NewLC(); |
|
564 |
|
565 newSdpConfig->iMedia.Set(mediaData); |
|
566 newSdpConfig->iProtocol.Set(protocolData); |
|
567 newSdpConfig->iPort = portData; |
|
568 newSdpConfig->iFormat.Set(formatData); |
|
569 |
|
570 if(GetStringFromConfig(ConfigSection(), fConnAddr, connAddrData)) |
|
571 { |
|
572 newSdpConfig->iConnAddr.Set(connAddrData); |
|
573 } |
|
574 |
|
575 // Read Stream Associated Agents Private Folder Path |
|
576 TName fPrivateFolderPath; |
|
577 TName fSingleProcessAgent; |
|
578 |
|
579 fPrivateFolderPath.Format(KScafConfigPrivateFolderPath, baseIndex); |
|
580 fSingleProcessAgent.Format(KScafConfigSingleProcessAgent, baseIndex); |
|
581 |
|
582 TPtrC privateFolderPath; |
|
583 TBool singleProcessAgent; |
|
584 |
|
585 if(GetStringFromConfig(ConfigSection(), fPrivateFolderPath, privateFolderPath) && |
|
586 GetBoolFromConfig(ConfigSection(), fSingleProcessAgent, singleProcessAgent)) |
|
587 { |
|
588 newSdpConfig->iPrivateFolderPath.Set(privateFolderPath); |
|
589 newSdpConfig->iSingleProcessAgent = singleProcessAgent; |
|
590 } |
|
591 |
|
592 // Read SDP Attribute Data |
|
593 TInt attributeIndex = 0; |
|
594 |
|
595 TName fAttributeType; |
|
596 TName fAttributeName; |
|
597 TName fAttributeValue; |
|
598 |
|
599 fAttributeType.Format(KSdpAttributeType,baseIndex,attributeIndex); |
|
600 fAttributeName.Format(KSdpAttributeName,baseIndex,attributeIndex); |
|
601 fAttributeValue.Format(KSdpAttributeValue,baseIndex,attributeIndex); |
|
602 |
|
603 TPtrC attributeType; |
|
604 TPtrC attributeName; |
|
605 TPtrC attributeValue; |
|
606 |
|
607 while (GetStringFromConfig(ConfigSection(), fAttributeType, attributeType) && |
|
608 GetStringFromConfig(ConfigSection(), fAttributeName, attributeName) && |
|
609 GetStringFromConfig(ConfigSection(), fAttributeValue, attributeValue)) |
|
610 { |
|
611 TSdpAttribute newAttribute; |
|
612 |
|
613 newAttribute.iAttributeType.Set(attributeType); |
|
614 newAttribute.iAttributeName.Set(attributeName); |
|
615 newAttribute.iAttributeValue.Set(attributeValue); |
|
616 |
|
617 newSdpConfig->iAttributeArray.Append(newAttribute); |
|
618 |
|
619 attributeIndex++; |
|
620 fAttributeType.Format(KSdpAttributeType,baseIndex,attributeIndex); |
|
621 fAttributeName.Format(KSdpAttributeName,baseIndex,attributeIndex); |
|
622 fAttributeValue.Format(KSdpAttributeValue,baseIndex,attributeIndex); |
|
623 } |
|
624 |
|
625 iDecoderConfigurationArray.Append(newSdpConfig); |
|
626 |
|
627 CleanupStack::Pop(newSdpConfig); |
|
628 |
|
629 baseIndex++; |
|
630 fMedia.Format(KSdpMedia, baseIndex); |
|
631 fProtocol.Format(KSdpProtocol, baseIndex); |
|
632 fPort.Format(KSdpPort, baseIndex); |
|
633 fFormat.Format(KSdpFormat, baseIndex); |
|
634 fConnAddr.Format(KSdpConnAddr, baseIndex); |
|
635 } |
|
636 |
|
637 // Read Expected Key Stream Decoder Attribute Values |
|
638 TName fIsProgramProtected; |
|
639 TName fIsServiceProtected; |
|
640 TName fCanExport; |
|
641 TName fMustProtectIfRecording; |
|
642 TName fCanPlay; |
|
643 TName fContentId; |
|
644 TName fRightsIssuerUri; |
|
645 |
|
646 baseIndex = 0; |
|
647 |
|
648 fIsProgramProtected.Format(KScafConfigIsProgramProtected,baseIndex); |
|
649 fIsServiceProtected.Format(KScafConfigIsServiceProtected,baseIndex); |
|
650 fCanExport.Format(KScafConfigCanExport,baseIndex); |
|
651 fMustProtectIfRecording.Format(KScafConfigMustProtectIfRecording,baseIndex); |
|
652 fCanPlay.Format(KScafConfigCanPlay,baseIndex); |
|
653 fContentId.Format(KScafConfigContentId,baseIndex); |
|
654 fRightsIssuerUri.Format(KScafConfigRightsIssuerUri,baseIndex); |
|
655 |
|
656 TBool isProgramProtected; |
|
657 TBool isServiceProtected; |
|
658 TBool canExport; |
|
659 TBool mustProtectIfRecording; |
|
660 TBool canPlay; |
|
661 TPtrC contentId; |
|
662 TPtrC rightsIssuerUri; |
|
663 |
|
664 while(GetBoolFromConfig(ConfigSection(),fIsProgramProtected,isProgramProtected) && |
|
665 GetBoolFromConfig(ConfigSection(),fIsServiceProtected,isServiceProtected) && |
|
666 GetBoolFromConfig(ConfigSection(),fCanExport,canExport) && |
|
667 GetBoolFromConfig(ConfigSection(),fMustProtectIfRecording,mustProtectIfRecording) && |
|
668 GetBoolFromConfig(ConfigSection(),fCanPlay,canPlay) && |
|
669 GetStringFromConfig(ConfigSection(),fContentId,contentId) && |
|
670 GetStringFromConfig(ConfigSection(),fRightsIssuerUri,rightsIssuerUri)) |
|
671 { |
|
672 TExpectedKeyStreamDecoderAttributes newExpectedValues; |
|
673 |
|
674 newExpectedValues.IsProgramProtected = isProgramProtected; |
|
675 newExpectedValues.IsServiceProtected = isServiceProtected; |
|
676 newExpectedValues.CanExport = canExport; |
|
677 newExpectedValues.MustProtectIfRecording = mustProtectIfRecording; |
|
678 newExpectedValues.CanPlay = canPlay; |
|
679 newExpectedValues.ContentId.Set(contentId); |
|
680 newExpectedValues.RightsIssuerUri.Set(rightsIssuerUri); |
|
681 |
|
682 iExpectedKeyStreamDecoderData.Append(newExpectedValues); |
|
683 |
|
684 baseIndex++; |
|
685 fIsProgramProtected.Format(KScafConfigIsProgramProtected,baseIndex); |
|
686 fIsServiceProtected.Format(KScafConfigIsServiceProtected,baseIndex); |
|
687 fCanExport.Format(KScafConfigCanExport,baseIndex); |
|
688 fMustProtectIfRecording.Format(KScafConfigMustProtectIfRecording,baseIndex); |
|
689 fCanPlay.Format(KScafConfigCanPlay,baseIndex); |
|
690 fContentId.Format(KScafConfigContentId,baseIndex); |
|
691 fRightsIssuerUri.Format(KScafConfigRightsIssuerUri,baseIndex); |
|
692 } |
|
693 |
|
694 // Read OOM Test Flag |
|
695 GetBoolFromConfig(ConfigSection(), KScafConfigOOMTest, iOOMTest); |
|
696 } |
|
697 |
|
698 TBool CScafStep::CheckKeyStreamDecoderAttributesL(const CKeyStreamDecoder& aDecoder, |
|
699 const TExpectedKeyStreamDecoderAttributes& aExpectedData) |
|
700 { |
|
701 // Overall result of the attribute value checks (ETrue = Pass / EFalse = Fail) |
|
702 TBool result = ETrue; |
|
703 |
|
704 _LIT(KIsProgramProtectedDescription,"IsProgramProtected"); |
|
705 _LIT(KIsServiceProtectedDescription,"IsServiceProtected"); |
|
706 _LIT(KCanExportDescription,"CanExport"); |
|
707 _LIT(KMustProtectIfRecordingDescription,"MustProtectIfRecording"); |
|
708 _LIT(KCanPlayDescription,"CanPlay"); |
|
709 _LIT(KContentIDDescription,"ContentID"); |
|
710 _LIT(KRightIssuerURIDescription,"RightIssuerURI"); |
|
711 |
|
712 // Query the stream agent to determine whether the program is protected |
|
713 if(!CompareBooleanAttributeL(aDecoder, |
|
714 EIsProgramProtected, |
|
715 KIsProgramProtectedDescription, |
|
716 aExpectedData.IsProgramProtected)) |
|
717 { |
|
718 result = EFalse; |
|
719 } |
|
720 |
|
721 // Query the stream agent to determine whether the whole service is protected |
|
722 if(!CompareBooleanAttributeL(aDecoder, |
|
723 EIsServiceProtected, |
|
724 KIsServiceProtectedDescription, |
|
725 aExpectedData.IsServiceProtected)) |
|
726 { |
|
727 result = EFalse; |
|
728 } |
|
729 |
|
730 // Query the stream agent to determine whether the content can be exported |
|
731 if(!CompareBooleanAttributeL(aDecoder, |
|
732 ECanExport, |
|
733 KCanExportDescription, |
|
734 aExpectedData.CanExport)) |
|
735 { |
|
736 result = EFalse; |
|
737 } |
|
738 |
|
739 // Query the stream agent to determine whether the content must be protected whilst recording |
|
740 if(!CompareBooleanAttributeL(aDecoder, |
|
741 EMustProtectIfRecording, |
|
742 KMustProtectIfRecordingDescription, |
|
743 aExpectedData.MustProtectIfRecording)) |
|
744 { |
|
745 result = EFalse; |
|
746 } |
|
747 |
|
748 // Query the stream agent to determine whether the content can be played |
|
749 if(!CompareBooleanAttributeL(aDecoder, |
|
750 ECanPlay, |
|
751 KCanPlayDescription, |
|
752 aExpectedData.CanPlay)) |
|
753 { |
|
754 result = EFalse; |
|
755 } |
|
756 |
|
757 // Query the stream agent to retrieve the Content ID |
|
758 if(!CompareStringAttributeL(aDecoder, |
|
759 EContentID, |
|
760 KContentIDDescription, |
|
761 aExpectedData.ContentId)) |
|
762 { |
|
763 result = EFalse; |
|
764 } |
|
765 |
|
766 // Query the stream agent to retrieve the Rights Issuer URI |
|
767 if(!CompareStringAttributeL(aDecoder, |
|
768 ERightsIssuerURI, |
|
769 KRightIssuerURIDescription, |
|
770 aExpectedData.RightsIssuerUri)) |
|
771 { |
|
772 result = EFalse; |
|
773 } |
|
774 |
|
775 return result; |
|
776 } |
|
777 |
|
778 TBool CScafStep::CompareBooleanAttributeL(const CKeyStreamDecoder& aDecoder, |
|
779 const TAttribute& aAttributeEnum, |
|
780 const TDesC& aAttributeDescription, |
|
781 const TBool aExpectedValue) |
|
782 { |
|
783 TBool retrievedValue; |
|
784 |
|
785 // Query the stream agent to determine the actual value of the attribute |
|
786 TRAPD(err,aDecoder.GetAttributeL(aAttributeEnum,retrievedValue)); |
|
787 |
|
788 if(err != KErrNone) |
|
789 { |
|
790 ERR_PRINTF4(_L("*** Thread %d: Failed to Retrieve '%S' Value - %d ***"),iThreadId,&aAttributeDescription,err); |
|
791 User::Leave(err); |
|
792 } |
|
793 |
|
794 if(retrievedValue != aExpectedValue) |
|
795 { |
|
796 INFO_PRINTF4(_L("Thread %d: Expected '%S' Value = %d"),iThreadId,&aAttributeDescription,aExpectedValue); |
|
797 INFO_PRINTF4(_L("Thread %d: Retrieved '%S' Value = %d"),iThreadId,&aAttributeDescription,retrievedValue); |
|
798 ERR_PRINTF3(_L("*** Thread %d: Unexpected '%S' Value ***"),iThreadId,&aAttributeDescription); |
|
799 return EFalse; |
|
800 } |
|
801 |
|
802 return ETrue; |
|
803 } |
|
804 |
|
805 TBool CScafStep::CompareStringAttributeL(const CKeyStreamDecoder& aDecoder, |
|
806 const TStringAttribute& aAttributeEnum, |
|
807 const TDesC& aAttributeDescription, |
|
808 const TDesC& aExpectedValue) |
|
809 { |
|
810 TBool result = ETrue; |
|
811 |
|
812 // Query the stream agent to determine the actual value of the attribute |
|
813 HBufC* retrievedValue = aDecoder.GetStringAttributeLC(aAttributeEnum); |
|
814 |
|
815 if(retrievedValue->Des() != aExpectedValue) |
|
816 { |
|
817 INFO_PRINTF4(_L("Thread %d: Expected '%S' Value = %S"),iThreadId,&aAttributeDescription,&aExpectedValue); |
|
818 INFO_PRINTF4(_L("Thread %d: Retrieved '%S' Value = %S"),iThreadId,&aAttributeDescription,retrievedValue); |
|
819 ERR_PRINTF3(_L("*** Thread %d: Unexpected '%S' Value ***"),iThreadId,&aAttributeDescription); |
|
820 result = EFalse; |
|
821 } |
|
822 |
|
823 // Destroy the heap based descriptor |
|
824 CleanupStack::PopAndDestroy(retrievedValue); |
|
825 |
|
826 return result; |
|
827 } |