/*
*********************************************************************
* Includes
*********************************************************************
*/
#include "kwp2000_interface.h"
#include "kwp2000_tp.h"
#include "kwp2000_service.h"

#include "Common_Interface.h"
#include "GUI.h"
/*
*********************************************************************
* structure
*********************************************************************
*/

/*
*********************************************************************
* variable
*********************************************************************
*/
Kwp2000_Negative_t Kwp2000_Negative;

_K_LINE_SIGNAL_FLAG K_LINE_SIGNAL_FLAG;

unsigned char Sendseed1;
unsigned char Sendseed2;
unsigned char Sendseed3;
unsigned char Sendseed4;

unsigned char Recvseed1;
unsigned char Recvseed2;
unsigned char Recvseed3;
unsigned char Recvseed4;

unsigned char Seed1, Seed2, Seed3, Seed4;

_NVMNODIGIT NVMNODIGIT;
_ECUStatus ECUStatusONE;

unsigned char DTCstatusCHGFFK_Line;

unsigned char AccessMode2701KeyTimeFlag;
unsigned char AccessMode2701KeyTime;

unsigned long EOLSeedRandomNumber = 0x6879716169716872ul;

/*
*********************************************************************
* function
*********************************************************************
*/

/*-------------------------------------------------------------------------
* Function Name  : kwp_NegativeResponse
* Description    : Negative Response
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
unsigned char kwp_NegativeResponse(unsigned char sId_u8, unsigned char NegRC_u8, unsigned char *blockByte)
{
    unsigned char bufPos = 0;

    (*blockByte++) = KWP_NEGATIVE_RESPONSE;
    (*blockByte++) = sId_u8;
    (*blockByte) = NegRC_u8;

    bufPos = 3;

    return (bufPos);
}
/*-------------------------------------------------------------------------
* Function Name  : kwp_EcuReset
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 11
--------------------------------------------------------------------------*/
unsigned char kwp_EcuReset(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;

    switch (RequestData[0]) /* subFunction */
    {
    case 1: /* hardReset */
        (*TxData++) = KWP2000_ECURESET_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData) = RequestData[0];
        Tx_Len = 2;
        break;
    case 2: /* keyOffOnReset */
        (*TxData++) = KWP2000_ECURESET_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData) = RequestData[0];
        Tx_Len = 2;
        break;
    case 3: /* softReset */
        (*TxData++) = KWP2000_ECURESET_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData) = RequestData[0];
        Tx_Len = 2;
        break;
    default: /* subFunctionNotSupported */
        Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        break;
    }
    return Tx_Len;
}

/*-------------------------------------------------------------------------
* Function Name  : kwp_TesterPresent
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 3E
--------------------------------------------------------------------------*/
unsigned char kwp_TesterPresent(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;
    (*TxData) = KWP2000_TESTERPRESENT_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
    Tx_Len = 1;
    return Tx_Len;
}

/*-------------------------------------------------------------------------
* Function Name  : kwp_StartCommunication
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 81
--------------------------------------------------------------------------*/
unsigned char kwp_StartCommunication(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;
    K_LINE_SIGNAL_FLAG.RecvStart = 1;

    (*TxData++) = KWP2000_STARTCOMMUNICATION_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
    (*TxData++) = KWP2000_KEYBYTE1;
    (*TxData) = KWP2000_KEYBYTE2;
    Tx_Len = 3;

    return Tx_Len;
}

