/* 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_P05.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_P05.h" /******************************************************************************* * General 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 3432 EOF*/ /* P2VAR and other macros in the Compiler conforms to AUTOSAR standard.There's no need to revise. */ /***************************************************************************** * E2E QAC Suppression *****************************************************************************/ /*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 3435,3456 EOF*/ /* Allow multiple use parameters in macros */ /****************************************************************************** * Macro ******************************************************************************/ #define E2E_P05_BYTE_MASK ((uint8)0xFF) #define E2E_P05_MAX_COUNTER_VALUE ((uint8)0xFF) #define E2E_P05_CRC_INIT_VALUE ((uint16)0xFFFF) /*defined in bits*/ #define E2E_P05_MAX_DATA_LENGTH ((uint16)0x8000) #define E2E_P05_PROTECT_HEADER_LENGTH ((uint16)(3 * 8)) /*defined in bytes*/ #define E2E_P05_COUNTER_OFFSET ((uint16)2) #define E2E_P05_CRC_OFFSET ((uint16)0) #define E2E_P05_CRC_LENGTH ((uint16)2) /*SWS_E2E_00397*/ #define E2E_P05_MAX_COUNTER_VALUE ((uint8)0xFF) #define E2E_P05_DATA_UINT_BIT ((uint16)8) #define E2E_P05_GET_HEADEROFFSET(config) ((config)->Offset >> (uint16)3) #define E2E_P05_GET_DATALEN(config) ((config)->DataLength >> (uint16)3) #define E2E_P05_LETO16MCU(data) (uint16)((uint16)(((uint16)(data)[1] & (uint16)0x00FF) << (uint16)8)\ | (uint16)(((uint16)(data)[0] & (uint16)0x00FF) << (uint16)0)) #define E2E_P05_BYTE_ALIGNED_MASK ((uint16)0x0007) #define E2E_P05_IS_NOT_BYTE_ALIGNED(bit) ((uint16)((bit) & E2E_P05_BYTE_ALIGNED_MASK) != (uint16)0) #define E2E_START_SEC_CODE #include "E2E_MemMap.h" /****************************************************************************** * Private Functions Declare ******************************************************************************/ STATIC FUNC(void, E2E_CODE)E2E_P05CheckRecvCounter ( uint8 Counter, P2CONST(E2E_P05ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P05CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ); STATIC FUNC(uint8, E2E_CODE) E2E_P05GetDeltaCounter ( uint8 Counter, uint8 LastValidCounter ); STATIC FUNC(uint16, E2E_CODE)E2E_P05GetCrc ( P2CONST(E2E_P05ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data ); /****************************************************************************** * Private Functions ******************************************************************************/ /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P05CheckRecvCounter * * 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 */ /*SWS_E2E_00416*/ STATIC FUNC(void, E2E_CODE)E2E_P05CheckRecvCounter ( uint8 Counter, P2CONST(E2E_P05ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P05CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ) { uint8 DeltaCounter; /*compute delta counter*/ DeltaCounter = E2E_P05GetDeltaCounter(Counter, State->Counter); if((uint8)0 == DeltaCounter) { State->Status = E2E_P05STATUS_REPEATED; } else if((uint8)1 == DeltaCounter) { State->Status = E2E_P05STATUS_OK; } else if(DeltaCounter <= Config->MaxDeltaCounter) { State->Status = E2E_P05STATUS_OKSOMELOST; } else { State->Status = E2E_P05STATUS_WRONGSEQUENCE; } State->Counter = Counter; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P05GetDeltaCounter * * 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_P05GetDeltaCounter ( uint8 Counter, uint8 LastValidCounter ) { uint8 DeltaCounter; if(Counter >= LastValidCounter) { DeltaCounter = Counter - LastValidCounter; } else { DeltaCounter = ((uint8)(E2E_P05_MAX_COUNTER_VALUE - LastValidCounter) + (uint8)1) + Counter; } return DeltaCounter; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P05GetCrc * * Description: Calculate the crc value. * * Inputs: Config : Pointer to static configuration. * Data : Pointer to the data to be protected. * * Outputs: The crc value. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00406*/ STATIC FUNC(uint16, E2E_CODE)E2E_P05GetCrc ( P2CONST(E2E_P05ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data ) { uint16 crc = E2E_P05_CRC_INIT_VALUE; uint16 headerOffset = E2E_P05_GET_HEADEROFFSET(Config); uint16 length = E2E_P05_GET_DATALEN(Config); uint8 dataIdLow; uint8 dataIdHigh; uint16 CrcCopyLength; if(Config->Offset > (uint16)0) { /*SWS_E2E_00221*//*SWS_E2E_00400*//*SWS_E2E_00401*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC16(&Data[0], (uint32)headerOffset, crc, TRUE); /*SWS_E2E_00400*//*SWS_E2E_00401*/ CrcCopyLength = (uint16)(length - headerOffset) - E2E_P05_CRC_LENGTH; crc = Crc_CalculateCRC16(&Data[headerOffset + E2E_P05_CRC_LENGTH], (uint32)CrcCopyLength, crc, FALSE); } else { /*SWS_E2E_00221*//*SWS_E2E_00400*//*SWS_E2E_00401*//*SWS_E2E_00110*/ CrcCopyLength = (uint16)(length - headerOffset) - E2E_P05_CRC_LENGTH; crc = Crc_CalculateCRC16(&Data[headerOffset + E2E_P05_CRC_LENGTH], (uint32)CrcCopyLength, crc, TRUE); } dataIdLow = (uint8)(Config->DataID) & E2E_P05_BYTE_MASK; dataIdHigh = (uint8)(Config->DataID >> E2E_P05_DATA_UINT_BIT) & E2E_P05_BYTE_MASK; /*SWS_E2E_00221*//*SWS_E2E_00399*//*SWS_E2E_00400*//*SWS_E2E_00401*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC16(&dataIdLow, (uint32)1, crc, FALSE); /*SWS_E2E_00400*//*SWS_E2E_00401*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC16(&dataIdHigh, (uint32)1, crc, FALSE); return crc; } /****************************************************************************** * Public Funtions ******************************************************************************/ /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P05ProtectInit * * 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_00447*/ FUNC(Std_ReturnType, E2E_CODE) E2E_P05ProtectInit ( P2VAR(E2E_P05ProtectStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr ) { Std_ReturnType ret; /*SWS_E2E_00448*//*SWS_E2E_00011*/ if(NULL_PTR == StatePtr) { ret = E2E_E_INPUTERR_NULL; } else { ret = E2E_E_OK; /*SWS_E2E_00397*/ StatePtr->Counter = (uint8)0; } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P05Protect * * Description: Protects the array/buffer to be transmitted using the E2E profile 5. * This includes checksum calculation, handling of counter. * * Inputs: ConfigPtr : Pointer to static configuration. * StatePtr : Pointer to port/data communication state. * DataPtr : Pointer to Data to be transmitted. * Length : Length of the data in bytes. * * Outputs: E2E_E_INPUTERR_NULL, * E2E_E_INPUTERR_WRONG, * E2E_E_INTERR, * E2E_E_OK * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00446*//*SWS_E2E_00403*/ FUNC(Std_ReturnType, E2E_CODE) E2E_P05Protect ( P2CONST(E2E_P05ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr, P2VAR(E2E_P05ProtectStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr, P2VAR(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr, uint16 Length ) { Std_ReturnType ret = E2E_E_OK; uint16 headerOffset; uint16 crc; /*verify input parameters*//*SWS_E2E_00011*//*SWS_E2E_00404*/ if((NULL_PTR == ConfigPtr) || (NULL_PTR == StatePtr) || (NULL_PTR == DataPtr)) { ret = E2E_E_INPUTERR_NULL; } else if ((E2E_P05_MAX_DATA_LENGTH < (ConfigPtr->DataLength)) || (ConfigPtr->DataLength < E2E_P05_PROTECT_HEADER_LENGTH) || (E2E_P05_IS_NOT_BYTE_ALIGNED(ConfigPtr->DataLength))) { ret = E2E_E_INPUTERR_WRONG; } else if ((ConfigPtr->Offset > (ConfigPtr->DataLength - E2E_P05_PROTECT_HEADER_LENGTH)) || (E2E_P05_IS_NOT_BYTE_ALIGNED(ConfigPtr->Offset))) { ret = E2E_E_INPUTERR_WRONG; } /*SWS_E2E_00404*/ else if ((Length * E2E_P05_DATA_UINT_BIT) != ConfigPtr->DataLength) { ret = E2E_E_INPUTERR_WRONG; } else { /*Compute offset*//*SWS_E2E_00469*/ headerOffset = E2E_P05_GET_HEADEROFFSET(ConfigPtr); /*Write Counter to DataPtr*//*SWS_E2E_00394*//*SWS_E2E_00405*/ DataPtr[headerOffset + E2E_P05_COUNTER_OFFSET] = StatePtr->Counter; /*calculate crc*/ crc = E2E_P05GetCrc(ConfigPtr, DataPtr); /*write the crc to data using Little Endian order*//*SWS_E2E_00394*//*SWS_E2E_00407*/ DataPtr[headerOffset + E2E_P05_CRC_OFFSET] = (uint8)crc & E2E_P05_BYTE_MASK; DataPtr[(uint16)(headerOffset + E2E_P05_CRC_OFFSET) + (uint16)1] = (uint8)(crc >> E2E_P05_DATA_UINT_BIT) & E2E_P05_BYTE_MASK; /*PRQA S 3383 ++*/ /*The previously logical judgment of the data is guaranteed that the data value will not overflow.*/ /*Increment Counter*//*SWS_E2E_00221*//*SWS_E2E_00397*//*SWS_E2E_00409*/ StatePtr->Counter++; /*PRQA S 3383 --*/ } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P05Check * * Description: Checks the Data received using the E2E profile 5. This includes * CRC calculation, handling of Counter. * * Inputs: ConfigPtr : Pointer to static configuration. * StatePtr : Pointer to port/data communication state. * DataPtr : Pointer to received data. * Length : Length of the data in bytes. * * Outputs: E2E_E_INPUTERR_NULL, * E2E_E_INPUTERR_WRONG, * E2E_E_INTERR, * E2E_E_OK * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00449*//*SWS_E2E_00411*/ FUNC(Std_ReturnType, E2E_CODE)E2E_P05Check ( P2CONST(E2E_P05ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr, P2VAR(E2E_P05CheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr, uint16 Length ) { Std_ReturnType ret = E2E_E_OK; uint16 calCrc; uint16 recvCrc; uint16 headOffset; uint8 recvCounter; /*SWS_E2E_00011*//*SWS_E2E_00412*/ if((NULL_PTR == ConfigPtr) || (NULL_PTR == StatePtr)) { ret = E2E_E_INPUTERR_NULL; } else if ((E2E_P05_MAX_DATA_LENGTH < (ConfigPtr->DataLength)) || (ConfigPtr->DataLength < E2E_P05_PROTECT_HEADER_LENGTH) || (E2E_P05_IS_NOT_BYTE_ALIGNED(ConfigPtr->DataLength))) { ret = E2E_E_INPUTERR_WRONG; } else if ((ConfigPtr->Offset > (ConfigPtr->DataLength - E2E_P05_PROTECT_HEADER_LENGTH)) || (E2E_P05_IS_NOT_BYTE_ALIGNED(ConfigPtr->Offset))) { ret = E2E_E_INPUTERR_WRONG; } /*SWS_E2E_00412*/ else if (DataPtr == NULL_PTR) { if(Length != (uint16)0) { ret = E2E_E_INPUTERR_WRONG; } else { /*SWS_E2E_00416*/ StatePtr->Status = E2E_P05STATUS_NONEWDATA; } } else if ((Length * E2E_P05_DATA_UINT_BIT) != ConfigPtr->DataLength) { ret = E2E_E_INPUTERR_WRONG; } /*the length of the data received is correct*/ else { /*compute offset*/ headOffset = E2E_P05_GET_HEADEROFFSET(ConfigPtr); /*read received counter from data*//*SWS_E2E_00413*/ recvCounter = DataPtr[headOffset + E2E_P05_COUNTER_OFFSET]; /*PRQA S 4571 ++*/ /*Allows less than int length data to shift and retrieve other operations, and the department is verified and there is no problem.*/ /*read received crc from data*//*SWS_E2E_00414*/ recvCrc = E2E_P05_LETO16MCU(&DataPtr[headOffset + E2E_P05_CRC_OFFSET]); /*PRQA S 4571 --*/ /*Compute CRC*/ calCrc = E2E_P05GetCrc(ConfigPtr, DataPtr); /*SWS_E2E_00416*/ /*Check if the received crc is equal to the calculated crc*//*SWS_E2E_00416*/ if(recvCrc == calCrc) { /*check counter*//*SWS_E2E_00416*/ E2E_P05CheckRecvCounter(recvCounter, ConfigPtr, StatePtr); } else { /*SWS_E2E_00416*/ StatePtr->Status = E2E_P05STATUS_ERROR; } } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P05CheckInit * * Description: Initializes the check state. * * Inputs: StatePtr : Pointer to port/data communication state. * * Outputs: E2E_E_INPUTERR_NULL, * E2E_E_OK * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00450*/ FUNC(Std_ReturnType, E2E_CODE) E2E_P05CheckInit ( P2VAR(E2E_P05CheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr ) { Std_ReturnType ret; /*SWS_E2E_00451*//*SWS_E2E_00011*/ if(NULL_PTR == StatePtr) { ret = E2E_E_INPUTERR_NULL; } else { StatePtr->Status = E2E_P05STATUS_ERROR; /*SWS_E2E_00472*/ StatePtr->Counter = E2E_P05_MAX_COUNTER_VALUE; ret = E2E_E_OK; } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P05MapStatusToSM * * Description: The function maps the check status of Profile 5 to a generic * check status, which can be used by E2E state machine check function. * The E2E Profile 5 delivers a more fine-granular status, but this * is not relevant for the E2E state machine. * * Inputs: CheckReturn : Return value of the E2E_P05Check function. * Status : Status determined by E2E_P05Check function. * * Outputs: Profile-independent status of the reception on one single Data in one cycle. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00452*/ FUNC(E2E_PCheckStatusType, E2E_CODE) E2E_P05MapStatusToSM ( Std_ReturnType CheckReturn, E2E_P05CheckStatusType Status ) { E2E_PCheckStatusType CheckStatus; /*SWS_E2E_00453*/ if(E2E_E_OK == CheckReturn) { if((E2E_P05STATUS_OK == Status) || (E2E_P05STATUS_OKSOMELOST == Status)) { CheckStatus = E2E_P_OK; } else if(E2E_P05STATUS_ERROR == Status) { CheckStatus = E2E_P_ERROR; } else if(E2E_P05STATUS_REPEATED == Status) { CheckStatus = E2E_P_REPEATED; } else if(E2E_P05STATUS_NONEWDATA == Status) { CheckStatus = E2E_P_NONEWDATA; } else { CheckStatus = E2E_P_WRONGSEQUENCE; } } /*SWS_E2E_00454*/ else { CheckStatus = E2E_P_ERROR; } return CheckStatus; } #define E2E_STOP_SEC_CODE #include "E2E_MemMap.h"