/*******************************************************************************
********************************************************************************
**
**  Copyright(c) 2022, Alliance for Automotive Innovation
**  Used only under license from the Alliance for Automotive Innovation. All Rights Reserved.
**
**  Project:  J1699-3
**  FileName: TestToVerifyPermanentCodes.c
**  Author:   EnGenius
**  Date:     2/25/2022
**  Email:    <support@autosinnovate.org>
**
**  Purpose:  SAE J1699-3 Vehicle OBD II Compliance Test Cases Source Code.
**            This source code is intended to run the tests described in
**            the SAE J1699-3 document in an automated manner, when compiled
**            and used with an SAE J2534-compatible pass-thru device.
**
**            File j1699.c contains information on building and running this test.
**
**  Description:
**
**  Modifications:  12/07/2022  Initial Version
**
********************************************************************************
*******************************************************************************/

#include <stdio.h>    // C Library input and output declarations
#include <stdlib.h>   // C Library general function declarations
#include <string.h>   // C Library character array declarations
#include <time.h>     // C Library time and date declarations
#include <windows.h>  // Windows API declarations
#include "j2534.h"    // j1699 project j2534 declarations
#include "j1699.h"    // j1699 project general declarations


// Function Prototypes
extern STATUS VerifyIPTData ( BOOL *pbIPTSupported );
extern STATUS LogInf12 ( void );
extern STATUS RunDynamicTest10 ( unsigned long EngineStartTimestampMsecs );
extern void   AllocateMemoryForTest10_InUseCounters ( void );
extern void   FreeMemoryForTest10_InUseCounters ( void );


/*******************************************************************************
**
**  Function:  Test9_8to21_PermanentCodes
**
**  Purpose:   Run Tests 9.8-21 to read permanent codes
**
*******************************************************************************/
STATUS Test9_8to21_PermanentCodes ( void )
{
	STATUS        eRetCode;

	unsigned long EngineStartTimestampMsecs;
	BOOL          bIptSupported = FALSE;
	BOOL          bSubTestFailed = FALSE;


//*******************************************************************************
//  Test 9.8 - Induce Circuit Fault to Set Pending DTC
//*******************************************************************************
	gTestSubsection = 8;
	gbTestSubsectionFailed = FALSE;

	// Prompt user to induce fault and set pending DTC
	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Induce Circuit Fault to Set Pending DTC)" );

	printf ( "\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Turn key off and induce a failure that will generate a MIL light.\n"
	      "The selected fault must illuminate the MIL within a maximum of\n"
	      "two (for OBD-II) or three (for EOBD/IOBD/OBDBr) driving cycles.\n\n"

	      "NOTE: You may first start the engine and then induce a failure\n"
	      "in order to avoid starting issues.\n" );

	printf ( "\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Start engine or activate propulsion system for Hybrid/PHEV.\n\n"

	      "Let idle for one minute or whatever time it takes to set a pending DTC.\n\n"

	      "NOTE: Some powertrain control systems have engine controls that can start and\n"
	      "stop the engine without regard to ignition position.\n" );

	printf ( "\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Turn ignition OFF (engine OFF) for 30 seconds or longer, as appropriate\n"
	      "for the ECU, and keep failure present.\n" );

	if ( gstUserInput.eComplianceType != US_OBDII &&
	     gstUserInput.eComplianceType != HD_OBD   &&
	     gstUserInput.eComplianceType != CNOBD_NO_IUMPR )
	{
		printf ( "\n\n\n" );
		Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
		      "Start engine or activate propulsion system for Hybrid/PHEV.\n\n"
		      "Let idle for one minute or whatever time it takes to set\n"
		      "a confirmed DTC. The MIL may or may not illuminate on this driving cycle.\n\n"

		      "NOTE: Some powertrain control systems have engine controls that can start and\n"
		      "stop the engine without regard to ignition position.\n" );

		printf ( "\n\n\n" );
		Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
		      "Turn ignition OFF (engine OFF) for 30 seconds or longer, as appropriate\n"
		      "for the ECU, and keep failure present.\n" );
	}

	printf ( "\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Start engine or activate propulsion system for Hybrid/PHEV.\n\n"

	      "Let idle for one minute or whatever time it takes to set\n"
	      "a confirmed DTC and illuminate the MIL.\n\n"

	      "NOTE: Some powertrain control systems have engine controls that can start and\n"
	      "stop the engine without regard to ignition position.\n" );

	printf ( "\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Turn ignition OFF (engine OFF) for 30 seconds or longer, as appropriate\n"
	      "for the ECU, and keep failure present.\n"
	      "(This completes the driving cycle and allows permanent code to be set).\n" );

	printf ( "\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Turn ignition on. DO NOT crank engine.\n" );

	// Engine should now be not running
	gbEngineRunning = FALSE;

	Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );


