/*******************************************************************************
********************************************************************************
**
**  Copyright(c) 2022, Alliance for Automotive Innovation
**  Used only under license from the Alliance for Automotive Innovation. All Rights Reserved.
**
**  Project:  J1699-3
**  FileName: VerifyDiagnosticSupportAndData.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
STATUS DetermineVariablePidSize ( void );
STATUS VerifyPid01 ( PID *pPid, BYTE EcuIdx, unsigned long *pfIMBitsSupported );
STATUS VerifyPid1C ( PID *pPid, BYTE EcuIdx );
STATUS VerifyPid41 ( PID *pPid, BYTE EcuIdx, BOOL bEngineDontCare );
STATUS GetPid4FArray ( void );
STATUS GetPid50Array ( void );
void   GetHoursMinsSecs ( unsigned long time, unsigned long *pHours, unsigned long *pMins, unsigned long *pSecs );


// Variables
#define MAX_PIDS 0x100


// SID $01 PID $01 Bit defines - for tracking support when
// 'at least one ECU' must have these bits set
#define DATA_B_BIT_0 0x00010000
#define DATA_B_BIT_1 0x00020000
#define DATA_B_BIT_2 0x00040000
#define DATA_B_BIT_3 0x00080000
#define DATA_C_BIT_0 0x00000100
#define DATA_C_BIT_1 0x00000200
#define DATA_C_BIT_2 0x00000400
#define DATA_C_BIT_3 0x00000800
#define DATA_C_BIT_5 0x00002000
#define DATA_C_BIT_6 0x00004000
#define DATA_C_BIT_7 0x00008000


/*******************************************************************************
**  OBD type definitions
*******************************************************************************/
// maximum number of OBD types for SID $01 PID $1C
#define MAX_OBD_TYPES        43
const char *szOBD_TYPE[MAX_OBD_TYPES] =
{
	"UNKNOWN",                      // 0x00
	"OBD II",                       // 0x01
	"OBD",                          // 0x02
	"OBD and OBDII",                // 0x03
	"OBD I",                        // 0x04
	"NO OBD",                       // 0x05
	"EOBD",                         // 0x06
	"EOBD and OBD II",              // 0x07
	"EOBD and OBD",                 // 0x08
	"EOBD, OBD, and OBD II",        // 0x09
	"JOBD",                         // 0x0A
	"JOBD and OBD II",              // 0x0B
	"JOBD and EOBD",                // 0x0C
	"JOBD, EOBD, and OBD II",       // 0x0D
	"OBD, EOBD, and KOBD",          // 0x0E
	"OBD, OBDII, EOBD, and KOBD",   // 0x0F
	"reserved",                     // 0x10
	"EMD",                          // 0x11
	"EMD+",                         // 0x12
	"HD OBD-C",                     // 0x13
	"HD OBD",                       // 0x14
	"WWH OBD",                      // 0x15
	"reserved",                     // 0x16
	"HD EOBD-I",                    // 0x17
	"HD EOBD-I N",                  // 0x18
	"HD EOBD-II",                   // 0x19
	"HD EOBD-II N",                 // 0x1A
	"reserved",                     // 0x1B
	"OBDBr-1",                      // 0x1C
	"OBDBr-2 and 2+",               // 0x1D
	"KOBD",                         // 0x1E
	"IOBD I",                       // 0x1F
	"IOBD II",                      // 0x20
	"HD EOBD-VI",                   // 0x21
	"OBD, OBDII, and HD OBD",       // 0x22
	"OBDBr-3",                      // 0x23
	"Motorcycle, Euro OBD-I",       // 0x24
	"Motorcycle, Euro OBD-II",      // 0x25
	"Motorcycle, China OBD-I",      // 0x26
	"Motorcycle, Taiwan OBD-I",     // 0x27
	"Motorcycle, Japan OBD-I",      // 0x28
	"China Nationwide Stage 6",     // 0x29
	"Brazil OBD Diesel"             // 0x2A
};


/************************
**  Fuel type definitions
************************/
#define MAX_FUELTYPE_LENGTH 10
const char *szFUEL_TYPE[] =
{
	"NONE",      // 00 Not Available
	"GAS",       // 01 Gasoline
	"METH",      // 02 Methanol
	"ETH",       // 03 Ethanol
	"DSL",       // 04 Diesel
	"LPG",       // 05 Liquefied Petroleum Gas
	"CNG",       // 06 Compressed Natural Gas
	"PROP",      // 07 Propane
	"ELEC",      // 08 Battery/Electric
	"BI_GAS",    // 09 Bi-fuel vehicle using gasoline
	"BI_METH",   // 0A Bi-fuel vehicle using methanol
	"BI_ETH",    // 0B Bi-fuel vehicle using ethanol
	"BI_LPG",    // 0C Bi-fuel vehicle using LPG
	"BI_CNG",    // 0D Bi-fuel vehicle using CNG
	"BI_PROP",   // 0E Bi-fuel vehicle using propane
	"BI_ELEC",   // 0F Bi-fuel vehicle using battery [Not to be used]
	"BI_MIX",    // 10 Bi-fuel vehicle using battery and combustion engine [Not to be used]
	"HYB_GAS",   // 11 Hybrid vehicle using gasoline engine [Not to be used]
	"HYB_ETH",   // 12 Hybrid vehicle using gasoline engine on ethanol [Not to be used]
	"HYB_DSL",   // 13 Hybrid vehicle using diesel engine [Not to be used]
	"HYB_ELEC",  // 14 Hybrid vehicle using battery [Not to be used]
	"HYB_MIX",   // 15 Hybrid vehicle using battery and combustion engine [Not to be used]
	"HYB_REG",   // 16 Hybrid vehicle in regeneration mode [Not to be used]
	"NOT_USED",  // 17 (Bi-fuel vehicle using diesel) or (Natural Gas) (as defined in J1979) [Not to be used]
	"BI_NG",     // 18 Bi-fuel vehicle using Natural Gas
	"BI_DSL",    // 19 Bi-fuel vehicle using diesel
	"NG",        // 1A Natural Gas (Compressed or Liquefied Natural Gas)
	"DSL_CNG",   // 1B Dual Fuel � Diesel and CNG
	"DSL_LNG",   // 1C Dual Fuel � Diesel and LNG
	"FC_H2",     // 1D Fuel cell utilizing hydrogen
	"HICE_HHO",  // 1E Hydrogen Internal Combustion Engine
	"KERO",      // 1F Kerosene
	"RESERVED"   // 20 -FF RESERVED
};


/************************
**  Gear definitions
************************/
const char *szGEAR[] =
{
	"NEUTRAL",      // 00 Neutral
	"GEAR 1",
	"GEAR 2",
	"GEAR 3",
	"GEAR 4",
	"GEAR 5",
	"GEAR 6",
	"GEAR 7",
	"GEAR 8",
	"GEAR 9",
	"GEAR 10",
	"GEAR 11",
	"GEAR 12",
	"GEAR 13",
	"GEAR 14",
	"GEAR 15"
};


/************************
**  Gear definitions
************************/
const char *szCON_STATUS[] =
{
	"RESERVED",      // 00 reserved
	"OPEN LOOP",
	"CLOSED LOOP",
	"FAULT"
};


unsigned int  gVariablePidSize = 0;
BYTE Pid4F[MAX_ECUS][4];
BYTE Pid50[MAX_ECUS][4];


