/******************************************************************************
** 文件名:  EnvelopeScreen.c
** 描 述:   包络筛选处理
*******************************************************************************/

#include "EnvelopeLogicProcess.h"
#include "WholeLineScreenAPI.h"
#include "TrainDataManage.h"


/*================================静态函数声明区==============================*/
static UINT8 elm_ProcessUCTAfterScreen(UINT8 flag,IN const EnvelopeStruct* pTemp,IN const EnvelopeStruct* pEnvelop);  /** 筛选后UCT包络的处理*/
static void elm_AdjustUCTPointAfterScreen(UINT8 flag, UINT16 ACID, LOD_STRU basePose, IN const EnvelopeStruct* pEnvelop);    /** 筛选后UCT包络位置调整*/
static UINT8  elm_TrainScreenByRecover(UINT8 flag,IN const EnvelopeStruct* pEnvelop);    /** 前方列车通信恢复时的快速筛选 */
static void elm_TrainHeadScreen(IN const EnvelopeStruct* pEnvelop);    /* 列车前端筛选 */
static void elm_TrainTailScreen(IN const EnvelopeStruct* pEnvelop);    /* 列车后端筛选 */


/**
 * @brief 筛选后UCT包络的处理
 * @param[in] UINT8 flag 标志位 
 * @param[in] IN const EnvelopeStruct* pTemp, UKT包络
 * @param[in] IN const EnvelopeStruct* pEnvelop， CT包络
 * @param[out] 无
 * @return CI_ERROR 处理失败
           CI_SUCCESS 处理成功
 * @note 无
 */
static UINT8 elm_ProcessUCTAfterScreen(UINT8 flag,IN const EnvelopeStruct* pTemp,IN const EnvelopeStruct* pEnvelop)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 cycleTrain = 0u;
	UINT8 selfFlag = ELM_BELONG_OTHER;
	UINT16 tmpACIndex = 0u;
	UINT16 tmpACID = 0u;

	/** 入口参数校验 */
	ASSERT_RET_VALUE((NULL == pTemp) || (NULL == pEnvelop),ret,0x80000000u);
	ASSERT_RET_VALUE((ELM_HEAD != flag) && (ELM_TAIL != flag),ret,0x40000000u);

	/** 获取需要删除的计轴ID */
	tmpACID = (ELM_TAIL == flag) ? pTemp->ACID[0u] : pTemp->ACID[pTemp->ACCnt - 1u];

	/** 删除计轴到包络的映射 */
	tmpACIndex = elm_PrepareACIndex(tmpACID);
	funRtn = elm_SetACRelEnvelopeMap(OP_DEL,tmpACIndex,pTemp->id);
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);

	/** 设置车尾出清*/
	funRtn = elm_UCTEnvelopeLeaveAC(flag,pTemp,tmpACID);
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x10000000u);

	/** 计轴空闲,回缩车尾,对包络计轴进行了操作，所以需要放到最后*/
	funRtn = elm_PopEnvelopACSeq(flag,pTemp->id);
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x08000000u);

	if (0u == pTemp->ACCnt)
	{
		/** 判断包络是否属于本OC */
		selfFlag = elm_PrepareEnvelopeIsSelf(pTemp);

		if (ELM_BELONG_OWNER == selfFlag)
		{
			/** 清除列车映射关系*/
			for (cycleTrain = 0u; cycleTrain < pTemp->trianCnt;cycleTrain++)
			{
				/** 清除列车关联的包络ID */
				funRtn = elm_SetTrainRelEnvelopeMap(OP_DEL,pTemp->trainID[cycleTrain], pTemp->id);
				ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x04000000u);
			}
		}
		else
		{
			/** 非本OC范围内的包络，不建立列与包络的映射关系 */
		}

		/** 清空包络空间 */
		ELM_LOG(ELM_LOG_FATAL,"info:delete UCT%d because of CT%d Screen.\n",pTemp->id,pEnvelop->id);
		funRtn = elm_ClearEnvelope(pTemp->id);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x02000000u);

	}
	else
	{
		/** 更新计轴 */
		tmpACID = (ELM_TAIL == flag) ? pTemp->ACID[0u] : pTemp->ACID[pTemp->ACCnt - 1u];

		funRtn = elm_SetUCTEnvelopeDot(flag,tmpACID,pTemp);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x01000000u);

		funRtn = elm_ScreenUctCfpFreeProc(pTemp);
		ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00800000u);
	}

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT%d Process error after CT%d Screen.!",errorCode,pTemp->id,pEnvelop->id));
	return ret;
}


