#include "TP_Layer.h"
#include "app_Service.h"
#include "Link_Layer.h"
#include "UDS_def.h"

#include "UDS_CFG.h"
#include "app_ServiceProc.h"
#include <string.h>


#define GLOBALS_UDS_CFG
#define GLOBALS_USER_DEF

volatile _DiagnoCtl DiagnoCtl;  //诊断当前状态
volatile _N_USData Exct_USData; //报文接收的ID数据
volatile _DiagClock DiagClock;
volatile _ErrorFrame Error; //错误信息
_DiagReciveDTC DiagReciveDTC;
_DiagReciveGaugePara DiagReciveGaugePara;
//volatile uint32_t CrcCheckSum;

uint8_t NormalCanSt = 0;
uint8_t NMCanSt = 0;

/*-------------------------------------------------------------------------
* Function Name  : DiagnosisInit_main
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void DiagnosisInit_main(void)
{
    N_US_R_MultiData.ind.N_Result = STATE0;
    N_US_S_MultiData.ind.N_Result = STATE0;
    N_USSFData[0].ind.N_Result = STATE0;
    N_USSFData[1].ind.N_Result = STATE0;
    Exct_USData.ind.N_Result = STATE0;
    N_RSPData.ind.N_Result = STATE0;
    LinkDataBuf[0].TransferStatus = empoty;
    LinkDataBuf[1].TransferStatus = empoty;

    DiagnoCtl.SubFunction = 0;
    DiagnoCtl.CommCtl = SubEnableRxAndTx;
    DiagnoCtl.SessionType = DefSession;
    DiagnoCtl.AccessLock = Lock;
    DiagnoCtl.N_REV_MAX_BS = MaxBuff / 8;
    DiagnoCtl.N_STmin_0 = 20;
    DiagnoCtl.DTCSettingType = DtcSetOn;
    DiagnoCtl.tDiagStart = 0;
    DiagnoCtl.DTCByStatusMask = 0x09; //0x08已确认的诊断故障代码
    //0x01测试失败

    Error.FrameErr = 0;

    TP_SetSTminTimer(DiagnoCtl.N_STmin_0, (_DiagClock *)&DiagClock);
}
/*-------------------------------------------------------------------------
* Function Name  : App_Load_DTCNum
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_Load_DTCNum(uint32_t *DtcNum, uint8_t *data)
{
    *(DtcNum) = data[0];
    *(DtcNum) = *(DtcNum) << 8;
    *(DtcNum) |= data[1];
    *(DtcNum) = *(DtcNum) << 8;
    *(DtcNum) |= data[2];
    //*(DtcNum) = *(DtcNum);
}

/*-------------------------------------------------------------------------
* Function Name  : Diagnosis_main
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void Diagnosis_main(void)
{
    TP_Buffer_handle();
    if (LinkData.TransferStatus == full)
    {
        TP_ReciveSF_handle();
        TP_ReciveMultiF_handle();

        TP_NormalRecFC_handle();
        LinkData.TransferStatus = empoty;
    }

    TP_NormalSendFC_Fun();

    if (N_USSFData[0].ind.N_Result == N_OK_2)
    {
        App_CopyRam((uint8_t *)&Exct_USData, (uint8_t *)&N_USSFData[0], sizeof(_N_USSFData));
        Exct_USData.ind.N_Result = N_OK_2;
        N_USSFData[0].ind.N_Result = STATE0;
    }
    else if ((N_USSFData[1].ind.N_Result == N_OK_2) && (Exct_USData.ind.N_Result == STATE0))
    {
        App_CopyRam((uint8_t *)&Exct_USData, (uint8_t *)&N_USSFData[1], sizeof(_N_USSFData));
        Exct_USData.ind.N_Result = N_OK_2;
        N_USSFData[1].ind.N_Result = STATE0;
    }
    else if ((N_US_R_MultiData.ind.N_Result == N_OK_2) && (Exct_USData.ind.N_Result == STATE0) &&
             (N_US_S_MultiData.ind.N_Result == STATE0))
    {
        App_CopyRam((uint8_t *)&Exct_USData, (uint8_t *)&N_US_R_MultiData, sizeof(_N_USData));
        N_US_R_MultiData.ind.N_Result = STATE0;
    }

    if (N_US_S_Data_FF.ind.N_PCI == FC_WAIT)
    {
        if (TP_BsTimerOver((_DiagClock *)&DiagClock))
        {
            N_US_S_MultiData.ind.N_Result = N_TIMEOUT_Bs_6;
        }
    }

    if (N_US_S_MultiData.ind.N_Result == STATE0)
    {
        DiagClock.TT_BsEnable = 0;
        N_US_S_Data_FF.ind.N_FC_Num = 0;
    }

    if (N_US_R_MultiData.ind.N_Result == N_OK_2)
    {
        N_US_R_Data_FF.ind.pos = 0;
        N_US_R_Data_FF.ind.N_PCI = 0;
    }
    if ((N_US_R_MultiData.ind.N_Result == N_TIMEOUT_Bs_6) || (N_US_R_MultiData.ind.N_Result == N_WRONG_SN_9))
    {
        N_US_R_MultiData.ind.N_Result = STATE0;
        N_US_R_Data_FF.ind.pos = 0;
        N_US_R_Data_FF.ind.N_PCI = 0;
        N_US_R_Data_FF.ind.N_RecSN_L = 0;
    }

    if ((N_US_S_MultiData.ind.N_Result == N_TIMEOUT_Bs_6) ||
            (N_US_S_MultiData.ind.N_Result == OVFLW) ||
            (N_US_S_MultiData.ind.N_Result == N_INVALID_FS_8))
    {
        N_US_S_MultiData.ind.N_Result = STATE0;
        N_US_S_Data_FF.ind.N_PCI = 0;
        N_US_S_Data_FF.ind.N_SID = 0;
        N_US_S_Data_FF.ind.N_BS_CNT = 0;
    }

    if (App_SessionTimerOver((_DiagClock *)&DiagClock))
    {
        DiagnoCtl.SessionType = DefSession;
        DiagnoCtl.A5_Sequence = 0;
        //  DiagnoCtl.SubFunction = SubHardReset;
    }
    if (App_ReUnlockTimerOver((_DiagClock *)&DiagClock))
    {
        DiagnoCtl.AccessCount = 0;
    }
    if (DiagnoCtl.SessionType == DefSession)
    {
        DiagnoCtl.AccessLock = Lock;
        DiagnoCtl.CommCtl = SubEnableRxAndTx;
        DiagnoCtl.CommType = NOR_NM_Message;

        DiagnoCtl.DTCSettingType = DtcSetOn;
    }

    if (Exct_USData.ind.N_Result == N_OK_2)
    {
        switch (Exct_USData.ind.N_TAtype)
        {


        case ID_BCM_ResAddr:
            switch (Exct_USData.ind.MsgData[0])
            {
            case ReqReadDtcId:
                App_59_service((_N_USData *)&Exct_USData); //
                break;
            case ReqReadDataId:
                App_62_service((_N_USData *)&Exct_USData); //
                break;
            case ReqProgMilId:
                App_01_service((_N_USData *)&Exct_USData);
                break;
            default:

                /* Error.N_TAtype = ID_PhyAddr;
                Error.FrameErr = ServiceNotSupported; //服务不支持
                Error.RespSerId = Exct_USData.ind.MsgData[0];*/
                break;
            }
            break;

        //case ID_PhyAddr:
        //    switch (Exct_USData.ind.MsgData[0])
        //    {
        //    case ReqSessionCtlId:
        //        App_10_service((_N_USData*)&Exct_USData);
        //        break;
        //    case ReqECUResetId:
        //        App_11_service((_N_USData*)&Exct_USData);
        //        break;
        //    default:

        //        /* Error.N_TAtype = ID_PhyAddr;
        //        Error.FrameErr = ServiceNotSupported; //服务不支持
        //        Error.RespSerId = Exct_USData.ind.MsgData[0];*/
        //        break;
        //    }
        //    break;
        default:
            ;
        }
        Exct_USData.ind.N_Result = STATE0;
    }

    TP_TransmitPDU(); //仪表诊断回复
    App_11_Reset_handle();
}

