/******************************************************************************
|  File Name :  CanTp.c
|  Description: Manages segmenting of data in the send direction,
|               assembling of data in the receive direction,
|               and monitoring of the data stream.
|------------------------------------------------------------------------------
| (c) This software is the proprietary of Wenzhou Changjiang AutoMobile (DAMING)
|     All rights are reserved by DAMING.
|------------------------------------------------------------------------------
| Initials      Name                   Company
| --------      --------------------   ----------------------------------------
|                				       DAMING
|------------------------------------------------------------------------------
|               R E V I S I O N   H I S T O R Y
|------------------------------------------------------------------------------
| Date         Version    Author       Description
| ----------   --------   ------       ----------------------------------------
| 2015-9-1     V1.0       LZY          
 *****************************************************************************/
/*
TP层理论上 可以以 500us 以内的间隔接收连续帧 但是考虑到APP层其他进程的进行 
CAN中断太过频繁会造成时间片的偏移，所以流控帧 的 STmin定为5ms

诊断报文接收丢弃策略：
单帧 接收中 响应第一个单帧 响应超时前(1000 ms) 丢弃后来的所有帧
多帧 接收中 可被 (单帧) (多帧首帧) 打断 
多帧 接受完毕后 响应超时前(1000 ms) 丢弃后来的所有帧



上层响应报文后，TP层开始接收新的一帧

上层通过TP层发送报文，则TP层认为已经响应当前报文。(除 负响应 78外，接收到78负响应 延长1个S3时间的响应时间 5S)

S3 ： 接收到报文 至 反馈完毕（以调用发送函数为标志） 读接口为 ACTIVE 否则为 INACTIVE

反馈响应时间：1S
TP层占用10% APP层占用90% 即900ms APP层必须将反馈发送至 TP层 （无反馈发送DL = 0）
APP层超时，TP层将中止该帧报文的响应流程 回到空闲状态 准备接受下一帧

78负响应 延长1个S3时间的响应时间 5S
*/


 
 
/******************************************************************************
 * Description:     : Include File Section 									
******************************************************************************/
//#include "global.h"
#include "CanTp.h"

/******************************************************************************
 * Description:     : Global Variable Definition Section 									
 ******************************************************************************/


/******************************************************************************
 * Description:     : Static Variable Definition Section 									
 ******************************************************************************/	

#define DAMING_TRUE     DCM_TRUE
#define DAMING_FALSE    DCM_FALSE
#define DAMING_ACTIVE   DCM_ACTIVE
#define DAMING_INACTIVE DCM_INACTIVE
static uint8 SaCanTp_u_RxSFBuffer[8]; /*单帧buffer*/

static TeCanTp_e_TpSts   SeCanTp_e_TpSts;/*TP层工作状态*/


static uint8 SeCanTp_u_BS;
static uint8 SeCanTp_u_STmin;

static uint8 SaCanTp_u_RxMFBuffer[CANTP_MFLEN_MAX];/*多帧接收buffer*/

static uint16 SeCanTp_u_RxLen;
static TeCanTp_e_AddrMethod SeCanTp_e_AddrMethod;/*寻址方式*/

static uint16 SeCanTp_u_RxMFDataCnt;
static uint8 SeCanTp_u_LastSN;

static uint16 SeCanTp_u_Timer;	
static TeCanTp_e_MFTimerSwitch SeCanTp_e_TimerSwitch;

static TeCanTp_e_TxSts SeCanTp_e_TxSts;/*发送状态*/

static uint8 SaCanTp_u_TxDataBuffer[CANTP_MFLEN_MAX];
static uint8 SaCanTp_u_TxBuffer[8];

static uint16 SeCanTp_u_TxLen;

static uint16     SeCanTp_u_TxMFIndex;
static TeCanTp_e_MFTxSts SeCanTp_e_MFTxSts;
static uint8 SeCanTp_u_MFTxSN; 
static uint8 SeCanTp_u_MFTxSpacing;

static uint16 SeCanTp_w_RespTimer; /*反馈计时器*/
static uint8 SeCanTp_u_RespFlag;
/******************************************************************************
 * Description:     : Static Function Prototype Declaration									
 *****************************************************************************/
 
/******************************************************************************
 * Description:     : Write User Function Code								
 *****************************************************************************/

/******************************************************************************
 *函数名称    : 

 *参数        : TeCanTp_e_AddrMethod* LeCanTp_p_AddrMethod ,   Addressing Method
                uint16* LeCanTp_p_DL ,    Data Length
                uint8* LeCanTp_p_DataAddr        array of data pointer

 *返回值      : 

 *描述        : get frame data 

 *编辑时间    : 

 *备注        : 
 *****************************************************************************/