/**
 * @brief 筛选后UCT包络位置调整
 * @param[in] UINT8 flag 包络头和包络尾标识
 * @param[in] const EnvelopeStruct* pEnvelop 列车包络 
 * @param[out] 无
 * @return 无
 * @note 无
 */
static void elm_AdjustUCTPointAfterScreen(UINT8 flag, UINT16 ACID,LOD_STRU basePose,IN const EnvelopeStruct* pEnvelop)
{
	UINT32 errorCode = 0u;
	UINT8 cycleElm = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 dirCheck = 0u;
	UINT32 disHead = 0u;
	UINT32 disTail = 0u;
	UINT32 minDisBtwHeadAndTail = 0u;
	UINT32 minDis = 0xffffffffu;
	const EnvelopeStruct* pTemp = NULL;
	const EnvelopeStruct* pOut = NULL;
	UINT8 envelopeCnt = 0u;     /* 包络数量 */
	UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] = {0u};  /*包络ID数组*/

	/** 入口参数校验 */
	ASSERT_RET_NO_VALUE(NULL == pEnvelop,0x80000000u);
	ASSERT_RET_NO_VALUE((ELM_HEAD != flag) && (ELM_TAIL != flag),0x40000000u);

	/** 查询对方分界点处计轴上的包络信息 */
	envelopeCnt = elm_MergeEnvelope(&ACID,1u,arEnvelopID);

	/** 判断包络是否存在UCT包络 */
	for (cycleElm = 0u; cycleElm < envelopeCnt; cycleElm++)
	{
		/** 获取包络的地址指针 */
		pTemp = elm_GetEnvelopeInfoPtr(arEnvelopID[cycleElm]);

		if ((NULL != pTemp) && (TYPE_UCT_ENVELOPE == pTemp->envelopeType))
		{
			/** 存在UCT包络 */
			break;
		}
		else
		{
			/** 继续遍历 */
		}
	}

	if (cycleElm == envelopeCnt)
	{
		/** 说明待筛选计轴上不存在UKT包络，无需处理 */
	}
	else
	{
		/** 查询离筛选点最近的包络 */
		for (cycleElm = 0; cycleElm < envelopeCnt;cycleElm++)
		{
			/** 获取UCT包络的地址指针 */
			pTemp = elm_GetEnvelopeInfoPtr(arEnvelopID[cycleElm]);
			ASSERT_BREAK(NULL == pTemp,errorCode,0x08000000u);

			/** 获取包络起终点离分界点的距离 */
			disHead = elm_PrepareDistanceBtwPoints(pTemp->endPos,basePose);
			disTail = elm_PrepareDistanceBtwPoints(pTemp->startPos,basePose);
			minDisBtwHeadAndTail = disHead > disTail ? disTail : disHead;

			if ((minDis >= minDisBtwHeadAndTail) && (TYPE_UCT_ENVELOPE == pTemp->envelopeType))
			{
				pOut = pTemp;
				minDis = minDisBtwHeadAndTail;
			}
			else if ((minDis >= minDisBtwHeadAndTail) && (TYPE_UCT_ENVELOPE != pTemp->envelopeType))
			{
				/** 补丁：说明UCT在后面*/
				pOut = NULL;
				minDis = minDisBtwHeadAndTail;
			}
			else
			{
				/** 不处理 */
			}
		}

		if (NULL != pOut)
		{
			/** 查询两个包络的位置关系 */
			dirCheck = elm_DirIsSameELMWithELM(pEnvelop,pOut);
			ASSER_ERROR(0u == dirCheck,errorCode,0x10000000u);

			if (ELM_HEAD == flag)
			{		
				if ((ELM_DIR_SAME == dirCheck) && (pOut->ACID[0u] == ACID))
				{
					funRtn = elm_ProcessUCTAfterScreen(ELM_TAIL,pOut,pEnvelop);
					ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x08000000u);
				}
				else if ((ELM_DIR_CONVERT == dirCheck) && (pOut->ACID[pOut->ACCnt - 1u] == ACID))
				{
					funRtn = elm_ProcessUCTAfterScreen(ELM_HEAD,pOut,pEnvelop);
					ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x04000000u);
				}
				else
				{
					/** 无需处理 */
				}
			}
			else
			{
				if ((ELM_DIR_CONVERT == dirCheck) && (pOut->ACID[0u] == ACID))
				{
					funRtn = elm_ProcessUCTAfterScreen(ELM_TAIL,pOut,pEnvelop);
					ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00800000u);
				}
				else if ((ELM_DIR_SAME == dirCheck) && (pOut->ACID[pOut->ACCnt - 1u] == ACID))
				{
					funRtn = elm_ProcessUCTAfterScreen(ELM_HEAD,pOut,pEnvelop);
					ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00400000u);
				}
				else
				{
					/** 无需处理 */
				}
			}
		}
	}

	if(0u != errorCode)
	{
		/** UCT包络跟踪失败 */
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:CT%d after Screen to Adjust UCTPoint error，ELM need reset !",errorCode,pEnvelop->id);
	}
	else
	{
		/** 处理正确*/
	}
}


