#include "UDS_19Service_Main.h"

/**
  *19服务函数入口
  *@param A_TA_type 收到数据的地址
  *@param A_Length 收到数据的长度
  *@param A_Data 收到数据的数据
  */
void UDS_Service_19_Indication(uint32_t A_TA_type, uint16_t A_Length, uint8_t A_Data[])
{
    uint8_t NRC = positiveResponse;
    setDiagMSG(A_TA_type, A_Length, A_Data);
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_NRC11();                                            /*19服务是否支持功能寻址*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_NRC7F();                                            /*19服务会话是否支持验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_NRC33();                                            /*19服务解锁等级验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_NRC13_MinLengthCheck();                             /*19服务最小长度验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_NRC31();                                            /*19服务超出请求范围验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_NRC13_TotalLengthCheck();                           /*19服务总长度长度验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_NRC22();                                            /*19服务条件验证*/
    }
    if (NRC == positiveResponse)
    {
        UDS_19Service_Sub();                                                    /*19服务子功能*/
    }
    clearDiagMSG();                                                             /*清除诊断信息*/
}

/**
  *19服务子功能
  */
void UDS_19Service_Sub(void)
{
    uint8_t NRC = positiveResponse;
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_Sub_NRC13_MinLengthCheck();                         /*19服务子功能最小长度验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_Sub_NRC12();                                        /*19服务子功能是否支持验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_Sub_NRC7E();                                        /*19服务子功能会话是否支持验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_Sub_NRC31();                                        /*19服务子功能超出请求范围验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_Sub_NRC13_TotalLengthCheck();                       /*19服务子功能总长度长度验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_Sub_NRC24();                                        /*19服务子功能请求顺序验证*/
    }
    if (NRC == positiveResponse)
    {
        NRC = UDS_19Service_Sub_NRC22();                                        /*19服务子功能条件验证*/
    }
    if (NRC == positiveResponse)
    {
        switch (DiagMSG.msgData.SidDetail.SubID)                                /*子服务判断*/
        {
        case ReportNumberOfDTCByStatusMask:
            UDS_19Service_Sub01();                                              /*19服务01子功能*/
            break;
        case ReportDTCByStatusMask:
            UDS_19Service_Sub02();                                              /*19服务02子功能*/
            break;
        case ReportDTCSnapshotRecordByDTCNumber:
            UDS_19Service_Sub04();                                              /*19服务04子功能*/
            break;
        case ReportSupportedDTC:
            UDS_19Service_Sub0A();                                              /*19服务0A子功能*/
            break;
        default:
            break;
        }
    }
}

/**
  *19服务01子功能
  */
void UDS_19Service_Sub01(void)
{
    uint8_t  i = 0u;
    uint8_t  DTCStatus = 0u;
    uint16_t DTCCount = 0u;
    for (i = 0u; i < sizeof(DTCToDFlashInfo.DTC) / sizeof(DTCUnion); ++i)
    {
        if(DTCList[i][1u])
        {
            DTCStatus = DTCToDFlashInfo.DTC[i].DTCStatus & DTCMask;
            if (DTCStatus & DiagMSG.msgData.SidDetail.Data[0])
            {
                ++DTCCount;
            }
        }
    }
    DiagMSG.msgData.SidDetail.Data[0] = DTCMask;
    DiagMSG.msgData.SidDetail.Data[1] = 0x00u;
    DiagMSG.msgData.SidDetail.Data[2] = (uint8_t)(DTCCount >> 8);
    DiagMSG.msgData.SidDetail.Data[3] = (uint8_t)(DTCCount);
    UDS_Service_Response(0x19u, POSITIVE_RSP, DIAG_ID_Tx, 5u, DiagMSG.msgData.Data);
}

/**
  *19服务02子功能
  */
void UDS_19Service_Sub02(void)
{
    uint8_t  i = 0u;
    uint8_t  DTCStatus = 0u;
    uint16_t count = 1u;
    uint32_t DTC = 0u;
    for (i = 0u; i < sizeof(DTCToDFlashInfo.DTC) / sizeof(DTCUnion); ++i)
    {
        if(DTCList[i][1u])
        {
            DTCStatus = DTCToDFlashInfo.DTC[i].DTCStatus & DTCMask;
            if (DTCStatus & DiagMSG.msgData.SidDetail.Data[0])
            {
                DTC = getDTCNumber(i);
                DiagMSG.msgData.SidDetail.Data[count++] = (uint8_t)(DTC >> 16u);
                DiagMSG.msgData.SidDetail.Data[count++] = (uint8_t)(DTC >> 8u);
                DiagMSG.msgData.SidDetail.Data[count++] = (uint8_t)(DTC);
                DiagMSG.msgData.SidDetail.Data[count++] = DTCStatus;
            }
        }
    }
    DiagMSG.msgData.SidDetail.Data[0] = DTCMask;
    UDS_Service_Response(0x19u, POSITIVE_RSP, DIAG_ID_Tx, count + 1u, DiagMSG.msgData.Data);
}

/**
  *19服务04子功能
  */