TeCanTp_e_RxBufferSts GetCanTp_e_RxBufferSts(uint8* LeCanTp_p_AddrMethod , uint16* LeCanTp_p_DL , uint8** LeCanTp_p_DataAddr)
{
	TeCanTp_e_RxBufferSts LeCanTp_e_RxSts;
	
	if(SeCanTp_e_TpSts == CeCanTp_e_SF_Get)
	{
		SeCanTp_e_TpSts = CeCanTp_e_Answer;
		*LeCanTp_p_AddrMethod = SeCanTp_e_AddrMethod;
		*LeCanTp_p_DL = SeCanTp_u_RxLen;
		*LeCanTp_p_DataAddr = SaCanTp_u_RxSFBuffer;
		LeCanTp_e_RxSts = CeCanTp_e_Full;
	}
	else if(SeCanTp_e_TpSts == CeCanTp_e_MF_Get)
	{
		SeCanTp_e_TpSts = CeCanTp_e_Answer;
		*LeCanTp_p_AddrMethod = SeCanTp_e_AddrMethod;
		*LeCanTp_p_DL = SeCanTp_u_RxLen;
		*LeCanTp_p_DataAddr = SaCanTp_u_RxMFBuffer;
		LeCanTp_e_RxSts = CeCanTp_e_Full;
	}
	else
	{
		LeCanTp_e_RxSts = CeCanTp_e_Empty;
	}
	return LeCanTp_e_RxSts;
}
 
 /******************************************************************************
 *函数名称    : 

 *参数        : 

 *返回值      : 

 *描述        : CanIf调用 给TP数据函数 物理寻址

 *编辑时间    : 

 *备注        : 
 *****************************************************************************/

