/* 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_P02.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_P02.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. */ /****************************************************************************** * Macro ******************************************************************************/ #define E2E_P02_CRC_INIT_VALUE ((uint8)0xFF) /*SWS_E2E_00122*/ #define E2E_P02_CRC_OFFSET ((uint16)0) /* SWS_E2E_00121 */ #define E2E_P02_MAX_DATA_LENGTH ((uint16)2048)/*in bits*/ #define E2E_P02_MIN_DATA_LENGTH ((uint16)16)/*in bits*/ /*SWS_E2E_00219*//*SWS_E2E_00128*/ #define E2E_P02_MAX_COUNTER_VALUE ((uint8)15) /*in bytes*/ #define E2E_P02_BYTE_ALIGNED_MASK ((uint16)0x0007) #define E2E_P02_LOW_NIBBLE_MASK ((uint8)0x0F) #define E2E_P02_HIGH_NIBBLE_MASK ((uint8)0xF0) #define E2E_P02_GET_DATALEN(config) ((uint16)((config)->DataLength >> (uint16)3) - (uint16)1) #define E2E_P02_GET_HEADEROFFSET(config) ((config)->Offset >> (uint16)3) #define E2E_P02_IS_NOT_BYTE_ALIGNED(bit) ((uint16)((bit) & E2E_P02_BYTE_ALIGNED_MASK) != (uint16)0) #define E2E_START_SEC_CODE #include "E2E_MemMap.h" /****************************************************************************** * Private Functions Declare ******************************************************************************/ STATIC FUNC(void, E2E_CODE)E2E_P02CheckRecvCounter ( uint8 Counter, P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P02CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ); STATIC FUNC(void, E2E_CODE) E2E_P02InitDeltaAndLastValidCounter ( uint8 Counter, P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P02CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ); STATIC FUNC(void, E2E_CODE) E2E_P02CheckSyncCounter ( uint8 Counter, uint8 DeltaCounter, P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P02CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ); STATIC FUNC(uint8, E2E_CODE) E2E_P02GetDeltaCounter ( uint8 Counter, uint8 LastValidCounter ); STATIC FUNC(uint8, E2E_CODE)E2E_P02GetCrc ( uint8 DataId, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data, uint16 DataLen ); /****************************************************************************** * Private Functions ******************************************************************************/ /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02CheckRecvCounter * * 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_P02CheckRecvCounter ( uint8 Counter, P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P02CheckStateType, 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_P02GetDeltaCounter(Counter, State->LastValidCounter); if ((uint8)0 == DeltaCounter) { /*SWS_E2E_00301*/ if (State->NoNewOrRepeatedDataCounter < E2E_P02_MAX_COUNTER_VALUE) { State->NoNewOrRepeatedDataCounter++; } /*SWS_E2E_00146*/ State->Status = E2E_P02STATUS_REPEATED; } else if ((uint8)1 == DeltaCounter) { /*SWS_E2E_00147*/ State->Status = E2E_P02STATUS_OK; E2E_P02CheckSyncCounter(Counter, DeltaCounter, Config, State); } else if (DeltaCounter <= State->MaxDeltaCounter) { /*SWS_E2E_00148*/ State->Status = E2E_P02STATUS_OKSOMELOST; E2E_P02CheckSyncCounter(Counter, DeltaCounter, Config, State); } /*DeltaCounter is greater than State->MaxDeltaCounter*/ else { /*SWS_E2E_00300*/ State->NoNewOrRepeatedDataCounter = (uint8)0; /*SWS_E2E_00145*/ State->SyncCounter = Config->SyncCounterInit; if (State->SyncCounter > (uint8)0) { /*SWS_E2E_00150,SWS_E2E_00151*/ E2E_P02InitDeltaAndLastValidCounter(Counter, Config, State); } /*SWS_E2E_00145*/ State->Status = E2E_P02STATUS_WRONGSEQUENCE; } } /*The data is received for the first time*/ else { /*SWS_E2E_00143*/ State->WaitForFirstData = FALSE; /*SWS_E2E_00150,SWS_E2E_00151*/ E2E_P02InitDeltaAndLastValidCounter(Counter, Config, State); /*SWS_E2E_00142*/ State->Status = E2E_P02STATUS_INITIAL; } } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02InitDeltaAndLastValidCounter * * 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_P02InitDeltaAndLastValidCounter ( uint8 Counter, P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P02CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ) { /*SWS_E2E_00150*/ State->MaxDeltaCounter = Config->MaxDeltaCounterInit; /*SWS_E2E_00151*/ State->LastValidCounter = Counter; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02CheckSyncCounter * * 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_P02CheckSyncCounter ( uint8 Counter, uint8 DeltaCounter, P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) Config, P2VAR(E2E_P02CheckStateType, AUTOMATIC, E2E_APPL_DATA) State ) { /*SWS_E2E_00150,SWS_E2E_00151*/ E2E_P02InitDeltaAndLastValidCounter(Counter, Config, State); /*update the lost data counter. SWS_E2E_00149*/ State->LostData = DeltaCounter - (uint8)1; /*the NoNewOrRepeatedDataCounter is less than the configured value*/ if (State->NoNewOrRepeatedDataCounter <= Config->MaxNoNewOrRepeatedData) { if (State->SyncCounter > (uint8)0) { /*SWS_E2E_00299*/ State->SyncCounter--; /*SWS_E2E_00299*/ State->Status = E2E_P02STATUS_SYNC; } } else { /*SWS_E2E_00298*/ State->SyncCounter = Config->SyncCounterInit; /*SWS_E2E_00298*/ State->Status = E2E_P02STATUS_SYNC; } /*SWS_E2E_00300*/ State->NoNewOrRepeatedDataCounter = (uint8)0; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02GetDeltaCounter * * 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 */ /*SWS_E2E_00135*/ STATIC FUNC(uint8, E2E_CODE) E2E_P02GetDeltaCounter ( uint8 Counter, uint8 LastValidCounter ) { uint8 DeltaCounter; if(Counter >= LastValidCounter) { DeltaCounter = Counter - LastValidCounter; } else { DeltaCounter = ((uint8)(E2E_P02_MAX_COUNTER_VALUE - LastValidCounter) + (uint8)1) + Counter; } return DeltaCounter; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02GetCrc * * Description: Calculate the crc value. * * Inputs: DataId : Data ID. * Data : Pointer to the data to be protected. * DataLen : The length of the data to be protected, except crc. * * Outputs: The crc value. * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ STATIC FUNC(uint8, E2E_CODE)E2E_P02GetCrc ( uint8 DataId, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data, uint16 DataLen ) { uint8 CrcData = DataId; /*SWS_E2E_00118*/ uint8 crc = E2E_P02_CRC_INIT_VALUE; /*SWS_E2E_00117*//*SWS_E2E_00221*//*SWS_E2E_00219*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC8H2F(Data, (uint32)DataLen, crc, TRUE); /*SWS_E2E_00117*//*SWS_E2E_00221*//*SWS_E2E_00219*//*SWS_E2E_00110*/ crc = Crc_CalculateCRC8H2F(&CrcData, (uint32)1, crc, FALSE); return crc; } /****************************************************************************** * Public Funtions ******************************************************************************/ /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02ProtectInit * * 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_00387*/ FUNC(Std_ReturnType, E2E_CODE) E2E_P02ProtectInit ( P2VAR(E2E_P02ProtectStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr ) { Std_ReturnType ret; /*SWS_E2E_00388*//*SWS_E2E_00011*/ if(NULL_PTR == StatePtr) { ret = E2E_E_INPUTERR_NULL; } else { ret = E2E_E_OK; StatePtr->Counter = (uint8)0; } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02Protect * * Description: Protects the array/buffer to be transmitted using the E2E profile 2. * 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 the data to be protected. * * Outputs: E2E_E_INPUTERR_NULL, * E2E_E_INPUTERR_WRONG, * E2E_E_INTERR, * E2E_E_OK * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00160*//*SWS_E2E_00124*//*SWS_E2E_00126*/ FUNC(Std_ReturnType, E2E_CODE) E2E_P02Protect ( P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr, P2VAR(E2E_P02ProtectStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr, P2VAR(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr ) { uint8 dataId; uint8 crc; uint8 counter; uint16 dataLen; Std_ReturnType ret = E2E_E_OK; uint16 headOffset; /*SWS_E2E_00011*/ if((NULL_PTR == ConfigPtr) || (NULL_PTR == StatePtr) || (NULL_PTR == DataPtr)) { ret = E2E_E_INPUTERR_NULL; } else if ((E2E_P02_MAX_DATA_LENGTH < (ConfigPtr->DataLength)) || (E2E_P02_MIN_DATA_LENGTH > (ConfigPtr->DataLength)) || (E2E_P02_IS_NOT_BYTE_ALIGNED(ConfigPtr->DataLength))) { ret = E2E_E_INPUTERR_WRONG; } else if(E2E_P02_CRC_OFFSET != ConfigPtr->Offset) { ret = E2E_E_INPUTERR_WRONG; } else { /*increase counter*//*SWS_E2E_00221*//*SWS_E2E_00219*//*SWS_E2E_00127*//*SWS_E2E_00129*/ /*SWS_E2E_00130*/ counter = (uint8)(StatePtr->Counter + (uint8)1) & E2E_P02_LOW_NIBBLE_MASK; StatePtr->Counter = counter; headOffset = E2E_P02_GET_HEADEROFFSET(ConfigPtr); /*record the counter*//*SWS_E2E_00123*//*SWS_E2E_00124*/ DataPtr[headOffset + (uint16)1] = (DataPtr[headOffset + (uint16)1] & E2E_P02_HIGH_NIBBLE_MASK) | (counter); /*get data id*//*SWS_E2E_00120*/ dataId = ConfigPtr->DataIDList[counter]; /* get data length*/ dataLen = E2E_P02_GET_DATALEN(ConfigPtr); /*calculate crc*//*SWS_E2E_00132*/ crc = E2E_P02GetCrc(dataId, &DataPtr[headOffset + (uint16)1], dataLen); /*SWS_E2E_00122*//*SWS_E2E_00124*//*SWS_E2E_00133*/ DataPtr[headOffset] = crc; } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02Check * * Description: Check the array/buffer using the E2E profile 2. 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 the data to be cheecked. * * Outputs: E2E_E_INPUTERR_NULL, * E2E_E_INPUTERR_WRONG, * E2E_E_INTERR, * E2E_E_OK * * Limitations: None ******************************************************************************* END_FUNCTION_HDR */ /*SWS_E2E_00161,SWS_E2E_00134*//*SWS_E2E_00125*/ FUNC(Std_ReturnType, E2E_CODE)E2E_P02Check ( P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr, P2VAR(E2E_P02CheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr, P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr ) { uint8 recvCounter; uint8 dataId; uint8 crc; uint16 dataLen; uint16 headOffset; Std_ReturnType ret = E2E_E_OK; /*SWS_E2E_00011*/ if((NULL_PTR == ConfigPtr) || (NULL_PTR == StatePtr) || (NULL_PTR == DataPtr)) { ret = E2E_E_INPUTERR_NULL; } else if ((E2E_P02_MAX_DATA_LENGTH < (ConfigPtr->DataLength)) || (E2E_P02_MIN_DATA_LENGTH > (ConfigPtr->DataLength)) || (E2E_P02_IS_NOT_BYTE_ALIGNED(ConfigPtr->DataLength))) { ret = E2E_E_INPUTERR_WRONG; } else if(E2E_P02_CRC_OFFSET != ConfigPtr->Offset) { ret = E2E_E_INPUTERR_WRONG; } else { /*SWS_E2E_00136,SWS_E2E_00137*/ if (StatePtr->MaxDeltaCounter < E2E_P02_MAX_COUNTER_VALUE) { StatePtr->MaxDeltaCounter++; } if (StatePtr->NewDataAvailable == TRUE) { headOffset = E2E_P02_GET_HEADEROFFSET(ConfigPtr); /*get received counter*//*SWS_E2E_00123*/ recvCounter = DataPtr[headOffset + (uint16)1] & E2E_P02_LOW_NIBBLE_MASK; /*get data id SWS_E2E_00139*//*SWS_E2E_00120*/ dataId = ConfigPtr->DataIDList[recvCounter]; /* get data length */ dataLen = E2E_P02_GET_DATALEN(ConfigPtr); /*calculate crc, SWS_E2E_00140*/ crc = E2E_P02GetCrc(dataId, &DataPtr[headOffset + (uint16)1], dataLen); if (crc == DataPtr[headOffset]) { /*check counter*/ E2E_P02CheckRecvCounter(recvCounter, ConfigPtr, StatePtr); } else { /*SWS_E2E_00141*/ StatePtr->Status = E2E_P02STATUS_WRONGCRC; } } else { /*SWS_E2E_00301*/ if (StatePtr->NoNewOrRepeatedDataCounter < E2E_P02_MAX_COUNTER_VALUE) { StatePtr->NoNewOrRepeatedDataCounter++; } /*SWS_E2E_00138*/ StatePtr->Status = E2E_P02STATUS_NONEWDATA; } } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02CheckInit * * 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_00391*/ FUNC(Std_ReturnType, E2E_CODE) E2E_P02CheckInit ( P2VAR(E2E_P02CheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr ) { Std_ReturnType ret; /*SWS_E2E_00392*//*SWS_E2E_00011*/ if(NULL_PTR == StatePtr) { ret = E2E_E_INPUTERR_NULL; } else { StatePtr->LastValidCounter = (uint8)0; StatePtr->MaxDeltaCounter = (uint8)0; StatePtr->WaitForFirstData = TRUE; StatePtr->NewDataAvailable = TRUE; StatePtr->LostData = (uint8)0; StatePtr->Status = E2E_P02STATUS_NONEWDATA; StatePtr->NoNewOrRepeatedDataCounter = (uint8)0; StatePtr->SyncCounter = (uint8)0; ret = E2E_E_OK; } return ret; } /* BEGIN_FUNCTION_HDR ******************************************************************************* * Function Name: E2E_P02MapStatusToSM * * Description: The function maps the check status of Profile 2 to a generic * check status, which can be used by E2E state machine check function. * The E2E Profile 2 delivers a more fine-granular status, but this * is not relevant for the E2E state machine. * * Inputs: CheckReturn : Return value of the E2E_P02Check function. * Status : Status determined by E2E_P02Check 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_00379*/ FUNC(E2E_PCheckStatusType, E2E_CODE) E2E_P02MapStatusToSM ( Std_ReturnType CheckReturn, E2E_P02CheckStatusType Status, boolean profileBehavior ) { /*SWS_E2E_00381*/ E2E_PCheckStatusType CheckStatus = E2E_P_ERROR; /*SWS_E2E_00380,SWS_E2E_00477*/ if(E2E_E_OK == CheckReturn) { if((E2E_P02STATUS_OK == Status) || (E2E_P02STATUS_OKSOMELOST == Status)) { CheckStatus = E2E_P_OK; } else if(E2E_P02STATUS_SYNC == Status) { /*SWS_E2E_00380*/ if(TRUE == profileBehavior) { CheckStatus = E2E_P_OK; } /*SWS_E2E_00477*/ else { CheckStatus = E2E_P_WRONGSEQUENCE; } } else if(E2E_P02STATUS_WRONGCRC == Status) { CheckStatus = E2E_P_ERROR; } else if(E2E_P02STATUS_REPEATED == Status) { CheckStatus = E2E_P_REPEATED; } else if(E2E_P02STATUS_NONEWDATA == Status) { CheckStatus = E2E_P_NONEWDATA; } else if(E2E_P02STATUS_WRONGSEQUENCE == Status) { CheckStatus = E2E_P_WRONGSEQUENCE; } else { /*SWS_E2E_00380*/ if(TRUE == profileBehavior) { CheckStatus = E2E_P_WRONGSEQUENCE; } /*SWS_E2E_00477*/ else { CheckStatus = E2E_P_OK; } } } return CheckStatus; } #define E2E_STOP_SEC_CODE #include "E2E_MemMap.h"