/**
 * @brief 静态函数：前/后方列车通信恢复时的快速筛选
 * @param[in] UINT8 flag  包络头和包络尾标识
 * @param[in] const EnvelopeStruct* pEnvelop 列车包络 
 * @param[out] 
 * @return CI_ERROR 无法因为前/后方列车通信恢复完成筛选
           CI_SUCCESS 前/后方列车通信恢复完成筛选
 * @note 
 */
static UINT8  elm_TrainScreenByRecover(UINT8 flag,IN const EnvelopeStruct* pEnvelop)
{
	UINT8 ret = CI_ERROR; 
	UINT8 comstatus = ELM_COM_STATUS_ERROR;
	UINT16 tmpTrainID = 0u;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == pEnvelop,ret,0x80000000u);
	ASSERT_RET_VALUE((ELM_HEAD != flag) && (ELM_TAIL != flag),ret,0x40000000u);

	/** 获取前/后方列车 */
	if (ELM_HEAD == flag)
	{
		tmpTrainID = pEnvelop->headTrainID;
	}
	else
	{
		tmpTrainID = pEnvelop->tailTrainID;
	}

	/** 获取列车的通信状态 */
	comstatus = elm_PrepareTrainCommStatus(tmpTrainID);

	/** 设置函数返回值 */
	ASSERT_SETRET(ELM_COM_STATUS_OK == comstatus,ret,CI_SUCCESS,CI_ERROR);

	return ret;
}


