|
/***************************************************
|
* Include files
|
***************************************************/
|
#include <stddef.h>
|
#include <stdbool.h>
|
#include <string.h> /* For memcpy */
|
#include "cantp.h"
|
#include "cantp_user.h"
|
#include "xl_mcan.h"
|
#include "uds.h"
|
#include "did.h"
|
#include "fbl_ap.h"
|
#include "fbl_def.h"
|
#include "nvm.h"
|
#include "countdowntimer.h"
|
#ifdef ENABLE_BOOTLOADER
|
#endif
|
|
/***************************************************
|
* Local Defines
|
***************************************************/
|
typedef enum
|
{
|
SESSION_CONTROL = 0x10,
|
ECU_RESET = 0x11,
|
CLEAR_DIAGNOSTIC_INFORMATION = 0x14,
|
READ_DTC_INFORMATION = 0x19,
|
READ_DATA_BY_IDENTIFIER = 0x22,
|
SECURITY_ACCESS = 0x27,
|
COMMUNICATION_CONTROL = 0x28,
|
WRITE_DATA_BY_IDENTIFIER = 0x2E,
|
ROUTINE_CONTROL = 0x31,
|
TESTER_PRESENT = 0x3E,
|
CONTROL_DTC_SETTING = 0x85,
|
IN_OUT_CONTROL_BY_IDENTIFIER = 0x2F,
|
/*
|
READDATASTREAM = 0x2A,
|
READMEMORYBYADDRESS = 0x23,
|
WRITEMEMORYBYADDRESS = 0x3D,*/
|
REQUEST_DOWNLOAD = 0x34,
|
TRANSFER_DATA = 0x36,
|
REQUEST_TRANSFER_EXIT = 0x37,
|
|
} UDS_SID_e;
|
|
typedef enum READ_SID
|
{
|
READ_DATA_BY_ID = 0x22,
|
READ_DATA_BY_ADDRESS = 0x23,
|
MAX_READ_SID = 0
|
} READ_SID_e;
|
|
typedef enum UDS_SESSION
|
{
|
DEFAULT = 1,
|
PROGRAMMING = 2,
|
EXTENDED = 3,
|
} UDS_SESSIONS_e;
|
|
typedef enum UDS_RESP_PENDING
|
{
|
ERASE_RESP_PENDING = 0x01,
|
WRITE_RAM_RESP_PENDING = 0x02,
|
WRITE_FLASH_RESP_PENDING = 0x04,
|
CHECK_PROGRAMMING_INTERGRITY_PENDING = 0x08,
|
RESP_PENDING_MAX = 0x00
|
} UDS_RESP_PENDING_Te;
|
|
/* These define the index into */
|
enum UDS_RQ_FRAME_IDX
|
{
|
UDS_RQ_BYTE0,
|
UDS_RQ_BYTE1,
|
UDS_RQ_BYTE2,
|
UDS_RQ_BYTE3,
|
UDS_RQ_BYTE4,
|
UDS_RQ_BYTE5,
|
UDS_RQ_BYTE6,
|
UDS_RQ_BYTE7,
|
UDS_RQ_BYTE8,
|
UDS_RQ_BYTE9,
|
UDS_RQ_BYTE10,
|
UDS_RQ_BYTE11
|
};
|
|
typedef enum
|
{
|
NRC_GENERAL_REJECT = 0x10,
|
NRC_SERVICE_NOT_SUPPORTED = 0x11,
|
NRC_SUBFUNCTION_NOT_SUPPORTED = 0x12,
|
NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT = 0x13,
|
NRC_CONDITIONS_NOT_CORRECT = 0x22,
|
NRC_REQUEST_SEQUENCE_ERROR = 0x24,
|
NRC_REQUEST_OUT_OF_RANGE = 0x31,
|
NRC_SECURITY_ACCESS_DENIED = 0x33,
|
NRC_INVALID_KEY = 0x35,
|
NRC_EXCEEDED_NUMBER_OF_ATTEMPTS = 0x36,
|
NRC_BUSY_REPEAT_REQUEST = 0x21,
|
NRC_REQUIRED_TIME_DELAY_NOT_EXPIRED = 0x37,
|
NRC_TRANSFER_DATA_SUSPENDED = 0x71,
|
NRC_GENERAL_PROGRAMMING_FAILURE = 0x72,
|
NRC_WRONG_BLOCK_SEQUENCE_COUNTER = 0x73,
|
NRC_SERVICE_BUSY = 0x78,
|
NRC_SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION = 0x7F
|
} NEGA_RESP_Code_e;
|
|
typedef struct Read_DID_set
|
{
|
uint16_t DID_Value;
|
uint16_t DID_Table_Index;
|
|
} Read_DID_set_t;
|
|
#define REQUEST_LEVEL_ONE_SEED 0x01
|
#define SEND_LEVEL_ONE_KEY 0x02
|
#define REQUEST_LEVEL_TWO_SEED 0x09
|
#define SEND_LEVEL_TWO_KEY 0x0A
|
#define SECURITY_ACCESS_STEP_MAX 0xff
|
|
typedef enum SECURITY_ACCESS_STATE
|
{
|
SECURITY_ACCESS_LOCKED,
|
/* SECURITY_ACCESS_WAIT_KEY1, */
|
/* SECURITY_ACCESS_WAIT_KEY2, */
|
SECURITY_ACCESS_UNLOCK_LEVEL_1,
|
SECURITY_ACCESS_UNLOCK_LEVEL_2
|
} SECURITY_ACCESS_STATE_e;
|
|
typedef enum
|
{
|
TRANFER_IDLE,
|
TRANFER_START,
|
TRANFER_END
|
} UDS_TRANFER_DATA_STATE_Te;
|
|
typedef enum
|
{
|
PRGRAMMING_FAIL,
|
PRGRAMMING_OK,
|
PRGRAMMING_STATE_MAX
|
} FBL_PRGRAMMING_STATE_Te;
|
|
typedef struct Program_State
|
{
|
uint8_t ECU_SW_State;
|
uint8_t ECU_RAM_ROM_State;
|
} Program_State_t;
|
typedef struct Calibration_state
|
{
|
uint32_t cmd;
|
uint32_t calibrating_flag;
|
} Calibration_state_t;
|
|
#define RSP_DATA_LEN (6)
|
#define UDS_TASK_RATE (10)
|
|
#define CANTP_RX_BUFFER_SIZE (128)
|
#define FBL_RX_BUFFER_SIZE (256)
|
#define CANTP_TX_BUFFER_SIZE (128)
|
|
#define MAX_READ_DID_SET_SIZE (25)
|
#define SID_SIZE (1)
|
|
// ÕýÏìÓ¦ID
|
#define GET_RESPONSE_SERVICE_ID(SID) (0x40 + SID)
|
|
#define P2SERVER_TIMEROUT (50u)
|
#define P2SERVER_PENDING_TIMEROUT (5000u)
|
#define ENTRY_SLEEP_MODE_TIMEOU (30000 / UDS_TASK_RATE)
|
#define SECURITY_ACCESS_WAIT_TIME (10000 / UDS_TASK_RATE)
|
#define MAX_SECURITY_FAULT_CNT (3)
|
#define STOPALLDIDREQSIZE (2)
|
#define SIZE_OF_SID_DID (3)
|
|
#if 0
|
#define SEED_SIZE sizeof(uint32_t)
|
#define KEY_SIZE sizeof(uint32_t)
|
|
#define LEVEL1_SEED_MASK 0x521025A0
|
#define LEVEL1_KEY 0x6dfb5320u
|
|
#define LEVEL2_SEED_MASK 0x2035446A
|
#define LEVEL2_KEY 0x9e8e7b22u
|
#else /* дËÀµÄseed key */
|
// #define SEED_SIZE sizeof(uint16_t)
|
// #define KEY_SIZE sizeof(uint16_t)
|
|
// #define LEVEL1_SEED 0x0CA2u
|
// #define LEVEL1_KEY 0xB342u
|
|
// #define LEVEL2_SEED 0x0CA2u
|
// #define LEVEL2_KEY 0xB342u
|
|
#define SEED_SIZE sizeof(uint32_t)
|
#define KEY_SIZE sizeof(uint32_t)
|
|
#define LEVEL1_MASK 0x521025a0u
|
#define LEVEL2_MASK 0x2035446au
|
|
#define LEVEL1_SEED 0x11223344u
|
#define LEVEL1_KEY 0x20AA097Bu
|
|
#define LEVEL2_SEED 0x11223344u
|
#define LEVEL2_KEY 0x70237577u
|
|
#endif
|
|
#define REQUEST_DOWNLOAD_MSG_SIZE (0x0B)
|
#define DOWNLOAD_RAM ((uint8_t)0x10u)
|
#define DOWNLOAD_FLASH ((uint8_t)0x40u)
|
|
/*****************************************************************************/
|
/* Global Variable Declaration */
|
/*****************************************************************************/
|
static uint32_t eraseAddress; /* Actual transfer address */
|
static uint32_t eraseRemainder; /* Number of remaining transfer bytes */
|
static UDS_RESP_PENDING_Te UDS_L_ResponsePendingRequest_e;
|
static UDS_RESP_PENDING_Te UDS_L_ResponsePendingRelease_e;
|
|
static SECURITY_ACCESS_STATE_e UDS_O_SecurityAccessState_e = SECURITY_ACCESS_LOCKED;
|
static bool UDS_L_ProgrammingPreconditionCheckOK_b = true;
|
static UDS_CONTOL_TYPE_e UDS_L_CommunicationControlType_e = EnableRxAndTx;
|
|
static uint8_t UDS_L_SecurityFault_cnt;
|
static uint8_t UDS_L_SecurityStartDelay = 0;
|
static uint8_t UDS_L_SecurityAccessStep_e = SECURITY_ACCESS_STEP_MAX;
|
/*****************************************************************************/
|
/* Local Variables Definition */
|
/*****************************************************************************/
|
static uint8_t UDS_L_SupplyVoltage = 120u;
|
static uint16_t UDS_L_VehicleSpeed = 0u;
|
/* Timer value to keep the session in extended session */
|
static uint16_t TesterPresentTimer_u16;
|
|
/* Current diagnostic session */
|
static UDS_SESSIONS_e UDS_L_Diag_session_e;
|
/* Read data stream request received */
|
static uint16_t SecurityAcessTimer_u16;
|
static uint16_t UDS_NS_SessionTimeout_u16;
|
|
/* CANTP buffer */
|
static uint8_t UDS_L_rx_buffer[CANTP_RX_BUFFER_SIZE];
|
static uint8_t UDS_L_tx_buffer[CANTP_TX_BUFFER_SIZE];
|
|
/* Message buffer */
|
static uint8_t UDS_L_rx_msg_buffer[CANTP_RX_BUFFER_SIZE];
|
static uint16_t UDS_L_rx_msg_size;
|
static uint8_t UDS_L_tx_msg_buffer[CANTP_TX_BUFFER_SIZE];
|
static uint16_t UDS_L_tx_msg_size;
|
|
/* CANTP Stack */
|
static CANTP_Stack_t UDS_L_tp_stack;
|
|
/* static uint16_t UDS_L_ReadDidSetSize_u16 = 0U; */
|
static Read_DID_set_t UDS_L_ReadDIDSet_t;
|
|
/* Current processing request SID */
|
static uint8_t UDS_L_Current_SID __attribute__((__unused__));
|
static uint16_t ResponsePendingTimer_u16;
|
static bool UDS_L_TransferDataInProgressing_b = false;
|
static bool UDS_L_CRCCheckFail_b = false;
|
static uint32_t UDS_L_CRCReceived = 0;
|
static UDS_TRANFER_DATA_STATE_Te UDS_L_TransferDataState_e;
|
|
static uint8_t expectedSequenceCnt; /* Block sequence counter */
|
static uint8_t currentSequenceCnt; /* Current Block sequence counter */
|
static FBL_ADDR_TYPE transferAddress; /* Actual transfer address */
|
static FBL_MEMSIZE_TYPE transferRemainder; /* Number of remaining transfer bytes */
|
static uint8_t transferType; /* Download into RAM/Flash or upload */
|
static uint8_t currentbuffId; /* Download into RAM/Flash or upload */
|
static FBL_ADDR_TYPE eraseAddress; /* Actual transfer address */
|
static FBL_MEMSIZE_TYPE eraseRemainder; /* Number of remaining transfer bytes */
|
|
static FBL_ADDR_TYPE DownloadAddress; /* Actual transfer address */
|
static FBL_MEMSIZE_TYPE DownloadLength; /* Number of remaining transfer bytes */
|
|
/*****************************************************************************/
|
/* Local Function Prototypes */
|
/*****************************************************************************/
|
static void UDS_UpdateVehicleStatus(void);
|
/* Read data by DID */
|
static void UDS_ReadData(uint8_t *payload);
|
/* Write data by DID */
|
static void UDS_WriteDataByIdentifier(uint8_t *payload);
|
static void UDS_WriteF1DIDdata(uint8_t *p_src, uint16_t DID_TableIndex) __attribute__((__unused__));
|
/*0x11 service*/
|
static void UDS_ECURest(uint8_t *payload);
|
/*0x31 service*/
|
static void UDS_RoutineControl(uint8_t *payload);
|
/* Tester present(SID:3E) message handling */
|
static void UDS_TesterPresent(uint8_t *payload);
|
/* Diagnostic session control */
|
static void UDS_SessionControl(uint8_t *payload);
|
/* Extended session timer handling */
|
static void UDS_SessionTiming(void);
|
/*security Access fault timer*/
|
static void UDS_SecurityAccessTiming(void);
|
/*calibration respons wait calibration finsh command*/
|
static void UDS_CalibrationResp(void);
|
|
/* Dispatcher when a CAN message is received */
|
/* static void UDS_MsgDispatch(void); */
|
/* Compose and send negative response */
|
static void UDS_SendNegResp(NEGA_RESP_Code_e reason);
|
/* Flip endianness of memory locations based on the size */
|
static void UDS_FlipEndian(void *address, uint16_t size);
|
/* Compose and send out the requested DID data */
|
static void UDS_SendDidData(void);
|
/* Build DID data set */
|
static bool UDS_BuildDidSet(uint8_t *payload);
|
/* Switch to default session */
|
static void UDS_SwitchtoDefaultSession(uint8_t resetcmd);
|
/*Security access*/
|
|
static void UDS_ControlDTCSetting(uint8_t *payload);
|
static void UDS_CommunicationControl(uint8_t *payload);
|
static void UDS_ReadDTCInformation(uint8_t *payload);
|
static void UDS_ReportDTCNumByStatusMask(uint8_t *payload);
|
static void UDS_ReportDTCByStatusMask(uint8_t *payload);
|
static void UDS_ReportSupportedDTCs(uint8_t *payload);
|
static void UDS_ClearDTCInformation(uint8_t *payload);
|
static void UDS_IOControlByIdentifierg(uint8_t *payload);
|
#if 0
|
static void CANTP_zeroRestOfFrame(TP_PDU_t *msg);
|
#endif
|
static void UDS_RespTxMessage(void);
|
static void UDS_SecurityAccess(uint8_t *payload);
|
static void UDS_CheckProgrammingIntergrity(uint8_t *payload);
|
static void UDS_CheckProgrammingDependence(uint8_t *payload);
|
static void UDS_CheckProgrammingPrecondition(void);
|
static void UDS_EraseMemory(uint8_t *payload);
|
static void UDS_HardwareReset(void) __attribute__((__unused__));
|
static void UDS_SoftwareReset(void) __attribute__((__unused__));
|
static void UDS_RequestDownload(uint8_t *payload) __attribute__((__unused__));
|
static void UDS_TransferData(uint8_t *payload) __attribute__((__unused__));
|
static void UDS_RequestTransferExit(uint8_t *payload) __attribute__((__unused__));
|
static uint8_t UDS_SendF1DIDdata(uint8_t *Copy_position, uint16_t DID_idx);
|
static void UDS_StringCopy(char *p_src, char *p_dest, uint8_t max_size);
|
static void UDS_ResponseTiming(void);
|
|
/*
|
static void UDS_SetEraseResult(uint8_t mem_operation_type, uint8_t partition, int8_t success);
|
static void UDS_SetWriteResult(uint8_t mem_operation_type, uint8_t partition, int8_t success);
|
static void UDS_SetCRCCheckResult(uint8_t mem_peration_type, uint8_t partition, int8_t success);
|
*/
|
|
/************************ new add ************************/
|
#define SESSION_CONTROL_MIN_LEN (0x02u)
|
#define ECU_RESET_MIN_LEN (0x02u)
|
#define CLEAR_DIAGNOSTIC_INFORMATION_MIN_LEN (0x04u) /* 3 Bytes DTC */
|
#define READ_DTC_INFORMATION_MIN_LEN (0x02u)
|
#define READ_DATA_BY_IDENTIFIER_MIN_LEN (0x03u)
|
#define SECURITY_ACCESS_MIN_LEN (0x02u)
|
#define COMMUNICATION_CONTROL_MIN_LEN (0x03u)
|
#define WRITE_DATA_BY_IDENTIFIER_MIN_LEN (0x04u)
|
#define ROUTINE_CONTROL_MIN_LEN (0x04u)
|
#define TESTER_PRESENT_MIN_LEN (0x02u)
|
#define CONTROL_DTC_SETTING_MIN_LEN (0x02u)
|
#define REQUEST_DOWNLOAD_MIN_LEN (0xB)
|
#define TRANSFER_DATA_MIN_LEN (0XC)
|
#define REQUEST_TRANSFER_EXIT_MIN_LEN (0X01)
|
|
typedef struct
|
{
|
uint8_t uds_sid;
|
/* uint8_t uds_min_len; */
|
// void (*uds_service)(uint8_t msg_buf[]);
|
void (*uds_service)(uint8_t *payload);
|
bool std_spt; /* default session support */
|
bool ext_spt; /* extended session support */
|
bool fun_spt; /* function address support */
|
bool ssp_spt; /* subfunction suppress PosRsp bit support */
|
SECURITY_ACCESS_STATE_e uds_sa; /* security access */
|
} uds_service_t;
|
|
/* clang-format off */
|
static const uds_service_t uds_service_list[] = {
|
// service id function default extend fun_add ssp_spt SECURITY LEVEL
|
{SESSION_CONTROL, UDS_SessionControl, true, true, false, true, SECURITY_ACCESS_LOCKED},
|
{ECU_RESET, UDS_ECURest, false, true, false, true, SECURITY_ACCESS_LOCKED},
|
{READ_DATA_BY_IDENTIFIER, UDS_ReadData, true, true, false, false, SECURITY_ACCESS_LOCKED},
|
{SECURITY_ACCESS, UDS_SecurityAccess, false, true, false, false, SECURITY_ACCESS_LOCKED},
|
// {COMMUNICATION_CONTROL, UDS_CommunicationControl, false, true, true, true, SECURITY_ACCESS_LOCKED},
|
{WRITE_DATA_BY_IDENTIFIER, UDS_WriteDataByIdentifier, false, true, false, false, SECURITY_ACCESS_UNLOCK_LEVEL_1},
|
{ROUTINE_CONTROL, UDS_RoutineControl, false, true, false, false, SECURITY_ACCESS_UNLOCK_LEVEL_2},
|
{TESTER_PRESENT, UDS_TesterPresent, true, true, true, true, SECURITY_ACCESS_LOCKED},
|
// {CONTROL_DTC_SETTING, UDS_ControlDTCSetting, false, true, false, true, SECURITY_ACCESS_LOCKED},
|
{REQUEST_DOWNLOAD, UDS_RequestDownload, false, true, false, true, SECURITY_ACCESS_UNLOCK_LEVEL_2},
|
{TRANSFER_DATA, UDS_TransferData, false, true, false, true, SECURITY_ACCESS_UNLOCK_LEVEL_2},
|
{REQUEST_TRANSFER_EXIT, UDS_RequestTransferExit, false, true, false, true, SECURITY_ACCESS_UNLOCK_LEVEL_2},
|
|
};
|
/* clang-format on */
|
|
#define UDS_SERVICE_NUM (sizeof(uds_service_list) / sizeof(uds_service_list[0]))
|
|
typedef enum
|
{
|
/* net target address type ÍøÂçÄ¿µÄµØÖ·ÀàÐÍ */
|
N_TATYPE_NONE = 0,
|
N_TATYPE_PHYSICAL, /* ÎïÀíѰַ */
|
N_TATYPE_FUNCTIONAL /* ¹¦ÄÜѰַ */
|
} n_tatype_t;
|
|
#define REPORT_DTC_NUMBER_BY_STATUS_MASK (0x01)
|
#define REPORT_DTC_BY_STATUS_MASK (0x02)
|
#define REPORT_DTC_SNOPSHOT_BY_DTC_NUMBER (0x04)
|
#define REPORT_DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER (0x06)
|
#define REPORT_SUPPORTED_DTC (0x0a)
|
|
#define UDS_REQUEST_SEED (0x01)
|
#define UDS_SEND_KEY (0x02)
|
|
/* »ñÈ¡ÒÖÖÆÕýÏìÓ¦±êʶλ =0²»ÒÖÖÆ =1ÒÖÖÆ */
|
#define UDS_GET_SUB_FUNCTION_SUPPRESS_POSRSP(byte) (((byte) >> 7u) & 0x01u)
|
/* »ñÈ¡×Ó¹¦ÄÜ */
|
#define UDS_GET_SUB_FUNCTION(byte) ((byte)&0x7fu)
|
|
/* Õý·´À¡ÒÖÖÆ±êʶλ =true ²»·¢ËÍÕýÏìÓ¦ =false ·¢ËÍÕýÏìÓ¦ */
|
static bool ssp_flg;
|
|
static bool uds_check_len(uint8_t msg_buf[], uint16_t msg_dlc)
|
{
|
bool result;
|
uint8_t subfunction;
|
uint8_t sid;
|
sid = msg_buf[0];
|
|
subfunction = UDS_GET_SUB_FUNCTION(msg_buf[1]);
|
|
switch (sid)
|
{
|
case SESSION_CONTROL:
|
{
|
if (msg_dlc == SESSION_CONTROL_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
}
|
break;
|
case ECU_RESET:
|
{
|
if (msg_dlc == ECU_RESET_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
}
|
break;
|
case CLEAR_DIAGNOSTIC_INFORMATION:
|
{
|
if (msg_dlc == CLEAR_DIAGNOSTIC_INFORMATION_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
}
|
break;
|
case READ_DTC_INFORMATION:
|
{
|
if ((subfunction == REPORT_DTC_NUMBER_BY_STATUS_MASK && msg_dlc != (READ_DTC_INFORMATION_MIN_LEN + 1)) ||
|
(subfunction == REPORT_DTC_BY_STATUS_MASK && msg_dlc != (READ_DTC_INFORMATION_MIN_LEN + 1)) ||
|
(subfunction == REPORT_SUPPORTED_DTC && msg_dlc != READ_DTC_INFORMATION_MIN_LEN))
|
{
|
result = false;
|
}
|
else
|
{
|
result = true;
|
}
|
}
|
break;
|
case READ_DATA_BY_IDENTIFIER:
|
{
|
if (msg_dlc == READ_DATA_BY_IDENTIFIER_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
}
|
break;
|
case SECURITY_ACCESS:
|
{
|
if ((subfunction == UDS_REQUEST_SEED && msg_dlc != SECURITY_ACCESS_MIN_LEN) ||
|
(subfunction == UDS_SEND_KEY && msg_dlc != (SECURITY_ACCESS_MIN_LEN + KEY_SIZE)))
|
{
|
result = false;
|
}
|
else
|
{
|
result = true;
|
}
|
}
|
break;
|
case COMMUNICATION_CONTROL:
|
{
|
if (msg_dlc == COMMUNICATION_CONTROL_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
}
|
break;
|
case WRITE_DATA_BY_IDENTIFIER:
|
{
|
if (msg_dlc >= WRITE_DATA_BY_IDENTIFIER_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
}
|
break;
|
case ROUTINE_CONTROL:
|
if (msg_dlc >= ROUTINE_CONTROL_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
break;
|
case TESTER_PRESENT:
|
{
|
if (msg_dlc == TESTER_PRESENT_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
}
|
break;
|
case CONTROL_DTC_SETTING:
|
{
|
if (msg_dlc == CONTROL_DTC_SETTING_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
}
|
break;
|
case REQUEST_DOWNLOAD:
|
if (msg_dlc == REQUEST_DOWNLOAD_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
break;
|
case TRANSFER_DATA:
|
if (msg_dlc >= TRANSFER_DATA_MIN_LEN)
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
break;
|
case REQUEST_TRANSFER_EXIT:
|
result = true;
|
|
break;
|
default:
|
result = false;
|
break;
|
}
|
return result;
|
}
|
|
static void uds_data_indication(uint8_t msg_buf[], uint16_t msg_dlc, uint8_t ta_type)
|
{
|
/* uint8_t *payload = UDS_L_rx_msg_buffer; */
|
/* On any request, reset the S3 timer if current session is extended */
|
/* session */
|
if ((UDS_L_Diag_session_e == EXTENDED) || (UDS_L_Diag_session_e == PROGRAMMING))
|
{
|
/* Reset the tester present waiting timer. If current session is */
|
/* extended session */
|
CDT_RESET(TesterPresentTimer_u16,
|
UDS_NS_SessionTimeout_u16 / UDS_TASK_RATE);
|
}
|
|
uint8_t i;
|
uint8_t sid;
|
uint8_t ssp;
|
bool find_sid;
|
bool session_spt;
|
|
sid = msg_buf[0];
|
UDS_L_Current_SID = sid;
|
ssp = UDS_GET_SUB_FUNCTION_SUPPRESS_POSRSP(msg_buf[1]);
|
find_sid = false;
|
for (i = 0; i < UDS_SERVICE_NUM; i++)
|
{
|
if (sid == uds_service_list[i].uds_sid)
|
{
|
/* UDS_L_Diag_session_e = EXTENDED; */
|
if (UDS_L_Diag_session_e == DEFAULT)
|
{
|
session_spt = uds_service_list[i].std_spt;
|
}
|
else
|
{
|
session_spt = uds_service_list[i].ext_spt;
|
}
|
|
if (session_spt == true)
|
{
|
if (ta_type == N_TATYPE_FUNCTIONAL && uds_service_list[i].fun_spt == false)
|
{ /* ¹¦ÄÜѰַÇҸ÷þÎñ²»Ö§³Ö¹¦ÄÜѰַ */
|
/* uds_no_response(); */
|
}
|
else
|
{
|
if (uds_check_len(msg_buf, msg_dlc))
|
{
|
if (UDS_O_SecurityAccessState_e >= uds_service_list[i].uds_sa)
|
{
|
if (uds_service_list[i].ssp_spt == true && ssp == 0x01)
|
{
|
ssp_flg = true;
|
}
|
else
|
{
|
ssp_flg = false;
|
}
|
uds_service_list[i].uds_service(msg_buf);
|
}
|
else
|
{
|
/* uds_negative_rsp(sid, NRC_SECURITY_ACCESS_DENIED); */
|
UDS_SendNegResp(NRC_SECURITY_ACCESS_DENIED);
|
}
|
}
|
else
|
{
|
/* uds_negative_rsp(sid, NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT); */
|
UDS_SendNegResp(NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT);
|
}
|
}
|
}
|
else
|
{
|
/* uds_negative_rsp(sid, NRC_SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION); */
|
UDS_SendNegResp(NRC_SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION);
|
}
|
find_sid = true;
|
break;
|
}
|
}
|
|
if (find_sid == false)
|
{
|
/* uds_negative_rsp(sid, NRC_SERVICE_NOT_SUPPORTED); */
|
UDS_SendNegResp(NRC_SERVICE_NOT_SUPPORTED);
|
}
|
}
|
|
/*********************** new add end ***********************/
|
|
/***************************************************
|
* Extern Function Definition Starts Here
|
***************************************************/
|
/* extern void UDS_GetCommunicationControlType(unsigned char *type);
|
extern void UDS_RxFunIdMessage(TP_PDU_t *msg); */
|
/*****************************************************************************/
|
/* NAME : extern void UDS_Init(void) */
|
/* */
|
/* DESCRIPTION : */
|
/* Initialization function for FACT module */
|
/* INPUTS : */
|
/* None */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* [1] Initialize the variables */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 06/16/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/* (2) Date: 08/16/2014 Fogbugz: case#: 1766 */
|
/* Add version registration by Tom Tao */
|
/*****************************************************************************/
|
extern void UDS_Init(void)
|
{
|
/* uint8_t i; */
|
/* Tester present timer */
|
CDT_RESET(SecurityAcessTimer_u16,
|
SECURITY_ACCESS_WAIT_TIME); // power on wait 10s
|
TesterPresentTimer_u16 = 0;
|
UDS_NS_SessionTimeout_u16 = 5000;
|
UDS_L_SecurityFault_cnt = 0;
|
UDS_L_SecurityStartDelay = 0;
|
UDS_L_Diag_session_e = DEFAULT;
|
UDS_O_SecurityAccessState_e = SECURITY_ACCESS_LOCKED;
|
UDS_L_Current_SID = 0;
|
UDS_L_ProgrammingPreconditionCheckOK_b = true;
|
UDS_L_TransferDataState_e = TRANFER_IDLE;
|
UDS_L_CRCCheckFail_b = false;
|
UDS_L_ResponsePendingRequest_e = RESP_PENDING_MAX;
|
UDS_L_ResponsePendingRelease_e = RESP_PENDING_MAX;
|
|
UDS_L_TransferDataInProgressing_b = false;
|
UDS_L_ReadDIDSet_t.DID_Table_Index = 0;
|
UDS_L_ReadDIDSet_t.DID_Value = 0;
|
|
/* Initialize CANTP stack with FACT CAN buffer */
|
CANTP_Init(&UDS_L_tp_stack,
|
UDS_L_rx_buffer,
|
CANTP_RX_BUFFER_SIZE,
|
UDS_L_tx_buffer,
|
CANTP_TX_BUFFER_SIZE);
|
|
CANTP_InitIds(&UDS_L_tp_stack,
|
0, /* CAN channel 0 */
|
UDS_PHY_REQ_RID, /* phy req id*/
|
UDS_RESP_TID, /* phy resp id*/
|
UDS_FUN_REQ_RID); /* fun req id*/
|
|
UDS_InitDIDMapRO(DID_NS_ActiveDiagSession, &UDS_L_Diag_session_e, 1);
|
}
|
|
/*****************************************************************************/
|
/* NAME : extern void UDS_Task_10ms(void) */
|
/* */
|
/* DESCRIPTION : */
|
/* Factory diagnosis task called in every 10ms */
|
/* INPUTS : */
|
/* None */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* [1] Call routine function in FACT module */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 06/16/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
extern void UDS_Task_10ms(void *p)
|
{
|
UDS_SessionTiming();
|
UDS_SecurityAccessTiming();
|
UDS_ResponseTiming();
|
}
|
|
static void UDS_RxTask_1ms(void)
|
{
|
static TP_PDU_t msg_rx_temp = {0};
|
CAN_PDU_t msg_can_temp = {0};
|
uint8_t msg_num = MCAN_GetReceiveMessageCounter(MCAN);
|
while (msg_num--)
|
{
|
MCAN_ReceiveData(MCAN, (MCAN_MsgTypeDef *)(&msg_can_temp));
|
|
msg_rx_temp.arbId = msg_can_temp.MCAN_ID;
|
msg_rx_temp.dlc = msg_can_temp.MCAN_DLC;
|
|
for (TP_uint8_t i = 0; i < msg_can_temp.MCAN_DLC; i++)
|
{
|
msg_rx_temp.frame[i] = msg_can_temp.MCAN_Data[i];
|
}
|
|
if (msg_rx_temp.arbId == UDS_PHY_REQ_RID)
|
{
|
UDS_RxMessage(&msg_rx_temp);
|
}
|
else
|
{
|
UDS_RxFunIdMessage(&msg_rx_temp);
|
}
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : extern void UDS_Task_1ms(void) */
|
/* */
|
/* DESCRIPTION : */
|
/* Factory diagnosis task called in every 1ms */
|
/* INPUTS : */
|
/* None */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* [1] Call routine function in FACT module */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 06/30/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
extern void UDS_Task_1ms(void *p)
|
{
|
/* Call tp task first to free up buffer */
|
CANTP_Task_1ms(&UDS_L_tp_stack);
|
UDS_RxTask_1ms();
|
|
/*
|
* This block of stuff controls whether the NVM is allowed to write data or
|
* not. This was added to allow the tester to shut off writes to dynamic
|
* NVM areas (in case during manufacturing there is a situation where
|
* DTCs are being constantly cleared / written for example). Stopping the
|
* writes will allow the current NVM writes to finish but further write
|
* attempts will be blocked. This has to happen from 1msec task for the
|
* following reasons:
|
* 1. If it is not in same timeslice as the request, there will be a window
|
* where the actual state does not match the data being returned to the
|
* tester. This could mean that the local RAM data indicates the NVM is
|
* not dirty, but if you're only updating the 'dirty' state every 20msec
|
* another app could have requested a write in previous 19 of the 20 msec,
|
* meaning we could return 'not busy' while a write was actually pending.
|
* 2. The factory DIDs don't wind up triggering callbacks, they are linked
|
* to data. It would be better if we worked like Vector and ran a callback
|
* instead of just returning data, so that we could (on receiving a particular
|
* DID) make the call into NVM directly and not through a timed task.
|
*/
|
}
|
|
/********************************************************* UDS_RxMessage() ************
|
* Each call is responsible for updating the rsp_data_size and rsp_data[] buffer if
|
* they do not want the standard ACK.
|
***************************************************************************************/
|
extern void UDS_RxMessage(TP_PDU_t *msg)
|
{
|
bool Msg_Recv_Comp_b;
|
uint8_t *Rcv_Buffer_Ptr = UDS_L_rx_msg_buffer;
|
|
/* Process the message with CANTP function */
|
CANTP_RxFrame(&UDS_L_tp_stack, msg);
|
|
/* Check if a message has been received completely */
|
Msg_Recv_Comp_b = CANTP_IsRxComplete(&UDS_L_tp_stack,
|
&Rcv_Buffer_Ptr, &UDS_L_rx_msg_size);
|
|
if (Msg_Recv_Comp_b != false)
|
{
|
/*cantp rx buff to UDS_L_rx_msg_buffer*/
|
memcpy(UDS_L_rx_msg_buffer, Rcv_Buffer_Ptr, UDS_L_rx_msg_size);
|
/* Call Message dispatcher */
|
/* UDS_MsgDispatch(); */
|
uds_data_indication(UDS_L_rx_msg_buffer, UDS_L_rx_msg_size, N_TATYPE_PHYSICAL);
|
}
|
}
|
extern void UDS_RxFunIdMessage(TP_PDU_t *msg)
|
{
|
uint8_t *Rcv_Buffer_Ptr = msg->frame;
|
/*as Single Frame*/
|
if ((msg->frame[1] == TESTER_PRESENT)) // only support 3E
|
{
|
UDS_L_rx_msg_size = (Rcv_Buffer_Ptr[0] & 0x0f);
|
/*cantp rx buff to UDS_L_rx_msg_buffer*/
|
memcpy(UDS_L_rx_msg_buffer, &Rcv_Buffer_Ptr[1], UDS_L_rx_msg_size);
|
/* Call Message dispatcher */
|
/* UDS_MsgDispatch(); */
|
uds_data_indication(UDS_L_rx_msg_buffer, UDS_L_rx_msg_size, N_TATYPE_FUNCTIONAL);
|
}
|
}
|
|
#if 1 /* ²ð·Ö */
|
/**
|
* @brief
|
*
|
* @param DIDitem
|
* @param nvBlockID
|
* @param address
|
* @param size
|
*/
|
extern void UDS_InitDIDMapRW(UDS_DIDList_e DIDitem, uint16_t nvBlockID, void *address, uint16_t size)
|
{
|
uint16_t i;
|
|
/* Make sure DID table still has space. If current DID table
|
* size is already larger than specified, do not update DID table */
|
if (DIDTable_Entry_Count_u16 >= UDS_DID_TABLE_SIZE)
|
{
|
return;
|
}
|
|
/* Look for existing table item with the same DID */
|
for (i = 0; i < DIDTable_Entry_Count_u16; i++)
|
{
|
if (DIDtable[i].DidEnum == DIDitem)
|
{
|
return;
|
}
|
}
|
|
/* If there is no such DID, add the new DID into the table */
|
if ((i == DIDTable_Entry_Count_u16) &&
|
(DIDTable_Entry_Count_u16 < UDS_DID_TABLE_SIZE))
|
{
|
|
/* Assign enumeration, address, size to the table */
|
DIDtable[DIDTable_Entry_Count_u16].DidEnum = DIDitem;
|
DIDtable[DIDTable_Entry_Count_u16].nvBlockID = nvBlockID;
|
DIDtable[DIDTable_Entry_Count_u16].address = address;
|
DIDtable[DIDTable_Entry_Count_u16].size = size;
|
DIDtable[DIDTable_Entry_Count_u16].access = READWRITE;
|
|
/* Calculate CRC */
|
/* DIDtable[DIDTable_Entry_Count_u16].crc = CRC16_Calc(&address, size); */
|
DIDTable_Entry_Count_u16++;
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : extern void UDS_InitDIDMap(UDS_DIDList_e DIDitem, */
|
/* const void *address, uint16_t size) */
|
/* */
|
/* DESCRIPTION : */
|
/* Function to be called by individual tasks to establish connection*/
|
/* between the variables to read and the enumeration */
|
/* INPUTS : */
|
/* enum DidEnum : enumeration value of DID items */
|
/* uint16_t address: DID item address */
|
/* uint16_t size : DID item size */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* [1] Add DID table items */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 08/13/2014 Fogbugz: case#: 1791 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
extern void UDS_InitDIDMapRO(UDS_DIDList_e DIDitem, const void *address,
|
uint16_t size)
|
{
|
uint16_t i;
|
|
/* Make sure DID table still has space. If current DID table
|
* size is already larger than specified, do not update DID table */
|
if (DIDTable_Entry_Count_u16 >= UDS_DID_TABLE_SIZE)
|
{
|
return;
|
}
|
|
/* Look for existing table item with the same DID */
|
for (i = 0; i < DIDTable_Entry_Count_u16; i++)
|
{
|
if (DIDtable[i].DidEnum == DIDitem)
|
{
|
return;
|
}
|
}
|
|
/* If there is no such DID, add the new DID into the table */
|
if ((i == DIDTable_Entry_Count_u16) &&
|
(DIDTable_Entry_Count_u16 < UDS_DID_TABLE_SIZE))
|
{
|
|
/* Assign enumeration, address, size to the table */
|
DIDtable[DIDTable_Entry_Count_u16].DidEnum = DIDitem;
|
DIDtable[DIDTable_Entry_Count_u16].nvBlockID = 0xFF;
|
DIDtable[DIDTable_Entry_Count_u16].address = (void *)address;
|
DIDtable[DIDTable_Entry_Count_u16].size = size;
|
DIDtable[DIDTable_Entry_Count_u16].access = READONLY;
|
|
/* Calculate CRC */
|
/* DIDtable[DIDTable_Entry_Count_u16].crc = CRC16_Calc((void *)&address, size); */
|
DIDTable_Entry_Count_u16++;
|
}
|
}
|
#endif
|
|
extern void UDS_SwitchtoProgrammingSession(void)
|
{
|
UDS_L_Diag_session_e = PROGRAMMING;
|
CDT_RESET(TesterPresentTimer_u16,
|
UDS_NS_SessionTimeout_u16 / UDS_TASK_RATE);
|
}
|
|
extern void UDS_ResponseEntryProgrammingSession(void)
|
{
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(SESSION_CONTROL);
|
UDS_L_tx_msg_buffer[1] = UDS_L_Diag_session_e;
|
UDS_L_tx_msg_buffer[2] = 0x00;
|
UDS_L_tx_msg_buffer[3] = 0x01;
|
UDS_L_tx_msg_buffer[4] = 0;
|
UDS_L_tx_msg_buffer[5] = 0;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x06;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
/*****************************************************************************/
|
/* Local Function definitions */
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_SessionTiming(void) */
|
/* */
|
/* DESCRIPTION : */
|
/* Decrease the session timer if it's not expired, if the timer */
|
/* expires, set the session back to default session */
|
/* INPUTS : */
|
/* None */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* [1] Add DID table items */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 06/16/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_SessionTiming(void)
|
{
|
/* Decrease tester present waiting timer, if timer expired, set Factory
|
* diag session to default session */
|
if (UDS_L_Diag_session_e != DEFAULT)
|
{
|
/* CDT_RESET(EntrySleepModeTimer_u16,ENTRY_SLEEP_MODE_TIMEOU); */
|
if (CDT_HASEXPIRED(TesterPresentTimer_u16) == false)
|
{
|
|
CDT_EXPIRED(TesterPresentTimer_u16);
|
|
if (CDT_HASEXPIRED(TesterPresentTimer_u16) != false)
|
{
|
UDS_SwitchtoDefaultSession(false);
|
}
|
}
|
else
|
{
|
UDS_SwitchtoDefaultSession(false);
|
}
|
}
|
else
|
{
|
CDT_RESET(TesterPresentTimer_u16, 0);
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_SecurityAccessTiming(void) */
|
/* */
|
/* DESCRIPTION : */
|
/* Decrease the security Access timer if it's not expired, if the timer */
|
/* expires, set the UDS_SecurityFault_cnt-- */
|
/* INPUTS : */
|
/* None */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* [1] */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 08/10/2017 Fogbugz: case#: */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_SecurityAccessTiming(void)
|
{
|
if ((UDS_L_SecurityFault_cnt != 0) || (UDS_L_SecurityStartDelay == 1))
|
{
|
if (CDT_EXPIRED(SecurityAcessTimer_u16) == true)
|
{
|
UDS_L_SecurityFault_cnt--;
|
UDS_L_SecurityStartDelay = 0;
|
}
|
else
|
{
|
}
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_ReadData(uint8_t * payload) */
|
/* */
|
/* DESCRIPTION : */
|
/* This function reads the data by enumeration value and place the */
|
/* result in the transmit buffer to send out response */
|
/* INPUTS : */
|
/* uint8_t * payload: pointer to the payload starting address */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* Read data by identifier */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 06/16/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_ReadData(uint8_t *payload)
|
{
|
bool DIDnotFound = false;
|
|
/* Build up the DID set while set the flag for DID found */
|
DIDnotFound = UDS_BuildDidSet(payload);
|
|
/* DIDnotFound == false means all requested DID have been found in */
|
/* DID table, thus their indexes have been stored in */
|
/* UDS_L_ReadDIDSet_t[x].DID_Table_Index */
|
if (DIDnotFound == false)
|
{
|
|
/* Compose a tx message to send out all requested DID data */
|
UDS_SendDidData();
|
}
|
else
|
{
|
/* A requested DID item cannot be found in the DID table. */
|
/* All current data should be abandoned */
|
memset(UDS_L_tx_msg_buffer, 0, CANTP_TX_BUFFER_SIZE);
|
/* Send a negative response */
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_WriteDataByIdentifier(uint8_t * payload) */
|
/* */
|
/* DESCRIPTION : */
|
/* This function writes the data passed by user to the data item */
|
/* specified by DID value */
|
/* INPUTS : */
|
/* uint8_t * payload: pointer to the payload starting address */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* Write data by identifier */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 06/16/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_WriteDataByIdentifier(uint8_t *payload)
|
{
|
uint16_t i;
|
uint16_t DID_u16;
|
uint16_t Index_to_be_written;
|
|
if ((UDS_L_Diag_session_e == DEFAULT) || ((UDS_O_SecurityAccessState_e != SECURITY_ACCESS_UNLOCK_LEVEL_1) && (UDS_O_SecurityAccessState_e != SECURITY_ACCESS_UNLOCK_LEVEL_2)))
|
{
|
/* Send a negative response.*/
|
UDS_SendNegResp(NRC_SECURITY_ACCESS_DENIED);
|
return;
|
}
|
/* 2nd and 3rd byte specifies the DID */
|
DID_u16 = payload[1] << 8 | payload[2];
|
|
for (i = 0; i < DIDTable_Entry_Count_u16; i++)
|
{
|
if (DIDtable[i].DidEnum == DID_u16)
|
{
|
/* Record index i */
|
Index_to_be_written = i;
|
break; /* DID data found, stop the search */
|
}
|
else
|
{
|
/* Otherwise, keep on looking */
|
}
|
}
|
|
/* i == DIDTable_Entry_Count_u16 means no data with the DID is found */
|
if (i == DIDTable_Entry_Count_u16)
|
{
|
/* Send out negative response */
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
}
|
else if (DIDtable[Index_to_be_written].access == READONLY)
|
{
|
|
/* Send out negative response */
|
UDS_SendNegResp(NRC_CONDITIONS_NOT_CORRECT);
|
}
|
else
|
{
|
|
/* Check the total received message size should be equal to */
|
/* SID+DID+DataSize */
|
if (UDS_L_rx_msg_size != (DIDtable[Index_to_be_written].size + SIZE_OF_SID_DID))
|
{
|
/* Send out negative response */
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
}
|
else
|
{
|
/* UDS_WriteF1DIDdata(&payload[3], Index_to_be_written); */
|
memcpy(DIDtable[Index_to_be_written].address, &payload[3],
|
DIDtable[Index_to_be_written].size);
|
|
/* Write the change to NVM */
|
if (DIDtable[Index_to_be_written].nvBlockID != 0xFF)
|
{
|
DID_SetWriteSaveFlag();
|
}
|
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(WRITE_DATA_BY_IDENTIFIER);
|
UDS_L_tx_msg_buffer[1] = payload[1];
|
UDS_L_tx_msg_buffer[2] = payload[2];
|
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 3;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
}
|
}
|
|
static uint8_t UDS_SendF1DIDdata(uint8_t *Copy_position, uint16_t DID_idx)
|
{
|
#if 1
|
uint8_t rtn_length = 0;
|
char *ptr_src = NULL;
|
uint16_t F1DID = 0;
|
uint8_t length = 0;
|
F1DID = (uint16_t)(DIDtable[DID_idx].DidEnum & 0x0000FFFFu);
|
ptr_src = DIDtable[DID_idx].address;
|
length = DIDtable[DID_idx].size;
|
|
UDS_FlipEndian(&(F1DID), sizeof(F1DID));
|
/* Copy requested DID into transmission buffer */
|
memcpy(Copy_position, &(F1DID), sizeof(F1DID));
|
Copy_position = Copy_position + sizeof(F1DID);
|
rtn_length += 2;
|
|
switch (((uint16_t)(DIDtable[DID_idx].DidEnum & 0x0000FFFFu)))
|
{
|
// case DID_UDS_NS_VINDataIdentifier: /*0xF190*/
|
// case DID_UDS_NS_DUNSIdentification:
|
// case DID_UDS_NS_MTC:
|
// case DID_UDS_NS_ManufacturersModeFlag:
|
// case DID_UDS_NS_ECUPartNumber:
|
// case DID_UDS_NS_SupplierECUSoftwareVersionNumber:
|
// UDS_StringCopy(ptr_src, (char *)Copy_position, length);
|
// break;
|
// case DID_UDS_NS_BaseModelPartNumber:
|
// case DID_UDS_NS_EndModelPartNumber:
|
// memcpy(Copy_position, ptr_src, 4);
|
// UDS_FlipEndian(Copy_position, 4);
|
// break;
|
// case DID_UDS_NS_BaseModelPartNumberVersionCode:
|
// case DID_UDS_NS_EndModelPartNumberVersionCode:
|
// memcpy(Copy_position, ptr_src, 2);
|
// UDS_FlipEndian(Copy_position, 2);
|
// break;
|
// case DID_UDS_NS_RepairShopCode:
|
// memcpy(Copy_position, ptr_src, 8);
|
// break;
|
// case DID_UDS_NS_ProgrammingDate:
|
// memcpy(Copy_position, ptr_src, 4);
|
break;
|
default:
|
break;
|
}
|
rtn_length += length;
|
#endif
|
return 0;
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_SendDidData(void) */
|
/* */
|
/* DESCRIPTION : */
|
/* This function composes the payload of requested DID data and */
|
/* pass the payload for CANTP to send */
|
/* INPUTS : */
|
/* void */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* Compose and send payload */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 06/18/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_SendDidData(void)
|
{
|
uint16_t i = 0;
|
uint16_t SendDataSize = 1; /* Reserve for the Response ID */
|
uint8_t *Copy_position; /* Specifies the starting address of copying */
|
/* Use a word to store the least significant 2 bytes of enum value */
|
uint16_t TwoByteDID = 0;
|
|
/* Initialize the starting position of the copy, reserve the SID size */
|
Copy_position = UDS_L_tx_msg_buffer + SID_SIZE;
|
|
/* Have a simple variable to store the intended index */
|
i = UDS_L_ReadDIDSet_t.DID_Table_Index;
|
|
/* Parse out only the least significant 2 bytes */
|
TwoByteDID = (uint16_t)(DIDtable[i].DidEnum & 0x0000FFFFu);
|
if ((TwoByteDID & 0xff00u) == 0xf100u)
|
{
|
UDS_SendF1DIDdata(Copy_position, i);
|
SendDataSize = SendDataSize + sizeof(TwoByteDID);
|
}
|
else
|
{
|
/* Flip the two byte DID */
|
UDS_FlipEndian(&(TwoByteDID), sizeof(TwoByteDID));
|
|
/* Copy requested DID into transmission buffer */
|
memcpy(Copy_position, &(TwoByteDID), sizeof(TwoByteDID));
|
|
/* Update the copying position */
|
Copy_position = Copy_position + sizeof(TwoByteDID);
|
SendDataSize = SendDataSize + sizeof(TwoByteDID);
|
|
/* First copy the DID data into tx buffer */
|
memcpy(Copy_position, DIDtable[i].address, DIDtable[i].size);
|
|
/* Flip endianness of the data to be sent IN THE TX BUFFER */
|
/* NOTE that we should not flip at DIDtable[i].address because */
|
/* it will crash the original data stored there */
|
UDS_FlipEndian(Copy_position, DIDtable[i].size);
|
|
Copy_position = Copy_position + DIDtable[i].size;
|
}
|
|
SendDataSize = SendDataSize + DIDtable[i].size;
|
|
/* Specify read data by DID response ID */
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(READ_DATA_BY_IDENTIFIER);
|
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = SendDataSize;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
|
static void UDS_RespTxMessage(void)
|
{
|
if (ssp_flg == true) /* ÒÖÖÆÕýÏìÓ¦, ²»·¢ËÍÕýÏìÓ¦ */
|
return;
|
|
if (!CANTP_TxMessage(&UDS_L_tp_stack, UDS_L_tx_msg_buffer,
|
UDS_L_tx_msg_size))
|
{
|
UDS_SendNegResp(NRC_BUSY_REPEAT_REQUEST);
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_TesterPresent(uint8_t * payload) */
|
/* */
|
/* DESCRIPTION : */
|
/* This function resets the tester present timer */
|
/* INPUTS : */
|
/* uint8_t * payload: pointer to the payload starting address */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* Read data stream by identifier */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 06/18/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_TesterPresent(uint8_t *payload)
|
{
|
|
/* Reset the tester present waiting timer. If current session is */
|
/* extended session */
|
CDT_RESET(TesterPresentTimer_u16,
|
UDS_NS_SessionTimeout_u16 / UDS_TASK_RATE);
|
|
uint8_t sub_func = UDS_GET_SUB_FUNCTION(payload[UDS_RQ_BYTE1]);
|
switch (sub_func)
|
{
|
case 0x00:
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(TESTER_PRESENT);
|
UDS_L_tx_msg_buffer[1] = 0x00;
|
UDS_L_tx_msg_size = 2;
|
UDS_RespTxMessage();
|
break;
|
default:
|
UDS_SendNegResp(NRC_SUBFUNCTION_NOT_SUPPORTED);
|
break;
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_SessionControl(uint8_t * payload) */
|
/* */
|
/* DESCRIPTION : */
|
/* Factory diagnosis session control */
|
/* INPUTS : */
|
/* uint8_t * payload: pointer to the payload starting address */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* Change session based on the third byte value of CAN msg */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 06/18/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_SessionControl(uint8_t *payload)
|
{
|
uint16_t cnt = 5000u;
|
/* Change session based on CAN message request */
|
bool UDS_SessionSetOk_b = false;
|
uint8_t sub_func = UDS_GET_SUB_FUNCTION(payload[UDS_RQ_BYTE1]);
|
switch (sub_func)
|
{
|
case EXTENDED:
|
|
if ((UDS_L_Diag_session_e == DEFAULT) || (UDS_L_Diag_session_e == EXTENDED))
|
{
|
UDS_L_Diag_session_e = EXTENDED;
|
/* Reset the tester present waiting timer. */
|
CDT_RESET(TesterPresentTimer_u16,
|
UDS_NS_SessionTimeout_u16 / UDS_TASK_RATE);
|
UDS_SessionSetOk_b = true;
|
}
|
else
|
{
|
UDS_SendNegResp(NRC_CONDITIONS_NOT_CORRECT);
|
}
|
|
break;
|
case PROGRAMMING:
|
/* UDS_SendNegResp(NRC_SUBFUNCTION_NOT_SUPPORTED); */
|
if (((UDS_L_Diag_session_e == EXTENDED) || (UDS_L_Diag_session_e == PROGRAMMING)) && (UDS_L_ProgrammingPreconditionCheckOK_b == true))
|
{
|
/**/
|
UDS_L_Diag_session_e = PROGRAMMING;
|
UDS_SessionSetOk_b = true;
|
FblSetFblProgramRequestFlag();
|
}
|
else if ((UDS_L_Diag_session_e == DEFAULT) || (UDS_L_ProgrammingPreconditionCheckOK_b == false)) /*DEFAULT session can not trans to PROGRAMMING*/
|
{
|
UDS_SendNegResp(NRC_CONDITIONS_NOT_CORRECT);
|
}
|
else
|
{
|
}
|
break;
|
case DEFAULT:
|
if (UDS_L_Diag_session_e == PROGRAMMING)
|
{
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(SESSION_CONTROL);
|
UDS_L_tx_msg_buffer[1] = UDS_L_Diag_session_e;
|
UDS_L_tx_msg_buffer[2] = 0;
|
UDS_L_tx_msg_buffer[3] = 0;
|
UDS_L_tx_msg_buffer[4] = 0;
|
UDS_L_tx_msg_buffer[5] = 0;
|
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x06;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
while (cnt--)
|
{
|
; /// wait send command send out and then reset
|
}
|
|
UDS_SwitchtoDefaultSession(true);
|
while (1)
|
;
|
}
|
else
|
{
|
UDS_SwitchtoDefaultSession(false);
|
}
|
|
TesterPresentTimer_u16 = 0;
|
break;
|
default:
|
UDS_SendNegResp(NRC_SUBFUNCTION_NOT_SUPPORTED);
|
break;
|
}
|
if (UDS_SessionSetOk_b == true)
|
{
|
/* Compose the response payload */
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(SESSION_CONTROL);
|
UDS_L_tx_msg_buffer[1] = UDS_L_Diag_session_e;
|
UDS_L_tx_msg_buffer[2] = 0;
|
UDS_L_tx_msg_buffer[3] = 0;
|
UDS_L_tx_msg_buffer[4] = 0;
|
UDS_L_tx_msg_buffer[5] = 0;
|
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x06;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : UDS_SecurityAccess(uint8_t * payload) */
|
/* */
|
/* DESCRIPTION : */
|
/* Security Access */
|
/* INPUTS : */
|
/* void */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 08/03/2017 Fogbugz: case#: */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_SecurityAccess(uint8_t *payload)
|
{
|
if (UDS_L_Diag_session_e == DEFAULT)
|
{
|
/* Send a negative response.*/
|
UDS_SendNegResp(NRC_SECURITY_ACCESS_DENIED);
|
return;
|
}
|
if ((UDS_L_SecurityFault_cnt == 3) || (UDS_L_SecurityStartDelay == 1))
|
{
|
UDS_SendNegResp(NRC_REQUIRED_TIME_DELAY_NOT_EXPIRED);
|
return;
|
}
|
uint32_t ReceiveKey = 0;
|
uint8_t sub_func = UDS_GET_SUB_FUNCTION(payload[UDS_RQ_BYTE1]);
|
switch (sub_func)
|
{
|
case REQUEST_LEVEL_ONE_SEED:
|
case SEND_LEVEL_ONE_KEY:
|
UDS_SendNegResp(NRC_SUBFUNCTION_NOT_SUPPORTED); // only support LEVEL 2
|
return;
|
break;
|
case REQUEST_LEVEL_TWO_SEED:
|
UDS_L_SecurityAccessStep_e = REQUEST_LEVEL_TWO_SEED;
|
|
/* Compose the response payload */
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(SECURITY_ACCESS);
|
UDS_L_tx_msg_buffer[1] = UDS_L_SecurityAccessStep_e;
|
#if 0
|
UDS_L_tx_msg_buffer[2] = (uint8_t)(LEVEL2_SEED >> 8);
|
UDS_L_tx_msg_buffer[3] = (uint8_t)(LEVEL2_SEED);
|
#endif
|
for (int i = 0; i < SEED_SIZE; i++)
|
{
|
UDS_L_tx_msg_buffer[2 + i] = (uint8_t)(LEVEL2_SEED >> ((SEED_SIZE - i - 1) * 8));
|
}
|
/* Specify the send payload size */
|
/* UDS_L_tx_msg_size = 0x04; */
|
UDS_L_tx_msg_size = 2 + SEED_SIZE;
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
break;
|
case SEND_LEVEL_TWO_KEY:
|
if (UDS_L_SecurityAccessStep_e != REQUEST_LEVEL_TWO_SEED)
|
{
|
UDS_SendNegResp(NRC_REQUEST_SEQUENCE_ERROR);
|
return;
|
}
|
/* ReceiveKey = payload[UDS_RQ_BYTE2]; */
|
/* ReceiveKey = (ReceiveKey << 8) | payload[UDS_RQ_BYTE3]; */
|
for (int i = 0; i < KEY_SIZE; i++)
|
{
|
ReceiveKey = ReceiveKey << 8 | payload[2 + i];
|
}
|
if (ReceiveKey == LEVEL2_KEY)
|
{
|
/*right key*/
|
UDS_L_SecurityFault_cnt = 0;
|
UDS_O_SecurityAccessState_e = SECURITY_ACCESS_UNLOCK_LEVEL_2;
|
UDS_L_SecurityAccessStep_e = SECURITY_ACCESS_STEP_MAX;
|
/* Compose the response payload */
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(SECURITY_ACCESS);
|
UDS_L_tx_msg_buffer[1] = SEND_LEVEL_TWO_KEY;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x02;
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
else
|
{
|
UDS_SendNegResp(NRC_INVALID_KEY);
|
if (++UDS_L_SecurityFault_cnt >= MAX_SECURITY_FAULT_CNT)
|
{
|
UDS_L_SecurityFault_cnt = MAX_SECURITY_FAULT_CNT;
|
CDT_RESET(SecurityAcessTimer_u16,
|
SECURITY_ACCESS_WAIT_TIME);
|
UDS_SendNegResp(NRC_EXCEEDED_NUMBER_OF_ATTEMPTS);
|
}
|
}
|
break;
|
default:
|
break;
|
}
|
}
|
|
static void UDS_Reset(uint8_t ResetType)
|
{
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(ECU_RESET);
|
UDS_L_tx_msg_buffer[1] = ResetType;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x02;
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
// UDS_RespTxMessage();
|
|
if (ssp_flg == false) // ûÓÐÕýÏìÓ¦ÒÖÖÆ
|
{
|
TP_PDU_t msg;
|
msg.arbId = UDS_RESP_TID;
|
msg.extended = false;
|
msg.RTR = false;
|
msg.dlc = 8;
|
msg.frame[0] = 0x03;
|
msg.frame[1] = GET_RESPONSE_SERVICE_ID(ECU_RESET);
|
msg.frame[2] = ResetType;
|
|
for (int i = 0; i < 200; i++) // È·±£·¢³öÏìÓ¦
|
{
|
UDS_WriteData(&msg, 0);
|
}
|
}
|
|
CPU_HardReset();
|
}
|
|
static void UDS_HardwareReset(void)
|
{
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(ECU_RESET);
|
UDS_L_tx_msg_buffer[1] = 0x01;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x02;
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
CPU_HardReset();
|
}
|
static void UDS_SoftwareReset(void)
|
{
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(ECU_RESET);
|
UDS_L_tx_msg_buffer[1] = 0x02;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x02;
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
CPU_HardReset();
|
}
|
|
static void UDS_ECURest(uint8_t *payload)
|
{
|
uint8_t sub_func = UDS_GET_SUB_FUNCTION(payload[UDS_RQ_BYTE1]);
|
uint8_t reset_type = payload[UDS_RQ_BYTE1];
|
switch (sub_func)
|
{
|
case 0x01: // Hard Reset
|
UDS_Reset(reset_type);
|
break;
|
case 0x02: // Key On Off Reset
|
// UDS_Reset(reset_type);
|
UDS_SendNegResp(NRC_SUBFUNCTION_NOT_SUPPORTED);
|
break;
|
case 0x03: // Soft Reset
|
UDS_Reset(reset_type);
|
break;
|
case 0x04: // Enable Rapid Power Shutdown
|
UDS_Reset(reset_type);
|
break;
|
default:
|
UDS_SendNegResp(NRC_SUBFUNCTION_NOT_SUPPORTED);
|
break;
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_RoutineControl(uint8_t * payload) */
|
/* */
|
/* DESCRIPTION : */
|
/* Factory routine control */
|
/* INPUTS : */
|
/* uint8_t * payload: pointer to the payload starting address */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 09/09/06 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_RoutineControl(uint8_t *payload)
|
{
|
uint16_t RoutineID = 0;
|
if ((UDS_L_Diag_session_e == DEFAULT) || ((UDS_O_SecurityAccessState_e != SECURITY_ACCESS_UNLOCK_LEVEL_1) && (UDS_O_SecurityAccessState_e != SECURITY_ACCESS_UNLOCK_LEVEL_2)))
|
{
|
/* Send a negative response.*/
|
UDS_SendNegResp(NRC_SECURITY_ACCESS_DENIED);
|
return;
|
}
|
RoutineID = (uint16_t)payload[UDS_RQ_BYTE2] << 8 | (uint16_t)payload[UDS_RQ_BYTE3];
|
|
switch (RoutineID)
|
{
|
case 0xf001:
|
UDS_CheckProgrammingIntergrity(payload);
|
|
break;
|
case 0xff02:
|
UDS_CheckProgrammingPrecondition();
|
break;
|
case 0xff00:
|
UDS_EraseMemory(payload);
|
break;
|
case 0xff01:
|
UDS_CheckProgrammingDependence(payload);
|
/* UDS_SendNegResp(NRC_REQUEST_SEQUENCE_ERROR); */
|
break;
|
default:
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
break;
|
}
|
}
|
|
static void UDS_ResponseTiming(void)
|
{
|
if (RESP_PENDING_MAX != UDS_L_ResponsePendingRequest_e)
|
{
|
if (CDT_EXPIRED(ResponsePendingTimer_u16) == true)
|
{
|
/**/
|
CDT_RESET(ResponsePendingTimer_u16, P2SERVER_PENDING_TIMEROUT);
|
UDS_SendNegResp(NRC_TRANSFER_DATA_SUSPENDED);
|
}
|
else
|
{
|
if ((UDS_L_ResponsePendingRequest_e & CHECK_PROGRAMMING_INTERGRITY_PENDING) != 0)
|
{
|
if (transferType == DOWNLOAD_FLASH)
|
{
|
UDS_L_CRCCheckFail_b = !MEM_PartitionCRCOK((uint8_t)MEM_PARTITION_CODEFLASH, UDS_L_CRCReceived);
|
if (UDS_L_CRCCheckFail_b == false)
|
{
|
NVM_ReInitFlashDriveRam(); // CLEAR FLASH DRIVE IN RAM
|
}
|
}
|
else
|
{
|
UDS_L_CRCCheckFail_b = !MEM_PartitionCRCOK((uint8_t)MEM_PARTITION_RAM, UDS_L_CRCReceived);
|
if (UDS_L_CRCCheckFail_b == true)
|
{
|
NVM_ReInitFlashDriveRam(); // CLEAR FLASH DRIVE IN RAM
|
}
|
}
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(ROUTINE_CONTROL);
|
UDS_L_tx_msg_buffer[1] = 0x01;
|
UDS_L_tx_msg_buffer[2] = 0xf0;
|
UDS_L_tx_msg_buffer[3] = 0x01;
|
UDS_L_tx_msg_buffer[4] = (uint8_t)UDS_L_CRCCheckFail_b;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x05;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
|
UDS_L_ResponsePendingRequest_e &= (~CHECK_PROGRAMMING_INTERGRITY_PENDING);
|
UDS_L_ResponsePendingRelease_e &= (~CHECK_PROGRAMMING_INTERGRITY_PENDING);
|
}
|
}
|
}
|
else
|
{
|
CDT_RESET(ResponsePendingTimer_u16, P2SERVER_PENDING_TIMEROUT);
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_CommunicationControl(uint8_t * payload) */
|
/* */
|
/* DESCRIPTION : */
|
/* Factory communication control */
|
/* INPUTS : */
|
/* uint8_t * payload: pointer to the payload starting address */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* Change communication based on the third byte value of CAN msg */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 07/31/2017 Fogbugz: case#: */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_CommunicationControl(uint8_t *payload)
|
{
|
|
if (UDS_L_Diag_session_e != EXTENDED)
|
{
|
/* Send a negative response.*/
|
UDS_SendNegResp(NRC_SECURITY_ACCESS_DENIED);
|
return;
|
}
|
|
uint8_t ControlType = UDS_GET_SUB_FUNCTION(payload[UDS_RQ_BYTE1]);
|
uint8_t CommunicationType = payload[UDS_RQ_BYTE2];
|
if ((ControlType != (uint8_t)EnableRxAndTx) ||
|
(CommunicationType != NormalCommunicationMessage) && (CommunicationType != NetManageCommMessage) && (CommunicationType != BothCommunicationMessage))
|
{
|
UDS_SendNegResp(NRC_SUBFUNCTION_NOT_SUPPORTED);
|
return;
|
}
|
|
if (payload[UDS_RQ_BYTE2] == NetManageCommMessage)
|
{
|
UDS_SendNegResp(NRC_SUBFUNCTION_NOT_SUPPORTED);
|
return;
|
}
|
|
/* Change communnication type based on CAN message request */
|
UDS_L_CommunicationControlType_e = (UDS_CONTOL_TYPE_e)ControlType;
|
|
/* Compose the response payload */
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(COMMUNICATION_CONTROL);
|
UDS_L_tx_msg_buffer[1] = UDS_L_CommunicationControlType_e;
|
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x02;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
extern void UDS_GetCommunicationControlType(unsigned char *type)
|
{
|
*type = (unsigned char)(UDS_L_CommunicationControlType_e & 0x3);
|
}
|
|
static void UDS_EraseMemory(uint8_t *payload)
|
{
|
uint8_t lengthFormat = 0;
|
uint8_t addrFormat = 0;
|
uint8_t i = 0;
|
int8_t erase_state = OP_STATUS_FAIL;
|
lengthFormat = (uint8_t)((payload[UDS_RQ_BYTE4] & 0xf0) >> 4);
|
addrFormat = (uint8_t)(payload[UDS_RQ_BYTE4] & 0x0f);
|
eraseAddress = 0;
|
eraseRemainder = 0;
|
if (Nvm_Flags.flash_driver_loaded == 0)
|
{
|
/*flash not load to ram*/
|
UDS_SendNegResp(NRC_CONDITIONS_NOT_CORRECT);
|
return;
|
}
|
for (i = 0; i < lengthFormat; i++)
|
{
|
eraseAddress <<= 8;
|
eraseAddress |= payload[i + UDS_RQ_BYTE5];
|
}
|
for (i = 0; i < addrFormat; i++)
|
{
|
eraseRemainder <<= 8;
|
eraseRemainder |= payload[i + UDS_RQ_BYTE5 + lengthFormat];
|
}
|
eraseRemainder += (64 - (eraseRemainder % 64));
|
|
if ((eraseAddress != APPCODE_START) || (eraseRemainder == 0))
|
{
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
return;
|
}
|
|
UDS_L_ResponsePendingRequest_e |= ERASE_RESP_PENDING;
|
UDS_SendNegResp(NRC_SERVICE_BUSY);
|
erase_state = NVM_EraseData(eraseAddress, eraseRemainder);
|
if (erase_state == OP_STATUS_OK)
|
{
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(ROUTINE_CONTROL);
|
UDS_L_tx_msg_buffer[1] = 0x01;
|
UDS_L_tx_msg_buffer[2] = 0xff;
|
UDS_L_tx_msg_buffer[3] = 0x00;
|
UDS_L_tx_msg_buffer[4] = 0; // 0:ok 1£ºerror
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 5;
|
UDS_RespTxMessage();
|
}
|
else
|
{
|
UDS_SendNegResp(NRC_GENERAL_PROGRAMMING_FAILURE);
|
}
|
}
|
|
static void UDS_CheckProgrammingIntergrity(uint8_t *payload)
|
{
|
#if 0
|
int8_t crc_state=OP_STATUS_FAIL;
|
bool crc_result=false;
|
FBL_UDS_O_transferCRC=(uint32_t)payload[4]<<24|(uint32_t)payload[5]<<16|(uint32_t)payload[6]<<8|(uint32_t)payload[7];
|
//crc_state=MEM_CodeCRCCheck(transferAddress+4,transferRemainder,FBL_UDS_SetCRCCheckResult);
|
#if 0
|
if(crc_state==OP_STATUS_OK)
|
{
|
FBL_UDS_L_ResponsePendingRequest_e|=CHECK_PROGRAMMING_INTERGRITY_PENDING;
|
UDS_SendNegResp(RESPONSEPENDING);
|
}
|
else
|
{
|
UDS_SendNegResp(GENERALPROGRAMMINGFAILURE);
|
}
|
#endif
|
UDS_L_tx_msg_buffer[0] = RESP_ID_ROUTINE_CONTROL;
|
UDS_L_tx_msg_buffer[1] = 0x01;
|
UDS_L_tx_msg_buffer[2] = 0xf0;
|
UDS_L_tx_msg_buffer[3] =0x01;
|
if(transferType==DOWNLOAD_FLASH)
|
{
|
crc_result=MEM_PartitionCRCOK((uint8_t)MEM_PARTITION_CODEFLASH);
|
}
|
else
|
{
|
crc_result=MEM_PartitionCRCOK((uint8_t)MEM_PARTITION_RAM);
|
}
|
//UDS_L_tx_msg_buffer[4] = (uint8_t)(!crc_result);
|
UDS_L_tx_msg_buffer[4] = 0;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x05;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
if(FBL_CANTP_TxMessage(&UDS_L_tp_stack, UDS_L_tx_msg_buffer,
|
UDS_L_tx_msg_size))
|
{
|
FBL_UDS_L_ResponsePendingRequest_e &=(~CHECK_PROGRAMMING_INTERGRITY_PENDING);
|
FBL_UDS_L_ResponsePendingRelease_e &=(~CHECK_PROGRAMMING_INTERGRITY_PENDING);
|
}
|
#endif
|
UDS_L_CRCReceived = (uint32_t)payload[4] << 24 | (uint32_t)payload[5] << 16 | (uint32_t)payload[6] << 8 | (uint32_t)payload[7];
|
UDS_L_ResponsePendingRequest_e |= CHECK_PROGRAMMING_INTERGRITY_PENDING;
|
CDT_RESET(ResponsePendingTimer_u16, P2SERVER_PENDING_TIMEROUT);
|
}
|
|
static void UDS_CheckProgrammingDependence(uint8_t *payload)
|
{
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(ROUTINE_CONTROL);
|
UDS_L_tx_msg_buffer[1] = 0x01;
|
UDS_L_tx_msg_buffer[2] = 0xff;
|
UDS_L_tx_msg_buffer[3] = 0x01;
|
UDS_L_tx_msg_buffer[4] = 0;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x05;
|
|
/* Compose a response message and send a positive */
|
UDS_RespTxMessage();
|
}
|
|
static void UDS_CheckProgrammingPrecondition()
|
{
|
UDS_L_ProgrammingPreconditionCheckOK_b = true; /* always is true,maybe need check shiftpostion,speed and so on */
|
|
/* Compose the response payload */
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(ROUTINE_CONTROL);
|
UDS_L_tx_msg_buffer[1] = 0x01;
|
UDS_L_tx_msg_buffer[2] = 0xff;
|
UDS_L_tx_msg_buffer[3] = 0x02;
|
UDS_L_tx_msg_buffer[4] = 0;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x05;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
|
static void UDS_RequestDownload(uint8_t *payload)
|
{
|
uint8_t lengthFormat;
|
uint16_t receive_size = 0;
|
lengthFormat = (uint8_t)((payload[UDS_RQ_BYTE2] & 0xf0) >> 4);
|
|
if (payload[UDS_RQ_BYTE2] != 0x44)
|
{
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
return;
|
}
|
if (UDS_L_rx_msg_size != REQUEST_DOWNLOAD_MSG_SIZE)
|
{
|
UDS_SendNegResp(NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT);
|
return;
|
}
|
if (UDS_L_TransferDataInProgressing_b == true)
|
{
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
return;
|
}
|
expectedSequenceCnt = 0x01;
|
currentSequenceCnt = 0x01;
|
transferAddress = ((uint32_t)payload[UDS_RQ_BYTE3]) << 24 | ((uint32_t)payload[UDS_RQ_BYTE4]) << 16 | ((uint32_t)payload[UDS_RQ_BYTE5]) << 8 | ((uint32_t)payload[UDS_RQ_BYTE6]);
|
transferRemainder = ((uint32_t)payload[UDS_RQ_BYTE7]) << 24 | ((uint32_t)payload[UDS_RQ_BYTE8]) << 16 | ((uint32_t)payload[UDS_RQ_BYTE9]) << 8 | ((uint32_t)payload[UDS_RQ_BYTE10]);
|
|
if (transferRemainder == 0)
|
{
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
return;
|
}
|
DownloadAddress = transferAddress;
|
DownloadLength = transferRemainder;
|
if (transferAddress == FLASH_DRIVER_START_ADDR)
|
{
|
transferType = DOWNLOAD_RAM;
|
}
|
else if (transferAddress == APPCODE_START)
|
{
|
transferType = DOWNLOAD_FLASH;
|
}
|
else
|
{
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
return;
|
}
|
|
if (transferType == DOWNLOAD_FLASH)
|
{
|
/*flash driver is loaded?*/
|
if ((Nvm_Flags.flash_driver_loaded == 0))
|
{
|
UDS_SendNegResp(NRC_REQUEST_SEQUENCE_ERROR);
|
return;
|
}
|
|
if ((transferAddress != APPCODE_START) || (transferAddress + transferRemainder > APPLICATION_END_ADDR))
|
{
|
UDS_SendNegResp(NRC_REQUEST_OUT_OF_RANGE);
|
return;
|
}
|
}
|
else if ((transferType == DOWNLOAD_RAM))
|
{
|
if ((transferRemainder > (uint32_t)RAM_FALSH_DRIVE_LENGHT) || ((tFblAddress)flashCode != transferAddress))
|
{
|
// FblErrStatSetError(FBL_ERR_FLASHCODE_EXCEEDS_MEMORY);
|
UDS_SendNegResp(NRC_REQUEST_SEQUENCE_ERROR);
|
return;
|
}
|
else
|
{
|
}
|
}
|
DID_UpdateAtpProgramCnt();
|
/*always from buff 0*/
|
currentbuffId = 0;
|
UDS_L_TransferDataState_e = TRANFER_START;
|
receive_size = FBL_RX_BUFFER_SIZE + 2;
|
/*RESPONSE*/
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(REQUEST_DOWNLOAD);
|
// UDS_L_tx_msg_buffer[1] = lengthFormat<<4;
|
UDS_L_tx_msg_buffer[1] = 0x20;
|
UDS_L_tx_msg_buffer[2] = (uint8_t)(receive_size >> 8); /*max length of block size,256Byte*/
|
UDS_L_tx_msg_buffer[3] = ((uint8_t)receive_size);
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x04;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
static void UDS_TransferData(uint8_t *payload)
|
{
|
uint8_t partition_id;
|
uint32_t loadlength = 0;
|
uint8_t i = 0;
|
MEM_OPERATION_Ts operation_write;
|
int8_t write_result = OP_STATUS_FAIL;
|
/* Check if the requested sequence number is expected */
|
if (payload[UDS_RQ_BYTE1] != expectedSequenceCnt)
|
{
|
/* Check if sequence number corresponds to a retry */
|
if (payload[UDS_RQ_BYTE1] == currentSequenceCnt)
|
{
|
/* Handle the retries here */
|
|
/* Repetition of last transferData request */
|
/* Simply send a positive response without loading data to memory */
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(TRANSFER_DATA);
|
UDS_L_tx_msg_buffer[1] = currentSequenceCnt;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x02;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
else /* Sequence number is not for a retry */
|
{
|
/* Send a WrongSequenceError */
|
UDS_SendNegResp(NRC_WRONG_BLOCK_SEQUENCE_COUNTER);
|
return;
|
}
|
}
|
|
if (transferRemainder == 0) //||(transferAddress>=startaddr+length)
|
{
|
/*already receive all data*/
|
UDS_SendNegResp(NRC_REQUEST_SEQUENCE_ERROR);
|
return;
|
}
|
|
if (transferType == DOWNLOAD_FLASH)
|
{
|
if (transferAddress >= APPLICATION_END_ADDR)
|
{
|
/*already receive all data*/
|
UDS_SendNegResp(NRC_REQUEST_SEQUENCE_ERROR);
|
return;
|
}
|
partition_id = (uint8_t)MEM_PARTITION_CODEFLASH;
|
}
|
else
|
{
|
partition_id = (uint8_t)MEM_PARTITION_RAM;
|
}
|
/*COPY TP RX BUFF DATA TO MEM_TRMP BUFF*/
|
if (transferType == DOWNLOAD_FLASH)
|
{
|
if ((UDS_L_rx_msg_size - 2) < FBL_RX_BUFFER_SIZE)
|
{
|
for (i = 0; i < (FBL_RX_BUFFER_SIZE + 2 - UDS_L_rx_msg_size); i++)
|
{
|
payload[UDS_L_rx_msg_size + i] = 0xff;
|
}
|
}
|
else
|
{
|
}
|
loadlength = FBL_RX_BUFFER_SIZE;
|
}
|
else
|
{
|
// loadlength+=((uint32_t)(UDS_L_rx_msg_size-2));
|
loadlength = ((uint32_t)(UDS_L_rx_msg_size - 2));
|
}
|
memcpy((void *)&Mem_PartionTempBuff[currentbuffId][0], &payload[UDS_RQ_BYTE2], loadlength);
|
|
operation_write.p_buffer = &Mem_PartionTempBuff[currentbuffId][0];
|
operation_write.partition_id = partition_id;
|
operation_write.mem_operation_id = NVM_OP_TYPE_WRITE;
|
operation_write.start_addr = transferAddress;
|
operation_write.size_in_bytes = loadlength;
|
operation_write.pfn_complete_cbk = NULL;
|
operation_write.current_sequenc = expectedSequenceCnt;
|
operation_write.prev_seqence = currentSequenceCnt;
|
|
UDS_SendNegResp(NRC_SERVICE_BUSY); // first send busy
|
write_result = NEM_WriteData(&operation_write); // todo write all data at this function
|
if (write_result == OP_STATUS_OK)
|
{
|
transferAddress += loadlength;
|
transferRemainder -= (UDS_L_rx_msg_size - 2);
|
// transferRemainder-=loadlength;
|
if (transferRemainder == 0)
|
{
|
UDS_L_TransferDataState_e = TRANFER_END;
|
}
|
|
if (currentbuffId == 0)
|
{
|
currentbuffId = 1;
|
}
|
else
|
{
|
|
currentbuffId = 0;
|
}
|
/* Memorize current counter */
|
currentSequenceCnt = expectedSequenceCnt;
|
|
/* Sequence counter value of next transferData request */
|
expectedSequenceCnt++;
|
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(TRANSFER_DATA);
|
UDS_L_tx_msg_buffer[1] = currentSequenceCnt;
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x02;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
}
|
else
|
{
|
UDS_SendNegResp(NRC_GENERAL_PROGRAMMING_FAILURE);
|
}
|
}
|
static void UDS_RequestTransferExit(uint8_t *payload)
|
{
|
|
if (transferType == DOWNLOAD_FLASH)
|
{
|
transferAddress = APPCODE_START;
|
transferRemainder = 0;
|
}
|
else
|
{
|
transferAddress = FLASH_DRIVER_START_ADDR;
|
transferRemainder = 0;
|
}
|
UDS_L_TransferDataInProgressing_b = false;
|
UDS_L_TransferDataState_e = TRANFER_IDLE;
|
// transferType=0;
|
expectedSequenceCnt = 0x01;
|
currentSequenceCnt = 0x01;
|
|
UDS_L_tx_msg_buffer[0] = GET_RESPONSE_SERVICE_ID(REQUEST_TRANSFER_EXIT);
|
/* Specify the send payload size */
|
UDS_L_tx_msg_size = 0x01;
|
|
/* Compose a response message and send a positive */
|
/* response with the request data */
|
UDS_RespTxMessage();
|
DID_UpdateProgramCnt();
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_SendNegResp(NEGA_RESP_Code_e reason) */
|
/* */
|
/* DESCRIPTION : */
|
/* This function composes and send a negative response */
|
/* INPUTS : */
|
/* NEGA_RESP_Code_e reason: Negative response reason */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* Send negative response */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 07/29/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_SendNegResp(NEGA_RESP_Code_e reason)
|
{
|
TP_PDU_t out = {0};
|
/* Pack and send CAN message */
|
out.arbId = UDS_RESP_TID;
|
out.extended = false;
|
out.RTR = false;
|
out.dlc = 8;
|
out.frame[0] = 3;
|
out.frame[1] = 0x7F;
|
out.frame[2] = UDS_L_rx_msg_buffer[0];
|
out.frame[3] = (uint8_t)reason;
|
#if 0
|
CANTP_zeroRestOfFrame(&out);
|
#endif
|
UDS_WriteData(&out, 0);
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_FlipEndian(void *address, uint16_t size) */
|
/* */
|
/* DESCRIPTION : */
|
/* Function to flip the endianness of a set of memory locations */
|
/* and put the flipped number back to *address location */
|
/* INPUTS : */
|
/* void* address : Start address of the memory location */
|
/* uint16_t size : Memory size */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* [1] Flip endianness */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 07/31/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_FlipEndian(void *address, uint16_t size)
|
{
|
|
uint8_t temp = 0;
|
uint8_t i = 0;
|
for (i = size; i > size / 2; i--)
|
{
|
temp = ((uint8_t *)address)[size - i];
|
((uint8_t *)address)[size - i] = ((uint8_t *)address)[i - 1];
|
((uint8_t *)address)[i - 1] = temp;
|
}
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_BuildDidSet(uint8_t * payload) */
|
/* */
|
/* DESCRIPTION : */
|
/* This function builds up the set of requested DID */
|
/* INPUTS : */
|
/* uint8_t * payload: pointer to the payload starting address */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* Build requested DID set */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 07/31/2014 Fogbugz: case#: 1575 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static bool UDS_BuildDidSet(uint8_t *payload)
|
{
|
#if 1
|
uint16_t i = 0;
|
bool DIDnotFoundflag = false;
|
|
/* Set the initial value of requested DID set size */
|
/* UDS_L_ReadDidSetSize_u16 = 0; */
|
|
UDS_L_ReadDIDSet_t.DID_Value = payload[1] << 8 | payload[2];
|
|
/* For each requested DID, verify it can be found in current DID table */
|
|
for (i = 0; (i < UDS_DID_TABLE_SIZE) && (DIDtable[i].DidEnum != UDS_L_ReadDIDSet_t.DID_Value); i++)
|
{
|
/* break; */
|
}
|
|
/* i == DIDTable_Entry_Count_u16 means no data with the DID is found */
|
if (i == UDS_DID_TABLE_SIZE)
|
{
|
/* Flag the fact that there is DID that cannot be found */
|
DIDnotFoundflag = true;
|
}
|
else
|
{
|
/* Continue with next requested DID */
|
UDS_L_ReadDIDSet_t.DID_Table_Index = i;
|
}
|
|
return (DIDnotFoundflag);
|
#else
|
bool not_found = true;
|
UDS_L_ReadDIDSet_t.DID_Value = payload[1] << 8 | payload[2];
|
uint16_t i;
|
for (i = 0; i < UDS_DID_TABLE_SIZE; i++)
|
{
|
if (UDS_L_ReadDIDSet_t.DID_Value == DIDtable[i].DidEnum)
|
{
|
UDS_L_ReadDIDSet_t.DID_Table_Index = i;
|
not_found = false;
|
break;
|
}
|
}
|
return not_found;
|
#endif
|
}
|
|
/*****************************************************************************/
|
/* NAME : static void UDS_SwitchtoDefaultSession(void) */
|
/* */
|
/* DESCRIPTION : */
|
/* This function handles the operations to switch to default session*/
|
/* INPUTS : */
|
/* None */
|
/* OUTPUTS : */
|
/* None */
|
/* RETURN : */
|
/* void */
|
/* PROCESS : */
|
/* Build requested DID set */
|
/* NOTES : */
|
/* None */
|
/* REVISION HISTORY : */
|
/* (1) Date: 10/30/2014 Fogbugz: case#: 2283 */
|
/* Initial release by Tom Tao */
|
/*****************************************************************************/
|
static void UDS_SwitchtoDefaultSession(uint8_t restcmd)
|
{
|
UDS_L_Diag_session_e = DEFAULT;
|
UDS_L_ProgrammingPreconditionCheckOK_b = false;
|
if (restcmd == true)
|
{
|
CPU_HardReset();
|
}
|
}
|
|
static void UDS_StringCopy(char *p_src, char *p_dest, uint8_t max_size)
|
{
|
uint8_t pn_len = 0u;
|
uint8_t i = 0u;
|
|
if ((p_src != NULL) && (p_dest != NULL) && (max_size > 0))
|
{
|
/* get the length of the string, limited to max_size */
|
pn_len = strnlen(p_src, max_size);
|
/* p_src=p_src+pn_len; */
|
/* copy source into dest */
|
for (i = 0u; i < pn_len; i++)
|
{
|
*p_dest++ = *p_src++;
|
}
|
for (i = pn_len; i < max_size; i++)
|
{
|
*p_dest++ = '\0';
|
}
|
}
|
}
|
|
/* end of _UDS_H */
|