/*-------------------------------------------------------------------------
* Function Name  : App_10_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_10_service(_N_USData *AppUSData)
{
    _SubFun SubFun;

    App_ErrorInfoInit((_N_USData *)AppUSData);

    SubFun.SubData = AppUSData->ind.MsgData[1];

    if (AppUSData->ind.Length == 0x02) //请求命令的字节长度 2个  10 01
    {
        if (DiagnoCtl.SessionType == SubDefSession) //当前为默认会话模式
        {
            if ((SubFun.SubBits.SubFunBit0_6 & 0xf) == SubDefSession) //请求命令子功能 01
            {
                DiagnoCtl.AccessLock = Lock;        //上锁
                DiagnoCtl.SessionType = DefSession; //默认模式
                if (DiagnoCtl.SessionType != SubFun.SubBits.SubFunBit0_6)
                {
                    DiagnoCtl.SessionType = SubFun.SubBits.SubFunBit0_6;
                    DiagnoCtl.A5_Sequence = 0;
                }
            }
            else if ((SubFun.SubBits.SubFunBit0_6 & 0xf) == SubExtSession) //请求命令子功能 03
            {
                DiagnoCtl.AccessLock = Lock;
                if (DiagnoCtl.SessionType != SubFun.SubBits.SubFunBit0_6)
                {
                    DiagnoCtl.SessionType = SubFun.SubBits.SubFunBit0_6;
                    DiagnoCtl.A5_Sequence = 0;
                }

                App_SetSessionTimer(N_Session, (_DiagClock *)&DiagClock);
            }
            else
            {
                Error.FrameErr = SubFunctionNotSupported; //子功能不支持 10 04
            }
        }
        else if (DiagnoCtl.SessionType == SubExtSession) //当前编程模式
        {
            if ((SubFun.SubBits.SubFunBit0_6 & 0xf) == SubDefSession)
            {
                DiagnoCtl.AccessLock = Lock;
                DiagnoCtl.SessionType = DefSession;
                if (DiagnoCtl.SessionType != SubFun.SubBits.SubFunBit0_6)
                {
                    DiagnoCtl.SessionType = SubFun.SubBits.SubFunBit0_6;
                    DiagnoCtl.A5_Sequence = 0;
                }
            }
            else if ((SubFun.SubBits.SubFunBit0_6 & 0xf) == SubExtSession)
            {
                DiagnoCtl.AccessLock = Lock;
                if (DiagnoCtl.SessionType != SubFun.SubBits.SubFunBit0_6)
                {
                    DiagnoCtl.SessionType = SubFun.SubBits.SubFunBit0_6;
                    DiagnoCtl.A5_Sequence = 0;
                }

                App_SetSessionTimer(N_Session, (_DiagClock *)&DiagClock);
            }
            else if ((SubFun.SubBits.SubFunBit0_6 & 0xf) == SubProgSession)
            {
                DiagnoCtl.AccessLock = Lock;
                if (DiagnoCtl.SessionType != SubFun.SubBits.SubFunBit0_6)
                {
                    DiagnoCtl.SessionType = SubFun.SubBits.SubFunBit0_6;
                    DiagnoCtl.A5_Sequence = 0;

                    DiagnoCtl.SubFunction = SubHardReset;
                }

                App_SetSessionTimer(N_Session, (_DiagClock *)&DiagClock);
            }
            else
            {
                Error.FrameErr = SubFunctionNotSupported; //子功能不支持
            }
        }
        else if (DiagnoCtl.SessionType == SubProgSession) //当前为扩展模式
        {
            if ((SubFun.SubBits.SubFunBit0_6 & 0xf) == SubDefSession)
            {
                DiagnoCtl.AccessLock = Lock;
                DiagnoCtl.SessionType = DefSession;
                if (DiagnoCtl.SessionType != SubFun.SubBits.SubFunBit0_6)
                {
                    DiagnoCtl.SessionType = SubFun.SubBits.SubFunBit0_6;
                    DiagnoCtl.A5_Sequence = 0;
                }
                DiagnoCtl.SubFunction = SubHardReset;
            }
            else if ((SubFun.SubBits.SubFunBit0_6 & 0xf) == SubProgSession)
            {
                DiagnoCtl.AccessLock = Lock;
                if (DiagnoCtl.SessionType != SubFun.SubBits.SubFunBit0_6)
                {
                    DiagnoCtl.SessionType = SubFun.SubBits.SubFunBit0_6;
                    DiagnoCtl.A5_Sequence = 0;
                }

                App_SetSessionTimer(N_Session, (_DiagClock *)&DiagClock);
            }
            else
            {
                Error.FrameErr = SubFunctionNotSupported; //子功能不支持
            }
        }
    }
    else
    {
        Error.FrameErr = ErrFormatLength; //长度不对
    }

    //格式正确,返回正确      头 + 50 01 00 32 01 F4
    if (Error.FrameErr == 0)
    {
        if (!SubFun.SubBits.SubFunBit7_7) //请求命令子功能 第7位为0
        {
            N_RSPData.ind.len = 7;                                       //7个字节
            N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;            //头
            N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40; //50
            N_RSPData.ind.MsgData[2] = SubFun.SubBits.SubFunBit0_6;      //01
            N_RSPData.ind.MsgData[3] = 0x00;
            N_RSPData.ind.MsgData[4] = 0x32;
            N_RSPData.ind.MsgData[5] = 0x01;
            N_RSPData.ind.MsgData[6] = 0xF4;

            N_RSPData.ind.N_Result = N_OK_2; //正确
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_11_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_11_service(_N_USData *AppUSData)
{
    _SubFun SubFun;

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if ((DiagnoCtl.SessionType == ExtSession) ||
            (DiagnoCtl.SessionType == ProgSession))
    {
        if (AppUSData->ind.Length > 1)
        {
            SubFun.SubData = AppUSData->ind.MsgData[1];
            switch (SubFun.SubBits.SubFunBit0_6)
            {
            case SubHardReset: //11 01
                if (AppUSData->ind.Length == 0x02)
                {
                    DiagnoCtl.SubFunction = SubHardReset;
                }
                else
                {
                    Error.FrameErr = ErrFormatLength; //长度不对
                }
                break;
            case SubKeyOffOnReset: //11 02
                if (AppUSData->ind.Length == 0x02)
                {
                    DiagnoCtl.SubFunction = SubKeyOffOnReset;
                }
                else
                {
                    Error.FrameErr = ErrFormatLength; //长度不对
                }
                break;
            case SubSoftReset: //11 03
                if (AppUSData->ind.Length == 0x02)
                {
                    DiagnoCtl.SubFunction = SubSoftReset;
                }
                else
                {
                    Error.FrameErr = ErrFormatLength; //长度不对
                }
                break;
            default:
                Error.FrameErr = SubFunctionNotSupported; //子功能不支持
            }
        }
        else
        {
            Error.FrameErr = ErrFormatLength; //长度不对
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession;
    }
    if (Error.FrameErr == 0)
    {
        if (!SubFun.SubBits.SubFunBit7_7)
        {
            N_RSPData.ind.len = 3;
            N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
            N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
            N_RSPData.ind.MsgData[2] = SubFun.SubBits.SubFunBit0_6;
            N_RSPData.ind.N_Result = N_OK_2;
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_85_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_85_service(_N_USData *AppUSData)
{
    _SubFun SubFun;

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if (DiagnoCtl.SessionType == ExtSession)
    {
        if (AppUSData->ind.Length > 1)
        {
            SubFun.SubData = AppUSData->ind.MsgData[1];

            switch (SubFun.SubBits.SubFunBit0_6)
            {
            case DtcSetOn:
                if (AppUSData->ind.Length == 0x02)
                {
                    DiagnoCtl.DTCSettingType = SubFun.SubBits.SubFunBit0_6;
                }
                else
                {
                    Error.FrameErr = ErrFormatLength; //长度不对
                }
                break;
            case DtcSetOff:
                if (AppUSData->ind.Length == 0x02)
                {
                    DiagnoCtl.DTCSettingType = SubFun.SubBits.SubFunBit0_6;
                }
                else
                {
                    Error.FrameErr = ErrFormatLength; //长度不对
                }

                break;
            default:
                Error.FrameErr = SubFunctionNotSupported; //子功能不支持
            }
        }
        else
        {
            Error.FrameErr = ErrFormatLength; //长度不对
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession;
    }
    if (Error.FrameErr == 0)
    {
        if (!SubFun.SubBits.SubFunBit7_7)
        {
            N_RSPData.ind.len = 3;
            N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
            N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
            N_RSPData.ind.MsgData[2] = SubFun.SubBits.SubFunBit0_6;
            N_RSPData.ind.N_Result = N_OK_2;
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_27_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_27_service(_N_USData *AppUSData)
{

    uint16_t ret;

    _SubFun SubFun;

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if ((DiagnoCtl.SessionType == ProgSession) || (DiagnoCtl.SessionType == SubExtSession))
    {
        if (AppUSData->ind.Length > 0x01)
        {
            SubFun.SubData = AppUSData->ind.MsgData[1];
            switch (SubFun.SubBits.SubFunBit0_6)
            {
            case SubReqSeed1: //27 01
            case SubReqSeed5: //27 05
                if (AppUSData->ind.Length == 0x02)
                {

                    if (!SubFun.SubBits.SubFunBit7_7)
                    {
                        N_RSPData.ind.len = 7;
                        N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;            //06
                        N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40; //67
                        N_RSPData.ind.MsgData[2] = SubFun.SubBits.SubFunBit0_6;      //01
                        if ((DiagnoCtl.AccessLock == UnLockLv1) || (DiagnoCtl.AccessLock == UnLockLv4))
                        {
                            N_RSPData.ind.MsgData[3] = 0; //如果已经解锁,则回复0
                            N_RSPData.ind.MsgData[4] = 0;
                            N_RSPData.ind.MsgData[5] = 0;
                            N_RSPData.ind.MsgData[6] = 0;
                        }
                        else
                        {
                        }
                        N_RSPData.ind.N_Result = N_OK_2;
                    }
                    if (SubFun.SubBits.SubFunBit0_6 == SubReqSeed5) //27 _05
                    {
                    }
                    if (SubFun.SubBits.SubFunBit0_6 == SubReqSeed1) //27 _01
                    {
                    }

                    DiagnoCtl.w27_Sequence = SubFun.SubBits.SubFunBit0_6;

                    if (DiagClock.TT_UnlockEnable)
                    {
                        N_RSPData.ind.len = 4;
                        N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
                        N_RSPData.ind.MsgData[1] = NegativeId;
                        N_RSPData.ind.MsgData[2] = AppUSData->ind.MsgData[0];
                        N_RSPData.ind.MsgData[3] = ReqTimeDelayNotExpired;
                        N_RSPData.ind.N_Result = N_OK_2;
                    }
                }
                else
                {
                    Error.FrameErr = ErrFormatLength; //长度不对
                }
                break;
            case SubSendKey2: //27 02 解锁
            case SubSendKey6: //27 06 解锁
                if (((DiagnoCtl.w27_Sequence == SubReqSeed1) && (SubFun.SubBits.SubFunBit0_6 == SubSendKey2)) ||
                        ((DiagnoCtl.w27_Sequence == SubReqSeed3) && (SubFun.SubBits.SubFunBit0_6 == SubSendKey4)) ||
                        ((DiagnoCtl.w27_Sequence == SubReqSeed5) && (SubFun.SubBits.SubFunBit0_6 == SubSendKey6)) ||
                        ((DiagnoCtl.w27_Sequence == SubReqSeed7) && (SubFun.SubBits.SubFunBit0_6 == SubSendKey8)))
                {
                    DiagnoCtl.w27_Sequence = SubFun.SubBits.SubFunBit0_6;
                    if (!DiagClock.TT_UnlockEnable)
                    {
                        if (AppUSData->ind.Length == 0x06)
                        {
                            if (DiagnoCtl.AccessCount < 5)
                            {
                                DiagnoCtl.AccessCount++;
                            }

                            if (ret == 0)
                            {
                                if (!SubFun.SubBits.SubFunBit7_7)
                                {
                                    N_RSPData.ind.len = 3;
                                    N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
                                    N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
                                    N_RSPData.ind.MsgData[2] = SubFun.SubBits.SubFunBit0_6;
                                    N_RSPData.ind.N_Result = N_OK_2;
                                }
                                if (DiagnoCtl.AccessCount <= 3)
                                {
                                    if (SubFun.SubBits.SubFunBit0_6 == SubSendKey2) //27 _02
                                    {
                                        DiagnoCtl.AccessLock = UnLockLv1; //解锁
                                    }

                                    else if (SubFun.SubBits.SubFunBit0_6 == SubSendKey6) //27 _06
                                    {
                                        DiagnoCtl.AccessLock = UnLockLv4; //解锁
                                    }
                                    /* else if (SubFun.SubBits.SubFunBit0_6 == SubSendKey8)
                                        {
                                            DiagnoCtl.AccessLock = UnLockLv4;
                                        }*/

                                    DiagnoCtl.AccessCount = 0;
                                }
                            }
                        }
                        else
                        {
                            Error.FrameErr = ErrFormatLength;
                        }
                    }
                }
                else
                {
                    Error.FrameErr = ReqSequenceError;
                }
                break;
            default:
                Error.FrameErr = SubFunctionNotSupported; //子功能不支持
            }

            if (Error.FrameErr == 0)
            {
                if ((DiagnoCtl.w27_Sequence == SubSendKey2) || (DiagnoCtl.w27_Sequence == SubSendKey6))
                {
                    DiagnoCtl.w27_Sequence = 0;

                    if ((DiagnoCtl.AccessLock != UnLockLv1) && (DiagnoCtl.AccessLock != UnLockLv4))
                    {
                        if (DiagnoCtl.AccessCount <= 1)
                        {
                            N_RSPData.ind.len = 4;
                            N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
                            N_RSPData.ind.MsgData[1] = NegativeId;
                            N_RSPData.ind.MsgData[2] = AppUSData->ind.MsgData[0];
                            N_RSPData.ind.MsgData[3] = InvalidKey; //秘钥错误
                            N_RSPData.ind.N_Result = N_OK_2;
                        }
                        if (DiagnoCtl.AccessCount >= 2)
                        {
                            N_RSPData.ind.len = 4;
                            N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
                            N_RSPData.ind.MsgData[1] = NegativeId;
                            N_RSPData.ind.MsgData[2] = AppUSData->ind.MsgData[0];
                            N_RSPData.ind.MsgData[3] = ExceedNumberOfAttempts;
                            N_RSPData.ind.N_Result = N_OK_2;

                            if (!DiagClock.TT_UnlockEnable)
                            {
                                App_SetReUnlockTimer(N_Unlock, (_DiagClock *)&DiagClock);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            Error.FrameErr = ErrFormatLength; //长度不对
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession; //此会话不支持功能
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_31_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_31_service(_N_USData *AppUSData)
{

    uint8_t data = 1;
    uint16_t DID;

    _SubFun SubFun;

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if ((DiagnoCtl.SessionType == ProgSession) || (DiagnoCtl.SessionType == SubExtSession))
    {
        if (AppUSData->ind.Length > 0x01)
        {
            SubFun.SubData = AppUSData->ind.MsgData[1];
            switch (SubFun.SubBits.SubFunBit0_6)
            {
            case 1: //startRoutine
                if (AppUSData->ind.Length >= 4)
                {
                    App_Load_DID((uint16_t *)&DID, (uint8_t *)&AppUSData->ind.MsgData[2]);
                    if ((DiagnoCtl.AccessLock == UnLockLv1) || (DiagnoCtl.AccessLock == UnLockLv4))
                    {

                        if (DID == 0xFF00) //eraseMemory
                        {
                            if (AppUSData->ind.Length == 13)
                            {
                                if (AppUSData->ind.MsgData[4] == 0x44)
                                {
                                }
                                else
                                {
                                    Error.FrameErr = RequestOutOfRange;
                                }
                            }
                            else
                            {
                                Error.FrameErr = ErrFormatLength; //长度不对
                            }
                        }

                        else if (DID == 0xFF01) //checkProgrammingDependencies
                        {
                            if (AppUSData->ind.Length == 4)
                            {
                            }
                            else
                            {
                                Error.FrameErr = ErrFormatLength; //长度不对
                            }
                        }
                        else
                        {
                            Error.FrameErr = RequestOutOfRange;
                        }
                    }
                    else
                    {
                        Error.FrameErr = SecurityAccessDenied;
                    }
                }
                else
                {
                    Error.FrameErr = ErrFormatLength; //长度不对
                }
                break;
            case 2: //stopRoutine
                if (AppUSData->ind.Length == 4)
                {
                    App_Load_DID((uint16_t *)&DID, (uint8_t *)&AppUSData->ind.MsgData[2]);
                    if ((DiagnoCtl.AccessLock == UnLockLv1) || (DiagnoCtl.AccessLock == UnLockLv4))
                    {

                        if (DID == 0xFF00)
                        {
                        }

                        else
                        {
                            Error.FrameErr = RequestOutOfRange;
                        }
                    }
                    else
                    {
                        Error.FrameErr = SecurityAccessDenied;
                    }
                }
                else
                {
                    Error.FrameErr = ErrFormatLength; //长度不对
                }
                break;
            case 3: //requestRoutineResults
                if ((DiagnoCtl.AccessLock == UnLockLv1) || (DiagnoCtl.AccessLock == UnLockLv4))
                {

                    //  data = 1;
                }
                break;
            default:;
            }
        }
        else
        {
            Error.FrameErr = ErrFormatLength; //长度不对
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession;
    }

    if (Error.FrameErr == 0)
    {
        if (!SubFun.SubBits.SubFunBit7_7)
        {
            N_RSPData.ind.len = 5;
            if (DID == 0x0203)
                N_RSPData.ind.len = 8;
            N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
            N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
            N_RSPData.ind.MsgData[2] = SubFun.SubBits.SubFunBit0_6;
            N_RSPData.ind.MsgData[3] = (uint8_t)(DID >> 8);
            N_RSPData.ind.MsgData[4] = (uint8_t)DID;
            N_RSPData.ind.MsgData[5] = data;
            N_RSPData.ind.MsgData[6] = 0;
            N_RSPData.ind.MsgData[7] = 0;

            //N_RSPData.ind.N_Result = N_OK_2;

            (void)memcpy((uint8_t *)N_US_S_MultiData.ind.MsgData, (uint8_t *)(N_RSPData.ind.MsgData + 1), N_RSPData.ind.len);
            if (N_RSPData.ind.len >= 8)
            {
                N_US_S_Data_FF.ind.Length = N_RSPData.ind.len;
                N_US_S_Data_FF.ind.N_PCI = FirstFrame;
            }
            else
            {
                N_US_S_MultiData.ind.Length = N_RSPData.ind.len;
                N_US_S_Data_FF.ind.N_PCI = 0;
            }
            N_US_S_MultiData.ind.N_Result = N_OK_2;
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_34_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_34_service(_N_USData *AppUSData)
{

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if (DiagnoCtl.SessionType == ProgSession)
    {
        if (DiagnoCtl.AccessLock == UnLockLv4)
        {
            if (AppUSData->ind.Length == 11)
            {
            }
            else
            {
                Error.FrameErr = ErrFormatLength; //长度不对
            }
        }
        else
        {
            Error.FrameErr = SecurityAccessDenied;
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession;
    }
    if (DiagnoCtl.AccessLock == UnLockLv4)
    {
        if (Error.FrameErr == 0)
        {
            N_RSPData.ind.len = 5;
            N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
            N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
            N_RSPData.ind.MsgData[2] = 0x20;
            N_RSPData.ind.MsgData[3] = 0x00;
            N_RSPData.ind.MsgData[4] = 128;

            N_RSPData.ind.N_Result = N_OK_2;
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_36_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_36_service(_N_USData *AppUSData)
{

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if (DiagnoCtl.SessionType == ProgSession)
    {
        if (DiagnoCtl.AccessLock == UnLockLv4)
        {
            if ((AppUSData->ind.Length > 2) && (AppUSData->ind.Length <= 1024))
            {
            }
            else
            {
                Error.FrameErr = ErrFormatLength; //长度不对
            }
        }
        else
        {
            Error.FrameErr = SecurityAccessDenied;
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession;
    }

    if (Error.FrameErr == 0)
    {
        N_RSPData.ind.len = 3;
        N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
        N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
        N_RSPData.ind.MsgData[2] = AppUSData->ind.MsgData[1];

        N_RSPData.ind.N_Result = N_OK_2;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_37_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_37_service(_N_USData *AppUSData)
{
    App_ErrorInfoInit((_N_USData *)AppUSData);
    if (DiagnoCtl.SessionType == ProgSession)
    {
        if (DiagnoCtl.AccessLock == UnLockLv4)
        {
            if (AppUSData->ind.Length == 1)
            {
            }
            else
            {
                Error.FrameErr = ErrFormatLength; //长度不对
            }
        }
        else
        {
            Error.FrameErr = SecurityAccessDenied;
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession;
    }

    if (Error.FrameErr == 0)
    {
        N_RSPData.ind.len = 2;
        N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
        N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;

        N_RSPData.ind.N_Result = N_OK_2;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_28_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_28_service(_N_USData *AppUSData)
{
    _SubFun SubFun;

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if (DiagnoCtl.SessionType == ExtSession)
    {
        if (AppUSData->ind.Length > 1)
        {
            SubFun.SubData = AppUSData->ind.MsgData[1];
            switch (SubFun.SubBits.SubFunBit0_6) //子功能判断
            {

            case SubEnableRxAndTx:                 //28 00
                if (AppUSData->ind.Length == 0x03) //长度为3
                {
                    if (AppUSData->ind.MsgData[2] == NOR_Message) //28 00 01 应用报文
                    {
                        DiagnoCtl.CommCtl = SubEnableRxAndTx; //使能接收发送
                        DiagnoCtl.CommType = NOR_Message;
                    }
                    else if (AppUSData->ind.MsgData[2] == NM_Message) //28 00 02 网络管理报文
                    {
                        DiagnoCtl.CommCtl = SubEnableRxAndTx; //使能接收发送
                        DiagnoCtl.CommType = NM_Message;
                    }
                    else if (AppUSData->ind.MsgData[2] == NOR_NM_Message) //28 00 03 应用和网络管理报文
                    {
                        DiagnoCtl.CommCtl = SubEnableRxAndTx; //使能接收发送
                        DiagnoCtl.CommType = NOR_NM_Message;
                    }
                    else
                    {
                        Error.FrameErr = RequestOutOfRange; //超出范围
                    }
                }
                else
                {
                    Error.FrameErr = RequestOutOfRange; //超出范围
                }
                break;
            case SubDisableRxAndTx: //28 03
                if (AppUSData->ind.Length == 0x03)
                {
                    if (AppUSData->ind.MsgData[2] == NOR_Message) //28 03 01  应用报文
                    {
                        DiagnoCtl.CommCtl = SubDisableRxAndTx; //关闭
                        DiagnoCtl.CommType = NOR_Message;
                    }
                    else if (AppUSData->ind.MsgData[2] == NM_Message) //28 03 02 网络管理报文
                    {
                        DiagnoCtl.CommCtl = SubDisableRxAndTx; //关闭
                        DiagnoCtl.CommType = NM_Message;
                    }
                    else if (AppUSData->ind.MsgData[2] == NOR_NM_Message) //28 03 03 应用和网络管理报文
                    {
                        DiagnoCtl.CommCtl = SubDisableRxAndTx; //关闭
                        DiagnoCtl.CommType = NOR_NM_Message;
                    }
                    else
                    {
                        Error.FrameErr = RequestOutOfRange;
                    }
                }
                else
                {
                    Error.FrameErr = RequestOutOfRange;
                }
                break;
            default:
                Error.FrameErr = SubFunctionNotSupported; //子功能不支持
            }
        }
        else
        {
            Error.FrameErr = ErrFormatLength; //长度不对
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession;
    }
    if (Error.FrameErr == 0)
    {
        N_RSPData.ind.len = 3;
        N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
        N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
        N_RSPData.ind.MsgData[2] = SubFun.SubBits.SubFunBit0_6;

        N_RSPData.ind.N_Result = N_OK_2;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_22_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_62_service(_N_USData *AppUSData)
{

    uint16_t DID;
    App_ErrorInfoInit((_N_USData *)AppUSData);
    //获取DID
    App_Load_DID((uint16_t *)&DID, (uint8_t *)&AppUSData->ind.MsgData[1]);
    if (AppUSData->ind.Length > 1)
    {

        switch (DID)
        {
        case DID0005: //读-当前会话模式
            App_CopyRam((uint8_t *)&DiagReciveGaugePara.CoolantTemp, (uint8_t *)&AppUSData->ind.MsgData[3], (AppUSData->ind.Length - 3));
            //Reset_CoolantTemp_Signal_Time();
            break;

        default:
            break;
        }
    }
}

/*-------------------------------------------------------------------------
* Function Name  : App_2E_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/

void App_2E_service(_N_USData *AppUSData)
{
    uint16_t DID;

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if ((DiagnoCtl.SessionType == ExtSession) || ((DiagnoCtl.SessionType == ProgSession)))
    {
        if ((DiagnoCtl.AccessLock == UnLockLv1) || (DiagnoCtl.AccessLock == UnLockLv4))
        {
            if (AppUSData->ind.Length > 1)
            {
                App_Load_DID((uint16_t *)&DID, (uint8_t *)&AppUSData->ind.MsgData[1]);
            }
            else
            {
                Error.FrameErr = ErrFormatLength;
            }
        }
        else
        {
            Error.FrameErr = SecurityAccessDenied;
        }

        if ((DiagnoCtl.AccessLock == UnLockLv1) || ((DiagnoCtl.AccessLock == UnLockLv4)))
        {
            if (Error.FrameErr == 0)
            {
                N_RSPData.ind.len = 4;
                N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
                N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
                N_RSPData.ind.MsgData[2] = (uint8_t)(DID >> 8);
                N_RSPData.ind.MsgData[3] = (uint8_t)(DID);
                N_RSPData.ind.N_Result = N_OK_2;
            }
        }
        else
        {
            Error.FrameErr = SecurityAccessDenied;
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_14_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_14_service(_N_USData *AppUSData)
{

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if (Error.FrameErr == 0)
    {
        N_RSPData.ind.len = 2;
        N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
        N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
        N_RSPData.ind.N_Result = N_OK_2;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_19_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_59_service(_N_USData *AppUSData)
{
    uint16_t DID;
    App_ErrorInfoInit((_N_USData *)AppUSData);
    //获取DID
    App_Load_DID((uint16_t *)&DID, (uint8_t *)&AppUSData->ind.MsgData[1]);
    (void)memset((uint8_t *)&DiagReciveDTC.UnionDTC, 0, sizeof(_DiagReciveDTC));
    if (AppUSData->ind.Length > 1)
    {

        if (AppUSData->ind.MsgData[1] == 0x02)
        {
            App_CopyRam((uint8_t *)&DiagReciveDTC.UnionDTC, (uint8_t *)&AppUSData->ind.MsgData[3], (AppUSData->ind.Length - 3));
        }
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_2F_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_2F_service(_N_USData *AppUSData)
{
    uint8_t InOutCtrlParameter;
    uint16_t DID;
    uint16_t MsgLen = 4;
    App_ErrorInfoInit((_N_USData *)AppUSData);

    if (DiagnoCtl.SessionType == ExtSession) //2F + DID + 控制参数 + INfo
    {
        if ((DiagnoCtl.AccessLock == UnLockLv1) || (DiagnoCtl.AccessLock == UnLockLv4)) //解锁
        {
            if (AppUSData->ind.Length > 1)
            {
                App_Load_DID((uint16_t *)&DID, (uint8_t *)&AppUSData->ind.MsgData[1]);

                InOutCtrlParameter = AppUSData->ind.MsgData[3]; //2F 10 01 _03..+ 1byte

                if (Error.FrameErr == 0)
                {
                }
            }
            else
            {
                Error.FrameErr = ErrFormatLength; //长度不对
            }
            if (Error.FrameErr == 0)
            {
                N_US_S_MultiData.ind.MsgData[0] = AppUSData->ind.MsgData[0] + 0x40;
                N_US_S_MultiData.ind.MsgData[1] = (uint8_t)(DID >> 8);
                N_US_S_MultiData.ind.MsgData[2] = (uint8_t)DID;
                N_US_S_MultiData.ind.MsgData[3] = InOutCtrlParameter;

                if (MsgLen >= 8)
                {
                    N_US_S_Data_FF.ind.Length = MsgLen;
                    N_US_S_Data_FF.ind.N_PCI = FirstFrame;
                }
                else
                {
                    N_US_S_MultiData.ind.Length = MsgLen;
                    N_US_S_Data_FF.ind.N_PCI = 0;
                }
                N_US_S_MultiData.ind.N_Result = N_OK_2;
            }
        }
        else
        {
            Error.FrameErr = SecurityAccessDenied;
        }
    }
    else
    {
        Error.FrameErr = NotSuppInActiveSession;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_3E_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_3E_service(_N_USData *AppUSData)
{
    _SubFun SubFun;

    App_ErrorInfoInit((_N_USData *)AppUSData);

    if (AppUSData->ind.Length > 1)
    {
        SubFun.SubData = AppUSData->ind.MsgData[1];

        switch (SubFun.SubBits.SubFunBit0_6)
        {
        case SubZeroFun0:
            if (AppUSData->ind.Length == 0x02)
            {
                if (!SubFun.SubBits.SubFunBit7_7)
                {
                    N_RSPData.ind.len = 3;
                    N_RSPData.ind.MsgData[0] = N_RSPData.ind.len - 1;
                    N_RSPData.ind.MsgData[1] = AppUSData->ind.MsgData[0] + 0x40;
                    N_RSPData.ind.MsgData[2] = SubFun.SubBits.SubFunBit0_6;
                    N_RSPData.ind.N_Result = N_OK_2;
                }
                App_SetSessionTimer(N_Session, (_DiagClock *)&DiagClock);
            }
            else
            {
                Error.FrameErr = ErrFormatLength; //长度不对
            }
            break;
        default:
            Error.FrameErr = SubFunctionNotSupported; //子功能不支持
        }
    }
    else
    {
        Error.FrameErr = ErrFormatLength; //长度不对
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_19_service
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_01_service(_N_USData *AppUSData)
{

    if (AppUSData->ind.Length == 0x06)
    {
        if (AppUSData->ind.MsgData[1] == 1)
        {
            DiagReciveGaugePara.MilLamp = 1;

        }
        else
        {
            DiagReciveGaugePara.MilLamp = 0;
        }
        //Reset_Mil_Signal_Time();
        //DelfuModuleIn();
    }
    else
    {
        ;
    }
}
/*-------------------------------------------------------------------------
* Function Name  : App_SetSequenceTimer
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_SetSequenceTimer(uint32_t Second, _DiagClock *T)
{
    T->TT_SequenceEnable = 1;
    T->OverSequenceTime = Second;
    T->SequenceTime = 0;
}
/*-------------------------------------------------------------------------
* Function Name  : App_SequenceTimerOver
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
uint8_t App_SequenceTimerOver(_DiagClock *T)
{
    if ((T->SequenceTime >= T->OverSequenceTime) && (T->TT_SequenceEnable))
    {
        T->TT_SequenceEnable = 0;
        T->SequenceTime = 0;
        return 1;
    }
    else
    {
        return 0;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : App_SetSessionTimer
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_SetSessionTimer(uint32_t Second, _DiagClock *T)
{
    T->TT_SessionEnable = 1;
    T->OverSessionTime = Second;
    T->SessionTime = 0;
}
/*-------------------------------------------------------------------------
* Function Name  : Api_TTimerOver3
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
uint8_t App_SessionTimerOver(_DiagClock *T)
{
    if ((T->SessionTime >= T->OverSessionTime) && (T->TT_SessionEnable))
    {
        T->TT_SessionEnable = 0;
        T->SessionTime = 0;
        return 1;
    }
    else
    {
        return 0;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : App_SetReUnlockTimer
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void App_SetReUnlockTimer(uint32_t Second, _DiagClock *T)
{
    T->TT_UnlockEnable = 1;
    T->OverUnlockTime = Second;
    T->UnlockTime = 0;
}
/*-------------------------------------------------------------------------
* Function Name  : App_ReUnlockTimerOver
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
uint8_t App_ReUnlockTimerOver(_DiagClock *T)
{
    if ((T->UnlockTime >= T->OverUnlockTime) && (T->TT_UnlockEnable))
    {
        T->TT_UnlockEnable = 0;
        T->UnlockTime = 0;
        return 1;
    }
    else
    {
        return 0;
    }
}