#include "UDS_2EService_Filter.h"

const uint8_t  S2EDLC[] = {17u,     4u,      8u,      16u,     8u,      64u,     64u,      64u,     64u,     8u,      24u,     8u,       3u,      3u,      1u,      1u     };
const uint16_t S2EDID[] = {0xF190u, 0xF1A2u, 0xF112u, 0xF198u, 0xF197u, 0xDFECu, 0xDFEDu,  0xDFEEu, 0xDFEFu, 0xF101u, 0xF102u, 0xF110u,  0x7101u, 0x7102u, 0x7103u, 0x7104u};

/**
  *2E服务是否支持功能寻址
  *功能寻址下屏蔽该负反馈
  *@return 负反馈编号
  */
uint8_t UDS_2EService_NRC11(void)
{
    uint8_t NRC = positiveResponse;
    if(DiagMSG.msgID == DIAG_ID_Rx_FUN)
    {
        NRC = serviceNotSupported;
    }
    return NRC;
}

/**
  *2E服务会话是否支持验证
  *功能寻址下屏蔽该负反馈
  *@return 负反馈编号
  */
uint8_t UDS_2EService_NRC7F(void)
{
    uint8_t NRC = positiveResponse;
    if(getSessionType() == DefaultSession)
    {
        NRC = serviceNotSupportedInActiveSession;
        UDS_Service_Response(0x2Eu, NEGATIVE_RSP, DIAG_ID_Tx, 1u, (uint8_t*)&NRC);
    }
    else
    {
        NRC = positiveResponse;
    }
    return NRC;
}

/**
  *2E服务解锁等级验证
  *@return 负反馈编号
  */
uint8_t UDS_2EService_NRC33(void)
{
    uint8_t NRC = positiveResponse;
    if(getSecurityLevel() == NormalKeyUnlock)
    {
        NRC = positiveResponse;
    }
    else
    {
        NRC = securityAccessDenied;
        UDS_Service_Response(0x2Eu, NEGATIVE_RSP, DIAG_ID_Tx, 1u, (uint8_t*)&NRC);
    }  
    return NRC;
}

/**
  *2E服务最小长度验证
  *@return 负反馈编号
  */
uint8_t UDS_2EService_NRC13_MinLengthCheck(void)
{
    uint8_t NRC = positiveResponse;
    if(DiagMSG.msgDLC < 3u)
    {
        NRC = incorrectMessageLength;
        UDS_Service_Response(0x2Eu, NEGATIVE_RSP, DIAG_ID_Tx, 1u, (uint8_t*)&NRC);
    }
    else
    {
        NRC = positiveResponse;
    }
    return NRC;
}

/**
  *2E服务超出请求范围验证
  *功能寻址下屏蔽该负反馈
  *@return 负反馈编号
  */
