/******************************************************************************
锟斤拷 锟斤拷 锟斤拷锟斤拷UDS_ISO14229_Server.c
锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷ISO 14229 锟芥范锟芥定锟斤拷锟斤拷戏锟斤拷锟斤拷锟斤拷锟斤拷锟剿猴拷锟斤拷锟斤拷锟侥硷拷
锟斤拷    锟竭ｏ拷锟斤拷锟斤拷
锟斤拷    锟斤拷锟斤拷V1.0
锟斤拷    锟节ｏ拷2016.11.1
******************************************************************************/
#include "UDS_ISO14229_Server.h"
#include "UDS_ISO14229_Client.h"

UDS_APP_RX_Union UDS_APP_RX;

extern uint8_t CAN_Current_state;

#define POSITIVE_RSP 0
#define NEGATIVE_RSP 1
/******************************************************************************
锟斤拷台锟斤拷锟斤拷
******************************************************************************/
/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_Server_Application_Service
锟斤拷  锟杰ｏ拷UDS锟斤拷锟斤拷锟斤拷应锟矫诧拷锟斤拷品锟斤拷锟?
锟斤拷  锟斤拷锟斤拷锟斤拷
锟斤拷锟斤拷值锟斤拷锟斤拷
*******************************************************************************
注  锟解：锟矫凤拷锟斤拷锟斤拷锟斤拷锟诫被实时锟斤拷锟斤拷
******************************************************************************/
void UDS_Server_Application_Service(void)
{
    UDS_Process_Service_Request( );
}

/******************************************************************************
锟结话锟斤拷锟铰诧拷涌诩锟斤拷锟绞憋拷锟斤拷锟绞碉拷锟?
******************************************************************************/

/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_N_USData_Request
锟斤拷  锟杰ｏ拷锟矫凤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷
        This service is used to request the transfer of data. If necessary, the
        network layer segments the data.
锟斤拷  锟斤拷锟斤拷N_TAtype    锟斤拷目锟斤拷锟街凤拷锟斤拷锟?,锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷使锟斤拷 DIAG_ID_Tx
        MessageData 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟?
        Length      锟斤拷锟斤拷锟捷筹拷锟斤拷
锟斤拷锟斤拷值锟斤拷锟斤拷
******************************************************************************/
void UDS_N_USData_Request(uint32_t N_TAtype, uint8_t *MessageData, uint16_t Length)
{
    DoCAN_N_USData_Request(N_TAtype, MessageData, Length);

    /*锟斤拷时*/
}

/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_N_USData_Confirm
锟斤拷  锟杰ｏ拷锟矫凤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷惴?拷锟?,锟斤拷锟斤拷确锟斤拷前一锟斤拷使锟斤拷N_USData.request锟斤拷锟斤拷锟斤拷
        N_TAtype锟斤拷址锟斤拷锟酵碉拷锟斤拷锟斤拷锟角凤拷锟斤拷锟斤拷锟?
        The N_USData.confirm service is issued by the network layer. The service
        primitive confirms the completion of an N_USData.request service
        identified by the address information in N_TAtype.
锟斤拷  锟斤拷锟斤拷N_TAtype 锟斤拷N_USData.confirm锟斤拷锟斤拷锟斤拷锟斤拷姆锟斤拷偷锟街?
        N_Result 锟斤拷N_USData.request锟斤拷锟斤拷拇锟斤拷锟阶刺?
锟斤拷锟斤拷值锟斤拷锟斤拷
******************************************************************************/
extern void UDS_N_USData_Confirm(uint32_t N_TAtype, N_ResultEnum N_Result)
{
    if ( N_Result == N_OK )
    {
        UDS_S_Data_Confirm(N_TAtype, S_OK);
    }
    else
    {
        UDS_S_Data_Confirm(N_TAtype, S_NOK);
    }

    /*锟斤拷时*/
}

/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_N_USData_FF_Indication
锟斤拷  锟杰ｏ拷锟矫凤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷惴?拷锟?,锟斤拷锟斤拷锟斤拷锟较诧拷指示锟斤拷址为N_TAtype锟斤拷一锟斤拷锟街★拷锟斤拷莸锟斤拷锟街?
        锟侥碉拷锟斤拷
        The N_USData_FF.indication service is issued by the network layer. The
        service primitive indicates to the adjacent upper layer the arrival of
        a FirstFrame (FF) of a segmented message received from a peer protocol
        entity, identified by the address information N_TAtype.
