/*******************************************************************************
********************************************************************************
**
**  Copyright(c) 2022, Alliance for Automotive Innovation
**  Used only under license from the Alliance for Automotive Innovation. All Rights Reserved.
**
**  Project:  J1699-5
**  FileName: VerifyMIDSupportAndData.c
**  Author:   EnGenius
**  Date:     2/25/2022
**  Email:    <support@autosinnovate.org>
**
**  Purpose:  SAE J1699-5 Vehicle OBD II Compliance Test Cases Source Code.
**            This source code is intended to run the tests described in
**            the SAE J1699-5 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:  03/13/2023  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;
	STATUS          eRetCode;

	unsigned short  IdIdx;
	unsigned short  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            bGasolineMonSup     = FALSE;     // set if Gasoline Monitor is supported (otherwise Diesel)

//	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            bCATSupported       = FALSE; // set if PID $01 Data C bit 0 is supported by the vehicle
	BOOL            bHCCATSupported     = 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            bHCATSupported      = FALSE; // set if PID $01 Data C bit 1 is supported by the vehicle
	BOOL            bSCRSupported       = 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            bEVAPSupported      = 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            bAIRSupported       = FALSE; // set if PID $01 Data C bit 3 is supported by the vehicle
	BOOL            bBPSupported        = 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            bO2SSupported       = FALSE; // set if PID $01 Data C bit 5 is supported by the vehicle
	BOOL            bEGSSupported       = 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            bHTRSupported       = FALSE; // set if PID $01 Data C bit 6 is supported by the vehicle
	BOOL            bPMSupported        = 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            bEGRSupported       = 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 MID support data
	if ( RequestIDSupportData ( MIDREQUEST, FALSE ) != PASS )
	{
		return FAIL;
	}

	if ( gbPhysicalAddressing == FALSE )
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Request MID (SID $22 DID $F6xx) Functionally Addressed\n" );
	}
	else
	{
		Log ( INFORMATION, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "Request MID (SID $22 DID $F6xx) Physically Addressed\n" );
	}

	// For each MID group
	for ( IdIdx = 0xF601;
	      IdIdx < 0xF700;
	      IdIdx++ )
	{
		// skip PID supported PIDs
		// and unsupportyed PIDs
		if ( IdIdx != 0xF620 && IdIdx != 0xF640 &&
		     IdIdx != 0xF660 && IdIdx != 0xF680 &&
		     IdIdx != 0xF6A0 && IdIdx != 0xF6C0 &&
		     IdIdx != 0xF6E0 &&
		     IsIDSupported ( ALLECUS, MIDREQUEST, IdIdx ) == TRUE )
		{
			stReqMsg.SID      = 0x22;
			stReqMsg.NumIds   = 1;
			stReqMsg.u.DID[0] = IdIdx;
			if ( gbPhysicalAddressing == FALSE )
			{
				eRetCode = RequestSID ( &stReqMsg, REQ_MSG_NORMAL );
			}
			else if ( gbPhysicalAddressing == TRUE )
			{
				eRetCode = PASS;
				gbAllECUResetCompleted = FALSE;
				for ( EcuIdx = 0;
				      EcuIdx < gNumOfECUs;
				      EcuIdx++ )
				{
					if ( IsIDSupported ( EcuIdx, MIDREQUEST, IdIdx ) == TRUE )
					{
						if ( RequestSID_PhysicallyAddressed_Single ( &stReqMsg, REQ_MSG_NORMAL, gstResponse[EcuIdx].ReqId ) != PASS )
						{
							eRetCode = FAIL;
						}
					}
				}
			}

			if ( eRetCode != PASS )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "MID $%04X request\n",
				      IdIdx );
				bError = TRUE;
				continue;  // just go to the next itteration of the MID for loop
			}

			// Verify that all MID test data is reset or within limits
			for ( EcuIdx = 0;
			      EcuIdx < gNumOfECUs;
			      EcuIdx++ )
			{
				// Test 5.14.3
				if ( geTestPhase == eTestNoDTC && gTestSubsection == 14 )
				{
//					// if Gasoline Module (PID $F401 Data B bit 3 == 0)
//					if ( (gstResponse[EcuIdx].PIDF501.Data[1] & 0x08) == 0x00 )
//					{
//						bGasolineMonSup = TRUE;
//						gstUserInput.eFuelType == GASOLINE;
//					}
//					else
//					{
//						bGasolineMonSup = FALSE;
//						gstUserInput.eFuelType == DIESEL;
//					}
					if ( gstUserInput.eFuelType == GASOLINE )
					{
						bGasolineMonSup = TRUE;
					}
					else if ( gstUserInput.eFuelType == DIESEL )

					{
						bGasolineMonSup = FALSE;
					}


					// if ECU does not only support CCM requirements (PID $F401 Data B bit 2 == 1)
//					if ( (gstResponse[EcuIdx].PIDF501.Data[1] & 0x03) != 0x00 ||
//					     (gstResponse[EcuIdx].PIDF501.Data[2] & 0xFF) != 0x00 )
					if ( (gstResponse[EcuIdx].PIDF501.Data[1] & 0x03) != 0x00 ||
					     (gstResponse[EcuIdx].PIDF501.Data[2] & 0x0F) != 0x00 ||
					     (gstResponse[EcuIdx].PIDF501.Data[3] & 0x0F) != 0x00 ||
					     (gstResponse[EcuIdx].PIDF501.Data[4] & 0x0F) != 0x00 ||
					     (gstResponse[EcuIdx].PIDF501.Data[5] & 0x0F) != 0x00 )
					{
//						// Test PID $F401 Data B bit 3 for each ECU
//						if ( gstUserInput.eFuelType == DIESEL &&
//						     fGasolineMonSup == TRUE )
//						{
//							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//							      "ECU %X  PID $F401  Data B bit 3 must = 1 for Diesel Vehicles\n",
//							      GetEcuId ( EcuIdx ) );
//							fError = TRUE;
//						}
//						else if ( gstUserInput.eFuelType == GASOLINE &&
//						          fGasolineMonSup == FALSE )
//						{
//							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//							      "ECU %X  PID $F401  Data B bit 3 must = 0 for Gasoline Vehicles\n",
//							      GetEcuId ( EcuIdx ) );
//							fError = TRUE;
//						}
					}


//					if ( (gstResponse[EcuIdx].PIDF501.Data[2] & 0x10) != 0 )
//					{
//						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//						      "ECU %X  PID $F401  Data C bit 4 is set (Must be 0 for All Vehicles)\n",
//						      GetEcuId ( EcuIdx ) );
//						fError = TRUE;
//					}

//					if ( fGasolineMonSup == FALSE &&
//					     (gstResponse[EcuIdx].PIDF501.Data[2] & 0x04) != 0 )
//					{
//						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//						      "ECU %X  PID $F401  Data C bit 2 is set (Must be 0 for Diesel Vehicles)\n",
//						      GetEcuId ( EcuIdx ) );
//						fError = TRUE;
//					}

//					// Test SID1 Data B bit 1 for the vehicle
//					if ( gstResponse[EcuIdx].PIDF501.Data[1] & 0x01 )
//					{
//						fDataBBit0Supported = TRUE;
//					}

//					// Test SID1 Data C bit 0 for the vehicle
//					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x01 )
					// Test $F501 CAT/HCCAT for this ECU
					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x01 )
					{
						bCATSupported = TRUE;
					}
					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x02 )
					{
						bHCCATSupported = TRUE;
					}

//					// Test SID1 Data C bit 1 for the vehicle
//					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x02 )
					// Test $F501 HCAT/SCR for this ECU
					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x04 )
					{
						bHCATSupported = TRUE;
					}
					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x08 )
					{
						bSCRSupported = TRUE;
					}

//					// Test SID1 Data C bit 2 for the vehicle
//					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x04 )
					// Test $F501 EVAP for this ECU
					if ( gstResponse[EcuIdx].PIDF501.Data[3] & 0x01 )
					{
						bEVAPSupported = TRUE;
					}

//					// Test SID1 Data C bit 3 for the vehicle
//					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x08 )
					// Test $F501 AIR/BP for this ECU
					if ( gstResponse[EcuIdx].PIDF501.Data[3] & 0x02 )
					{
						bAIRSupported = TRUE;
					}
					if ( gstResponse[EcuIdx].PIDF501.Data[3] & 0x04 )
					{
						bBPSupported = TRUE;
					}

//					// Test SID1 Data C bit 5 for the vehicle
//					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x20 )
					// Test $F501 EGS for this ECU
					if ( gstResponse[EcuIdx].PIDF501.Data[4] & 0x01 )
					{
						bEGSSupported = TRUE;
					}

//					// Test SID1 Data C bit 6 for the vehicle
//					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x40 )
					// Test $F501 PM for this ECU
					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x40 )
					{
						bPMSupported = TRUE;
					}

//					// Test SID1 Data C bit 7 for the vehicle
//					if ( gstResponse[EcuIdx].PIDF501.Data[2] & 0x80 )
					// Test $F501 EGR for this ECU
					if ( gstResponse[EcuIdx].PIDF501.Data[4] & 0x04 )
					{
						bEGRSupported = TRUE;
					}

				} // end Test5.14.3


				if ( IsIDSupported ( EcuIdx, MIDREQUEST, IdIdx ) == TRUE )
				{
					if ( gstResponse[EcuIdx].MIDSize == 0 )
					{
						Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
						      "ECU %X  No MID $%04X 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 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].MIDLSB <= 0x10 && pMid[MidIdx].SDTID <= 4) &&
							     !(geTestPhase == eTestNoDTC && gTestSubsection == 14 &&
							       ((pMid[MidIdx].MIDLSB >= 0xA1 && pMid[MidIdx].MIDLSB <= 0xB1) ||
							        (pMid[MidIdx].MIDLSB >= 0x81 && pMid[MidIdx].MIDLSB <= 0x84))) )
							{
								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  MID $%02X%02X test value/limits not reset\n",
									      GetEcuId ( EcuIdx ),
									      pMid[MidIdx].MIDMSB,
									      pMid[MidIdx].MIDLSB );
								}
							}


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

								// Check MID ranges common to Gasoline and Diesel vehicles
								else if ( pMid[MidIdx].MIDLSB <= 0x10 )
								{
									bMid01_10Supported = TRUE;

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

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

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

								// Check MID ranges for Gasoline Vehicles
								else if ( bGasolineMonSup == TRUE )
								{
									if ( pMid[MidIdx].MIDLSB >= 0x21 && pMid[MidIdx].MIDLSB <= 0x24 )
									{
										bMid21_24Supported = TRUE;

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

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

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

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

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

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

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

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

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

							}  // end Test 5.13

						}  // 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].MIDLSB >= 0xA1 && pMid[MidIdx].MIDLSB <= 0xB1 )
						{
							bMidA1_B1Supported = TRUE;

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

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

						// IF in drive cycle (Test 11.4)
						if ( 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  MID $%02X%02X test value exceeded min\n",
								      GetEcuId ( EcuIdx ),
								      pMid[MidIdx].MIDMSB,
								      pMid[MidIdx].MIDLSB );
								bError = TRUE;
							}

							if ( TestVal > TestLimMax )
							{
								Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
								      "ECU %X  MID $%02X%02X test value exceeded max\n",
								      GetEcuId ( EcuIdx ),
								      pMid[MidIdx].MIDMSB,
								      pMid[MidIdx].MIDLSB );
								bError = TRUE;
							}
						} // end if ( geTestPhase == eTestPerformanceCounters )

					} // end for (MidIdx . . .

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

			} // end for (EcuIdx . . .

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

	} // end for (IdIdx . . .

	// Check for vehicle required MIDs
	// 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 $22 MID $F6A2 SDTID $0B or $0C not supported (Required for All Vehicles with PID $F401 Data B bit 0 set)\n" );
//			bError = TRUE;
//		}
//
//		if ( bDataCBit5Supported == TRUE && bMid01Supported == FALSE )
//		{
//			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//			      "SID $22 MID $F601 not supported (Required for All Vehicles with PID $F501 EGS support set)\n" );
//			bError = TRUE;
//		}
//
//		if ( bDataCBit7Supported == TRUE && bMid31_38Supported == FALSE )
//		{
//			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//			      "SID $22 MID $F631-$F638 not supported (At least one required for All Vehicles with PID $F501 EGR support set)\n" );
//			bError = TRUE;
//		}

		if ( gstUserInput.eFuelType == GASOLINE )
		{
//			if ( bDataCBit0Supported == TRUE && bMid21Supported == FALSE )
//			{
//				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//				      "SID $22 MID $F621 not supported (Required for Gasoline Vehicles with PID $F501 CAT support set)\n" );
//				bError = TRUE;
//			}

//			if ( bDataCBit1Supported == TRUE && bMid61_64Supported == FALSE )
//			{
//				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//				      "SID $22 MID $F661-$F664 not supported (At least one required for Gasoline Vehicles with PID $F501 HCAT support set)\n" );
//				bError = TRUE;
//			}

//			if ( bDataCBit2Supported == TRUE && bMid39_3DSupported == FALSE )
//			{
//				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//				      "SID $22 MID $F639-$F63D not supported (At least one required for Gasoline Vehicles with PID $F501 EVAP support set)\n" );
//				bError = TRUE;
//			}

//			if ( bDataCBit3Supported == TRUE && bMid71_74Supported == FALSE )
//			{
//				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//				      "SID $22 MID $F671-$F674 not supported (At least one required for Gasoline Vehicles with PID $F501 AIR support set)\n" );
//				bError = TRUE;
//			}
		}
		// ELSE a Diesel vehicle
		else if ( gstUserInput.eFuelType == DIESEL )
		{
//			if ( bDataCBit6Supported == TRUE && bMidB2Supported == FALSE )
//			{
//				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//				      "SID $22 MID $F6B2 not supported (Required for Diesel Vehicles with PID $F501 PM support set)\n" );
//				bError = TRUE;
//			}

//			if ( bDataCBit1Supported == TRUE && bMid90919899Supported == FALSE )
//			{
//				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//				      "SID $22 MID $F690, $F691, $F698, $F699 not supported (At least one required for Diesel Vehicles with PID $F501 SCR support set)\n" );
//				bError = TRUE;
//			}

//			if ( bDataCBit3Supported == TRUE && bMid85_86Supported == FALSE )
//			{
//				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
//				      "SID $22 MID $F685-$F686 not supported (At least one required for Diesel Vehicles with PID $F501 BP support 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 $22 MID $F6A2 SDTID $0B or $0C not supported by the vehicle\n" );
		bError = TRUE;
	}

	// Make sure the required MIDLSB/SDTID values are supported and try group support
	if ( geTestPhase != eTestPerformanceCounters )
	{
		// Link Active test after completion of group request
//		if ( VerifyGroupMonitorTestSupport ( ) == FAIL )
		if ( RequestGroupPIDSupportData ( 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;
	}

}


/*******************************************************************************
**
**   Function:  VerifyMIDSupportData
**
**   Purpose:   Verify each controller supports at a minimum one PID.
**              Any ECU that responds that does not support at least
**              one PID is flagged as an error.
**
*******************************************************************************/
int VerifyMIDSupportData ( void )
{
	int           bReturn = PASS;
	int           bEcuResult;
	unsigned int  EcuIdx;
	unsigned int  Index;

	// For each ECU
	for ( EcuIdx = 0;
	      EcuIdx < gNumOfECUs;
	      EcuIdx++ )
	{
		bEcuResult = FAIL;
		for ( Index = 0;
		      Index < gstResponse[EcuIdx].MIDSupportSize;
		      Index++ )
		{
			// If MID is supported, keep looking
			if ( gstResponse[EcuIdx].MIDSupport[Index].SupBits[0] ||
			     gstResponse[EcuIdx].MIDSupport[Index].SupBits[1] ||
			     gstResponse[EcuIdx].MIDSupport[Index].SupBits[2] ||
			     ((gstResponse[EcuIdx].MIDSupport[Index].SupBits[3]) & 0xFE) != 0x00 )
			{
				bEcuResult = PASS;
				break;
			}
		}

		if ( bEcuResult == FAIL && gstResponse[EcuIdx].MIDSupportSize > 0 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  MID-Supported MIDs indicate no MIDs supported\n",
			      GetEcuId ( EcuIdx ) );
			bReturn = FAIL;
		}
	}

	return bReturn;
}