void RxIndicationCanTP_AddrPhy_Message(CanIf_HwHandleType LeCanTp_e_Hrh, 
									   CanIf_CanIdType    LeCanTp_e_CanId, 
									   CanIf_CanDlcType   LeCanTp_e_CanDlc, 
								 const CanIf_CanDataType  LeCanTp_e_CanSduPtr[])
{
	uint8 LeCanTp_u_FrameInfo = 0;
	uint8 LeCanTp_u_DataIndex;
	
	(void)LeCanTp_e_Hrh;
	(void)LeCanTp_e_CanDlc;
	
	if(LeCanTp_e_CanId == CANTP_ADDR_PHY_REQ)
	{
		LeCanTp_u_FrameInfo = LeCanTp_e_CanSduPtr[0] >> 4;
		 
		if((SeCanTp_e_TpSts == CeCanTp_e_SF_Get)/*已接收到单帧*/
			||(SeCanTp_e_TpSts == CeCanTp_e_MF_Get)/*已接收到多帧*/
			||(SeCanTp_e_TpSts == CeCanTp_e_Answer))/*当前正在响应*/
		{
			if((SeCanTp_e_TpSts == CeCanTp_e_Answer) && (SeCanTp_e_MFTxSts == CeCanTp_e_TX_FCWaiting))/*反馈阶段 发送多帧数据*/
			{
				if(LeCanTp_u_FrameInfo == 3)/*FC*/
				{
					if((LeCanTp_e_CanSduPtr[0]&0x0F) == 0x00)/*FS判断 正常*/
					{
						SeCanTp_e_MFTxSts = CeCanTp_e_TX_CFGaving;
							
						if(LeCanTp_e_CanSduPtr[1] == 0)
						{
							SeCanTp_u_BS = CANTP_MFLEN_MAX;
						}
						else
						{
							SeCanTp_u_BS = LeCanTp_e_CanSduPtr[1];
						}
							
						if(SeCanTp_u_STmin < 0x7FU)
						{
							SeCanTp_u_STmin = ((LeCanTp_e_CanSduPtr[2]-1)/CANTP_TASK)+1;
						}
						else
						{
							SeCanTp_u_STmin = 0;
						}
							
						SeCanTp_u_MFTxSpacing = 0;/*开始最小间隔计时*/
						SeCanTp_u_Timer = 0;
					}
					else if((LeCanTp_e_CanSduPtr[0]&0x0F) == 0x01)/*FS判断 等待*/
					{
						/*等待 清空计时器 再等一个 bs*/
						SeCanTp_u_Timer = 0;
					}
					else
					{
						/*过载丢帧*/
						SeCanTp_e_MFTxSts = CeCanTp_e_TX_Idel;
						SeCanTp_e_TpSts = CeCanTp_e_Idel;
						SeCanTp_e_TxSts = CeCanTp_e_Tx_Idle;
					}
				}
			}
			else{/*丢帧*/}
		}
		else
		{
			if(LeCanTp_u_FrameInfo == 0)/*SF*/
			{
				SeCanTp_u_RxLen = LeCanTp_e_CanSduPtr[0]&0x0f;
				if((SeCanTp_u_RxLen < 8) && (SeCanTp_u_RxLen > 0))
				{
					SeCanTp_e_TpSts = CeCanTp_e_SF_Get;/*单帧接收*/
					
					SeCanTp_e_AddrMethod = CeCanTp_e_Physical;
					for(LeCanTp_u_DataIndex = 0;LeCanTp_u_DataIndex < SeCanTp_u_RxLen;LeCanTp_u_DataIndex++)
					{
						SaCanTp_u_RxSFBuffer[LeCanTp_u_DataIndex] = LeCanTp_e_CanSduPtr[LeCanTp_u_DataIndex+1];
					}
					
					SeCanTp_u_RespFlag = DAMING_TRUE;
					SeCanTp_w_RespTimer = 1000U;
				}
				else
				{/*丢帧*/}
			}
			else if(LeCanTp_u_FrameInfo == 1)/*FF*/ 
			{
				SeCanTp_u_RxLen =(uint16)(((uint16)(LeCanTp_e_CanSduPtr[0] & 0x0f) << 8) + (uint16)LeCanTp_e_CanSduPtr[1]);
				if(SeCanTp_u_RxLen > CANTP_MFLEN_MAX)		// add for 15765-2-6.5.2.2 
				{
					/*丢帧*/
					/*直接回复过载流控帧*/
					SaCanTp_u_TxBuffer[0] = 0x30;
					SaCanTp_u_TxBuffer[1] = 2;
					SaCanTp_u_TxBuffer[2] = CANTP_RX_STMIN;
					
					TransmitCanIf_Buffer(CANTP_RESP_CANID,8,SaCanTp_u_TxBuffer);
				}
				else if(SeCanTp_u_RxLen > 7)
				{
					SeCanTp_e_AddrMethod = CeCanTp_e_Physical;
						
					/*获得多帧长度*/
					SeCanTp_u_RxMFDataCnt = 0;
						
					/*获得前6个数据*/
					for(LeCanTp_u_DataIndex = 2;LeCanTp_u_DataIndex < 8;LeCanTp_u_DataIndex++)
					{
						SaCanTp_u_RxMFBuffer[SeCanTp_u_RxMFDataCnt] = LeCanTp_e_CanSduPtr[LeCanTp_u_DataIndex];
						SeCanTp_u_RxMFDataCnt++;
					}
					SeCanTp_u_LastSN = 1;
					
					/*直接回复流控帧*/
					SaCanTp_u_TxBuffer[0] = 0x30;
					SaCanTp_u_TxBuffer[1] = 0;
					SaCanTp_u_TxBuffer[2] = CANTP_RX_STMIN;
					
					TransmitCanIf_Buffer(CANTP_RESP_CANID,8,SaCanTp_u_TxBuffer);
					
					SeCanTp_e_TpSts = CeCanTp_e_MF_CFTakein;/*等待接收后续帧*/
					
					SeCanTp_e_TimerSwitch = CeCanTp_e_Cr;
					SeCanTp_u_Timer = 0;
				}
				else
				{/*丢帧*/}
			}
			else if(LeCanTp_u_FrameInfo == 2)/*CF*/	 
			{
				if(SeCanTp_e_TpSts == CeCanTp_e_MF_CFTakein)
				{
					/*检验SN*/
					SeCanTp_u_Timer = 0;
					
					if((LeCanTp_e_CanSduPtr[0]&0x0F) == (SeCanTp_u_LastSN & 0x0F))
					{
						/*获得数据*/
						SeCanTp_u_LastSN++;
						if((LeCanTp_e_CanDlc < 8)&&(LeCanTp_e_CanDlc >0)&&(SeCanTp_u_RxMFDataCnt < (SeCanTp_u_RxLen - LeCanTp_e_CanDlc)))
						{
							SeCanTp_e_TpSts = CeCanTp_e_Idel;	// 错误的DLC  
						}
						else
						{						
							for(LeCanTp_u_DataIndex = 1;LeCanTp_u_DataIndex < 8;LeCanTp_u_DataIndex++)
							{
								if(SeCanTp_u_RxMFDataCnt < SeCanTp_u_RxLen)
								{
									SaCanTp_u_RxMFBuffer[SeCanTp_u_RxMFDataCnt] = LeCanTp_e_CanSduPtr[LeCanTp_u_DataIndex];
									SeCanTp_u_RxMFDataCnt++;
								}
								else
								{
									/*数据接收完毕*/
									SeCanTp_e_TpSts = CeCanTp_e_MF_Get;
									
									SeCanTp_u_RespFlag = DAMING_TRUE;
									SeCanTp_w_RespTimer = 1000U;
									break;
								}
								
								if(SeCanTp_u_RxMFDataCnt == SeCanTp_u_RxLen)
								{
									/*数据接收完毕*/
									SeCanTp_e_TpSts = CeCanTp_e_MF_Get;
									
									SeCanTp_u_RespFlag = DAMING_TRUE;
									SeCanTp_w_RespTimer = 1000U;
									break;
								}
							}
						}
						
					}
					else
					{
						/*SN错误 丢帧*/
						SeCanTp_e_TpSts = CeCanTp_e_Idel;
					}
				}
				else
				{
					/*当前不是 多帧接受后续帧阶段 丢帧*/
				}
			}
			else
			{
				/*不接受 流控帧 与 其他状态帧*/
			}
		}
	}
	else
	{
		
	}
}
 
  /******************************************************************************
 *函数名称    : 

 *参数        : 

 *返回值      : 

 *描述        : CanIf调用 给TP数据函数 功能寻址

 *编辑时间    : 

 *备注        : 
 *****************************************************************************/