锟斤拷  锟斤拷锟斤拷N_TAtype 锟斤拷锟铰碉拷锟侥讹拷帧锟斤拷锟斤拷锟斤拷帧锟侥碉拷址锟斤拷息
        Length   锟斤拷锟铰碉拷锟侥讹拷帧锟斤拷锟捷碉拷锟杰筹拷锟斤拷
锟斤拷锟斤拷值锟斤拷锟斤拷
******************************************************************************/
extern void UDS_N_USData_FF_Indication(uint32_t N_TAtype, uint16_t Length)
{

    /*锟斤拷时*/
}

/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_N_USData_Indication
锟斤拷  锟杰ｏ拷锟矫凤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷惴?拷锟?,锟斤拷锟斤拷锟斤拷锟较诧拷指锟斤拷锟斤拷N_TAtype锟斤拷址锟斤拷锟斤拷锟斤拷锟侥筹拷锟斤拷为Length
        锟斤拷MessageData锟斤拷锟捷的达拷锟酵斤拷锟絅_Result,锟斤拷同时锟斤拷锟斤拷锟斤拷一锟斤拷锟斤拷
        The N_USData.indication service is issued by the network layer. The
        service primitive indicates <N_Result> events and delivers
        <MessageData> with <Length> bytes received from a peer protocol entity
        identified by the address information in N_TAtype to the adjacent upper
        layer.
锟斤拷  锟斤拷锟斤拷N_TAtype    锟斤拷锟斤拷锟秸碉拷锟斤拷锟斤拷锟捷碉拷址锟斤拷息
        MessageData 锟斤拷锟斤拷锟秸碉拷锟斤拷锟斤拷锟斤拷      (锟斤拷锟斤拷N_Result为N_OK时锟斤拷效)
        Length      锟斤拷锟斤拷锟秸碉拷锟斤拷锟斤拷锟捷筹拷锟斤拷  (锟斤拷锟斤拷N_Result为N_OK时锟斤拷效)
        N_Result    锟斤拷锟斤拷锟捷的斤拷锟秸斤拷锟?
锟斤拷锟斤拷值锟斤拷锟斤拷
******************************************************************************/
void UDS_N_USData_Indication(uint32_t N_TAtype, uint8_t *MessageData, uint16_t Length, N_ResultEnum N_Result)
{
    if ( N_Result == N_OK )
    {
        UDS_S_Data_Indication(N_TAtype, MessageData, Length, S_OK);
    }
    else
    {
        UDS_S_Data_Indication(N_TAtype, MessageData, Length, S_NOK);
    }

    /*锟斤拷时*/
}

/******************************************************************************
锟结话锟斤拷锟较诧拷涌锟?
******************************************************************************/

/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_S_Data_Request
锟斤拷  锟杰ｏ拷锟矫凤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷目锟斤拷锟街稴_TAtype锟斤拷锟酵筹拷锟斤拷为S_Length锟斤拷S_Data.
        The service primitive requests transmission of S_Data with S_Length
        number of bytes from the sender to the receiver peer entities
        identified by the address information in S_TAtype.
锟斤拷  锟斤拷锟斤拷S_TAtype 锟斤拷锟斤拷锟斤拷锟斤拷锟捷碉拷目锟斤拷锟街?
        S_Data   锟斤拷锟斤拷锟酵碉拷锟斤拷锟斤拷
        S_Length 锟斤拷锟斤拷锟捷的筹拷锟斤拷
锟斤拷锟斤拷值锟斤拷锟斤拷
******************************************************************************/
void UDS_S_Data_Request(uint32_t S_TAtype, uint8_t *S_Data, uint16_t S_Length)
{
    UDS_N_USData_Request(S_TAtype, S_Data, S_Length);
}

/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_S_Data_Request
锟斤拷  锟杰ｏ拷锟矫凤拷锟斤拷锟缴会话锟姐发锟斤拷,锟斤拷锟斤拷指锟斤拷锟斤拷S_TAtype为目锟斤拷锟街凤拷锟絊_Data.request锟斤拷锟斤拷锟斤拷锟斤拷
        锟角凤拷锟斤拷锟?
        The S_Data.confirm service is issued by the session layer. The service
        primitive confirms the completion of an S_Data.request service
        identified by the address information in S_TAtype.
锟斤拷  锟斤拷锟斤拷S_TAtype 锟斤拷锟斤拷锟斤拷锟斤拷锟捷碉拷目锟斤拷锟街?
        S_Result 锟斤拷锟斤拷锟捷的凤拷锟酵斤拷锟?
