#ifndef _UDS_FBL_SERVICE_34_SOURCE #define _UDS_FBL_SERVICE_34_SOURCE /******************************************************************************* ** Include Section ** *******************************************************************************/ /*#include "uds_fbl_mgr.h"*/ #include "uds_fbl_service34.h" /******************************************************************************* ** Version Information ** *******************************************************************************/ /******************************************************************************* ** Version Check ** *******************************************************************************/ /******************************************************************************* ** Macro definition ** *******************************************************************************/ /******************************************************************************* ** Global Data ** *******************************************************************************/ #define SERIAL_SERVER_ONE_PAGE_SIZE 0x800 const uds_nrc nrc_3400[5] = { UDSincorrectMessageLengthOrInvalidFormat,\ UDSrequestOutOfRange,\ UDSsecurityAccessDenied,\ UDSconditionNotCorrect,\ UDSuploadDownloadNotAccepted }; /*--------- <0x34> sub function config start-------------*/ static const DIAG_sunfunction_t SessionSubfunction[] = { {0x00,2,true,11,4,NULL,{nrc_3400, 5}} }; /*--------- <0x34>sub function config end---------------*/ /*-------------------------------------------------------*/ extern void FlsPgm_SetProgramAddr(uint32_t addr); /******************************************************************************* ** Function Definitions ** *******************************************************************************/ /*==============================================================================================================*/ /* static MEM_TYPE Service34_GetMemType(UDSpacket_t* qUDSpacket, uint8_t addrFormat_u8, */ /* uint8_t lenFormat_u8 ,uint32_t *addr_u32, */ /* uint32_t *len_u32) */ /* -------------------------------------------------------------------------------------------------------------*/ /* Function: Get the request memory type(FBL,,APP,FLASH DRIVER) */ /* Arguments: None */ /* Return: Yes or No */ /*==============================================================================================================*/ static MEM_TYPE Service34_GetMemType(UDSpacket_t* qUDSpacket, uint8_t addrFormat_u8, uint8_t lenFormat_u8 ,uint32_t *addr_u32, uint32_t *len_u32) { uint8_t formatIndex_u8 = 0; MEM_TYPE result; *addr_u32 = 0; *len_u32 = 0; /* Get address */ for(formatIndex_u8 = addrFormat_u8; formatIndex_u8 > 0; formatIndex_u8--) { *addr_u32 |= ((((uint32_t)qUDSpacket->Data.Byte[formatIndex_u8 + 2]) & 0x000000ff) \ << (addrFormat_u8 - formatIndex_u8) * 8); } /* Get length */ for(formatIndex_u8=lenFormat_u8+addrFormat_u8;formatIndex_u8>addrFormat_u8;formatIndex_u8--) { *len_u32 |= ((((uint32_t)qUDSpacket->Data.Byte[formatIndex_u8 + 2]) & 0x000000ff) \ << (lenFormat_u8 + addrFormat_u8 - formatIndex_u8) * 8); } result = MEM_GetType(*addr_u32, *len_u32); return result; } /*==============================================================================================================*/ /* static bool Check_Nrc_13_Of_Service34(uint16_t sourceLength, uint8_t targetLength_1, uint8_t targetLength_2) */ /* -------------------------------------------------------------------------------------------------------------*/ /* Function: Check if the length of the service request is wrong */ /* Arguments: sourceLength : Actual service request length */ /* targetLength_1 : address bytes */ /* targetLength_2 : length bytes */ /* Return: Yes or No */ /*==============================================================================================================*/ static bool Check_Nrc_13_Of_Service34(uint16_t sourceLength, uint8_t targetLength_1, uint8_t targetLength_2) { if (sourceLength != targetLength_1 + targetLength_2 + 3) { return true; } else { return false; } } /*==============================================================================================================*/ /* static bool Check_Nrc_22_Of_Service34(void) */ /* -------------------------------------------------------------------------------------------------------------*/ /* Function: Check if the downlaod condition is wrong */ /* Arguments: None */ /* Return: Yes or No */ /*==============================================================================================================*/ static bool Check_Nrc_22_Of_Service34(void) { bool request_sts; bool result; request_sts = udsFbl_Get_Request_Is_Trigger(); if(request_sts == TRUE) /* receives a request for this service while in the process of receiving a download */ { result = TRUE; } else { result = FALSE; } return result; } /*==============================================================================================================*/ /* static bool Check_Nrc_31_Of_Service34(UDSpacket_t* qUDSpacket, uint8_t addrFormat_u8, uint8_t lenFormat_u8) */ /* -------------------------------------------------------------------------------------------------------------*/ /* Function: Check whether the download data format exceeds the valid range */ /* Arguments: qUDSpacket : CAN message structure pointer */ /* addrFormat_u8 : address bytes */ /* lenFormat_u8 : length bytes */ /* Return: Yes or No */ /*==============================================================================================================*/ static bool Check_Nrc_31_Of_Service34(UDSpacket_t* qUDSpacket, uint8_t addrFormat_u8, uint8_t lenFormat_u8) { uint32_t addr_u32; uint32_t len_u32; bool nrcFlag; MEM_TYPE typeIndex_e; typeIndex_e = Service34_GetMemType(qUDSpacket,addrFormat_u8,lenFormat_u8,&addr_u32,&len_u32); if(MEM_ERROR == typeIndex_e) { nrcFlag = true; } else { if((typeIndex_e == MEM_CAL_APP) && ((addr_u32 != COD_APPL_ADDR_START) || (len_u32 != MEM_COD_APP_LEN))) { nrcFlag = true; } else if((typeIndex_e == MEM_FBL) && ((addr_u32 != FLU_FBL_ADDR_START_OnApp) || (len_u32 != MEM_FBL_LEN))) { nrcFlag = true; } else if((typeIndex_e == MEM_FLASHDRIVER) && ((addr_u32 != DRIVER_ADDR_START) || (len_u32 != MEM_DRIVER_LEN))) { nrcFlag = true; } else { nrcFlag = false; } } return nrcFlag; } /*==============================================================================================================*/ /* static bool Check_Nrc_70_Of_Service34(UDSpacket_t* qUDSpacket, uint8_t addrFormat_u8, uint8_t lenFormat_u8) */ /* -------------------------------------------------------------------------------------------------------------*/ /* Function: Check if the programming is successful */ /* Arguments: qUDSpacket : CAN message structure pointer */ /* addrFormat_u8 : address bytes */ /* lenFormat_u8 : length bytes */ /* Return: Yes or No */ /*==============================================================================================================*/ static bool Check_Nrc_70_Of_Service34(UDSpacket_t* qUDSpacket, uint8_t addrFormat_u8, uint8_t lenFormat_u8) { uint32_t addr_u32; uint32_t len_u32; uint8_t eraseResult = 0; bool nrcFlag = false; uint16_t blockLength = 0; uint8_t request_type; uint8_t start_address[4]; uint8_t data_length[4]; request_type = Service34_GetMemType(qUDSpacket,addrFormat_u8,lenFormat_u8,&addr_u32,&len_u32); /* eraseResult = MEM_Erase(addr_u32, len_u32);*/ if(MEM_FBL == request_type) { eraseResult = MEM_Request(FLU_FBL_ADDR_START_OnApp, MEM_FBL_LEN); udsFbl_Set_Curr_Download_Type(MEM_FBL); } else { eraseResult = MEM_Request(addr_u32, len_u32); udsFbl_Set_Curr_Download_Type(request_type); } memcpy(start_address,&qUDSpacket->Data.Byte[3],4); memcpy(data_length,&qUDSpacket->Data.Byte[7],4); if(MEM_OK == eraseResult) { /* calc hash with startaddress and datalength */ /*sha256_init(&md_value); sha256_process(&md_value, start_address, 4); sha256_process(&md_value, data_length, 4);*/ /* Record the address and length of the request */ udsFbl_Set_Request_StartAddr(addr_u32); if(MEM_FLASHDRIVER == request_type) { /* do nothing */ } else if(MEM_FBL == request_type) { FlsPgm_SetProgramAddr(FLU_FBL_ADDR_START_OnApp); } else { FlsPgm_SetProgramAddr(addr_u32); } udsFbl_Set_Request_EndAddr(addr_u32 + len_u32 - 1); udsFbl_Set_Request_Is_Trigger(true); udsFbl_Set_Download_Addr(udsFbl_Get_Request_StartAddr()); udsFbl_Set_Download_Block_Cnt(1); udsFbl_Set_PreDownload_Block_Cnt(0); udsFbl_Set_DownloadStatus(FALSE); /* Set the reply data, the reply data is the length of each packet */ qUDSpacket->Data.Byte[0] = UDS_GET_POSITIVE_RSP(qUDSpacket->Data.Byte[0]); qUDSpacket->Data.Byte[1] = (uint8_t)0x20; qUDSpacket->Data.Byte[2] = (uint8_t)(((SERIAL_SERVER_ONE_PAGE_SIZE+2)>>8)&0XFF); qUDSpacket->Data.Byte[3] = (uint8_t)(((SERIAL_SERVER_ONE_PAGE_SIZE+2)>>0)&0XFF); blockLength = (((uint16_t)qUDSpacket->Data.Byte[2] << 8) |((uint16_t)qUDSpacket->Data.Byte[3])); udsFbl_Set_maxNumberOfBlockLength(blockLength); qUDSpacket->size = 4; } else { nrcFlag = true; } return nrcFlag; } /*==============================================================================================================*/ /* uds_nrc service34_nrc_check(UDSpacket_t* qUDSpacket) */ /* -------------------------------------------------------------------------------------------------------------*/ /* Function: 34 service negative response judgment */ /* Arguments: qUDSpacket : CAN message structure pointer */ /* Return: Response type */ /*==============================================================================================================*/ uds_nrc service34_nrc_check(UDSpacket_t* qUDSpacket) { uds_nrc returnType = 0; uint8_t const kwpdiag_num = (sizeof(SessionSubfunction)/sizeof(DIAG_sunfunction_t)); uint8_t index = 0; uint8_t dataFormatIdentifier = 0; uint8_t index_nrc = 0; /* Decompose the data, take out the address and length */ uint8_t addrFormat_u8 = 0; /* address Format Identifier */ uint8_t lenFormat_u8 = 0; /* Length Format Identifier */ if(qUDSpacket->size < 5) { returnType = UDSincorrectMessageLengthOrInvalidFormat; } else { dataFormatIdentifier = qUDSpacket->Data.Byte[1]; lenFormat_u8 = ((qUDSpacket->Data.Byte[2] & 0xf0) >> 4); addrFormat_u8 = ((qUDSpacket->Data.Byte[2] & 0x0f) >> 0); if(0x00 != dataFormatIdentifier ||\ 0x04 != addrFormat_u8 ||\ 0x04 != lenFormat_u8) { returnType = UDSrequestOutOfRange; } else { for (index = 0; index < kwpdiag_num; index++) { nrc_table_t nrc_table = SessionSubfunction[index].nrc_table; /* Judge abnormal situations according to NRC priority */ for (index_nrc = 0; (index_nrc < nrc_table.nrc_cnt) && (returnType == 0); index_nrc++) { switch (nrc_table.nrc_list[index_nrc]) { case UDSincorrectMessageLengthOrInvalidFormat: if (Check_Nrc_13_Of_Service34(qUDSpacket->size, addrFormat_u8, lenFormat_u8)) { returnType = UDSincorrectMessageLengthOrInvalidFormat; } break; case UDSrequestOutOfRange: if (Check_Nrc_31_Of_Service34(qUDSpacket, addrFormat_u8, lenFormat_u8)) { returnType = UDSrequestOutOfRange; } break; case UDSsecurityAccessDenied: if (Uds_Nrc33_Occur((uint16_t)dataFormatIdentifier, SessionSubfunction, kwpdiag_num)) { returnType = UDSsecurityAccessDenied; } break; case UDSuploadDownloadNotAccepted: if (Check_Nrc_70_Of_Service34(qUDSpacket, addrFormat_u8, lenFormat_u8)) { returnType = UDSuploadDownloadNotAccepted; } break; case UDSconditionNotCorrect: if (Check_Nrc_22_Of_Service34()) { returnType = UDSconditionNotCorrect; } break; default: break; } } } } } return returnType; /* return highest priority nrc*/ } /*==============================================================================================================*/ /* uint8_t ApplDiag_RequestDownload_34(UDSpacket_t* qUDSpacket) */ /* -------------------------------------------------------------------------------------------------------------*/ /* Function: 34 service negative response judgment */ /* Arguments: qUDSpacket : CAN message structure pointer */ /* Return: Response type */ /*==============================================================================================================*/ uint8_t ApplDiag_RequestDownload_34(UDSpacket_t* qUDSpacket) { uds_nrc returnType = 0; returnType = service34_nrc_check(qUDSpacket); return returnType; } /******************************************************************************* ** End of File ** *******************************************************************************/ #endif /*_UDS_FBL_SERVICE_34_SOURCE*/