/**
 * @brief 静态函数：列车前端筛选
 * @param[in] const EnvelopeStruct* pEnvelop 列车包络
 * @param[out]
 * @return 
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
static void elm_TrainHeadScreen(IN const EnvelopeStruct* pEnvelop)
{
	/*- 局部变量定义 */
	UINT32 errorCode = 0u;                   /* 错误码 */
	UINT8 acCnt = 0u;                         /* 列车最小安全前前方计轴数量*/
	UINT16 acID[AC_MAXCNT_IN_SWITCH] = {0u};  /* 列车最小安全前前方计轴*/
	UINT8 funRet = CI_ERROR;                 /* 函数返回值 */
	UINT16 tmpACId = 0u;                      /*计轴id缓存*/
	UINT8 cycleAc = 0u;                       /*循环变量*/
	UINT8 acStatus = ELM_AC_OCC;             /*计轴占用状态*/
	UINT8 phyStatus = SECTION_OCCUPY_YES;	/*岔区不连通计轴所处物理区段占用状态*/
	UINT8 trainDir = 0u;
	LOD_STRU tmpLoc = {0u};                  /*最小安全前缓存*/
	ELM_AxisLocStruct tmpACLoc = {0u};       /* 计轴端点位置*/
	UINT8 screenCheck = CI_ERROR;                 /* 函数返回值 */
	UINT8 chTrainNvramFlag = 0U;/*列车NVRAM标志*/
	UINT8 chTrainPosMonitorState = 0U;/*列车位置监督标志*/

	/** 入口参数校验 */
	ASSERT_RET_NO_VALUE(NULL == pEnvelop,0x80000000u);

	/** 前方列车通信恢复时的快速筛选 */
	funRet = elm_TrainScreenByRecover(ELM_HEAD,pEnvelop);
	chTrainNvramFlag = GetTrainNvramPosFlag(pEnvelop->trainID[0]);
	chTrainPosMonitorState = GetTrainPosMonitorState(pEnvelop->trainID[0]);

	/** 正常筛选 */
	if (CI_ERROR == funRet)
	{
		/** 查询最小安全前前方计轴*/
		acCnt = elm_PrepareNextAcMinSafeHeadLoc(pEnvelop->trainID[0],acID);
		ASSER_ERROR((0u == acCnt) || (AC_MAXCNT_IN_SWITCH < acCnt),errorCode, 0x40000000u);

		/*- 判断前方计轴是否空闲 */
		for (cycleAc = 0u; cycleAc < acCnt; cycleAc++)
		{
			/** 获取计轴状态 */
			acStatus = elm_PrepareACStatus(acID[cycleAc]);

			/** 判断是否需要退出循环 */
			ASSERT_BREAK(ELM_AC_OCC == acStatus,errorCode,0x20000000u);

			/*当计轴区段为道岔区段，不连通的时候，需要检查计轴所处计轴区段全部空闲才给前筛通过*/
			phyStatus = elm_PrepareACofSwichPhyStatus(acID[cycleAc]);

			/** 判断是否需要退出循环 */
			ASSERT_BREAK(SECTION_OCCUPY_YES == phyStatus, errorCode, 0x00400000u);
		}

		/** 最小安全前前方计轴是否在安全包络内*/
		funRet = elm_PrepareInUINT16Array(acID[0],pEnvelop->ACID,pEnvelop->ACCnt);
		if (CI_SUCCESS == funRet)
		{
			/** 判断前方计轴是否为安全车头所属计轴,如果相同则可以完成前筛，如果安全包络太大并且无占用，应该是车停下的延时，那么就晚点完成前筛也是可以的*/
			funRet = elm_PrepareInUINT16Array(pEnvelop->ACID[pEnvelop->ACCnt - 1U],acID,acCnt);
			ASSER_ERROR(CI_ERROR == funRet,errorCode, 0x10000000u);
		}
		else
		{
			/** 可继续进行筛选*/
		}

		/** 获取最小安全前所属计轴区段*/
		tmpACId = elm_PrepareACOfMinSafeHeadLoc(pEnvelop->trainID[0]);
		ASSER_ERROR(0u == tmpACId,errorCode, 0x08000000u);

		/** 获取列车运行方向 */
		trainDir = elm_PrepareTrainMinHeadDir(pEnvelop->trainID[0]);
		ASSER_ERROR(0u == trainDir,errorCode, 0x04000000u);

		/** 获取计轴端点位置*/
		funRet = elm_PrepareACLoc(tmpACId,trainDir,&tmpACLoc);
		ASSER_ERROR(CI_ERROR == funRet,errorCode, 0x02000000u);

		/** 获取最小安全前位置 */
		funRet = elm_PrepareMinSafeHeadLoc(pEnvelop->trainID[0],&tmpLoc);
		ASSER_ERROR(CI_ERROR == funRet,errorCode, 0x01000000u);

		screenCheck = elm_PrepareHeadScreenCheck(pEnvelop->trainID[0], tmpLoc,tmpACLoc.endPos,&errorCode);

		if ((0u == errorCode) && (CI_SUCCESS == screenCheck) && ((TRAIN_NVRAM_POS_FLAG_NO == chTrainNvramFlag)
			|| ((TRAIN_NVRAM_POS_FLAG_YES == chTrainNvramFlag) && (TRAIN_POS_MONITOR_VALID == chTrainPosMonitorState))))
		{	
			/** 处理前方UCT包络 */
			elm_AdjustUCTPointAfterScreen(ELM_HEAD,tmpACId,tmpACLoc.endPos,pEnvelop);

			/** 设置前车无其他车 */
			funRet = elm_SetEnvelopeHeadTrainID(pEnvelop->id, 0u);
			ASSER_ERROR(CI_ERROR == funRet,errorCode, 0x00200000u);

			/** 维护日志--调试级别*/
			ELM_LOG_LOC(ELM_LOG_FATAL,"info:Train%d,delete Head suspicious.",pEnvelop->trainID[0]);
		}
		else
		{
			if (ADJUST_UCT == screenCheck)
			{
				/** 处理前方UCT包络 */
				elm_AdjustUCTPointAfterScreen(ELM_HEAD,tmpACId,tmpACLoc.endPos,pEnvelop);
			}
			else
			{
				/** 不处理*/
			}

			/** 无法完成筛选*/
			ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:Train%d can't delete Head suspicious.",errorCode,pEnvelop->trainID[0]);
		}
	}
	else
	{
		if ((TRAIN_NVRAM_POS_FLAG_NO == chTrainNvramFlag)
			|| ((TRAIN_NVRAM_POS_FLAG_YES == chTrainNvramFlag) && (TRAIN_POS_MONITOR_VALID == chTrainPosMonitorState)))
		{
			/** 维护日志--调试级别*/
			ELM_LOG_LOC(ELM_LOG_FATAL, "info:Train%d,delete Head suspicious by headTrain%d recover.", pEnvelop->trainID[0], pEnvelop->headTrainID);

			/** 设置前车无其他车 */
			funRet = elm_SetEnvelopeHeadTrainID(pEnvelop->id, 0u);
			ASSER_ERROR(CI_ERROR == funRet, errorCode, 0x00100000u);
		}
		else
		{

		}		
	}
}