#if (CANTP_ADDRFUNC_MF_FORBID == DAMING_TRUE)
void RxIndicationCanTP_AddrFunc_Message(CanIf_HwHandleType LeCanTp_e_Hrh, 
									    CanIf_CanIdType    LeCanTp_e_CanId, 
									    CanIf_CanDlcType   LeCanTp_e_CanDlc, 
								  const CanIf_CanDataType  LeCanTp_e_CanSduPtr[])
{
	uint8 LeCanTp_u_FrameInfo = 0;
	uint8 LeCanTp_u_DataIndex;
	
	(void)LeCanTp_e_Hrh;
	(void)LeCanTp_e_CanDlc;
	
	if(LeCanTp_e_CanId == CANTP_ADDR_FUNC_REQ)
	{
		LeCanTp_u_FrameInfo = LeCanTp_e_CanSduPtr[0] >> 4;
		 
		if((SeCanTp_e_TpSts == CeCanTp_e_SF_Get)/*已接收到单帧*/
			||(SeCanTp_e_TpSts == CeCanTp_e_MF_Get)/*已接收到多帧*/
			||(SeCanTp_e_TpSts == CeCanTp_e_Answer))/*当前正在响应*/
		{
			if((SeCanTp_e_TpSts == CeCanTp_e_Answer) && (SeCanTp_e_MFTxSts == CeCanTp_e_TX_FCWaiting))/*反馈阶段 发送多帧数据*/
			{
				if(LeCanTp_u_FrameInfo == 3)/*FC*/
				{
					if((LeCanTp_e_CanSduPtr[0]&0x0F) == 0x00)/*FS判断 正常*/
					{
						SeCanTp_e_MFTxSts = CeCanTp_e_TX_CFGaving;
							
						if(LeCanTp_e_CanSduPtr[1] == 0)
						{
							SeCanTp_u_BS = CANTP_MFLEN_MAX;
						}
						else
						{
							SeCanTp_u_BS = LeCanTp_e_CanSduPtr[1];
						}
							
						if(SeCanTp_u_STmin < 0x7FU)
						{
							SeCanTp_u_STmin = ((LeCanTp_e_CanSduPtr[2]-1)/CANTP_TASK)+1;
						}
						else
						{
							SeCanTp_u_STmin = 0;
						}
							
						SeCanTp_u_MFTxSpacing = 0;/*开始最小间隔计时*/
					}
					else if((LeCanTp_e_CanSduPtr[0]&0x0F) == 0x01)/*FS判断 等待*/
					{
						/*等待 清空计时器 再等一个 bs*/
						SeCanTp_u_Timer = 0;
					}
					else
					{
						/*过载丢帧*/
						SeCanTp_e_MFTxSts = CeCanTp_e_TX_Idel;
						SeCanTp_e_TpSts = CeCanTp_e_Idel;
						SeCanTp_e_TxSts = CeCanTp_e_Tx_Idle;
					}
				}
			}
		}
		else
		{
			if(LeCanTp_u_FrameInfo == 0)/*SF*/
			{
				SeCanTp_u_RxLen = LeCanTp_e_CanSduPtr[0]&0x0f;
				if((SeCanTp_u_RxLen < 8) && (SeCanTp_u_RxLen > 0))
				{
					SeCanTp_e_TpSts = CeCanTp_e_SF_Get;/*单帧接收*/
					
					SeCanTp_e_AddrMethod = CeCanTp_e_Functional;
					for(LeCanTp_u_DataIndex = 0;LeCanTp_u_DataIndex < SeCanTp_u_RxLen;LeCanTp_u_DataIndex++)
					{
						SaCanTp_u_RxSFBuffer[LeCanTp_u_DataIndex] = LeCanTp_e_CanSduPtr[LeCanTp_u_DataIndex+1];
					}
					
					SeCanTp_u_RespFlag = DAMING_TRUE;
					SeCanTp_w_RespTimer = 1000U;
				}
				else
				{/*丢帧*/}
			}

			else if(LeCanTp_u_FrameInfo == 1)/*FF*/ 
			{
				SeCanTp_u_RxLen =(uint16)(((uint16)(LeCanTp_e_CanSduPtr[0] & 0x0f) << 8) + (uint16)LeCanTp_e_CanSduPtr[1]);
				
				if(SeCanTp_u_RxLen > 7)
				{
					SeCanTp_e_AddrMethod = CeCanTp_e_Functional;
						
					/*获得多帧长度*/
					//SeCanTp_u_RxLen =(uint16)(((uint16)(LeCanTp_e_CanSduPtr[0] & 0x0f) << 8) + (uint16)LeCanTp_e_CanSduPtr[1]);
					SeCanTp_u_RxMFDataCnt = 0;
						
					/*获得前6个数据*/
					for(LeCanTp_u_DataIndex = 2;LeCanTp_u_DataIndex < 8;LeCanTp_u_DataIndex++)
					{
						SaCanTp_u_RxMFBuffer[SeCanTp_u_RxMFDataCnt] = LeCanTp_e_CanSduPtr[LeCanTp_u_DataIndex];
						SeCanTp_u_RxMFDataCnt++;
					}
					SeCanTp_u_LastSN = 1;
					
					/*直接回复流控帧*/
					SaCanTp_u_TxBuffer[0] = 0x30;
					SaCanTp_u_TxBuffer[1] = 0;
					SaCanTp_u_TxBuffer[2] = CANTP_RX_STMIN;
					
					TransmitCanIf_Buffer(CANTP_RESP_CANID,8,SaCanTp_u_TxBuffer);
					
					SeCanTp_e_TpSts = CeCanTp_e_MF_CFTakein;/*等待接收后续帧*/
					
					SeCanTp_e_TimerSwitch = CeCanTp_e_Cr;
					SeCanTp_u_Timer = 0;
				}
				else
				{/*丢帧*/}
			}
			else if(LeCanTp_u_FrameInfo == 2)/*CF*/	 
			{
				if(SeCanTp_e_TpSts == CeCanTp_e_MF_CFTakein)
				{
					/*检验SN*/
					if((LeCanTp_e_CanSduPtr[0]&0x0F) == ((SeCanTp_u_LastSN+1)&0x0F))
					{
						/*获得数据*/
						SeCanTp_u_LastSN++;
						
						for(LeCanTp_u_DataIndex = 1;LeCanTp_u_DataIndex < 8;LeCanTp_u_DataIndex++)
						{
							if(SeCanTp_u_RxMFDataCnt < SeCanTp_u_RxLen)
							{
								SaCanTp_u_RxMFBuffer[SeCanTp_u_RxMFDataCnt] = LeCanTp_e_CanSduPtr[LeCanTp_u_DataIndex];
								SeCanTp_u_RxMFDataCnt++;
							}
							else
							{
								/*数据接收完毕*/
								SeCanTp_e_TpSts = CeCanTp_e_MF_Get;
								
								SeCanTp_u_RespFlag = DAMING_TRUE;
								SeCanTp_w_RespTimer = 1000U;
								break;
							}
							
							if(SeCanTp_u_RxMFDataCnt == SeCanTp_u_RxLen)
							{
								/*数据接收完毕*/
								SeCanTp_e_TpSts = CeCanTp_e_MF_Get;
								
								SeCanTp_u_RespFlag = DAMING_TRUE;
								SeCanTp_w_RespTimer = 1000U;
								break;
							}
						}
					}
					else
					{
						/*SN错误 丢帧*/
						SeCanTp_e_TpSts = CeCanTp_e_Idel;
					}
				}
				else
				{
					/*当前不是 多帧接受后续帧阶段 丢帧*/
				}
			}
			else
			{
				/*不接受 流控帧 与 其他状态帧*/
			}
		}
	}
	else
	{}
}
#else  
void RxIndicationCanTP_AddrFunc_Message(CanIf_HwHandleType LeCanTp_e_Hrh, 
									    CanIf_CanIdType    LeCanTp_e_CanId, 
									    CanIf_CanDlcType   LeCanTp_e_CanDlc, 
								  const CanIf_CanDataType  LeCanTp_e_CanSduPtr[])
{
	uint8 LeCanTp_u_FrameInfo = 0;
	uint8 LeCanTp_u_DataIndex;
	
	(void)LeCanTp_e_Hrh;
	(void)LeCanTp_e_CanDlc;
	
	if(LeCanTp_e_CanId == CANTP_ADDR_FUNC_REQ)
	{
		LeCanTp_u_FrameInfo = LeCanTp_e_CanSduPtr[0] >> 4;
		 
		if((SeCanTp_e_TpSts == CeCanTp_e_SF_Get)/*已接收到单帧*/
			||(SeCanTp_e_TpSts == CeCanTp_e_MF_Get)/*已接收到多帧*/
			||(SeCanTp_e_TpSts == CeCanTp_e_Answer))/*当前正在响应*/
		{
			/*丢帧*/
		}
		else
		{
			if(LeCanTp_u_FrameInfo == 0)/*SF*/
			{
				SeCanTp_u_RxLen = LeCanTp_e_CanSduPtr[0]&0x0f;
				if(SeCanTp_u_RxLen < 8)
				{
					SeCanTp_e_TpSts = CeCanTp_e_SF_Get;/*单帧接收*/
					
					SeCanTp_e_AddrMethod = CeCanTp_e_Functional;
					for(LeCanTp_u_DataIndex = 0;LeCanTp_u_DataIndex < SeCanTp_u_RxLen;LeCanTp_u_DataIndex++)
					{
						SaCanTp_u_RxSFBuffer[LeCanTp_u_DataIndex] = LeCanTp_e_CanSduPtr[LeCanTp_u_DataIndex+1];
					}
					
					SeCanTp_u_RespFlag = DAMING_TRUE;
					SeCanTp_w_RespTimer = 1000U;
				}
				else
				{/*丢帧*/}
			}
		}
	}
	else
	{}
}  
#endif

 /******************************************************************************
 *函数名称    : 

 *参数        : 

 *返回值      : 

 *描述        : 发送

 *编辑时间    : 

 *备注        : 
 *****************************************************************************/
