#include "UDS_27Service_Main.h"
#include "UDS_Common.h"
const uint8_t XorArray[4]= {0x74,0xF7,0x15,0x17};
static void Ser27_CalculateKeyLV1(uint8_t Seed[],uint8_t Key[])  ;


void UDS_Service_27_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_27Service_NRC11();                                            /*27服务是否支持功能寻址*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_NRC7F();                                            /*27服务会话是否支持验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_NRC33();                                            /*27服务解锁等级验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_NRC13_MinLengthCheck();                             /*27服务最小长度验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_NRC31();                                            /*27服务超出请求范围验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_NRC13_TotalLengthCheck();                           /*27服务总长度长度验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_NRC22();                                            /*27服务条件验证*/
    }
    if(NRC == positiveResponse)
    {
        UDS_27Service_Sub();                                                    /*27服务子功能*/
    }
    clearDiagMSG();                                                             /*清除诊断信息*/
}

/**
  *10服务子功能
  */
void UDS_27Service_Sub(void)
{
    uint8_t NRC = positiveResponse;
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_Sub_NRC13_MinLengthCheck();                         /*27服务子功能最小长度验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_Sub_NRC12();                                        /*27服务子功能是否支持验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_Sub_NRC7E();                                        /*27服务子功能会话是否支持验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_Sub_NRC31();                                        /*27服务子功能超出请求范围验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_Sub_NRC13_TotalLengthCheck();                       /*27服务子功能总长度长度验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_Sub_NRC24();                                        /*27服务子功能请求顺序验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_Sub_NRC22();                                        /*27服务子功能条件验证*/
    }
    if(NRC == positiveResponse)
    {
        NRC = UDS_27Service_Sub_NRC37();                                        /*27延时验证*/
    }
    if(NRC == positiveResponse)
    {
        switch(DiagMSG.msgData.SidDetail.SubID)                                 /*子服务判断*/
        {
        case requestSeed_LV1:
            UDS_27Service_Sub01();                                              /*27服务01子功能*/
            break;
        case sendKey_LV1:
            UDS_27Service_Sub02();                                              /*27服务02子功能*/
            break;
        default:
            break;
        }
    }
}

 /**
  *27服务01子功能
  */
void UDS_27Service_Sub01(void)
{
    uint8_t randomseed[4];
    uint8_t NRC = 0;
    if(Ser27_FlowCtrl.LV1SafetyStatus != NormalKeyUnlock )
    {
        if(Ser27_FlowCtrl.LV1Ctrl != SER27_REQ_SEEDED)
        {
            Ser27_CreateRandomSeed();
            Ser27_FlowCtrl.LV1Seed[0] = ((uint8_t)(Ser27_SeedRandomNumber) ^ 0x31u)+16u ;
            Ser27_FlowCtrl.LV1Seed[1] = ((uint8_t)(Ser27_SeedRandomNumber>>8) ^ 0x56u)+9u ;
            Ser27_FlowCtrl.LV1Seed[2] = ((uint8_t)(Ser27_SeedRandomNumber>>16) ^ 0x87u)+1u ;
            Ser27_FlowCtrl.LV1Seed[3] = ((uint8_t)(Ser27_SeedRandomNumber>>24) ^ 0x92u)+21u ; 
        }
        else
        {
            Ser27_FlowCtrlCnt.LV1ReqSeedCnt +=1u;
        }
        /*
        将FailCnt存入D-Flash*/
        Ser27_WriteCtrlInfoToDFlash();
        Ser27_FlowCtrl.LV1Ctrl = SER27_REQ_SEEDED;
        if( Ser27_FlowCtrlCnt.LV1ReqSeedCnt >= SER27_MAX_REQ_SEED_NUM )
        {
            Ser27_EnDelayTimer();
            Ser27_FlowCtrl.LV1Ctrl = SER27_CLEAR_REQ_SEEDED;
            NRC = UDS_27Service_Sub_NRC36();
        }
    }
    else
    {
        Ser27_FlowCtrl.LV1Seed[0] = 0u;
        Ser27_FlowCtrl.LV1Seed[1] = 0u;
        Ser27_FlowCtrl.LV1Seed[2] = 0u;
        Ser27_FlowCtrl.LV1Seed[3] = 0u;
    }
    DiagMSG.msgData.SidDetail.Data[0] = Ser27_FlowCtrl.LV1Seed[0]; 		  
    DiagMSG.msgData.SidDetail.Data[1] = Ser27_FlowCtrl.LV1Seed[1];		    
    DiagMSG.msgData.SidDetail.Data[2] = Ser27_FlowCtrl.LV1Seed[2];      
    DiagMSG.msgData.SidDetail.Data[3] = Ser27_FlowCtrl.LV1Seed[3];      
    randomseed[0] = Ser27_FlowCtrl.LV1Seed[0];
    randomseed[1] = Ser27_FlowCtrl.LV1Seed[1]; 
    randomseed[2] = Ser27_FlowCtrl.LV1Seed[2]; 
    randomseed[3] = Ser27_FlowCtrl.LV1Seed[3];

    if((randomseed[0] ==0x00u) &&(randomseed[1] ==0x00u) &&(randomseed[2] ==0x00u) &&(randomseed[3] ==0x00u))
    {

    }
    else
    {
        Ser27_CalculateKeyLV1(randomseed, Ser27_FlowCtrl.LV1Key);
    }
    if((DiagMSG.msgData.SidDetail.PositiveSuppression == 0u) && (NRC == 0))
    {
        UDS_Service_Response(0x27u, POSITIVE_RSP, DIAG_ID_Tx, 5u, DiagMSG.msgData.Data);
    }
}

 /**
  *27服务02子功能
  */