/*******************************************************************************
**
**  Function:  VerifyPidSupportAndData
**
**  Purpose:   Verify PID diagnostic support and data
**
*******************************************************************************/
STATUS VerifyPidSupportAndData ( BOOL bEngineDontCare )
{
	REQ_MSG       stReqMsg;
	PID          *pPid;
	BYTE          EcuIdx;

	unsigned long IdIdx;
	unsigned long InitialFailureCount = 0;
	unsigned long TempFailureCount = 0;
	long          TempData_long;
	float         TempData_float;
	float         Temp_EGR_CMD;
	float         Temp_EGR_ACT;
	unsigned int  BSIndex;
	BOOL          bPid13Supported = FALSE;      // set if the current ECU supports PID $13
	BOOL          bPid1DSupported = FALSE;      // set if the current ECU supports PID $1D
	BOOL          bPid4FSupported = FALSE;      // set if the current ECU supports PID $4F
	BOOL          bPid50Supported = FALSE;      // set if the current ECU supports PID $50
	BOOL          bReqPidNotSupported = FALSE;  // set if a required PID is not supported
	BOOL          bPidSupported[MAX_PIDS+1];    // an array of PIDs (TRUE if PID is supported)

	// PID $01 is different as we must track support for specific bits.
	// In this case, the ULONG will be structured so that DATA_A is the
	// most significant byte and DATA_D is the least significant byte (i.e., AABBCCDD)
	unsigned long IMBitSupportFlags = 0;        // holds the PID 01 IM bits supported by the vehicle
	BOOL          bPid9FSuccess = FALSE;
	unsigned long hours;
	unsigned long mins;
	unsigned long secs;


	InitialFailureCount = GetFailureCount ( );

	// Read SID 1 PID support PIDs
	if ( RequestIDSupportData ( PIDREQUEST, FALSE ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems verifying PID supported data.\n" ) == 'N' )
		{
			return FAIL;
		}
	}

	// Verify ECU did not drop out
	if ( VerifyECUCommunication ( ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems verifying link active.\n" ) == 'N' )
		{
			return FAIL;
		}
	}

	// Determine size of PIDs $06, $07, $08, $09
	if ( DetermineVariablePidSize ( ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems determining the size of variable PIDs.\n" ) == 'N' )
		{
			return FAIL;
		}
	}

	if ( GetPid4FArray ( ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems getting PID $4F.\n" ) == 'N' )
		{
			return FAIL;
		}
	}

	if ( GetPid50Array ( ) != PASS )
	{
		if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
		           "Problems getting PID $50.\n" ) == 'N' )
		{
			return FAIL;
		}
	}


	// For each PID
	for ( IdIdx = 0x01;
	      IdIdx < MAX_PIDS;
	      IdIdx++ )
	{
		// clear PID supported indicator
		bPidSupported[IdIdx] = FALSE;

		// skip PID supported PIDs
		// and unsupported PIDs
		if ( IdIdx == 0x20 || IdIdx == 0x40 ||
		     IdIdx == 0x60 || IdIdx == 0x80 ||
		     IdIdx == 0xA0 || IdIdx == 0xC0 ||
		     IdIdx == 0xE0 ||
		     IsIDSupported ( ALLECUS, PIDREQUEST, IdIdx ) == FALSE )
		{
			continue;  // just go to the next itteration of the PID for loop
		}

		stReqMsg.SID    = 0x01;
		stReqMsg.NumIds = 1;
		stReqMsg.ID[0]  = (BYTE)IdIdx;
		if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			// There must be a response for ISO15765 protocol
			if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $01 PID $%02X request\n",
				      IdIdx );
				continue;  // just go to the next itteration of the PID for loop
			}
		}

		// check each ECU for data in it's reaponse
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( gstResponse[EcuIdx].PidSize != 0 )
			{
				break;  // leave ECU for loop
			}
		}

		// if none of the ECUs have any data for this PID, go to the next one
		if ( EcuIdx >= gNumOfECUs )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "No SID $01 PID $%02X data\n",
			      IdIdx );
			continue;  // just go to the next itteration of the PID for loop
		}

		// get Failure Count to allow for FAILURE checks from this point on
		TempFailureCount = GetFailureCount ( );

		// Verify that all SID 1 PID data is valid
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			// Set ECU dependent PID flags
			bPid13Supported = IsIDSupported ( EcuIdx, PIDREQUEST, 0x13 );
			bPid1DSupported = IsIDSupported ( EcuIdx, PIDREQUEST, 0x1D );
			bPid4FSupported = IsIDSupported ( EcuIdx, PIDREQUEST, 0x4F );
			bPid50Supported = IsIDSupported ( EcuIdx, PIDREQUEST, 0x50 );

			// If PID is supported, check it
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, IdIdx ) == TRUE )
			{
				// Check the data to see if it is valid
				pPid = (PID *)&gstResponse[EcuIdx].Pid[0];
				if ( gstResponse[EcuIdx].PidSize == 0 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  PID $%02X supported but no data\n",
					      GetEcuId ( EcuIdx ),
					      IdIdx );
				}

				else
				{
					// save indication that PID is supported
					bPidSupported[IdIdx] = TRUE;

					// Check various PID values for validity based on vehicle state
					switch ( pPid->ID )
					{
						case 0x01:
						{
							// Store the response from PID $01
							// for use with SID 01 PID 41 and
							// SID $06 MID verification logic
							memcpy ( &gstEcuSIDData[EcuIdx].Pid01.ID,
							         pPid,
							         sizeof ( PID ) );

							if ( bEngineDontCare == FALSE ) // NOT Test 10.2
							{
								if ( VerifyPid01 ( pPid, EcuIdx, &IMBitSupportFlags) != PASS )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "SID $01 PID $01 failures detected.\n" );
								}
							}
						}
						break;

						case 0x02:
						{
							TempData_long = (pPid->Data[0] << 8) +
							                 pPid->Data[1];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $02  DTCFRZF  = $%04X\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE && gbEngineWarm == FALSE )  // test 5.6 & 5.10
							{
								if ( pPid->Data[0] != 0x00 ||
								     pPid->Data[1] != 0x00 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  DTCFRZF Not 0 (Freeze frames should not be available)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x03:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $03  FUELSYSA = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Fuel System A Status bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL          = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CL          = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL-Drive    = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL-Fault    = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CL-Fault    = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL_B2       = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL-Drive_B2 = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL-Fault_B2 = %s\n",
							      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $03  FUELSYSB = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[1] );
							// Fuel System B Status bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL          = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CL          = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL-Drive    = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL-Fault    = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CL-Fault    = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL_B2       = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL-Drive_B2 = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  OL-Fault_B2 = %s\n",
							      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							if ( bEngineDontCare == FALSE && gbEngineRunning == FALSE &&  // if Test 5.6 AND
							     ((pPid->Data[0] & 0x02) != 0 ||                      // FUELSYSA Closed Loop OR
							      (pPid->Data[1] & 0x02) != 0) )                      // FUELSYSB Closed Loop
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FUELSYSA Bit 1 and FUELSYSB Bit 1 must both be 0 (not Closed Loop)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x04:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $04  LOAD_PCT = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
								{
									if ( gbHybrid != TRUE )
									{
										// don't range check hybrids at idle, as LOAD_PCT could be up to 100%
										if ( TempData_float == 0 || TempData_float > 60 )
										{
											// Load should be 60% or less with engine running
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  LOAD_PCT should be 60 %% or less (but not 0) with engine running\n\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
								else  // test 5.6
								{
									if ( TempData_float != 0 )
									{
										// There should be no load with the engine OFF
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  LOAD_PCT > 0 %% (There should be no load with the engine OFF)\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x05:
						{
							TempData_long = pPid->Data[0] - 40;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $05  ECT      = %d C\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( TempData_long < -20 || TempData_long > 120 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  ECT outside expected range (-20 to 120)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x06:
						{
							TempData_float = (float)(pPid->Data[0]) * (float)(100.0/128.0) - (float)100.0;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $06  SHRTFT1  = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
							{
								if ( TempData_float < -50.0 || TempData_float > 50.0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  SHRTFT1 outside expected range (-50 to 50)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( gVariablePidSize == 2 )
							{
								TempData_float = (float)(pPid->Data[1]) * (float)(100.0/128.0) - (float)100.0;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $06  SHRTFT3  = %.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
								{
									if ( TempData_float < -50.0 || TempData_float > 50.0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  SHRTFT3 outside expected range (-50 to 50)\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x07:
						{
							TempData_float = (float)(pPid->Data[0]) * (float)(100.0/128.0) - (float)100.0;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $07  LONGFT1  = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
							{
								if ( TempData_float < -50.0 || TempData_float > 50.0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  LONGFT1 outside expected range (-50 to 50)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( gVariablePidSize == 2 )
							{
								TempData_float = (float)(pPid->Data[1]) * (float)(100.0/128.0) - (float)100.0;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $07  LONGFT3  = %.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
								{
									if ( TempData_float < -50.0 || TempData_float > 50.0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  LONGFT3 outside expected range (-50 to 50)\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x08:
						{
							TempData_float = (float)(pPid->Data[0]) * (float)(100.0/128.0) - (float)100.0;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $08  SHRTFT2  = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
							{
								if ( TempData_float < -50.0 || TempData_float > 50.0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  SHRTFT2 outside expected range (-50 to 50)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( gVariablePidSize == 2 )
							{
								TempData_float = (float)(pPid->Data[1]) * (float)(100.0/128.0) - (float)100.0;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $08  SHRTFT4  = %.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
								{
									if ( TempData_float < -50.0 || TempData_float > 50.0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  SHRTFT4 outside expected range (-50 to 50)\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x09:
						{
							TempData_float = (float)(pPid->Data[0]) * (float)(100.0/128.0) - (float)100.0;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $09  LONGFT2  = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
							{
								if ( TempData_float < -50.0 || TempData_float > 50.0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  LONGFT2 outside expected range (-50 to 50)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( gVariablePidSize == 2 )
							{
								TempData_float = (float)(pPid->Data[1]) * (float)(100.0/128.0) - (float)100.0;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $09  LONGFT4  = %.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
								{
									if ( TempData_float < -50.0 || TempData_float > 50.0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  LONGFT4 outside expected range (-50 to 50)\n",
										       GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x0A:
						{
							TempData_long = pPid->Data[0] * 3;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $0A  FRP      = %u kPa\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
							{
								if ( TempData_long == 0 && gbHybrid != TRUE )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FRP must be greater than 0\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x0B:
						{
							TempData_float = (float)(pPid->Data[0]);
							if ( bPid4FSupported == TRUE && Pid4F[EcuIdx][3]!=0 )
							{
								TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][3]*10)/255);
							}
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $0B  MAP      = %.1f kPa\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
							{
								if ( TempData_float == 0.0 && gbHybrid != TRUE )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  MAP should be greater than 0\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x0C:
						{
							TempData_long = ((pPid->Data[0] << 8) +
							                  pPid->Data[1]) / 4;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $0C  RPM      = %d rpm\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
								{
									// if idle RPM is outside the reasonable range
									if ( TempData_long > 2000 || TempData_long < 300 )
									{
										// Gas, Deisel vehicle
										if ( gbHybrid == FALSE )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  RPM outside expected range (300 - 2000)\n",
											      GetEcuId ( EcuIdx ) );
										}

										// HEV, PHEV, S/S vehicle
										else if ( TempData_long != 0 )
										{
											if ( TempData_long >= 1 && TempData_long < 300 )
											{
												Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
												      "ECU %X  RPM outside expected range (1 - 300)\n",
												      GetEcuId ( EcuIdx ) );
											}
											else
											{
												Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
												      "ECU %X  RPM outside expected range (1 - 300)\n",
												      GetEcuId ( EcuIdx ) );
											}
										}
									}
								}
								else  // test 5.6
								{
									if ( TempData_long != 0 )
									{
										// There should be no RPM with the engine OFF
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  RPM should be 0 with engine Off\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x0D:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $0D  VSS      = %d km/h\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );

							if ( pPid->Data[0] != 0x00 )
							{
								// There should be no vehicle speed when not moving
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  VSS > 0 km/h (There should be no vehicle speed when not moving)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x0E:
						{
							TempData_float = ((float)pPid->Data[0] / (float)2.0) - (float)64.0;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $0E  SPARKADV = %.1f deg\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
							{
								if ( TempData_float < -35 || TempData_float > 55 )
								{
									if ( gbHybrid == FALSE )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  SPARKADV outside expected range (-35 to 55)\n",
										      GetEcuId ( EcuIdx ) );
									}

									// HEV, PHEV, S/S vehicle
									else
									{
										Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  SPARKADV outside expected range (-35 to 55)\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x0F:
						{
							TempData_long = pPid->Data[0] - 40;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $0F  IAT      = %d C\n",
							       GetEcuId ( EcuIdx ),
							       TempData_long );

 							if ( TempData_long < -20 || TempData_long > 120 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  IAT outside expected range (-20 to 120)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x10:
						{
							TempData_float = (float)((pPid->Data[0] << 8) +
							                          pPid->Data[1]);
							if ( bPid50Supported == TRUE && Pid50[EcuIdx][0] != 0 )
							{
								TempData_float = TempData_float * ((float)(Pid50[EcuIdx][0] * 10) / 65535);
							}
							else
							{
								TempData_float = TempData_float / (float)100.0;
							}
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $10  MAF      = %.2f g/s\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
								{
									if ( TempData_float == 0.0 && gbHybrid != TRUE )
									{
										// MAF should not be zero with the engine running
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  MAF should not be zero with the engine running\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
									else  // test 5.6, engine off
								{
									if ( TempData_float > 5.0 )
									{
										// MAF should be zero with the engine OFF
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  MAF should be less than 5 g/s with the engine OFF\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x11:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $11  TP       = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

								if ( gbDiesel == FALSE )
							{
								// non-diesel
								if ( TempData_float > 50 )
								{
									// Throttle position should be 40% or less when not driving
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TP should be 50 %% or less when not driving\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
							else
							{
								// diesel
								if ( TempData_float > 100 )
								{
									// Throttle position should be 100% or less when not driving
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TP should be 100 %% or less when not driving\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x12:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $12  AIR_STAT = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
						}
						break;

						/*
						case 0x13:  See 0x1D
						*/

						case 0x14:
						case 0x15:
						case 0x16:
						case 0x17:
						case 0x18:
						case 0x19:
						case 0x1A:
						case 0x1B:
						{
							switch ( pPid->ID )
							{
								case 0x14:
									BSIndex = 0x11;
								break;
								case 0x15:
									BSIndex = 0x12;
								break;
								case 0x16:
									BSIndex = bPid13Supported ? 0x13 : 0x21;
								break;
								case 0x17:
									BSIndex = bPid13Supported ? 0x14 : 0x22;
								break;
								case 0x18:
									BSIndex = bPid13Supported ? 0x21 : 0x31;
								break;
								case 0x19:
									BSIndex = bPid13Supported ? 0x22 : 0x32;
								break;
								case 0x1A:
									BSIndex = bPid13Supported ? 0x23 : 0x41;
								break;
								case 0x1B:
									BSIndex = bPid13Supported ? 0x24 : 0x42;
								break;
							}

							TempData_float = (float)pPid->Data[0] * (float).005;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $%02X  O2S%x    = %.3f V\n",
							      GetEcuId ( EcuIdx ),
							      pPid->ID,
							      BSIndex,
							      TempData_float );

							TempData_float = ((float)(pPid->Data[1]) * (float)(100.0 / 128.0)) - (float)100.0;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $%02X  SHRTFT%x = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      pPid->ID,
							      BSIndex,
							      TempData_float );
						}
						break;

						case 0x1C:
						{
							if ( VerifyPid1C ( pPid, EcuIdx ) != PASS )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "SID $01 PID $1C failures detected.\n" );
							}
						}
						break;

						case 0x13:
						case 0x1D:
						{
							unsigned short O2Bit;
							unsigned short O2Count;

							// Identify support for PID 0x13 / 0x1D
							if ( pPid->ID == 0x13 )
							{
								bPid13Supported = TRUE;
							}
							else
							{
								bPid1DSupported = TRUE;
							}

							// Evaluate for dual PID / Spark engine support
							if ( bPid13Supported == TRUE &&
							     bPid1DSupported == TRUE )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID 13 & 1D both indicated as supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// Count the number of O2 sensors
							for ( O2Bit = 0x01, O2Count = 0;
							      O2Bit != 0x100;
							      O2Bit = O2Bit << 1 )
							{
								if ( pPid->Data[0] & O2Bit )
								{
									O2Count++;
								}
							}
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $%02X  2SLOC    = $%02X (%d O2 Sensors)\n",
							      GetEcuId ( EcuIdx ),
							      pPid->ID,
							      pPid->Data[0],
							      O2Count );

							// At least 2 O2 sensors required for spark ignition enges
							if ( gbDiesel == FALSE &&
							     O2Count < 2 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  O2S < 2 (At least 2 O2 sensors required for spark ignition enges)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x1E:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $1E  PTO_STAT = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
						}
						break;

						case 0x1F:
						{
							TempData_long = ((pPid->Data[0] << 8) +
							                  pPid->Data[1]);
							GetHoursMinsSecs ( TempData_long, &hours, &mins, &secs );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $1F  RUNTM    = %d sec (%d hrs, %d mins, %d secs)\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long,
							      hours, mins, secs );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineRunning == TRUE )
								{
									if ( gbEngineWarm == TRUE)  // test 10.13
									{
										if ( TempData_long <= 300 )
										{
											// Run time should be greater than 300 seconds
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  RUNTM should be greater than 300 seconds\n",
											      GetEcuId ( EcuIdx ) ,
											      TempData_long );
										}
									}
									else  // test 5.10
									{
										if ( TempData_long == 0 && gbHybrid != TRUE )
										{
											// Run time should not be zero if engine is running
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  RUNTM should not be zero if engine is running\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
								else  // test 5.6
								{
									if ( TempData_long != 0 )
									{
										// Run time should be zero if engine is OFF
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  RUNTM should be zero if engine is OFF\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x21:
						{
							TempData_long = ((pPid->Data[0] << 8) +
							                  pPid->Data[1]);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $21  MIL_DIST = %d km\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( (gbEngineWarm == TRUE      ||            // test 10.12
								      gbEngineRunning == FALSE  ||            // test 5.6
								      (gbEngineRunning == TRUE   &&          // test 5.10
								       gbEngineWarm == FALSE     &&
								       gstResponse[EcuIdx].ClrDTCSize > 0 &&
								       gstResponse[EcuIdx].ClrDTC[0] == 0x44) ) &&
								     TempData_long != 0x00 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  MIL_DIST should not be greater than 0 after clearing DTCs\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x22:
						{
							TempData_float = (float)((pPid->Data[0] << 8) +
							                          pPid->Data[1]) * (float)0.079;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $22  FRP (relative to manifold) = %.1f kPa\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE &&  // NOT Test 10.2
							     gbEngineRunning == TRUE  &&  // test 5.10 & 10.13
							     gbHybrid != TRUE         &&  // not a hybrid vehicle
							     TempData_float == 0.0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FRP should be greater than 0\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x23:
						{
							TempData_long = ((pPid->Data[0] << 8) +
							                  pPid->Data[1]) * 10;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $23  FRP      = %ld kPa\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE &&  // NOT Test 10.2
							     gbEngineRunning == TRUE  &&  // test 5.10 & 10.12
							     gbHybrid    != TRUE      &&  // not a hybrid vehicle
							     TempData_long == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FRP should be greater than 0\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x24:
						case 0x25:
						case 0x26:
						case 0x27:
						case 0x28:
						case 0x29:
						case 0x2A:
						case 0x2B:
						{
							switch ( pPid->ID )
							{
								case 0x24:
									BSIndex = 0x11;
								break;
								case 0x25:
									BSIndex = 0x12;
								break;
								case 0x26:
									BSIndex = bPid13Supported ? 0x13 : 0x21;
								break;
								case 0x27:
									BSIndex = bPid13Supported ? 0x14 : 0x22;
								break;
								case 0x28:
									BSIndex = bPid13Supported ? 0x21 : 0x31;
								break;
								case 0x29:
									BSIndex = bPid13Supported ? 0x22 : 0x32;
								break;
								case 0x2A:
									BSIndex = bPid13Supported ? 0x23 : 0x41;
								break;
								case 0x2B:
									BSIndex = bPid13Supported ? 0x24 : 0x42;
								break;
							}

							TempData_float = (float)((unsigned long)(pPid->Data[0] << 8) +
							                                         pPid->Data[1]);
							if ( bPid4FSupported == FALSE || Pid4F[EcuIdx][0] == 0 )
							{
								TempData_float = TempData_float * (float)0.0000305;
							}
							else
							{
								TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][0])/65535);
							}
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $%02X  EQ_RAT%x = %.3f %%\n",
							      GetEcuId ( EcuIdx ),
							      pPid->ID,
							      BSIndex,
							      TempData_float );

							TempData_float = (float)((unsigned long)(pPid->Data[2] << 8) +
							                                         pPid->Data[3]);
							if ( bPid4FSupported == FALSE || Pid4F[EcuIdx][1] == 0 )
							{
								TempData_float = TempData_float * (float)0.000122;
							}
							else
							{
								TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][1])/65535);
							}
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $%02X  O2S%x    = %.3f V\n",
							      GetEcuId ( EcuIdx ),
							      pPid->ID,
							      BSIndex,
							      TempData_float );
						}
						break;

						case 0x2C:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $2C  EGR_PCT  = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( gbEngineRunning == FALSE )  // test 5.6
							{
								if ( TempData_float > 10 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  EGR_PCT should be less than 10 %%\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
							else  // test 5.10 & 10.13
							{
								if ( gbDiesel == TRUE )  // compression ignition
								{
									if ( TempData_float > 100 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  EGR_PCT should be less than 100 %%\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
								else  // spark ignition engine
								{
									if ( gbHybrid == FALSE && TempData_float > 10 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  EGR_PCT should be less than 10 %%\n",
										      GetEcuId ( EcuIdx ) );
									}
									else if ( gbHybrid == TRUE && TempData_float > 50 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  EGR_PCT should be less than 50 %% \n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x2D:
						{
							TempData_float = ( (float)pPid->Data[0] * (float)(100.0/128.0) ) - (float)100.0;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $2D  EGR_ERR  = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
						}
						break;

						case 0x2E:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0/255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $2E  EVAP_PCT = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
						}
						break;

						case 0x2F:
						{
							TempData_float = ((float)pPid->Data[0]) * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $2F  FLI      = %.1f\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( TempData_float < 1.0 || TempData_float > 100.0 )
							{
								Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FLI outside expected range (1 to 100)\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x30:
						{
							TempData_long = pPid->Data[0];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $30  WARM_UPS = %d\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineWarm == TRUE)  // test 10.13
								{
									if ( TempData_long > 4 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  WARM_UPS should be less than or equal to 4\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
								else if ( gbEngineRunning == FALSE )          // test 5.6
								{
									if ( TempData_long > 0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  WARM_UPS should be less than or equal to 0\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
								else if ( gbEngineRunning == TRUE  &&       // test 5.10
								          gstResponse[EcuIdx].ClrDTCSize > 0 &&
								          gstResponse[EcuIdx].ClrDTC[0] == 0x44 )
								{
									if ( TempData_long > 1 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  WARM_UPS should be less than or equal to 1\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x31:
						{
							TempData_long = (pPid->Data[0] << 8) +
							                 pPid->Data[1];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $31  CLR_DIST = %d km\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineWarm == TRUE)                     // test 10.13
								{
									if ( TempData_long >= 50 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  CLR_DIST should be less than 50km after CARB drive cycle\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
								else if ( gbEngineRunning == FALSE ||       // test 5.6
								          (gbEngineRunning == TRUE &&       // test 5.10
								           gstResponse[EcuIdx].ClrDTCSize > 0 &&
								           gstResponse[EcuIdx].ClrDTC[0] == 0x44) )
								{
									if ( TempData_long != 0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  CLR_DIST should be 0 km after clearing DTCs\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x32:
						{
							TempData_float = (float)((signed short)((pPid->Data[0] << 8) +
							                                         pPid->Data[1])) * (float).25;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $32  EVAP_VP  = %.1f Pa\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
						}
						break;

						case 0x33:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $33  BARO     = %d kPa\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );

							if ( pPid->Data[0] < 71 || pPid->Data[0] > 110 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  BARO outside expected range (71 to 110)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x34:
						case 0x35:
						case 0x36:
						case 0x37:
						case 0x38:
						case 0x39:
						case 0x3A:
						case 0x3B:
						{
							switch ( pPid->ID )
							{
								case 0x34:
									BSIndex = 0x11;
								break;
								case 0x35:
									BSIndex = 0x12;
								break;
								case 0x36:
									BSIndex = bPid13Supported ? 0x13 : 0x21;
								break;
								case 0x37:
									BSIndex = bPid13Supported ? 0x14 : 0x22;
								break;
								case 0x38:
									BSIndex = bPid13Supported ? 0x21 : 0x31;
								break;
								case 0x39:
									BSIndex = bPid13Supported ? 0x22 : 0x32;
								break;
								case 0x3A:
									BSIndex = bPid13Supported ? 0x23 : 0x41;
								break;
								case 0x3B:
									BSIndex = bPid13Supported ? 0x24 : 0x42;
								break;
							}

							// scale Equivalence Ratio
							TempData_float = (float)((unsigned long)(pPid->Data[0] << 8) +
							                                         pPid->Data[1]);
							if ( bPid4FSupported == FALSE || Pid4F[EcuIdx][0] == 0 )
							{
								TempData_float = TempData_float * (float)0.0000305;
							}
							else
							{
								TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][0])/65535);
							}
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $%02X  EQ_RAT%x = %.3f %%\n",
							      GetEcuId ( EcuIdx ),
							      pPid->ID,
							      BSIndex,
							      TempData_float );

							// offset and scale Oxygen Sensor Current
							TempData_float = (float)((((signed short)(pPid->Data[2]) << 8) +
							                                          pPid->Data[3]) - 0x8000);
							if ( bPid4FSupported == FALSE || Pid4F[EcuIdx][2] == 0 )
							{
								TempData_float = TempData_float * (float)0.00390625;
							}
							else
							{
								TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][2])/32768);
							}
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $%02X  O2S%x    = %.2f mA\n",
							      GetEcuId ( EcuIdx ),
							      pPid->ID,
							      BSIndex,
							      TempData_float );
						}
						break;

						case 0x3C:
						case 0x3D:
						case 0x3E:
						case 0x3F:
						{
							switch ( pPid->ID )
							{
								case 0x3C:
									BSIndex = 0x11;
								break;
								case 0x3D:
									BSIndex = 0x21;
								break;
								case 0x3E:
									BSIndex = 0x12;
								break;
								case 0x3F:
									BSIndex = 0x22;
								break;
							}
							TempData_float = ((float)((pPid->Data[0] << 8) +
							                           pPid->Data[1]) * (float).1) - (float)(40.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $%02X  CATEMP%X = %.1f C\n",
							      GetEcuId ( EcuIdx ),
							      pPid->ID,
							      BSIndex,
							      TempData_float );
						}
						break;

						case 0x41:
						{
							if ( VerifyPid41( pPid, EcuIdx, bEngineDontCare) != PASS )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "SID $01 PID $41 failures detected.\n" );
							}
						}
						break;

						case 0x42:
						{
							TempData_float = (float)((pPid->Data[0] << 8) +
							                          pPid->Data[1]) * (float).001;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $42  VPWR     = %.3f V\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
						}
						break;

						case 0x43:
						{
							TempData_float = (float)((pPid->Data[0] << 8) +
							                          pPid->Data[1]) * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $43  LOAD_ABS = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
								{
									if ( TempData_float == 0.0 && gbHybrid != TRUE )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  LOAD_ABS should be greater than 0 %% when engine is running\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
								else  // test 5.6
								{
									if ( TempData_float != 0.0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  LOAD_ABS should be 0 %% when engine is not running\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x44:
						{
							TempData_float = (float)(((unsigned long)(pPid->Data[0]) << 8) +
							                                          pPid->Data[1]);
							if ( bPid4FSupported == FALSE ||
							     Pid4F[EcuIdx][0] == 0 )
							{
								TempData_float = TempData_float * (float)0.0000305;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $44  EQ_RAT   = %.3f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE && gbEngineWarm == TRUE )  // test 10.13
								{
									if ( gbDiesel == FALSE &&
									     gbHybrid != TRUE )
									{
										if ( TempData_float < 0.5 || TempData_float > 1.5  )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EQ_RAT outside expected range (0.5 to 1.5)\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}
							else
							{
								TempData_float = TempData_float * ((float)(Pid4F[EcuIdx][0])/65535);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $44  EQ_RAT   = %.3f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x45:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $45  TP_R     = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( gbDiesel == FALSE &&
							     gbHybrid == FALSE &&
							     TempData_float > 50 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TP_R should be less than 50 %%\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x46:
						{
							TempData_long = pPid->Data[0] - 40;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $46  AAT      = %d C\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( TempData_long < -20 || TempData_long > 85 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  AAT outside expected range (-20 to 85)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x47:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $47  TP_B     = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( gbDiesel == FALSE &&
							     gbHybrid == FALSE &&
							     TempData_float > 60 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TP_B should be less than 60 %%\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x48:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $48  TP_C     = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( gbDiesel == FALSE &&
							     gbHybrid == FALSE &&
							     TempData_float > 60 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TP_C should be less than 60 %%\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x49:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $49  APP_D    = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( TempData_float > 40 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  APP_D should be less than 40 %%\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x4A:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $4A  APP_E    = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( TempData_float > 40 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  APP_E should be less than 40 %%\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x4B:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $4B  APP_F    = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( TempData_float > 40 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  APP_F should be less than 40 %%\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x4C:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $4C  TAC_PCT  = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
						}
						break;

						case 0x4D:
						{
							TempData_long = (pPid->Data[0] << 8) +
							                 pPid->Data[1];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $4D  MIL_TIME = %d min\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( TempData_long != 0x00 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  MIL_TIME should be 0\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x4E:
						{
							TempData_long = (pPid->Data[0] << 8) +
							                 pPid->Data[1];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $4E  CLR_TIME = %d min\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineWarm == TRUE )                   // test 10.13
								{
									if ( TempData_long < 5 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  CLR_TIME should be greater than 5 min\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
								else if ( gbEngineRunning == FALSE ||       // test 5.6
								          (gbEngineRunning == TRUE   &&     // test 5.10
								           gstResponse[EcuIdx].ClrDTCSize > 0 &&
								           gstResponse[EcuIdx].ClrDTC[0] == 0x44) )
								{
									if ( TempData_long != 0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  CLR_TIME should be 0 min\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x4F:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $4F  EQ_RAT scaling      = %d / 65535\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );

							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $4F  O2S Voltage scaling = %d * (1 V / 65535)\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[1] );

							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $4F  O2S Current scaling = %d * (1 mA / 32768)\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[2] );

							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $4F  MAP scaling         = %d * (10 kPa / 255)\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[3] );
						}
						break;

						case 0x50:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $50  MAF scaling         = %d * (10 g/s / 65535)\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
						}
						break;

						case 0x51:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $51  FUEL_TYP = $%02X (%s)\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0],
							      (pPid->Data[0] <= 0x1F ? szFUEL_TYPE[pPid->Data[0]] : szFUEL_TYPE[0x20]) );

							if ( pPid->Data[0] == 0x00 ||
							     (pPid->Data[0] >= 0x0F && pPid->Data[0] <= 0x17) )
							{
								Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FUEL_TYPE must be $01 to $0E or $18 to $1C\n",
								      GetEcuId ( EcuIdx ) );
							}
							else if ( pPid->Data[0] >= 0x1D )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FUEL_TYPE must be $01 to $0E or $18 to $1C\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x52:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $52  ALCH_PCT = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
						}
						break;

						case 0x53:
						{
							TempData_float = ((pPid->Data[0] << 8) +
							                   pPid->Data[1]) * (float)0.005;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $53  EVAP_VPA = %.3f kPa\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
						}
						break;

						case 0x54:
						{
							TempData_long = (long)((signed short)((pPid->Data[0] << 8) +
							                                       pPid->Data[1]));
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $54  EVAP_VP  = %d Pa\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );
						}
						break;

						case 0x55:
						{
							TempData_float = (float)(pPid->Data[0] - 128) * (float)(100.0 / 128.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $55  STSO2FT1 = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( TempData_float < -100.0 || TempData_float > 99.2 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  STSO2FT1 outside expected range (-100 to 99.2)\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( gVariablePidSize == 2 )
							{
								TempData_float =  (float)(pPid->Data[1] - 128) * (float)(100.0 / 128.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $55  STSO2FT3 = %.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( TempData_float < -100.0 || TempData_float > 99.2 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  STSO2FT3 outside expected range (-100 to 99.2)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x56:
						{
							TempData_float = (float)( pPid->Data[0] - 128 ) * (float)(100.0 / 128.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $56  LGSO2FT1 = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( TempData_float < -100.0 || TempData_float > 99.2 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  LGSO2FT1 outside expected range (-100 to 99.2)\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( gVariablePidSize == 2 )
							{
								TempData_float = (float)( pPid->Data[1] - 128 ) * (float)(100.0 / 128.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $56  LGSO2FT3 = %.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( TempData_float < -100.0 || TempData_float > 99.2 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  LGSO2FT3 outside expected range (-100 to 99.2)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x57:
						{
							TempData_float = (float)( pPid->Data[0] - 128 ) * (float)(100.0 / 128.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $57  STSO2FT2 = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( TempData_float < -100.0 || TempData_float > 99.2 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  STSO2FT2 outside expected range (-100 to 99.2)\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( gVariablePidSize == 2 )
							{
								TempData_float = (float)( pPid->Data[1] - 128 ) * (float)(100.0 / 128.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $57  STSO2FT4 = %.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( TempData_float < -100.0 || TempData_float > 99.2 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  STSO2FT4 outside expected range (-100 to 99.2)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x58:
						{
							TempData_float = (float)( pPid->Data[0] - 128 ) * (float)(100.0 / 128.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $58  LGSO2FT2 = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( TempData_float < -100.0 || TempData_float > 99.2 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  LGSO2FT2 outside expected range (-100 to 99.2)\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( gVariablePidSize == 2 )
							{
								TempData_float = (float)( pPid->Data[1] - 128 ) * (float)(100.0 / 128.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $58  LGSO2FT4 = %.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( TempData_float < -100.0 || TempData_float > 99.2 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  LGSO2FT4 outside expected range (-100 to 99.2)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x59:
						{
							TempData_long = ( (pPid->Data[0] << 8) +
							                   pPid->Data[1] ) * 10;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $59  FRP      = %d kPa\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE && gbHybrid != TRUE &&
							     TempData_long == 0 )  // test 5.10 & 10.13
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FRP should not be 0\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x5A:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $5A  APP_R    = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( TempData_float > 40 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  APP_R should be less than 40 %%\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x5B:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $5B  BAT_PWR  = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE &&
							     TempData_float == 0 )  // test 5.10 & 10.13
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  BAT_PWR should not be 0\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x5C:
						{
							TempData_long = pPid->Data[0] - 40;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $5C  EOT      = %d C\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( TempData_long  < -20 || TempData_long > 150 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EOT outside expected range (-20 to 150)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x5D:
						{
							TempData_float = (float)(((pPid->Data[0] << 8) +
							                           pPid->Data[1]) - 26880) / 128;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $5D  FUEL_TIMING = %.2f\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
							if ( TempData_float < -210 || TempData_float >= 302 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FUEL_TIMING outside expected range (-209 to 301)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x5E:
						{
							TempData_float = ((pPid->Data[0] << 8) +
							                   pPid->Data[1]) * (float)0.05;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $5E  FUEL_RATE = %.2f L/h\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineRunning == TRUE)  // test 5.10 & 10.13
								{
									if ( gbHybrid != TRUE &&
									     TempData_float == 0.0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  FUEL_RATE should not be 0 when engine running\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
								else // test 5.6
								{
									if ( TempData_float != 0.0 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  FUEL_RATE should be 0 when engine is not running\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x5F:
						{
							TempData_long = pPid->Data[0];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $5F  EMIS_SUP = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( TempData_long  < 0x0E || TempData_long > 0x10 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EMIS_SUP outside expected range ($0E to $10)\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x61:
						{
							TempData_long = pPid->Data[0] - 125;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $61  TQ_DD    = %d %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );
						}
						break;

						case 0x62:
						{
							TempData_long = pPid->Data[0] - 125;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $62  TQ_ACT   = %d %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE )  // NOT Test 10.2
							{
								if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
								{
									if ( TempData_long <= 0 )
									{
										if ( !(TempData_long == 0 && gbHybrid == TRUE) )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  TQ_ACT should be greater than 0 when egine is running\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
								else if ( TempData_long < 0 )  // test 5.6
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TQ_ACT should not be less than 0 when engine is not running\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x63:
						{
							TempData_long = (pPid->Data[0] << 8) +
							                 pPid->Data[1];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $63  TQ_REF   = %d Nm\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE &&
							     TempData_long <= 0 )  // test 5.10 & 10.13
							{
								if ( !(TempData_long == 0 && gbHybrid == TRUE) )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TQ_REF should be greater than 0\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x64:
						{
							TempData_long = pPid->Data[0] - 125;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $64  TQ_MAX1  = %d %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
							{
								if ( TempData_long <= 0 )
								{
									if ( !(TempData_long == 0 && gbHybrid == TRUE) )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  TQ_MAX1 should be greater than 0\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}

							TempData_long = pPid->Data[1] - 125;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $64  TQ_MAX2  = %d %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
							{
								if ( TempData_long <= 0 )
								{
									if ( !(TempData_long == 0 && gbHybrid == TRUE) )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  TQ_MAX2 should be greater than 0\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}

							TempData_long = pPid->Data[2] - 125;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $64  TQ_MAX3  = %d %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
							{
								if ( TempData_long <= 0 )
								{
									if ( !(TempData_long == 0 && gbHybrid == TRUE) )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  TQ_MAX3 should be greater than 0\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}

							TempData_long = pPid->Data[3] - 125;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $64  TQ_MAX4  = %d %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
							{
								if ( TempData_long <= 0 )
								{
									if ( !(TempData_long == 0 && gbHybrid == TRUE) )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  TQ_MAX4 should be greater than 0\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}

							TempData_long = pPid->Data[4] - 125;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $64  TQ_MAX5  = %d %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
							{
								if ( TempData_long <= 0 )
								{
									if ( !(TempData_long == 0 && gbHybrid == TRUE) )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  TQ_MAX5 should be greater than 0\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x65:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $65  Auxiliary I/O Support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Auxiliary I/O Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PTO_STAT_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  N/D_STAT_SUP  = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  N/G_STAT_SUP  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  GPL_STAT_SUP  = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  GEAR_RCMD_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x1F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Auxiliary I/O Support  No devices supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( gbDiesel == TRUE &&
							     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) &&
							     (pPid->Data[0] & 0x08) == 0 )
							{
								Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Auxiliary I/O Support Bit 3 (GPL_STAT_SUP) must be set for diesel vehicles\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( (pPid->Data[0] & 0xE0) != 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Auxiliary I/O Support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $65  Auxiliary I/O Status = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[1] );

							// Auxiliary I/O Status bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PTO_STAT  = %s\n",
							      (pPid->Data[1] & 0x01) ? "ON" : "OFF" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  N/D_STAT  = %s\n",
							      (pPid->Data[1] & 0x02) ? "DRIVE" : "NEUT" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  N/G_STAT  = %s\n",
							      (pPid->Data[1] & 0x04) ? "GEAR" : "NEUT" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  GPL_STAT  = %s\n",
							      (pPid->Data[1] & 0x08) ? "ON" : "OFF" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  GEAR_RCMD = $%02X (%s)\n",
							      pPid->Data[1] >> 4,
							      szGEAR[pPid->Data[1] >> 4] );
						}
						break;

						case 0x66:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $66  MAF Sensor support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Mass Air Flow Sensor Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  MAFA_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  MAFB_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x03) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  MAF Sensor support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  MAF Sensor support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (float)( (pPid->Data[1] << 8) +
								                           pPid->Data[2] ) * (float)0.03125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $66  MAFA     = %.3f g/s\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE )  // NOT Test 10.2
								{
									if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
									{
										if ( TempData_float <= 0 )
										{
											if ( !(TempData_float == 0.0 && gbHybrid == TRUE) )
											{
												Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
												      "ECU %X  MAFA should be greater than 0 when engine running\n",
												      GetEcuId ( EcuIdx ) );
											}
										}
									}
									else  // test 5.6
									{
										if ( TempData_float > 5 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  MAFA should be less than or equal to 5 when engine is not running\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = (float)( (pPid->Data[3] << 8) +
								                           pPid->Data[4] ) * (float)0.03125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $66  MAFB     = %.3f g/s\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE )  // NOT Test 10.2
								{
									if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
									{
										if ( TempData_float <= 0 )
										{
											if ( !(TempData_float == 0.0 && gbHybrid == TRUE) )
											{
												Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
												      "ECU %X  MAFB should be greater than 0 when engine is running\n",
												      GetEcuId ( EcuIdx ) );
											}
										}
									}
									else  // test 5.6
									{
										if ( TempData_float > 5 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  MAFB should be less than or equal to 5 when engine is not running\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}
						}
						break;

						case 0x67:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $67  ECT Sensor support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Engine Coolant Temperature Sensor Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  ECT1_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  ECT2_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x03) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  ECT Sensor support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  ECT Sensor support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = (pPid->Data[1] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $67  ECT1     = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  ECT1 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = (pPid->Data[2] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $67  ECT2     = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  ECT2 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x68:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $68  IAT Sensor support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Intake Air Temperature Sensor Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAT11_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAT12_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAT13_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAT21_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAT22_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAT23_SUP = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x3F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  IAT Sensor support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xC0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  IAT Sensor support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = ( pPid->Data[1] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $68  IAT11    = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  IAT11 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = ( pPid->Data[2] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $68  IAT12    = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  IAT12 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = (pPid->Data[3] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $68  IAT13    = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  IAT13 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = ( pPid->Data[4] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $68  IAT21    = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  IAT21 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x10) != 0 )
							{
								TempData_long = ( pPid->Data[5] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $68  IAT22    = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  IAT22 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x20) != 0 )
							{
								TempData_long =  (pPid->Data[6] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $68  IAT23    = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  IAT23 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x69:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $69  EGR data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// EGR System Data Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGR_A_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGR_A_ACT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGR_A_ERR_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGR_B_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGR_B_ACT_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGR_B_ERR_SUP = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x3F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGR data support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xC0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGR data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
								Temp_EGR_CMD = TempData_float;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $69  EGR_A_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE)  // test 5.6
								{
									if ( TempData_float > 10 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  EGR_A_CMD should be less than or equal to 10 %% when engine is not running\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
								else  // test 5.10 & 10.13
								{
									if ( gbDiesel == TRUE )  // compression ignition
									{
										if ( TempData_float > 100 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_A_CMD should be less than or equal to 100 %% when engine is running\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
									else  // spark ignition
									{
										if ( gbHybrid == FALSE &&
										     TempData_float > 10 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_A_CMD should be less than or equal to 10 %% when engine is running\n",
											      GetEcuId ( EcuIdx ) );
										}
										else if ( gbHybrid == TRUE &&
										          TempData_float > 50 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_A_CMD should be less than or equal to 50 %% when engine is running\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
								Temp_EGR_ACT = TempData_float;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $69  EGR_A_ACT = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = (float)(pPid->Data[3] - 128 ) * (float)(100.0 / 128.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $69  EGR_A_ERR = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								// if EGR_CMD and EGR_ACT supported, check for proper EGR_ERR
								if ( (pPid->Data[0] & 0x01) != 0 && (pPid->Data[0] & 0x02) != 0 )
								{
									if ( Temp_EGR_CMD == 0 )
									{
										if ( Temp_EGR_ACT == 0 && TempData_float != 0 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_A_ERR should be 0%% when EGR_A_CMD == 0%% and EGR_A_ACT == 0%%\n",
											      GetEcuId ( EcuIdx ) );
										}
										else if ( Temp_EGR_ACT > 0 && pPid->Data[3] != 0xFF )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_A_ERR should be 99.2%% when EGR_A_CMD == 0%% and EGR_A_ACT > 0%%\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
								Temp_EGR_CMD = TempData_float;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $69  EGR_B_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE)  // test 5.6
								{
									if ( TempData_float > 10 )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  EGR_B_CMD should be less than or equal to 10 %% when engine is not running\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
								else  // test 5.10 & 10.13
								{
									if ( gbDiesel == TRUE )  // compression ignition
									{
										if ( TempData_float > 100 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_B_CMD should be less than or equal to 100 %% when engine is running\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
									else  // spark ignition
									{
										if ( gbHybrid == FALSE && TempData_float > 10 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_B_CMD should be less than or equal to 10 %% when engine is running\n",
											      GetEcuId ( EcuIdx ) );
										}
										else if ( gbHybrid == TRUE && TempData_float > 50 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_B_CMD should be less than or equal to 50 %% when engine is running\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}

							if ( (pPid->Data[0] & 0x10) != 0 )
							{
								TempData_float = (float)pPid->Data[5] * (float)(100.0 / 255.0);
								Temp_EGR_ACT = TempData_float;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $69  EGR_B_ACT = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x20) != 0 )
							{
								TempData_float = (float)( pPid->Data[6] - 128) * (float)(100.0 / 128.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $69  EGR_B_ERR = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								// if EGR_CMD and EGR_ACT supported, check for proper EGR_ERR
								if ( (pPid->Data[0] & 0x08) != 0 && (pPid->Data[0] & 0x10) != 0 )
								{
									if ( Temp_EGR_CMD == 0 )
									{
										if ( Temp_EGR_ACT == 0 && TempData_float != 0 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_B_ERR should be 0%% when EGR_B_CMD == 0%% and EGR_B_ACT == 0%%\n",
											      GetEcuId ( EcuIdx ) );
										}
										else if ( Temp_EGR_ACT > 0 && pPid->Data[6] != 0xFF )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGR_B_ERR should be 99.2%% when EGR_B_CMD == 0%% and EGR_B_ACT > 0%%\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}
						}
						break;

						case 0x6A:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $6A  IAF data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Intake Air Flow Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAF_A_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAF_A_REL_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAF_B_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IAF_B_REL_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  IAF data support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  IAF data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6A  IAF_A_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6A  IAF_A_REL = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = (float)pPid->Data[3] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6A  IAF_B_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6A  IAF_B_REL = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x6B:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $6B  EGRT sensor support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  EGR Temperature Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGRTA_SUP    = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGRTC_SUP    = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGRTB_SUP    = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGRTD_SUP    = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGRTA_WR_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGRTC_WR_SUP = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGRTB_WR_SUP = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGRTD_WR_SUP = %s\n",
							      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0xFF) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGRT sensor support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that only one range bit is set for each sensor
							TempData_long = pPid->Data[0] >> 4;
							if ( (pPid->Data[0] & TempData_long) != 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGRT sensor support  Both Normal and Wide Range supported for sensor(s)\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x11) != 0 )
							{
								if ( (pPid->Data[0] & 0x01) != 0 )
								{
									TempData_long = (pPid->Data[1]) - 40;
								}
								else
								{
									TempData_long = ((pPid->Data[1]) * 4) - 40;
								}

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6B  EGRT11  = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( bEngineDontCare == FALSE )  // NOT Test 10.2
								{
									if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
									{
										if ( (pPid->Data[0] & 0x01) != 0 &&
										     (TempData_long < -20 || TempData_long > 215) )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT11 outside expected range (-20 to 215)\n",
											      GetEcuId ( EcuIdx ) );
										}
										else if ( (pPid->Data[0] & 0x10) != 0 &&
										          (TempData_long < -20 || TempData_long > 500) )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT11 outside expected range (-20 to 500)\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
									else  // test 5.6
									{
										if ( TempData_long < -20 || TempData_long > 200 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT11 outside expected range (-20 to 200)\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}

							if ( (pPid->Data[0] & 0x22) != 0 )
							{
								if ( (pPid->Data[0] & 0x02) != 0 )
								{
									TempData_long = (pPid->Data[2]) - 40;
								}
								else
								{
									TempData_long = ((pPid->Data[2]) * 4) - 40;
								}

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6B  EGRT12  = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( bEngineDontCare == FALSE )  // NOT Test 10.2
								{
									if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
									{
										if ( (pPid->Data[0] & 0x02) != 0 &&
										     (TempData_long < -20 || TempData_long > 215) )
										{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  EGRT12 outside expected range (-20 to 215)\n",
										      GetEcuId ( EcuIdx ) );
										}
										else if ( (pPid->Data[0] & 0x20) != 0 &&
										          (TempData_long < -20 || TempData_long > 500) )
										{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  EGRT12 outside expected range (-20 to 500)\n",
										      GetEcuId ( EcuIdx ) );
										}
									}
									else  // test 5.6
									{
										if ( TempData_long < -20 || TempData_long > 200 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT12 outside expected range (-20 to 200)\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}

							if ( (pPid->Data[0] & 0x44) != 0 )
							{
								if ( (pPid->Data[0] & 0x04) != 0 )
								{
									TempData_long = (pPid->Data[3]) - 40;
								}
								else
								{
									TempData_long = ((pPid->Data[3]) * 4) - 40;
								}

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6B  EGRT21  = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( bEngineDontCare == FALSE )  // NOT Test 10.2
								{
									if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
									{
										if ( (pPid->Data[0] & 0x04) != 0 &&
										     (TempData_long < -20 || TempData_long > 215) )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT21 outside expected range (-20 to 215)\n",
											      GetEcuId ( EcuIdx ) );
										}
										else if ( (pPid->Data[0] & 0x40) != 0 &&
										          (TempData_long < -20 || TempData_long > 500) )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT21 outside expected range (-20 to 500)\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
									else  // test 5.6
									{
										if ( TempData_long < -20 || TempData_long > 200 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT21 outside expected range (-20 to 200)\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}

							if ( (pPid->Data[0] & 0x88) != 0 )
							{
								if ( (pPid->Data[0] & 0x08) != 0 )
								{
									TempData_long = (pPid->Data[4]) - 40;
								}
								else
								{
									TempData_long = ((pPid->Data[4]) * 4) - 40;
								}

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6B  EGRT22  = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( bEngineDontCare == FALSE )  // NOT Test 10.2
								{
									if ( gbEngineRunning == TRUE )  // test 5.10 & 10.13
									{
										if ( (pPid->Data[0] & 0x08) != 0 &&
										     (TempData_long < -20 || TempData_long > 215) )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT22 outside expected range (-20 to 215)\n",
											      GetEcuId ( EcuIdx ) );
										}
										else if ( (pPid->Data[0] & 0x80) != 0 &&
										          (TempData_long < -20 || TempData_long > 500) )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT22 outside expected range (-20 to 500)\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
									else  // test 5.6
									{
										if ( TempData_long < -20 || TempData_long > 200 )
										{
											Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
											      "ECU %X  EGRT22 outside expected range (-20 to 200)\n",
											      GetEcuId ( EcuIdx ) );
										}
									}
								}
							}
						}
						break;

						case 0x6C:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $6C  TAC data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  EGR Temperature Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TAC_A_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TP_A_REL_SUP  = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TAC_B_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TP_B_REL_SUP  = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TAC data support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TAC data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6C  TAC_A_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6C  TP_A_REL  = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE && gbDiesel == FALSE && gbHybrid == FALSE &&
								     TempData_float > 50 )  // NOT test 10.2
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TP_A_REL should be less than or equal to 50 %%\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = (float)pPid->Data[3] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6C  TAC_B_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6C  TP_B_REL  = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE && gbDiesel == FALSE && gbHybrid == FALSE &&
								     TempData_float > 50 )  // NOT Test 10.2
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TP_B_REL should be less than or equal to 50 %%\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x6D:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $6D  FRP data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Fuel Pressure Control Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FRP_A_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FRP_A_SUP     = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FRT_A_SUP     = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FRP_B_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FRP_B_SUP     = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FRT_B_SUP     = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x3F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FRP data support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xC0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  FRP data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = ((pPid->Data[1] << 8) +
								                  pPid->Data[2]) * 10;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6D  FRP_A_CMD = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = ((pPid->Data[3] << 8) +
								                  pPid->Data[4]) * 10;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6D  FRP_A     = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = ( pPid->Data[5] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6D  FRT_A     = %5d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FRT_A outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = ((pPid->Data[6] << 8) +
								                  pPid->Data[7]) * 10;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6D  FRP_B_CMD = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( (pPid->Data[0] & 0x10) != 0 )
							{
								TempData_long = ((pPid->Data[8] << 8) +
								                  pPid->Data[9]) * 10;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6D  FRP_B     = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( (pPid->Data[0] & 0x20) != 0 )
							{
								TempData_long = pPid->Data[10] - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6D  FRT_B     = %5d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FRT_B outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x6E:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $6E  ICP system data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Injection Pressure Control Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  ICP_A_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  ICP_A_SUP     = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  ICP_B_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  ICP_B_SUP     = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  ICP data support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  ICP data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = ((pPid->Data[1] << 8) +
								                  pPid->Data[2]) * 10;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6E  ICP_A_CMD = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = ((pPid->Data[3] << 8) +
								                  pPid->Data[4]) * 10;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6E  ICP_A     = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = ((pPid->Data[5] << 8) +
								                  pPid->Data[6]) * 10;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6E  ICP_B_CMD = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = ((pPid->Data[7] << 8) +
								                  pPid->Data[8]) * 10;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6E  ICP_B     = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0x6F:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $6F  TCA sensor support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Injection Pressure Control Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCA_CINP_SUP    = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCB_CINP_SUP    = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCA_CINP_WR_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCA_CINP_WR_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TCA sensor support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TCA sensor support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							// TCA_CINP supported
							if ( (pPid->Data[0] & 0x05) != 0 )
							{
								TempData_long = pPid->Data[1];
								//if 8kPa/bit
								if ( (pPid->Data[0] & 0x04) != 0 )
								{
									TempData_long *= 8;
								}
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6F  TCA_CINP = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							// TCB_CINP supported
							if ( (pPid->Data[0] & 0x0A) != 0 )
							{
								TempData_long = pPid->Data[2];
								//if 8kPa/bit
								if ( (pPid->Data[0] & 0x08) != 0 )
								{
									TempData_long *= 8;
								}
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $6F  TCB_CINP = %5d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0x70:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $70  BP data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Boost Pressure Control Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  BP_A_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  BP_A_ACT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  BP_A_STA_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  BP_B_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  BP_B_ACT_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  BP_B_STA_SUP = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x3F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  BP data support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xC0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  BP data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = ((pPid->Data[1] << 8) +
								                   pPid->Data[2]) * (float)0.03125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $70  BP_A_CMD = %4.3f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = ((pPid->Data[3] << 8) +
								                   pPid->Data[4]) * (float)0.03125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $70  BP_A_ACT = %4.3f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = ((pPid->Data[5] << 8) +
								                   pPid->Data[6]) * (float)0.03125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $70  BP_B_CMD = %.3f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x10) != 0 )
							{
								TempData_float = ((pPid->Data[7] << 8) +
								                   pPid->Data[8]) * (float)0.03125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $70  BP_B_ACT = %4.3f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							// bit 2 (0x04) BP_A Status and bit 5 (0x20) BP_B Status
							if ( (pPid->Data[0] & 0x24) != 0 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $70  BP control status = $%02X\n",
								      GetEcuId ( EcuIdx ),
								      pPid->Data[9] );
								//  Boost Pressure Status bits
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  BP_A_STA = %s\n",
								      szCON_STATUS[(pPid->Data[0] & 0x03)] );
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  BP_B_STA = %s\n",
								      szCON_STATUS[(pPid->Data[0] & 0x0C) >> 2] );

								// check that reserved bits are not set
								if ( pPid->Data[9] & 0xF0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  BP control status  Reserved bits set\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x71:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $71  VGT data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Variable Geometry Turbo Control Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  VGT_A_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  VGT_A_ACT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  VGT_A_STA_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  VGT_B_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  VGT_B_ACT_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  VGT_B_STA_SUP = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x3F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  VGT data support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xC0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  VGT data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $71  VGT_A_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $71  VGT_A_ACT = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (float)pPid->Data[3] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $71  VGT_B_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x10) != 0 )
							{
								TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $71  VGT_B_ACT = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							// bit 2 (0x04) VGT_A Status and bit 5 (0x20) VGT_B Status
							if ( (pPid->Data[0] & 0x24) != 0 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $71  VGT control status = $%02X\n",
								      GetEcuId ( EcuIdx ),
								      pPid->Data[5] );
								//  Boost Pressure Status bits
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  VGT_A_STA = %s\n",
								      szCON_STATUS[(pPid->Data[0] & 0x03)] );
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  VGT_B_STA = %s\n",
								      szCON_STATUS[(pPid->Data[0] & 0x0C) >> 2] );

								// check that reserved bits are not set
								if ( pPid->Data[5] & 0xF0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  VGT control status  Reserved bits set\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x72:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $72  WG data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Wastegate Control Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  WG_A_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  WG_A_ACT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  WG_B_CMD_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  WG_B_ACT_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  WG data support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  WG data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (float)pPid->Data[1] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $72  WG_A_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = (float)pPid->Data[2] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $72  WG_A_ACT = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = (float)pPid->Data[3] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $72  WG_B_CMD = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (float)pPid->Data[4] * (float)(100.0 / 255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $72  WG_B_ACT = %2.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x73:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $73  EP data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Exhaust Pressure Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EP1_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EP2_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x03) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EP data support  No sensors supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EP data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = ((pPid->Data[1] << 8) +
								                   pPid->Data[2]) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $73  EP1    = %4.2f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = ((pPid->Data[3] << 8) +
								                   pPid->Data[4]) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $73  EP2    = %4.2f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x74:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $74  TC_RPM data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Exhaust Pressure Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCA_RPM_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCB_RPM_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x03) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TC_RPM data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TC_RPM data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = (pPid->Data[1] << 8) +
								                 pPid->Data[2];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $74  TCA_RPM = %d RPM\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $74  TCB_RPM = %d RPM\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0x75:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $75  TC A Temp data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Turbocharger A Temperature Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCA_CINT_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCA_COUTT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCA_TINT_SUP  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCA_TOUTT_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TC A Temp data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TC A Temp data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = ( pPid->Data[1] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $75  TCA_CINT  = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TCA_CINT outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = ( pPid->Data[2] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $75  TCA_COUTT = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TCA_COUTT outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = (((pPid->Data[3] << 8) +
								                    pPid->Data[4]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $75  TCA_TINT  = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
								if ( TempData_float < -20 || TempData_float > 1000 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TCA_TINT outside expected range (-20 to 1000)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (((pPid->Data[5] << 8) +
								                    pPid->Data[6]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $75  TCA_TOUTT = %.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
								if ( TempData_float < -20 || TempData_float > 1000 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TCA_TOUTT outside expected range (-20 to 1000)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x76:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $76  TC B Temp data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Turbocharger A Temperature Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCB_CINT_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCB_COUTT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCB_TINT_SUP  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  TCB_TOUTT_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TC B Temp data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  TC B Temp data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = ( pPid->Data[1] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $76  TCB_CINT  = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TCB_CINT outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = ( pPid->Data[2] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $76  TCB_COUTT = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TCB_COUTT outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = (((pPid->Data[3] << 8) +
								                    pPid->Data[4]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $76  TCB_TINT  = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
								if ( TempData_float < -20 || TempData_float > 1000 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TCB_TINT outside expected range (-20 to 1000)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (((pPid->Data[5] << 8) +
								                    pPid->Data[6]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $76  TCB_TOUTT = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
								if ( TempData_float < -20 || TempData_float > 1000 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  TCB_TOUTT outside expected range (-20 to 1000)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x77:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $77  CACT data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Charge Air Cooler Temperature Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CACT11_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CACT12_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CACT21_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CACT22_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  CACT data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  CACT data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = ( pPid->Data[1] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $77  CACT11 = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  CACT11 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = ( pPid->Data[2] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $77  CACT12 = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  CACT12 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = ( pPid->Data[3] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $77  CACT21 = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  CACT21 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = ( pPid->Data[4] ) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $77  CACT22 = %3d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
								if ( TempData_long < -20 || TempData_long > 120 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  CACT22 outside expected range (-20 to 120)\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0x78:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $78  EGT Bank 1 data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Exhaust Gas Temperature Bank 1 Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT11_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT12_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT13_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT14_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGT Bank 1 data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGT Bank 1 data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (((pPid->Data[1] << 8) +
								                    pPid->Data[2]) * (float).1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $78  EGT11 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = (((pPid->Data[3] << 8) +
								                    pPid->Data[4]) * (float).1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $78  EGT12 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = (((pPid->Data[5] << 8) +
								                    pPid->Data[6]) * (float).1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $78  EGT13 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (((pPid->Data[7] << 8) +
								                    pPid->Data[8]) * (float).1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $78  EGT14 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x79:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $79  EGT Bank 2 data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Exhaust Gas Temperature Bank 2 Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT21_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT22_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT23_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT24_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGT Bank 2 data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGT Bank 2 data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (((pPid->Data[1] << 8) +
								                    pPid->Data[2]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $79  EGT21 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = (((pPid->Data[3] << 8) +
								                    pPid->Data[4]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $79  EGT22 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = (((pPid->Data[5] << 8) +
								                    pPid->Data[6]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $79  EGT23 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (((pPid->Data[7] << 8) +
								                    pPid->Data[8]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $79  EGT24 = %.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x7A:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $7A  DPF Bank 1 data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Particulate Filter Bank 1 Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DPF1_DP_SUP   = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DPF1_INP_SUP  = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DPF1_OUTP_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x07) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  DPF Bank 1 data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF8 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  DPF Bank 1 data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (float)((signed short)((pPid->Data[1] << 8) +
								                                         pPid->Data[2])) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7A  DPF1_DP   = %4.1f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = ((pPid->Data[3] << 8) +
								                   pPid->Data[4]) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7A  DPF1_INP  = %4.1f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = ((pPid->Data[5] << 8) +
								                   pPid->Data[6]) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7A  DPF1_OUTP = %4.1f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x7B:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $7B  DPF Bank 2 data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Particulate Filter Bank 2 Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DPF2_DP_SUP   = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DPF2_INP_SUP  = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DPF2_OUTP_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x07) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  DPF Bank 2 data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF8 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  DPF Bank 2 data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (float)((signed short)((pPid->Data[1] << 8) +
								                                         pPid->Data[2])) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7B  DPF2_DP   = %4.1f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = ((pPid->Data[3] << 8) +
								                   pPid->Data[4]) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7B  DPF2_INP  = %4.1f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = ((pPid->Data[5] << 8) +
								                   pPid->Data[6]) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7B  DPF2_OUTP = %4.1f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x7C:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $7C  DPF Temp data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Particulate Filter Temperature Support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PF1_INT_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PF1_OUTT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PF2_INT_SUP  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PF2_OUTT_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  DPF Temp data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  DPF Temp data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = (((pPid->Data[1] << 8) +
								                    pPid->Data[2]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7C  DPF1_INT  = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = (((pPid->Data[3] << 8) +
								                    pPid->Data[4]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7C  DPF1_OUTT = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_float = (((pPid->Data[5] << 8) +
								                    pPid->Data[6]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7C  DPF2_INT  = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_float = (((pPid->Data[7] << 8) +
								                    pPid->Data[8]) * (float)0.1) - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $7C  DPF2_OUTT = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x7D:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $7D  NOx NTE control area status = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// NOx NTE control area status bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NNTE_IN  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NNTE_OUT = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NNTE_CAA = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NNTE_DEF = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  NOx NTE control area status  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x7E:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $7E  PM NTE control area status = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// PM NTE control area status bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PNTE_IN  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PNTE_OUT = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PNTE_CAA = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PNTE_DEF = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PM NTE control area status  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x7F:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $7F  Run Time support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Engine Run Time support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  RUN_TIME_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IDLE_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PTO_TIME_SUP  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x07) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF8 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = (pPid->Data[1] << 24) +
								                (pPid->Data[2] << 16) +
								                (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $7F  RUN_TIME = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $7F  RUN_TIME  = %d sec (%d hrs, %d mins, %d secs)\n",
									     GetEcuId ( EcuIdx ),
									     TempData_long,
									     hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = (pPid->Data[5] << 24) +
								                (pPid->Data[6] << 16) +
								                (pPid->Data[7] << 8) +
								                 pPid->Data[8];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $7F  IDLE_TIME = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $7F  IDLE_TIME = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = (pPid->Data[9] << 24) +
								                (pPid->Data[10] << 16) +
								                (pPid->Data[11] << 8) +
								                 pPid->Data[12];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $7F  PTO_TIME = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $7F  PTO_TIME  = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}
						}
						break;

						case 0x81:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $81  Run Time for AECD #1-#5 support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Engine Run Time for AECD #1 - #5 support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD1_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD2_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD3_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD4_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD5_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x1F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time for AECD #1-#5 support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xE0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time for AECD #1-#5 support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = (pPid->Data[1] << 24) +
								                (pPid->Data[2] << 16) +
								                (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD1_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD1_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[5] << 24) +
								                (pPid->Data[6] << 16) +
								                (pPid->Data[7] << 8) +
								                 pPid->Data[8];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD1_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD1_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = (pPid->Data[9] << 24) +
								                (pPid->Data[10] << 16) +
								                (pPid->Data[11] << 8) +
								                 pPid->Data[12];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD2_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD2_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[13] << 24) +
								                (pPid->Data[14] << 16) +
								                (pPid->Data[15] << 8) +
								                 pPid->Data[16];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD2_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD2_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = (pPid->Data[17] << 24) +
								                (pPid->Data[18] << 16) +
								                (pPid->Data[19] << 8) +
								                 pPid->Data[20];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD3_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD3_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[21] << 24) +
								                (pPid->Data[22] << 16) +
								                (pPid->Data[23] << 8) +
								                 pPid->Data[24];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD3_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD3_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = (pPid->Data[25] << 24) +
								                (pPid->Data[26] << 16) +
								                (pPid->Data[27] << 8) +
								                 pPid->Data[28];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD4_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD4_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[29] << 24) +
								                (pPid->Data[30] << 16) +
								                (pPid->Data[31] << 8) +
								                 pPid->Data[32];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD4_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD4_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x10) != 0 )
							{
								TempData_long = (pPid->Data[33] << 24) +
								                (pPid->Data[34] << 16) +
								                (pPid->Data[35] << 8) +
								                 pPid->Data[36];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD5_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD5_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[37] << 24) +
								                (pPid->Data[38] << 16) +
								                (pPid->Data[39] << 8) +
								                 pPid->Data[40];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD5_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $81  AECD5_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}
						}
						break;

						case 0x82:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $82  Run Time for AECD #6-#10 support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Engine Run Time for AECD #6 - #10 support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD6_TIME_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD7_TIME_SUP  = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD8_TIME_SUP  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD9_TIME_SUP  = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD10_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x1F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time for AECD #6-#10 support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xE0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time for AECD #6-#10 support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = (pPid->Data[1] << 24) +
								                (pPid->Data[2] << 16) +
								                (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD6_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD6_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[5] << 24) +
								                (pPid->Data[6] << 16) +
								                (pPid->Data[7] << 8) +
								                 pPid->Data[8];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD6_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD6_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = (pPid->Data[9] << 24) +
								                (pPid->Data[10] << 16) +
								                (pPid->Data[11] << 8) +
								                 pPid->Data[12];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD7_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD7_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[13] << 24) +
								                (pPid->Data[14] << 16) +
								                (pPid->Data[15] << 8) +
								                 pPid->Data[16];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD7_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD7_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = (pPid->Data[17] << 24) +
								                (pPid->Data[18] << 16) +
								                (pPid->Data[19] << 8) +
								                 pPid->Data[20];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD8_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD8_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[21] << 24) +
								                (pPid->Data[22] << 16) +
								                (pPid->Data[23] << 8) +
								                 pPid->Data[24];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD8_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD8_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = (pPid->Data[25] << 24) +
								                (pPid->Data[26] << 16) +
								                (pPid->Data[27] << 8) +
								                 pPid->Data[28];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD9_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD9_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[29] << 24) +
								                (pPid->Data[30] << 16) +
								                (pPid->Data[31] << 8) +
								                 pPid->Data[32];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD9_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD9_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x10) != 0 )
							{
								TempData_long = (pPid->Data[33] << 24) +
								                (pPid->Data[34] << 16) +
								                (pPid->Data[35] << 8) +
								                 pPid->Data[36];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD10_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD10_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									     hours, mins, secs );
								}

								TempData_long = (pPid->Data[37] << 24) +
								                (pPid->Data[38] << 16) +
								                (pPid->Data[39] << 8) +
								                 pPid->Data[40];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD10_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $82  AECD10_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}
						}
						break;

						case 0x83:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $83  NOx Sensor Data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  NOx Sensor Data support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX11_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX12_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX21_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX22_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX11_DAT = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX12_DAT = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX21_DAT = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX22_DAT = %s\n",
							      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  NOx Sensor Data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = (pPid->Data[1] << 8) +
								                 pPid->Data[2];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $83  NOX11 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( (pPid->Data[0] & 0x10) != 0 && TempData_long != 0xFFFF )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  NOX11 should report $FFFF when Byte A Bit 4 (NOX11_DAT) is set\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $83  NOX12 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( (pPid->Data[0] & 0x20) != 0 && TempData_long != 0xFFFF )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  NOX12 should report $FFFF when Byte A Bit 5 (NOX12_DAT) is set\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = (pPid->Data[1] << 8) +
								                 pPid->Data[2];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $83  NOX21 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( (pPid->Data[0] & 0x40) != 0 && TempData_long != 0xFFFF )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  NOX21 should report $FFFF when Byte A Bit 6 (NOX21_DAT)is set\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $83  NOX22 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( (pPid->Data[0] & 0x80) != 0 && TempData_long != 0xFFFF )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  NOX22 should report $FFFF when Byte A Bit 7 (NOX22_DAT)is set\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long );
								}
							}
						}
						break;

						case 0x84:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $84  MST   = %d C\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] - 40 );
						}
						break;

						case 0x85:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $85  NOx Reagent data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  NOx Control System  support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  REAG_RATE_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  REAG_DEMD_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  REAG_LVL_SUP  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NWI_TIME_SUP  = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  NOx Reagent data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  NOx Reagent data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = ((pPid->Data[1] << 8) +
								                   pPid->Data[2]) * (float)0.005;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $85  REAG_RATE = %.3f L/h\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = ((pPid->Data[3] << 8) +
								                   pPid->Data[4]) * (float)0.005;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $85  REAG_DEMD = %.3f L/h\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = ( pPid->Data[5] * 100) / 255;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $85  REAG_LVL = %d %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = (pPid->Data[6] << 24) +
								                (pPid->Data[7] << 16) +
								                (pPid->Data[8] << 8) +
								                 pPid->Data[9];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $85  NWI_TIME = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $85  NWI_TIME = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}
						}
						break;

						case 0x86:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $86  PM data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Particulate Matter Sensor support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PM11_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PM21_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x03) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PM data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PM data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = ((pPid->Data[1] << 8) +
								                   pPid->Data[2]) * (float)0.0125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $86  PM11 = %.3f mg/m3\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = ((pPid->Data[3] << 8) +
								                   pPid->Data[4]) * (float)0.0125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $86  PM21 = %.3f mg/m3\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x87:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $87  MAP data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Intake Manifold Absolute Pressure support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  MAP_A_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  MAP_B_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x03) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  MAP data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  MAP data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_float = ((pPid->Data[1] << 8) +
								                   pPid->Data[2]) * (float)0.03125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $87  MAP_A = %.3f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
								{
									if ( (TempData_float == 0.0) && (gbHybrid != TRUE) )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  MAP_A must be non-zero when engine is running\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_float = ((pPid->Data[3] << 8) +
								                   pPid->Data[4]) * (float)0.03125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $87  MAP_B = %.3f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( bEngineDontCare == FALSE && gbEngineRunning == TRUE )  // test 5.10 & 10.13
								{
									if ( (TempData_float == 0.0) && (gbHybrid != TRUE) )
									{
										Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
										      "ECU %X  MAP_B must be non-zero when engine is running\n",
										      GetEcuId ( EcuIdx ) );
									}
								}
							}
						}
						break;

						case 0x88:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $88  SCR_INDUCE_SYSTEM = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  SCR inducement system actual state bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LEVEL_LOW          = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  INCORR_REAG        = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CONSUMP_DEVIATION  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOx_LEVEL          = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  ACTIVE             = %s\n",
							      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0x70 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  SCR_INDUCE_SYSTEM State  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}


							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $88  SCR_INDUCE_SYSTEM_HIST12 = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[1] );
							//  SCR inducement system state 10K history bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LEVEL_LOW1         = %s\n",
							      (pPid->Data[1] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  INCORR_REAG1       = %s\n",
							      (pPid->Data[1] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CONSUMP_DEVIATION1 = %s\n",
							      (pPid->Data[1] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOx_LEVEL1         = %s\n",
							      (pPid->Data[1] & 0x08) ? "YES" : "NO" );
							//  SCR inducement system state 20K history bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LEVEL_LOW2         = %s\n",
							      (pPid->Data[1] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  INCORR_REAG2       = %s\n",
							      (pPid->Data[1] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CONSUMP_DEVIATION2 = %s\n",
							      (pPid->Data[1] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOx_LEVEL2         = %s\n",
							      (pPid->Data[1] & 0x80) ? "YES" : "NO" );


							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $88  SCR_INDUCE_SYSTEM_HIST34 = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[2] );
							//  SCR inducement system state 30K history bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LEVEL_LOW3         = %s\n",
							      (pPid->Data[2] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  INCORR_REAG3       = %s\n",
							      (pPid->Data[2] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CONSUMP_DEVIATION3 = %s\n",
							      (pPid->Data[2] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOx_LEVEL3         = %s\n",
							      (pPid->Data[2] & 0x08) ? "YES" : "NO" );
							//  SCR inducement system state 40K history bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LEVEL_LOW4         = %s\n",
							      (pPid->Data[2] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  INCORR_REAG4       = %s\n",
							      (pPid->Data[2] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CONSUMP_DEVIATION4 = %s\n",
							      (pPid->Data[2] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOx_LEVEL4         = %s\n",
							      (pPid->Data[2] & 0x80) ? "YES" : "NO" );

							TempData_long = ((pPid->Data[3] << 8) +
							                  pPid->Data[4]);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $88  SCR_INDUCE_DIST_1N = %d km\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							TempData_long = ((pPid->Data[5] << 8) +
							                  pPid->Data[6]);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $88  SCR_INDUCE_DIST_1D = %d km\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							TempData_long = ((pPid->Data[7] << 8) +
							                  pPid->Data[8]);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $88  SCR_INDUCE_DIST_2N = %d km\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							TempData_long = ((pPid->Data[9] << 8) +
							                  pPid->Data[10]);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $88  SCR_INDUCE_DIST_3N = %d km\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							TempData_long = ((pPid->Data[11] << 8) +
							                  pPid->Data[12]);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $88  SCR_INDUCE_DIST_4N = %d km\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );
						}
						break;

						case 0x89:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $89  Run Time for AECD #11-#15 support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Engine Run Time for AECD #11 - #15 support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD11_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD12_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD13_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD14_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD15_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x1F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time for AECD #11-#15 support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xE0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time for AECD #11-#15 support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = (pPid->Data[1] << 24) +
								                (pPid->Data[2] << 16) +
								                (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD11_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD11_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[5] << 24) +
								                (pPid->Data[6] << 16) +
								                (pPid->Data[7] << 8) +
								                 pPid->Data[8];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD11_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD11_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = (pPid->Data[9] << 24) +
								                (pPid->Data[10] << 16) +
								                (pPid->Data[11] << 8) +
								                 pPid->Data[12];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD12_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD12_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[13] << 24) +
								                (pPid->Data[14] << 16) +
								                (pPid->Data[15] << 8) +
								                 pPid->Data[16];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD12_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD12_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = (pPid->Data[17] << 24) +
								                (pPid->Data[18] << 16) +
								                (pPid->Data[19] << 8) +
								                 pPid->Data[20];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD13_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD13_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[21] << 24) +
								                (pPid->Data[22] << 16) +
								                (pPid->Data[23] << 8) +
								                 pPid->Data[24];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD13_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD13_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = (pPid->Data[25] << 24) +
								                (pPid->Data[26] << 16) +
								                (pPid->Data[27] << 8) +
								                 pPid->Data[28];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD14_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD14_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[29] << 24) +
								                (pPid->Data[30] << 16) +
								                (pPid->Data[31] << 8) +
								                 pPid->Data[32];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD14_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD14_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x10) != 0 )
							{
								TempData_long = (pPid->Data[33] << 24) +
								                (pPid->Data[34] << 16) +
								                (pPid->Data[35] << 8) +
								                 pPid->Data[36];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD15_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD15_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[37] << 24) +
								                (pPid->Data[38] << 16) +
								                (pPid->Data[39] << 8) +
								                 pPid->Data[40];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD15_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $89  AECD15_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}
						}
						break;

						case 0x8A:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $8A  Run Time for AECD #16-#20 support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Engine Run Time for AECD #16 - #20 support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD16_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD17_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD18_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD19_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AECD20_TIME_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x1F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time for AECD #16-#20 support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xE0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Run Time for AECD #16-#20 support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( (pPid->Data[0] & 0x01) != 0 )
							{
								TempData_long = (pPid->Data[1] << 24) +
								                (pPid->Data[2] << 16) +
								                (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD16_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD16_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									     GetEcuId ( EcuIdx ),
									     TempData_long,
									     hours, mins, secs );
								}

								TempData_long = (pPid->Data[5] << 24) +
								                (pPid->Data[6] << 16) +
								                (pPid->Data[7] << 8) +
								                 pPid->Data[8];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD16_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD16_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x02) != 0 )
							{
								TempData_long = (pPid->Data[9] << 24) +
								                (pPid->Data[10] << 16) +
								                (pPid->Data[11] << 8) +
								                 pPid->Data[12];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD17_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD17_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[13] << 24) +
								                (pPid->Data[14] << 16) +
								                (pPid->Data[15] << 8) +
								                 pPid->Data[16];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD17_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD17_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x04) != 0 )
							{
								TempData_long = (pPid->Data[17] << 24) +
								                (pPid->Data[18] << 16) +
								                (pPid->Data[19] << 8) +
								                 pPid->Data[20];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD18_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD18_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[21] << 24) +
								                (pPid->Data[22] << 16) +
								                (pPid->Data[23] << 8) +
								                 pPid->Data[24];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD18_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD18_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x08) != 0 )
							{
								TempData_long = (pPid->Data[25] << 24) +
								                (pPid->Data[26] << 16) +
								                (pPid->Data[27] << 8) +
								                 pPid->Data[28];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD19_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD19_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}

								TempData_long = (pPid->Data[29] << 24) +
								                (pPid->Data[30] << 16) +
								                (pPid->Data[31] << 8) +
								                 pPid->Data[32];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD19_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD19_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}

							if ( (pPid->Data[0] & 0x10) != 0 )
							{
								TempData_long = (pPid->Data[33] << 24) +
								                (pPid->Data[34] << 16) +
								                (pPid->Data[35] << 8) +
								                 pPid->Data[36];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD20_TIME1 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD20_TIME1 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									     hours, mins, secs );
								}

								TempData_long = (pPid->Data[37] << 24) +
								                (pPid->Data[38] << 16) +
								                (pPid->Data[39] << 8) +
								                 pPid->Data[40];
								if ( TempData_long == -1 )
								{
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD20_TIME2 = n.a.\n" );
								}
								else
								{
									GetHoursMinsSecs( TempData_long, &hours, &mins, &secs );
									Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PID $8A  AECD20_TIME2 = %d sec (%d hrs, %d mins, %d secs)\n",
									      GetEcuId ( EcuIdx ),
									      TempData_long,
									      hours, mins, secs );
								}
							}
						}
						break;

						case 0x8B:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $8B  Diesel Aftertreatment support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Aftertreatment Status support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PF_REGEN_STAT_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PF_REGEN_TYPE_SUP  = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX_ADS_REGEN_SUP  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX_ADS_DESULF_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PF_REGEN_PCT_SUP   = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PF_REGEN_AVGT_SUP  = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PF_REGEN_AVGD_SUP  = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );

							// check that reserved bit is not set
							if ( pPid->Data[0] & 0x80 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Diesel Aftertreatment Status support reserved bit 7 set\n",
								      GetEcuId ( EcuIdx ) );
							}

							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $8B  Diesel Aftertreatment Status = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[1] );
							// Diesel Aftertreatment Status bits
							if ( pPid->Data[0] & 0x01 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  DPF_REGEN_STATUS = %s\n",
								      (pPid->Data[1] & 0x01) ? "IN PROGRESS" : "NOT IN PROGRESS" );
							}
							if ( pPid->Data[0] & 0x02 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  DPF_REGEN_TYPE   = %s\n",
								      (pPid->Data[1] & 0x02) ? "ACTIVE" : "PASSIVE" );
							}
							if ( pPid->Data[0] & 0x04 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  NOX_ADS_REGEN    = %s\n",
								      (pPid->Data[1] & 0x04) ? "IN PROGRESS" : "NOT IN PROGRESS" );
							}
							if ( pPid->Data[0] & 0x08 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  NOX_ADS_DESULF   = %s\n",
								      (pPid->Data[1] & 0x08) ? "IN PROGRESS" : "NOT IN PROGRESS" );
							}

							// check that reserved bits are not set
							if ( pPid->Data[1] & 0xF0 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Diesel Aftertreatment Status  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}


							if ( pPid->Data[0] & 0x10 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8B  DPF_REGEN_PCT  = %.1f %%\n",
								      GetEcuId ( EcuIdx ),
								      (float)pPid->Data[2] * (float)(100.0 / 255.0) );
							}

							if ( pPid->Data[0] & 0x20 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8B  DPF_REGEN_AVGT = %d minutes\n",
								      GetEcuId ( EcuIdx ),
								      (pPid->Data[3] << 8) +
								      pPid->Data[4] );
							}

							if ( pPid->Data[0] & 0x40 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8B  DPF_REGEN_AVGD = %d km\n",
								      GetEcuId ( EcuIdx ),
								      (pPid->Data[5] << 8) +
								      pPid->Data[6] );
							}
						}
						break;

						case 0x8C:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $8C  O2 Sensor (Wide Range) support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// O2 Sensor (Wide Range) support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  O2S11_PCT_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  O2S12_PCT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  O2S21_PCT_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  O2S22_PCT_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LAMBDA11_SUP  = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LAMBDA12_SUP  = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LAMBDA21_SUP  = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LAMBDA22_SUP  = %s\n",
							      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							// display associated values
							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = (float)((pPid->Data[1] << 8) +
								                          pPid->Data[2]) * (float)(.001526);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8C  O2S11_PCT = %3.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((pPid->Data[3] << 8) +
								                          pPid->Data[4]) * (float)(.001526);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8C  O2S12_PCT = %3.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = (float)((pPid->Data[5] << 8) +
								                          pPid->Data[6]) * (float)(.001526);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8C  O2S21_PCT = %3.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x08 )
							{
								TempData_float = (float)((pPid->Data[7] << 8) +
								                          pPid->Data[8]) * (float)(.001526);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8C  O2S22_PCT = %3.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x10 )
							{
								TempData_float = (float)((pPid->Data[9] << 8) +
								                          pPid->Data[10]) * (float)(.000122);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8C  LAMBDA11 = %.3f\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x20 )
							{
								TempData_float = (float)((pPid->Data[11] << 8) +
								                          pPid->Data[12]) * (float)(.000122);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8C  LAMBDA12 = %.3f\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x40 )
							{
								TempData_float = (float)((pPid->Data[13] << 8) +
								                          pPid->Data[14]) * (float)(.000122);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8C  LAMBDA21 = %.3f\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x80 )
							{
								TempData_float = (float)((pPid->Data[15] << 8) +
								                          pPid->Data[16]) * (float)(.000122);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8C  LAMBDA22 = %.3f\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x8D:
						{
							TempData_float = (float)pPid->Data[0] * (float)(100.0 / 255.0);
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $8D  TP_G  = %.1f %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
						}
						break;

						case 0x8E:
						{
							TempData_long = (signed long)(pPid->Data[0]) - 125;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $8E  TQ_FR = %d %%\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );
						}
						break;

						case 0x8F:
						{
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $8F  PM Sensor support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Particulate Matter (PM) Sensor Output support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PM11_STA_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PM11_SUP     = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PM21_STA_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  PM21_SUP     = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PM Sensor Data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}
							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PM Sensor Data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							// PM Sensor Operating Status Bank 1 Sensor 1
							if ( pPid->Data[0] & 0x01 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8F  PM11 Sensor status = $%02X\n",
								      GetEcuId ( EcuIdx ),
								      pPid->Data[1] );

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  PM11_ACTIVE = %s\n",
								      (pPid->Data[1] & 0x01) ? "YES" : "NO" );

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  PM11_REGEN  = %s\n",
								      (pPid->Data[1] & 0x02) ? "YES" : "NO" );

								// check that reserved bit is not set
								if ( pPid->Data[1] & 0xFC )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PM11 Sensor Operating Status  Reserved bits set\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							// PM Sensor Normalized Output Bank 1 Sensor 1
							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((signed short)((pPid->Data[2] << 8) +
								                                         pPid->Data[3])) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8F  PM11        = %3.2f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( TempData_float < -100 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PM11 must be greater than -100%%\n",
									      GetEcuId ( EcuIdx ),
									      TempData_float );
								}
							}

							// PM Sensor Operating Status Bank 2 Sensor 1
							if ( pPid->Data[0] & 0x04 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8F  PM21 Sensor status = $%02X\n",
								      GetEcuId ( EcuIdx ),
								      pPid->Data[4] );

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  PM21_ACTIVE = %s\n",
								     (pPid->Data[4] & 0x01) ? "YES" : "NO" );

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  PM21_REGEN  = %s\n",
								     (pPid->Data[4] & 0x02) ? "YES" : "NO" );

								if ( pPid->Data[4] & 0xFC )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PM21 Sensor Operating Status  Reserved bits set\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							// PM Sensor Normalized Output Bank 2 Sensor 1
							if ( pPid->Data[0] & 0x08 )
							{
								TempData_float = (float)((signed short)((pPid->Data[5] << 8) +
								                                         pPid->Data[6])) * (float)0.01;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $8F  PM21        = %.2f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( TempData_float < -100 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  PM21 must be greater than -100%%\n",
									      GetEcuId ( EcuIdx ),
									      TempData_float );
								}
							}
						}
						break;

						case 0x90:
						{
							// WWH-OBD Vehicle OBD System Information
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $90  WWH-OBD Vehicle OBD System Information = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  MI_DISP_VOBD = $%02X\n",
							      pPid->Data[0] & 0x03 );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  MI_MODE_VOBD = $%02X\n",
							      (pPid->Data[0] & 0x3C) >> 2 );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  VOBD_RDY     = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0x80 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  WWH-OBD Vehicle OBD System Information  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							TempData_long = (pPid->Data[1] << 8) +
							                 pPid->Data[2];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $90  VOBD_MI_TIME = %d hrs\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );
						}
						break;

						case 0x91:
						{
							// WWH-OBD Vehicle OBD System Information
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $91  WWH-OBD ECU OBD System Information  = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  MI_MODE_ECU = $%02X\n",
							      pPid->Data[0] & 0x0F );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  WWH-OBD ECU OBD System Information support  Reserved bits set\n",
							      GetEcuId ( EcuIdx ) );
							}

							TempData_long = (pPid->Data[1] << 8) +
							                 pPid->Data[2];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $91  OBD_MI_TIME = %d hrs\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );

							TempData_long = (pPid->Data[3] << 8) +
							                 pPid->Data[4];
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $91  OBD_B1_TIME = %d hrs\n",
							      GetEcuId ( EcuIdx ),
							      TempData_long );
						}
						break;

						case 0x92:
						{
							// Fuel System Control Status (Compression Ignition)
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $92  Fuel System Control Status support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Fuel System Status support bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FP1_CL_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FIQ1_CL_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FIT1_CL_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IFB1_CL_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FP2_CL_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FIQ2_CL_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FIT2_CL_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  IFB2_CL_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0xFF) == 0 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "         Fuel System Control Status support  No data supported\n" );
							}

							// Fuel System Status
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $92  FUELSYS = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[1] );
							// Fuel Pressure Control 1 Status
							if ( pPid->Data[0] & 0x01 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  FP1_CL  = %c\n",
								      (pPid->Data[1] & 0x01) ? '1' : '0' );
							}
							// Fuel Injection Quantity Control 1 Status
							if ( pPid->Data[0] & 0x02 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  FIQ1_CL = %c\n",
								      (pPid->Data[1] & 0x02) ? '1' : '0' );
							}
							// Fuel Injection Timing Control 1 Status
							if ( pPid->Data[0] & 0x04 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  FIT1_CL = %c\n",
								      (pPid->Data[1] & 0x04) ? '1' : '0' );
							}
							// Idle Fuel Balance/Contribution Control 1 Status
							if ( pPid->Data[0] & 0x08 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  IFB1_CL = %c\n",
								      (pPid->Data[1] & 0x08) ? '1' : '0' );
							}
							// Fuel Pressure Control 2 Status
							if ( pPid->Data[0] & 0x10 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  FP2_CL  = %c\n",
								      (pPid->Data[1] & 0x10) ? '1' : '0' );
							}
							// Fuel Injection Quantity Control 2 Status
							if ( pPid->Data[0] & 0x20 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  FIQ2_CL = %c\n",
								      (pPid->Data[1] & 0x20) ? '1' : '0' );
							}
							// Fuel Injection Timing Control 2 Status
							if ( pPid->Data[0] & 0x40 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  FIT2_CL = %c\n",
								      (pPid->Data[1] & 0x40) ? '1' : '0' );
							}
							// Idle Fuel Balance/Contribution Control 2 Status
							if ( pPid->Data[0] & 0x80 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  IFB2_CL = %c\n",
								      (pPid->Data[1] & 0x80) ? '1' : '0' );
							}
						}
						break;

						case 0x93:
						{
							// WWH-OBD Vehicle OBD Counters support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $93  WWH-OBD Vehicle OBD Counters support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  WWH-OBD Vehicle Counters support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  MI_TIME_CUM_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFE )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  WWH-OBD Vehicle OBD Counters support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_long = (pPid->Data[1] << 8) +
								                 pPid->Data[2];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $93  MI_TIME_CUM = %d hrs\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0x94:
						{
							// NOx Warning And Inducement System support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $94  NOx Warning And Inducement System support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  NOx control - driver inducement system support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX_WARN_ACT_STA_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  REAG_QUAL_TIME_SUP   = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  REAG_CON_TIME_SUP    = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  REAG_DOSE_TIME_SUP   = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGR_TIME_SUP         = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX_DTC_TIME_SUP     = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x3F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  NOx Warning And Inducement System support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xC0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  NOx Warning And Inducement System support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							// NOx Warning And Inducement System support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $94  NOx Warning And Inducement System status = $%02X\n",
							      GetEcuId ( EcuIdx ),
							     pPid->Data[1] );
							if ( pPid->Data[0] & 0x01 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  NOX_WARN_ACT = %s\n",
								      (pPid->Data[1] & 0x01) ? "YES" : "NO" );

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  INDUC_L1 = $%02X\n",
								      (pPid->Data[1] & 0x06) >> 1 );

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  INDUC_L2 = $%02X\n",
								      (pPid->Data[1] & 0x18) >> 3 );

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  INDUC_L3 = $%02X\n",
								      (pPid->Data[1] & 0x60) >> 5 );

								if ( pPid->Data[0] & 0x80 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  NOx Warning And Inducement Ststem status  Reserved bits set\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							TempData_long = (pPid->Data[2] << 8) +
							                 pPid->Data[3];
							if ( pPid->Data[0] & 0x02 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $94  REAG_QUAL_TIME = %d hrs\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
							else if ( TempData_long != 65535 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  REAG_QUAL_TIME must be 65535 if it is not supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							TempData_long = (pPid->Data[4] << 8) +
							                 pPid->Data[5];
							if ( pPid->Data[0] & 0x04 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $94  REAG_CON_TIME  = %d hrs\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
							else if ( TempData_long != 65535 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  REAG_CON_TIME must be 65535 if it is not supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							TempData_long = (pPid->Data[6] << 8) +
							                 pPid->Data[7];
							if ( pPid->Data[0] & 0x08 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $94  REAG_DOSE_TIME = %d hrs\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
							else if ( TempData_long != 65535 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  REAG_DOSE_TIME must be 65535 if it is not supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							TempData_long = (pPid->Data[8] << 8) +
							                 pPid->Data[9];
							if ( pPid->Data[0] & 0x10 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $94  EGR_TIME       = %d hrs\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
							else if ( TempData_long != 65535 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGR_TIME must be 65535 if it is not supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							TempData_long = (pPid->Data[10] << 8) +
							                 pPid->Data[11];
							if ( pPid->Data[0] & 0x20 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $94  NOX_DTC_TIME   = %d hrs\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
							else if ( TempData_long != 65535 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  NOX_DTC_TIME must be 65535 if it is not supported\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x95:
						{
							// SCR Catalyst NH3 Storage data support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $95  SCR Catalyst NH3 Storage data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  SCR Catalyst NH3 Storage data support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  SCR_NH3_TGT_A_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  SCR_NH3_ACT_A_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  SCR_NH3_TGT_B_SUP  = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  SCR_NH3_ACT_B_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  SCR Catalyst NH3 Storage data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}


							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = ((pPid->Data[1] << 8) +
								                   pPid->Data[2]) * (float)(.0001);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $95  SCR_NH3_TGT_A = %f g/l\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = ((pPid->Data[3] << 8) +
								                   pPid->Data[4]) * (float)(.0001);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $95  SCR_NH3_ACT_A = %f g/l\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = ((pPid->Data[5] << 8) +
								                   pPid->Data[6]) * (float)(.0001);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $95  SCR_NH3_TGT_B = %f g/l\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x08 )
							{
								TempData_float = ((pPid->Data[7] << 8) +
								                   pPid->Data[8]) * (float)(.0001);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $95  SCR_NH3_ACT_B = %f g/l\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x96:
						{
							// Hydrocarbon Doser data support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $96  Hydrocarbon Doser data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  Hydrocarbon Doser data support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  HC_INJ_F_SUP  = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  HC_INJ_DC_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AFT_FP_SUP    = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF8 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Hydrocarbon Doser data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}


							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = ((pPid->Data[1] << 8) +
								                   pPid->Data[2]) * (float)(.05);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $96  HC_INJ_F = %f g/min\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_long = (pPid->Data[3] * 100) / 255;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $96  HC_INJ_DC = %d %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = ((pPid->Data[4] << 8) +
								                   pPid->Data[5]) * (float)(.1);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $96  AFT_FP = %f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x97:
						{
							// NOx Mass Emission Rate data support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $97  NOx Mass Emission Rate data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							//  NOx Mass Emission Rate data support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOx_EO = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOx_TP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  NOx Mass Emission Rate data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}


							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = ((pPid->Data[1] << 8) +
								                   pPid->Data[2]) * (float)(.0001);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $97  NOx_EO = %f g/s\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = ((pPid->Data[3] << 8) +
								                   pPid->Data[4]) * (float)(.0001);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $97  NOx_TP = %f g/s\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x98:
						{
							// Exhaust Gas Temperature Sensor support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $98  Exhaust Gas Temperature Sensor Bank 1 support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Exhaust Gas Temperature Sensor support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT15_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT16_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT17_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT18_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Exhaust Gas Temperature Sensor Bank 1 support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Exhaust Gas Temperature Sensor Bank 1 support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = ((float)((pPid->Data[1] << 8) +
								                           pPid->Data[2]) * (float).1) - (float)40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $98  EGT15 = %.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = ((float)((pPid->Data[3] << 8) +
								                           pPid->Data[4]) * (float).1) - (float)40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $98  EGT16 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = ((float)((pPid->Data[5] << 8) +
								                           pPid->Data[6]) * (float).1) - (float)40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $98  EGT17 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x08 )
							{
								TempData_float = ((float)((pPid->Data[7] << 8) +
								                           pPid->Data[8]) * (float).1) - (float)40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $98  EGT18 = %3.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x99:
						{
							// Exhaust Gas Temperature Sensor support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $99  Exhaust Gas Temperature Sensor Bank 2 support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Exhaust Gas Temperature Sensor support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT25_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT26_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT27_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGT28_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Exhaust Gas Temperature Sensor Bank 2 support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Exhaust Gas Temperature Sensor Bank 2 support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = ((float)((pPid->Data[1] << 8) +
								                           pPid->Data[2]) * (float).1) - (float)40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $99  EGT25 = %.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = ((float)((pPid->Data[3] << 8) +
								                           pPid->Data[4]) * (float).1) - (float)40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $99  EGT26 = %.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = ((float)((pPid->Data[5] << 8) +
								                           pPid->Data[6]) * (float).1) - (float)40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $99  EGT27 = %.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x08 )
							{
								TempData_float = ((float)((pPid->Data[7] << 8) +
								                           pPid->Data[8]) * (float).1) - (float)40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $99  EGT28 = %.1f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x9A:
						{
							// Hybrid/EV Vehicle System Data support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $9A  Hybrid/EV Vehicle System Data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Hybrid/EV Vehicle System Data support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  HEV_MODE_SUP     = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  HEV_BATT_V_SUP   = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  HEV_BATT_A_SUP   = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  HEV_MODE_ENH_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Hybrid/EV Vehicle System Data support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							// Hybrid/EV Vehicle state
							if ( pPid->Data[0] & 0x01 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9A  HEV_MODE    = $%02X\n",
								      GetEcuId ( EcuIdx ),
								      pPid->Data[1] & 0x01 );
							}

							// Enhanced Hybrid/EV Vehicle state
							if ( pPid->Data[0] & 0x08 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9A  HEV_MODE_ENH = $%02X\n",
								      GetEcuId ( EcuIdx ),
								      (pPid->Data[1] & 0x06) >> 1 );
							}

							// Check if reserved bits set
							if ( pPid->Data[1] & 0xF8 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  HEV_MODE (Hybrid/EV Vehicle Charging state)  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}


							// Hybrid/EV Battery System Voltage
							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((unsigned short)((pPid->Data[2] << 8) +
								                                           pPid->Data[3])) * (float)0.015625;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9A  HEV_BATT_V  = %.6f V\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( TempData_float <= 0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  HEV_BATT_V must be greater than 0 V\n",
									      GetEcuId ( EcuIdx ),
									      TempData_float );
								}
							}

							// Hybrid/EV Battery System Current
							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = (float)((signed short)((pPid->Data[4] << 8) +
								                                         pPid->Data[5])) * (float)0.1;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9A  HEV_BATT_A  = %.2f A\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x9B:
						{
							// Diesel Exhaust Fluid Sensor Data support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $9B  Diesel Exhaust Fluid Sensor Data support = $%1X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] & 0x0F );
							// Diesel Exhaust Fluid Sensor Data support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DEF_TYPE_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DEF_CON_SUP  = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DEF_T_SUP    = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DEF_LVL_SUP  = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x07) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Diesel Exhaust Fluid Sensor Data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							// Diesel Exhaust Fluid Type
							if ( pPid->Data[0] & 0x01 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9B  DEF_TYPE = $%1X\n",
								      GetEcuId ( EcuIdx ),
								      (pPid->Data[0] >> 4) );
							}

							// Diesel Exhaust Fluid Concentration
							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[1])) * (float)0.25;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9B  DEF_CON  = %.2f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							// Diesel Exhaust Fluid Tank Temperature
							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[2])) - (float)40.00;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9B  DEF_T    = %f C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							// Diesel Exhaust Fluid Tank Level
							if ( pPid->Data[0] & 0x08 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[3])) * (float)(100.0/255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9B  DEF_LVL  = %.2f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x9C:
						{
							// Exhaust Gas Temperature Sensor support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $9C  O2 Sensor Data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Exhaust Gas Temperature Sensor support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  O2S13_PCT_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  O2S14_PCT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  O2S23_PCT_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  O2S24_PCT_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LAMBDA13_SUP  = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LAMBDA14_SUP  = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LAMBDA23_SUP  = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  LAMBDA24_SUP  = %s\n",
							      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0xFF) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  O2 Sensor Data support  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = (float)((pPid->Data[1] << 8) +
								                          pPid->Data[2]) * (float).001526;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9C  O2S13_PCT = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((pPid->Data[3] << 8) +
								                          pPid->Data[4]) * (float).001526;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9C  O2S14_PCT = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = (float)((pPid->Data[5] << 8) +
								                          pPid->Data[6]) * (float).001526;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9C  O2S23_PCT = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x08 )
							{
								TempData_float = (float)((pPid->Data[7] << 8) +
								                          pPid->Data[8]) * (float).001526;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9C  O2S24_PCT = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x10 )
							{
								TempData_float = (float)((pPid->Data[9] << 8) +
								                          pPid->Data[10]) * (float).000122;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9C  LAMBDA13 = %.6f\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x20 )
							{
								TempData_float = (float)((pPid->Data[11] << 8) +
								                          pPid->Data[12]) * (float).000122;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9C  LAMBDA14 = %.6f\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x40 )
							{
								TempData_float = (float)((pPid->Data[13] << 8) +
								                          pPid->Data[14]) * (float).000122;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9C  LAMBDA23 = %.6f\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x80 )
							{
								TempData_float = (float)((pPid->Data[15] << 8) +
								                          pPid->Data[16]) * (float).000122;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9C  LAMBDA24 = %.6f\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0x9D:
						{
							// Engine Fuel Rate
							TempData_float = (float)((unsigned short)((pPid->Data[0] << 8) +
							                                           pPid->Data[1])) * (float).02;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $9D  ENG_FUEL_RATE = %.2f g/s\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( gbEngineRunning == FALSE && TempData_float != 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  ENG_FUEL_RATE must be 0 g/s when engine is not running\n",
								      GetEcuId ( EcuIdx ) );
							}
							else if ( gbEngineRunning == TRUE && TempData_float == 0 && gbHybrid != TRUE )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  ENG_FUEL_RATE must be greater than 0 g/s when engine is running\n",
								      GetEcuId ( EcuIdx ) );
							}

							TempData_float = (float)((unsigned short)((pPid->Data[2] << 8) +
							                                           pPid->Data[3])) * (float).02;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $9D  VEH_FUEL_RATE = %.2f g/s\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( gbEngineRunning == FALSE && TempData_float != 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  VEH_FUEL_RATE must be 0 g/s when engine is not running\n",
								      GetEcuId ( EcuIdx ) );
							}
							else if ( gbEngineRunning == TRUE && TempData_float == 0 && gbHybrid != TRUE )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  VEH_FUEL_RATE must be greater than 0 g/s when engine is running\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x9E:
						{
							// Engine Exhaust Flow Rate
							TempData_float = (float)((unsigned short)((pPid->Data[0] << 8) +
							                                           pPid->Data[1])) * (float).2;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $9E  EXH_RATE = %.2f kg/h\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( gbEngineRunning == FALSE && TempData_float != 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EXH_RATE must be 0 kg/h when engine is not running\n",
								      GetEcuId ( EcuIdx ) );
							}
							else if ( gbEngineRunning == TRUE && TempData_float == 0 && gbHybrid != TRUE )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EXH_RATE must be greater than 0 kg/h when engine is running\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0x9F:
						{
							// Fuel System Percentage Use support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $9F  Fuel System Percentage Use support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Fuel System Percentage Use support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FUELSYSA_B1_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FUELSYSB_B1_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FUELSYSA_B2_SUP = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FUELSYSB_B2_SUP = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FUELSYSA_B3_SUP = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FUELSYSB_B3_SUP = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FUELSYSA_B4_SUP = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FUELSYSB_B4_SUP = %s\n",
							      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x03) == 0 &&  // bits 0,1  Fuel System A,B uses Bank 1
							     (pPid->Data[0] & 0x0C) == 0 &&  // bits 2,3  Fuel System A,B uses Bank 2
							     (pPid->Data[0] & 0x30) == 0 &&  // bits 4,5  Fuel System A,B uses Bank 3
							     (pPid->Data[0] & 0xC0) == 0 )   // bits 6,7  Fuel System A,B uses Bank 4
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Fuel System Percentage Use support  (At least one bank must be supported)\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[1]) * (float)(100.0/255.0));
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9F  FUELSYSA_B1 = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE && TempData_float != 0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FUELSYSA_B1 must be 0 %% when engine is not running\n",
									      GetEcuId ( EcuIdx ) );
								}
								else if ( (gbEngineRunning == TRUE && TempData_float != 0) ||
								          gbHybrid == TRUE )
								{
									bPid9FSuccess = TRUE;
								}
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[2])) * (float)(100.0/255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9F  FUELSYSB_B1 = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE && TempData_float != 0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FUELSYSB_B1 must be 0 %% when engine is not running\n",
									      GetEcuId ( EcuIdx ) );
								}
								else if ( (gbEngineRunning == TRUE && TempData_float != 0) ||
								          gbHybrid == TRUE )
								{
									bPid9FSuccess = TRUE;
								}
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[3])) * (float)(100.0/255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9F  FUELSYSA_B2 = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE && TempData_float != 0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FUELSYSA_B2 must be 0 %% when engine is not running\n",
									      GetEcuId ( EcuIdx ) );
								}
								else if ( (gbEngineRunning == TRUE && TempData_float != 0) ||
								          gbHybrid == TRUE )
								{
									bPid9FSuccess = TRUE;
								}
							}

							if ( pPid->Data[0] & 0x08 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[4])) * (float)(100.0/255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9F  FUELSYSB_B2 = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE && TempData_float != 0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FUELSYSB_B2 must be 0 %% when engine is not running\n",
									      GetEcuId ( EcuIdx ) );
								}
								else if ( (gbEngineRunning == TRUE && TempData_float != 0) ||
								          gbHybrid == TRUE )
								{
									bPid9FSuccess = TRUE;
								}
							}

							if ( pPid->Data[0] & 0x10 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[5])) * (float)(100.0/255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9F  FUELSYSA_B3 = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE && TempData_float != 0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FUELSYSA_B3 must be 0 %% when engine is not running\n",
									      GetEcuId ( EcuIdx ) );
								}
								else if ( (gbEngineRunning == TRUE && TempData_float != 0) ||
								          gbHybrid == TRUE )
								{
									bPid9FSuccess = TRUE;
								}
							}

							if ( pPid->Data[0] & 0x20 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[6])) * (float)(100.0/255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9F  FUELSYSB_B3 = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE && TempData_float != 0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FUELSYSB_B3 must be 0 %% when engine is not running\n",
									      GetEcuId ( EcuIdx ) );
								}
								else if ( (gbEngineRunning == TRUE && TempData_float != 0) ||
								          gbHybrid == TRUE )
								{
									bPid9FSuccess = TRUE;
								}
							}

							if ( pPid->Data[0] & 0x40 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[7])) * (float)(100.0/255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9F  FUELSYSA_B4 = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE && TempData_float != 0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FUELSYSA_B4 must be 0 %% when engine is not running\n",
									      GetEcuId ( EcuIdx ) );
								}
								else if ( (gbEngineRunning == TRUE && TempData_float != 0) ||
								          gbHybrid == TRUE )
								{
									bPid9FSuccess = TRUE;
								}
							}

							if ( pPid->Data[0] & 0x80 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[8])) * (float)(100.0/255.0);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $9F  FUELSYSB_B4 = %.6f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );

								if ( gbEngineRunning == FALSE && TempData_float != 0 )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  FUELSYSB_B4 must be 0 %% when engine is not running\n",
									      GetEcuId ( EcuIdx ) );
								}
								else if ( (gbEngineRunning == TRUE && TempData_float != 0) ||
								          gbHybrid == TRUE )
								{
									bPid9FSuccess = TRUE;
								}
							}

							if ( bPid9FSuccess == FALSE && gbEngineRunning == TRUE)
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  At least one of the FUELSYS banks must be greater than 0 %% when engine is running\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0xA1:
						{
							// NOx Sensor Corrected Data support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $A1  NOx Sensor Corrected Data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// NOx Sensor Corrected Data support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC11_SUP       = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC21_SUP       = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC12_SUP       = %s\n",
							      (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC22_SUP       = %s\n",
							      (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC11_DAT_AVAIL = %s\n",
							      (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC11_DAT_AVAIL = %s\n",
							      (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC11_DAT_AVAIL = %s\n",
							      (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC11_DAT_AVAIL = %s\n",
							      (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x0F) == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  NOx Sensor Corrected Data  No data supported\n",
								      GetEcuId ( EcuIdx ) );
							}


							if ( pPid->Data[0] & 0x01 )
							{
								TempData_long = (unsigned short)((pPid->Data[1] << 8) +
								                                  pPid->Data[2]);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A1  NOXC11 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( (pPid->Data[0] & 0x10) == 0x10 && TempData_float != 0xFFFF )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  NOXC11 Data Availability Bit Set, Sensor Data should report $FFFF\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_long = (unsigned short)((pPid->Data[3] << 8) +
								                                  pPid->Data[4]);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A1  NOXC12 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( (pPid->Data[0] & 0x20) == 0x20 && TempData_float != 0xFFFF )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  NOXC12 Data Availability Bit Set, Sensor Data should report $FFFF\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_long = (unsigned short)((pPid->Data[5] << 8) +
								                                  pPid->Data[6]);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A1  NOXC21 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( (pPid->Data[0] & 0x40) == 0x40 && TempData_long != 0xFFFF )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  NOXC21 Data Availability Bit Set, Sensor Data should report $FFFF\n",
									      GetEcuId ( EcuIdx ) );
								}
							}

							if ( pPid->Data[0] & 0x08 )
							{
								TempData_long = (unsigned short)((pPid->Data[7] << 8) +
								                                  pPid->Data[8]);
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A1  NOXC22 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );

								if ( (pPid->Data[0] & 0x80) == 0x80 && TempData_long != 0xFFFF )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  NOXC22 Data Availability Bit Set, Sensor Data should report $FFFF\n",
									      GetEcuId ( EcuIdx ) );
								}
							}
						}
						break;

						case 0xA2:
						{
							// Cylinder Fuel Rate
							TempData_float = (float)((unsigned short)((pPid->Data[0] << 8) +
							                                           pPid->Data[1])) * (float)0.03125;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $A2  CYL_RATE = %.5f mg/stroke\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );

							if ( gbEngineRunning == FALSE && TempData_float != 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  CYL_RATE must be 0 mg/stroke when engine is not running\n",
								      GetEcuId ( EcuIdx ) );
							}
							else if ( gbEngineRunning == TRUE && TempData_float == 0 && gbHybrid != TRUE )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  CYL_RATE must be greater than 0 mg/stroke when engine is running\n",
								      GetEcuId ( EcuIdx ) );
							}
						}
						break;

						case 0xA3:
						{
							// Evap System Vapor Pressure Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $A3  Evaporative System Vapor Pressure support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Evap System Vapor Pressure Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EVAP_A_VP_SUP    = %s\n",
							     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EVAP_A_VP_WR_SUP = %s\n",
							     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EVAP_B_VP_SUP    = %s\n",
							     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EVAP_B_VP_WR_SUP = %s\n",
							     (pPid->Data[0] & 0x08) ? "YES" : "NO" );

							// check that required bit is set
							if ( (pPid->Data[0] & 0x03) == 0x03 ||
							     (pPid->Data[0] & 0x0C) == 0x0C )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Evaporative System Vapor Pressure support  Two different scaling ranges supported for the same sensor\n",
								      GetEcuId ( EcuIdx ) );
							}

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xF0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Evaporative System Vapor Pressure support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = (float)((signed short)((pPid->Data[1] << 8) +
								                                         pPid->Data[2])) * (float)0.25;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A3  EVAP_A_VP = %.2f Pa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_long = (signed short)((pPid->Data[3] << 8) +
								                                 pPid->Data[4]) * 2;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A3  EVAP_A_VP (Wide Range) = %d Pa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = (float)((signed short)((pPid->Data[5] << 8) +
								                                         pPid->Data[6])) * (float)0.25;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A3  EVAP_B_VP = %.2f Pa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x08 )
							{
								TempData_long = (signed short)((pPid->Data[7] << 8) +
								                                pPid->Data[8]) * 2;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A3  EVAP_B_VP (Wide Range) = %d Pa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0xA4:
						{
							// Transmission Actual Gear Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $A4  Transmission Actual Gear Status support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Transmission Actual Gear Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  GEAR_ACT_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  GEAR_RAT_SUP = %s\n",
							      (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Transmission Actual Gear Status support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A4  GEAR_ACT = $%02X (%s)\n",
								      GetEcuId ( EcuIdx ),
								      (pPid->Data[1] >> 4),
								      szGEAR[pPid->Data[1] >> 4] );
							}

								// check that reserved bits are not set
								if ( pPid->Data[1] & 0x0F )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  Transmission Actual Gear Status  Reserved bits set\n",
									      GetEcuId ( EcuIdx ) );
								}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((unsigned short)((pPid->Data[2] << 8) +
								                                           pPid->Data[3])) * (float)0.001;

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A4  GEAR_RAT = %.3f\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0xA5:
						{
							// Diesel Exhaust Fluid Dosing Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $A5  Commanded DEF Dosing support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Diesel Exhaust Fluid Dosing Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DEF_CMD_SUP  = %s\n",
							     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DEF_UCDC_SUP = %s\n",
							     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Commanded DEF Dosing support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = (float)((unsigned short)(pPid->Data[1])) * (float)0.5;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A5  DEF_CMD  = %f %%\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((unsigned short)((pPid->Data[2] << 8) +
								                                           pPid->Data[3])) * (float)0.0005;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A5  DEF_UCDC = %.4f L\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0xA6:
						{
							TempData_float = (float)((unsigned short)(pPid->Data[0] << 24) +
							                                         (pPid->Data[1] << 16) +
							                                         (pPid->Data[2] << 8) +
							                                          pPid->Data[3]) * (float)0.1;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $A5  ODO = %.1f km (%.1f miles)\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float,
							      TempData_float/(float)1.609344 );
						}
						break;

						case 0xA7:
						{
							// NOx Sensor Data Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $A7  NOx Sensor Data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// NOx Sensor Data Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX13_SUP       = %s\n",
							     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX14_SUP       = %s\n",
							     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX23_SUP       = %s\n",
							     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX24_SUP       = %s\n",
							     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX13_DAT_AVAIL = %s\n",
							     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX14_DAT_AVAIL = %s\n",
							     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX23_DAT_AVAIL = %s\n",
							     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOX24_DAT_AVAIL = %s\n",
							     (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							if ( pPid->Data[0] & 0x01 && pPid->Data[0] & 0x10 )
							{
								TempData_long = (pPid->Data[1] << 8) +
								                  pPid->Data[2];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A7  NOX13 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x02 && pPid->Data[0] & 0x20)
							{
								TempData_long = (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A7  NOX14 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x04 && pPid->Data[0] & 0x40 )
							{
								TempData_long = (pPid->Data[5] << 8) +
								                 pPid->Data[6];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A7  NOX23 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x08 && pPid->Data[0] & 0x80 )
							{
								TempData_long = (pPid->Data[7] << 8) +
								                 pPid->Data[8];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A7  NOX24 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0xA8:
						{
							// NOx Sensor Corrected Data Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $A8  NOx Sensor Data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// NOx Sensor Corrected Data Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC13_SUP       = %s\n",
							     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC14_SUP       = %s\n",
							     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC23_SUP       = %s\n",
							     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC24_SUP       = %s\n",
							     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC13_DAT_AVAIL = %s\n",
							     (pPid->Data[0] & 0x10) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC14_DAT_AVAIL = %s\n",
							     (pPid->Data[0] & 0x20) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC23_DAT_AVAIL = %s\n",
							     (pPid->Data[0] & 0x40) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  NOXC24_DAT_AVAIL = %s\n",
							     (pPid->Data[0] & 0x80) ? "YES" : "NO" );

							if ( pPid->Data[0] & 0x01 && pPid->Data[0] & 0x10 )
							{
								TempData_long = (pPid->Data[1] << 8) +
								                 pPid->Data[2];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A8  NOXC13 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x02 && pPid->Data[0] & 0x20)
							{
								TempData_long = (pPid->Data[3] << 8) +
								                 pPid->Data[4];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A8  NOXC14 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x04 && pPid->Data[0] & 0x40 )
							{
								TempData_long = (pPid->Data[5] << 8) +
								                 pPid->Data[6];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A8  NOXC23 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x08 && pPid->Data[0] & 0x80 )
							{
								TempData_long = (pPid->Data[7] << 8) +
								                 pPid->Data[8];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A8  NOXC24 = %d ppm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0xA9:
						{
							// Motorcycle Input/Output Status Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $A9  Motorcycle Input/Output Status support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Motorcycle Input/Output Status Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  ABS_DISABLED_SUP = %s\n",
							      (pPid->Data[0] & 0x01) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFE )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Motorcycle Input/Output Status support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $A9  ABS Disable Switch State = %02X\n",
								      GetEcuId ( EcuIdx ),
								      pPid->Data[1] );

								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "                  ABS_DISABLED = %s\n",
								      (pPid->Data[1] & 0x01) ? "YES" : "NO" );
							}
						}
						break;

						case 0xAA:
						{
							// Motorcycle Input/Output Status Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $AA  V_SET = %d km/h\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
						}
						break;

						case 0xAB:
						{
							// Alternative Fuel Vehicle Data Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $AB  Alternative Fuel Vehicle Data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Alternative Fuel Vehicle Data Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  AFRP_AF_SUP = %s\n",
							     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FRT_AF_SUP  = %s\n",
							     (pPid->Data[0] & 0x02) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FTP_AF_SUP  = %s\n",
							     (pPid->Data[0] & 0x04) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FTPW_AF_SUP = %s\n",
							     (pPid->Data[0] & 0x08) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  FTT_AF_SUP  = %s\n",
							     (pPid->Data[0] & 0x10) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xE0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Alternative Fuel Vehicle Data Support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = (float)((pPid->Data[1] << 8) +
								                          pPid->Data[2]) * (float)0.03125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AB  FRP_AF = %.5f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_long = pPid->Data[3] - 40;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AB  FRT_AF = %.d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x04 )
							{
								TempData_float = (float)((pPid->Data[4] << 8) +
								                          pPid->Data[5]) * (float)0.125;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AB  FTP_AF = %.3f kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x08 )
							{
								TempData_long = (pPid->Data[6] << 8) +
								                 pPid->Data[7];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AB  FTPW_AF = %d kPa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}

							if ( pPid->Data[0] & 0x10 )
							{
								TempData_long = pPid->Data[8] - 256;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AB  FTT_AF = %d C\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0xAC:
						{
							// Maximum DEF Dosing Rate/Mode Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $AC Maximum DEF Dosing Rate/Mode support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Maximum DEF Dosing Rate/Mode Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DEF_MODE_SUP = %s\n",
							     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  DEF_MAX_SUP  = %s\n",
							     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Maximum DEF Dosing Rate/Mode Support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AC  DEF_MODE = $%02X\n",
								      GetEcuId ( EcuIdx ),
								      pPid->Data[1] );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((pPid->Data[2] << 8) +
								                          pPid->Data[3]) * (float)0.3;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AC  DEF_MAX = %.1f g/hr\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;

						case 0xAD:
						{
							// Crankcase Data Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $AD Crankcase Data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Crankcase Data Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CKC_P_SUP         = %s\n",
							     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  CKC_OSEP_RPM_SUP  = %s\n",
							     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Crankcase Data Support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = (float)((pPid->Data[1] << 8) +
								                          pPid->Data[2]) * (float)0.25;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AD  CKC_P = %.2f Pa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_long = (pPid->Data[2] << 8) +
								                 pPid->Data[3];
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AD  CKC_OSEP_RPM = %d rpm\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0xAE:
						{
							// Evap System Purge Pressure Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $AE Evap System Purge Pressure support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// Crankcase Data Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EVAP_PP_SUP    = %s\n",
							     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EVAP_PP_WR_SUP = %s\n",
							     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  Evap System Purge Pressure Support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = (float)((pPid->Data[1] << 8) +
								                          pPid->Data[2]) * (float)0.25;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AE  EVAP_PP = %.2f Pa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_long = ((pPid->Data[2] << 8) +
								                  pPid->Data[3]) * 2;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $AE  EVAP_PP_WR = %d Pa\n",
								      GetEcuId ( EcuIdx ),
								      TempData_long );
							}
						}
						break;

						case 0xAF:
						{
							// Commanded/Target Fresh Air Flow
							TempData_float = (float)((pPid->Data[0] << 8) +
							                          pPid->Data[1]) * (float)0.05;
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $AF  AIR_FL_TGT = %.2f Pa\n",
							      GetEcuId ( EcuIdx ),
							      TempData_float );
						}
						break;

						case 0xB0:
						{
							// EGR Mass Flow data Support
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  PID $B0  EGR Mass Flow data support = $%02X\n",
							      GetEcuId ( EcuIdx ),
							      pPid->Data[0] );
							// EGR Mass Flow data Support Bits
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGR_M_FL_A_SUP = %s\n",
							     (pPid->Data[0] & 0x01) ? "YES" : "NO" );
							Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "                  EGR_M_FL_B_SUP = %s\n",
							     (pPid->Data[0] & 0x02) ? "YES" : "NO" );

							// check that reserved bits are not set
							if ( pPid->Data[0] & 0xFC )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  EGR Mass Flow data Support  Reserved bits set\n",
								      GetEcuId ( EcuIdx ) );
							}

							if ( pPid->Data[0] & 0x01 )
							{
								TempData_float = (float)((pPid->Data[1] << 8) +
								                          pPid->Data[2]) * (float)0.05;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $B0  EGR_M_FL_A = %.2f kg/hr\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}

							if ( pPid->Data[0] & 0x02 )
							{
								TempData_float = (float)((pPid->Data[2] << 8) +
								                          pPid->Data[3]) * (float)0.05;
								Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  PID $B0  EGR_M_FL_B = %.2f kg/hr\n",
								      GetEcuId ( EcuIdx ),
								      TempData_float );
							}
						}
						break;


						default:
						{
							// Non-OBD PID
						}
						break;

					}  // end switch(pPid->ID)

				}  // end else ... datasize != 0

			}  // end if ( IsIDSupported (EcuIdx, IdIdx) == TRUE)

		}  // end for (EcuIdx

		// If there where any errors in the data, fail
		if ( TempFailureCount != GetFailureCount ( ) )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Invalid SID $01 PID $%02X Data\n",
			      IdIdx );
		}

	}  // end for (IdIdx


	if ( bEngineDontCare == FALSE )  // NOT Test 10.2
	{
		/**************************************************************************
		* "Either Or" required PIDs
		**************************************************************************/
		// All vehicles require Pid $05 or $67
		if ( bPidSupported[0x05] == FALSE &&
		     bPidSupported[0x67] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither SID $01 PID $05 nor $67 supported (Support of one required for all vehicles)\n" );
		}

		// Gasoline vehicles require Pid $0B, $87, $10 or $66
		if ( gbDiesel == FALSE &&
		     (bPidSupported[0x0B] == FALSE &&
		      bPidSupported[0x87] == FALSE &&
		      bPidSupported[0x10] == FALSE &&
		      bPidSupported[0x66] == FALSE) )
		{
			bReqPidNotSupported = TRUE;
			Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "SID $01 PID $0B, $87, $10 nor $66 supported (Support of one required for gasoline vehicles)\n" );
		}

		// Gasoline vehicles require Pid $0F or $68
		if ( gbDiesel == FALSE &&
		     bPidSupported[0x0F] == FALSE &&
		     bPidSupported[0x68] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither SID $01 PID $0F nor $68 supported (Support of one required for gasoline vehicles)\n" );
		}

		// Gasoline vehicles require Pid $13 or $1D
		if ( gbDiesel == FALSE &&
		     bPidSupported[0x13] == FALSE &&
		     bPidSupported[0x1D] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither SID $01 PID $13 nor $1D supported (Support of one required for gasoline vehicles)\n" );
		}

		// ISO15765 vehicles require Pid $21 or $4D
		if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 &&
		     bPidSupported[0x21] == FALSE &&
		     bPidSupported[0x4D] == FALSE )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither SID $01 PID $21 nor $4D supported (Support of one required for ISO15765 vehicles)\n",
			      IdIdx );
		}

		// MY 2010 diesel vehicles require Pid $2C or $69
		if ( gModelYear >= 2010 &&
		     gbDiesel == TRUE &&
		     (gstUserInput.eComplianceType == US_OBDII ||
		      gstUserInput.eComplianceType == HD_OBD   ||
		      gstUserInput.eComplianceType == CNOBD_NO_IUMPR) &&
		     (bPidSupported[0x2C] == FALSE &&
		      bPidSupported[0x69] == FALSE) )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither SID $01 PID $2C nor $69 supported (Support of one required for MY 2010 and beyond diesel vehicles)\n",
			      IdIdx );
		}

		// ISO15765 vehicles require Pid $31 or $4E
		if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 &&
		     (bPidSupported[0x31] == FALSE &&
		      bPidSupported[0x4E] == FALSE) )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither SID $01 PID $31 nor $4E supported (Support of one required for ISO15765 vehicles)\n",
			      IdIdx );
		}

		// Gasoline vehicles require Pid $45 or $6C
		if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 &&
		     gbDiesel == FALSE &&
		     (bPidSupported[0x45] == FALSE &&
		      bPidSupported[0x6C] == FALSE) )
		{
			if ( gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD )
			{
				bReqPidNotSupported = TRUE;
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "Neither SID $01 PID $45 nor $6C supported (Support of one required for ISO15765 gasoline vehicles)\n",
				      IdIdx );
			}
			else
			{
				Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "Neither SID $01 PID $45 nor $6C supported (Support of one required for ISO15765 gasoline vehicles)\n",
				      IdIdx );
			}
		}

		// MY 2013 diesel vehicles require PID $85 or $9
		if ( gModelYear >= 2013 &&
		     gbDiesel == TRUE &&
		     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) &&
		     (bPidSupported[0x85] == FALSE &&
		      bPidSupported[0x9B] == FALSE) )
		{
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Neither SID $01 PID $85 nor $9B supported (Support required for MY 2013 and beyond diesel vehicles)\n",
			      IdIdx );
		}


		/**************************************************************************
		* Individually required PIDs
		**************************************************************************/
		if ( bPidSupported[0x01] == FALSE )
		{
			// Must be supported for all vehicles
			bReqPidNotSupported = TRUE;
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "SID $01 PID $01 not supported (Support required for all vehicles)\n" );
		}

		else
		{
			// check the 'required by at least one ECU' bits
			if ( (IMBitSupportFlags & DATA_B_BIT_0) != DATA_B_BIT_0 &&
			     ((gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) ||
			      ((gstUserInput.eComplianceType != US_OBDII && gstUserInput.eComplianceType != HD_OBD) &&
			       gbDiesel == FALSE ) ) )
			{
				// Must be supported for all US_OBDII and EOBD gas vehicles
				bReqPidNotSupported = TRUE;
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $01 PID $01 DATA_B Bit 0 not supported (Support required for all vehicles)\n" );
			}
			if ( (IMBitSupportFlags & DATA_B_BIT_1) != DATA_B_BIT_1 &&
			     ( gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD ) )
			{
				// Must be supported for all vehicles
				bReqPidNotSupported = TRUE;
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $01 PID $01 DATA_B Bit 1 not supported (Support required for all vehicles)\n" );
			}
			if ( gbDiesel == FALSE )
			{
				if ( (IMBitSupportFlags & DATA_C_BIT_0) != DATA_C_BIT_0 )
				{
					// Must be supported for all spark ignition vehicles
					bReqPidNotSupported = TRUE;
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $01 PID $01 DATA_C Bit 0 not supported (Support required for all vehicles)\n" );
				}
				if ( (IMBitSupportFlags & DATA_C_BIT_2) != DATA_C_BIT_2 &&
				     (gstUserInput.eComplianceType == US_OBDII ||
				      gstUserInput.eComplianceType == HD_OBD   ||
				      gstUserInput.eComplianceType == CNOBD_NO_IUMPR) )
				{
					// Must be supported for all US_OBDII spark ignition vehicles
					bReqPidNotSupported = TRUE;
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $01 PID $01 DATA_C Bit 2 not supported (Support required for all vehicles)\n" );
				}
			}
			else
			{
				if ( (IMBitSupportFlags & DATA_C_BIT_2) == DATA_C_BIT_2 )
				{
					// Must be 0 for all compression ignition vehicles
					bReqPidNotSupported = TRUE;
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $01 PID $01 DATA_C Bit 2 supported (Must be reserved for all diesel vehicles)\n" );
				}

				if ( (IMBitSupportFlags & DATA_C_BIT_3) != DATA_C_BIT_3 &&
				     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) )
				{
					// Must be supported for all US_OBDII compression ignition vehicles
					bReqPidNotSupported = TRUE;
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $01 PID $01 DATA_C Bit 3 not supported (Support required for all vehicles)\n" );
				}
				if ( (IMBitSupportFlags & DATA_C_BIT_7) != DATA_C_BIT_7 &&
				     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) )
				{
					// Must be supported for all US_OBDII compression ignition vehicles
					bReqPidNotSupported = TRUE;
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $01 PID $01 DATA_C Bit 7 not supported (Support required for all vehicles)\n" );
				}
			}
			if ( (IMBitSupportFlags & DATA_C_BIT_5) != DATA_C_BIT_5 &&
			     ((gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) ||
			      ((gstUserInput.eComplianceType != US_OBDII && gstUserInput.eComplianceType != HD_OBD) &&
			        gbDiesel == FALSE)) )
			{
				// Must be supported for all US_OBDII and EOBD gas vehicles
				bReqPidNotSupported = TRUE;
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $01 PID $01 DATA_C Bit 5 not supported (Support required)\n" );
			}
			if ( (IMBitSupportFlags & DATA_C_BIT_6) != DATA_C_BIT_6 )
			{
				// Must be supported for all vehicles
				bReqPidNotSupported = TRUE;
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $01 PID $01 DATA_C Bit 6 not supported (Support required for all vehicles)\n" );
			}
		}

		for ( IdIdx = 0x02;
		      IdIdx < MAX_PIDS;
		      IdIdx++ )
		{
			if ( bPidSupported[IdIdx] == FALSE )
			{
				switch ( IdIdx )
				{
					case 0x04:
					case 0x0C:
					case 0x1C:
					{
						// Must be supported for all vehicles
						bReqPidNotSupported = TRUE;
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "SID $01 PID $%02X not supported (Support required for all vehicles)\n",
						      IdIdx );
					}
					break;

					case 0x06:
					case 0x07:
					{
						// Warn if not supported for gasoline vehicles
						if ( gbDiesel == FALSE &&
						     gstUserInput.eComplianceType == US_OBDII != OBDBr_NO_IUMPR )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for gasoline vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x0D:
					{
						// Must be supported for all light duty vehicles
						if ( gstUserInput.eVehicleType == LD )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for all light duty vehicles)\n",
							      IdIdx );
						}
						// Warn if not supported for gasoline vehicles
						else if ( gstUserInput.eVehicleType == MD ||  gstUserInput.eVehicleType == HD )
						{
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for all medium and heavy duty vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x03:
					case 0x11:
					{
						// Must be supported for gasoline vehicles
						if ( gbDiesel == FALSE )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for gasoline vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x0E:
					{
						// Must be supported for gasoline vehicles
						if ( gbDiesel == FALSE )
						{
							bReqPidNotSupported = TRUE;
							if ( gbHybrid == TRUE )
							{
								Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "SID $01 PID $%02X not supported (Support required for gasoline vehicles)\n",
								      IdIdx );
							}
							else
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "SID $01 PID $%02X not supported (Support required for gasoline vehicles)\n",
								      IdIdx );
							}
						}
					}
					break;

					case 0x2F:
					{
						// Warn if not supported for ISO15765 vehicles
						if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for ISO15765 vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x41:
					case 0x43:
					{
						// Must be supported for ISO15765 protocol on US_OBDII
						if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
						{
							if ( gstUserInput.eComplianceType == US_OBDII )
							{
								bReqPidNotSupported = TRUE;
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "SID $01 PID $%02X not supported (Support required for ISO15765 protocol vehicles)\n",
								      IdIdx );
							}
							else if ( gstUserInput.eComplianceType != HD_OBD )
							{
								Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "SID $01 PID $%02X not supported\n",
								      IdIdx );
							}
						}
					}
					break;

					case 0x1F:
					case 0x30:
					case 0x33:
					case 0x42:
					{
						// Must be supported for ISO15765 protocol
						if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for ISO15765 protocol vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x2E:
					{
						// Warn if not supported for ISO15765 gasoline vehicles
						if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 &&
						     gbDiesel == FALSE )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for ISO15765 gasoline vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x44:
					{
						// Must be supported for ISO15765 gasoline vehicles
						if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 &&
						     gbDiesel == FALSE )
						{
							if ( gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD )
							{
								bReqPidNotSupported = TRUE;
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "SID $01 PID $%02X not supported (Support required for ISO15765 gasoline vehicles)\n",
								      IdIdx );
							}
							else
							{
								Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "SID $01 PID $%02X not supported\n",
								      IdIdx );
							}
						}
					}
					break;

					case 0x46:
					{
						// Must be supported for US vehicles
						if ( gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for all vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x49:
					{
						// Must be supported for ISO15765 diesel vehicles
						if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 &&
						     gbDiesel == TRUE )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for ISO15765 diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x51:
					{
						// Must be supported for MY 2015 vehicles
						if ( gModelYear >= 2015  &&
						     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2015 and beyond vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x5C:
					case 0x5D:
					case 0x5E:
					case 0x65:
					{
						// Warn if not supported for MY 2010 diesel vehicles
						if ( gModelYear >= 2010 &&
						     gbDiesel == TRUE &&
						     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) )
						{
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2010 and beyond diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x5B:
					{
						// Must be supported for MY 2013 hybrid vehicles
						if ( gModelYear >= 2013 &&
						     (gstUserInput.ePwrTrnType == HEV || gstUserInput.ePwrTrnType == PHEV) &&
						     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2013 and beyond hybrid vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x61:
					{
						// Must be supported for MY 2010 diesel vehicles
						if ( gModelYear >= 2010 &&
						     gbDiesel == TRUE &&
						     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2010 and beyond diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x62:
					{
						// Must be supported for MY 2010 diesel vehicles
						if ( gModelYear >= 2010 &&
						     gbDiesel == TRUE &&
						     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2010 and beyond diesel vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2019 && gModelYear < 2021 &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2021 &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2021 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x63:
					{
						// Must be supported for MY 2010 heavy duty diesel vehicles
						if ( gModelYear >= 2010 &&
						     gbDiesel == TRUE &&
						     gstUserInput.eComplianceType == HD_OBD )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2010 and beyond heavy duty diesel vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2019 &&
						          gbDiesel == TRUE &&
						          gstUserInput.eComplianceType == US_OBDII && gstUserInput.eVehicleType == MD )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond medium duty diesel vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2019 && gModelYear < 2021 &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2021 &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2021 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x7D:
					case 0x7E:
					case 0x81:
					{
						// Must be supported for MY 2010 heavy duty diesel vehicles
						if ( gModelYear >= 2010 &&
						     gbDiesel == TRUE &&
						     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) &&
						     (gstUserInput.eVehicleType == HD || gstUserInput.eVehicleType == MD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2010 and beyond heavy duty diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x7F:
					{
						// Must be supported for MY 2010 heavy duty vehicles
						if ( gModelYear >= 2010 &&
						     (gstUserInput.eComplianceType == HD_OBD ||
						      (gbDiesel == TRUE && gstUserInput.eVehicleType == MD)) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2010 and beyond heavy duty vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x8B:
					{
						// Must be supported for MY 2013 diesel vehicles
						if ( gModelYear >= 2013 &&
						     gbDiesel == TRUE &&
						     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2013 and beyond diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x88:
					{
						// Must be supported for MY 2013 heavy duty diesel vehicles
						if ( gModelYear >= 2013 &&
						     gbDiesel == TRUE &&
						     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) &&
						     (gstUserInput.eVehicleType == HD || gstUserInput.eVehicleType == MD) )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2013 and beyond heavy duty diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x8E:
					{
						// Must be supported for MY 2010 heavy duty diesel vehicles
						if ( gModelYear >= 2010 &&
						     gbDiesel == TRUE &&
						     gstUserInput.eComplianceType == HD_OBD )
						{
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2010 and beyond heavy duty diesel vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2019 &&
						          gbDiesel == TRUE &&
						          gstUserInput.eComplianceType == US_OBDII && gstUserInput.eVehicleType == MD )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond heavy duty diesel vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2019 && gModelYear < 2021 &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2021 &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2021 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x9A:
					{
						// Must be supported for MY 2019 PHEV vehicles
						if ( gModelYear >= 2019 &&
						     gbPlugIn == TRUE &&
						     gstUserInput.eComplianceType == US_OBDII )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond plug-in hybrid electric vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0x9D:
					case 0x9E:
					{
						// Must be supported for MY 2016 heavy duty diesel vehicles
						if ( gModelYear >= 2016 &&
						     gbDiesel == TRUE &&
						     gstUserInput.eComplianceType == HD_OBD )
						{
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2016 and beyond heavy duty diesel vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2019 &&
						          gbDiesel == TRUE &&
						          gstUserInput.eComplianceType == US_OBDII && gstUserInput.eVehicleType == MD )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond medium duty diesel vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2019 && gModelYear < 2021 &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2021 &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2021 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xA2:
					{
						// Must be supported for MY 2016 heavy duty diesel vehicles
						if ( gModelYear >= 2016 &&
						     gbDiesel == TRUE &&
						     gstUserInput.eComplianceType == HD_OBD )
						{
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2016 and beyond heavy duty diesel vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2019 &&
						          gbDiesel == TRUE &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond OBD-II diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xA5:
					{
						if ( gModelYear >= 2019 &&
						     gbDiesel == TRUE &&
						     gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond OBD-II diesel vehicles)\n",
							      IdIdx );
						}
					}
					break;

					case 0xA6:
					{
						if ( gModelYear >= 2019 && gModelYear < 2021 &&
						     gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2019 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
						else if ( gModelYear >= 2021 &&
						          gstUserInput.eComplianceType == US_OBDII )
						{
							bReqPidNotSupported = TRUE;
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "SID $01 PID $%02X not supported (Support required for MY 2021 and beyond OBD-II vehicles)\n",
							      IdIdx );
						}
					}
					break;
				}  // end switch ( IdIdx )
			}  // end if ( bPidSupported[IdIdx] == FALSE )
		}  // end for ( IdIdx


		if ( bReqPidNotSupported == FALSE )
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "All required SID $01 PIDs supported!\n" );
		}
		else
		{
			Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Not all required SID $01 PIDs are supported\n" );
		}


		// Try group support if ISO15765
		if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
		{
			if ( RequestGroupIDSupportData ( PIDREQUEST ) == FAIL )
			{
				if ( Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, YES_NO_ALL_PROMPT,
				           "Problems verifying group diagnostic support.\n" ) == 'N' )
				{
					return FAIL;
				}
			}
		}

		// Link active test to verify communication remained active for ALL protocols
		if ( VerifyECUCommunication ( ) != PASS )
		{
			return FAIL;
		}
	} // end if ( bEngineDontCare == FALSE)

	if ( InitialFailureCount != GetFailureCount ( ) )
	{
		// There could have been early/late responses that weren't treated as FAIL
		// or PIDs out of range
		return FAIL;
	}

	return PASS;
}


/*******************************************************************************
**
**  Function:  DiplayM01P01
**
**  Purpose:   Display bit name and value of SID $01 PID $01
**
*******************************************************************************/
void DisplayPid01( BYTE  EcuIdx,  // index of associated ECU
                   BOOL  bCC )    // Called from ClearCodes?
{
	if ( !bCC )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $01  IM Readiness  A = $%02X  B = $%02X  C = $%02X  D = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      gstEcuSIDData[EcuIdx].Pid01.Data[0],
		      gstEcuSIDData[EcuIdx].Pid01.Data[1],
		      gstEcuSIDData[EcuIdx].Pid01.Data[2],
		      gstEcuSIDData[EcuIdx].Pid01.Data[3] );

		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                  %-9s = %-7d    %-9s = %s\n",
		      "DTC_CNT",  (gstEcuSIDData[EcuIdx].Pid01.Data[0] & 0x7F),
		      "MIL",      (gstEcuSIDData[EcuIdx].Pid01.Data[0] & 0x80) ? "ON" : "OFF" );
	}
	else
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  PID $01  IM Readiness (from the last SID $01 PID $01 request)  B = $%02X  C = $%02X  D = $%02X\n",
		      GetEcuId ( EcuIdx ),
		      gstEcuSIDData[EcuIdx].Pid01.Data[1],
		      gstEcuSIDData[EcuIdx].Pid01.Data[2],
		      gstEcuSIDData[EcuIdx].Pid01.Data[3] );
	}

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	      "MIS_SUP",  (gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x01) ? "1 (YES)" : "0 (NO)",
	      "MIS_RDY",  (gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	      "FUEL_SUP", (gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x02) ? "1 (YES)" : "0 (NO)",
	      "FUEL_RDY", (gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	      "CCM_SUP",  (gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x04) ? "1 (YES)" : "0 (NO)",
	      "CCM_RDY",  (gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	     gbDiesel ? "HCCAT_SUP" : "CAT_SUP",  (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x01) ? "1 (YES)" : "0 (NO)",
	     gbDiesel ? "HCCAT_RDY" : "CAT_RDY",  (gstEcuSIDData[EcuIdx].Pid01.Data[3] & 0x01) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	     gbDiesel ? "NCAT_SUP"  : "HCAT_SUP", (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x02) ? "1 (YES)" : "0 (NO)",
	     gbDiesel ? "NCAT_RDY"  : "HCAT_RDY", (gstEcuSIDData[EcuIdx].Pid01.Data[3] & 0x02) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	     gbDiesel ? "reserved"  : "EVAP_SUP", (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x04) ? "1 (YES)" : "0 (NO)",
	     gbDiesel ? "reserved"  : "EVAP_RDY", (gstEcuSIDData[EcuIdx].Pid01.Data[3] & 0x04) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	     gbDiesel ? "BP_SUP"    : "AIR_SUP",  (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x08) ? "1 (YES)" : "0 (NO)",
	     gbDiesel ? "BP_RDY"    : "AIR_RDY",  (gstEcuSIDData[EcuIdx].Pid01.Data[3] & 0x08) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	     gbDiesel ? "reserved"   : "GPF_SUP",  (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x10) ? "1 (YES)" : "0 (NO)",
	     gbDiesel ? "reserved"   : "GPF_RDY",  (gstEcuSIDData[EcuIdx].Pid01.Data[3] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	     gbDiesel ? "EGS_SUP"   : "O2S_SUP",  (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x20) ? "1 (YES)" : "0 (NO)",
	     gbDiesel ? "EGS_RDY"   : "O2S_RDY",  (gstEcuSIDData[EcuIdx].Pid01.Data[3] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-9s = %s\n",
	     gbDiesel ? "PM_SUP"    : "HTR_SUP",  (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x40) ? "1 (YES)" : "0 (NO)",
	     gbDiesel ? "PM_RDY"    : "HTR_RDY",  (gstEcuSIDData[EcuIdx].Pid01.Data[3] & 0x40) ? "1 (NO)"  : "0 (YES)" );

	if ( !bCC )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "                  %-9s = %-7s    %-9s = %s\n",
		      "EGR_SUP",  (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x80) ? "1 (YES)" : "0 (NO)",
		      "EGR_RDY",  (gstEcuSIDData[EcuIdx].Pid01.Data[3] & 0x80) ? "1 (NO)"  : "0 (YES)" );
	}
}


/*******************************************************************************
**
**  Function:  VerifyPid01
**
**  Purpose:   Verify SID $01 PID $01 data, that all bits are in the approptiate state
**
*******************************************************************************/
STATUS VerifyPid01 ( PID           *pPid,               // pointer to SID $01 Data
                     BYTE           EcuIdx,             // index of associated ECU
                     unsigned long *pfIMBitsSupported ) // bit map of bits that must set on at least one ECU
{
	BOOL bTestFailed = FALSE;

	DisplayPid01 ( EcuIdx, FALSE );

	// Check if the MIL light is ON (SID 1 PID 1 Data A Bit 7)
	if ( pPid->Data[0] & 0x80 )
	{
		if ( gbDTCStored == FALSE )
		{
			// MIL is ON when there should not be a stored DTC
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  MIL status failure.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Check if any DTC status bits (SID 1 PID 1 Data A Bits 0-6)
	if ( pPid->Data[0] & 0x7F )
	{
		// if DTC status bit(s) set when there should not be a stored DTC
		if ( gbDTCStored == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  DTC status failure.\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data B, BIT 0 - Misfire support
	if ( (pPid->Data[1] & 0x01) == 0x01 )
	{
		*pfIMBitsSupported = *pfIMBitsSupported | DATA_B_BIT_0;
	}

	// Evaluate Data B, BIT 1 - Fuel support
	if ( (pPid->Data[1] & 0x02) == 0x02 )
	{
		*pfIMBitsSupported = *pfIMBitsSupported | DATA_B_BIT_1;
	}

	// Evaluate Data B, BIT 2 - CCM support
	if ( (pPid->Data[1] & 0x04) != 0x04 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  CCM monitor must be supported (CCM_SUP = 1 (YES))\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Check Data B BIT 3 state
	// only check if MY 2010 and beyond and ECU does not only supports CCM requirements (SID 1 PID 1 Data B bit 2==1)
	if ( gModelYear >= 2010 &&
	     ((gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x03) != 0x00 ||
	      (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0xFF) != 0x00) )
	{
		if ( (pPid->Data[1] & 0x08) == 0x00 &&
		     gbDiesel == 1  )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  SID $01 PID $01 Data B bit 3 clear (Spark Ignition) does not match user input (Diesel)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
		else if ( (pPid->Data[1] & 0x08) == 0x08 &&
		          gbDiesel == 0  )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  SID $01 PID $01 Data B bit 3 set (Compression Ignition) does not match user input (Non Diesel)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data B, BIT 4 - Misfire
	if ( (pPid->Data[1] & 0x01) == 0x01 )
	 {
		// if Misfire is supported
		if ( gbDiesel == FALSE )
		{
			// if it's a spark engine
			if ( (pPid->Data[1] & 0x10) != 0x00 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  Misfire Monitor must be 0 (MIS_SUP = NO) for spark ignition vehicles or controllers that do not support misfire.\n",
				      GetEcuId ( EcuIdx ) );
				bTestFailed = TRUE;
			}
		}
		else
		{
			// Bit 4 may be 0 or 1 for compression ignition w/ or wo/ Engine running
			// except in Test 11 where it must be complete (0).
			if ( geTestPhase == eTestPerformanceCounters )
			{
				if ( (pPid->Data[1] & 0x10) != 0x00 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  Misfire Monitor must be 0 (MIS_SUP = NO) for compression ignition vehicles.\n",
					      GetEcuId ( EcuIdx ) );
					bTestFailed = TRUE;
				}
			}
		}
	}
	// If Misfire unsupported it must indicate complete
	if ( (pPid->Data[1] & 0x01) == 0x00 &&
	     (pPid->Data[1] & 0x10) == 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported Misfire Monitor (MIS_SUP = 0 (NO) ) must indicate complete (MIS_RDY = 0 (YES)).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data B, BIT 5 - Fuel status
	if ( (pPid->Data[1] & 0x02) == 0x02 )
	{
		// only check for tests 11.3 and 11.7 (not 10.6)
		if ( geTestPhase == eTestPerformanceCounters &&
		     (pPid->Data[1] & 0x20) == 0x20 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported Fuel System Monitor (FUEL_SUP = 1 (YES)) must indicate complete (FUEL_RDY = 0 (YES)).\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	// If fuel system monitor unsupported it must indicate complete
	if ( (pPid->Data[1] & 0x02) == 0x00 &&
	     (pPid->Data[1] & 0x20) == 0x20 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported Fuel System Monitor (FUEL_SUP = 0 (NO)) must indicate complete (FUEL_RDY = 0 (YES)).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data B, BIT 6 - CCM status
	if ( (pPid->Data[1] & 0x40) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  CCM must indicate complete (CCM_RDY = 0 (YES)).\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Check Data B bit 7 if reserved bit is set
	if ( pPid->Data[1] & 0x80 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Reserved I/M readiness Data B bit 7 set\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data C, BIT 0
	if ( pPid->Data[2] & 0x01 )
	{
		*pfIMBitsSupported = *pfIMBitsSupported | DATA_C_BIT_0;
	}

	// Evaluate Data C, BIT 2
	if ( pPid->Data[2] & 0x04 )
	{
		if ( gbDiesel != TRUE &&
		     (gstUserInput.eComplianceType == US_OBDII ||
		      gstUserInput.eComplianceType == HD_OBD   ||
		      gstUserInput.eComplianceType == CNOBD_NO_IUMPR ) )
		{
			*pfIMBitsSupported = *pfIMBitsSupported | DATA_C_BIT_2;
		}
		else if ( gbDiesel == TRUE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Reserved I/M readiness Data C bit 2 set\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	// Evaluate Data C, BIT 3
	if ( pPid->Data[2] & 0x08 )
	{
		*pfIMBitsSupported = *pfIMBitsSupported | DATA_C_BIT_3;
	}

	// Evaluate Data C, BIT 4
	if ( pPid->Data[2] & 0x10 &&
	     (gstUserInput.eComplianceType == US_OBDII ||
	      gstUserInput.eComplianceType == HD_OBD ||
	       gbDiesel == TRUE) )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Reserved I/M readiness Data C bit 4 set\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data C, BIT 5
	if ( pPid->Data[2] & 0x20 )
	{
		*pfIMBitsSupported = *pfIMBitsSupported | DATA_C_BIT_5;
	}

	// Evaluate Data C, BIT 6
	if ( pPid->Data[2] & 0x40 )
	{
		*pfIMBitsSupported = *pfIMBitsSupported | DATA_C_BIT_6;
	}

	// Evaluate Data C, BIT 7
	if ( pPid->Data[2] & 0x80 )
	{
		*pfIMBitsSupported = *pfIMBitsSupported | DATA_C_BIT_7;
	}

	// Evaluate Data D, BIT 2
	if ( (pPid->Data[3] & 0x04) == 0x04 &&
	     gbDiesel == TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Reserved I/M readiness Data D bit 2 set\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// Evaluate Data D, BIT 4
	if ( pPid->Data[3] & 0x10 &&
	     (gstUserInput.eComplianceType == US_OBDII ||
	      gstUserInput.eComplianceType == HD_OBD) &&
	     gbDiesel == TRUE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Reserved I/M readiness Data D bit 4 set\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	if ( gbEngineRunning == FALSE && geTestPhase != eTestPerformanceCounters )  // test 5.6 & 10.6
	{
		// supported monitors should not be complete (except O2 on spark ignition)
		// DATA_D Bit 0
		if ( (pPid->Data[2] & 0x01) == 0x01 &&
		     (pPid->Data[3] & 0x01) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gbDiesel ? "HCCAT" : "CAT",
			      gbDiesel ? "HCCAT" : "CAT" );
			bTestFailed = TRUE;
		}

		// DATA_D Bit 1
		if ( (pPid->Data[2] & 0x02) == 0x02 &&
		     (pPid->Data[3] & 0x02) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gbDiesel ? "NCAT" : "HCAT",
			      gbDiesel ? "NCAT" : "HCAT" );
			bTestFailed = TRUE;
		}

		// DATA_D Bit 2
		if ( (pPid->Data[2] & 0x04) == 0x04 &&
		     (pPid->Data[3] & 0x04) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gbDiesel ? "RESERVED2" : "EVAP",
			      gbDiesel ? "RESERVED2" : "EVAP" );
			bTestFailed = TRUE;
		}

		// DATA_D Bit 3
		if ( (pPid->Data[2] & 0x08) == 0x08 &&
		     (pPid->Data[3] & 0x08) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gbDiesel ? "BP" : "AIR",
			      gbDiesel ? "BP" : "AIR" );
			bTestFailed = TRUE;
		}

		// DATA_D Bit 4
		if ( (pPid->Data[2] & 0x10) == 0x10 &&
		     (pPid->Data[3] & 0x10) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported monitor (RESERVED Byte C Bit 4 = 1) must indicate incomplete (RESERVED Byte D Bit 4 = 1)\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}

		// DATA_D Bit 5
		if ( (pPid->Data[2] & 0x20) == 0x20 &&
		     (pPid->Data[3] & 0x20) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gbDiesel ? "EGS" : "O2S",
			      gbDiesel ? "EGS" : "O2S" );
			bTestFailed = TRUE;
		}

		// DATA_D Bit 6
		if ( (pPid->Data[2] & 0x40) == 0x40 &&
		     (pPid->Data[3] & 0x40) == 0x00 &&
		     gbDiesel )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported monitor (%s_SUP = 1 (YES)) must indicate incomplete (%s_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ),
			      gbDiesel ? "PM" : "HTR",
			      gbDiesel ? "PM" : "HTR" );
			bTestFailed = TRUE;
		}

		// DATA_D Bit 7
		if ( (pPid->Data[2] & 0x80) == 0x80 &&
		     (pPid->Data[3] & 0x80) == 0x00 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported monitor (EGR_SUP = 1 (YES)) must indicate incomplete (EGR_RDY = 1 (NO))\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}


	// unsupported monitors should be complete
	// DATA_D Bit 0
	if ( (pPid->Data[2] & 0x01) == 0x00 &&
	     (pPid->Data[3] & 0x01) == 0x01 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported monitor (%s_SUP = N) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gbDiesel ? "HCCAT" : "CAT",
		      gbDiesel ? "HCCAT" : "CAT" );
		bTestFailed = TRUE;
	}

	// DATA_D Bit 1
	if ( (pPid->Data[2] & 0x02) == 0x00 &&
	     (pPid->Data[3] & 0x02) == 0x02 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gbDiesel ? "NCAT" : "HCAT",
		      gbDiesel ? "NCAT" : "HCAT" );
		bTestFailed = TRUE;
	}

	// DATA_D Bit 2
	if ( (pPid->Data[2] & 0x04) == 0x00 &&
	     (pPid->Data[3] & 0x04) == 0x04 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gbDiesel ? "RESERVED2" : "EVAP",
		      gbDiesel ? "RESERVED2" : "EVAP" );
		bTestFailed = TRUE;
	}

	// DATA_D Bit 3
	if ( (pPid->Data[2] & 0x08) == 0x00 &&
	     (pPid->Data[3] & 0x08) == 0x08 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gbDiesel ? "BP" : "AIR",
		      gbDiesel ? "BP" : "AIR" );
		bTestFailed = TRUE;
	}

	// DATA_D Bit 4
	if ( (pPid->Data[2] & 0x10) == 0x00 &&
	     (pPid->Data[3] & 0x10) == 0x10 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  ERVED4: Unsupported (%s_SUP = 0 (NO)) monitor mustindicate (%s_RDY = 0 (YES))'complete'\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	// DATA_D Bit 5
	if ( (pPid->Data[2] & 0x20) == 0x00 &&
	     (pPid->Data[3] & 0x20) == 0x20 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gbDiesel ? "EGS" : "O2S",
		      gbDiesel ? "EGS" : "O2S" );
		bTestFailed = TRUE;
	}

	// DATA_D Bit 6
	if ( (pPid->Data[2] & 0x40) == 0x00 &&
	     (pPid->Data[3] & 0x40) == 0x40 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  Unsupported monitor (%s_SUP = 0 (NO)) must indicate complete (%s_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ),
		      gbDiesel ? "PM" : "HTR",
		      gbDiesel ? "PM" : "HTR" );
		bTestFailed = TRUE;
	}

	// DATA_D Bit 7
	if ( (pPid->Data[2] & 0x80) == 0x00 &&
	     (pPid->Data[3] & 0x80) == 0x80 )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X : Unsupported monitor (EGR_SUP = 0 (NO)) must indicate complete (EGR_RDY = 0 (YES))\n",
		      GetEcuId ( EcuIdx ) );
		bTestFailed = TRUE;
	}

	if ( geTestPhase == eTestPerformanceCounters )
	{
		if ( pPid->Data[3] != 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Supported monitors (SUP = 1 (YES)) must be complete (RDY = 0 (YES)) after I/M drive cycle\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	if ( bTestFailed == TRUE )
	{
		return  FAIL;
	}
	else
	{
		return  PASS;
	}
}


/*******************************************************************************
**
**  Function:  VerifyPid1C
**
**  Purpose:
**
*******************************************************************************/
STATUS VerifyPid1C ( PID  *pPid,     // pointer to SID $01 Data
                     BYTE  EcuIdx )  // index of associated ECU
{
	BOOL bTestFailed = FALSE;


	// Make sure value is in the valid range before the lookup
	if ( pPid->Data[0] > MAX_OBD_TYPES )
	{
		pPid->Data[0] = 0;
	}

	// Vehicle should support OBD-II
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $1C  OBD_TYPE = %s\n",
	      GetEcuId ( EcuIdx ),
	      szOBD_TYPE[pPid->Data[0]]);

	if ( gstUserInput.eComplianceType == US_OBDII )
	{
		if ( pPid->Data[0] != 0x01 &&  // CARB OBD II
		     pPid->Data[0] != 0x03 &&  // OBDI and OBD II
		     pPid->Data[0] != 0x07 &&  // EOBD and OBD II
		     pPid->Data[0] != 0x09 &&  // EOBD, OBD and OBD II
		     pPid->Data[0] != 0x0B &&  // JOBD and OBD II
		     pPid->Data[0] != 0x0D &&  // JOBD, EOBD, and OBD II
		     pPid->Data[0] != 0x0F &&
		     pPid->Data[0] != 0x22 )   // OBD, OBD II and HD_OBD
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a Light Duty OBD II ECU\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	else if ( gstUserInput.eComplianceType == HD_OBD )
	{
		if ( pPid->Data[0] != 0x13 &&  // HD OBD-C
		     pPid->Data[0] != 0x14 &&  // HD OBD
		     pPid->Data[0] != 0x22 )   // OBD, OBD II and HD_OBD
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a Heavy Duty OBD II ECU\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	else if ( gstUserInput.eComplianceType == EOBD_WITH_IUMPR ||
	          gstUserInput.eComplianceType == EOBD_NO_IUMPR )
	{
		if ( pPid->Data[0] != 0x06 &&  // EOBD
		     pPid->Data[0] != 0x07 &&  // EOBD and OBD II
		     pPid->Data[0] != 0x08 &&  // EOBD and OBD
		     pPid->Data[0] != 0x09 &&  // EOBD, OBD and OBD II
		     pPid->Data[0] != 0x0C &&  // JOBD and EOBD
		     pPid->Data[0] != 0x0D &&  // JOBD, EOBD, and OBD II
		     pPid->Data[0] != 0x0E &&  // EURO IV B1
		     pPid->Data[0] != 0x0F )   // EURO V B2
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a Light Duty EOBD ECU\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	else if ( gstUserInput.eComplianceType == HD_EOBD )
	{
		if ( pPid->Data[0] != 0x17 &&  // HD EOBD-I
		     pPid->Data[0] != 0x18 &&  // HD EOBD-I N
		     pPid->Data[0] != 0x19 &&  // HD EOBD-II
		     pPid->Data[0] != 0x1A &&  // HD EOBD-II N
		     pPid->Data[0] != 0x21 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a Heavy Duty EOBD ECU\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	else if ( gstUserInput.eComplianceType == IOBD_NO_IUMPR || gstUserInput.eComplianceType == HD_IOBD_NO_IUMPR )
	{
		if ( pPid->Data[0] != 0x20 )  // IOBD
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a IOBD II ECU\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	else if ( gstUserInput.eComplianceType == OBDBr_NO_IUMPR )
	{
		if ( pPid->Data[0] != 0x1C &&  // OBDBr-1
		     pPid->Data[0] != 0x1D &&  // OBDBr-2
		     pPid->Data[0] != 0x23 &&  // OBDBr-3
		     pPid->Data[0] != 0x2A )   // OBDBr-D
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a OBDBr ECU\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}
	else if ( gstUserInput.eComplianceType == CNOBD_NO_IUMPR )
	{
		if ( pPid->Data[0] != 0x29 )  // CN-OBD-6
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  Not a China6 ECU\n",
			      GetEcuId ( EcuIdx ) );
			bTestFailed = TRUE;
		}
	}

	if ( bTestFailed == TRUE )
	{
		return  FAIL;
	}
	else
	{
		return  PASS;
	}
}


/*******************************************************************************
**
**  Function:  VerifyPid41
**
**  Purpose:   Verify SID 1 PID 41 data, that all bits are in the appropriate state
**
********************************************************************************/
STATUS VerifyPid41 ( PID  *pPid,              // pointer to PID Data
                     BYTE  EcuIdx,            // index of associated ECU
                     BOOL  bEngineDontCare )  // copy of bEngineDontCare flag from calling routine
{
#define  MAX_STRING_NUMBER  8
#define  MAX_NAME_LENGTH    12

	BOOL          bTestFailed = FALSE;
	unsigned int  ByteIdx;
	unsigned int  BitIndex;
	unsigned int  BitMask;
	unsigned int  BitMask2;
	char          String[MAX_STRING_NUMBER][MAX_NAME_LENGTH];
	BYTE          StringIndex;


	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "ECU %X  PID $41  Monitor Status  Byte A = $%02X  B = $%02X  C = $%02X  D = $%02X\n",
	      GetEcuId ( EcuIdx ),
	      pPid->Data[0],
	      pPid->Data[1],
	      pPid->Data[2],
	      pPid->Data[3] );

	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      "MIS_ENA",   (pPid->Data[1] & 0x01) ? "1 (YES)" : "0 (NO)",
	      "MIS_CMPL",  (pPid->Data[1] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      "FUEL_ENA",  (pPid->Data[1] & 0x02) ? "1 (YES)" : "0 (NO)",
	      "FUEL_CMPL", (pPid->Data[1] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      "CCM_ENA",   (pPid->Data[1] & 0x04) ? "1 (YES)" : "0 (NO)",
	      "CCM_CMPL",  (pPid->Data[1] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      gbDiesel ? "HCCAT_ENA"  : "CAT_ENA",  (pPid->Data[2] & 0x01) ? "1 (YES)" : "0 (NO)",
	      gbDiesel ? "HCCAT_CMPL" : "CAT_CMPL", (pPid->Data[3] & 0x01) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      gbDiesel ? "NCAT_ENA"  : "HCAT_ENA",  (pPid->Data[2] & 0x02) ? "1 (YES)" : "0 (NO)",
	      gbDiesel ? "NCAT_CMPL" : "HCAT_CMPL", (pPid->Data[3] & 0x02) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      gbDiesel ? "reserved" : "EVAP_ENA",   (pPid->Data[2] & 0x04) ? "1 (YES)" : "0 (NO)",
	      gbDiesel ? "reserved" : "EVAP_CMPL",  (pPid->Data[3] & 0x04) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      gbDiesel ? "BP_ENA"  : "AIR_ENA",     (pPid->Data[2] & 0x08) ? "1 (YES)" : "0 (NO)",
	      gbDiesel ? "BP_CMPL" : "AIR_CMPL",    (pPid->Data[3] & 0x08) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      gbDiesel ? "reserved" : "GPF_ENA",    (pPid->Data[2] & 0x10) ? "1 (YES)" : "0 (NO)",
	      gbDiesel ? "reserved" : "GPF_CMPL",   (pPid->Data[3] & 0x10) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      gbDiesel ? "EGS_ENA"  : "O2S_ENA",    (pPid->Data[2] & 0x20) ? "1 (YES)" : "0 (NO)",
	      gbDiesel ? "EGS_CMPL" : "O2S_CMPL",   (pPid->Data[3] & 0x20) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      gbDiesel ? "PM_ENA"  : "HTR_ENA",     (pPid->Data[2] & 0x40) ? "1 (YES)" : "0 (NO)",
	      gbDiesel ? "PM_CMPL" : "HTR_CMPL",    (pPid->Data[3] & 0x40) ? "1 (NO)"  : "0 (YES)" );
	Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "                  %-9s = %-7s    %-10s = %s\n",
	      "EGR_ENA",   (pPid->Data[2] & 0x80) ? "1 (YES)" : "0 (NO)",
	      "EGR_CMPL",  (pPid->Data[3] & 0x80) ? "1 (NO)"  : "0 (YES)" );


	// check that bits set in PID $41 match support in PID $01
	for ( ByteIdx = 1;
	      ByteIdx <= 3;
	      ByteIdx++ )
	{
		if ( ByteIdx == 1 )
		{
			strcpy_s ( String[0], MAX_NAME_LENGTH, "MIS" );
			strcpy_s ( String[1], MAX_NAME_LENGTH, "FUEL" );
			strcpy_s ( String[2], MAX_NAME_LENGTH, "CCM" );
			strcpy_s ( String[3], MAX_NAME_LENGTH, "no display" );
			strcpy_s ( String[4], MAX_NAME_LENGTH, "MIS" );
			strcpy_s ( String[5], MAX_NAME_LENGTH, "FUEL" );
			strcpy_s ( String[6], MAX_NAME_LENGTH, "CCM" );
			strcpy_s ( String[7], MAX_NAME_LENGTH, "reserved" );

			BitMask2 = 0x01;
		}
		else
		{
			strcpy_s ( String[0], MAX_NAME_LENGTH, gbDiesel ? "HCCAT"    : "CAT" );
			strcpy_s ( String[1], MAX_NAME_LENGTH, gbDiesel ? "NCAT"     : "HCAT" );
			strcpy_s ( String[2], MAX_NAME_LENGTH, gbDiesel ? "reserved" : "EVAP" );
			strcpy_s ( String[3], MAX_NAME_LENGTH, gbDiesel ? "BP"       : "AIR" );
			strcpy_s ( String[4], MAX_NAME_LENGTH, "reserved" );
			strcpy_s ( String[5], MAX_NAME_LENGTH, gbDiesel ? "EGS"      : "O2S" );
			strcpy_s ( String[6], MAX_NAME_LENGTH, gbDiesel ? "PM"       : "HTR" );
			strcpy_s ( String[7], MAX_NAME_LENGTH, "EGR" );

			BitMask2 = 0x01;
		}


		for ( BitIndex = 0, BitMask = 0x01, StringIndex = 0;
		      BitIndex < 8;
		      BitIndex++, BitMask <<= 1, StringIndex++ )
		{
			// reserved bit check
			if ( (ByteIdx == 1 && BitIndex == 7 && (pPid->Data[1] & BitMask) == BitMask) ||  // reserved bit is set
			     (ByteIdx == 2 && BitIndex == 4 && (pPid->Data[2] & BitMask) == BitMask) ||  // reserved bit is set
			     (ByteIdx == 3 && BitIndex == 4 && (pPid->Data[3] & BitMask) == BitMask) )   // reserved bit is set
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  PID $41 Reserved Bit (Byte %c Bit %d) set (1) (must be clear (0))\n",
				      GetEcuId ( EcuIdx ),
				      'A'+ ByteIdx,
				      BitIndex );
			}

			// Compression Ignition (Diesel) bit check
			// Compression bit should match user input
			else if ( ByteIdx == 1 && BitIndex == 3 )
			{
				// only check if MY 2010 and beyond and ECU does not only supports CCM requirements (SID 1 PID 1 Data B bit 2==1)
				if ( gModelYear >= 2010 &&
				     ((gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x03) != 0x00 ||
				      (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0xFF) != 0x00) )
				{
					if ( (pPid->Data[1] & 0x08) == 0x00 &&
					     gbDiesel == 1 )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  SID $01 PID $41 Data B bit 3 clear (Spark Ignition) does not match user input (Diesel)\n",
						      GetEcuId ( EcuIdx ) );
						bTestFailed = TRUE;
					}
					else if ( (pPid->Data[1] & 0x08) == 0x08 &&
					          (gbDiesel == FALSE) )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  SID $01 PID $41 Data B bit 3 set (Compression Ignition) does not match user input (Non Diesel)\n",
						      GetEcuId ( EcuIdx ) );
						bTestFailed = TRUE;
					}
				}
			}

			// Enable/Support bit check
			// enabled monitors should be supported
			else if ( ((ByteIdx == 1 && BitIndex >= 0 && BitIndex <=2) ||
			           ByteIdx == 2) &&
			          (pPid->Data[ByteIdx] & BitMask) == BitMask  &&  // enabled       in PID $41
			          (gstEcuSIDData[EcuIdx].Pid01.Data[ByteIdx] & BitMask) == 0x00 )       // not supported in PID $01
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  If monitor enabled (%s_ENA = 1 (YES)) in PID $41 it must indicate supported (%s_SUP = 1 (YES)) in PID $01\n",
				      GetEcuId ( EcuIdx ),
				      String[StringIndex],
				      String[StringIndex] );
				bTestFailed = TRUE;
			}


			else
			{
				// Incomplete/Supported bit check
				// incomplete monitors should be supported
				if ( (pPid->Data[ByteIdx] & BitMask) == BitMask &&                                                                    // not complete  in PID $41
				     ((ByteIdx == 1 && BitIndex >= 4 && BitIndex <=6 && (gstEcuSIDData[EcuIdx].Pid01.Data[1] & BitMask2) == 0x00) ||  // not supported in PID $01
				      (ByteIdx == 3 &&                                  (gstEcuSIDData[EcuIdx].Pid01.Data[2] & BitMask)  == 0x00)) )  // not supported in PID $01
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  If monitor not complete (%s_CMPL = 1 (NO)) in PID $41 it must indicate supported (%s_SUP = 1 (YES)) in PID $01\n",
					      GetEcuId ( EcuIdx ),
					      String[StringIndex],
					      String[StringIndex] );
					bTestFailed = TRUE;
				}
				if ( ByteIdx == 1 && BitIndex >= 4 && BitIndex <=6 )
				{
					BitMask2 <<= 1;
				}


				// Byte 3 (D) only checks
				if ( ByteIdx == 3 )
				{
					// Supported/Incomplete bit check
					// supported monitors should be incomplete (when engine off)
					if ( bEngineDontCare == FALSE && gbEngineRunning == FALSE &&        // test 5.6 ONLY; NOT Test 5.10, 10.2 & 10.13
					     (gstEcuSIDData[EcuIdx].Pid01.Data[2] & BitMask) == BitMask &&  // supported in PID $01
					     (pPid->Data[3]    & BitMask) == 0x00 )                         // complete  in PID $41
					{
						if ( BitIndex != 6 || gbDiesel == TRUE )  // O2 Heater monitor is allowed to complete for gasoline vehicles
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  If monitor supported (%s_SUP = 1 (YES)) in PID $01 it must indicate incomplete (%s_CMPL = 1 (NO)) in PID $41\n",
							      GetEcuId ( EcuIdx ),
							      String[StringIndex],
							      String[StringIndex] );
							bTestFailed = TRUE;
						}
					}


					// Unupported/Complete bit check
					// unsupported monitors should be complete
					if ( (gstEcuSIDData[EcuIdx].Pid01.Data[2] & BitMask) == 0x00 &&  // not supported in PID $01
					     (pPid->Data[3] & BitMask) == BitMask )                      // not complete  in PID $41
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  If monitor unsupported (%s_SUP = 0 (NO)) in PID $01 it must indicate complete (%s_CMPL = 0 (YES)) in PID $41\n",
						      GetEcuId ( EcuIdx ),
						      String[StringIndex],
						      String[StringIndex] );
						bTestFailed = TRUE;
					}
				}
			}
		}
	}


	if ( bTestFailed == TRUE )
	{
		return  FAIL;
	}
	else
	{
		return  PASS;
	}
}


/*******************************************************************************
**
**  Function:  VerifyIM_Ready
**
**  Purpose:   Request SID 1 PID 1 and check IM Ready
**
*******************************************************************************/
STATUS VerifyIM_Ready ( void )
{
	REQ_MSG       stReqMsg;
	PID          *pPid;
	BYTE          EcuIdx;

	unsigned long TempData_long;

	BOOL          bTestFailed = FALSE;


	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0x01 ) == FALSE )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "SID $01 PID $01 not supported\n" );
		bTestFailed = TRUE;
	}

	stReqMsg.SID    = 0x01;
	stReqMsg.NumIds = 1;
	stReqMsg.ID[0]  = 0x01;
	if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
	{
		// There must be a response for ISO15765 protocol
		if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "SID $01 PID $01 request\n" );
			bTestFailed = TRUE;
		}
	}
	else
	{
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( gstResponse[EcuIdx].PidSize != 0 )
			{
				break;  // leave ECU for loop
			}
		}

		if ( EcuIdx >= gNumOfECUs )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "No SID $01 PID $01 data\n" );
			bTestFailed = TRUE;
		}
		else
		{
			// Verify that all SID 1 PID data is valid
			for ( EcuIdx = 0;
			      EcuIdx < gNumOfECUs;
			      EcuIdx++ )
			{
				// If PID is supported, check it
				if ( IsIDSupported ( EcuIdx, PIDREQUEST, 1 ) == TRUE)
				{
					// Check the data to see if it is valid
					pPid = (PID *)&gstResponse[EcuIdx].Pid[0];
					memcpy ( &gstEcuSIDData[EcuIdx].Pid01.ID,
					         &pPid[0],
					         sizeof( PID ) );
					if ( gstResponse[EcuIdx].PidSize != 0 )
					{
						if ( VerifyPid01 ( pPid, EcuIdx, &TempData_long ) != PASS )   // TempData_long is ignored
						{
							bTestFailed = TRUE;
						}
					}
					else
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  SID $01 PID $01 data size is 0\n",
						      GetEcuId ( EcuIdx ) );
						bTestFailed = TRUE;
					}
				}
			}
		}
	}

	// if this is test 11.3, check for appropriate value of SID $01 PID $31 and $4E
	if ( geTestPhase == eTestPerformanceCounters && gTestSubsection == 3 )
	{
		// If PID $31 is supported, request it
		if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0x31 ) == TRUE )
		{
			stReqMsg.SID    = 0x01;
			stReqMsg.NumIds = 1;
			stReqMsg.ID[0]  = 0x31;
			if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
			{
				// There must be a response for ISO15765 protocol
				if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $01 PID $31 request\n" );
					bTestFailed = TRUE;
				}
			}
			else
			{
				// Check the data to see if it is valid
				for ( EcuIdx = 0;
				      EcuIdx < gNumOfECUs;
				      EcuIdx++ )
				{
					if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0x31 ) == TRUE )
					{
						pPid = (PID *)&gstResponse[EcuIdx].Pid[0];
						TempData_long = ((pPid->Data[0] << 8) +
						                   pPid->Data[1]);
						if ( gstResponse[EcuIdx].PidSize != 0 )
						{
							if ( TempData_long == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  SID $01 PID $31 is 0\n",
								      GetEcuId ( EcuIdx ) );
								bTestFailed = TRUE;
							}
						}
						else
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  SID $01 PID $31 size is 0\n",
							      GetEcuId ( EcuIdx ) );
							bTestFailed = TRUE;
						}
					}
				}
			}
		}

		// If PID $4E is supported, request it
		if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0x4E ) == TRUE )
		{
			stReqMsg.SID    = 0x01;
			stReqMsg.NumIds = 1;
			stReqMsg.ID[0]  = 0x4E;
			if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
			{
				// There must be a response for ISO15765 protocol
				if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $01 PID $4E request\n" );
					bTestFailed = TRUE;
				}
			}
			else
			{
				// Check the data to see if it is valid
				for ( EcuIdx = 0;
				      EcuIdx < gNumOfECUs;
				      EcuIdx++ )
				{
					if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0x4E ) == TRUE )
					{
						pPid = (PID *)&gstResponse[EcuIdx].Pid[0];
						TempData_long = ((pPid->Data[0] << 8) +
						                  pPid->Data[1]);
						if ( gstResponse[EcuIdx].PidSize != 0 )
						{
							if ( TempData_long == 0 )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  SID $01 PID $4E is 0\n",
								      GetEcuId ( EcuIdx ) );
								bTestFailed = TRUE;
							}
						}
						else
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  SID $01 PID $4E size is 0\n",
							      GetEcuId ( EcuIdx ) );
							bTestFailed = TRUE;
						}
					}
				}
			}
		}
	}

	if ( bTestFailed == TRUE )
	{
		return  FAIL;
	}
	else
	{
		return  PASS;
	}
}