TeCanTp_e_TxResult SetCanTp_TxBuffer(uint16 LeCanTp_p_DL , const uint8 LeCanTp_p_DataAddr[])
{
	TeCanTp_e_TxResult LeCanTp_e_TxResult;
	uint16 LeCanTp_s_Index;
	
	/*只有在反馈阶段 可以发送数据*/
	if ((SeCanTp_e_TpSts == CeCanTp_e_Answer) && (SeCanTp_e_TxSts == CeCanTp_e_Tx_Idle))
	{
		SeCanTp_u_RespFlag = DAMING_FALSE;
		SeCanTp_w_RespTimer = 1000U;
		
		if(LeCanTp_p_DL == 0)
		{
			/*该报文无反馈*/
			SeCanTp_e_TpSts = CeCanTp_e_Idel;
		}
		else if(LeCanTp_p_DL < 8)
		{
			/*单帧 直接发送*/
			SaCanTp_u_TxBuffer[0] = (uint8)LeCanTp_p_DL;
			
			for(LeCanTp_s_Index = 1; LeCanTp_s_Index < 8; LeCanTp_s_Index++)
			{
				SaCanTp_u_TxBuffer[LeCanTp_s_Index] = 0x55;
			}
			
			for(LeCanTp_s_Index = 0; LeCanTp_s_Index < LeCanTp_p_DL; LeCanTp_s_Index++)
			{
				SaCanTp_u_TxBuffer[LeCanTp_s_Index + 1] = LeCanTp_p_DataAddr[LeCanTp_s_Index];
			}
			
			TransmitCanIf_Buffer(CANTP_RESP_CANID,8,SaCanTp_u_TxBuffer);
			
			SeCanTp_e_TpSts = CeCanTp_e_Idel;		
		}
		else
		{
			/*多帧报文*/
			SeCanTp_e_TxSts = CeCanTp_e_Tx_Busy;
			
			/*数据提取*/
			for(LeCanTp_s_Index = 0; LeCanTp_s_Index < LeCanTp_p_DL; LeCanTp_s_Index++)
			{
				SaCanTp_u_TxDataBuffer[LeCanTp_s_Index] = LeCanTp_p_DataAddr[LeCanTp_s_Index];
			}
			
			SeCanTp_u_TxLen = LeCanTp_p_DL;
			
			
			/*发送首帧*/
			SaCanTp_u_TxBuffer[0] = 0x10 + (uint8)(LeCanTp_p_DL >> 8);
			SaCanTp_u_TxBuffer[1] = (uint8)(LeCanTp_p_DL & 0x00ff);
			

			for(SeCanTp_u_TxMFIndex = 0; SeCanTp_u_TxMFIndex < 6; SeCanTp_u_TxMFIndex++)
			{
				SaCanTp_u_TxBuffer[SeCanTp_u_TxMFIndex+2] = SaCanTp_u_TxDataBuffer[SeCanTp_u_TxMFIndex];
			}
			TransmitCanIf_Buffer(CANTP_RESP_CANID,8,SaCanTp_u_TxBuffer);
			
	        SeCanTp_e_TimerSwitch = CeCanTp_e_Bs;
			SeCanTp_u_Timer = 0;
			
			SeCanTp_u_MFTxSN = 1;
			SeCanTp_e_MFTxSts = CeCanTp_e_TX_FCWaiting;
		}
		
		LeCanTp_e_TxResult = CeCanTp_e_Tx_Succeed;
	}
	else
	{
		LeCanTp_e_TxResult = CeCanTp_e_Tx_Wrong;
	}
	
	return LeCanTp_e_TxResult;
}
  
 /******************************************************************************
 *函数名称    : 

 *参数        : 

 *返回值      : 

 *描述        : 78负响应  发送响应后 不中断当前 反馈流程

 *编辑时间    : 

 *备注        : 
 *****************************************************************************/
