/*******************************************************************************
********************************************************************************
**
**  Copyright(c) 2022, Alliance for Automotive Innovation
**  Used only under license from the Alliance for Automotive Innovation. All Rights Reserved.
**
**  Project:  J1699-3
**  FileName: SidResetResponseData.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:  ResetSidResponseData
**
**  Purpose:   Reset SID response data
**
*******************************************************************************/
STATUS ResetSidResponseData ( PASSTHRU_MSG *pTxMsg )
{
	BYTE HeaderSize;
	BYTE Data0Offset;
	BYTE EcuIdx;


	// Set the response header size based on the protocol
	HeaderSize = gstProtocolList[gProtocolIdx].HeaderSize;
	Data0Offset = HeaderSize + 1;

	// Reset SID response data for all ECUs
	for ( EcuIdx = 0;
	      EcuIdx < gNumOfECUsForAlloc;
	      EcuIdx++ )
	{
		gstResponse[EcuIdx].bResponseReceived = FALSE; // reset response received flag

		// Save the data in the appropriate SID/PID/MID/TID/INF
		switch ( pTxMsg->Data[HeaderSize] )
		{
			// OBD Services
			// SID 1 (Mode 1)
			case 0x01:
			{
				switch ( pTxMsg->Data[Data0Offset] )
				{
					case 0x00:  // ID-Support IDs 01-20
					{
						// IF called from VerifyECUCommunication or DetermineOBDProtocol,
						if ( gbVerifyLink == TRUE ||
						     gbDetermineProtocol == TRUE )
						{
							gstResponse[EcuIdx].bLinkActive = FALSE;
						}
						else if ( gReverseOrderStateArray[EcuIdx] == NOT_REVERSE_ORDER )
						{
							// Clear out the support data when PID 0x00 is requested
							gstResponse[EcuIdx].PidSupportSize = 0;

							memset ( gstResponse[EcuIdx].PidSupport,
							         0,
							         sizeof ( gstResponse[EcuIdx].PidSupport ) );
						}
					}
					// 0x00 falls through

					case 0x20:  // ID-Support IDs 0x21-0x40
					case 0x40:  // ID-Support IDs 0x41-0x60
					case 0x60:  // ID-Support IDs 0x61-0x80
					case 0x80:  // ID-Support IDs 0x81-0xA0
					case 0xA0:  // ID-Support IDs 0xA1-0xC0
					case 0xC0:  // ID-Support IDs 0xC1-0xE0
					case 0xE0:  // ID-Support IDs 0xE1-0xFF
					{
						if ( gReverseOrderStateArray[EcuIdx] == REVERSE_ORDER_REQUESTED )
						{
							// indicate first reverse order response received and SupportSize cleared
							gReverseOrderStateArray[EcuIdx] = REVERSE_ORDER_RESPONSE;

							// Clear out the support data when PID 0x00 is requested
							gstResponse[EcuIdx].PidSupportSize = 0;

							memset ( gstResponse[EcuIdx].PidSupport,
							         0,
							         sizeof ( gstResponse[EcuIdx].PidSupport ) );
						}
					}
					// 0x00-0xE0 falls through

					default:
					{
						// All other requests reset the PID data
						gstResponse[EcuIdx].PidSize = 0;

						memset ( gstResponse[EcuIdx].Pid,
						         0,
						         sizeof ( gstResponse[EcuIdx].Pid ) );
					}
					break;
				}
			}
			break;

			// SID 2 (Mode 2)
			case 0x02:
			{
				switch ( pTxMsg->Data[Data0Offset] )
				{
					case 0x00:  // ID-Support IDs 01-20
					{
						// Clear out the support data when PID 0x00 is requested
						gstResponse[EcuIdx].FFSupportSize = 0;
						memset ( gstResponse[EcuIdx].FFSupport,
						         0,
						         sizeof ( gstResponse[EcuIdx].FFSupport ) );
					}
					// 0x00 falls through

					case 0x20:  // ID-Support IDs 0x21-0x40
					case 0x40:  // ID-Support IDs 0x41-0x60
					case 0x60:  // ID-Support IDs 0x61-0x80
					case 0x80:  // ID-Support IDs 0x81-0xA0
					case 0xA0:  // ID-Support IDs 0xA1-0xC0
					case 0xC0:  // ID-Support IDs 0xC1-0xE0
					case 0xE0:  // ID-Support IDs 0xE1-0xFF
					{
						// Don't do anything with other PID support requests
					}
					// 0x00-0xE0 falls through

					default:
					{
						// All other requests reset the PID data
						gstResponse[EcuIdx].FFSize = 0;
						memset ( gstResponse[EcuIdx].FF,
						         0,
						         sizeof ( gstResponse[EcuIdx].FF ) );
					}
					break;
				}
			}
			break;

			// SID 3 (Mode 3)
			case 0x03:
			{
				gstResponse[EcuIdx].bConfDTCSupported = FALSE;
				gstResponse[EcuIdx].ConfDTCSize = 0;
				memset ( gstResponse[EcuIdx].ConfDTC,
				         0,
				         sizeof ( gstResponse[EcuIdx].ConfDTC ) );
			}
			break;

			// SID 4 (Mode 4)
			case 0x04:
			{
				gstResponse[EcuIdx].ClrDTCSize = 0;
			}
			break;

			// SID 5 (Mode 5)
			case 0x05:
			{
				switch ( pTxMsg->Data[Data0Offset] )
				{
					case 0x00:  // ID-Support IDs 01-20
					{
						// Clear out the support data when PID 0x00 is requested
						gstResponse[EcuIdx].O2TidSupportSize = 0;
						memset ( gstResponse[EcuIdx].O2TidSupport,
						         0,
						         sizeof ( gstResponse[EcuIdx].O2TidSupport ) );
					}
					break;

					case 0x20:  // ID-Support IDs 0x21-0x40
					case 0x40:  // ID-Support IDs 0x41-0x60
					case 0x60:  // ID-Support IDs 0x61-0x80
					case 0x80:  // ID-Support IDs 0x81-0xA0
					case 0xA0:  // ID-Support IDs 0xA1-0xC0
					case 0xC0:  // ID-Support IDs 0xC1-0xE0
					case 0xE0:  // ID-Support IDs 0xE1-0xFF
					{
						// Don't do anything with other PID support requests
					}
					break;

					default:
					{
						// All other requests reset the PID data
						gstResponse[EcuIdx].O2TidSize = 0;
						memset ( gstResponse[EcuIdx].O2Tid,
						         0,
						         sizeof ( gstResponse[EcuIdx].O2Tid ) );
					}
					break;
				}
			}
			break;

			// SID 6 (Mode 6)
			case 0x06:
			{
				switch ( pTxMsg->Data[Data0Offset] )
				{
					case 0x00:  // ID-Support IDs 01-20
					{
						// Clear out the support data when PID 0x00 is requested
						gstResponse[EcuIdx].MidSupportSize = 0;
						memset ( gstResponse[EcuIdx].MidSupport,
						         0,
						         sizeof ( gstResponse[EcuIdx].MidSupport ) );
					}
					// 0x00 falls through

					case 0x20:  // ID-Support IDs 0x21-0x40
					case 0x40:  // ID-Support IDs 0x41-0x60
					case 0x60:  // ID-Support IDs 0x61-0x80
					case 0x80:  // ID-Support IDs 0x81-0xA0
					case 0xA0:  // ID-Support IDs 0xA1-0xC0
					case 0xC0:  // ID-Support IDs 0xC1-0xE0
					case 0xE0:  // ID-Support IDs 0xE1-0xFF
					{
						// Don't do anything with other PID support requests
					}
					// 0x00-0xE0 falls through

					default:
					{
						// All other requests reset the PID data
						gstResponse[EcuIdx].MidSize = 0;
						memset ( gstResponse[EcuIdx].Mid,
						         0,
						         sizeof ( gstResponse[EcuIdx].Mid ) );
					}
					break;
				}
			}
			break;

			// SID 7 (Mode 7)
			case 0x07:
			{
				gstResponse[EcuIdx].bPendDTCSupported = FALSE;
				gstResponse[EcuIdx].PendDTCSize = 0;
				memset ( gstResponse[EcuIdx].PendDTC,
				         0,
				         sizeof ( gstResponse[EcuIdx].PendDTC ) );
			}
			break;

			// SID 8 (Mode 8)
			case 0x08:
			{
				switch ( pTxMsg->Data[Data0Offset] )
				{
					case 0x00:  // ID-Support IDs 01-20
					{
						// Clear out the support data when PID 0x00 is requested
						gstResponse[EcuIdx].TidSupportSize = 0;
						memset ( gstResponse[EcuIdx].TidSupport,
						         0,
						         sizeof ( gstResponse[EcuIdx].TidSupport ) );
					}
					// 0x00 falls through

					case 0x20:  // ID-Support IDs 0x21-0x40
					case 0x40:  // ID-Support IDs 0x41-0x60
					case 0x60:  // ID-Support IDs 0x61-0x80
					case 0x80:  // ID-Support IDs 0x81-0xA0
					case 0xA0:  // ID-Support IDs 0xA1-0xC0
					case 0xC0:  // ID-Support IDs 0xC1-0xE0
					case 0xE0:  // ID-Support IDs 0xE1-0xFF
					{
						// Don't do anything with other PID support requests
					}
					// 0x00-0xE0 falls through

					default:
					{
						// All other requests reset the PID data
						gstResponse[EcuIdx].TidSize = 0;
						memset ( gstResponse[EcuIdx].Tid,
						         0,
						         sizeof ( gstResponse[EcuIdx].Tid ) );
					}
					break;
				}
			}
			break;

			// SID 9 (Mode 9)
			case 0x09:
			{
				switch ( pTxMsg->Data[Data0Offset] )
				{
					case 0x00:  // ID-Support IDs 01-20
					{
						// Clear out the support data when PID 0x00 is requested
						gstResponse[EcuIdx].InfSupportSize = 0;
						memset ( gstResponse[EcuIdx].InfSupport,
						         0,
						         sizeof ( gstResponse[EcuIdx].InfSupport ) );
					}
					// 0x00 falls through

					case 0x20:  // ID-Support IDs 0x21-0x40
					case 0x40:  // ID-Support IDs 0x41-0x60
					case 0x60:  // ID-Support IDs 0x61-0x80
					case 0x80:  // ID-Support IDs 0x81-0xA0
					case 0xA0:  // ID-Support IDs 0xA1-0xC0
					case 0xC0:  // ID-Support IDs 0xC1-0xE0
					case 0xE0:  // ID-Support IDs 0xE1-0xFF
					{
						// Don't do anything with other PID support requests
					}
					// 0x00-0xE0 falls through

					default:
					{
						// All other requests reset the PID data
						gstResponse[EcuIdx].InfSize = 0;
						memset ( gstResponse[EcuIdx].Inf,
						         0,
						         sizeof ( gstResponse[EcuIdx].Inf ) );
					}
					break;
				}
			}
			break;

			// SID A (Mode A)
			case 0x0A:
			{
				// reset the PID data
				gstResponse[EcuIdx].bConfDTCSupported = FALSE;
				gstResponse[EcuIdx].PermDTCSize = 0;
				memset ( gstResponse[EcuIdx].PermDTC,
				         0,
				         sizeof ( gstResponse[EcuIdx].PermDTC ) );
			}
			break;

			// SID 00,0B-0F (Reserved Modes 00, 0B-0F)
			case 0x00:  // ID-Support IDs 01-20
			case 0x0B:
			case 0x0C:
			case 0x0D:
			case 0x0E:
			case 0x0F:
			{
			}
			break;


			default:
			{
				// Unexpected reset of SID data
				Log ( FAILURE, SCREENOUTPUTON, LOGOUTPUTON, NO_PROMPT,
				      "ECU %X  Unexpected reset of data for SID $%02X\n",
				      GetEcuId ( EcuIdx ),
				      pTxMsg->Data[HeaderSize] );
				return FAIL;

			}

		}  // end switch ( TxMsg->Data[HeaderSize] )

	}  // end for ( EcuIdx )

	return PASS;
}