/*-------------------------------------------------------------------------
* Function Name  : kwp_StartCommunication
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 82 服务，没有否定应答
--------------------------------------------------------------------------*/
unsigned char kwp_StopCommunication(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;
    if (K_LINE_SIGNAL_FLAG.RecvStart == 1)
    {
        K_LINE_SIGNAL_FLAG.RecvStart = 0;            /*EOL诊断结束标识*/
        K_LINE_SIGNAL_FLAG.SendSeedEQUSRecvSeed = 0; /*清空密钥配对成功标识*/

        (*TxData) = KWP2000_STOPCOMMUNICATION_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        Tx_Len = 1;
    }
    else
    {
        Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
    }

    return Tx_Len;
}
/*-------------------------------------------------------------------------
* Function Name  : kwp_readEcuIdentification
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 1A
--------------------------------------------------------------------------*/
unsigned char kwp_readEcuIdentification(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;
    switch (RequestData[0]) /* subFunction */
    {
    case 0x81: /* ECUIdentificationScalingTable */
        (*TxData++) = KWP2000_READECUIDENTIFICATION_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = RequestData[0];
        (*TxData++) = 0x03; /* Scaling Offset*/
        (*TxData++) = 0x91; /* 汽车制造厂编号*/
        (*TxData++) = 0x6A; /* Ascii 10 byte*/
        (*TxData++) = 0xFF;
        Tx_Len = 6;
        break;
    case 0x91: /* vehicleManufacturerECUHardwareNumber */
        (*TxData++) = KWP2000_READECUIDENTIFICATION_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = RequestData[0]; // ISUZU Parts No. 8979683010
        (*TxData++) = NVMNODIGIT.No_Digit1;
        (*TxData++) = NVMNODIGIT.No_Digit2;
        (*TxData++) = NVMNODIGIT.No_Digit3;
        (*TxData++) = NVMNODIGIT.No_Digit4;
        (*TxData++) = NVMNODIGIT.No_Digit5;
        (*TxData++) = NVMNODIGIT.No_Digit6;
        (*TxData++) = NVMNODIGIT.No_Digit7;
        (*TxData++) = NVMNODIGIT.No_Digit8;
        (*TxData++) = NVMNODIGIT.No_Digit9;
        (*TxData++) = NVMNODIGIT.No_Digit10;
        Tx_Len = 12;
        break;
    default: /* subFunctionNotSupported */
        Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        break;
    }
    return Tx_Len;
}