uint8_t UDS_2EService_NRC31(void)
{
    uint8_t i;
    uint8_t j;
    uint8_t NRC = requestOutOfRange;
    for(i = 0u; i < DIM(S2EDID); ++i)
    {
        if(getDID(DiagMSG.msgData.DidDetail.DID_H, DiagMSG.msgData.DidDetail.DID_L) == S2EDID[i])
        {
            if(getDID(DiagMSG.msgData.DidDetail.DID_H, DiagMSG.msgData.DidDetail.DID_L) == 0xF199u)
            {
               for(j = 0u; j < (DiagMSG.msgDLC - 2u); ++j)
               {
                  if(isBCD(DiagMSG.msgData.DidDetail.Data[j]))
                  {
                      NRC = positiveResponse;
                  }
                  else
                  {
                      NRC = requestOutOfRange;
                      break;
                  }
               }
               if((NRC == positiveResponse) && (DiagMSG.msgDLC == 6u))
               {
                  if(DiagMSG.msgData.DidDetail.Data[0] < 0x20u)
                  {
                      NRC = requestOutOfRange;
                  }
                  if((DiagMSG.msgData.DidDetail.Data[2] == 0x00u) || (DiagMSG.msgData.DidDetail.Data[2] > 0x12u))
                  {
                      NRC = requestOutOfRange;
                  }
                  if((DiagMSG.msgData.DidDetail.Data[3] == 0x00u) || (DiagMSG.msgData.DidDetail.Data[3] > 0x31u))
                  {
                      NRC = requestOutOfRange;
                  }
               }
            }
            else if(getDID(DiagMSG.msgData.DidDetail.DID_H, DiagMSG.msgData.DidDetail.DID_L) == 0xF1A2u)
            {
                for(j = 0u; j < (DiagMSG.msgDLC - 2u); ++j)
               {
                   if(isBCD(DiagMSG.msgData.DidDetail.Data[j]))
                  {
                      NRC = positiveResponse;
                  }
                  else
                  {
                      NRC = requestOutOfRange;
                      break;
                  }
               }
               if((NRC == positiveResponse) && (DiagMSG.msgDLC == 6u))
               {
                  if(DiagMSG.msgData.DidDetail.Data[0] < 0x20u)
                  {
                      NRC = requestOutOfRange;
                  }
                  if((DiagMSG.msgData.DidDetail.Data[2] == 0x00u) || (DiagMSG.msgData.DidDetail.Data[2] > 0x12u))
                  {
                      NRC = requestOutOfRange;
                  }
                  if((DiagMSG.msgData.DidDetail.Data[3] == 0x00u) || (DiagMSG.msgData.DidDetail.Data[3] > 0x31u))
                  {
                      NRC = requestOutOfRange;
                  }
               }
            }
            else if(getDID(DiagMSG.msgData.DidDetail.DID_H, DiagMSG.msgData.DidDetail.DID_L) == 0x7101u)
            {
                for(j = 0u; j < (DiagMSG.msgDLC - 2u); ++j)
               {
                   if(isBCD(DiagMSG.msgData.DidDetail.Data[j]))
                  {
                      NRC = positiveResponse;
                  }
                  else
                  {
                      NRC = requestOutOfRange;
                      break;
                  }
               }
               if(DiagMSG.msgData.DidDetail.Data[0] > 0x50) 
                {
                    NRC = requestOutOfRange;
                    break;  
                } 
                else if((DiagMSG.msgData.DidDetail.Data[0] == 0x50u) && ((DiagMSG.msgData.DidDetail.Data[1] | DiagMSG.msgData.DidDetail.Data[2]) > 0)) 
                {
                    NRC = requestOutOfRange;
                    break;  
                } 
                else
                {
                    NRC = positiveResponse;
                
                }            
            }
            else if(getDID(DiagMSG.msgData.DidDetail.DID_H, DiagMSG.msgData.DidDetail.DID_L) == 0x7102u)
            {
                for(j = 0u; j < (DiagMSG.msgDLC - 2u); ++j)
               {
                   if(isBCD(DiagMSG.msgData.DidDetail.Data[j]))
                  {
                      NRC = positiveResponse;
                  }
                  else
                  {
                      NRC = requestOutOfRange;
                      break;
                  }
               }
               if(DiagMSG.msgData.DidDetail.Data[0] > 0x50) 
                {
                    NRC = requestOutOfRange;
                    break;  
                } 
                else if((DiagMSG.msgData.DidDetail.Data[0] == 0x50u) && ((DiagMSG.msgData.DidDetail.Data[1] | DiagMSG.msgData.DidDetail.Data[2]) > 0)) 
                {
                    NRC = requestOutOfRange;
                    break;  
                } 
                else
                {
                    NRC = positiveResponse;
                
                }            
            }
            else if(getDID(DiagMSG.msgData.DidDetail.DID_H, DiagMSG.msgData.DidDetail.DID_L) == 0x7103u)
            {
                for(j = 0u; j < (DiagMSG.msgDLC - 2u); ++j)
               {
                   if((DiagMSG.msgData.DidDetail.Data[j] == 0x00) || (DiagMSG.msgData.DidDetail.Data[j] == 0x01))
                  {
                      NRC = positiveResponse;
                  }
                  else
                  {
                      NRC = requestOutOfRange;
                      break;
                  }
               }
            }
            else if(getDID(DiagMSG.msgData.DidDetail.DID_H, DiagMSG.msgData.DidDetail.DID_L) == 0x7104u)
            {
                for(j = 0u; j < (DiagMSG.msgDLC - 2u); ++j)
               {
                   if((DiagMSG.msgData.DidDetail.Data[j] == 0x00) || (DiagMSG.msgData.DidDetail.Data[j] == 0x01))
                  {
                      NRC = positiveResponse;
                  }
                  else
                  {
                      NRC = requestOutOfRange;
                      break;
                  }
               }
            }
            else
            {
                NRC = positiveResponse;
            }
            break;
        }
    }
    if((NRC == requestOutOfRange) && (DiagMSG.msgID == DIAG_ID_Rx_PHY))
    {
        UDS_Service_Response(0x2Eu, NEGATIVE_RSP, DIAG_ID_Tx, 1u, (uint8_t*)&NRC);
    }
    return NRC;/**/
}

/**
  *2E服务总长度长度验证
  *@return 负反馈编号
  */
uint8_t UDS_2EService_NRC13_TotalLengthCheck(void)
{
    uint8_t i;
    uint8_t NRC = positiveResponse;
    for(i = 0u; i < DIM(S2EDID); ++i)
    {
        if(getDID(DiagMSG.msgData.DidDetail.DID_H, DiagMSG.msgData.DidDetail.DID_L) == S2EDID[i])
        {
            if(DiagMSG.msgDLC != (S2EDLC[i] + 2))
            {
                NRC = incorrectMessageLength;
                UDS_Service_Response(0x2Eu, NEGATIVE_RSP, DIAG_ID_Tx, 1u, (uint8_t*)&NRC);
            }
            else
            {
                NRC = positiveResponse;
            }
            break;
        }
    }/**/
    return NRC;
}

/**
  *2E服务条件验证
  *@return 负反馈编号
  */
uint8_t UDS_2EService_NRC22(void)
{
    uint8_t NRC = positiveResponse;
    if((getSpeed() > 0u) && (1/*power on*/) )
    {
        NRC = conditionsNotCorrect;
        UDS_Service_Response(0x2Eu, NEGATIVE_RSP, DIAG_ID_Tx, 1u, (uint8_t*)&NRC);
    } 
    else
    {
        NRC = positiveResponse;
    }
    
    if(NRC == positiveResponse)
    {
      if(getDID(DiagMSG.msgData.DidDetail.DID_H, DiagMSG.msgData.DidDetail.DID_L) == 0x6208u)
      {
        //if(Services_Read_ODO_ClearCnt1()>=10000u)
        {
          NRC = conditionsNotCorrect;
          UDS_Service_Response(0x2Eu, NEGATIVE_RSP, DIAG_ID_Tx, 1u, (uint8_t*)&NRC);
        }
        //else
        {
          NRC = positiveResponse;
        }
        
      }
    } 
    return NRC;
}
