/*******************************************************************************
********************************************************************************
**
**  Copyright(c) 2022, Alliance for Automotive Innovation
**  Used only under license from the Alliance for Automotive Innovation. All Rights Reserved.
**
**  Project:  J1699-3
**  FileName: CheckIDSupport.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


// Functio Prototypes
void FormatTIDSupReq ( REQ_MSG *pReqMsg );

// ID type string length
#define MAX_TYPE_LENGTH  5

#define MAX_IDS 0xE0

// ID type number
unsigned int Sid[NUM_ID_SUP_TYPES] = { 0x01,   // Service 1 - PID
                                       0x02,   // Service 2 - FF
                                       0x06,   // Service 6 - MID
                                       0x08,   // Service 8 - TID
                                       0x09 }; // Service 9 - INF

// ID type strings
char IDTypeString[NUM_ID_SUP_TYPES][MAX_TYPE_LENGTH] =
{
	"PID",   // Service 1 - PID
	"FF",    // Service 2 - FF
	"MID",   // Service 6 - MID
	"TID",   // Service 8 - TID
	"INF"    // Service 9 - INF
};


/*******************************************************************************
**
**  Function:  VerifyIDSupportData
**
**  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.
**
*******************************************************************************/
STATUS VerifyIDSupportData ( IDTYPE IdType )
{
	ID_SUPPORT    *pSup;
	BYTE           SupSize;
	BYTE           EcuIdx;
	STATUS         eRetCode = PASS;

	BOOL           bIDSupport;
	unsigned long  Index;


	// For each ECU
	for ( EcuIdx = 0;
	      EcuIdx < gNumOfECUs;
	      EcuIdx++ )
	{
		if ( IdType == PIDREQUEST )
		{
			SupSize = gstResponse[EcuIdx].PidSupportSize;
			pSup = &gstResponse[EcuIdx].PidSupport[0];
		}
		else if ( IdType == MIDREQUEST )
		{
			SupSize = gstResponse[EcuIdx].MidSupportSize;
			pSup = &gstResponse[EcuIdx].MidSupport[0];
		}
		else if ( IdType == TIDREQUEST )
		{
			SupSize = gstResponse[EcuIdx].TidSupportSize;
			pSup = &gstResponse[EcuIdx].TidSupport[0];
		}
		else
		{
			SupSize = gstResponse[EcuIdx].InfSupportSize;
			pSup = &gstResponse[EcuIdx].InfSupport[0];
		}

		bIDSupport = FALSE;
		// PID $00 not required to indicate PIDs Supported
		for ( Index = 1;
		      Index < SupSize;
		      Index++ )
		{
			// If PID is supported, keep looking
			if ( pSup[Index].SupBits[0] ||
			     pSup[Index].SupBits[1] ||
			     pSup[Index].SupBits[2] ||
			     (pSup[Index].SupBits[3] & 0xFE) != 0x00 )
			{
				bIDSupport = TRUE;
				break;  // leave support ID for loop
			}
		}

		if ( bIDSupport == FALSE &&
		     SupSize > 1 )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  SID $02X  %s-Supported %ss indicate no %ss supported",
			      GetEcuId ( EcuIdx ),
			      Sid[IdType],
			      IDTypeString[IdType],
			      IDTypeString[IdType],
			      IDTypeString[IdType] );
			eRetCode = FAIL;
		}
	}

	return eRetCode;
}


