#include "UDS_19Service_Main.h"

/**
  *19���������
  *@param A_TA_type �յ����ݵĵ�ַ
  *@param A_Length �յ����ݵij���
  *@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);
    if ( DiagMSG.msgData.SidDetail.PositiveSuppression == 0u )
    {
        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;
    if ( DiagMSG.msgData.SidDetail.PositiveSuppression == 0u )
    {
        UDS_Service_Response(0x19u, POSITIVE_RSP, DIAG_ID_Tx, count + 1u, DiagMSG.msgData.Data);
    }
}

/**
  *19����04�ӹ���
  */
void UDS_19Service_Sub04(void)
{
    #if 0
    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 & DTCMask;
        DiagMSG.msgData.SidDetail.Data [ 3 ] = DTCStatus;
        if ( ( uint8_t )(DTCStatus & DTCConfirmed) == DTCConfirmed )
        {
            DiagMSG.msgData.SidDetail.Data [ 4 ]  = 0x01u;
            DiagMSG.msgData.SidDetail.Data [ 5 ]  = 0x05u;
            DiagMSG.msgData.SidDetail.Data [ 6 ]  = 0xDFu;
            DiagMSG.msgData.SidDetail.Data [ 7 ]  = 0x01u;
            DiagMSG.msgData.SidDetail.Data [ 8 ]  = ( uint8_t )(DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.OdometerValue >> 16u);
            DiagMSG.msgData.SidDetail.Data [ 9 ]  = ( uint8_t )(DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.OdometerValue >> 8u);
            DiagMSG.msgData.SidDetail.Data [ 10 ] = ( uint8_t )(DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.OdometerValue);
            DiagMSG.msgData.SidDetail.Data [ 11 ] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data [ 12 ] = 0x02u;
            DiagMSG.msgData.SidDetail.Data [ 13 ] = DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.SystemSupplyVoltage;
            DiagMSG.msgData.SidDetail.Data [ 14 ] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data [ 15 ] = 0x03u;
            DiagMSG.msgData.SidDetail.Data [ 16 ] = ( uint8_t )(DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.VehicleSpeed >> 8u);
            DiagMSG.msgData.SidDetail.Data [ 17 ] = ( uint8_t )(DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.VehicleSpeed);
            DiagMSG.msgData.SidDetail.Data [ 18 ] = 0xDFu;
            DiagMSG.msgData.SidDetail.Data [ 19 ] = 0x04u;
            DiagMSG.msgData.SidDetail.Data [ 20 ] = DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.DTCLocalTime_second;
            DiagMSG.msgData.SidDetail.Data [ 21 ] = DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.DTCLocalTime_minute;
            DiagMSG.msgData.SidDetail.Data [ 22 ] = DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.DTCLocalTime_hour;
            DiagMSG.msgData.SidDetail.Data [ 23 ] = DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.DTCLocalTime_day;
            DiagMSG.msgData.SidDetail.Data [ 24 ] = DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.DTCLocalTime_month;
            DiagMSG.msgData.SidDetail.Data [ 25 ] = DTCToDFlashInfo.DTC [ DTCcount ].Snapshot.DTCLocalTime_year;
            if ( DiagMSG.msgData.SidDetail.PositiveSuppression == 0u )
            {
                UDS_Service_Response(0x19u, POSITIVE_RSP, DIAG_ID_Tx, 1 + 26u, DiagMSG.msgData.Data);
            }
        }
        else
        {
            if ( DiagMSG.msgData.SidDetail.PositiveSuppression == 0u )
            {
                UDS_Service_Response(0x19u, POSITIVE_RSP, DIAG_ID_Tx, 1 + 4u, DiagMSG.msgData.Data);
            }
        }
    }
    #endif
}

/**
  *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;
        }
    }
    if ( DiagMSG.msgData.SidDetail.PositiveSuppression == 0u )
    {
        UDS_Service_Response(0x19u, POSITIVE_RSP, DIAG_ID_Tx, count + 1u, DiagMSG.msgData.Data);
    }
}