/*******************************************************************************
**
**  Function:  DetermineVariablePidSize
**
**  Purpose:   Determine number of data bytes in PIDs $06 - $09, $55 - $58
**
******************************************************************************/
STATUS DetermineVariablePidSize ( void )
{
	REQ_MSG        stReqMsg;
	PID           *pPid;
	BYTE           EcuIdx;

	BYTE           PidArray[MAX_ECUS];
	unsigned long  EcuIdIdx[MAX_ECUS];

	BYTE           NumResp;


	// only need to check once
	if ( gVariablePidSize != 0 )
	{
		return PASS;
	}

	// -1 ==> cannot determine the PID size
	gVariablePidSize = -1;

	// only check if needed
	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0x06 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0x07 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0x08 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0x09 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0x55 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0x56 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0x57 ) == FALSE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0x58 ) == FALSE )
	{
		 return PASS;
	}

	// cannot support both PID $13 and $1D
	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0x13 ) == TRUE &&
	     IsIDSupported ( ALLECUS, PIDREQUEST, 0x1D ) == TRUE )
	{
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0x13 ) == TRUE )
			{
				Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  Supports SID $01 PID $13\n",
				      GetEcuId ( EcuIdx ) );
			}

			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0x1D ) == TRUE )
			{
				Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  Supports SID $01 PID $1D\n",
				      GetEcuId ( EcuIdx ) );
			}
		}
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Both PID $13 and $1D are supported\n" );
		return FAIL;
	}

	// check PID $13 first
	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0x13 ) == TRUE )
	{
		stReqMsg.SID    = 0x01;
		stReqMsg.NumIds = 1;
		stReqMsg.ID[0]  = 0x13;
		if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			// There must be a response for ISO15765 protocol
			if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $01 PID $13 request\n" );
				return FAIL;
			}
		}

		NumResp = 0;
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0x13 ) == TRUE )
			{
				if ( gstResponse[EcuIdx].PidSize > 0 )
				{
					pPid = (PID *)(gstResponse[EcuIdx].Pid);
					if ( pPid->ID == 0x13 )
					{
						Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  PID $13  O2SLOC = $%02X\n",
						      GetEcuId ( EcuIdx ),
						      pPid->Data[0] );
						EcuIdIdx[NumResp] = EcuIdx;
						PidArray[NumResp++] = pPid->Data[0];
					}
				}
			}
		}

		if ( NumResp == 0 || NumResp > 2 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "SID $01 PID $13 supported by %d ECUs (1 to 2 expected)\n",
			      NumResp );
			return FAIL;
		}

		gVariablePidSize = 1;
		return PASS;
	}

	// check PID $1D second
	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0x1D ) == TRUE )
	{
		stReqMsg.SID    = 0x01;
		stReqMsg.NumIds = 1;
		stReqMsg.ID[0]  = 0x1D;
		if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			// There must be a response for ISO15765 protocol
			if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $01 PID $1D request\n" );
				return FAIL;
			}
		}

		NumResp = 0;
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0x1D ) == TRUE )
			{
				if ( gstResponse[EcuIdx].PidSize > 0 )
				{
					pPid = (PID *)(gstResponse[EcuIdx].Pid);
					if ( pPid->ID == 0x1D )
					{
						Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  PID $1D  O2SLOC = $%02X\n",
						      GetEcuId ( EcuIdx ),
						      pPid->Data[0] );
						EcuIdIdx[NumResp] = EcuIdx;
						PidArray[NumResp++] = pPid->Data[0];
					}
				}
			}
		}

		if ( NumResp == 1 )
		{
			gVariablePidSize = (PidArray[0] == 0xFF) ? 2 : 1;
			return PASS;
		}

		else if ( NumResp == 2 )
		{
			if ( (PidArray[0] | PidArray[1]) != 0xFF )
			{
				gVariablePidSize = 1;
				return PASS;
			}

			if ( (PidArray[0] == 0xF0 && PidArray[1] == 0x0F) ||
			     (PidArray[0] == 0x0F && PidArray[1] == 0xF0) )
			{
				gVariablePidSize = 2;
				return PASS;
			}

			if ( (PidArray[0] == 0xCC && PidArray[1] == 0x33) ||
			     (PidArray[0] == 0x33 && PidArray[1] == 0xCC) )
			{
				gVariablePidSize = 2;
				return PASS;
			}

			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Unable to determine number of data bytes in PIDs $06 - $09\n" );
			return FAIL;
		}

		// NumResp == 0 or NumResp > 2
		else
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      " SID $01 PID $1D supported by %d ECUs ( 1 to 2 expected)\n",
			      NumResp );
			return FAIL;
		}
	}

	Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
	      "Neither SID $01 PID $13 nor $1D are supported\n" );
	return FAIL;
}