/*******************************************************************************
**
**  Function:  RequestIDSupportData
**
**  Purpose:   Identify support for Service Support IDs
**
*******************************************************************************/
STATUS RequestIDSupportData ( IDTYPE  IdType,
                              BOOL    bVerifyECUCommunication )
{
	REQ_MSG       stReqMsg;
	ID_SUPPORT   *pSup;
	BYTE          EcuIdx = 0;

	unsigned int  IdIdx;
	BOOL          bIDSupport;           // Evaluate $E0 ID support indication.
	BOOL          bTestFailed = FALSE;


	// Request SID support data
	for ( IdIdx =  0x00;
	      IdIdx < MAX_IDS;
	      IdIdx += 0x20 )
	{
		stReqMsg.SID    = Sid[IdType];
		stReqMsg.NumIds = 1;
		stReqMsg.ID[0]  = IdIdx;
		if ( stReqMsg.SID == 0x08 )
		{
			FormatTIDSupReq ( &stReqMsg );
		}
		if ( (stReqMsg.SID == 0x08 && RequestSid ( &stReqMsg, REQ_MSG_NORMAL|REQ_MSG_ALLOW_NO_RESPONSE ) == FAIL) ||
		     (stReqMsg.SID != 0x08 && RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL) )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "Error in response to SID $%02X %s-Supported %s $%02X request\n",
			      Sid[IdType],
			      IDTypeString[IdType],
			      IDTypeString[IdType],
			      IdIdx );
			bTestFailed = TRUE;
		}

		// Check if we need to request the next group
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( (IdType == PIDREQUEST && (gstResponse[EcuIdx].PidSupport[(IdIdx >> 5)].SupBits[3] & 0x01)) ||
			     (IdType == MIDREQUEST && (gstResponse[EcuIdx].MidSupport[(IdIdx >> 5)].SupBits[3] & 0x01)) ||
			     (IdType == TIDREQUEST && (gstResponse[EcuIdx].TidSupport[(IdIdx >> 5)].SupBits[3] & 0x01)) ||
			     (IdType == INFREQUEST && (gstResponse[EcuIdx].InfSupport[(IdIdx >> 5)].SupBits[3] & 0x01)) )
			{
				break;  // leave ECU for loop
			}
		}
		// If no ECU supports the next ID support ID, end requests
		if ( EcuIdx >= gNumOfECUs )
		{
			break;  // leave support ID for loop
		}
	}


	// Verify support information
	if ( EcuIdx != 0 &&
	     VerifyIDSupportData ( IdType ) == FAIL )
	{
		bTestFailed = TRUE;
	}


	// Verify support information if request is at upper limit of $E0
	if ( IdIdx == 0xE0 )
	{
		// Init variable to no-support
		bIDSupport = FALSE;

		// For each ECU
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( IdType == PIDREQUEST )
			{
				pSup = &gstResponse[EcuIdx].PidSupport[0];
			}
			else if ( IdType == MIDREQUEST )
			{
				pSup = &gstResponse[EcuIdx].MidSupport[0];
			}
			else if ( IdType == TIDREQUEST )
			{
				pSup = &gstResponse[EcuIdx].TidSupport[0];
			}
			else
			{
				pSup = &gstResponse[EcuIdx].InfSupport[0];
			}

			// If DID is supported, keep looking
			if ( pSup[IdIdx >> 5].SupBits[0] ||
			     pSup[IdIdx >> 5].SupBits[1] ||
			     pSup[IdIdx >> 5].SupBits[2] ||
			     (pSup[IdIdx >> 5].SupBits[3] & 0xFE) != 0x00  )
			{
				// Flag as support indicated!
				bIDSupport = TRUE;
			}
		}

		// Flag as error if no support indicated in $E0
		if ( bIDSupport == FALSE )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "SID %02X %s $%04X support failure.  No ID support indicated!\n",
			      Sid,
			      IDTypeString[IdType],
			      IdIdx );
			bTestFailed = TRUE;
		}
	}
	// Request next unsupported DID-Supported DID
	else if ( IdType != INFREQUEST ||
	          geTestPhase != eTestNoDTC || gTestSubsection != 17 )  // IF not Test 5.17
	{
		IdIdx += 0x20;

		stReqMsg.SID    = Sid[IdType];
		stReqMsg.NumIds = 1;
		stReqMsg.ID[0]  = IdIdx;
		if ( stReqMsg.SID == 0x08 )
		{
			FormatTIDSupReq ( &stReqMsg );
		}
		if ( RequestSid ( &stReqMsg, REQ_MSG_NORMAL|REQ_MSG_IGNORE_NO_RESPONSE ) != FAIL  )
		{
			for ( EcuIdx = 0;
			      EcuIdx < gNumOfECUs;
			      EcuIdx++ )
			{
				if ( (IdType == PIDREQUEST && gstResponse[EcuIdx].PidSize != 0) ||
				     (IdType == MIDREQUEST && gstResponse[EcuIdx].MidSize != 0) ||
				     (IdType == TIDREQUEST && gstResponse[EcuIdx].TidSize != 0) ||
				     (IdType == INFREQUEST && gstResponse[EcuIdx].InfSize != 0) )
				{
					Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
					      "ECU %X  Unexpected response to unsupported SID $%02X %s $%02X!\n",
					      GetEcuId ( EcuIdx ),
					      Sid[IdType],
					      IDTypeString[IdType],
					      IdIdx );
				}
			}
			bTestFailed = TRUE;
		}
	}

	// Verify ECU did not drop out
	if ( bVerifyECUCommunication &&
	     VerifyECUCommunication ( ) != PASS )
	{
		bTestFailed = TRUE;
	}

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

	return PASS;
}