锟斤拷锟斤拷值锟斤拷锟斤拷
******************************************************************************/
void UDS_S_Data_Confirm(uint32_t S_TAtype, S_Result_Enum S_Result)
{
    if ( S_TAtype == DIAG_ID_Tx )
    {
        if ( S_Result == S_NOK )
        {
            UDS_TP_ArTimeOutHandle( );
        }
    }
}

/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_S_Data_Request
锟斤拷  锟杰ｏ拷锟矫凤拷锟斤拷锟缴会话锟姐发锟斤拷,锟斤拷锟斤拷锟斤拷锟较诧拷指锟斤拷S_Result锟斤拷锟斤拷状态锟皆硷拷锟斤拷锟捷达拷S_TAtype锟斤拷址
        锟斤拷锟秸碉拷锟斤拷S_Length锟斤拷锟饺碉拷S_Data锟斤拷锟斤拷

        The S_Data.indication service is issued by the session layer. The
        service primitive indicates S_Result events and delivers S_Data with
        S_Length bytes received from a peer protocol entity identified by the
        address information in S_TAtype to the adjacent upper layer.
锟斤拷  锟斤拷锟斤拷S_TAtype 锟斤拷锟斤拷锟秸碉拷锟斤拷锟斤拷锟捷碉拷址锟斤拷息
        S_Data   锟斤拷锟斤拷锟秸碉拷锟斤拷锟斤拷锟斤拷      (锟斤拷锟斤拷S_Result为S_OK时锟斤拷效)
        S_Length 锟斤拷锟斤拷锟秸碉拷锟斤拷锟斤拷锟捷筹拷锟斤拷  (锟斤拷锟斤拷S_Result为S_OK时锟斤拷效)
        S_Result 锟斤拷锟斤拷锟捷的斤拷锟秸斤拷锟?
锟斤拷锟斤拷值锟斤拷锟斤拷
******************************************************************************/
void UDS_S_Data_Indication(uint32_t S_TAtype, uint8_t S_Data [], uint16_t S_Length, S_Result_Enum S_Result)
{
    uint16_t i;

    if ( S_Result == S_OK )
    {
        UDS_APP_RX.Data.New     = 1u;
        UDS_APP_RX.Data.TA_type = S_TAtype;
        UDS_APP_RX.Data.Length  = S_Length - 1u;

        for ( i = 0u; i < S_Length; i++ )
        {
            UDS_APP_RX.Data.A_Data [ i ] = S_Data [ i ];
        }
    }
    else if ( S_Result == S_NOK )
    {
        UDS_TP_ArTimeOutHandle( );
    }
    else
    {
    }
}

/******************************************************************************
应锟矫诧拷锟斤拷锟斤拷锟斤拷
******************************************************************************/

/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_Process_Service_Request
锟斤拷  锟杰ｏ拷锟矫猴拷锟斤拷锟斤拷锟节达拷锟斤拷锟斤拷锟皆客伙拷锟剿的凤拷锟斤拷锟斤拷锟斤拷,锟斤拷锟斤拷锟铰的凤拷锟斤拷锟斤拷锟襟到达拷时,锟斤拷锟斤拷SI选锟斤拷锟斤拷
        应锟侥凤拷锟斤拷实锟街猴拷锟斤拷执锟叫凤拷锟斤拷