/*******************************************************************************
**
**  Function:  GetPid4FArray
**
**  Purpose:   Copy PID $4F values into an array.
**
*******************************************************************************/
STATUS GetPid4FArray ( void )
{
	REQ_MSG  stReqMsg;
	PID     *pPid;
	BYTE     EcuIdx;


	for ( EcuIdx = 0;
	      EcuIdx < gNumOfECUs;
	      EcuIdx++ )
	{
		Pid4F[EcuIdx][0] = 0x00;
		Pid4F[EcuIdx][1] = 0x00;
		Pid4F[EcuIdx][2] = 0x00;
		Pid4F[EcuIdx][3] = 0x00;
	}

	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0x4F ) == TRUE )
	{
		stReqMsg.SID    = 0x01;
		stReqMsg.NumIds = 1;
		stReqMsg.ID[0]  = 0x4F;
		if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "SID $01 PID $4F request\n" );
			return FAIL;
		}

		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0x4F ) == TRUE )
			{
				if ( gstResponse[EcuIdx].PidSize > 0 )
				{
					pPid = (PID *)(gstResponse[EcuIdx].Pid);
					if ( pPid->ID == 0x4F )
					{
						Pid4F[EcuIdx][0] = pPid->Data[0];
						Pid4F[EcuIdx][1] = pPid->Data[1];
						Pid4F[EcuIdx][2] = pPid->Data[2];
						Pid4F[EcuIdx][3] = pPid->Data[3];
					}
				}
			}
		}
	}
	return PASS;
}