/*******************************************************************************
**
**  Function:  RequestGroupIDSupportData
**
**  Purpose:   Verify ID group support
**
*******************************************************************************/
STATUS RequestGroupIDSupportData ( IDTYPE IdType )
{
	REQ_MSG       stReqMsg;
	ID_SUPPORT   *pSup;
	BYTE          SupSize;
	ID_SUPPORT   *pCompSup;
	BYTE          CompSupSize;
	BYTE          EcuIdx;

	unsigned int  NumIds;
	unsigned int  IdIdx;
	unsigned int  NextSupportOffset = 5;
	BOOL          bReqNextGroup;        // Binary logic for request for next group!
	BOOL          bTestFailed = FALSE;


	// Save the original response data for comparison
	memcpy ( &gstCompareResponse[0],
	         &gstResponse[0],
	         sizeof ( OBD_DATA ) * gNumOfECUsForAlloc );

	// Set starting ID Support ID
	IdIdx = 0x00;

	do
	{
		bReqNextGroup = FALSE;

		// first support request's group is $00 $20 $40 $60 $80 $A0
		// the second support request's group is $C0 $E0
		if ( IdIdx < 0xC0 )
		{
			NumIds = 6;
		}
		else
		{
			NumIds = 2;
		}

		// Request DID support data as a group
		stReqMsg.SID    = Sid[IdType];
		stReqMsg.NumIds = NumIds;
		stReqMsg.ID[0]  = IdIdx;
		stReqMsg.ID[1]  = IdIdx + 0x20;
		if ( NumIds != 2 )
		{
			stReqMsg.ID[2] = IdIdx + 0x40;
			stReqMsg.ID[3] = IdIdx + 0x60;
			stReqMsg.ID[4] = IdIdx + 0x80;
			stReqMsg.ID[5] = IdIdx + 0xA0;
		}
		if ( (stReqMsg.SID == 0x08 && RequestSid ( &stReqMsg, REQ_MSG_NORMAL|REQ_MSG_ALLOW_NO_RESPONSE ) == FAIL ) ||
		     (stReqMsg.SID != 0x08 && RequestSid ( &stReqMsg, REQ_MSG_NORMAL ) == FAIL) )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "SID $%02X %s group $%02X-$%02X support request failed\n",
			      Sid[IdType],
			      IDTypeString[IdType],
			      IdIdx,
			      IdIdx + (0x20 * (NumIds-1)) );
			bTestFailed = TRUE;
		}
		else
		{
			// Set next group select to false
			bReqNextGroup = FALSE;

			// Determine if next group support request is required
			for ( EcuIdx = 0;
			      EcuIdx < gNumOfECUs;
			      EcuIdx++ )
			{
				if ( ( IdType == PIDREQUEST && (gstResponse[EcuIdx].PidSupport[NextSupportOffset].SupBits[3] & 0x01) ) ||
				     ( IdType == MIDREQUEST && (gstResponse[EcuIdx].MidSupport[NextSupportOffset].SupBits[3] & 0x01) ) ||
				     ( IdType == TIDREQUEST && (gstResponse[EcuIdx].TidSupport[NextSupportOffset].SupBits[3] & 0x01) ) ||
				     ( IdType == INFREQUEST && (gstResponse[EcuIdx].InfSupport[NextSupportOffset].SupBits[3] & 0x01) ) )
				{
					bReqNextGroup = TRUE;
					IdIdx += 0xC0;
					NextSupportOffset += 2;
					break;  // leave ECU for loop
				}
			}
		}
	}
	while ( bReqNextGroup == TRUE );

	// Verify that all INF group/individual support data compares
	for ( EcuIdx = 0;
	      EcuIdx < gNumOfECUs;
	      EcuIdx++ )
	{
		if ( IdType == PIDREQUEST )
		{
			SupSize = gstResponse[EcuIdx].PidSupportSize;
			pSup = &gstResponse[EcuIdx].PidSupport[0];

			CompSupSize = gstCompareResponse[EcuIdx].PidSupportSize;
			pCompSup = &gstCompareResponse[EcuIdx].PidSupport[0];
		}
		else if ( IdType == MIDREQUEST )
		{
			SupSize = gstResponse[EcuIdx].MidSupportSize;
			pSup = &gstResponse[EcuIdx].MidSupport[0];

			CompSupSize = gstCompareResponse[EcuIdx].MidSupportSize;
			pCompSup = &gstCompareResponse[EcuIdx].MidSupport[0];
		}
		else if ( IdType == TIDREQUEST )
		{
			SupSize = gstResponse[EcuIdx].TidSupportSize;
			pSup = &gstResponse[EcuIdx].TidSupport[0];

			CompSupSize = gstCompareResponse[EcuIdx].TidSupportSize;
			pCompSup = &gstCompareResponse[EcuIdx].TidSupport[0];
		}
		else
		{
			SupSize = gstResponse[EcuIdx].InfSupportSize;
			pSup = &gstResponse[EcuIdx].InfSupport[0];

			CompSupSize = gstCompareResponse[EcuIdx].InfSupportSize;
			pCompSup = &gstCompareResponse[EcuIdx].InfSupport[0];
		}

		if ( CompareIDSupport ( EcuIdx,
		                        IdType,
		                        SupSize,
		                        CompSupSize,
		                        pSup,
		                        pCompSup,
		                        TRUE ) == FAIL )
		{
			bTestFailed = TRUE;
		}
	}

	if ( bTestFailed == TRUE )
	{
		// Something was wrong, restore the original response data
		memcpy ( &gstResponse[0],
		         &gstCompareResponse[0],
		         sizeof ( OBD_DATA ) * gNumOfECUsForAlloc );
		return FAIL;
	}

	return PASS;
}