锟斤拷  锟斤拷锟斤拷锟斤拷
锟斤拷锟斤拷值锟斤拷锟斤拷  SYSC0_RUNPLL2CNTR
******************************************************************************/
void UDS_Process_Service_Request(void)
{
    uint8_t NRC = 0x7f;
    if ( UDS_APP_RX.A_PDU.New )
    {
        switch ( UDS_APP_RX.A_PDU.A_PCI.SI )
        {
            case 0x50:
                UDS_Service_50_Indication(UDS_APP_RX.A_PDU.TA_type, UDS_APP_RX.A_PDU.Length, UDS_APP_RX.A_PDU.Data);
                break;
            case 0x51:
                UDS_Service_51_Indication(UDS_APP_RX.A_PDU.TA_type, UDS_APP_RX.A_PDU.Length, UDS_APP_RX.A_PDU.Data);
                break;
            case 0x59:
                UDS_Service_59_Indication(UDS_APP_RX.A_PDU.TA_type, UDS_APP_RX.A_PDU.Length, UDS_APP_RX.A_PDU.Data);
                break;   
            case 0x62:
                UDS_Service_62_Indication(UDS_APP_RX.A_PDU.TA_type, UDS_APP_RX.A_PDU.Length, UDS_APP_RX.A_PDU.Data);
                break;
            case 0x6E:
                UDS_Service_6E_Indication(UDS_APP_RX.A_PDU.TA_type, UDS_APP_RX.A_PDU.Length, UDS_APP_RX.A_PDU.Data);
                break;
            case 0x67:
                UDS_Service_67_Indication(UDS_APP_RX.A_PDU.TA_type, UDS_APP_RX.A_PDU.Length, UDS_APP_RX.A_PDU.Data);
                break;
            case 0x6F:
                UDS_Service_6F_Indication(UDS_APP_RX.A_PDU.TA_type, UDS_APP_RX.A_PDU.Length, UDS_APP_RX.A_PDU.Data);
            case 0x7E:
                UDS_Service_7E_Indication(UDS_APP_RX.A_PDU.TA_type, UDS_APP_RX.A_PDU.Length, UDS_APP_RX.A_PDU.Data);
                break;

            case 0x7F:
                UDS_Service_7F_Indication(UDS_APP_RX.A_PDU.TA_type, UDS_APP_RX.A_PDU.Length, UDS_APP_RX.A_PDU.Data);
                break;

            default:




                if ( UDS_APP_RX.A_PDU.TA_type != DIAG_ID_Rx_FUN )
                {
                    NRC = 0x7f; /*锟斤拷锟斤拷支锟斤拷*/
                    UDS_Service_Response(UDS_APP_RX.A_PDU.A_PCI.SI, NEGATIVE_RSP, DIAG_ID_Tx, 1u, ( uint8_t * )&NRC);
                }

                break;
        }
        UDS_APP_RX.A_PDU.New = 0u;
    }
}

/******************************************************************************
锟斤拷锟斤拷锟斤拷锟斤拷UDS_Service_Response
锟斤拷  锟杰ｏ拷锟矫猴拷锟斤拷锟斤拷锟捷凤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷应锟侥凤拷锟斤拷锟斤拷锟捷达拷锟捷革拷锟酵伙拷锟斤拷,通锟斤拷锟节革拷锟斤拷锟斤拷锟斤拷姆锟斤拷锟?
锟斤拷  锟斤拷锟斤拷si        锟斤拷锟斤拷锟斤拷ID
        RspType   锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷  POSITIVE_RSP 锟斤拷锟斤拷锟斤拷
                             NEGATIVE_RSP 锟斤拷锟斤拷锟斤拷
        A_TA_type 锟斤拷目锟斤拷锟街凤拷锟斤拷锟?
        A_Length  锟斤拷锟芥反锟斤拷携锟斤拷锟斤拷锟斤拷锟捷的筹拷锟斤拷(锟斤拷锟斤拷锟斤拷锟斤拷A_Data锟侥筹拷锟斤拷)
        A_Data    锟斤拷锟芥反锟斤拷携锟斤拷锟斤拷锟斤拷锟斤拷
锟斤拷锟斤拷值锟斤拷锟斤拷
******************************************************************************/
void UDS_Service_Response(uint8_t si, uint8_t RspType, uint32_t A_TA_type, uint16_t A_Length, uint8_t A_Data [])
{
    uint16_t         i;
    UDS_APP_TX_Union UDS_APP_TX;
    if ( RspType )
    {
        UDS_APP_TX.A_PDU.TA_type    = A_TA_type;
        UDS_APP_TX.A_PDU.A_PCI.SI   = 0x7Fu;
        UDS_APP_TX.A_PDU.Data [ 0 ] = si;
        UDS_APP_TX.A_PDU.Length     = A_Length;

        for ( i = 0u; i < UDS_APP_TX.A_PDU.Length; i++ )
        {
            UDS_APP_TX.A_PDU.Data [ i + 1u ] = A_Data [ i ];
        }

        UDS_S_Data_Request(UDS_APP_TX.Data.TA_type, UDS_APP_TX.Data.A_Data, UDS_APP_TX.Data.Length + 2u);
    }
    else
    {
        UDS_APP_TX.A_PDU.TA_type  = A_TA_type;
        UDS_APP_TX.A_PDU.A_PCI.SI = si;    //| 0x40u;
        UDS_APP_TX.A_PDU.Length   = A_Length;

        for ( i = 0u; i < UDS_APP_TX.A_PDU.Length; i++ )
        {
            UDS_APP_TX.A_PDU.Data [ i ] = A_Data [ i ];
        }

        UDS_S_Data_Request(UDS_APP_TX.Data.TA_type, UDS_APP_TX.Data.A_Data, UDS_APP_TX.Data.Length + 1u);
    }
}
