/* BEGIN_FILE_HDR ******************************************************************************* * NOTICE * This software is the property of HiRain Technologies. Any information * contained in this doc should not be reproduced, or used, or disclosed * without the written authorization from HiRain Technologies. ******************************************************************************* * File Name : E2E_P01.c ******************************************************************************* * Project/Product : AUTOSAR R21-11 * Title : End-to-End protect module * Author : Hirain ******************************************************************************* * Description : The source file of the End-to-End module. * ******************************************************************************* * Limitations : None * ******************************************************************************* * ******************************************************************************* * Revision History: * * Version Date Initials CR# Descriptions * --------- ---------- ------------ ---------- --------------- * 04.00.00 01/08/2022 wenbo.cui N/A Original ******************************************************************************* * END_FILE_HDR*/ /****************************************************************************** * Includes ******************************************************************************/ #include "E2E_P01.h" /******************************************************************************* * General QAC Suppression *******************************************************************************/ /***************************************************************************** * E2E QAC Suppression *****************************************************************************/ /*PRQA S 3214,0862,3614 EOF*/ /* According to the requirements of AUTOSAR Specification,when locating address segments in the files of each module,#include "E2E_MemMap.h" is required.Defined XXX_START_SEC_ will undefine in E2E_MemMap.h */ /*PRQA S 4640,4641 EOF*/ /* Function, macrodefinition is named with a fixed requirement and does not make changes */ /*PRQA S 3429,3453 EOF*/ /* Allow the use of macrofunction access definitions, and the department is verified and there is no problem. */ /*PRQA S 3432 EOF*/ /* P2VAR and other macros in the Compiler conforms to AUTOSAR standard.There's no need to revise. */ /****************************************************************************** * Macro ******************************************************************************/ #define E2E_P01_MAX_DATA_LENGTH ((uint16)256)/*in bits*/ #define E2E_P01_MIN_DATA_LENGTH ((uint16)16)/*in bits*/ #define E2E_P01_LOW_NIBBLE_MSKE ((uint8)0x0F) #define E2E_P01_HIGH_NIBBLE_MSKE ((uint8)0xF0) #define E2E_P01_BYTE_MASK ((uint8)0xFF) #define E2E_P01_CRC_INIT_VALUE ((uint8)0x00) #define E2E_P01_CRC_XOR_VALUE ((uint8)0x00) #define E2E_P01_NIBBLE_BIT_LENGTH ((uint8)4) /*SWS_E2E_00218*/ #define E2E_P01_MAX_COUNTER_VALUE ((uint8)14) #define E2E_P01_DATA_UINT_BIT ((uint16)8) #define E2E_P01_CRC_UINT_BIT ((uint16)8) #define E2E_P01_COUNTER_UINT_BIT ((uint16)4) #define E2E_P01_IDNIBBLE_UINT_BIT ((uint16)4) #define E2E_P01_BYTE_ALIGNED_MASK ((uint16)0x0007) #define E2E_P01_NIBBLE_ALIGNED_MASK ((uint16)0x0003) #define E2E_P01_GET_DATA_LENGTH(bit) ((uint16)(bit) >> (uint16)3) #define E2E_P01_GET_BYTE_OFFSET(bitOffset) ((uint16)(bitOffset) >> (uint16)3) #define E2E_P01_IS_BYTE_ALIGNED(bit) ((uint16)((bit) & E2E_P01_BYTE_ALIGNED_MASK) == (uint16)0) #define E2E_P01_IS_NOT_BYTE_ALIGNED(bit) ((uint16)((bit) & E2E_P01_BYTE_ALIGNED_MASK) != (uint16)0) #define E2E_P01_IS_NOT_NIBBLE_ALIGNED(bit) ((uint16)((bit) & E2E_P01_NIBBLE_ALIGNED_MASK) != (uint16)0) #define E2E_P01_IS_EVEN_DATA(data) ((uint8)((data) & (uint8)1) == (uint8)0) #define E2E_START_SEC_CODE #include "E2E_MemMap.h" /****************************************************************************** * Private Functions Declare ******************************************************************************/ STATIC FUNC(void, E2E_CODE)E2E_P01CheckRecvCounter ( uint8 Counter, P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ); STATIC FUNC(void, E2E_CODE) E2E_P01InitDeltaAndLastValidCounter ( uint8 Counter, P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ); STATIC FUNC(void, E2E_CODE) E2E_P01CheckSyncCounter ( uint8 Counter, uint8 DeltaCounter, P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ); STATIC FUNC(uint8, E2E_CODE) E2E_P01GetDeltaCounter ( uint8 Counter, uint8 LastValidCounter ); STATIC FUNC(uint8, E2E_CODE)E2E_P01GetNibbleData ( uint16 bitOffset, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data ); STATIC FUNC(uint8, E2E_CODE)E2E_P01GetCrc ( uint8 Counter, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data, P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config ); /****************************************************************************** * Private Functions ******************************************************************************/ /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01CheckRecvCounter * * Description: Check the received counter. * * Inputs: Counter : Received counter.. * Config : Pointer to static configuration. * State : Pointer to port/data communication state. * * Outputs: None. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ STATIC FUNC(void, E2E_CODE)E2E_P01CheckRecvCounter ( uint8 Counter, P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ) { uint8 DeltaCounter; /*The data is not received for the first time*/ if (State->WaitForFirstData == FALSE) { /*get delta counter*/ DeltaCounter = E2E_P01GetDeltaCounter(Counter, State->LastValidCounter); if ((uint8)0 == DeltaCounter) { if (State->NoNewOrRepeatedDataCounter < E2E_P01_MAX_COUNTER_VALUE) { State->NoNewOrRepeatedDataCounter++; } /*SWS_E2E_00076*/ State->Status = E2E_P01STATUS_REPEATED; } else if ((uint8)1 == DeltaCounter) { /*SWS_E2E_00076*/ State->Status = E2E_P01STATUS_OK; E2E_P01CheckSyncCounter(Counter, DeltaCounter, Config, State); } else if (DeltaCounter <= State->MaxDeltaCounter) { /*SWS_E2E_00076*/ State->Status = E2E_P01STATUS_OKSOMELOST; E2E_P01CheckSyncCounter(Counter, DeltaCounter, Config, State); } /*DeltaCounter is greater than State->MaxDeltaCounter*/ else { State->NoNewOrRepeatedDataCounter = (uint8)0; State->SyncCounter = Config->SyncCounterInit; if (State->SyncCounter > (uint8)0) { E2E_P01InitDeltaAndLastValidCounter(Counter, Config, State); } /*SWS_E2E_00076*/ State->Status = E2E_P01STATUS_WRONGSEQUENCE; } } /*The data is received for the first time*/ else { State->WaitForFirstData = FALSE; E2E_P01InitDeltaAndLastValidCounter(Counter, Config, State); State->Status = E2E_P01STATUS_INITIAL; } } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01InitDeltaAndLastValidCounter * * Description: Initialize MaxDeltaCounter and LastValidCounter. * * Inputs: Counter : Received counter. * Config : Pointer to static configuration. * State : Pointer to port/data communication state. * * Outputs: None. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ STATIC FUNC(void, E2E_CODE) E2E_P01InitDeltaAndLastValidCounter ( uint8 Counter, P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ) { State->MaxDeltaCounter = Config->MaxDeltaCounterInit; State->LastValidCounter = Counter; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01CheckSyncCounter * * Description: Evaluate the credibility of the received counter. * * Inputs: Counter : Received counter. * DeltaCounter : Dalta counter. * Config : Pointer to static configuration. * State : Pointer to port/data communication state. * * Outputs: None. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ STATIC FUNC(void, E2E_CODE) E2E_P01CheckSyncCounter ( uint8 Counter, uint8 DeltaCounter, P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ) { E2E_P01InitDeltaAndLastValidCounter(Counter, Config, State); /*update the lost data counter.*/ State->LostData = DeltaCounter - (uint8)1; /*the NoNewOrRepeatedDataCounter is less than the configured value*/ if (State->NoNewOrRepeatedDataCounter <= Config->MaxNoNewOrRepeatedData) { if (State->SyncCounter > (uint8)0) { State->SyncCounter--; State->Status = E2E_P01STATUS_SYNC; } } else { State->SyncCounter = Config->SyncCounterInit; State->Status = E2E_P01STATUS_SYNC; } State->NoNewOrRepeatedDataCounter = (uint8)0; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01GetDeltaCounter * * Description: Calculate the delta counter. * * Inputs: Counter : Received counter.. * LastValidCounter : The last valid counter value. * * Outputs: The delta counter value. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ STATIC FUNC(uint8, E2E_CODE) E2E_P01GetDeltaCounter ( uint8 Counter, uint8 LastValidCounter ) { uint8 DeltaCounter; if(Counter >= LastValidCounter) { DeltaCounter = Counter - LastValidCounter; } else { DeltaCounter = ((uint8)(E2E_P01_MAX_COUNTER_VALUE - LastValidCounter) + (uint8)1) + Counter; } return DeltaCounter; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01GetNibbleData * * Description: Get nibble data based on bit offset. * * Inputs: uint16 : Bit offset of the data to get. * Data : Pointer to the data. * * Outputs: the nibble data. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ STATIC FUNC(uint8, E2E_CODE)E2E_P01GetNibbleData ( uint16 bitOffset, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data ) { uint8 byteOffset; uint8 readData; byteOffset = (uint8)E2E_P01_GET_BYTE_OFFSET(bitOffset); if(E2E_P01_IS_BYTE_ALIGNED(bitOffset)) { /*Read the data from low nibble of Data */ readData = Data[byteOffset] & E2E_P01_LOW_NIBBLE_MSKE; } else { /*Read the data from high nibble of Data */ readData = (uint8)(Data[byteOffset] >> E2E_P01_NIBBLE_BIT_LENGTH) & E2E_P01_LOW_NIBBLE_MSKE; } return readData; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01GetCrc * * Description: Calculate the crc value. * * Inputs: Counter : Counter to be used for selecting the DataID. * Data : Pointer to the data to be protected. * Config : Pointer to static configuration. * * Outputs: The crc value. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ STATIC FUNC(uint8, E2E_CODE)E2E_P01GetCrc ( uint8 Counter, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data, P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config ) { /*SWS_E2E_00070*//*SWS_E2E_00083*/ uint8 crc = E2E_P01_CRC_INIT_VALUE; uint8 dataIDLowByte; uint8 dataIDHighByte; uint16 firstDataLength; uint16 dataLength; uint16 CrcCopyLength; dataIDLowByte = ((uint8)Config->DataID) & E2E_P01_BYTE_MASK; dataIDHighByte = ((uint8)(Config->DataID >> E2E_P01_DATA_UINT_BIT)) & E2E_P01_BYTE_MASK; /*SWS_E2E_00082*/ switch(Config->DataIDMode) { /*SWS_E2E_00163*/ case E2E_P01_DATAID_BOTH: /*CRC over 2 bytes*//*SWS_E2E_00221*//*SWS_E2E_00218*//*SWS_E2E_00070*//*SWS_E2E_00083*/ /*SWS_E2E_190*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC8(&dataIDLowByte, (uint32)1, E2E_P01_CRC_INIT_VALUE, FALSE); crc = Crc_CalculateCRC8(&dataIDHighByte, (uint32)1, crc, FALSE); break; /*SWS_E2E_00163*/ case E2E_P01_DATAID_LOW: /*CRC over low byte only*//*SWS_E2E_00221*//*SWS_E2E_00218*//*SWS_E2E_00070*//*SWS_E2E_00083*/ /*SWS_E2E_190*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC8(&dataIDLowByte, (uint32)1, E2E_P01_CRC_INIT_VALUE, FALSE); break; /*SWS_E2E_00163*/ case E2E_P01_DATAID_ALT: /*counter is even*/ if(E2E_P01_IS_EVEN_DATA(Counter)) { /*SWS_E2E_00221*//*SWS_E2E_00218*//*SWS_E2E_00070*//*SWS_E2E_00083*//*SWS_E2E_190*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC8(&dataIDLowByte, (uint32)1, E2E_P01_CRC_INIT_VALUE, FALSE); } /*Counter is odd*/ else { /*SWS_E2E_00221*//*SWS_E2E_00218*//*SWS_E2E_00070*//*SWS_E2E_00083*//*SWS_E2E_190*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC8 (&dataIDHighByte, (uint32)1, E2E_P01_CRC_INIT_VALUE, FALSE); } break; /*SWS_E2E_00163*/ case E2E_P01_DATAID_NIBBLE: /*SWS_E2E_00221*//*SWS_E2E_00218*//*SWS_E2E_00070*//*SWS_E2E_00083*//*SWS_E2E_190*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC8(&dataIDLowByte, (uint32)1, E2E_P01_CRC_INIT_VALUE, FALSE); dataIDHighByte = (uint8)0; /*SWS_E2E_00221*//*SWS_E2E_00218*//*SWS_E2E_190*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC8(&dataIDHighByte, (uint32)1, crc, FALSE); break; default: /* Intentionally Empty */ break; } firstDataLength = E2E_P01_GET_DATA_LENGTH(Config->CRCOffset); dataLength = E2E_P01_GET_DATA_LENGTH(Config->DataLength); /*Compute CRC over the area before the CRC*/ if(firstDataLength >= (uint16)1) { /*SWS_E2E_00221*//*SWS_E2E_00218*//*SWS_E2E_190*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC8(Data, (uint32)firstDataLength, crc, FALSE); } /*Compute the area after CRC, if CRC is not the last byte.*/ if(firstDataLength < (dataLength - (uint16)1)) { /*SWS_E2E_00221*//*SWS_E2E_00218*//*SWS_E2E_190*//*SWS_E2E_00110*/ CrcCopyLength = (uint16)(dataLength - firstDataLength) - (uint16)1; crc = Crc_CalculateCRC8(&Data[firstDataLength + (uint16)1], (uint32)CrcCopyLength, crc, FALSE); } /*SWS_E2E_00070*//*SWS_E2E_00083*/ crc = crc ^ E2E_P01_CRC_XOR_VALUE; return crc; } /****************************************************************************** * Public Funtions ******************************************************************************/ /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01ProtectInit * * Description: Initializes the protection state. * * Inputs: StatePtr : Pointer to port/data communication state. * * Outputs: E2E_E_INPUTERR_NULL, * E2E_E_OK * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00385*/ FUNC(Std_ReturnType, E2E_CODE) E2E_P01ProtectInit ( P2VAR(E2E_P01ProtectStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr ) { Std_ReturnType ret; /*SWS_E2E_00386*//*SWS_E2E_00011*/ if(NULL_PTR == StatePtr) { ret = E2E_E_INPUTERR_NULL; } else { ret = E2E_E_OK; /*SWS_E2E_00075*/ StatePtr->Counter = (uint8)0; } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01Protect * * Description: Protects the array/buffer to be transmitted using the E2E profile 1. * This includes checksum calculation, handling of sequence counter * and Data ID. * * Inputs: ConfigPtr : Pointer to static configuration. * StatePtr : Pointer to port/data communication state. * DataPtr : Pointer to Data to be transmitted. * * Outputs: E2E_E_INPUTERR_NULL, * E2E_E_INPUTERR_WRONG, * E2E_E_INTERR, * E2E_E_OK * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00166,SWS_E2E_00195*/ FUNC(Std_ReturnType, E2E_CODE) E2E_P01Protect ( P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr, P2VAR(E2E_P01ProtectStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr, P2VAR(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr ) { Std_ReturnType ret = E2E_E_OK; uint8 counterOffset; uint8 idNibbleOffset; uint8 crcOffset; uint8 counter; uint8 idNibble; uint8 crc; /*SWS_E2E_00011*/ if((NULL_PTR == ConfigPtr) || (NULL_PTR == StatePtr) || (NULL_PTR == DataPtr)) { ret = E2E_E_INPUTERR_NULL; } else if ((E2E_P01_MAX_DATA_LENGTH < (ConfigPtr->DataLength)) || (E2E_P01_MIN_DATA_LENGTH > (ConfigPtr->DataLength)) || (E2E_P01_IS_NOT_BYTE_ALIGNED(ConfigPtr->DataLength))) { ret = E2E_E_INPUTERR_WRONG; } else if ((E2E_P01_IS_NOT_NIBBLE_ALIGNED(ConfigPtr->CounterOffset)) || (E2E_P01_IS_NOT_BYTE_ALIGNED(ConfigPtr->CRCOffset)) || (E2E_P01_IS_NOT_NIBBLE_ALIGNED(ConfigPtr->DataIDNibbleOffset))) { ret = E2E_E_INPUTERR_WRONG; } else if ((ConfigPtr->CounterOffset > (ConfigPtr->DataLength - E2E_P01_COUNTER_UINT_BIT)) || (ConfigPtr->CRCOffset > (ConfigPtr->DataLength - E2E_P01_CRC_UINT_BIT)) || (ConfigPtr->DataIDNibbleOffset > (ConfigPtr->DataLength - E2E_P01_IDNIBBLE_UINT_BIT))) { ret = E2E_E_INPUTERR_WRONG; } else { counterOffset = (uint8)E2E_P01_GET_BYTE_OFFSET(ConfigPtr->CounterOffset); if(E2E_P01_IS_BYTE_ALIGNED(ConfigPtr->CounterOffset)) { counter = (StatePtr->Counter) & E2E_P01_LOW_NIBBLE_MSKE; /*Write the counter in the low nibble of configured data byte*/ DataPtr[counterOffset] = (DataPtr[counterOffset] & E2E_P01_HIGH_NIBBLE_MSKE) | counter; } else { /*PRQA S 4571 ++*/ counter = (uint8)(StatePtr->Counter << E2E_P01_COUNTER_UINT_BIT) & E2E_P01_HIGH_NIBBLE_MSKE; /*Write the counter in the high nibble of configured data byte*/ DataPtr[counterOffset] = (DataPtr[counterOffset] & E2E_P01_LOW_NIBBLE_MSKE) | counter; /*PRQA S 4571 --*/ } if(E2E_P01_DATAID_NIBBLE == ConfigPtr->DataIDMode) { idNibbleOffset = (uint8)E2E_P01_GET_BYTE_OFFSET(ConfigPtr->DataIDNibbleOffset); /*DataIDNibbleOffset is byte aligned*/ if(E2E_P01_IS_BYTE_ALIGNED(ConfigPtr->DataIDNibbleOffset)) { idNibble = ((uint8)(ConfigPtr->DataID >> E2E_P01_DATA_UINT_BIT)) & E2E_P01_LOW_NIBBLE_MSKE; /*Write the low nibble of high byte of Data ID, in the low nibble of configured data byte*/ /*SWS_E2E_00163*/ DataPtr[idNibbleOffset] = (DataPtr[idNibbleOffset] & E2E_P01_HIGH_NIBBLE_MSKE) | idNibble; } else { idNibble = ((uint8)(ConfigPtr->DataID >> E2E_P01_IDNIBBLE_UINT_BIT)) & E2E_P01_HIGH_NIBBLE_MSKE; /*Write the low nibble of high byte of Data ID, in the high nibble of configured data byte*/ /*SWS_E2E_00163*/ DataPtr[idNibbleOffset] = (DataPtr[idNibbleOffset] & E2E_P01_LOW_NIBBLE_MSKE) | idNibble; } } /*Calculate CRC over Data*/ crc = E2E_P01GetCrc(StatePtr->Counter, DataPtr, ConfigPtr); crcOffset = (uint8)E2E_P01_GET_BYTE_OFFSET(ConfigPtr->CRCOffset); /*record the crc*/ DataPtr[crcOffset] = crc; /*increment the counter*//*SWS_E2E_00221*//*SWS_E2E_00218*//*SWS_E2E_00075*/ StatePtr->Counter = (StatePtr->Counter + (uint8)1) % (E2E_P01_MAX_COUNTER_VALUE + (uint8)1); } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01Check * * Description: Checks the Data received using the E2E profile 1. This includes * CRC calculation, handling of Counter and Data ID. * * Inputs: Config : Pointer to static configuration. * State : Pointer to port/data communication state. * Data : Pointer to received data. * * Outputs: E2E_E_INPUTERR_NULL, * E2E_E_INPUTERR_WRONG, * E2E_E_INTERR, * E2E_E_OK * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00158*//*SWS_E2E_00196*/ FUNC(Std_ReturnType, E2E_CODE)E2E_P01Check ( P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA) State, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data ) { uint8 recvCounter; uint8 calCrc; uint8 recvCrc; uint8 recvDataIDNibble = (uint8)0; Std_ReturnType ret = E2E_E_OK; /*SWS_E2E_00011*/ if((NULL_PTR == Config) || (NULL_PTR == State) || (NULL_PTR == Data)) { ret = E2E_E_INPUTERR_NULL; } else if ((E2E_P01_MAX_DATA_LENGTH < (Config->DataLength)) || (E2E_P01_MIN_DATA_LENGTH > (Config->DataLength)) || (E2E_P01_IS_NOT_BYTE_ALIGNED(Config->DataLength))) { ret = E2E_E_INPUTERR_WRONG; } else if ((E2E_P01_IS_NOT_NIBBLE_ALIGNED(Config->CounterOffset)) || (E2E_P01_IS_NOT_BYTE_ALIGNED(Config->CRCOffset)) || (E2E_P01_IS_NOT_NIBBLE_ALIGNED(Config->DataIDNibbleOffset))) { ret = E2E_E_INPUTERR_WRONG; } else if ((Config->CounterOffset > (Config->DataLength - E2E_P01_COUNTER_UINT_BIT)) || (Config->CRCOffset > (Config->DataLength - E2E_P01_CRC_UINT_BIT)) || (Config->DataIDNibbleOffset > (Config->DataLength - E2E_P01_IDNIBBLE_UINT_BIT))) { ret = E2E_E_INPUTERR_WRONG; } else { if(State->MaxDeltaCounter < E2E_P01_MAX_COUNTER_VALUE) { State->MaxDeltaCounter++; } if (State->NewDataAvailable == TRUE) { /*Read the Counter from Data, at the configured offset.*/ recvCounter = E2E_P01GetNibbleData(Config->CounterOffset, Data); if(recvCounter <= E2E_P01_MAX_COUNTER_VALUE) { /*Read CRC from Data*/ recvCrc = Data[E2E_P01_GET_BYTE_OFFSET(Config->CRCOffset)]; if(Config->DataIDMode == E2E_P01_DATAID_NIBBLE) { /*Read low nibble of high byte of Data ID from Data.*/ recvDataIDNibble = E2E_P01GetNibbleData(Config->DataIDNibbleOffset, Data); } /*Calculate CRC*/ calCrc = E2E_P01GetCrc(recvCounter, Data, Config); if(recvCrc == calCrc) { /*Check if received nibble is identical to the one in DataID.*/ if((Config->DataIDMode == E2E_P01_DATAID_NIBBLE) && (recvDataIDNibble != ((Config->DataID) >> E2E_P01_DATA_UINT_BIT))) { State->Status = E2E_P01STATUS_WRONGCRC; } else { E2E_P01CheckRecvCounter(recvCounter, Config, State); } } else { State->Status = E2E_P01STATUS_WRONGCRC; } } else { ret = E2E_E_INPUTERR_WRONG; } } else { if(State->NoNewOrRepeatedDataCounter < E2E_P01_MAX_COUNTER_VALUE) { State->NoNewOrRepeatedDataCounter++; } /*SWS_E2E_00076*/ State->Status = E2E_P01STATUS_NONEWDATA; } } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01CheckInit * * Description: Initializes the check state. * * Inputs: State : Pointer to port/data communication state. * * Outputs: E2E_E_INPUTERR_NULL, * E2E_E_OK * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00390*/ FUNC(Std_ReturnType, E2E_CODE) E2E_P01CheckInit ( P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ) { Std_ReturnType ret; /*SWS_E2E_00389*//*SWS_E2E_00011*/ if(NULL_PTR == State) { ret = E2E_E_INPUTERR_NULL; } else { State->LastValidCounter = (uint8)0; State->MaxDeltaCounter = (uint8)0; State->WaitForFirstData = TRUE; State->NewDataAvailable = TRUE; State->LostData = (uint8)0; State->Status = E2E_P01STATUS_NONEWDATA; State->NoNewOrRepeatedDataCounter = (uint8)0; State->SyncCounter = (uint8)0; ret = E2E_E_OK; } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P01MapStatusToSM * * Description: The function maps the check status of Profile 1 to a generic * check status, which can be used by E2E state machine check function. * The E2E Profile 1 delivers a more fine-granular status, but this * is not relevant for the E2E state machine. * * Inputs: CheckReturn : Return value of the E2E_P01Check function. * Status : Status determined by E2E_P01Check function. * profileBehavior : FALSE: check has the legacy behavior, before R4.2 * TRUE : check behaves like new P4/P5/P6 profiles * introduced in R4.2 * * Outputs: Profile-independent status of the reception on one single Data in one cycle. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00382*/ FUNC(E2E_PCheckStatusType, E2E_CODE) E2E_P01MapStatusToSM ( Std_ReturnType CheckReturn, E2E_P01CheckStatusType Status, boolean profileBehavior ) { /*SWS_E2E_00384*/ E2E_PCheckStatusType CheckStatus = E2E_P_ERROR; /*SWS_E2E_00383,SWS_E2E_00476*/ if(E2E_E_OK == CheckReturn) { if((E2E_P01STATUS_OK == Status) || (E2E_P01STATUS_OKSOMELOST == Status)) { CheckStatus = E2E_P_OK; } else if(E2E_P01STATUS_SYNC == Status) { /*SWS_E2E_00383*/ if(TRUE == profileBehavior) { CheckStatus = E2E_P_OK; } /*SWS_E2E_00476*/ else { CheckStatus = E2E_P_WRONGSEQUENCE; } } else if(E2E_P01STATUS_WRONGCRC == Status) { CheckStatus = E2E_P_ERROR; } else if(E2E_P01STATUS_REPEATED == Status) { CheckStatus = E2E_P_REPEATED; } else if(E2E_P01STATUS_NONEWDATA == Status) { CheckStatus = E2E_P_NONEWDATA; } else if(E2E_P01STATUS_WRONGSEQUENCE == Status) { CheckStatus = E2E_P_WRONGSEQUENCE; } else { /*SWS_E2E_00383*/ if(TRUE == profileBehavior) { CheckStatus = E2E_P_WRONGSEQUENCE; } /*SWS_E2E_00476*/ else { CheckStatus = E2E_P_OK; } } } return CheckStatus; } #define E2E_STOP_SEC_CODE #include "E2E_MemMap.h"