void UDS_19Service_Sub04(void)
{
    uint8_t  NRC;
    uint8_t  DTCcount = 0u;
    uint8_t  DTCStatus = 0u;
    uint32_t DTC = 0u;
    DTC = toUint32_t(0x00u, DiagMSG.msgData.SidDetail.Data[0], DiagMSG.msgData.SidDetail.Data[1], DiagMSG.msgData.SidDetail.Data[2]);
    DTCcount = getDTCCount(DTC);
    if (DTCcount < (sizeof(DTCList) / sizeof(DTCList[0u])))
    {
        DTCStatus = DTCToDFlashInfo.DTC[DTCcount].DTCStatus;//状态码需要修改
        DiagMSG.msgData.SidDetail.Data[3] = DTCStatus & DTCMask;
        if((uint8_t)(DTCStatus & DTCErrorLastClear) == DTCErrorLastClear)
        {
            DiagMSG.msgData.SidDetail.Data[4] = 0x01u;
            DiagMSG.msgData.SidDetail.Data[5] = 0x07u;
            DiagMSG.msgData.SidDetail.Data[6] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data[7] = 0x00u;
            DiagMSG.msgData.SidDetail.Data[8] = (DTCToDFlashInfo.DTC[DTCcount].Snapshot.ECUPowerVoltage >> 8u);
            DiagMSG.msgData.SidDetail.Data[9] = DTCToDFlashInfo.DTC[DTCcount].Snapshot.ECUPowerVoltage;            
            DiagMSG.msgData.SidDetail.Data[10] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data[11] = 0x01u;
            DiagMSG.msgData.SidDetail.Data[12] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.VehicleSpeed >> 8u);
            DiagMSG.msgData.SidDetail.Data[13] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.VehicleSpeed);
            DiagMSG.msgData.SidDetail.Data[14] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data[15] = 0x02u;
            DiagMSG.msgData.SidDetail.Data[16] = DTCToDFlashInfo.DTC[DTCcount].Snapshot.OccurrenceCounter;
            DiagMSG.msgData.SidDetail.Data[17] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data[18] = 0x03u;
            DiagMSG.msgData.SidDetail.Data[19] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.FirstMalfunction >> 16u);
            DiagMSG.msgData.SidDetail.Data[20] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.FirstMalfunction >> 8u);
            DiagMSG.msgData.SidDetail.Data[21] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.FirstMalfunction);
            DiagMSG.msgData.SidDetail.Data[22] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data[23] = 0x04u;
            DiagMSG.msgData.SidDetail.Data[24] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.LastMalfunction >> 16u);
            DiagMSG.msgData.SidDetail.Data[25] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.LastMalfunction >> 8u);
            DiagMSG.msgData.SidDetail.Data[26] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.LastMalfunction);
            DiagMSG.msgData.SidDetail.Data[27] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data[28] = 0x05u;
            DiagMSG.msgData.SidDetail.Data[29] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.EngineSpeed >> 8);
            DiagMSG.msgData.SidDetail.Data[30] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.EngineSpeed);
            /*DiagMSG.msgData.SidDetail.Data[30] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data[31] = 0x04u;
            DiagMSG.msgData.SidDetail.Data[32] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.PowerRange);*/
            DiagMSG.msgData.SidDetail.Data[31] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data[32] = 0x10u;
            DiagMSG.msgData.SidDetail.Data[33] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.TimeOfFailure_S);
            DiagMSG.msgData.SidDetail.Data[34] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.TimeOfFailure_Min);
            DiagMSG.msgData.SidDetail.Data[35] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.TimeOfFailure_Hr);
            DiagMSG.msgData.SidDetail.Data[36] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.TimeOfFailure_Month);
            DiagMSG.msgData.SidDetail.Data[37] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.TimeOfFailure_Day);
            DiagMSG.msgData.SidDetail.Data[38] = (uint8_t)(DTCToDFlashInfo.DTC[DTCcount].Snapshot.TimeOfFailure_Year);
            UDS_Service_Response(0x19u, POSITIVE_RSP, DIAG_ID_Tx, 40u, DiagMSG.msgData.Data);
        }
        else
        {
            UDS_Service_Response(0x19u, POSITIVE_RSP, DIAG_ID_Tx, 5u, DiagMSG.msgData.Data);
        }
    } 
    else
    {
        NRC = requestOutOfRange;
        if(DiagMSG.msgID == DIAG_ID_Rx_PHY)
        {
            UDS_Service_Response(0x19u, NEGATIVE_RSP, DIAG_ID_Tx, 1u, (uint8_t*)&NRC);
        }
    }
}

/**
  *19服务0A子功能
  */
void UDS_19Service_Sub0A(void)
{
    uint8_t  i = 0u;
    uint8_t  DTCStatus = 0u;
    uint16_t count = 0u;
    uint32_t DTC = 0u;
    DiagMSG.msgData.SidDetail.Data[count++] = DTCMask;
    for (i = 0u; i < sizeof(DTCToDFlashInfo.DTC) / sizeof(DTCUnion); ++i)
    {
        if(DTCList[i][1u])
        {
            DTC = getDTCNumber(i);
            DTCStatus = DTCToDFlashInfo.DTC[i].DTCStatus & DTCMask;
            DiagMSG.msgData.SidDetail.Data[count++] = (uint8_t)(DTC >> 16u);
            DiagMSG.msgData.SidDetail.Data[count++] = (uint8_t)(DTC >> 8u);
            DiagMSG.msgData.SidDetail.Data[count++] = (uint8_t)(DTC);
            DiagMSG.msgData.SidDetail.Data[count++] = DTCStatus;
        }
        
    }
    UDS_Service_Response(0x19u, POSITIVE_RSP, DIAG_ID_Tx, count + 1u, DiagMSG.msgData.Data);
}