TeCanTp_e_TxResult SetCanTp_Tx_78Neg(uint16 LeCanTp_p_DL , const uint8 LeCanTp_p_DataAddr[])
{
	TeCanTp_e_TxResult LeCanTp_e_TxResult;
	uint8 LeCanTp_u_Index;
	
	/*只有在反馈阶段 可以发送数据*/
	if ((SeCanTp_e_TpSts == CeCanTp_e_Answer) && (SeCanTp_e_TxSts == CeCanTp_e_Tx_Idle))
	{
		if(LeCanTp_p_DL < 8)
		{
			/*单帧 直接发送*/
			SaCanTp_u_TxBuffer[0] = (uint8)LeCanTp_p_DL;
			
			for(LeCanTp_u_Index = 1; LeCanTp_u_Index < 8; LeCanTp_u_Index++)
			{
				SaCanTp_u_TxBuffer[LeCanTp_u_Index] = 0x55;
			}
			
			for(LeCanTp_u_Index = 0; LeCanTp_u_Index < LeCanTp_p_DL; LeCanTp_u_Index++)
			{
				SaCanTp_u_TxBuffer[LeCanTp_u_Index + 1] = LeCanTp_p_DataAddr[LeCanTp_u_Index];
			}
			
			TransmitCanIf_Buffer(CANTP_RESP_CANID,8,SaCanTp_u_TxBuffer);
				
			LeCanTp_e_TxResult = CeCanTp_e_Tx_Succeed;		
			
			SeCanTp_w_RespTimer = 0u;
		}
		else
		{
			LeCanTp_e_TxResult = CeCanTp_e_Tx_Wrong;
		}
	}
	else
	{
		LeCanTp_e_TxResult = CeCanTp_e_Tx_Wrong;
	}
	
	return LeCanTp_e_TxResult;
}


 /******************************************************************************
 *函数名称    : 

 *参数        : 

 *返回值      : 

 *描述        : 

 *编辑时间    : 

 *备注        : 
 *****************************************************************************/
