/*******************************************************************************
********************************************************************************
**
**  Copyright(c) 2022, Alliance for Automotive Innovation
**  Used only under license from the Alliance for Automotive Innovation. All Rights Reserved.
**
**  Project:  J1699-3
**  FileName: VerifyMonitorTestSupportAndResults.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 <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:  VerifyMIDSupportAndResults
**
**  Purpose:   Verify MID monitor test support and results
**
*******************************************************************************/
STATUS VerifyMIDSupportAndResults ( void )
{
	REQ_MSG        stReqMsg;
	MID           *pMid;
	BYTE           EcuIdx;

	unsigned long  IdIdx;
	unsigned long  MidIdx;
	unsigned long  InitialFailureCount = 0;
	unsigned short TempData_unsigned;
	signed short   TempData_signed;
	long           TestVal;
	long           TestLimMax;
	long           TestLimMin;

	BOOL           bError = FALSE;               // set if an error occured during test
	BOOL           bSparkIgnMonSup = FALSE;      // set if Spark Ignition Monitor is supported (otherwise Compression)

	BOOL           bDataBBit0Supported = FALSE;  // set if PID 01 Data B bit 0 is supported by the vehicle
	BOOL           bDataCBit0Supported = FALSE;  // set if PID 01 Data C bit 0 is supported by the vehicle
	BOOL           bDataCBit1Supported = FALSE;  // set if PID 01 Data C bit 1 is supported by the vehicle
	BOOL           bDataCBit2Supported = FALSE;  // set if PID 01 Data C bit 2 is supported by the vehicle
	BOOL           bDataCBit3Supported = FALSE;  // set if PID 01 Data C bit 3 is supported by the vehicle
	BOOL           bDataCBit5Supported = FALSE;  // set if PID 01 Data C bit 5 is supported by the vehicle
	BOOL           bDataCBit6Supported = FALSE;  // set if PID 01 Data C bit 6 is supported by the vehicle
	BOOL           bDataCBit7Supported = FALSE;  // set if PID 01 Data C bit 7 is supported by the vehicle

	BOOL           bMid01Supported = FALSE;      // set if MID 01 is supported by the vehicle
	BOOL           bMid21Supported = FALSE;      // set if MID 21 is supported by the vehicle
	BOOL           bMidA20BSupported = FALSE;    // set if MID A2 SDTID 0B is supported by the vehicle
	BOOL           bMidA20CSupported = FALSE;    // set if MID A2 SDTID 0C is supported by the vehicle
	BOOL           bMidB2Supported = FALSE;      // set if MID B2 is supported by the vehicle

	BOOL           bMid01_10Supported = FALSE;   // set if a MID between 01 and 10 is supported by the ECU
	BOOL           bMid21_24Supported = FALSE;   // set if a MID between 21 and 24 is supported by the ECU
	BOOL           bMid31_38Supported = FALSE;   // set if a MID between 31 and 38 is supported by the ECU
	BOOL           bMid39_3DSupported = FALSE;   // set if a MID between 39 and 3D is supported by the ECU
	BOOL           bMid61_64Supported = FALSE;   // set if a MID between 61 and 64 is supported by the ECU
	BOOL           bMid71_74Supported = FALSE;   // set if a MID between 71 and 74 is supported by the ECU
	BOOL           bMid81_84Supported = FALSE;   // set if a MID between 81 and 84 is supported by the ECU
	BOOL           bMidA1_B1Supported = FALSE;   // set if a MID between A1 and B1 is supported by the ECU
	BOOL           bMidB2_B3Supported = FALSE;   // set if a MID between B2 and B3 is supported by the ECU
	BOOL           bMid85_86Supported = FALSE;   // set if a MID between 85 and 86 is supported by the ECU
	BOOL           bMid90919899Supported = FALSE;  // set if MID 90,91,98 or 99 is supported by the ECU


	InitialFailureCount = GetFailureCount ( );

	// Request SID 6 support data
	if ( RequestIDSupportData ( MIDREQUEST, FALSE ) != PASS )
	{
		return FAIL;
	}

	// Verify that all SID 6 test data is reset or within limits
	for ( EcuIdx = 0;
	      EcuIdx < gNumOfECUs;
	      EcuIdx++ )
	{
		// Test 5.14.3
		if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 &&
		     geTestPhase == eTestNoDTC && gTestSubsection == 14 )
		{
			// if Spark Ignition Module (SID $01 PID $01 Data B bit 3 == 0)
			if ( (gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x08) == 0x00 )
			{
				bSparkIgnMonSup = TRUE;
			}
			else
			{
				bSparkIgnMonSup = FALSE;
			}


			// if ECU does not only support CCM requirements (SID 1 PID 1 Data B bit 2 == 1)
			if ( (gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x03) != 0x00 ||
			     (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0xFF) != 0x00 )
			{
				// Test SID 1 PID 1 Data B bit 3 for each ECU
				if ( gModelYear >= 2010 )
				{
					if ( gbDiesel == TRUE &&
					     bSparkIgnMonSup == TRUE )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  SID $01 PID $01 Data B bit 3 must = 1 for Compression Ignition Vehicles\n",
						      GetEcuId ( EcuIdx ) );
						bError = TRUE;
					}
					else if ( gbDiesel == FALSE &&
					          bSparkIgnMonSup == FALSE )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  SID $01 PID $01 Data B bit 3 must = 0 for Spark Ignition Vehicles\n",
						      GetEcuId ( EcuIdx ) );
						bError = TRUE;
					}
				}
				// prior to MY 2010, warn for compression only
				else
				{
					if ( gbDiesel == TRUE &&
					     bSparkIgnMonSup == TRUE )
					{
						Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  SID $01 PID $01 Data B bit 3 should = 1 for Compression Ignition Vehicles\n",
						      GetEcuId ( EcuIdx ) );
					}
				}
			}


			if ( (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x10) != 0 &&
			     ((gstUserInput.eComplianceType != CNOBD_NO_IUMPR &&
			       gstUserInput.eComplianceType != EOBD_WITH_IUMPR &&
			       gstUserInput.eComplianceType != EOBD_NO_IUMPR &&
			       gstUserInput.eComplianceType != HD_EOBD &&
			       gstUserInput.eComplianceType != US_OBDII &&
			       gstUserInput.eComplianceType != HD_OBD) ||
			      gbDiesel == TRUE) )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  SID $01 PID $01 Data C bit 4 is set (Must be 0 for Compression Ignition and Non-China, US, EU Spark Ignition Vehicles)\n",
				      GetEcuId ( EcuIdx ) );
				bError = TRUE;
			}

			if ( bSparkIgnMonSup == FALSE &&
			     (gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x04) != 0 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  SID $01 PID $01 Data C bit 2 is set (Must be 0 for Compression Ignition Vehicles)\n",
				      GetEcuId ( EcuIdx ) );
				bError = TRUE;
			}

			// Test PID Data B bit 1 for the vehicle
			if ( gstEcuSIDData[EcuIdx].Pid01.Data[1] & 0x01 )
			{
				bDataBBit0Supported = TRUE;
			}

			// Test PID Data C bit 0 for the vehicle
			if ( gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x01 )
			{
				bDataCBit0Supported = TRUE;
			}

			// Test PID Data C bit 1 for the vehicle
			if ( gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x02 )
			{
				bDataCBit1Supported = TRUE;
			}

			// Test PID Data C bit 2 for the vehicle
			if ( gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x04 )
			{
				bDataCBit2Supported = TRUE;
			}

			// Test PID Data C bit 3 for the vehicle
			if ( gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x08 )
			{
				bDataCBit3Supported = TRUE;
			}

			// Test PID Data C bit 5 for the vehicle
			if ( gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x20 )
			{
				bDataCBit5Supported = TRUE;
			}

			// Test PID Data C bit 6 for the vehicle
			if ( gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x40 )
			{
				bDataCBit6Supported = TRUE;
			}

			// Test PID Data C bit 7 for the vehicle
			if ( gstEcuSIDData[EcuIdx].Pid01.Data[2] & 0x80 )
			{
				bDataCBit7Supported = TRUE;
			}

		} // end Test5.14.3

		// For each MID group
		for ( IdIdx = 0x01;
		      IdIdx < 0x100;
		      IdIdx++ )
		{
			// skip PID supported PIDs
			// and unsupportyed PIDs
			if ( IdIdx != 0x20 && IdIdx != 0x40 &&
			     IdIdx != 0x60 && IdIdx != 0x80 &&
			     IdIdx != 0xA0 && IdIdx != 0xC0 &&
			     IdIdx != 0xE0 &&
			     IsIDSupported ( EcuIdx, MIDREQUEST, IdIdx ) == TRUE )
			{
				stReqMsg.SID    = 0x06;
				stReqMsg.NumIds = 1;
				stReqMsg.ID[0]  = (BYTE)IdIdx;
				if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  SID $06 MID $%02X request\n",
					      GetEcuId ( EcuIdx ) ,
					      IdIdx );
					bError = TRUE;
					continue;  // just go to the next itteration of the MID for loop
				}

				if ( gstResponse[EcuIdx].MidSize == 0 )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  No SID $06 MID $%02X data\n",
					      GetEcuId ( EcuIdx ),
					      IdIdx );
					bError = TRUE;
					continue;  // just go to the next itteration of the MID for loop
				}

				// Check the data that should be reset and / or within limits
				pMid = (MID *)&gstResponse[EcuIdx].Mid[0];
				for ( MidIdx = 0;
				      MidIdx < (gstResponse[EcuIdx].MidSize / sizeof ( MID ));
				      MidIdx++ )
				{
					// If ISO15765 protocol...
					if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
					{
						// IF not test 11.4 (tests 5.5, 5.14 and 10.6
						if ( geTestPhase != eTestPerformanceCounters )
						{
							// If MID 0x01 - 0x10 TID 1 - 4 OR
							// Test 5.14.3 AND MID $A1 - $B1, don't check for reset
							// Otherwise, values should be zero after a code clear
							if ( !(pMid[MidIdx].ID <= 0x10 && pMid[MidIdx].SDTID <= 4) &&
							     !(geTestPhase == eTestNoDTC && gTestSubsection == 14 &&
							       pMid[MidIdx].ID >= 0xA1 && pMid[MidIdx].ID <= 0xB1) )
							{
								if ( pMid[MidIdx].TVHI    != 0 || pMid[MidIdx].TVLO    != 0 ||
								     pMid[MidIdx].MINTLHI != 0 || pMid[MidIdx].MINTLLO != 0 ||
								     pMid[MidIdx].MAXTLHI != 0 || pMid[MidIdx].MAXTLLO != 0 )
								{
									Log ( WARNING, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  SID $06 MID $%02X test value/limits not reset\n",
									      GetEcuId ( EcuIdx ),
									      pMid[MidIdx].ID );
								}
							}


							// Test 5.14.3
							if ( geTestPhase == eTestNoDTC && gTestSubsection == 14 )
							{
								// Check for prohibited MIDs
								if ( (pMid[MidIdx].ID >= 0x15 && pMid[MidIdx].ID <= 0x1F) ||
								     (pMid[MidIdx].ID >= 0x25 && pMid[MidIdx].ID <= 0x30) ||
								     pMid[MidIdx].ID == 0x3F  ||
								     (pMid[MidIdx].ID >= 0x55 && pMid[MidIdx].ID <= 0x5F) ||
								     (pMid[MidIdx].ID >= 0x65 && pMid[MidIdx].ID <= 0x70) ||
								     (pMid[MidIdx].ID >= 0x75 && pMid[MidIdx].ID <= 0x7F) ||
								     (pMid[MidIdx].ID >= 0x87 && pMid[MidIdx].ID <= 0x8F) ||
								     (pMid[MidIdx].ID >= 0x92 && pMid[MidIdx].ID <= 0x97) ||
								     (pMid[MidIdx].ID >= 0x9A && pMid[MidIdx].ID <= 0x9F) ||
								     (pMid[MidIdx].ID >= 0xB4 && pMid[MidIdx].ID <= 0xBF) ||
								     (pMid[MidIdx].ID >= 0xC1 && pMid[MidIdx].ID <= 0xDF) ||
								     (gstUserInput.eComplianceType == US_OBDII && pMid[MidIdx].ID >= 0xE1 && pMid[MidIdx].ID <= 0xFF) )
								{
									Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
									      "ECU %X  SID $06 MID $%02X support prohibited\n",
									      GetEcuId ( EcuIdx ),
									      pMid[MidIdx].ID );
									bError = TRUE;
								}

								// Check MID ranges common to spark and Compression Ignition vehicles
								else if ( pMid[MidIdx].ID <= 0x10 )
								{
									bMid01_10Supported = TRUE;

									// Test 5.14.3 - MID $01 must be supported by all vehicles
									if ( pMid[MidIdx].ID == 0x01 )
									{
										bMid01Supported = TRUE;
									}
								}

								else if ( pMid[MidIdx].ID >= 0x31 && pMid[MidIdx].ID <= 0x38 )
								{
									bMid31_38Supported = TRUE;
								}

								else if ( pMid[MidIdx].ID >= 0x81 && pMid[MidIdx].ID <= 0x84 )
								{
									bMid81_84Supported = TRUE;
								}

								// Check MID ranges for Spark Ignition Vehicles
								else if ( bSparkIgnMonSup == TRUE )
								{
									if ( pMid[MidIdx].ID >= 0x21 && pMid[MidIdx].ID <= 0x24 )
									{
										bMid21_24Supported = TRUE;

										if ( pMid[MidIdx].ID == 0x21 )
										{
											bMid21Supported = TRUE;
										}
									}

									else if ( pMid[MidIdx].ID >= 0x39 && pMid[MidIdx].ID <= 0x3D )
									{
										bMid39_3DSupported = TRUE;
									}

									else if ( pMid[MidIdx].ID >= 0x61 && pMid[MidIdx].ID <= 0x64 )
									{
										bMid61_64Supported = TRUE;
									}

									else if ( pMid[MidIdx].ID >= 0x71 && pMid[MidIdx].ID <= 0x74 )
									{
										bMid71_74Supported = TRUE;
									}
								}

								// Check MID ranges for Compression Ignition Vehicles
								else
								{
									if ( pMid[MidIdx].ID >= 0x21 && pMid[MidIdx].ID <= 0x24 )
									{
										bMid21_24Supported = TRUE;
									}

									else if ( pMid[MidIdx].ID >= 0x85 && pMid[MidIdx].ID <= 0x86 )
									{
										bMid85_86Supported = TRUE;
									}

									else if ( pMid[MidIdx].ID == 0x90 ||
									          pMid[MidIdx].ID == 0x91 ||
									          pMid[MidIdx].ID == 0x98 ||
									          pMid[MidIdx].ID == 0x99 )
									{
										bMid90919899Supported = TRUE;
									}

									if ( pMid[MidIdx].ID >= 0xB2 && pMid[MidIdx].ID <= 0xB3 )
									{
										bMidB2_B3Supported = TRUE;

										if ( pMid[MidIdx].ID == 0xB2 )
										{
											bMidB2Supported = TRUE;
										}
									}
								}

							}  // end Test 5.14.3

						}  // end if ( geTestPhase != eTestPerformanceCounters )

						// Tests 5.5, 5.14, 10.6 and 11.4
						// If MID $A1 thru $B1, MID $A2 SDTID $0B or $0C must be supported
						if ( pMid[MidIdx].ID >= 0xA1 && pMid[MidIdx].ID <= 0xB1 )
						{
							bMidA1_B1Supported = TRUE;

							if ( pMid[MidIdx].ID == 0xA2 )
							{
								if ( pMid[MidIdx].SDTID == 0x0B )
								{
									bMidA20BSupported = TRUE;
								}

								if ( pMid[MidIdx].SDTID == 0x0C )
								{
									bMidA20CSupported = TRUE;
								}
							}
						}

					}  // end if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765)

					// IF protocol other than ISO15765 OR in drive cycle (Test 11.4)
					if ( gstProtocolList[gProtocolIdx].eProtocol != ISO15765 ||
					     geTestPhase == eTestPerformanceCounters )
					{
						// Check the value against the limits
						if ( pMid[MidIdx].UASID & 0x80 )
						{
							// Signed values
							TempData_signed = (pMid[MidIdx].TVHI << 8) + pMid[MidIdx].TVLO;
							TestVal = TempData_signed;

							TempData_signed = (pMid[MidIdx].MINTLHI << 8) + pMid[MidIdx].MINTLLO;
							TestLimMin = TempData_signed;

							TempData_signed = (pMid[MidIdx].MAXTLHI << 8 ) + pMid[MidIdx].MAXTLLO;
							TestLimMax = TempData_signed;
						}
						else
						{
							// Unsigned values
							TempData_unsigned = (pMid[MidIdx].TVHI << 8) + pMid[MidIdx].TVLO;
							TestVal = TempData_unsigned;

							TempData_unsigned = (pMid[MidIdx].MINTLHI << 8) + pMid[MidIdx].MINTLLO;
							TestLimMin = TempData_unsigned;

							TempData_unsigned = (pMid[MidIdx].MAXTLHI << 8 ) + pMid[MidIdx].MAXTLLO;
							TestLimMax = TempData_unsigned;
						}

						if ( TestVal < TestLimMin )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  SID $06 MID $%02X test value exceeded min\n",
							      GetEcuId ( EcuIdx ),
							      pMid[MidIdx].ID );
							bError = TRUE;
						}

						if ( TestVal > TestLimMax )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  SID $06 MID $%02X test value exceeded max\n",
							      GetEcuId ( EcuIdx ),
							      pMid[MidIdx].ID );
							bError = TRUE;
						}
					} // end protocol other than ISO15765

				} // end for (MidIdx . . .

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

		} // end for (IdIdx . . .

	} // end for (EcuIdx . . .


	// Check for vehicle required MIDs
	if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
	{
		// Test 5.14.3
		if ( geTestPhase == eTestNoDTC && gTestSubsection == 14 )
		{
			if ( bDataBBit0Supported == TRUE &&
			     (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) &&
			     (bMidA20BSupported == FALSE || bMidA20CSupported == FALSE) )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $06 MID $A2 SDTID $0B or $0C not supported (Required for All Vehicles with SID $01 PID $01 Data B bit 0 set)\n" );
				bError = TRUE;
			}

			if ( bDataCBit5Supported == TRUE && bMid01Supported == FALSE )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $06 MID $01 not supported (Required for All Vehicles with SID $01 PID $01 Data C bit 5 set)\n" );
				bError = TRUE;
			}

			if ( bDataCBit7Supported == TRUE && bMid31_38Supported == FALSE )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "SID $06 MID $31-$38 not supported (At least one required for All Vehicles with SID $01 PID $01 Data C bit 7 set)\n" );
				bError = TRUE;
			}

			if ( gbDiesel == FALSE )
			{
				if ( bDataCBit0Supported == TRUE && bMid21Supported == FALSE )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $06 MID $21 not supported (Required for Spark Ignition Vehicles with SID $01 PID $01 Data C bit 0 set)\n" );
					bError = TRUE;
				}

				if ( bDataCBit1Supported == TRUE && bMid61_64Supported == FALSE )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $06 MID $61-$64 not supported (At least one required for Spark Ignition Vehicles with SID $01 PID $01 Data C bit 1 set)\n" );
					bError = TRUE;
				}

				if ( bDataCBit2Supported == TRUE && bMid39_3DSupported == FALSE )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $06 MID $39-$3D not supported (At least one required for Spark Ignition Vehicles with SID $01 PID $01 Data C bit 2 set)\n" );
					bError = TRUE;
				}

				if ( bDataCBit3Supported == TRUE && bMid71_74Supported == FALSE )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $06 MID $71-$74 not supported (At least one required for Spark Ignition Vehicles with SID $01 PID $01 Data C bit 3 set)\n" );
					bError = TRUE;
				}
			}
		// ELSE a compression ignition (diesel) vehicle
			else
			{
				if ( bDataCBit6Supported == TRUE && bMidB2Supported == FALSE )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $06 MID $B2 not supported (Required for Compression Ignition Vehicles with SID $01 PID $01 Data C bit 6 set)\n" );
					bError = TRUE;
				}

				if ( bDataCBit1Supported == TRUE && bMid90919899Supported == FALSE )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $06 MID $90, $91, $98, $99 not supported (At least one required for Compression Ignition Vehicles with SID $01 PID $01 Data C bit 1 set)\n" );
					bError = TRUE;
				}

				if ( bDataCBit3Supported == TRUE && bMid85_86Supported == FALSE )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "SID $06 MID $85-$86 not supported (At least one required for Compression Ignition Vehicles with SID $01 PID $01 Data C bit 3 set)\n" );
					bError = TRUE;
				}
			}
		}  // end Test 5.14

		else if ( (gstUserInput.eComplianceType == US_OBDII || gstUserInput.eComplianceType == HD_OBD) &&
		          (bMidA20BSupported == FALSE || bMidA20CSupported == FALSE) )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "SID $06 MID $A2 SDTID $0B or $0C not supported by the vehicle\n" );
			bError = TRUE;
		}
	}

	// If ISO15765 protocol, make sure the required ID/SDTID values are supported
	// and try group support
	if ( gstProtocolList[gProtocolIdx].eProtocol == ISO15765 )
	{
		if ( geTestPhase != eTestPerformanceCounters )
		{
			if( RequestGroupIDSupportData ( MIDREQUEST ) == FAIL )
			{
				return FAIL;
			}
		}
	}

	if ( InitialFailureCount != GetFailureCount ( ) || bError == TRUE )
	{
		// There could have been early/late responses that weren't treated as FAIL
		// or other failure
		return FAIL;
	}
	else
	{
		return PASS;
	}

}