/*-------------------------------------------------------------------------
* Function Name  : kwp_writeDataByLocalIdentifier
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 3B
--------------------------------------------------------------------------*/
unsigned char kwp_writeDataByLocalIdentifier(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;
    unsigned char CupFlag = 0;
    // if ((NVMUserSettings.KLINE == 0) || ((NVMUserSettings.KLINE == 1) && (K_LINE_SIGNAL_FLAG.SendSeedEQUSRecvSeed == 1)))
    if (0)
    {
        switch (RequestData[0]) /* */
        {
        case 0x20: /*应对ECE R13 0：非应对、1：应对*/
            K_Line_Set.K_Line_LID20 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x20;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x21: /*EBS/ABS 0：无、1：EBS、2：ABS(CAN应对) 3：ABS (CAN非应对)*/
            K_Line_Set.K_Line_LID21 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x21;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x22: /* EVSC 0：无、1：有 */
            K_Line_Set.K_Line_LID22 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x22;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x23: /* 驻车锁定 0：无、1：有*/
            K_Line_Set.K_Line_LID23 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x23;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x24: /* HSA */
            K_Line_Set.K_Line_LID24 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x24;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x25: /* AEBS */
            K_Line_Set.K_Line_LID25 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x25;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x26: /* ACC */
            K_Line_Set.K_Line_LID26 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x26;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x27: /* LDWS */
            K_Line_Set.K_Line_LID27 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x27;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x28: /* 车辆间报警 */
            K_Line_Set.K_Line_LID28 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x28;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x29: /* 有无巡航 */
            K_Line_Set.K_Line_LID29 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x29;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x2A: /* 气悬 */
            K_Line_Set.K_Line_LID2A = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x2A;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x2B: /* ISS */
            K_Line_Set.K_Line_LID2B = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x2B;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x2C: /* 装货台工作警报蜂鸣器 */
            K_Line_Set.K_Line_LID2C = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x2C;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x2D: /* ROWS */
            K_Line_Set.K_Line_LID2D = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x2D;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x2E: /* 行车记录仪*/
            K_Line_Set.K_Line_LID2E = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x2E;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x2F: /* 车型 */
            K_Line_Set.K_Line_LID2F = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x2F;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x30: /* 缓速器 */
            K_Line_Set.K_Line_LID30 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x30;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x31: /* 地图巡航 */
            K_Line_Set.K_Line_LID31 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x31;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x32: /* 装货台种类 */
            K_Line_Set.K_Line_LID32 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x32;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x33: /* SCR?DPD */
            K_Line_Set.K_Line_LID33 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x33;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x34: /* 驻车种类 */
            K_Line_Set.K_Line_LID34 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x34;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x35: /* 气压计 */
            K_Line_Set.K_Line_LID35 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x35;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x36: /* 低气压报警 */
            K_Line_Set.K_Line_LID36 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x36;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x37: /* 超限警报 */
            K_Line_Set.K_Line_LID37 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x37;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x38: /* 速度警报 */
            K_Line_Set.K_Line_LID38 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x38;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x39: /* 可变SLD */
            K_Line_Set.K_Line_LID39 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x39;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x3A: /* OEM */
            K_Line_Set.K_Line_LID3A = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x3A;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x3B: /*预留 */
            K_Line_Set.K_Line_LID3B = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x3B;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x3C: /* 预留 */
            K_Line_Set.K_Line_LID3C = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x3C;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x3D: /* 预留 */
            K_Line_Set.K_Line_LID3D = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x3D;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x3E: /* 预留 */
            K_Line_Set.K_Line_LID3E = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x3E;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x3F: /* 预留 */
            K_Line_Set.K_Line_LID3F = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x3F;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x40: /* 发动机种类名称 */
            K_Line_Set.K_Line_LID40 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x40;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x41: /* 变速器种类&控制 */
            K_Line_Set.K_Line_LID41 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x41;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x42: /* 驻车管道 */
            K_Line_Set.K_Line_LID42 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x42;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x43: /* 车型 */
            K_Line_Set.K_Line_LID43 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x43;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x44: /* 速度警报 */
            K_Line_Set.K_Line_LID44 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x44;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x45: /* 发动机转速 */
            K_Line_Set.K_Line_LID45 = RequestData[2];
            User_App.User_Speed = K_Line_Set.K_Line_LID45;
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x45;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x46: /* 急加速 */
            K_Line_Set.K_Line_LID46 = RequestData[2];
            User_App.User_JADD = K_Line_Set.K_Line_LID46;
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x46;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x47: /* 急减速 */
            K_Line_Set.K_Line_LID47 = RequestData[2];
            User_App.User_JSUB = K_Line_Set.K_Line_LID47;
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x47;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x48: /* 长时间怠速 */
            K_Line_Set.K_Line_LID48 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x48;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x49: /* 辅助驻车 */
            K_Line_Set.K_Line_LID49 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x49;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x4A: /* 变速箱油 */
            K_Line_Set.K_Line_LID4A = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x4A;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x4B: /* 差速器油 */
            K_Line_Set.K_Line_LID4B = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x4B;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x4C: /* 离合器油 */
            K_Line_Set.K_Line_LID4C = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x4C;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x4D: /* 动力转向油 */
            K_Line_Set.K_Line_LID4D = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x4D;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x4E: /* 轮胎 */
            K_Line_Set.K_Line_LID4E = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x4E;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x4F: /* 机油&滤清器 */
            K_Line_Set.K_Line_LID4F = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x4F;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x50: /* 预留 */
            K_Line_Set.K_Line_LID50 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x50;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x51: /* 工作模式 */
            K_Line_Set.K_Line_LID51 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x51;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;
        case 0x52: /* 电子部件设定 */
            K_Line_Set.K_Line_LID52 = RequestData[2];
            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x52;
            Tx_Len = 2;
            DTCstatusCHGFFK_Line = 1;
            break;

        case 0x91: /*  */
            NVMNODIGIT.No_Digit1 = RequestData[1];
            NVMNODIGIT.No_Digit2 = RequestData[2];
            NVMNODIGIT.No_Digit3 = RequestData[3];
            NVMNODIGIT.No_Digit4 = RequestData[4];
            NVMNODIGIT.No_Digit5 = RequestData[5];
            NVMNODIGIT.No_Digit6 = RequestData[6];
            NVMNODIGIT.No_Digit7 = RequestData[7];
            NVMNODIGIT.No_Digit8 = RequestData[8];
            NVMNODIGIT.No_Digit9 = RequestData[9];
            NVMNODIGIT.No_Digit10 = RequestData[10];

            /*写EEP*/
            // NVM_Data_Update(NVM_NO_DIGIT);   //----ECU ID_ECU件号 eep

            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = RequestData[0];
            Tx_Len = 2;
            break;
        case 0xA0: /*  */
            NVMNODIGIT.TesterECU = RequestData[2];

            if (NVMNODIGIT.METERCOUNT < 0xFF)
            {
                NVMNODIGIT.METERCOUNT++; /*修正率次数增加*/
                /*写EEP*/
                // NVM_Data_Update(NVM_NO_DIGIT);
            }
            else
            {
                NVMNODIGIT.METERCOUNT = 0xFF; /*修正率次数增加*/
                /*写EEP*/
                // NVM_Data_Update(NVM_NO_DIGIT);
            }

            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0xA0;
            Tx_Len = 2;
            break;
        case 0xA3: /*  */
            NVMNODIGIT.TesterECUCAN = RequestData[2];

            if (NVMNODIGIT.METERCOUNT < 0xFF)
            {
                NVMNODIGIT.METERCOUNT++; /*修正率次数增加*/
                /*写EEP*/
                // NVM_Data_Update(NVM_NO_DIGIT);
            }
            else
            {
                NVMNODIGIT.METERCOUNT = 0xFF; /*修正率次数增加*/
                /*写EEP*/
                // NVM_Data_Update(NVM_NO_DIGIT);
            }

            (*TxData++) = KWP2000_WRITEDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0xA3;
            Tx_Len = 2;
            break;
        default: /* subFunctionNotSupported */
            Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
            break;
        }
        return Tx_Len;
    }
    else
    {
        // if ((NVMUserSettings.KLINE == 1u) && (K_LINE_SIGNAL_FLAG.SendSeedEQUSRecvSeed == 0u))
        if (1)
        {
            if (((RequestData[0] >= 0x20) && (RequestData[0] <= 0x52)) || (RequestData[0] == 0x91) || (RequestData[0] == 0xA0) || (RequestData[0] == 0xA3))
                Kwp2000_Negative.ResponseCode = KWP2000_securityAccessDenied;
            else
                Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        }
        else
            Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        return Tx_Len;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : kwp_readDataByLocalIdentifier
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 21
--------------------------------------------------------------------------*/
unsigned char kwp_readDataByLocalIdentifier(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;
    unsigned int ECUStatusCup = 0;
    switch (RequestData[0]) /* subFunction */
    {
    case 0x20: /* 应对ECE R13 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x20;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID20;
        Tx_Len = 4;
        break;
    case 0x21: /* EBS/ABS */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x21;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID21;
        Tx_Len = 4;
        break;
    case 0x22: /* EVSC */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x22;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID22;
        Tx_Len = 4;
        break;
    case 0x23: /* 驻车锁定 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x23;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID23;
        Tx_Len = 4;
        break;
    case 0x24: /* HSA */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x24;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID24;
        Tx_Len = 4;
        break;
    case 0x25: /* AEBS */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x25;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID25;
        Tx_Len = 4;
        break;
    case 0x26: /* ACC */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x26;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID26;
        Tx_Len = 4;
        break;
    case 0x27: /* LDWS */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x27;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID27;
        Tx_Len = 4;
        break;
    case 0x28: /* 车辆间报警 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x28;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID28;
        Tx_Len = 4;
        break;
    case 0x29: /* 有无巡航 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x29;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID29;
        Tx_Len = 4;
        break;
    case 0x2A: /* 气悬 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x2A;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID2A;
        Tx_Len = 4;
        break;
    case 0x2B: /* ISS */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x2B;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID2B;
        Tx_Len = 4;
        break;
    case 0x2C: /* װ装货台工作警报蜂鸣器 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x2C;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID2C;
        Tx_Len = 4;
        break;
    case 0x2D: /* ROWS */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x2D;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID2D;
        Tx_Len = 4;
        break;
    case 0x2E: /* 行车记录仪 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x2E;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID2E;
        Tx_Len = 4;
        break;
    case 0x2F: /* 车型 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x2F;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID2F;
        Tx_Len = 4;
        break;
    case 0x30: /* 缓速器 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x30;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID30;
        Tx_Len = 4;
        break;
    case 0x31: /* 地图巡航 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x31;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID31;
        Tx_Len = 4;
        break;
    case 0x32: /* 装货台种类 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x32;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID32;
        Tx_Len = 4;
        break;
    case 0x33: /*  SCR?DPD */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x33;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID33;
        Tx_Len = 4;
        break;
    case 0x34: /* 驻车种类 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x34;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID34;
        Tx_Len = 4;
        break;
    case 0x35: /* 气压计 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x35;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID35;
        Tx_Len = 4;
        break;
    case 0x36: /* 低压警报 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x36;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID36;
        Tx_Len = 4;
        break;
    case 0x37: /* 超限警报 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x37;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID37;
        Tx_Len = 4;
        break;
    case 0x38: /* 速度警报 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x38;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID38;
        Tx_Len = 4;
        break;
    case 0x39: /* 可变SLD */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x39;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID39;
        Tx_Len = 4;
        break;
    case 0x3A: /* OEM */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x3A;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID3A;
        Tx_Len = 4;
        break;
    case 0x3B: /*  */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x3B;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID3B;
        Tx_Len = 4;
        break;
    case 0x3C: /*  */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x3C;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID3C;
        Tx_Len = 4;
        break;
    case 0x3D: /*  */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x3D;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID3D;
        Tx_Len = 4;
        break;
    case 0x3E: /*  */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x3E;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID3E;
        Tx_Len = 4;
        break;
    case 0x3F: /*  */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x3F;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID3F;
        Tx_Len = 4;
        break;
    case 0x40: /* 发动机种类 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x40;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID40;
        Tx_Len = 4;
        break;
    case 0x41: /* 变速器种类&控制 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x41;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID41;
        Tx_Len = 4;
        break;
    case 0x42: /* 5.2.14.1.4.  驻车管道*/
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x42;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID42;
        Tx_Len = 4;
        break;
    case 0x43: /* 5.2.14.1.5.  车型 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x43;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID43;
        Tx_Len = 4;
        break;
    case 0x44: /* 速度警报 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x44;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID44;
        Tx_Len = 4;
        break;
    case 0x45: /* 发动机转速 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x45;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID45;
        Tx_Len = 4;
        break;
    case 0x46: /* 急加速 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x46;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID46;
        Tx_Len = 4;
        break;
    case 0x47: /* 急减速 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x47;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID47;
        Tx_Len = 4;
        break;
    case 0x48: /* 长时间怠速 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x48;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID48;
        Tx_Len = 4;
        break;
    case 0x49: /* 辅助驻车 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x49;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID49;
        Tx_Len = 4;
        break;
    case 0x4A: /* 变速箱油 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x4A;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID4A;
        Tx_Len = 4;
        break;
    case 0x4B: /* 差速器油 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x4B;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID4B;
        Tx_Len = 4;
        break;
    case 0x4C: /* 离合器油 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x4C;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID4C;
        Tx_Len = 4;
        break;
    case 0x4D: /* 动力转向油 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x4D;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID4D;
        Tx_Len = 4;
        break;
    case 0x4E: /* 轮胎 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x4E;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID4E;
        Tx_Len = 4;
        break;
    case 0x4F: /* 机油&滤清器 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x4F;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID4F;
        Tx_Len = 4;
        break;
    case 0x50: /* 预留 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x50;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID50;
        Tx_Len = 4;
        break;
    case 0x51: /* 5.2.14.1.8.  工作模式 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x51;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID51;
        Tx_Len = 4;
        break;
    case 0x52: /* 5.2.14.1.9.  电子部件设定 */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x52;
        (*TxData++) = 0x00;
        (*TxData++) = K_Line_Set.K_Line_LID52;
        Tx_Len = 4;
        break;

    case 0xA0: /*  */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0xA0;
        (*TxData++) = 0x00;
        (*TxData++) = NVMNODIGIT.TesterECU;
        Tx_Len = 4;
        break;
    case 0xA3: /*  */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0xA3;
        (*TxData++) = 0x00;
        (*TxData++) = NVMNODIGIT.TesterECUCAN;
        Tx_Len = 4;
        break;
    case 0xA1: /*  */
    /*
    NVMNODIGIT.ECUStatus1 = ECUStatusONE.Data[0];

    if (DataVSpeedDisp <= 1275)
        NVMNODIGIT.ECUStatus2 = DataVSpeedDisp / 5 ;

    ECUStatusCup = ECUSTATUST_F ;
    NVMNODIGIT.ECUStatus3 = (unsigned char)(ECUStatusCup & 0xFF);
    NVMNODIGIT.ECUStatus4 = (unsigned char)((ECUStatusCup >> 8) & 0xFF);

    NVMNODIGIT.ECUStatus5 = 0x80;

    (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
    (*TxData++) = 0xA1;
    (*TxData++) = NVMNODIGIT.ECUStatus1;
    (*TxData++) = NVMNODIGIT.ECUStatus2;
    (*TxData++) = NVMNODIGIT.ECUStatus3;
    (*TxData++) = NVMNODIGIT.ECUStatus4;
    (*TxData++) = NVMNODIGIT.ECUStatus5;
    Tx_Len = 7;
    break;
    */
    case 0xA2: /*  */
        (*TxData++) = KWP2000_READDATABYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0xA2;
        (*TxData++) = NVMNODIGIT.METERCOUNT; /*修正率替换次数*/
        Tx_Len = 3;
        break;
    default: /* subFunctionNotSupported */
        Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        break;
    }
    return Tx_Len;
}
/*-------------------------------------------------------------------------
* Function Name  : kwp_readDataByCommonIdentifier
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 22
--------------------------------------------------------------------------*/
unsigned char kwp_readDataByCommonIdentifier(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;
    return Tx_Len;
}
/*-------------------------------------------------------------------------
* Function Name  : kwp_readDataAccessMode
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 27
--------------------------------------------------------------------------*/
unsigned char kwp_readDataAccessMode(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned long SeedKey = 0;
    unsigned char Tx_Len = 0;

    switch (RequestData[0]) /* subFunction */
    {
    case 0x01: /*  */
        // if (NVMUserSettings.KLINE == 1)/*是否锁定标记*/
        if (0)
        {
            /*密钥随机数生成*/
            EOLSeedRandomNumber = EOLSeedRandomNumber * 1024 + 520;
            SeedKey = (unsigned long)EOLSeedRandomNumber;
            SeedKey = SeedKey << 16;
            SeedKey |= (unsigned long)(~EOLSeedRandomNumber);

            Seed1 = (unsigned char)(SeedKey >> 24);
            Seed2 = (unsigned char)(SeedKey >> 16);
            Seed3 = (unsigned char)(SeedKey >> 8);
            Seed4 = (unsigned char)(SeedKey);

            /*计算密钥等待应答*/
            App_Uds_Calc_Key();

            K_LINE_SIGNAL_FLAG.AccessMode2701 = 1;
            AccessMode2701KeyTime = 0;
            AccessMode2701KeyTimeFlag = 1;

            (*TxData++) = KWP2000_SECURITYACCESS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x01;
            (*TxData++) = Seed1;
            (*TxData++) = Seed2;
            (*TxData++) = Seed3;
            (*TxData++) = Seed4;
            Tx_Len = 6;
        }
        else
        {
            Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        }
        break;
    case 0x02: /*  */
        Recvseed1 = RequestData[1];
        Recvseed2 = RequestData[2];
        Recvseed3 = RequestData[3];
        Recvseed4 = RequestData[4];
        if (
            (Sendseed1 == Recvseed1) &&
            (Sendseed2 == Recvseed2) &&
            (Sendseed3 == Recvseed3) &&
            (Sendseed4 == Recvseed4) &&
            (AccessMode2701KeyTimeFlag == 1))
        {
            K_LINE_SIGNAL_FLAG.AccessMode2701 = 0;
            AccessMode2701KeyTimeFlag = 1;

            K_LINE_SIGNAL_FLAG.SendSeedEQUSRecvSeed = 1;
            (*TxData++) = KWP2000_SECURITYACCESS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0x02;
            Tx_Len = 2;
        }
        else
        {
            K_LINE_SIGNAL_FLAG.SendSeedEQUSRecvSeed = 0;
            Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        }
        break;
    default: /* subFunctionNotSupported */
        Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        break;
    }

    return Tx_Len;
}
/*-------------------------------------------------------------------------
* Function Name  : kwp_readDataAccessMode
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 31
--------------------------------------------------------------------------*/
unsigned char kwp_StartroutInebykocalIdentifier(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;
    switch (RequestData[0]) /*  */
    {
    case 0x08: /*  */
        // K_LINE_SIGNAL_FLAG.S_Regist = 1;
        // NVMUserSettings.KLINE = 1 ;
        /*写EEP*/
        // NVM_Data_Update(NVM_USER_SETTINGS);
        (*TxData++) = KWP2000_STARTROUTINEBYLOCALIDENTIFIER_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
        (*TxData++) = 0x08;
        Tx_Len = 2;
        break;
    default: /*  */
        Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        break;
    }
    return Tx_Len;
}
/*-------------------------------------------------------------------------
* Function Name  : kwp_readDataStatusofDTC
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 18
--------------------------------------------------------------------------*/
unsigned char kwp_readDataStatusofDTC(unsigned char *TxData, unsigned char *RequestData)
{
    unsigned char Tx_Len = 0;
    switch (RequestData[0]) /* subFunction */
    {
    case 0x00: /*  */
    /*
    if ((RequestData[1] == 0xFF)&&(RequestData[2] == 0x00))
    {
      (*TxData++) = KWP2000_READDIAGNOSTICTROUBLECODESBYSTATUS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
      (*TxData++) = NVMNODIGIT.NoOfDTCFF00;
      Tx_Len = 2;
    }
    else if ((RequestData[1] == 0x80)&&(RequestData[2] == 0x00))
    {
      (*TxData++) = KWP2000_READDIAGNOSTICTROUBLECODESBYSTATUS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
      (*TxData++) = NVMNODIGIT.NoOfDTC8000;
      Tx_Len = 2;
    }
    else
    {
      Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
    }
    break;
    */
    case 0x01:
    /*
    if ((RequestData[1] == 0xFF)&&(RequestData[2] == 0x00))
    {
      (*TxData++) = KWP2000_READDIAGNOSTICTROUBLECODESBYSTATUS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
      (*TxData++) = NVMNODIGIT.NoOfDTCFF01;
      Tx_Len = 2;
    }
    else if ((RequestData[1] == 0x80)&&(RequestData[2] == 0x00))
    {
      (*TxData++) = KWP2000_READDIAGNOSTICTROUBLECODESBYSTATUS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
      (*TxData++) = NVMNODIGIT.NoOfDTC8001;
      Tx_Len = 2;
    }
    else
    {
      Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
    }
    break;
    */
    case 0x02:
    /*
    if ((RequestData[1] == 0xFF)&&(RequestData[2] == 0x00))
    {
      (*TxData++) = KWP2000_READDIAGNOSTICTROUBLECODESBYSTATUS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
      (*TxData++) = NVMNODIGIT.NoOfDTCFF02;
      Tx_Len = 2;
    }
    else if ((RequestData[1] == 0x80)&&(RequestData[2] == 0x00))
    {
      (*TxData++) = KWP2000_READDIAGNOSTICTROUBLECODESBYSTATUS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
      (*TxData++) = NVMNODIGIT.NoOfDTC8002;
      Tx_Len = 2;
    }
    else
    {
      Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
    }
    break;
    */
    case 0x03:
        if ((RequestData[1] == 0xFF) && (RequestData[2] == 0x00))
        {
            (*TxData++) = KWP2000_READDIAGNOSTICTROUBLECODESBYSTATUS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = NVMNODIGIT.NoOfDTCFF00;
            Tx_Len = 2;
        }
        else if ((RequestData[1] == 0x80) && (RequestData[2] == 0x00))
        {
            (*TxData++) = KWP2000_READDIAGNOSTICTROUBLECODESBYSTATUS_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = NVMNODIGIT.NoOfDTC8000;
            Tx_Len = 2;
        }
        else
        {
            Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        }
        break;
    default: /* subFunctionNotSupported */
        Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        break;
    }
    return Tx_Len;
}
/*-------------------------------------------------------------------------
* Function Name  : kwp_ClearDiagnosticInformation
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         : 14
--------------------------------------------------------------------------*/
unsigned char kwp_ClearDiagnosticInformation(unsigned char *TxData, unsigned char *RequestData)
{

    unsigned char Tx_Len = 0;
    switch (RequestData[0]) /* subFunction */
    {
    case 0xFF: /*  */
        if (RequestData[1] == 0x00)
        {
            (*TxData++) = KWP2000_CLEARDIAGNOSTICINFORMATION_REQUEST + KWP2000_POSITIVE_RESPONSE_OFFSET;
            (*TxData++) = 0xFF;
            (*TxData++) = 0x00;
            // NVMNODIGIT.NoOfDTCFF00 == 0x00;
            Tx_Len = 3;
        }
        else
        {
            Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        }
        break;
    default: /* subFunctionNotSupported */
        Kwp2000_Negative.ResponseCode = KWP2000_subFunctionNotSupported;
        break;
    }
    return Tx_Len;
}
/*-------------------------------------------------------------------------
* Function Name  : App_Uds_Calc_Key
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_Uds_Calc_Key(void)
{
    unsigned char CupChar1 = 0;
    unsigned char CupChar2 = 0;
    unsigned char CupChar3 = 0;
    unsigned char CupChar4 = 0;

    unsigned char CupChar5 = 0;
    unsigned char CupChar6 = 0;
    unsigned char CupChar7 = 0;
    unsigned char CupChar8 = 0;

    unsigned char CupChar9 = 0;
    unsigned char CupChar10 = 0;
    unsigned char CupChar11 = 0;
    unsigned char CupChar12 = 0;

    CupChar1 = Cup_Key(Seed1, 1, Seed1);
    CupChar2 = Cup_Key(Seed2, 2, Seed2);
    CupChar3 = Cup_Key(Seed3, 3, Seed3);
    CupChar4 = Cup_Key(Seed4, 4, Seed4);

    CupChar5 = Cup_Key(CupChar4, 1, Seed1);
    CupChar6 = Cup_Key(CupChar3, 2, Seed2);
    CupChar7 = Cup_Key(CupChar2, 3, Seed3);
    CupChar8 = Cup_Key(CupChar1, 4, Seed4);

    CupChar9 = Cup_Key(CupChar8, 1, Seed1);
    CupChar10 = Cup_Key(CupChar7, 2, Seed2);
    CupChar11 = Cup_Key(CupChar6, 3, Seed3);
    CupChar12 = Cup_Key(CupChar5, 4, Seed4);

    Sendseed4 = Cup_Key(CupChar12, 1, Seed1);
    Sendseed3 = Cup_Key(CupChar11, 2, Seed2);
    Sendseed2 = Cup_Key(CupChar10, 3, Seed3);
    Sendseed1 = Cup_Key(CupChar9, 4, Seed4);
}

unsigned char Cup_Key(unsigned char KLineseed, unsigned char Num, unsigned char Seed)
{
    unsigned char CupCharL = 0;
    unsigned char CupCharR = 0;

    CupCharL = KLineseed;
    CupCharR = KLineseed;

    CupCharL = (CupCharL << Num);
    CupCharR = (CupCharR >> (8 - Num));
    CupCharL = (CupCharL | CupCharR);

    CupCharL = (CupCharL ^ Seed);

    CupCharL = (~CupCharL);

    CupCharL = BitReplace(CupCharL);

    return CupCharL;
}

unsigned char BitReplace(unsigned char Data)
{
    unsigned char i = 0;
    unsigned char temp = 0;

    for (i = 0; i < 8; i++)
    {
        temp = temp << 1;
        temp |= (Data >> i) & 0x01;
    }

    return temp;
}