/*******************************************************************************
**
**  Function:  GetPid50Array
**
**  Purpose:   Copy PID $50 values into an array.
**
*******************************************************************************/
STATUS GetPid50Array ( void )
{
	REQ_MSG  stReqMsg;
	PID     *pPid;
	BYTE     EcuIdx;


	if ( IsIDSupported ( ALLECUS, PIDREQUEST, 0x50 ) == TRUE )
	{
		stReqMsg.SID    = 0x01;
		stReqMsg.NumIds = 1;
		stReqMsg.ID[0]  = 0x50;

		if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "SID $01 PID $50 request\n" );
			return FAIL;
		}

		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IsIDSupported ( EcuIdx, PIDREQUEST, 0x50 ) == TRUE )
			{
				if ( gstResponse[EcuIdx].PidSize > 0 )
				{
					pPid = (PID *)(gstResponse[EcuIdx].Pid);
					if ( pPid->ID == 0x50 )
					{
						Pid50[EcuIdx][0] = pPid->Data[0];
						Pid50[EcuIdx][1] = pPid->Data[1];
						Pid50[EcuIdx][2] = pPid->Data[2];
						Pid50[EcuIdx][3] = pPid->Data[3];
					}
				}
			}
		}
	}
	return PASS;
}


/*******************************************************************************
**
**  Function:  GetHoursMinsSecs
**
**  Purpose:   Convert the time (in seconds) into hours, minutes and seconds .
**
*******************************************************************************/
void GetHoursMinsSecs ( unsigned long time,
                        unsigned long *pHours,
                        unsigned long *pMins,
                        unsigned long *pSecs )
{
	*pHours = time/3600;

	*pMins = (time - (*pHours * 3600)) / 60;

	*pSecs = time - (*pHours * 3600) - (*pMins * 60);
}