void InitCanTp_Parameter(void)
{
	uint8 LeCanTp_u_InitIndex;
	
	for(LeCanTp_u_InitIndex = 0; LeCanTp_u_InitIndex<8 ; LeCanTp_u_InitIndex++)
	{
		SaCanTp_u_RxSFBuffer[LeCanTp_u_InitIndex] = 0;/*单帧buffer*/
		SaCanTp_u_TxBuffer[LeCanTp_u_InitIndex] = 0;
		SaCanTp_u_TxDataBuffer[LeCanTp_u_InitIndex] = 0;
		SaCanTp_u_RxMFBuffer[LeCanTp_u_InitIndex] = 0;/*多帧接收buffer*/
	}
	
	SeCanTp_e_TpSts = CeCanTp_e_Idel;/*TP层工作状态*/

	SeCanTp_u_BS = 0;
	SeCanTp_u_STmin = 10;

	
	SeCanTp_u_RxLen = 0;
	SeCanTp_e_AddrMethod = CeCanTp_e_Physical;/*寻址方式*/

	SeCanTp_u_RxMFDataCnt = 0;
	SeCanTp_u_LastSN = 0;

	SeCanTp_u_Timer = 0;	
	SeCanTp_e_TimerSwitch = 0;

	SeCanTp_e_TxSts = CeCanTp_e_Tx_Idle;/*发送状态*/

	SeCanTp_u_TxLen = 0;

	SeCanTp_u_TxMFIndex = 0;
	SeCanTp_e_MFTxSts = CeCanTp_e_TX_Idel;
	
	SeCanTp_u_MFTxSN = 0; 
	SeCanTp_u_MFTxSpacing = 0;

	SeCanTp_w_RespTimer = 1000U; /*反馈计时器*/
	SeCanTp_u_RespFlag = DAMING_FALSE;
}
  
  
  
  
 /******************************************************************************
 *函数名称    : 

 *参数        : 

 *返回值      : 

 *描述        : 主函数 用于发送 多帧 与 监控超时时间

 *编辑时间    : 

 *备注        : 
 *****************************************************************************/
