authorisation/userpromptservice/test/tups/src/tupsclientstep.cpp
changeset 8 35751d3474b7
child 94 0e6c5a9328b5
equal deleted inserted replaced
2:675a964f4eb5 8:35751d3474b7
       
     1 /*
       
     2 * Copyright (c) 2007-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 the License "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 
       
    18 
       
    19 
       
    20 #include "tupsclientstep.h"  
       
    21 #include "tupsintegdefs.h"
       
    22 #include "tupsproperty.h"
       
    23 #include <e32property.h>
       
    24 
       
    25 
       
    26 TServiceRequestParameters::TServiceRequestParameters() 
       
    27 	:iServiceUID(0), iServerName(0),iDestination(0), iExpectedError(0),
       
    28 	 iOpaqueData(0), iSelectDialogOption(0), iButtonsDisplayed(0),
       
    29 	 iDialogCreatorInvoked(0), iPolicyEvaluatorInvoked(0), iAccessGranted(0),
       
    30 	 iCloseSession(EFalse), iHoldEvaluatorOpen(EFalse), iHoldPrepareDialogOpen(EFalse), iHoldDisplayDialogOpen(EFalse),
       
    31 	 iRequestDurationThreshold(0), iLeaveDialog(EFalse), iLeaveEvaluator(EFalse), iCancelUpsRequest(EFalse),
       
    32 	 iPlatSecPass(EFalse),iForcePrompt(EFalse),iExpectedEvaluatorInfo(0),iSelectFingerprint(0),
       
    33 	 iWaitUntilFileAppears(0)	 	 	 	 
       
    34 	{	
       
    35 	};   
       
    36 
       
    37 COpenSession* COpenSession::NewL(const TPtrC& aServerName)
       
    38 	{
       
    39 	COpenSession * self = new (ELeave) COpenSession(); 
       
    40 	CleanupStack::PushL(self);
       
    41 	self->ConstructL(aServerName);
       
    42 	CleanupStack::Pop(self);
       
    43 	return(self);
       
    44 	} // End of function
       
    45 	
       
    46 void COpenSession::ConstructL(const TPtrC& aServerName)
       
    47 	{
       
    48 	iServerName = aServerName;
       
    49 	iPointerToServer = new RUpsTestServ;
       
    50 	User::LeaveIfError(iPointerToServer->Connect(iServerName, ETrue));
       
    51     iPointerToSession = new RUpsTestSession;
       
    52 	User::LeaveIfError(iPointerToSession->Open(*iPointerToServer));
       
    53 	} // End of function
       
    54 	
       
    55 COpenSession::~COpenSession() 
       
    56 	{	
       
    57 	if (iPointerToSession)
       
    58 		iPointerToSession->Close();
       
    59 	if (iPointerToServer)
       
    60 		iPointerToServer->Close();
       
    61 	delete iPointerToSession;
       
    62     delete iPointerToServer;
       
    63     }  // End of function
       
    64 
       
    65 CUpsClientStep::~CUpsClientStep()
       
    66 /**
       
    67  * Destructor
       
    68  */
       
    69 	{
       
    70 	iArraySersToRequest.Close();   
       
    71   
       
    72 	CloseAllOpenSessions();
       
    73 	delete iPropertyReader;
       
    74   	__UHEAP_MARKEND;
       
    75 	} // End of function
       
    76 
       
    77 
       
    78 CUpsClientStep::CUpsClientStep()
       
    79 /**
       
    80  * Constructor
       
    81  */
       
    82 	{
       
    83 	SetTestStepName(KUPSClientStep);
       
    84 	} // End of function
       
    85 
       
    86 
       
    87 TVerdict CUpsClientStep::doTestStepPreambleL()
       
    88 /**
       
    89  * @return - TVerdict code
       
    90  * Override of base class virtual
       
    91  */
       
    92 	{
       
    93 	
       
    94  	__UHEAP_MARK;
       
    95  	
       
    96 	// Read values to config servers from INI file. (ARRAY of values)
       
    97  	
       
    98     // Read how many times the test step needs to be repeated.
       
    99     TName fStepRepeat(_L("StepRepeat"));
       
   100     TInt  repeats;
       
   101     
       
   102     if(GetIntFromConfig(ConfigSection(),fStepRepeat,repeats))
       
   103 	    {
       
   104 	   	iStepRepeat=repeats;
       
   105 	    }
       
   106 	else
       
   107 		{
       
   108 		iStepRepeat=1;		
       
   109 		}
       
   110     
       
   111     // Read values for test sequence from INI file. (ARRAY of values)
       
   112 	TInt index=0;
       
   113 	TName fUseServiceUID;
       
   114 	fUseServiceUID.Format(_L("UseServiceUID_%d"),index);
       
   115 	TName fUseServerName;
       
   116 	fUseServerName.Format(_L("UseServerName_%d"),index);
       
   117 	TName fDestination;
       
   118 	fDestination.Format(_L("Destination_%d"),index);
       
   119 	TName fExpectedError;
       
   120 	fExpectedError.Format(_L("ExpectedError_%d"),index);
       
   121 	TName fUseOpaqueData;
       
   122 	fUseOpaqueData.Format(_L("UseOpaqueData_%d"),index);
       
   123 	TName fSelectDialogOption;
       
   124 	fSelectDialogOption.Format(_L("SelectDialogOption_%d"),index); 
       
   125 	TName fButtonsDisplayed;
       
   126 	fButtonsDisplayed.Format(_L("ButtonsDisplayed_%d"),index);
       
   127 	TName fDialogCreatorInvoked;
       
   128 	fDialogCreatorInvoked.Format(_L("DialogCreatorInvoked_%d"),index);
       
   129 	TName fPolicyEvaluatorInvoked;
       
   130 	fPolicyEvaluatorInvoked.Format(_L("PolicyEvaluatorInvoked_%d"),index);
       
   131 	TName fAccessGranted;
       
   132 	fAccessGranted.Format(_L("AccessGranted_%d"), index);
       
   133 	TName fCloseSession;
       
   134 	fCloseSession.Format(_L("CloseSession_%d"), index);
       
   135 	TName fHoldEvaluatorOpen;
       
   136 	fHoldEvaluatorOpen.Format(_L("HoldEvaluatorOpen_%d"), index);
       
   137 	TName fHoldPrepareDialogOpen;
       
   138 	fHoldPrepareDialogOpen.Format(_L("HoldPrepareDialogOpen_%d"), index);
       
   139 	TName fHoldDisplayDialogOpen;
       
   140 	fHoldDisplayDialogOpen.Format(_L("HoldDisplayDialogOpen_%d"), index);
       
   141 	TName fRequestDurationThreshold;
       
   142 	fRequestDurationThreshold.Format(_L("RequestDurationThreshold_%d"), index);
       
   143 	TName fLeaveDialog;
       
   144 	fLeaveDialog.Format(_L("LeaveDialog_%d"), index);
       
   145 	TName fLeaveEvaluator;
       
   146 	fLeaveEvaluator.Format(_L("LeaveEvaluator_%d"), index);
       
   147 	TName fCancelUpsRequest;
       
   148 	fCancelUpsRequest.Format(_L("CancelUpsRequest_%d"), index);
       
   149 	TName fPlatSecPass;
       
   150 	fPlatSecPass.Format(_L("PlatSecPass_%d"), index);
       
   151 	TName fForcePrompt;
       
   152 	fForcePrompt.Format(_L("ForcePrompt_%d"), index);
       
   153 	TName fExpectedEvaInfo;
       
   154 	fExpectedEvaInfo.Format(_L("ExpectedEvaluatorInfo_%d"), index);
       
   155 	TName fSelectFingerprint;
       
   156 	fSelectFingerprint.Format(_L("SelectFingerprint_%d"), index);
       
   157 	TName fWaitUntilFileAppears;
       
   158 	fWaitUntilFileAppears.Format(_L("WaitUntilFileAppears_%d"), index);
       
   159 	
       
   160 	TInt	useServiceUID;
       
   161 	TPtrC   useServerName;
       
   162 	TPtrC   destination;
       
   163 	TInt	expectedError;
       
   164 	TPtrC   useOpaqueData;
       
   165     TPtrC	selectDialogOption;
       
   166 	TInt	buttonsDisplayed;
       
   167 	TInt    dialogCreatorInvoked;
       
   168 	TInt	policyEvaluatorInvoked;
       
   169 	TPtrC	accessGranted;
       
   170 	TBool	closeSession;
       
   171 	TBool   holdEvaluatorOpen;
       
   172 	TBool   holdPrepareDialogOpen;
       
   173 	TBool   holdDisplayDialogOpen;
       
   174 	TInt 	requestDurationThreshold;
       
   175 	TBool   leaveDialog;
       
   176 	TBool   leaveEvaluator;
       
   177 	TBool   cancelUpsRequest;
       
   178 	TBool   platSecPass;
       
   179 	TBool   forcePrompt;
       
   180 	TInt    expectedEvaInfo;
       
   181 	TInt	selectFingerprint;
       
   182 	TPtrC   waitUntilFileAppears;	
       
   183 	
       
   184 	while (GetHexFromConfig(ConfigSection(), fUseServiceUID,useServiceUID)
       
   185 		&& GetStringFromConfig(ConfigSection(),fUseServerName,useServerName)
       
   186 		&& GetStringFromConfig(ConfigSection(),fDestination,destination)
       
   187 	  	&& GetStringFromConfig(ConfigSection(),fAccessGranted,accessGranted))
       
   188 		{
       
   189 	    TServiceRequestParameters newSerReq;
       
   190 	    newSerReq.iServiceUID = useServiceUID; 
       
   191 	    newSerReq.iServerName = useServerName;
       
   192 	    newSerReq.iDestination = destination;
       
   193 	    newSerReq.iAccessGranted = accessGranted;
       
   194 	    
       
   195         // Close session is optional.
       
   196         if(GetBoolFromConfig(ConfigSection(),fCloseSession,closeSession))
       
   197 	    	{
       
   198 	    	newSerReq.iCloseSession = closeSession;
       
   199 	    	}
       
   200 	    
       
   201 	    // use of dialog creator is optional.
       
   202 	    if(GetStringFromConfig(ConfigSection(),fSelectDialogOption,selectDialogOption)
       
   203 		&& GetIntFromConfig(ConfigSection(),fButtonsDisplayed,buttonsDisplayed)
       
   204 		&& GetIntFromConfig(ConfigSection(),fDialogCreatorInvoked,dialogCreatorInvoked))
       
   205 	    	{
       
   206 		    newSerReq.iSelectDialogOption = selectDialogOption;
       
   207 		    newSerReq.iButtonsDisplayed	= buttonsDisplayed;
       
   208 		    newSerReq.iDialogCreatorInvoked	= dialogCreatorInvoked;
       
   209 	    	} 
       
   210 	    
       
   211 	    // use of policy evaluator is optional.
       
   212 	    if(GetIntFromConfig(ConfigSection(),fPolicyEvaluatorInvoked,policyEvaluatorInvoked))
       
   213 	    	{
       
   214 	       	newSerReq.iPolicyEvaluatorInvoked = policyEvaluatorInvoked;
       
   215 	    	}
       
   216 	    	    
       
   217 	    // Opaque data is optional
       
   218 	    if(GetStringFromConfig(ConfigSection(),fUseOpaqueData,useOpaqueData))
       
   219 	    	{
       
   220 	       	HBufC8* converter = HBufC8::NewLC(useOpaqueData.Length());
       
   221 			converter->Des().Copy(useOpaqueData);	
       
   222              
       
   223 	       	newSerReq.iOpaqueData = converter->Ptr() ;	
       
   224 	       	CleanupStack::PopAndDestroy(); //converter 
       
   225 	    	}
       
   226 	    
       
   227 	    // Expected error is optional.
       
   228 	    if(GetIntFromConfig(ConfigSection(),fExpectedError,expectedError))
       
   229 	    	{
       
   230 			newSerReq.iExpectedError = expectedError;
       
   231 	    	}
       
   232 	    	
       
   233 	    // hold policy evaluator open is optional.
       
   234 	    if(GetBoolFromConfig(ConfigSection(),fHoldEvaluatorOpen, holdEvaluatorOpen))
       
   235 	    	{
       
   236 			newSerReq.iHoldEvaluatorOpen =	holdEvaluatorOpen;
       
   237 	    	}
       
   238 	    
       
   239 	    // hold prepare dialog open is optional.
       
   240 	    if(GetBoolFromConfig(ConfigSection(),fHoldPrepareDialogOpen, holdPrepareDialogOpen))
       
   241 	    	{
       
   242 			newSerReq.iHoldPrepareDialogOpen =	holdPrepareDialogOpen;
       
   243 	    	}
       
   244 	    	
       
   245 	    // hold display dialog open is optional.
       
   246 	    if(GetBoolFromConfig(ConfigSection(),fHoldDisplayDialogOpen, holdDisplayDialogOpen))
       
   247 	    	{
       
   248 			newSerReq.iHoldDisplayDialogOpen =	holdDisplayDialogOpen;
       
   249 	    	}
       
   250 	    
       
   251 	    // request duration threshold - if a request takes 
       
   252 	    // longer than this threshold it will fail the test
       
   253 	    if(GetIntFromConfig(ConfigSection(),fRequestDurationThreshold, requestDurationThreshold))
       
   254 	    	{
       
   255 	       	newSerReq.iRequestDurationThreshold = requestDurationThreshold;
       
   256 	    	}
       
   257 
       
   258 	    // leave dialog is optional.
       
   259 	    if(GetBoolFromConfig(ConfigSection(),fLeaveDialog,leaveDialog))
       
   260 	    	{
       
   261 	    	newSerReq.iLeaveDialog = leaveDialog;
       
   262 	   		}
       
   263 	    
       
   264 	    // leave Evaluator is optional.
       
   265 	    if(GetBoolFromConfig(ConfigSection(),fLeaveEvaluator,leaveEvaluator))
       
   266 	    	{
       
   267 			newSerReq.iLeaveEvaluator = leaveEvaluator;	
       
   268 	    	}
       
   269 		       
       
   270 	    // Cancel ups request is optional.
       
   271 	    if(GetBoolFromConfig(ConfigSection(),fCancelUpsRequest,cancelUpsRequest))
       
   272 	    	{
       
   273 	  		newSerReq.iCancelUpsRequest = cancelUpsRequest;		
       
   274 	    	}
       
   275     
       
   276 	    // plat sec pass is optional.
       
   277 	    if(GetBoolFromConfig(ConfigSection(),fPlatSecPass,platSecPass))
       
   278 	    	{
       
   279 			newSerReq.iPlatSecPass = platSecPass;
       
   280 	    	}
       
   281 	    
       
   282 	    // Force prompt is optional.
       
   283 	    if(GetBoolFromConfig(ConfigSection(),fForcePrompt,forcePrompt))
       
   284 	    	{
       
   285 			newSerReq.iForcePrompt = forcePrompt;
       
   286 	    	}
       
   287 	    
       
   288 	    // use of policy evaluator is optional.
       
   289 	    if(GetIntFromConfig(ConfigSection(),fExpectedEvaInfo,expectedEvaInfo))
       
   290 	    	{
       
   291 	       	newSerReq.iExpectedEvaluatorInfo = expectedEvaInfo;
       
   292 	    	}
       
   293 	    
       
   294 	    // Fingerprint selection is optional.
       
   295 	    if(GetIntFromConfig(ConfigSection(),fSelectFingerprint,selectFingerprint))
       
   296 	    	{
       
   297 	       	newSerReq.iSelectFingerprint = selectFingerprint;
       
   298 	    	}
       
   299 	    
       
   300 	    // iRepeatUntilFileAppears is optional.
       
   301 	    if(GetStringFromConfig(ConfigSection(),fWaitUntilFileAppears,waitUntilFileAppears))
       
   302 	    	{
       
   303 	    	newSerReq.iWaitUntilFileAppears = waitUntilFileAppears;
       
   304 	    	}
       
   305 	    
       
   306 	    // Add the new service to be requested to array.
       
   307 	    iArraySersToRequest.Append(newSerReq);
       
   308 	       
       
   309 	    index++;
       
   310 	    fUseServiceUID.Format(_L("UseServiceUID_%d"),index);
       
   311 	    fUseServerName.Format(_L("UseServerName_%d"),index);
       
   312 	    fDestination.Format(_L("Destination_%d"),index);
       
   313 	    fExpectedError.Format(_L("ExpectedError_%d"),index);
       
   314 	    fUseOpaqueData.Format(_L("UseOpaqueData_%d"),index);
       
   315 	    fSelectDialogOption.Format(_L("SelectDialogOption_%d"),index);
       
   316 	    fButtonsDisplayed.Format(_L("ButtonsDisplayed_%d"),index);
       
   317 	    fDialogCreatorInvoked.Format(_L("DialogCreatorInvoked_%d"),index); 
       
   318 	    fPolicyEvaluatorInvoked.Format(_L("PolicyEvaluatorInvoked_%d"),index);
       
   319 	    fAccessGranted.Format(_L("AccessGranted_%d"), index);  
       
   320 	    fCloseSession.Format(_L("CloseSession_%d"), index);
       
   321 	    fHoldEvaluatorOpen.Format(_L("HoldEvaluatorOpen_%d"), index);
       
   322 	    fHoldPrepareDialogOpen.Format(_L("HoldPrepareDialogOpen_%d"), index);
       
   323 	    fHoldDisplayDialogOpen.Format(_L("HoldDisplayDialogOpen_%d"), index);
       
   324 		fRequestDurationThreshold.Format(_L("RequestDurationThreshold_%d"), index);
       
   325 	    fLeaveDialog.Format(_L("LeaveDialog_%d"), index);
       
   326 	    fLeaveEvaluator.Format(_L("LeaveEvaluator_%d"), index);
       
   327 	    fCancelUpsRequest.Format(_L("CancelUpsRequest_%d"), index);
       
   328 	    fPlatSecPass.Format(_L("PlatSecPass_%d"), index);
       
   329 	    fForcePrompt.Format(_L("ForcePrompt_%d"), index);
       
   330 	   	fExpectedEvaInfo.Format(_L("ExpectedEvaluatorInfo_%d"), index);
       
   331 	   	fSelectFingerprint.Format(_L("SelectFingerprint_%d"), index);
       
   332 	   	fWaitUntilFileAppears.Format(_L("WaitUntilFileAppears_%d"), index);
       
   333 	   	}	
       
   334 
       
   335 	// now try for some clientStep specific stuff
       
   336 	// this ini file entry specifies the property key value for the hold flag
       
   337 	// If the hold flag property is true then monitor it until it becomes false
       
   338 	// then continue
       
   339 	TInt holdKey;
       
   340     if(GetIntFromConfig(ConfigSection(),_L("HoldClientStepKey"), holdKey))
       
   341 	    {
       
   342 		iHoldClientStepKey = holdKey;
       
   343 
       
   344 		// as this property is present then set it to true using a direct call to p&s api because
       
   345 		// the ups p&s api only handles policy evaluators and dialog creators and not test steps
       
   346 		User::LeaveIfError(RProperty::Set(KPropertyCreatorUid, iHoldClientStepKey, 2));
       
   347 	    }
       
   348 
       
   349 	// Instantiates property reader and seter
       
   350 	iPropertyReader= CUpsProperty::NewL(KPropertyCreatorUid); 
       
   351 
       
   352 	// reads client name and SID
       
   353 	TParse clientFullName;
       
   354 	RThread client;
       
   355 	clientFullName.Set(client.FullName(),NULL, NULL);
       
   356 	iTEFServerName=clientFullName.Name();
       
   357 	iExpectedClientSid = client.SecureId() ;
       
   358 	client.Close();
       
   359 			
       
   360 	SetTestStepResult(EPass);
       
   361 	return TestStepResult();
       
   362 	}
       
   363 
       
   364 
       
   365 TVerdict CUpsClientStep::doTestStepL()
       
   366 	{
       
   367 	// loop to request for different test services.
       
   368 	TVerdict testResult= EPass;
       
   369 	TInt numServicesToRequest = iArraySersToRequest.Count();
       
   370 
       
   371 	if(numServicesToRequest > 0) 
       
   372 		{
       
   373 		// check if the test step needs to hold until another step allows it to continue
       
   374 		if (iHoldClientStepKey)
       
   375 			{
       
   376 			HoldClientL();
       
   377 			}
       
   378 
       
   379 		// repeats the sequence of test services request as many times as specified in iStepRepeat
       
   380 		for(TInt repeatTimes = 0;repeatTimes<iStepRepeat;++repeatTimes)
       
   381 			{
       
   382 			INFO_PRINTF3(_L("%S: Repeat number: %d"),&iTEFServerName,repeatTimes);
       
   383 		
       
   384 			for(TInt index=0;index < numServicesToRequest; ++index )
       
   385 				{
       
   386 				INFO_PRINTF6(_L("%S: Service request: %d. SysServer: %S Destination: %S  ServiceUID: %X "),&iTEFServerName, index, &iArraySersToRequest[index].iServerName ,&iArraySersToRequest[index].iDestination, iArraySersToRequest[index].iServiceUID);
       
   387 				RUpsTestSession * sessionToBeUsed; 
       
   388 
       
   389 				sessionToBeUsed = GetSessionToServerL(iArraySersToRequest[index].iServerName);			    
       
   390 
       
   391 				SetTestDataL(index);
       
   392 				
       
   393 				sessionToBeUsed->UseTestService(iRequestData,iReturnData); 
       
   394 
       
   395 				iServerId=sessionToBeUsed->GetServerSid();
       
   396 				// Check results.
       
   397 				if(CheckResultsL(index) == EFalse)
       
   398 					{
       
   399 					ERR_PRINTF2(_L("%S: Incorrect results"),&iTEFServerName);
       
   400 					User::Leave(KErrGeneral);
       
   401 					}
       
   402 
       
   403 				// Checks from config value if session need to be closed.
       
   404 				if(iArraySersToRequest[index].iCloseSession)
       
   405 					{
       
   406 					INFO_PRINTF3(_L("%S :Closing session to server: %S"),&iTEFServerName, &iArraySersToRequest[index].iServerName );    
       
   407 					CloseSessionL(iArraySersToRequest[index].iServerName);
       
   408 					}   
       
   409 
       
   410 				// If it needs to wait for file installation (via swi)
       
   411 				if(iArraySersToRequest[index].iWaitUntilFileAppears.CompareF(_L(""))!=0)
       
   412 					{
       
   413 					WaitThatFileAppearsL(iArraySersToRequest[index].iWaitUntilFileAppears);
       
   414 					INFO_PRINTF3(_L("%S :File installed by SWI found: %S"),&iTEFServerName,&iArraySersToRequest[index].iWaitUntilFileAppears);
       
   415 					}
       
   416 				}  // End of second loop
       
   417 			}// End of first loop
       
   418 		
       
   419 		// Sets the status of the first instance of policy evaluator and dialog creator to
       
   420 		// completed so that the coordinator step can progress in concurrent mode 	
       
   421 		SetClientStatusCompleteL();
       
   422 		}
       
   423 	else
       
   424 		{
       
   425 		testResult= EFail;
       
   426 		ERR_PRINTF2(_L("%S :Problem reading ini file"),&iTEFServerName);
       
   427 		User::Leave(KErrGeneral);	
       
   428 		}  
       
   429 		
       
   430 	return testResult;	
       
   431 	}  // End of function
       
   432 
       
   433 
       
   434 TVerdict CUpsClientStep::doTestStepPostambleL()
       
   435 	{
       
   436 	return TestStepResult();
       
   437 	}
       
   438 
       
   439 
       
   440 void CUpsClientStep::HoldClientL(void)
       
   441 	{
       
   442 	RProperty checkIfStillNeedtoHold;
       
   443 	User::LeaveIfError(checkIfStillNeedtoHold.Attach(KPropertyCreatorUid, iHoldClientStepKey));
       
   444 	CleanupClosePushL(checkIfStillNeedtoHold);
       
   445 	checkIfStillNeedtoHold.Set(KPropertyCreatorUid, iHoldClientStepKey, 1);
       
   446     TRequestStatus holdStatus;
       
   447  	checkIfStillNeedtoHold.Subscribe(holdStatus);
       
   448  	
       
   449 	TInt holdState;
       
   450 
       
   451 	checkIfStillNeedtoHold.Get(KPropertyCreatorUid, iHoldClientStepKey, holdState);
       
   452 	if(!holdState)
       
   453  		{
       
   454  		checkIfStillNeedtoHold.Cancel();
       
   455  		}
       
   456  	else
       
   457  		{
       
   458  		User::WaitForRequest(holdStatus);
       
   459  		}
       
   460 
       
   461 	RDebug::Printf("[UPS ClientStep 0x%x] HoldClient() stopped holding\n", this);
       
   462 	
       
   463 	// set the hold state back to 1 for future holds
       
   464 	checkIfStillNeedtoHold.Set(KPropertyCreatorUid, iHoldClientStepKey, 2);
       
   465 	CleanupStack::PopAndDestroy(&checkIfStillNeedtoHold);
       
   466 	}
       
   467 
       
   468 
       
   469 TBool CUpsClientStep::FindOpenSession(const TDesC& aServerName,TInt &position)
       
   470 	{
       
   471 	TBool sessionFound = EFalse;
       
   472 	TInt sessionsCount = iArraySessionsInUse.Count();
       
   473 	for(TInt index = 0;index < sessionsCount; ++index)
       
   474 		{
       
   475 		if(!aServerName.CompareF(iArraySessionsInUse[index]->iServerName))
       
   476 			{
       
   477 			position = index;
       
   478 			sessionFound = ETrue;
       
   479 			break;
       
   480 			}
       
   481 		} 
       
   482 	return sessionFound;
       
   483 	} // End of function
       
   484 
       
   485 
       
   486 RUpsTestSession* CUpsClientStep::GetSessionToServerL(const TDesC& aServerName) 
       
   487 	{
       
   488 	// Finds out if a session is already open for server requested
       
   489 	TInt foundPos;
       
   490 	RUpsTestSession* sessionToReturn;
       
   491 	if(!FindOpenSession(aServerName,foundPos))
       
   492 		{
       
   493 		// if open session for intended server not found it creates a new one
       
   494 		COpenSession* sessionToAppend=COpenSession::NewL(aServerName);
       
   495 		iArraySessionsInUse.AppendL(sessionToAppend);		
       
   496 		foundPos = iArraySessionsInUse.Count()-1; // position of new session is last one in array. 
       
   497 		}
       
   498 	sessionToReturn = iArraySessionsInUse[foundPos]->iPointerToSession;
       
   499 	
       
   500 	return sessionToReturn;
       
   501 	} // End of function
       
   502 	
       
   503 	
       
   504 void CUpsClientStep::CloseSessionL(const TDesC& aServerName) 
       
   505 	{
       
   506 	// Finds out if a session is already open for server requested
       
   507 	TInt foundPos;
       
   508 	
       
   509 	if(!FindOpenSession(aServerName,foundPos))
       
   510 		{
       
   511 		// if a session for this server was not found it leaves.
       
   512 		ERR_PRINTF2(_L("%S: The server to be closed was not found"),&iTEFServerName);
       
   513 		User::Leave(KErrGeneral); 
       
   514 		}
       
   515 	delete iArraySessionsInUse[foundPos];  // deletes instance.
       
   516 	iArraySessionsInUse.Remove(foundPos);  // removes empty slot
       
   517 
       
   518 	} // End of function
       
   519 
       
   520 
       
   521 void CUpsClientStep::CloseAllOpenSessions()
       
   522 	{
       
   523 	while(iArraySessionsInUse.Count()>0)
       
   524 		{   // delete and remove first session of array.
       
   525 		delete iArraySessionsInUse[0];
       
   526 	    iArraySessionsInUse.Remove(0);	
       
   527 		}
       
   528 	iArraySessionsInUse.Close();
       
   529 	} // End of function
       
   530 
       
   531 
       
   532 void CUpsClientStep::SetTestDataL(TInt aIndex)
       
   533 	{
       
   534 	// Set data for request.
       
   535 	iReturnData.iError=KErrNone;
       
   536 	iServerId=0;
       
   537 	iRequestData.iMeasureResponceTime = EFalse;
       
   538 	iRequestData.iServiceUid = TUid::Uid(iArraySersToRequest[aIndex].iServiceUID);
       
   539 
       
   540 	if(iArraySersToRequest[aIndex].iOpaqueData.CompareF(_L8(""))==0)
       
   541 		{
       
   542 		iRequestData.iOpaquePresent = EFalse;
       
   543 		}
       
   544 	else
       
   545 		{
       
   546 		iRequestData.iOpaquePresent = ETrue;
       
   547 		iRequestData.iOpaqueData =iArraySersToRequest[aIndex].iOpaqueData;	
       
   548 		}
       
   549 		
       
   550 	iRequestData.iDestination = iArraySersToRequest[aIndex].iDestination;
       
   551 	iRequestData.iCancelRequest = iArraySersToRequest[aIndex].iCancelUpsRequest;
       
   552 	iRequestData.iPlatSecPass = iArraySersToRequest[aIndex].iPlatSecPass;
       
   553 	
       
   554 	// set properties for policy evaluator.
       
   555 	if (iArraySersToRequest[aIndex].iPolicyEvaluatorInvoked != 0)
       
   556 		{
       
   557 		//Reset various publisher and suscribe properties for policy evaluator.
       
   558 		TInt instance = iArraySersToRequest[aIndex].iPolicyEvaluatorInvoked;
       
   559 	  	iPropertyReader->SetL(instance,KPe_Status,CUpsProperty::EPolicyEvaluator, KUpsPeStatusReset);
       
   560 	  	iPropertyReader->SetL(instance,KPe_ClientSid,CUpsProperty::EPolicyEvaluator, 0);
       
   561 	  	iPropertyReader->SetL(instance,KPe_ServerSid,CUpsProperty::EPolicyEvaluator, 0);
       
   562 	  	TBool leaveEvaluator = iArraySersToRequest[aIndex].iLeaveEvaluator; 
       
   563 	  	iPropertyReader->SetL(instance,KPe_Leave,CUpsProperty::EPolicyEvaluator, leaveEvaluator);
       
   564 	  	iPropertyReader->SetL(instance,KPe_Error,CUpsProperty::EPolicyEvaluator, KErrNone);
       
   565 	  	TBool holdEvaluatorOpen = iArraySersToRequest[aIndex].iHoldEvaluatorOpen;
       
   566 	  	iPropertyReader->SetL(instance,KPe_HoldEvaluatorOpen,CUpsProperty::EPolicyEvaluator, holdEvaluatorOpen);
       
   567 	  	TBool forcePrompt = iArraySersToRequest[aIndex].iForcePrompt; 
       
   568 	  	iPropertyReader->SetL(instance,KPe_ForcePrompt,CUpsProperty::EPolicyEvaluator, forcePrompt);
       
   569 	  	iPropertyReader->SetL(instance,KPe_EvaluatorInfo,CUpsProperty::EPolicyEvaluator, 0);
       
   570 		}
       
   571 		
       
   572 	// set properties for dialog creator.
       
   573 	if (iArraySersToRequest[aIndex].iDialogCreatorInvoked != 0)
       
   574 		{
       
   575 		//Reset various publisher and suscribe properties for dialog creator.
       
   576 		TInt instance = iArraySersToRequest[aIndex].iDialogCreatorInvoked;
       
   577 	  	iPropertyReader->SetL(instance,KDc_Status,CUpsProperty::EDialogCreator, KUpsDcStatusReset);
       
   578 	  	iPropertyReader->SetL(instance,KDc_ClientSid,CUpsProperty::EDialogCreator, 0);
       
   579 	  	iPropertyReader->SetL(instance,KDc_ServerSid,CUpsProperty::EDialogCreator, 0);
       
   580 	  	TBool dialogLeave = iArraySersToRequest[aIndex].iLeaveDialog ;
       
   581 	  	iPropertyReader->SetL(instance,KDc_Leave,CUpsProperty::EDialogCreator, dialogLeave);
       
   582 	  	iPropertyReader->SetL(instance,KDc_Error,CUpsProperty::EDialogCreator, KErrNone);
       
   583 	  	iPropertyReader->SetL(instance,KDc_UpsRequestedButtons,CUpsProperty::EDialogCreator, 0);
       
   584 	    TInt buttonToPress = ButtonToInt(iArraySersToRequest[aIndex].iSelectDialogOption);
       
   585 	  	iPropertyReader->SetL(instance,KDc_WhichButtonToPress,CUpsProperty::EDialogCreator, buttonToPress);
       
   586 	  	TBool holdPrepareDialogOpen = iArraySersToRequest[aIndex].iHoldPrepareDialogOpen;
       
   587 	  	iPropertyReader->SetL(instance,KDc_HoldPrepareDialogOpen,CUpsProperty::EDialogCreator, holdPrepareDialogOpen);
       
   588 	  	TBool holdDisplayDialogOpen = iArraySersToRequest[aIndex].iHoldDisplayDialogOpen;
       
   589 	  	iPropertyReader->SetL(instance,KDc_HoldDisplayDialogOpen,CUpsProperty::EDialogCreator, holdDisplayDialogOpen);
       
   590 	  	TBool selectFingerprint = iArraySersToRequest[aIndex].iSelectFingerprint ;
       
   591 	  	iPropertyReader->SetL(instance,KDc_SelectFingerprint,CUpsProperty::EDialogCreator, selectFingerprint);
       
   592 		}
       
   593 
       
   594 	}  // End of function.
       
   595 
       
   596 
       
   597 void CUpsClientStep::SetClientStatusCompleteL()
       
   598 /**
       
   599  * Sets the status of the first policy evaluator invoked by the client to "KUpsClientCompleted" so that
       
   600  * the coordinator step can determine when the step has completely finish and progress in Concurrent mode
       
   601  *
       
   602  * NOTE: When using the Coordinator in this manner, ALL requests made to UPS must invoke the same instance
       
   603  * of the Policy Evaluator and Dialog Creator! e.g. Policy Evalutor 1 and Dialog Creator 1
       
   604  */	
       
   605  	{
       
   606 	TInt requestCount = iArraySersToRequest.Count();
       
   607 		
       
   608 	for(TInt i=0; i<requestCount; ++i)
       
   609 		{
       
   610 		if (iArraySersToRequest[i].iPolicyEvaluatorInvoked != 0)
       
   611 			{	 
       
   612 			TInt instance = iArraySersToRequest[i].iPolicyEvaluatorInvoked;
       
   613 			iPropertyReader->SetL(instance,KPe_Status,CUpsProperty::EPolicyEvaluator, KUpsClientCompleted);
       
   614 			iPropertyReader->SetL(instance,KDc_Status,CUpsProperty::EDialogCreator, KUpsClientCompleted);
       
   615 			break;
       
   616 			}	
       
   617 		}
       
   618 	}
       
   619 	
       
   620 	
       
   621 TUpsDecision CUpsClientStep::StringToTUpsDecision(const TPtrC& aString)
       
   622 	{
       
   623 	if(aString.CompareF(_L("Yes"))==0)
       
   624 		{
       
   625 		return TUpsDecision(EUpsDecYes);
       
   626 		}
       
   627 	else if(aString.CompareF(_L("No"))==0)
       
   628 		{
       
   629 		return TUpsDecision(EUpsDecNo);
       
   630 		}
       
   631 	else if(aString.CompareF(_L("SessionYes"))==0)
       
   632 		{
       
   633 		return TUpsDecision(EUpsDecSessionYes);
       
   634 		}
       
   635 	else
       
   636 		{
       
   637 		return TUpsDecision(EUpsDecSessionNo);
       
   638 		}	
       
   639 	} // End of function.
       
   640 
       
   641 
       
   642 TPtrC	CUpsClientStep::TUpsDecisionToString(TUpsDecision aDecision)
       
   643 	{
       
   644 	if(aDecision == EUpsDecYes)
       
   645 		{
       
   646 		return _L("Yes");
       
   647 		}
       
   648 	else if(aDecision == EUpsDecNo)
       
   649 		{
       
   650 		return _L("No");
       
   651 		}
       
   652 	else if(aDecision == EUpsDecSessionYes)
       
   653 		{
       
   654 		return _L("SessionYes");
       
   655 		}
       
   656 	else if(aDecision == EUpsDecSessionNo)
       
   657 		{
       
   658 		return _L("SessionNo");
       
   659 		}
       
   660 	else 
       
   661 		{
       
   662 		return _L("Undefined");
       
   663 		}
       
   664 	} // End of function.
       
   665 
       
   666 
       
   667 TInt CUpsClientStep::ButtonToInt(const TPtrC& aButton)
       
   668 	{
       
   669 	if(aButton.CompareF(_L("Yes"))==0)
       
   670 		{
       
   671 		return KYes;
       
   672 		}
       
   673 	else if(aButton.CompareF(_L("No"))==0)
       
   674 		{
       
   675 		return KNo;
       
   676 		}
       
   677 	else if(aButton.CompareF(_L("Always"))==0)
       
   678 		{
       
   679 		return KAlways;
       
   680 		}
       
   681 	else if(aButton.CompareF(_L("SessionYes"))==0)
       
   682 		{
       
   683 		return KSessionYes;
       
   684 		}
       
   685 	else if(aButton.CompareF(_L("SessionNo"))==0)
       
   686 		{
       
   687 		return KSessionNo;
       
   688 		}
       
   689 	else if(aButton.CompareF(_L("Never"))==0)
       
   690 		{
       
   691 		return KNever;
       
   692 		}
       
   693 	else return KNone;
       
   694 				
       
   695 	}  // End of function.
       
   696 
       
   697 
       
   698 TBool CUpsClientStep::CheckResultsL(TInt aIndex)
       
   699 	{
       
   700 	TBool theReturn = ETrue; 
       
   701 	
       
   702 	if(iArraySersToRequest[aIndex].iExpectedError == KErrNone)   
       
   703 		{
       
   704 		TUpsDecision expectedDecision = StringToTUpsDecision(iArraySersToRequest[aIndex].iAccessGranted);
       
   705 		if(expectedDecision != iReturnData.iDecision)
       
   706 	 		{
       
   707 	 		TPtrC decisionReceived(TUpsDecisionToString(iReturnData.iDecision));
       
   708 	 		ERR_PRINTF4(_L("%S: Decision expected: %S ,Decision received: %S"),&iTEFServerName, &iArraySersToRequest[aIndex].iAccessGranted, &decisionReceived);  
       
   709 	 		theReturn=EFalse;	
       
   710 	 		}		
       
   711 		}
       
   712 
       
   713  	if(iArraySersToRequest[aIndex].iExpectedError != iReturnData.iError) 
       
   714  		{
       
   715  		// Incorrect error code returned.
       
   716  		theReturn=EFalse;
       
   717  		ERR_PRINTF3(_L("%S: Error code expected: %d"),&iTEFServerName,iArraySersToRequest[aIndex].iExpectedError);
       
   718  		ERR_PRINTF3(_L("%S: Error code Received: %d"),&iTEFServerName,iReturnData.iError);
       
   719  		}
       
   720  	
       
   721  	// checks returned properties from dialog creator & policy evaluator.
       
   722  	if ( CheckDialogCreatorResultsL(aIndex) == EFalse || CheckPolicyEvaluatorResultsL(aIndex) == EFalse)
       
   723  		{
       
   724  			theReturn = EFalse;
       
   725  		}
       
   726 
       
   727  	// display the request duration and check against the ini file value, if supplied
       
   728 	INFO_PRINTF3(_L("%S: UPS decision request duration: %u milliseconds"),&iTEFServerName, iReturnData.iRequestDuration);
       
   729 	if (iArraySersToRequest[aIndex].iRequestDurationThreshold > 0)
       
   730 		{
       
   731 		// check whether the request duration was too long
       
   732 		if (static_cast<TInt>(iReturnData.iRequestDuration) > iArraySersToRequest[aIndex].iRequestDurationThreshold)
       
   733 			{
       
   734 	 		ERR_PRINTF3(_L("%S: UPS decision request took too long: %u"), &iTEFServerName, iArraySersToRequest[aIndex].iRequestDurationThreshold);
       
   735 	 		theReturn = EFalse;
       
   736 			}
       
   737 		}
       
   738 
       
   739 	return theReturn;
       
   740 	}  // End of function.
       
   741 
       
   742 
       
   743 TBool CUpsClientStep::CheckDialogCreatorResultsL(TInt aIndex)
       
   744 	{
       
   745 	TBool checkPassed = ETrue;
       
   746 	
       
   747 	// checks return properties from dialog creator.
       
   748  	if (iArraySersToRequest[aIndex].iDialogCreatorInvoked != 0)
       
   749 		{
       
   750 		TInt instanceDia = iArraySersToRequest[aIndex].iDialogCreatorInvoked;
       
   751 		TInt dialogError = 0;
       
   752 		iPropertyReader->GetL(instanceDia,KDc_Error,CUpsProperty::EDialogCreator, dialogError);
       
   753 		
       
   754 		// Checks that any error encountered by dialog creator is transmited by UPS to system server
       
   755 		if(dialogError != iReturnData.iError && dialogError!=KErrNone)
       
   756 			{
       
   757 			ERR_PRINTF3(_L("%S: Dialog creator found an error: %d"),&iTEFServerName,dialogError);
       
   758 			checkPassed = EFalse; 	
       
   759 			}
       
   760 		
       
   761 		TInt clientSidDia=0;
       
   762 		iPropertyReader->GetL(instanceDia,KDc_ClientSid,CUpsProperty::EDialogCreator, clientSidDia);
       
   763 	     
       
   764 	    if(iExpectedClientSid != clientSidDia)
       
   765 		    {
       
   766 		    ERR_PRINTF2(_L("%S: Client SID returned by dialog creator is not what is expected"),&iTEFServerName);
       
   767 			checkPassed = EFalse;
       
   768 		    }
       
   769 	    
       
   770 	    TInt buttonsDisplayed=0;
       
   771 		iPropertyReader->GetL(instanceDia,KDc_UpsRequestedButtons,CUpsProperty::EDialogCreator, buttonsDisplayed);
       
   772 	    TInt32 expectedButtonsDisplayed=iArraySersToRequest[aIndex].iButtonsDisplayed;
       
   773 	    if(expectedButtonsDisplayed != buttonsDisplayed)
       
   774 		    {
       
   775 		   	ERR_PRINTF2(_L("%S: Incorrect buttons displayed."),&iTEFServerName);
       
   776 		   	ERR_PRINTF3(_L("%S: Buttons displayed expected: %d"),&iTEFServerName,expectedButtonsDisplayed);
       
   777 		   	ERR_PRINTF3(_L("%S: Buttons displayed received: %d"),&iTEFServerName,buttonsDisplayed);
       
   778 			checkPassed = EFalse;
       
   779 		    }
       
   780 	    
       
   781 	    TInt serverSidDia=0;
       
   782 		iPropertyReader->GetL(instanceDia,KDc_ServerSid,CUpsProperty::EDialogCreator, serverSidDia);
       
   783 	     
       
   784 	    if(iServerId != serverSidDia)
       
   785 		    {
       
   786 		   	ERR_PRINTF2(_L("%S: Server SID returned by dialog creator is not what is expected"),&iTEFServerName);
       
   787 			checkPassed = EFalse;
       
   788 		    } 
       
   789 	    
       
   790 	    TInt serviceSidDia=0;
       
   791 		iPropertyReader->GetL(instanceDia,KDc_ServiceId,CUpsProperty::EDialogCreator, serviceSidDia);
       
   792 		if(serviceSidDia != iArraySersToRequest[aIndex].iServiceUID)
       
   793 		    {
       
   794 		   	ERR_PRINTF3(_L("%S: Service ID reported by dialog creator is not what is expected: %d"),&iTEFServerName,serviceSidDia);
       
   795 			checkPassed = EFalse;
       
   796 		    }  
       
   797 		}
       
   798 	
       
   799 	return checkPassed;
       
   800 	}  // End of function.
       
   801 
       
   802 
       
   803 TBool CUpsClientStep::CheckPolicyEvaluatorResultsL(TInt aIndex)
       
   804 	{
       
   805 	TBool checkPassed = ETrue;
       
   806 	
       
   807 	if (iArraySersToRequest[aIndex].iPolicyEvaluatorInvoked != 0)
       
   808 		{
       
   809 		TInt instanceEva = iArraySersToRequest[aIndex].iPolicyEvaluatorInvoked;
       
   810 		TInt evaluatorError = 0;
       
   811 		
       
   812 		// Checks that any error encountered by policy evaluator is transmited by UPS to system server
       
   813 		iPropertyReader->GetL(instanceEva,KPe_Error,CUpsProperty::EPolicyEvaluator, evaluatorError);
       
   814 		if(evaluatorError != iReturnData.iError && evaluatorError!=KErrNone)
       
   815 			{
       
   816 			ERR_PRINTF3(_L("%S: Policy evaluator found an error: %d"),&iTEFServerName,evaluatorError);
       
   817 			checkPassed = EFalse; 	
       
   818 			}
       
   819 		
       
   820 		TInt clientSidEva=0;
       
   821 		iPropertyReader->GetL(instanceEva,KPe_ClientSid,CUpsProperty::EPolicyEvaluator, clientSidEva);
       
   822 	     
       
   823 	    if(iExpectedClientSid != clientSidEva)
       
   824 		    {
       
   825 		   	ERR_PRINTF2(_L("%S: Client SID returned by policy evaluator is not what is expected"),&iTEFServerName);
       
   826 			checkPassed = EFalse;
       
   827 		    }
       
   828 	    
       
   829 	    TInt serverSidEva=0;
       
   830 		iPropertyReader->GetL(instanceEva,KPe_ServerSid,CUpsProperty::EPolicyEvaluator, serverSidEva);
       
   831 	     
       
   832 	    if(iServerId != serverSidEva)
       
   833 		    {
       
   834 		   	ERR_PRINTF2(_L("%S: Server SID returned by policy evaluator is not what is expected"),&iTEFServerName);
       
   835 			checkPassed = EFalse;
       
   836 		    } 
       
   837 	    
       
   838 	    TInt serviceSidEva = 0;
       
   839 		iPropertyReader->GetL(instanceEva,KPe_ServiceId,CUpsProperty::EPolicyEvaluator, serviceSidEva);
       
   840 		if(serviceSidEva != iArraySersToRequest[aIndex].iServiceUID)
       
   841 		    {
       
   842 		   	ERR_PRINTF3(_L("%S: Service ID reported by policy evaluator is not what is expected: %d"),&iTEFServerName,serviceSidEva);
       
   843 			checkPassed = EFalse;
       
   844 		    }
       
   845 	    if( iArraySersToRequest[aIndex].iForcePrompt)
       
   846 		    {
       
   847 	    	// Read evaluator info
       
   848 	    	TInt evaluatorInfo = 0;
       
   849 			iPropertyReader->GetL(instanceEva,KPe_EvaluatorInfo,CUpsProperty::EPolicyEvaluator, evaluatorInfo);
       
   850 	    	if(evaluatorInfo != iArraySersToRequest[aIndex].iExpectedEvaluatorInfo)
       
   851 	    		{
       
   852 	    		ERR_PRINTF4(_L("%S: incorrect evaluator info:Expected: %d Received: %d"),&iTEFServerName,iArraySersToRequest[aIndex].iExpectedEvaluatorInfo,evaluatorInfo);
       
   853 	    		checkPassed = EFalse;
       
   854 	    		}
       
   855 		    }
       
   856 		}
       
   857 		
       
   858 	return checkPassed;
       
   859 	}  // End of function.
       
   860 
       
   861 
       
   862 void  CUpsClientStep::WaitThatFileAppearsL(const TDesC& aFileName)
       
   863 	{
       
   864 	RFs aFs;
       
   865 	aFs.Connect();
       
   866 						
       
   867 	RProperty checkSwiState;
       
   868 	
       
   869 	User::LeaveIfError(checkSwiState.Attach(KUidSystemCategory, Swi::KUidSoftwareInstallKey));
       
   870 	CleanupClosePushL(checkSwiState);
       
   871 	
       
   872     TRequestStatus swiStatus;
       
   873     TInt swisState;
       
   874 
       
   875   	while(ETrue)
       
   876 		{
       
   877 		checkSwiState.Subscribe(swiStatus);
       
   878 		checkSwiState.Get(KUidSystemCategory,Swi::KUidSoftwareInstallKey, swisState);
       
   879 		if(((swisState & Swi::KSwisOperationMask) == Swi::ESwisNone) && BaflUtils::FileExists(aFs,aFileName))
       
   880 	 		{
       
   881 	 		checkSwiState.Cancel();
       
   882 	 		break;
       
   883 	 		}
       
   884 		User::WaitForRequest(swiStatus);
       
   885 		}
       
   886 
       
   887 	CleanupStack::PopAndDestroy(&checkSwiState);
       
   888 
       
   889 	//Wait for swiobserver to shutdown
       
   890     while(ETrue)
       
   891 	    {
       
   892 		_LIT(KSWIObserverName,"swiobserver.exe*");	    
       
   893 	    TFindProcess finder(KSWIObserverName);       
       
   894 	    TFullName result;
       
   895 	     if (KErrNone != finder.Next(result))
       
   896 	         {
       
   897 	         break;         
       
   898 	         }
       
   899 		User::After(4000);
       
   900 	    }
       
   901 	}  // End of function.