/**
 * @brief 静态函数：列车后端筛选
 * @param[in] const EnvelopeStruct* pEnvelop 列车包络 
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
static void elm_TrainTailScreen(IN const EnvelopeStruct* pEnvelop)
{
	/*- 局部变量定义 */
	UINT32 errorCode = 0u;                   /* 错误码 */
	UINT8 acCnt = 0u;                         /* 列车最小安全前前方计轴数量*/
	UINT16 acID[AC_MAXCNT_IN_SWITCH] = {0u};  /* 列车最小安全前前方计轴*/
	UINT8 funRet = CI_ERROR;                 /* 函数返回值 */
	UINT16 tmpACId = 0u;                      /*计轴id缓存*/
	UINT8 cycleAc = 0u;                       /*循环变量*/
	UINT8 acStatus = ELM_AC_OCC;             /*计轴占用状态*/
	UINT8 phyStatus = SECTION_OCCUPY_YES;	/*岔区不连通计轴所处物理区段占用状态*/
	UINT8 trainDir = 0u;
	LOD_STRU tmpLoc = {0u};                  /*最小安全前缓存*/
	ELM_AxisLocStruct tmpACLoc = {0u};       /* 计轴端点位置*/
	UINT8 screenCheck = CI_ERROR;                 /* 函数返回值 */
	UINT8 chTrainNvramFlag = 0U;/*列车NVRAM标志*/
	UINT8 chTrainPosMonitorState = 0U;/*列车位置监督标志*/

	/** 入口参数校验 */
	ASSERT_RET_NO_VALUE(NULL == pEnvelop,0x80000000u);

	/** 前方列车通信恢复时的快速筛选 */
	funRet = elm_TrainScreenByRecover(ELM_TAIL,pEnvelop);
	chTrainNvramFlag = GetTrainNvramPosFlag(pEnvelop->trainID[0]);
	chTrainPosMonitorState = GetTrainPosMonitorState(pEnvelop->trainID[0]);

	/** 正常筛选 */
	if (CI_ERROR == funRet)
	{
		/** 查询最大安全后后方计轴*/
		acCnt = elm_PrepareNextAcMaxSafeTailLoc(pEnvelop->trainID[0],acID);
		ASSER_ERROR((0u == acCnt) || (AC_MAXCNT_IN_SWITCH < acCnt),errorCode, 0x40000000u);

		/*- 判断后方计轴是否空闲 */
		for (cycleAc = 0u; cycleAc < acCnt; cycleAc++)
		{
			/** 获取计轴状态 */
			acStatus = elm_PrepareACStatus(acID[cycleAc]);

			/** 判断是否需要退出循环 */
			ASSERT_BREAK(ELM_AC_OCC == acStatus,errorCode,0x20000000u);

			/*当计轴区段为道岔区段，不连通的时候，需要检查计轴所处计轴区段全部空闲才给后筛通过*/
			phyStatus = elm_PrepareACofSwichPhyStatus(acID[cycleAc]);

			/** 判断是否需要退出循环 */
			ASSERT_BREAK(SECTION_OCCUPY_YES == phyStatus, errorCode, 0x00400000u);
		}

		/** 最大安全后后方计轴是否在安全包络内*/
		funRet = elm_PrepareInUINT16Array(acID[0],pEnvelop->ACID,pEnvelop->ACCnt);
		if (CI_SUCCESS == funRet)
		{
			/** 最大安全后后方计轴是否为最大安全后后方计轴*/
			funRet = elm_PrepareInUINT16Array(pEnvelop->ACID[0],acID,acCnt);
			ASSER_ERROR(CI_ERROR == funRet,errorCode, 0x10000000u);
		}
		else
		{
			/** 可继续进行筛选*/
		}

		/** 获取最大安全后所属计轴*/
		tmpACId = elm_PrepareACOfMaxSafeTailLoc(pEnvelop->trainID[0]);
		ASSER_ERROR(0u == tmpACId,errorCode, 0x08000000u);

		/** 获取列车运行方向 */
		trainDir = elm_PrepareTrainMaxTailDir(pEnvelop->trainID[0]);
		ASSER_ERROR(0u == trainDir,errorCode, 0x04000000u);

		/** 获取计轴端点位置*/
		funRet = elm_PrepareACLoc(tmpACId,trainDir,&tmpACLoc);
		ASSER_ERROR(CI_ERROR == funRet,errorCode, 0x02000000u);

		/** 获取最大安全后位置 */
		funRet = elm_PrepareMaxSafeTailLoc(pEnvelop->trainID[0],&tmpLoc);
		ASSER_ERROR(CI_ERROR == funRet,errorCode, 0x01000000u);

		screenCheck = elm_PrepareTailScreenCheck(pEnvelop->trainID[0], tmpLoc, tmpACLoc.startPos, &errorCode);

		if ((0u == errorCode) && (CI_SUCCESS == screenCheck) && ((TRAIN_NVRAM_POS_FLAG_NO == chTrainNvramFlag)
			|| ((TRAIN_NVRAM_POS_FLAG_YES == chTrainNvramFlag) && (TRAIN_POS_MONITOR_VALID == chTrainPosMonitorState))))
		{		
			/** 处理后方UCT包络 */
			elm_AdjustUCTPointAfterScreen(ELM_TAIL,tmpACId,tmpACLoc.startPos,pEnvelop);

			/** 设置后车无其他车 */
			funRet = elm_SetEnvelopeTailTrainID(pEnvelop->id, 0u);
			ASSER_ERROR(CI_ERROR == funRet,errorCode, 0x00200000u);

			/** 维护日志--调试级别*/
			ELM_LOG_LOC(ELM_LOG_FATAL,"info:Train%d,delete Tail suspicious.\n",pEnvelop->trainID[0]);
		}
		else
		{
			if (ADJUST_UCT == screenCheck)
			{
				/** 处理后方UCT包络 */
				elm_AdjustUCTPointAfterScreen(ELM_TAIL,tmpACId,tmpACLoc.startPos,pEnvelop);
			}
			else
			{
				/** 不处理*/
			}

			/** 无法完成筛选*/
			ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:Train%d can't delete Tail suspicious.",errorCode,pEnvelop->trainID[0]);
		}
	}
	else
	{
		if ((TRAIN_NVRAM_POS_FLAG_NO == chTrainNvramFlag)
			|| ((TRAIN_NVRAM_POS_FLAG_YES == chTrainNvramFlag) && (TRAIN_POS_MONITOR_VALID == chTrainPosMonitorState)))
		{
			/** 维护日志--调试级别*/
			ELM_LOG_LOC(ELM_LOG_FATAL, "info:Train%d,delete Tail suspicious by tailTrain%d recover.", pEnvelop->trainID[0], pEnvelop->tailTrainID);

			/** 设置前车无其他车 */
			funRet = elm_SetEnvelopeTailTrainID(pEnvelop->id, 0u);
			ASSER_ERROR(CI_ERROR == funRet, errorCode, 0x00100000u);
		}
		else
		{
			; 
		}
		
	}

}