//*******************************************************************************
//  Test 9.9 - Establish communication, engine off
//*******************************************************************************
	gTestSubsection = 9;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Determine Protocol, Engine Off)" );

	if ( DetermineOBDProtocol ( ) != PASS )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Protocol determination unsuccessful.\n" );
		Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
		return FAIL;
	}

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}


//*******************************************************************************
//  Test 9.10 - Verify Stored DTCs, Engine Off
//*******************************************************************************
	// A Permanent DTC should now be set
	gbDTCPermanent = TRUE;

	gTestSubsection = 10;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Verify Stored DTCs (Service $03), Engine Off)" );

	if ( VerifyStoredDTCData ( ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}


//*******************************************************************************
//  Test 9.11 - Verify stored DTC data, engine off
//*******************************************************************************
	gTestSubsection = 11;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Verify Permanent DTCs (Service $0A), Engine Off)" );

	if ( VerifyPermanentCodeSupport ( ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}


//*******************************************************************************
//  Test 9.12 - induce fault to be able to retrieve Permanent DTC
//*******************************************************************************
	gTestSubsection = 12;
	gbTestSubsectionFailed = FALSE;

	// Prompt user to induce fault to be able to retrieve Permanent DTC
	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Repair Circuit Fault)" );

	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Turn ignition OFF (engine OFF) for 30 seconds or longer, as appropriate\n"
	      "for the ECU." );

	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Connect sensor." );

	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Turn ignition on.  DO NOT crank engine.\n" );

	Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );


//*******************************************************************************
//  Test 9.13 - Establish communication, engine off
//*******************************************************************************
	gTestSubsection = 13;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Determine Protocol and Clear DTCs (Service $04), Engine Off)" );

	if ( DetermineOBDProtocol ( ) != PASS )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Protocol determination unsuccessful.\n" );
		Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
		return FAIL;
	}

	if ( ClearCodes ( ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}


//*******************************************************************************
//  Test 9.14 - Verify MIL status, engine off
//*******************************************************************************
	gTestSubsection = 14;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Verify MIL Status, Engine Off)" );

	if ( VerifyMILData ( ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}


//*******************************************************************************
//  Test 9.15 - Verify stored DTC data, engine off
//*******************************************************************************
	gTestSubsection = 15;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Verify Permanent DTCs (Service $0A), Engine Off)" );

	if ( VerifyPermanentCodeSupport ( ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}


//*******************************************************************************
//  Test 9.16 - repair circuit fault and complete one drive cycle
//*******************************************************************************
	gTestSubsection = 16;
	gbTestSubsectionFailed = FALSE;

	// Prompt user to repair circuit fault and complete one drive cycle
	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Complete One Driving Cycle With Fault Repaired)" );

	printf ( "\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Start engine or activate propulsion system for Hybrid/PHEV.\n\n"

	      "Let idle for one minute or whatever time it takes\n"
	      "to run monitor and detect that there is no malfunction\n"
	      "(Monitor may have already run with engine off).\n\n"

	      "NOTE: Some powertrain control systems have engine controls that can start and\n"
	      "stop the engine without regard to ignition position.\n" );

	printf ( "\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Turn ignition OFF (engine OFF) for 30 seconds or longer, as appropriate\n"
	      "for the ECU.\n"
	      "(This completes one driving cycle with no fault).\n" );

	printf  ("\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Start engine or activate propulsion system for Hybrid/PHEV.\n\n"

	      "REMAIN AT IDLE until directed to start drive cycle\n" );

	EngineStartTimestampMsecs = GetTickCount ( );

	printf ( "\n\n\n" );
	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Continue to idle until the ECU detects that there is no malfunction.\n"
	      "(This starts the second driving cycle; however, second driving cycle\n"
	      "will not be complete until key is turned off.)\n\n"

	      "NOTE: Some powertrain control systems have engine controls that can start and\n"
	      "stop the engine without regard to ignition position.\n" );

	// Engine should now be running
	gbEngineRunning = TRUE;

	Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );


//*******************************************************************************
//  Test 9.17 - Establish communication, engine running
//*******************************************************************************
	gTestSubsection = 17;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Determine Protocol, Engine Running)" );

	if ( DetermineOBDProtocol ( ) != PASS )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Protocol determination unsuccessful.\n" );
		Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
		return FAIL;
	}

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}


//*******************************************************************************
//  Test 9.18 - Verify stored DTC data, engine off
//*******************************************************************************
	// A Permanent DTC should now be set
	gbDTCPermanent = TRUE;

	gTestSubsection = 18;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Verify Permanent DTCs (Service $0A), Engine Running)" );

	if ( VerifyPermanentCodeSupport ( ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}


//*******************************************************************************
//  Test 9.19 - Complete Permanent Code Drive Cycle
//*******************************************************************************
	gTestSubsection = 19;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Complete Permanent Code Drive Cycle)" );

	// Initialize Array
	AllocateMemoryForTest10_InUseCounters ( );

	if ( VerifyIPTData ( &bIptSupported ) != PASS || gbTestSubsectionFailed == TRUE )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		          "Unable to capture Initial OBDCOND and IGNCNT.\n" ) == 'N' )
		{
			Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );

			// free memory for IPT Arrays
			FreeMemoryForTest10_InUseCounters ( );

			return FAIL;
		}

		bSubTestFailed = TRUE;
		gbTestSubsectionFailed = FALSE;
	}

	if ( gbPlugIn )
	{
		if ( LogInf12 (  ) != PASS )
		{
			bSubTestFailed = TRUE;
		}
	}

	// stop tester-present message
	StopPeriodicMsg ( TRUE );
	Sleep ( gRequestDelayTimeMsecs );

	gbSuspendScreenOutput = TRUE;
	eRetCode = RunDynamicTest10 ( EngineStartTimestampMsecs );
	gbSuspendScreenOutput = FALSE;

	// free memory for IPT Arrays
	FreeMemoryForTest10_InUseCounters ( );

	// re-start tester-present message
	StartPeriodicMsg ( );

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( eRetCode == FAIL || gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Errors detected during dynamic test.  View Logfile for more details.\n" );

		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}

	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Stop the vehicle in a safe location and turn the ignition off.\n" );

	// Engine should now be not running
	gbEngineRunning = FALSE;


//*******************************************************************************
//  Test 9.20 -
//*******************************************************************************
	gTestSubsection = 20;
	gbTestSubsectionFailed = FALSE;

	// Prompt user to induce fault to be able to retrieve Permanent DTC
	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Key On)" );

	Log ( PROMPT, SCREENOUTPUTON, LOGOUTPUTON, ENTER_PROMPT,
	      "Turn ignition on and Start engine or activate propulsion system for Hybrid/PHEV.\n" );

	// Engine should now be  running
	gbEngineRunning = TRUE;

	Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );


//*******************************************************************************
//  Test 9.21 - Establish communication, engine off
//*******************************************************************************
	// there should no longer be a Permanent DTC set
	gbDTCPermanent = FALSE;

	gTestSubsection = 21;
	gbTestSubsectionFailed = FALSE;
	bSubTestFailed = FALSE;

	Log ( SUBSECTION_BEGIN, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "(Determine Protocol, Engine Running)" );

	if ( DetermineOBDProtocol ( ) != PASS )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Protocol determination unsuccessful.\n" );
		Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
		return FAIL;
	}

	if ( VerifyVehicleState ( gbEngineRunning, gbHybrid ) != PASS )
	{
		bSubTestFailed = TRUE;
	}

	if ( gbTestSubsectionFailed == TRUE || bSubTestFailed == TRUE )
	{
		if ( Log ( SUBSECTION_FAILED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT, "" ) == 'N' )
		{
			return FAIL;
		}
	}
	else
	{
		Log ( SUBSECTION_PASSED_RESULT, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT, "" );
	}

	return PASS;
}