/*******************************************************************************
**
**  Function:  CompareIDSupport
**
**  Purpose:   Compare normal/single and reverse/group
**             PID Support responses for SID $01, $6, $8, $9
**
*******************************************************************************/
STATUS CompareIDSupport ( BYTE       EcuIdx,         // The index of the current ECU
                          IDTYPE     IdType,         // Type of DID support array
                          BYTE       ResponseSize,   // Size of group/reverse DID Support response
                          BYTE       CompareSize,    // Size of single/normal DID Support response
                          ID_SUPPORT ResponseData[], // Data of group/reverse DID Support response
                          ID_SUPPORT CompareData[],  // Data of single/normal DID Support response
                          BOOL       bGroup )        // Flag indicating if this is a group DID Support response
{
	unsigned int   IdIdx;
	unsigned int   IdBitIndex;
	unsigned int   BitIndex;
	BYTE           BitMask;
	BOOL           bTestFailed = FALSE;


	if ( ResponseSize != CompareSize )
	{
		Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
		      "ECU %X  SID $%02X %s Supported %s %s size mismatch\n"
		      "                          %s response size = %d\n"
		      "                          %s response size = %d\n",
		      GetEcuId ( EcuIdx ),
		      Sid[IdType],
		      IDTypeString[IdType],
		      IDTypeString[IdType],
		      bGroup ? "group/single" : "reverse/normal",
		      bGroup ? "Group " : "Reverse",
		      ResponseSize,
		      bGroup ? "Single" : "Normal ",
		      CompareSize );
		bTestFailed = TRUE;
	}

	// Verify that all SID X PID support data compares
	for ( IdIdx = 0;
	      IdIdx < 8;
	      IdIdx++ )
	{
		if ( CompareData[IdIdx].ID != ResponseData[IdIdx].ID )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  SID $%02X %s $%02X %s support response Support ID mismatch ($%02X)\n",
			      GetEcuId ( EcuIdx ),
			      Sid[IdType],
			      IDTypeString[IdType],
			      IdIdx * 0x20,
			      bGroup ? "group/single" : "reverse/normal",
			      CompareData[IdIdx].ID );
			bTestFailed = TRUE;

			if ( CompareData[IdIdx].ID != IdIdx * 0x20 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  SID $%02X %s $%02X invalid %s support response Support ID ($%02X)\n",
				      GetEcuId ( EcuIdx ),
				      Sid[IdType],
				      IDTypeString[IdType],
				      IdIdx * 0x20,
				      bGroup ? "single" : "normal",
				      CompareData[IdIdx].ID );
			}

			if ( ResponseData[IdIdx].ID != IdIdx * 0x20 )
			{
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  SID $%02X %s $%02X invalid %s support response Support ID ($%02X)\n",
				      GetEcuId ( EcuIdx ),
				      Sid[IdType],
				      IDTypeString[IdType],
				      IdIdx * 0x20,
				      bGroup ? "group" : "reverse",
				      ResponseData[IdIdx].ID );
			}
		}

		if ( ResponseData[IdIdx].SupBits[0] != CompareData[IdIdx].SupBits[0] ||
		     ResponseData[IdIdx].SupBits[1] != CompareData[IdIdx].SupBits[1] ||
		     ResponseData[IdIdx].SupBits[2] != CompareData[IdIdx].SupBits[2] ||
		     ResponseData[IdIdx].SupBits[3] != CompareData[IdIdx].SupBits[3] )
		{
			Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
			      "ECU %X  SID $%02X %s $%02X %s support response data mismatch\n"
			      "                         %7s response = %02X  %02X  %02X  %02X\n"
			      "                         %7s response = %02X  %02X  %02X  %02X\n",
			      GetEcuId ( EcuIdx ),
			      Sid[IdType],
			      IDTypeString[IdType],
			      IdIdx * 0x20,
			      bGroup ? "group/single" : "reverse/normal",
			      bGroup ? "Group " : "Reverse",
			      ResponseData[IdIdx].SupBits[0],
			      ResponseData[IdIdx].SupBits[1],
			      ResponseData[IdIdx].SupBits[2],
			      ResponseData[IdIdx].SupBits[3],
			      bGroup ? "Single" : "Normal ",
			      CompareData[IdIdx].SupBits[0],
			      CompareData[IdIdx].SupBits[1],
			      CompareData[IdIdx].SupBits[2],
			      CompareData[IdIdx].SupBits[3] );
			bTestFailed = TRUE;

			for ( IdBitIndex = 0;
			      IdBitIndex < 4;
			      IdBitIndex++ )
			{
				if ( (BitMask = (ResponseData[IdIdx].SupBits[IdBitIndex] ^ CompareData[IdIdx].SupBits[IdBitIndex])) != 0 )
				{
					for ( BitIndex = 8;
					      BitIndex != 0;
					      BitIndex--)
					{
						if ( (BitMask & 0x80) != 0 )
						{
							Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
							      "ECU %X  SID $%02X %s $%02X Byte %d:  %s $%02X support response mismatch\n",
							      GetEcuId ( EcuIdx ),
							      Sid[IdType],
							      IDTypeString[IdType],
							      IdIdx * 0x20,
							      IdBitIndex,
							      IDTypeString[IdType],
							      (IdIdx * 0x20) + (IdBitIndex * 8) + (8 - (BitIndex - 1)) );
						}
						BitMask <<= 1;
					}
				}
			}
		}
	}

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