/**
 * @brief 列车筛选
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_TrainScreen(void)
{
	UINT16 cycle = 0u;
	UINT8 vaildFlag = ENVELOPE_UNEXIT; 
	UINT32 errorCode = 0u;
	UINT8 comstatus = 0U;
	const EnvelopeStruct* pEnvelop = NULL;

	for (cycle = 1u; cycle < ENVELOPE_SUM_MAX; cycle++)
	{
		/** 获取空间使用标志*/
		vaildFlag = elm_IsEnvelopeExit(cycle);

		if (ENVELOPE_EXIT == vaildFlag)
		{
			/** 获取包络的地址 */
			pEnvelop = elm_GetEnvelopeInfoPtr(cycle);

			/** 判断包络地址是否正确 */
			ASSERT_BREAK(NULL == pEnvelop,errorCode,0x08000000u);
			/** 获取列车的通信状态 */
			comstatus = elm_PrepareTrainCommStatus(pEnvelop->trainID[0u]);
			/*CT包络且通信正常，才进行筛选*/
			if ((TYPE_CT_ENVELOPE == pEnvelop->envelopeType)&&(ELM_COM_STATUS_OK ==comstatus))
			{
				/** 判断前端是否可疑 */
				if (0u != pEnvelop->headTrainID)
				{
					/** 处理前端筛选*/
					elm_TrainHeadScreen(pEnvelop);
				}
				else
				{
					/** 无需处理 */
				}

				/** 判断后端是否可疑*/
				if (0u != pEnvelop->tailTrainID)
				{
					/** 处理后端筛选*/
					elm_TrainTailScreen(pEnvelop);
				}
				else
				{
					/** 无需处理 */
				}

			}
			else
			{
				/** 无需筛选*/
			}
		}
		else			
		{
			/** 无需筛选*/
		}

	}

}