void MngCanTp_MainFunction(void)
{
	uint8 LeCanTp_u_Index;
	
	if(SeCanTp_e_TpSts == CeCanTp_e_MF_CFTakein)/*超时*/
	{
		if(SeCanTp_e_TimerSwitch == CeCanTp_e_Cr)
		{
			if(SeCanTp_u_Timer > CANTP_CR_TIMEOUT)
			{
				/*超时*/
				SeCanTp_e_TpSts = CeCanTp_e_Idel;
			}
			else
			{
				SeCanTp_u_Timer++;
			}
		}
		else
		{
			SeCanTp_e_TimerSwitch = CeCanTp_e_Cr;
			SeCanTp_u_Timer = 0;
		}
	}
	else
	{
		
	}
	
	if(SeCanTp_u_RespFlag == DAMING_TRUE)/*APP反馈超时*/
	{
		if(SeCanTp_w_RespTimer > CANTP_APP_RESP_78NEG)
		{
			/*超时*/
			SeCanTp_e_TpSts = CeCanTp_e_Idel;
			
			SeCanTp_u_RespFlag = DAMING_FALSE;
			
			SeCanTp_w_RespTimer = 1000U;
		}
		else
		{
			SeCanTp_w_RespTimer++;
		}
	}
	else
	{
		SeCanTp_w_RespTimer = 1000U;
	}
	
	if(SeCanTp_e_TpSts == CeCanTp_e_Answer)
	{
		if(SeCanTp_e_MFTxSts == CeCanTp_e_TX_FCWaiting)/*FC等待超时*/
		{
			if(SeCanTp_e_TimerSwitch == CeCanTp_e_Bs)
			{
				if(SeCanTp_u_Timer > CANTP_BS_TIMEOUT)
				{
					/*超时*/
					SeCanTp_e_MFTxSts = CeCanTp_e_TX_Idel;
					SeCanTp_e_TpSts = CeCanTp_e_Idel;
					SeCanTp_e_TxSts = CeCanTp_e_Tx_Idle;	
				}
				else
				{
					SeCanTp_u_Timer++;
				}
			}
			else
			{
				SeCanTp_e_TimerSwitch = CeCanTp_e_Bs;
				SeCanTp_u_Timer = 0;
			}
		}
		else
		{}

		if(SeCanTp_e_MFTxSts == CeCanTp_e_TX_CFGaving)/*发送*/
		{
			/*CF*/
			SeCanTp_u_MFTxSpacing++;
			
			if(SeCanTp_u_BS > 0)
			{
				if(SeCanTp_u_MFTxSpacing > SeCanTp_u_STmin)
				{
					SeCanTp_u_MFTxSpacing = 1;
					if(SeCanTp_u_TxMFIndex < (SeCanTp_u_TxLen-7))
					{
						SaCanTp_u_TxBuffer[0] = 0x20 + SeCanTp_u_MFTxSN;
						
						for(LeCanTp_u_Index = 0; LeCanTp_u_Index < 7; LeCanTp_u_Index++)
						{
							SaCanTp_u_TxBuffer[LeCanTp_u_Index + 1] = SaCanTp_u_TxDataBuffer[SeCanTp_u_TxMFIndex++];
						}
						TransmitCanIf_Buffer(CANTP_RESP_CANID,8,SaCanTp_u_TxBuffer);
						
						SeCanTp_u_MFTxSN += 1;
						SeCanTp_u_MFTxSN &= 0x0f;
						
						if(SeCanTp_u_BS == 1u)
						{
							SeCanTp_e_MFTxSts = CeCanTp_e_TX_FCWaiting;/*等流控帧*/
							SeCanTp_u_Timer = 0;
							SeCanTp_e_TimerSwitch = CeCanTp_e_Bs;
						}
						else
						{
							SeCanTp_u_BS--;
						}
					}
					else
					{
						/*最后一帧*/
						uint8 LeCanTp_u_Cnt = SeCanTp_u_TxLen - SeCanTp_u_TxMFIndex;
						
						SaCanTp_u_TxBuffer[0] = 0x20 + SeCanTp_u_MFTxSN;
						
						for(LeCanTp_u_Index = 1; LeCanTp_u_Index < 8; LeCanTp_u_Index++)
						{
							SaCanTp_u_TxBuffer[LeCanTp_u_Index] = 0x55;
						}
						
						for(LeCanTp_u_Index = 0; LeCanTp_u_Index < LeCanTp_u_Cnt; LeCanTp_u_Index++)
						{ 
							SaCanTp_u_TxBuffer[LeCanTp_u_Index + 1] = SaCanTp_u_TxDataBuffer[SeCanTp_u_TxMFIndex++];
						}
						TransmitCanIf_Buffer(CANTP_RESP_CANID,8,SaCanTp_u_TxBuffer);
						
						SeCanTp_e_MFTxSts = CeCanTp_e_TX_Idel;
						SeCanTp_e_TpSts = CeCanTp_e_Idel;
						SeCanTp_e_TxSts = CeCanTp_e_Tx_Idle;
						
						SeCanTp_u_BS = 0;
					}
				}
				else
				{}
			}
			else
			{
				SeCanTp_e_MFTxSts = CeCanTp_e_TX_FCWaiting;/*等流控帧*/
				SeCanTp_u_Timer = 0;
				SeCanTp_e_TimerSwitch = CeCanTp_e_Bs;
			}	
		}
		else
		{
			
		}
	}
	else
	{
		
	}
}

 /******************************************************************************
 *函数名称    : 

 *参数        : 

 *返回值      : 

 *描述        : S3 状态函数
				S3 ： 接收到报文 至 反馈完毕（以调用发送函数为标志） 读接口为 DAMING_ACTIVE 否则为 DAMING_INACTIVE

 *编辑时间    : 

 *备注        : 
 *****************************************************************************/
uint8 GetCanTp_u_S3Sts(void)
{
	uint8 LeCanTp_u_Ret;
	
	if(SeCanTp_e_TpSts == CeCanTp_e_Idel)
	{
		LeCanTp_u_Ret = DAMING_ACTIVE;
	}
	else
	{
		LeCanTp_u_Ret = DAMING_INACTIVE;
	}
	
	return LeCanTp_u_Ret;
}