extern uint8_t DelayTimerFlag;
void UDS_27Service_Sub02(void)
{
    uint32_t KeyReceive;
    uint32_t KeyCalcValue;

    KeyReceive =(uint32_t)DiagMSG.msgData.SidDetail.Data[0];
    KeyReceive =(KeyReceive<<8u) | ((uint32_t)DiagMSG.msgData.SidDetail.Data[1]);
    KeyReceive =(KeyReceive<<8u) | ((uint32_t)DiagMSG.msgData.SidDetail.Data[2]);
    KeyReceive =(KeyReceive<<8u) | ((uint32_t)DiagMSG.msgData.SidDetail.Data[3]);

    KeyCalcValue =(uint32_t)Ser27_FlowCtrl.LV1Key[0];
    KeyCalcValue =(KeyCalcValue<<8u) | ((uint32_t)Ser27_FlowCtrl.LV1Key[1]);
    KeyCalcValue =(KeyCalcValue<<8u) | ((uint32_t)Ser27_FlowCtrl.LV1Key[2]);
    KeyCalcValue =(KeyCalcValue<<8u) | ((uint32_t)Ser27_FlowCtrl.LV1Key[3]);

    if(KeyReceive == KeyCalcValue)
    {
        Ser27_FlowCtrl.LV1SafetyStatus = NormalKeyUnlock; 
        Ser27_FlowCtrl.LV1Ctrl = SER27_CLEAR_REQ_SEEDED;
        Ser27_FlowCtrlCnt.LV1InvaidKyeCnt = 0u;
        Ser27_FlowCtrlCnt.LV1ReqSeedCnt = 0u; 
        DiagMSG.msgData.Data[0]=sendKey_LV1;
        DelayTimerFlag = 0;
        /*调用向flash写如函数*/
        Ser27_WriteCtrlInfoToDFlash();
           
        if(DiagMSG.msgData.SidDetail.PositiveSuppression == 0u)
        {
            UDS_Service_Response(0x27u, POSITIVE_RSP, DIAG_ID_Tx, 1u, DiagMSG.msgData.Data);
        }
    }
    else
    {
        Ser27_FlowCtrlCnt.LV1ReqSeedCnt +=1u;
        /*调用向flash写如函数*/
        Ser27_WriteCtrlInfoToDFlash();
        if(Ser27_FlowCtrlCnt.LV1ReqSeedCnt >= SER27_MAX_REQ_SEED_NUM  )
        {
            Ser27_EnDelayTimer();
            if(DelayTimerFlag == 1)
            {
                DelayTimerFlag = 0;
                UDS_27Service_Sub_NRC35();
            }
            else
            {
                UDS_27Service_Sub_NRC36();  
            }
        }
        else
        {
            UDS_27Service_Sub_NRC35();
        }
         Ser27_FlowCtrl.LV1Ctrl = SER27_CLEAR_REQ_SEEDED;  
    }
}

static void Ser27_CalculateKeyLV1(uint8_t Seed[],uint8_t Key[])       
{
    uint32_t Xor = 0x35EA6E2E;
    uint8_t Cal[4];
	uint32_t seed1 = 0;
	uint8_t  i;
	for(i = 0;i < 4;i++)
	{
		seed1 = seed1 << 8;
		seed1 |= Seed[i];
	}
	if(seed1 != 0)
	{
		for(i = 0;i < 35;i++)
		{
			if(seed1 & 0x80000000)
			{
				seed1 = seed1 << 1;
				seed1 = seed1 ^ Xor;
			}
			else
			{
				seed1 = seed1 << 1;
			}
		}
	}
	Key[0] = seed1 >> 24;
	Key[1] = seed1 >> 16;
	Key[2] = seed1 >> 8;
	Key[3] = seed1 >> 0;
}