/**
 * @brief 全线免筛处理
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 无
 */
void elm_WLScreenProcess(void)
{
	UINT16 cycle;
	UINT8 wlsFlag = WHOLE_LINE_SCREEN_UNVAILD;
	UINT8 relEnvelopeCnt= TRAIN_REL_ENVELOPE_SUM_MAX;    /*列车关联的包络数量*/
	UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] = {0u};  /*列车关联的包络索引*/
	const EnvelopeStruct *pEnvelopeInfo = NULL;
	UINT8 chTrainNvramPosFlag = 0U; /*列车NVRAM位置标识*/

	/** 获取全线免筛标志 */
	wlsFlag = wls_GetWLScreenPermitFlag();

	if (WHOLE_LINE_SCREEN_VAILD == wlsFlag)
	{
		for (cycle = 1u; cycle < LINE_MAX_TRAIN; cycle++)
		{
			relEnvelopeCnt = elm_GetRelELIdByTrainID(cycle,relEnvelopeID);

			if (1u == relEnvelopeCnt)
			{
				/** UCT包络本集中区内暂未裂变 */
				pEnvelopeInfo = elm_GetEnvelopeInfoPtr(relEnvelopeID[0u]);

				if ((NULL != pEnvelopeInfo) && 
					((TYPE_CT_ENVELOPE == pEnvelopeInfo->envelopeType) || (TYPE_UCT_ENVELOPE == pEnvelopeInfo->envelopeType)))
				{
					ELM_LOG(ELM_LOG_FATAL,"info:ELM%d WLS Process,",pEnvelopeInfo->id);
					chTrainNvramPosFlag = GetTrainNvramPosFlag(cycle);

					if (TRAIN_NVRAM_POS_FLAG_NO == chTrainNvramPosFlag)
					{
						if (LINE_MAX_TRAIN == pEnvelopeInfo->headTrainID)
						{
							ELM_LOG(ELM_LOG_FATAL, " delete Head suspicious,");
							(void)elm_SetEnvelopeHeadTrainID(pEnvelopeInfo->id, 0u);
						}
						else
						{
							/* 不处理 */
						}

						if (LINE_MAX_TRAIN == pEnvelopeInfo->tailTrainID)
						{
							ELM_LOG(ELM_LOG_FATAL, " delete Tail suspicious,");
							(void)elm_SetEnvelopeTailTrainID(pEnvelopeInfo->id, 0u);
						}
						else
						{
							/* 不处理 */
						}
						
					}
					else
					{
						ELM_LOG(ELM_LOG_FATAL, " not finish suspicious,because use nvram pos");
					}

					ELM_LOG(ELM_LOG_FATAL, "\n");		
				}
			}
			else
			{
				/* 无需处理 */
			}
		}
	}
	else
	{
		/** 不处理 */
	}
}