/*******************************************************************************
**
**  Function:  IsIDSupported
**
**  Purpose:   Determine if SID $xx ID $xx is supported on specific ECU.
**             Need to have called RequestIDSupportData() previously.
**             If EcuIdx < 0 then check all ECUs.
**
*******************************************************************************/
BOOL IsIDSupported ( BYTE         EcuIdx,
                     IDTYPE       IdType,
                     unsigned int IdIdx )
{
	unsigned int index1;
	unsigned int index2;
	unsigned int mask;


	if ( IdIdx == 0 )
	{
		return TRUE;            // all modules must support PID/MID/INF $00
	}

	IdIdx--;
	index1 = IdIdx >> 5;
	index2 = (IdIdx >> 3) & 0x03;
	mask   = 0x80 >> (IdIdx & 0x07);

	if ( EcuIdx == ALLECUS )
	{
		for ( EcuIdx = 0;
		      EcuIdx < gNumOfECUs;
		      EcuIdx++ )
		{
			if ( (IdType == PIDREQUEST && (gstResponse[EcuIdx].PidSupport[index1].SupBits[index2] & mask)) ||
			     (IdType == MIDREQUEST && (gstResponse[EcuIdx].MidSupport[index1].SupBits[index2] & mask)) ||
			     (IdType == TIDREQUEST && (gstResponse[EcuIdx].TidSupport[index1].SupBits[index2] & mask)) ||
			     (IdType == INFREQUEST && (gstResponse[EcuIdx].InfSupport[index1].SupBits[index2] & mask)) ||
			     (IdType == FFREQUEST  && (gstResponse[EcuIdx].FFSupport[index1].SupBits[index2] & mask)) )
			{
				return TRUE;
			}
		}
	}
	else
	{
		if ( (IdType == PIDREQUEST && (gstResponse[EcuIdx].PidSupport[index1].SupBits[index2] & mask)) ||
		     (IdType == MIDREQUEST && (gstResponse[EcuIdx].MidSupport[index1].SupBits[index2] & mask)) ||
		     (IdType == TIDREQUEST && (gstResponse[EcuIdx].TidSupport[index1].SupBits[index2] & mask)) ||
		     (IdType == INFREQUEST && (gstResponse[EcuIdx].InfSupport[index1].SupBits[index2] & mask)) ||
		     (IdType == FFREQUEST  && (gstResponse[EcuIdx].FFSupport[index1].SupBits[index2] & mask)) )
		{
			return TRUE;
		}
	}

	return FALSE;
}


/*******************************************************************************
**
**  Function:  FormatTIDSupReq
**
**  Purpose:
**
*******************************************************************************/
void FormatTIDSupReq ( REQ_MSG *pstReqMsg )
{
	if ( gstProtocolList[gProtocolIdx].eProtocol != ISO15765 )
	{
		// For ISO 9141-2, ISO 14230-4, and SAE J1850
		// DATA_A - DATA_E should be set to $00 for a request and response message.
		pstReqMsg->NumIds = 6;

		pstReqMsg->ID[1]  = 0; // Data record of Test ID
		pstReqMsg->ID[2]  = 0;
		pstReqMsg->ID[3]  = 0;
		pstReqMsg->ID[4]  = 0;
		pstReqMsg->ID[5]  = 0;
	}
}
