/******************************************************************************
** 文件名:  UCTEnvelopeTrack.c
** 描 述:   实现UCT包络的追踪处理
** 备注：UCT处理时，如果处理失败，根据更新后的包络进行导向安全处理，基于的是包络头/尾只有空闲才会回撤的原则。
        如果此原则被打破，需要重点去走查导向安全侧的处理。
*******************************************************************************/

#include "EnvelopeLogicProcess.h"
#include "LinkConfigDataManage.h"
#include "AxisSectionConfigDataManage.h"
#include "EnvelopeManageAPI.h"

#define SWITCH_ZONE_OCC_AND_ERROR 0x55u    /* 道岔区域占用且拓扑关系错误*/
#define SWITCH_ZONE_FREE_AND_ERROR 0xaau   /* 道岔区域空闲且拓扑关系错误*/
#define SWITCH_ZONE_OK 0xffu               /* 道岔区域拓扑关系正确*/

#define UCT_LEAVE_REFRESH 0x55u				/* UCT因刷新出清 */
#define UCT_LEAVE_SPLIT 0xaau				/* UCT因恢复出清 */


/*================================静态函数声明区==============================*/
static void elm_ProcessByELMLeave(const UINT8 flag, UINT8 ACCnt, UINT16 ACBuff[SECTION_IN_ENVELOPE_SUM_MAX]);
static UINT8 elm_CheckSwitchInEnvelope(const EnvelopeStruct* ptemp);                                         /* 检查包络内的道岔*/

static UINT8 elm_CheckEnvelopeMergeValid(UINT8 flag,const EnvelopeStruct* pBase, const EnvelopeStruct* pMerge);         /* UCT包络聚变条件有效性检查 */
static UINT8 elm_UCTEnvelopePreMerge(const EnvelopeStruct* pBase, const EnvelopeStruct* pMerge);             /* UCT包络前向聚变*/
static UINT8 elm_UCTEnvelopeBackMerge(const EnvelopeStruct* pBase, const EnvelopeStruct* pMerge);            /* UCT包络后向聚变 */
static UINT8 elm_UCTEnvelopeMerge(UINT8 flag,const EnvelopeStruct* pBase, const EnvelopeStruct* pMerge);     /* UCT包络聚变 */                                                                 /* UCT包络聚变 */


static void elm_HandleUCTHandoverFinished(UINT16 ownCutAcid,UINT16 OwnsideELMid,UINT16 OutsideELMid);    /* UCT切换完成处理 */
static UINT8 elm_HandleCloneOfHandover(UINT16 OwnACID,UINT8 dirHandover,UINT16 OwnsideELMid,UINT16 OutsideELMid, UINT8 cDirChangePointFlag);   /* 分界点处克隆处理 */
static UINT8 elm_SearchNearstTrainInCutPoint(UINT16 OwnACID, UINT8 dirHandover, UINT8 nextACCnt, UINT16 nextACIDBuff[AC_MAXCNT_IN_SWITCH], OUT UINT16 *pOwnsideELMid, OUT UINT16 *pOutsideELMid, UINT8 cDirChangePointFlag);  /* 查询分界点附近最接近的列车 */
static UINT8 elm_UCTEnvelopeCloneByHandOver(void);                                      /* UCT包络裂变--列车切换*/

static const EnvelopeStruct* elm_GetUCTRealEnvelope(UINT16 trainid,UINT8 relEnvelopeCnt,IN UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX]);    /*获取与恢复通信的UCT位置相匹配的UCT包络信息*/
static UINT8 elm_CreateRevoverEnvelope(UINT16 trainId,OUT EnvelopeStruct *pMid,OUT UINT8 *cutFlag);                                                 /*基于恢复通信车的位置，拆分出通信车包络*/
static UINT8 elm_SplitByUCTRevover(IN const EnvelopeStruct *pBase,OUT EnvelopeStruct *pMid,OUT EnvelopeStruct *pPre,OUT EnvelopeStruct *pBack);  /*基于恢复通信车的包络拆分前面的UCT包络*/
static void elm_ClearFormerUCTEnvelope(IN const EnvelopeStruct *pBase);                                                                          /*删除拆分前的UCT包络*/
static void elm_AddSplitEnvelopToRAM(IN EnvelopeStruct *pTemp,UINT8 cutFlag);                                                                    /*添加包络到包络存储区*/
static UINT8 elm_UCTEnvelopeSplit(UINT16 trainId, IN const EnvelopeStruct* pBase);                                                               /*当通信车恢复时，UCT包络拆分*/    

static void elm_RefreshUCTofACMapInfo(IN const EnvelopeStruct *ptemp);     /** 刷新UCT包络计轴映射表 */
static UINT8 elm_UCTEnvelopeHeadHandle(UINT8 endlineFlag,IN const EnvelopeStruct *ptemp,UINT16 headACId,UINT16 preEnvelopeId, UINT8 cDirChangedFlag);    /* UCT包络头部有接近包络的处理*/
static UINT8 elm_UCTEnvelopeHeadMoving(const EnvelopeStruct* ptemp);               /* UCT包络头部移动*/
static UINT8 elm_UCTEnvelopeTailHandle(UINT8 endlineFlag,IN const EnvelopeStruct *ptemp,UINT16 tailACId,UINT16 backEnvelopeId, UINT8 cDirChangedFlag);   /* UCT包络尾部有接近包络的处理*/
static UINT8 elm_UCTEnvelopeTailMoving(const EnvelopeStruct* ptemp);               /* UCT包络尾部移动*/
static UINT8 elm_UCTEnvelopeMoving(const EnvelopeStruct* ptemp);                                             /* UCT包络UCT包络行进 */

static UINT8 elm_ConvertToUCTCheck(const EnvelopeStruct* ptemp);                                             /** CT包络转换成UCT包络检查 */
static UINT8 elm_UCTEnvelopeCreate(const EnvelopeStruct* ptemp);                                             /* UCT包络创建 */
static UINT8 elm_UCTEnvelopeRefresh(const EnvelopeStruct* ptemp);

static UINT8 elm_UCTRecoverCheckElmNear(const UINT16 trainId, OUT UINT8 szFlag[TRAIN_REL_ENVELOPE_SUM_MAX], const UINT8 chEnvelopeCount, const UINT16 szEnvelopeId[TRAIN_REL_ENVELOPE_SUM_MAX]); /* UCT恢复，相邻包络查询 */

static UINT8 elm_UCTToUKTCheck(const EnvelopeStruct* ptemp);  /*根据全线通信车信息检查UCT转UKT条件是否满足*/

/**
 * @brief 包络出清后的计轴处理
 * @param[in] UINT8 ACCnt，计轴数量
 * @param[in] UINT16 ACBuff[SECTION_IN_ENVELOPE_SUM_MAX] 计轴ID存储
 * @param[out] 无
 * @return 无
 * @note 1、当UCT包络恢复时，包络回撤，如果回撤后计轴区段计轴故障，会导致包络重置
         2、当UCT包络内有车恢复，包络回撤，如果回撤后计轴区段计轴故障，会导致包络重置
 */
static void elm_ProcessByELMLeave(const UINT8 flag, UINT8 ACCnt,UINT16 ACBuff[SECTION_IN_ENVELOPE_SUM_MAX])
{
	UINT32 errorCode = 0u;
	UINT8 cycle = 0u;
	UINT8 acOCcStatus = ELM_AC_OCC;
	UINT8 passFlag = AAM_UT_PASS;
	UINT8 funRtn = CI_ERROR;

	/** 入口参数校验 */
	ASSERT_RET_NO_VALUE(ACCnt >= SECTION_IN_ENVELOPE_SUM_MAX,0x80000000u);
	ASSERT_RET_NO_VALUE(NULL == ACBuff,0x40000000u);

	/** 将出清的计轴无好车通过、且状态为占用的计轴添加UKT包络 */
	for (cycle = 0u; cycle < ACCnt; cycle++)
	{
		/** 获取计轴占用状态 */
		acOCcStatus = elm_PrepareACStatus(ACBuff[cycle]);

		/** 获取计轴好车通过标志位 */
		passFlag = aam_GetACPassTrainFlag(ACBuff[cycle]);

		/* 判断是否添加UKT包络 */
		if ((ELM_AC_OCC == acOCcStatus) && (AAM_CT_PASS != passFlag))
		{
			/*- 在占用无其他包络的计轴上添加UKT包络 */
			funRtn = elm_AddUKTEnvelopeInAC(ACBuff[cycle]);

			/** 判断是否执行正确 */
			if (CI_ERROR == funRtn)
			{
				/** 函数执行错误，需要设置该模块无法正常处理标志位 */
				elm_SetELMWorkFlag(ELM_WORK_ERROR);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);
				ASSER_DEBUG(0u != errorCode, ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:ELM Leave Process,ac%d add UKT error.", errorCode, ACBuff[cycle]));
			}
			else
			{
				/** 处理正确，继续处理*/
			}
		}
		else if ((ELM_AC_OCC == acOCcStatus) && (UCT_LEAVE_SPLIT == flag))
		{
			/** 计轴进入冗余状态 */
			aam_SetACEnterRedun(ACBuff[cycle]);
		}
		else
		{
			/** 不处理 */
		}
	}
}

/**
 * @brief 检查包络内的道岔状态
 * @param[in] const EnvelopeStruct* ptemp 包络信息指针
 * @param[out] 无
 * @return SWITCH_ZONE_OCC_AND_ERROR 道岔区域占用且拓扑关系错误
           SWITCH_ZONE_FREE_AND_ERROR 道岔区域空闲且拓扑关系错误
		   SWITCH_ZONE_OK 道岔区域拓扑关系正确
 * @note 无
 */
static UINT8 elm_CheckSwitchInEnvelope(const EnvelopeStruct* ptemp)
{
	UINT8 ret = SWITCH_ZONE_OCC_AND_ERROR;
	UINT8 cycle = 0u;
	UINT8 switchFlag = CI_ERROR;
	UINT8 OccStatus = ELM_AC_OCC;
	UINT8 midStatus = 0u;
	UINT32 errorCode = 0u;

	/** 入口参数检查 */
	ASSERT_RET_VALUE(NULL == ptemp,ret,0x80000000u);

	/** 遍历所有的计轴区段 */
	for (cycle = 0u; cycle < ptemp->ACCnt;cycle++)
	{
		/** 获取计轴的占用状态 */
		OccStatus = elm_PrepareACStatus(ptemp->ACID[cycle]);

		/** 获取计轴关联的道岔的拓扑关系 */
		switchFlag = elm_PrepareCheckACofSwichPos(ptemp->ACID[cycle]);

		if (ELM_AC_OCC == OccStatus)
		{
			/** 如果道岔占用且位置不符合，则跳出循环 */
			ASSERT_BREAK(CI_ERROR == switchFlag,errorCode,0x20000000u);
		}
		else
		{
			if (CI_ERROR == switchFlag)
			{
				/** 如果道岔空闲且位置不符合,继续循环 */
				midStatus = 1u;
			}
			else
			{
				/** 道岔符合拓扑系*/
			}
		}
	}

	/** 设置函数返回值 */
	if (cycle == ptemp->ACCnt)
	{
		ret = (1u == midStatus) ? SWITCH_ZONE_FREE_AND_ERROR : SWITCH_ZONE_OK;
	}
	else
	{
		/** 处理错误 */
	}
	
	return ret;
}


/**
 * @brief 判断两个包络是否满足聚变条件
 * @param[in] UINT8 flag, 聚变方式（ELM_HEAD 基准包络前方存在可聚变包络，ELM_TAIL 基准包络后方存在可聚变包络）
 * @param[in] EnvelopeStruct* pBase, 基准包络
 * @param[in] EnvelopeStruct* pMerge, 待合并包络
 * @param[out] 无
 * @return 0x00u 返回失败,不能合并
           0x55u 返回成功,且两包络内列车完全一致
		   0xaau 返回成功,但两包络内列车不完全一致 
 * @note 
 *       两个UCT包络相碰时，如果包络内跟踪的列车完全不一致，则可聚变成一个UCT包络
 *       两个UCT包络相碰时，如果包络内跟踪的列车完全一致，则可聚变成一个UCT包络
 *       两个UCT包络相碰时，如果两包络内的列车序列去重后可形成连续的列车序列，则可聚变成一个UCT包络
 *       其他情况，两个包络相碰时，不满足聚变条件
 */
static UINT8 elm_CheckEnvelopeMergeValid(UINT8 flag, const EnvelopeStruct* pBase, const EnvelopeStruct* pMerge)
{
	UINT8 ret = CI_ERROR;
	UINT8 baseIndex = 0u;
	UINT8 mergeIndex = 0u;
	UINT8 cycleBase = 0u;
	UINT8 cycleMerge = 0u;
	UINT8 mergeFlag = 0u;

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

	/** 判断两包络内的列车是否完全不一致*/
	if (pBase->trianCnt == pMerge->trianCnt)
	{
		for (cycleBase = 0u; cycleBase < pBase->trianCnt;cycleBase++)
		{
			if (pBase->trainID[cycleBase] != pMerge->trainID[cycleBase])
			{
				break;
			}
		}

		if (cycleBase == pBase->trianCnt)
		{
			/** 说明两包络内的列车完全一致，则可以合并*/
			ret = 0x55u;
		}
		else
		{
			/** 不完全一致，继续判断*/
		}
	}
	else
	{
		/** 不完全一致*/
	}

	if (0x55u != ret)
	{
		/** 说明两包络内的列车不完全一致，需要判断是否满足合并条件 */
		if (ELM_HEAD == flag)
		{
			baseIndex = 0u;
			for (cycleMerge = 0u; cycleMerge < pMerge->trianCnt;cycleMerge++)
			{
				if ((0u == mergeFlag) && (pMerge->trainID[cycleMerge] != pBase->trainID[0u]))
				{
					/** 继续遍历*/
				}
				else
				{
					/** 存在相同的列车序列*/
					mergeFlag = 1u;

					if ((pMerge->trainID[cycleMerge] != pBase->trainID[baseIndex++]))
					{
						/** 说明存在不相同的列车序列，跳出循环*/
						break;
					}
				}
			}

			/** 设置返回值 */
			ASSERT_SETRET(cycleMerge == pMerge->trianCnt,ret,0xaau,0x00u);					
		}
		else
		{
			mergeIndex = 0u;
			for (cycleBase = 0u; cycleBase < pBase->trianCnt;cycleBase++)
			{
				if ((0u == mergeFlag) && (pBase->trainID[cycleBase] != pMerge->trainID[0u]))
				{
					/** 继续遍历*/
				}
				else
				{
					/** 存在相同的列车序列*/
					mergeFlag = 1u;

					if ((pBase->trainID[cycleBase] != pMerge->trainID[mergeIndex++]))
					{
						/** 说明存在不相同的列车序列，跳出循环*/
						break;
					}
				}
			}	

			/** 设置返回值 */
			ASSERT_SETRET(cycleMerge == pBase->trianCnt,ret,0xaau,0x00u);	
		}

	}
	else
	{
		/** 序列完全一致 */
	}

	return ret;
}


/**
 * @brief UCT包络前向聚变
 * @param[in] EnvelopeStruct* pBase, 基准包络
 * @param[in] EnvelopeStruct* pMerge, 前向包络
 * @param[out] 无
 * @return CI_ERROR 返回失败
           CI_SUCCESS 返回成功
 * @note 
 *       如果基准包络和前方包络聚变后在包络中间可能产生隐藏车，则如下处理：
 *       1、如果基准包络和前方包络同向运行，则两包络范围合并，基准包络内的列车序列转换成后端可疑，前方包络内的列车序列保持
 *       2、如果基准包络和前方包络反向运行，则两包络范围合并，如果基准包络内的列车序列数量大于等于前方包络内的列车序列数量，则前方包络内的列车序列转换成基准包络的前方可疑,基准包络内的列车序列保持；
 *       3、如果基准包络和前方包络反向运行，则两包络范围合并，如果基准包络内的列车序列数量小于前方包络内的列车序列数量，则基准包络内的列车序列转换成前方包络的前方可疑，前方包络内的列车序列保持；
 *       如果基准包络和前方包络满足聚变条件且聚变后在包络中间不产生隐藏车，则直接进行聚变，则两包络范围合并，两包络内的列车序列合并。
 */
static UINT8 elm_UCTEnvelopePreMerge(const EnvelopeStruct* pBase, const EnvelopeStruct* pMerge)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 dirCheck = 0u;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == pBase,ret,0x80000000u);
	ASSERT_RET_VALUE(NULL == pMerge,ret,0x40000000u);

	/** 目前处理为：
	             如果两个包络方向相同，删除后方UCT包络导向为UKT，前方UCT包络染上后端可疑 
	             如果两个包络方向相反，删除后方UCT包络导向为UKT，前方UCT包络染上前端可疑 
    */
	dirCheck = elm_DirIsSameELMWithELM(pBase,pMerge);
	if (ELM_DIR_SAME == dirCheck)
	{
		/** 前方车设置后端可疑 */
		funRtn = elm_SetEnvelopeTailTrainID(pMerge->id,LINE_MAX_TRAIN);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);

		/** 聚变功能暂时预留，聚变时，删除后方UCT包络 */
		ELM_LOG(ELM_LOG_FATAL,"info:Delete UCT%d because of Pre UCT:%d SameDir Nearby.\n",pBase->id,pMerge->id);
		funRtn = elm_DeleteCTOrUCTEnvelope(pBase->id);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x10000000u);
	}
	else
	{
		/** 前方车设置前端可疑 */
		funRtn = elm_SetEnvelopeHeadTrainID(pMerge->id,LINE_MAX_TRAIN);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x08000000u);

		/** 聚变功能暂时预留，聚变时，删除后方UCT包络 */
		ELM_LOG(ELM_LOG_FATAL,"info:Delete both UCT:%d-%d because of Pre UCT:%d unSameDir Nearby.\n",pBase->id,pMerge->id,pMerge->id);
		funRtn = elm_DeleteCTOrUCTEnvelope(pBase->id);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x04000000u);
		funRtn = elm_DeleteCTOrUCTEnvelope(pMerge->id);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x02000000u);
	}

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode, ret, CI_SUCCESS, CI_ERROR);
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:UCT pre Merge error.",errorCode));
	return ret;
}

/**
 * @brief UCT包络后向聚变
 * @param[in] EnvelopeStruct* pBase, 基准包络
 * @param[in] EnvelopeStruct* pMerge, 后向包络
 * @param[out] 无
 * @return CI_ERROR 返回失败
           CI_SUCCESS 返回成功
 * @note 
 *       如果基准包络和前方包络聚变后在包络中间可能产生隐藏车，则如下处理：
 *       1、如果基准包络和前方包络同向/反向运行，则两包络范围合并，后向包络内的列车序列转换成后端可疑，基准包络内的列车序列保持
 *       如果基准包络和前方包络满足聚变条件且聚变后在包络中间不产生隐藏车，则直接进行聚变，则两包络范围合并，两包络内的列车序列合并。
 */
static UINT8 elm_UCTEnvelopeBackMerge(const EnvelopeStruct* pBase, const EnvelopeStruct* pMerge)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == pBase,ret,0x80000000u);
	ASSERT_RET_VALUE(NULL == pMerge,ret,0x40000000u);

	/** 目前处理为：
	             如果两个包络方向相同/相反，删除后方UCT包络导向为UKT，前方UCT包络染上后端可疑 
    */

	/** 前方车设置后端可疑 */
	funRtn = elm_SetEnvelopeTailTrainID(pBase->id,LINE_MAX_TRAIN);
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);

	/** 聚变功能暂时预留，聚变时，删除后方UCT包络 */
	ELM_LOG(ELM_LOG_FATAL,"info:Delete UCT%d because of back UCT:%d Nearby.\n",pMerge->id,pBase->id);
	funRtn = elm_DeleteCTOrUCTEnvelope(pMerge->id);
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x08000000u);

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode, ret, CI_SUCCESS, CI_ERROR);
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:UCT back Merge error.",errorCode));
	return ret;
}

/**
 * @brief UCT包络聚变
 * @param[in] UINT8 flag, 聚变方式（0x55 基准包络前方存在可聚变包络，0xaa 基准包络后方存在可聚变包络）
 * @param[in] EnvelopeStruct* pBack, 后向包络
 * @param[in] EnvelopeStruct* pFront, 前向包络
 * @param[out] 无
 * @return CI_ERROR 返回失败
           CI_SUCCESS 返回成功
 * @note 无
 */
static UINT8 elm_UCTEnvelopeMerge(UINT8 flag,const EnvelopeStruct* pBase, const EnvelopeStruct* pMerge)
{
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = CI_ERROR;
	UINT32 errorCode = 0u;

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

	/** 前向聚变 */
	if (ELM_HEAD == flag)
	{
		/** 前向聚变*/
		funRtn = elm_UCTEnvelopePreMerge(pBase,pMerge);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);
	}
	else
	{

		/** 后向聚变*/
		funRtn = elm_UCTEnvelopeBackMerge(pBase,pMerge);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x08000000u);
	}


	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	return ret;
}


/**
 * @brief UCT切换完成处理
 * @param[in] UINT16 ownCutAcid 分界点处本方计轴ID 
 * @param[in] UINT16 OwnsideELMid 分界点处理本方最接近分界点处的包络ID
 * @param[in] UINT16 OutsideELMid 分界点处理对方最接近分界点处的包络ID
 * @param[out] 无
 * @return CI_ERROR 返回失败
           CI_SUCCESS 返回成功
 * @note 无
 */
static void elm_HandleUCTHandoverFinished(UINT16 ownCutAcid,UINT16 OwnsideELMid,UINT16 OutsideELMid)
{
	UINT32 errorCode = 0u;
	UINT8 DelValid = 0xffu;
	UINT8 cycle = 0u;
	UINT8 acOccStatus = ELM_AC_OCC;
	UINT8 funRtn = CI_ERROR;
	UINT8 envelopeCnt = 0u;     /* 包络数量 */
	UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] = {0u};  /*包络ID数组*/
	const EnvelopeStruct *pOwn = NULL;
	const EnvelopeStruct *pNext = NULL;

	/** 判断是否需要处理本方切换过去的UCT包络 */
	pOwn = elm_GetEnvelopeInfoPtr(OwnsideELMid);
	pNext = elm_GetEnvelopeInfoPtr(OutsideELMid);

	if ((NULL != pOwn) && (NULL != pNext) && (TYPE_UCT_ENVELOPE == pOwn->envelopeType))
	{
		/** 判断UCT包络是否全空闲 */
		for (cycle = 0u; cycle < pOwn->ACCnt;cycle++)
		{
			acOccStatus =  elm_PrepareACStatus(pOwn->ACID[cycle]);
			ASSERT_BREAK(ELM_AC_OCC == acOccStatus,errorCode,0u);
		}

		if (cycle == pOwn->ACCnt)
		{
			if ((TYPE_CT_ENVELOPE == pNext->envelopeType) && (1u == pOwn->trianCnt) &&
				(pNext->trainID[0u] == pOwn->trainID[0u]))
			{
				DelValid = 0x55u;
			}
			else if(TYPE_UCT_ENVELOPE == pNext->envelopeType)
			{
				/** 两个包络满足聚变条件且本方包络所有的列车都包含于对方UCT包络 */
				funRtn = elm_CheckEnvelopeMergeValid(ELM_HEAD,pOwn,pNext);

				/** 设置包络是否可以删除 */
				DelValid = (0x55u == funRtn) ? 0x55u : 0xffu;

			}
			else if (TYPE_UKT_ENVELOPE == pNext->envelopeType)
			{
				/** 说明对方无法克隆，导向了UKT追踪，也可以删除*/
				DelValid = 0x55u;
			}
			else
			{
				/** 无需处理 */
			}

			if (0x55u == DelValid)
			{
				ELM_LOG(ELM_LOG_FATAL,"info:UCT%d handover finished.\n",pOwn->id);
				/* 完成切换，清除本控区好车通过 */
				for (cycle = 0u; cycle < pOwn->ACCnt; cycle++)
				{
					(void)aam_ClearACPassTrainFlag(pOwn->ACID[cycle]);
				}
				elm_ClearFormerUCTEnvelope(pOwn);
			}
			else
			{
				/** 无需处理 */
			}
		}
		else
		{
			/** UCT非空闲,无需处理 */
		}
	}
	else
	{
		/** 查询本方分界点处计轴上的包络信息 */
		envelopeCnt = elm_MergeEnvelope(&ownCutAcid,1u,arEnvelopID);

		if (TRAIN_SUM_MAX_IN_OC == envelopeCnt)
		{
			/** 查询错误，不处理*/
		}
		else
		{
			/** 临时补丁，后续分界点UCT合并时优化 */
			pOwn = elm_GetEnvelopeInfoPtr(arEnvelopID[0u]);
			if ((NULL != pOwn) && (TYPE_UCT_ENVELOPE == pOwn->envelopeType) && (1u == envelopeCnt))
			{
				ELM_LOG(ELM_LOG_FATAL,"info:UCT%d handover finished.\n",pOwn->id);
				/* 完成切换，清除本控区好车通过 */
				for (cycle = 0u; cycle < pOwn->ACCnt; cycle++)
				{
					(void)aam_ClearACPassTrainFlag(pOwn->ACID[cycle]);
				}
				elm_ClearFormerUCTEnvelope(pOwn);
			}
			else
			{
				/** 不处理 */
			}
		}
	}
}

/**
 * @brief 分界点处克隆处理
 * @param[in] UINT16 OwnACID 分界点本方计轴区段
 *            UINT8 dirHandover 移交方向
 *            UINT16 OwnsideELMid 分界点处理本方最接近分界点处的包络ID
 *            UINT8 cDirChangePointFlag 分界点是否为方向变化点标志
 * @param[in] UINT16 OutsideELMid 分界点处理对方最接近分界点处的包络ID
 * @param[out] 无
 * @return CI_ERROR 返回失败
           CI_SUCCESS 返回成功
 * @note 无
 */
static UINT8 elm_HandleCloneOfHandover(UINT16 OwnACID, UINT8 dirHandover, UINT16 OwnsideELMid, UINT16 OutsideELMid, UINT8 cDirChangePointFlag)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 dirCheck = 0u;
	UINT8 cloneFlag = 0u;
	const EnvelopeStruct* pOwnSide = NULL;
	const EnvelopeStruct* pOutSide = NULL;
	EnvelopeStruct cloneElm = { 0u };
	EnvelopeStruct tempElm = { 0u };
	ELM_AxisLocStruct AcLoc = { 0u };
	ELM_AxisLocStruct cOwnAcLoc = { 0u };
	UINT8 cDirChangeNum = 0U;  /*方向变化点数量*/
	UINT8 cDirChangeNumBtwCAndOwn = 0U;		/*分界点计轴到本方包络的方向变化点数量*/
	UINT8 cOwnQueryDir = 0U;
	UINT8 cOutQueryDir = 0U;
	UINT8 cTempElmFlag = FLAG_UNSET;
	UINT16* pLinkIDBuf = NULL;
	ELM_TrainSafeLocStruct safeLoc = { 0U };
	UINT8 chFunRtn = CI_ERROR;

	/** 入口参数校验*/
	ASSERT_RET_VALUE(((0U == OwnACID) || (AXIS_SECTION_SUM_MAX < OwnACID)), ret, 0x80000000u);
	ASSERT_RET_VALUE((ELM_DIR_SAME != dirHandover) && (ELM_DIR_CONVERT != dirHandover), ret, 0x80000000u);
	ASSERT_RET_VALUE(((DIRECTIONPOINT_FLAG_VALID != cDirChangePointFlag) && (DIRECTIONPOINT_FLAG_INVALID != cDirChangePointFlag)), ret, 0x80000000u);

	/** 获取包络信息 */
	pOwnSide = elm_GetEnvelopeInfoPtr(OwnsideELMid);
	pOutSide = elm_GetEnvelopeInfoPtr(OutsideELMid);

	if ((NULL == pOutSide) || (TYPE_UCT_ENVELOPE != pOutSide->envelopeType))
	{
		/** 说明外方无UCT包络接近，不处理 */
	}
	else if ((NULL == pOwnSide) || (TYPE_UCT_ENVELOPE != pOwnSide->envelopeType))
	{
		/** 说明本方无包络占用,克隆分界点外方UCT包络的信息 */
		funRtn = CommonMemCpy(&cloneElm, (UINT32)sizeof(EnvelopeStruct), pOutSide, (UINT32)sizeof(EnvelopeStruct));
		ASSER_ERROR(0u == funRtn, errorCode, 0x40000000u);

		/*本方不存在包络时，创建临时包络*/
		if (NULL == pOwnSide)
		{
			/*包络为空，创建临时包络*/
			funRtn = elm_CreatTempUKTEnvelope(OwnACID, EMAP_SAME_DIR, &tempElm);
			pOwnSide = &tempElm;  /*将临时包络作为本方分界点处包络，用于查询对方到本方间的方向变化点数量*/

			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00400000u);
			ASSERT_SETRET(CI_ERROR == funRtn, cTempElmFlag, FLAG_UNSET, FLAG_SET);  /*创建成功，置位*/
		}
		else
		{
			/*存在包络，不创建临时包络*/
		}

		/*确定本方与对方包络在分界点处的起点方向*/
		cDirChangeNum = elm_PrepareDirChangNum(&(pOutSide->startPos), &(pOwnSide->startPos));  /*判断方向变化点数量*/

																							   /*查询本方包络到分界点方向变换点数量*/
		pLinkIDBuf = GetAxisLinkIdBuf(OwnACID);
		cOwnAcLoc.startPos.Lnk = pLinkIDBuf[0U];
		cOwnAcLoc.startPos.Off = 1u;
		cDirChangeNumBtwCAndOwn = elm_PrepareDirChangNum(&(cOwnAcLoc.startPos), &(pOwnSide->startPos));		/*确定分界点到本方包络之间的方向变化点数量*/

		cDirChangeNum = cDirChangeNum - cDirChangeNumBtwCAndOwn;			/*考虑跨过分解点后仍然有方向变化点，会导致对方始端的方向转换不对*/

		cOwnQueryDir = elm_PrepareDirByChangeNum(pOutSide->startPos.Dir, cDirChangeNum);  /*确定本方包络起点方向，考虑对方方向变化点以及分界点处方向变化点后的方向，针对CT包络跨计轴在本方出现方向变化点会查重复情况*/

		if ((0U != cDirChangeNum) && (DIRECTIONPOINT_FLAG_VALID == cDirChangePointFlag))
		{
			cDirChangeNum--;  /*查询本方包络起点与对方包络起点间的方向变化点时包含分界点，若分界点为方向变化点，需去重*/
		}
		else
		{
			/*不处理*/
		}
		cOutQueryDir = elm_PrepareDirByChangeNum(pOutSide->startPos.Dir, cDirChangeNum);  /*确定对方包络在对方分界点计轴处的起点方向*/

																						  /** 判断是否本方通信车与相邻方的接近UCT ID一样，如果一样则无需clone */
		if (TYPE_CT_ENVELOPE == pOwnSide->envelopeType)
		{

			if (dirHandover != cOutQueryDir)
			{
				cloneFlag = (cloneElm.trainID[0u] == pOwnSide->trainID[0u]) ? 0u : 1u;
			}
			else
			{

				cloneFlag = (cloneElm.trainID[cloneElm.trianCnt - 1u] == pOwnSide->trainID[0u]) ? 0u : 1u;
			}
		}
		else if ((0u != pOutSide->headTrainID) && (0u != pOutSide->tailTrainID))
		{
			/** 补丁：外方UCT存在前后可疑，不进行克隆 */
			cloneFlag = 0u;
			ELM_LOG(ELM_LOG_FATAL, "info:can't Clone because UCT%d has head and tail suspicious.\n", pOutSide->id);
		}
		else
		{
			/** 本方占用无包络 */
			cloneFlag = 1u;
		}

		ASSER_ERROR((0U == cOwnQueryDir) || (0U == cOutQueryDir), errorCode, 0x00200000u);
		ASSERT_SETRET((0U == cOwnQueryDir) || (0U == cOutQueryDir), cloneFlag, 0U, cloneFlag);  /*保证方向需有效，无效不处理*/

		if (1u == cloneFlag)
		{
			/** 更新位置 */
			funRtn = elm_PrepareACLoc(OwnACID, cOwnQueryDir, &AcLoc);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);

			/** 初始化UCT包络的位置 */
			cloneElm.startPos = AcLoc.startPos;
			cloneElm.endPos = AcLoc.endPos;
			cloneElm.startPos.Dir = cOwnQueryDir;
			cloneElm.endPos.Dir = cOwnQueryDir;

			/** 根据本方UCT包络调整位置 */
			if ((NULL != pOwnSide) && (TYPE_CT_ENVELOPE == pOwnSide->envelopeType))
			{
				/** 查询两个包络的方向*/
				dirCheck = elm_DirIsSameELMWithELM(&cloneElm, pOwnSide);

				/** 获取包络的位置*/
				if (dirHandover == cOutQueryDir)
				{
					if (ELM_DIR_SAME == dirCheck)
					{
						chFunRtn = elm_PrepareTrainSafeLoc(pOwnSide->trainID[0U], &safeLoc);
						if (CI_SUCCESS == chFunRtn)
						{
							cloneElm.endPos = safeLoc.startPos;
						}
						else
						{
							; /*保持初始包络位置*/
						}
					}
					else
					{
						chFunRtn = elm_PrepareTrainSafeLoc(pOwnSide->trainID[0U], &safeLoc);
						if (CI_SUCCESS == chFunRtn)
						{
							cloneElm.endPos = safeLoc.endPos;
						}
						else
						{
							; /*保持初始包络位置*/
						}
					}
				}
				else
				{
					if (ELM_DIR_SAME == dirCheck)
					{
						chFunRtn = elm_PrepareTrainSafeLoc(pOwnSide->trainID[0U], &safeLoc);
						if (CI_SUCCESS == chFunRtn)
						{
							cloneElm.startPos = safeLoc.endPos;
						}
						else
						{
							; /*保持初始包络位置*/
						}
					}
					else
					{
						chFunRtn = elm_PrepareTrainSafeLoc(pOwnSide->trainID[0U], &safeLoc);
						if (CI_SUCCESS == chFunRtn)
						{
							cloneElm.startPos = safeLoc.startPos;
						}
						else
						{
							; /*保持初始包络位置*/
						}
					}
				}
			}
			else
			{
				/** 不需要调整 */
			}
			/*CT处理时会改方向*/
			cloneElm.startPos.Dir = cOwnQueryDir;
			cloneElm.endPos.Dir = cOwnQueryDir;
			/** 更新包络计轴序列*/
			funRtn = CommonMemSet(cloneElm.ACID, (UINT32)(sizeof(UINT16)*SECTION_IN_ENVELOPE_SUM_MAX), 0u, (UINT32)(sizeof(UINT16)*SECTION_IN_ENVELOPE_SUM_MAX));
			cloneElm.ACCnt = elm_PrepareACBtwPoints(cloneElm.startPos, cloneElm.endPos, &(cloneElm.ACID[0]));
			ASSER_ERROR((0u == funRtn) || (0u == cloneElm.ACCnt), errorCode, 0x10000000u);

			/** 将包络添加到内存区*/
			elm_AddSplitEnvelopToRAM(&cloneElm, ELM_NO_CUT);
			ASSER_DEBUG(0u == errorCode, ELM_LOG(ELM_LOG_FATAL, "info:Clone UCT%d base UCT%d.\n", cloneElm.id, pOutSide->id));

			/** 包络前后端监控 */
			if ((NULL == pOwnSide) || ((TYPE_UKT_ENVELOPE == pOwnSide->envelopeType) && (FLAG_SET == cTempElmFlag)))
			{
				/** 无需处理 */
			}
			else if ((TYPE_UKT_ENVELOPE == pOwnSide->envelopeType) && (FLAG_UNSET == cTempElmFlag))  /*本方包络非临时创建的UKT包络*/
			{
				if (dirHandover == cOutQueryDir)
				{
					funRtn = elm_SetEnvelopeHeadTrainID(cloneElm.id, LINE_MAX_TRAIN);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x08000000u);
				}
				else
				{
					funRtn = elm_SetEnvelopeTailTrainID(cloneElm.id, LINE_MAX_TRAIN);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x08000000u);
				}
			}
			else
			{
				/** 查询两个包络的方向*/
				dirCheck = elm_DirIsSameELMWithELM(&cloneElm, pOwnSide);

				/** 获取包络的位置*/
				if (dirHandover == cOutQueryDir)
				{
					if (((ELM_DIR_CONVERT == dirCheck) && ((cloneElm.trainID[cloneElm.trianCnt - 1u] == pOwnSide->headTrainID) || (0u == pOwnSide->headTrainID)))
						|| ((ELM_DIR_SAME == dirCheck) && ((cloneElm.trainID[cloneElm.trianCnt - 1u] == pOwnSide->tailTrainID) || (0u == pOwnSide->tailTrainID))))
					{
						/** 无需处理*/
					}
					else
					{
						funRtn = elm_SetEnvelopeHeadTrainID(cloneElm.id, LINE_MAX_TRAIN);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x04000000u);
					}
				}
				else
				{
					if (((ELM_DIR_SAME == dirCheck) && ((cloneElm.trainID[0u] == pOwnSide->headTrainID) || (0u == pOwnSide->headTrainID)))
						|| ((ELM_DIR_CONVERT == dirCheck) && ((cloneElm.trainID[0u] == pOwnSide->tailTrainID) || (0u == pOwnSide->tailTrainID))))
					{
						/** 无需处理*/
					}
					else
					{
						funRtn = elm_SetEnvelopeTailTrainID(cloneElm.id, LINE_MAX_TRAIN);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x02000000u);
					}
				}
			}

			/** 吃掉UKT包络 */
			if ((NULL != pOwnSide) && (TYPE_UKT_ENVELOPE == pOwnSide->envelopeType) && (FLAG_UNSET == cTempElmFlag))		/*临时建立的UKT，不让吃*/
			{
				/** 吃掉UCT包络 */
				funRtn = elm_DeleteUKTEnvelope(pOwnSide);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x01000000u);
			}
			else
			{
				/** 无需处理 */
			}
		}
		else
		{
			/** 不需要克隆 */
		}
	}
	else
	{
		/** 查询两个包络的方向*/
		dirCheck = elm_DirIsSameELMWithELM(pOutSide, pOwnSide);

		/*确定本方与对方包络在分界点处的起点方向*/
		cDirChangeNum = elm_PrepareDirChangNum(&(pOutSide->startPos), &(pOwnSide->startPos));  /*判断方向变化点数量*/

																							   /*查询本方包络到分界点方向变换点数量*/
		pLinkIDBuf = GetAxisLinkIdBuf(OwnACID);
		cOwnAcLoc.startPos.Lnk = pLinkIDBuf[0U];
		cOwnAcLoc.startPos.Off = 1u;
		cDirChangeNumBtwCAndOwn = elm_PrepareDirChangNum(&(cOwnAcLoc.startPos), &(pOwnSide->startPos));		/*确定分界点到本方包络之间的方向变化点数量*/

		cDirChangeNum = cDirChangeNum - cDirChangeNumBtwCAndOwn;			/*考虑跨过分解点后仍然有方向变化点，会导致对方始端的方向转换不对*/

		if ((0U != cDirChangeNum) && (DIRECTIONPOINT_FLAG_VALID == cDirChangePointFlag))
		{
			cDirChangeNum--;  /*查询本方包络起点与对方包络起点间的方向变化点时包含分界点，若分界点为方向变化点，需去重*/
		}
		else
		{
			/*不处理*/
		}
		cOutQueryDir = elm_PrepareDirByChangeNum(pOutSide->startPos.Dir, cDirChangeNum);  /*确定对方包络在对方分界点计轴处的起点方向*/

		if (0U != cOutQueryDir)
		{
			if ((ELM_DIR_SAME == dirCheck) && (1u == pOutSide->trianCnt) && (pOwnSide->trianCnt == pOutSide->trianCnt) && (pOwnSide->trainID[0u] == pOutSide->trainID[0u]))
			{
				/** 同一UCT切换可疑标志的污染 */
				if ((dirHandover != cOutQueryDir) && (0u != pOutSide->headTrainID))
				{
					(void)elm_SetEnvelopeHeadTrainID(pOwnSide->id, LINE_MAX_TRAIN);
				}
				else if ((dirHandover == cOutQueryDir) && (0u != pOutSide->tailTrainID))
				{
					(void)elm_SetEnvelopeTailTrainID(pOwnSide->id, LINE_MAX_TRAIN);
				}
				else
				{
					/** 无需处理 */
				}
			}
			else
			{
				ELM_LOG(ELM_LOG_FATAL, "info:UCT%d can't merge UCT%d,becasue:%02x,%d-%d,%d-%d.\n", pOwnSide->id, pOutSide->id, dirCheck, pOwnSide->trianCnt, \
					pOutSide->trianCnt, pOwnSide->trainID[0u], pOutSide->trainID[0u]);

				/** 删除本方的UCT包络 */
				funRtn = elm_DeleteCTOrUCTEnvelope(OwnsideELMid);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00800000u);
				if (dirHandover == cOutQueryDir)
				{
					(void)elm_SetEnvelopeHeadTrainID(pOutSide->id, LINE_MAX_TRAIN);
				}
				else
				{
					(void)elm_SetEnvelopeTailTrainID(pOutSide->id, LINE_MAX_TRAIN);
				}
			}
		}
		else
		{
			ASSER_ERROR(0U == cOwnQueryDir, errorCode, 0x00100000u);
		}
	}

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode, ret, CI_SUCCESS, CI_ERROR);
	ASSER_DEBUG(0u != errorCode, ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:Clone UCT%d base next UCT%d error.\n", errorCode, pOutSide->id));
	return ret;
}

/**
 * @brief 查询分界点附近最接近的列车
 * @param[in] UINT16 OwnACID 本方分界点处计轴区段
 * @param[in] UINT8 dirHandover 进入到本方区域的方向
 * @param[in] UINT8 nextACCnt 对方分界点处计轴区段数量
 * @param[in] UINT16 nextACIDBuff[AC_MAXCNT_IN_SWITCH] 对方分界点处计轴区段ID缓存
 * @param[in] cDirChangePointFlag 方向变化点标志
 * @param[out] UINT16 *pOwnsideELMid 本方接近分界点处的列车包络ID
 * @param[out] UINT16 *pOutsideELMid 对方接近分界点处的列车包络ID
 * @return CI_ERROR 返回失败
           CI_SUCCESS 返回成功
 * @note 
 */
static UINT8 elm_SearchNearstTrainInCutPoint(UINT16 OwnACID, UINT8 dirHandover, UINT8 nextACCnt, UINT16 nextACIDBuff[AC_MAXCNT_IN_SWITCH], OUT UINT16 *pOwnsideELMid, OUT UINT16 *pOutsideELMid, UINT8 cDirChangePointFlag)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 cycle = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 envelopeCnt = 0u;     /* 包络数量 */
	UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] = { 0u };  /*包络ID数组*/
	const EnvelopeStruct* pTemp = NULL;
	const EnvelopeStruct* pOut = NULL;
	UINT16 preEnvelopeid = 0u;
	UINT16 backEnvelopeid = 0u;
	UINT32 disHead = 0u;
	UINT32 disTail = 0u;
	UINT32 minDisBtwHeadAndTail = 0u;
	UINT32 minDis = 0xffffffffu;
	ELM_AxisLocStruct AcLoc = { 0u };
	UINT8 includeCnt = 0u;
	UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] = { 0u };  /** 重合的包络id */
	UINT16 szAxleIncLinkIdBuff[AXIS_INCLUDE_LINK_SUM_MAX] = { 0u };
	LOD_STRU lodStrPointA = { 0U };
	LOD_STRU lodStrPointB = { 0U };
	UINT8 cDirChangeNum = 0U;  /*方向变化点数量*/
	UINT8 cQueryDir = 0U;
	UINT8 dirOwnToC = 0U;		/*对方到分界点，在本方内的方向*/

								/** 入口参数校验 */
	ASSERT_RET_VALUE((NULL == nextACIDBuff) || (NULL == pOwnsideELMid) || (NULL == pOutsideELMid), ret, 0x80000000u);
	ASSERT_RET_VALUE((ELM_DIR_SAME != dirHandover) && (ELM_DIR_CONVERT != dirHandover), ret, 0x40000000u);
	ASSERT_RET_VALUE((0u == nextACCnt) && (AC_MAXCNT_IN_SWITCH <= nextACCnt), ret, 0x20000000u);

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

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

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

	if (cycle == envelopeCnt)
	{
		/** 无UCT接近，无需处理 */
		*pOwnsideELMid = 0u;
		*pOutsideELMid = 0u;
	}
	else if ((cycle != envelopeCnt) && (1u == nextACCnt))
	{
		/*更新初始方向*/
		if (DIRECTIONPOINT_FLAG_VALID == cDirChangePointFlag)
		{
			dirOwnToC = ~dirHandover;		/*有方向变化点，需要考虑起始寻的点的方向*/
		}
		else
		{
			dirOwnToC = dirHandover;	/*无方向变化点，无需转方向*/
		}
		/** 更新位置 */
		funRtn = elm_PrepareACLoc(OwnACID, dirOwnToC, &AcLoc);
		ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

		for (cycle = 0; cycle < envelopeCnt; cycle++)
		{
			/** 获取UCT包络的地址指针 */
			pTemp = elm_GetEnvelopeInfoPtr(arEnvelopID[cycle]);
			ASSERT_BREAK(NULL == pTemp, errorCode, 0x08000000u);

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

			if (minDis > minDisBtwHeadAndTail)
			{
				pOut = pTemp;
				minDis = minDisBtwHeadAndTail;
			}
			else
			{
				/** 不处理 */
			}
		}

		/** 判断是否查询成功 */
		ASSER_ERROR(NULL == pOut, errorCode, 0x04000000u);
		if (0u != errorCode)
		{
			/** 说明处理失败*/
		}
		else if (TYPE_UCT_ENVELOPE == pOut->envelopeType)
		{
			/** 设置外方包络id */
			*pOutsideELMid = pOut->id;

			/** 获取UCT包络的地址指针 */
			pTemp = elm_GetEnvelopeInfoPtr(arEnvelopID[0u]);

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

			/** 查询UCT前后方列车*/
			funRtn = elm_SearchNearestEnvelope(pOut, arEnvelopID, envelopeCnt, &preEnvelopeid, &backEnvelopeid, &includeCnt, includeELMid);
			ASSER_ERROR(CI_SUCCESS != funRtn, errorCode, 0x02000000u);

			/** 设置本方接近分界点的包络 */
			funRtn = elm_PrepareACrelLink(nextACIDBuff[0U], DIR_SAME, szAxleIncLinkIdBuff);  /*获取计轴包含的link*/
			if (CI_SUCCESS == funRtn)
			{
				lodStrPointA.Lnk = pOut->startPos.Lnk;
				lodStrPointA.Off = pOut->startPos.Off;

				lodStrPointB.Lnk = szAxleIncLinkIdBuff[0];
				lodStrPointB.Off = 1U;

				cDirChangeNum = elm_PrepareDirChangNum(&lodStrPointA, &lodStrPointB);  /*获取包络起点至分界点间的方向变化点数量*/

				cQueryDir = elm_PrepareDirByChangeNum(pOut->startPos.Dir, cDirChangeNum);  /*根据方向变化点数量改变查询方向*/
				if (0U != cQueryDir)
				{
					if (cQueryDir == dirHandover)
					{
						*pOwnsideELMid = preEnvelopeid;
					}
					else
					{
						*pOwnsideELMid = backEnvelopeid;
					}

					ELM_LOG(ELM_LOG_FATAL, "OutsideUCT:%d need to merge[%d,%d-%d] OwnUCT:%d in AC%d.\n", *pOutsideELMid, envelopeCnt, preEnvelopeid, backEnvelopeid, *pOwnsideELMid, OwnACID);
				}
				else
				{
					/*无操作*/
				}
			}
			else
			{
				/** 查询失败*/
			}
		}
		else
		{
			/** 无UCT接近，无需处理 */
			*pOwnsideELMid = 0u;
			*pOutsideELMid = 0u;
		}
	}
	else
	{
		/** UCT占用的计轴区段不可能四开，不可能分支 */
		errorCode += 0x08000000u;
	}

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode, ret, CI_SUCCESS, CI_ERROR);
	ASSER_DEBUG(0u != errorCode, ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:Search Nearest Train In CutPoint error.\n", errorCode));
	return ret;
}


/** 
 * @brief UCT包络裂变--列车切换
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 */
static UINT8 elm_UCTEnvelopeCloneByHandOver(void)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 cycle = 0u;
	UINT8 cycleAC = 0u;
	UINT8 acCnt = 0u;
	UINT16 acIDBuff[CUTOFF_POINT_SUM_MAX] = {0u};
	UINT8 acOccStatus = ELM_AC_OCC;
	UINT8 nextACCnt = 0u;
	UINT8 searchDir = 0u;
	UINT16 nextACIDBuff[AC_MAXCNT_IN_SWITCH] = {0u};
	UINT16 OwnsideELMid = 0u;
	UINT16 OutsideELMid = 0u;
	UINT8 cDirChangePointFlag = DIRECTIONPOINT_FLAG_INVALID;

	/** 获取分界点处本OC范围的计轴区段*/
	acCnt = elm_PrepareCfpAc(acIDBuff);
	ASSER_ERROR(CUTOFF_POINT_SUM_MAX == acCnt,errorCode,0x80000000u);

	for (cycle = 0u; cycle < acCnt; cycle++)
	{
		cDirChangePointFlag = DIRECTIONPOINT_FLAG_INVALID;  /*每遍历一次，清一次标志*/

		/** 查询分界点相邻OC的计轴区段，及查询到相邻OC区域计轴区段的方向 */
		nextACCnt = elm_PrepareCfpOtherTiocAc(acIDBuff[cycle], &searchDir, nextACIDBuff, &cDirChangePointFlag);
		ASSERT_BREAK(UINT8_MAX == nextACCnt,errorCode,0x40000000u);

		/** 查询相邻计轴区段是否占用 */
		for (cycleAC = 0u; cycleAC < nextACCnt; cycleAC++)
		{
			/** 获取计轴的占用*/
			acOccStatus = elm_PrepareACStatus(nextACIDBuff[cycleAC]);
			ASSERT_BREAK(ELM_AC_OCC == acOccStatus,errorCode,0x00000000u);
		}

		if (cycleAC == nextACCnt)
		{
			/** 相邻计轴空闲，无需处理 */
		}
		else
		{
			/** 查询分界点附近最接近的列车 */
			funRtn = elm_SearchNearstTrainInCutPoint(acIDBuff[cycle],searchDir,nextACCnt,nextACIDBuff,&OwnsideELMid,&OutsideELMid, cDirChangePointFlag);
			ASSERT_BREAK(CI_ERROR == funRtn,errorCode,0x20000000u);

			if (CI_SUCCESS == funRtn)
			{
				/** 获取计轴的占用*/
				acOccStatus = elm_PrepareACStatus(acIDBuff[cycle]);

				if (ELM_AC_FREE == acOccStatus)
				{
					/** UCT切换完成处理 */
					elm_HandleUCTHandoverFinished(acIDBuff[cycle],OwnsideELMid,OutsideELMid);
				}
				else
				{
					/** 分界点处克隆处理 */
					funRtn = elm_HandleCloneOfHandover(acIDBuff[cycle],searchDir,OwnsideELMid,OutsideELMid, cDirChangePointFlag);
					ASSERT_BREAK(CI_ERROR == funRtn,errorCode,0x10000000u);
				}
			}
			else
			{
				/** 相邻OC UCT跟踪失败，本OC暂时先处理成包络重置，后续再优化*/
			}
		}
	}

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:UCT Envelope Clone By HandOver error.\n",errorCode));
	return ret;
}

/**
 * @brief 获取与恢复通信的UCT位置相匹配的UCT包络信息
 * @param[in] UINT16 trainid 列车ID
 * @param[in] UINT8 relEnvelopeCnt 列车关联的UCT包络数量 
 * @param[in] UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] 列车关联的UCT包络ID
 * @param[out] 无
 * @return NULL 查询失败
           非NULL 查询成功，返回匹配的UCT包络信息
 * @note 无
 */
static const EnvelopeStruct* elm_GetUCTRealEnvelope(UINT16 trainid,UINT8 relEnvelopeCnt,IN UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX])
{
	const EnvelopeStruct* ret = NULL;
	const EnvelopeStruct* pTemp = NULL;
	UINT8 cycle = 0u;
	UINT16 trainHeadAc = 0u;
	UINT16 trainTailAc = 0u;
	UINT8 headRtn = CI_ERROR;
	UINT8 tailRtn = CI_ERROR;
	UINT32 errorCode = 0u;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == relEnvelopeID,ret,0x80000000u);

	/** 获取列车最大安全前所属计轴区段 */
	trainHeadAc = elm_PrepareACOfMaxSafeHeadLoc(trainid);
	/** 获取列车最小安全后所属计轴区段 */
	trainTailAc = elm_PrepareACOfMinSafeTailLoc(trainid);

	if ((0u == trainHeadAc) || (0u == trainTailAc))
	{
		/** 查询计轴区段失败 */
		errorCode += 0x40000000u;
	}
	else
	{
		for (cycle = 0u; cycle < relEnvelopeCnt; cycle++)
		{
			/** 获取包络的地址*/
			pTemp = elm_GetEnvelopeInfoPtr(relEnvelopeID[cycle]);
			ASSERT_BREAK(NULL == pTemp,errorCode,0x20000000u);

			/** 判断最小安全前是否在包络内 */
			headRtn = elm_PrepareInUINT16Array(trainHeadAc,pTemp->ACID,pTemp->ACCnt);
			tailRtn = elm_PrepareInUINT16Array(trainTailAc,pTemp->ACID,pTemp->ACCnt);

			if ((CI_SUCCESS == headRtn) || (CI_SUCCESS == tailRtn ))
			{
				/** CT只能在一个UCT包络内进行恢复 */
				ASSERT_BREAK(NULL != ret,errorCode,0x10000000u);

				/** 找了CT关联的UCT，设置返回值 */
				ret = pTemp;
			}
			else
			{
				/** 继续遍历*/
			}
		}

		if (cycle == relEnvelopeCnt)
		{
			/** 说明处理正确*/
		}
		else
		{
			ret = NULL;
		}		
	}

	/** 函数返回 */
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:Get tain%d real ELM error!",errorCode,trainid));
	return ret;
}


/**
 * @brief 基于恢复通信车的位置，拆分出通信车包络
 * @param[in] UINT16 trainId
 * @param[out] EnvelopeStruct *pMid 拆分的通信车包络
 * @param[out] UINT8 *cutFlag 包络截取标志
 * @return 无
 * @note 
 */
static UINT8 elm_CreateRevoverEnvelope(UINT16 trainId,OUT EnvelopeStruct *pMid,OUT UINT8 *cutFlag)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;
	ELM_TrainSafeLocStruct tmpSafeLoc = {0u};    /* 安全位置临时存储 */

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == pMid,ret,0x80000000u);
	ASSERT_RET_VALUE(NULL == cutFlag,ret,0x40000000u);

	/** 获取列车的安全位置*/
	funRtn = elm_PrepareTrainSafeLoc(trainId,&tmpSafeLoc);
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);
	ELM_LOG(ELM_LOG_FATAL,"info:Recover Train%d,safeT:%d-%d-%02x,safeH:%d-%d-%02x.\n",trainId,tmpSafeLoc.startPos.Lnk,tmpSafeLoc.startPos.Off,tmpSafeLoc.startPos.Dir, \
		tmpSafeLoc.endPos.Lnk,tmpSafeLoc.endPos.Off,tmpSafeLoc.endPos.Dir);

	/** 对包络进行截取 */
	funRtn = elm_PrepareCutZoneInSelf(&(tmpSafeLoc.startPos),&(tmpSafeLoc.endPos),cutFlag);
	ASSER_ERROR((ELM_BELONG_OTHER != funRtn) && (ELM_BELONG_OWNER != funRtn) ,errorCode,0x10000000u);
	ELM_LOG(ELM_LOG_FATAL,"info:CUT Recover Train%d,safeT:%d-%d-%02x,safeH:%d-%d-%02x.\n",trainId,tmpSafeLoc.startPos.Lnk,tmpSafeLoc.startPos.Off,tmpSafeLoc.startPos.Dir, \
		tmpSafeLoc.endPos.Lnk,tmpSafeLoc.endPos.Off,tmpSafeLoc.endPos.Dir);

	/** 先清空CT包络 */
	funRtn = CommonMemSet(pMid, (UINT32)sizeof(EnvelopeStruct), 0u , (UINT32)sizeof(EnvelopeStruct));
	ASSER_ERROR(0u == funRtn ,errorCode,0x08000000u);

	if (0u == errorCode)
	{
		funRtn = elm_CreateEnveLope(TYPE_CT_ENVELOPE,trainId,tmpSafeLoc.startPos,tmpSafeLoc.endPos,LINE_MAX_TRAIN,LINE_MAX_TRAIN,pMid);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x04000000u);

		/** 设置包络被创建 */
		pMid->exitFlag = ENVELOPE_EXIT;
	}
	else
	{
		/** 处理失败 */
	}

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	return ret;
}

/**
 * @brief 基于恢复通信车的包络拆分前面的UCT包络
 * @param[in] const EnvelopeStruct *pBase 基准包络
 * @param[out] EnvelopeStruct *pMid 恢复通信的包络
 * @param[out] EnvelopeStruct *pPre 前方UCT包络
 * @param[out] EnvelopeStruct *pBack 后方UCT包络
 * @return CI_ERROR 拆分失败
           CI_SUCCESS 拆分成功
 * @note 
 */
static UINT8 elm_SplitByUCTRevover(IN const EnvelopeStruct *pBase,OUT EnvelopeStruct *pMid,OUT EnvelopeStruct *pPre,OUT EnvelopeStruct *pBack)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = 0u;
	UINT8 cycle = 0u;
	UINT8 dirCheck = 0u;
	UINT8 splitFlag = 0u;
	EnvelopeStruct pTempOne = {0u};     /** 拆分后方UCT包络 */
	EnvelopeStruct pTempTwo = {0u};     /** 拆分前方UCT包络 */
	UINT8 cDirChangeNum = 0U;  /*方向变化点数量*/
	UINT8 cTempElmDir = 0U;  /*考虑方向变化点的包络方向*/

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == pBase,ret,0x80000000u);
	ASSERT_RET_VALUE((NULL == pMid) || (ENVELOPE_EXIT != pMid->exitFlag),ret,0x40000000u);
	ASSERT_RET_VALUE(NULL == pPre,ret,0x20000000u);
	ASSERT_RET_VALUE(NULL == pBack,ret,0x10000000u);

	/** 比较两个包络的方向 */
	dirCheck = elm_DirIsSameELMWithELM(pMid,pBase);
	ASSER_ERROR(0u == dirCheck,errorCode,0x08000000u);

	/** 将原始包络基于CT包络拆分 */
	if (0u == errorCode)
	{
		/** 进行列车序列的拆分 */
		for (cycle = 0u;cycle < pBase->trianCnt;cycle++)
		{
			if (pBase->trainID[cycle] == pMid->trainID[0u])
			{
				splitFlag = 1u;
			}
			else
			{
				if (0u == splitFlag)
				{
					pTempOne.trainID[pTempOne.trianCnt++] = pBase->trainID[cycle];
				}
				else
				{
					pTempTwo.trainID[pTempTwo.trianCnt++] = pBase->trainID[cycle];
				}
			}			
		}

		/** 处理pTempOne的起点和终点 */
		if (0u < pTempOne.trianCnt)
		{
			if (ELM_DIR_SAME == dirCheck)
			{
				(void)elm_PrepareMinSafeTailLoc(pMid->trainID[0u],&pTempOne.endPos);
			}
			else
			{
				(void)elm_PrepareMaxSafeHeadLoc(pMid->trainID[0u],&pTempOne.endPos);
			}

			cDirChangeNum = elm_PrepareDirChangNum(&pTempOne.endPos, &pBase->endPos);
			cTempElmDir = elm_PrepareDirByChangeNum(pBase->endPos.Dir, cDirChangeNum);  /*确定拆分后的后方包络的终点方向*/
			ASSER_ERROR(0U == cTempElmDir, errorCode, 0x00400000u);

			pTempOne.endPos.Dir = cTempElmDir;
			pTempOne.startPos = pBase->startPos;
			pTempOne.headTrainID = 0u;
			pTempOne.tailTrainID = pBase->tailTrainID;

			/** 查询包络范围的计轴区段 */
			pTempOne.envelopeType = TYPE_UCT_ENVELOPE;
			pTempOne.ACCnt = elm_PrepareACBtwPoints(pTempOne.startPos,pTempOne.endPos,&(pTempOne.ACID[0]));
			ASSER_ERROR((0u == pTempOne.ACCnt) || (SECTION_IN_ENVELOPE_SUM_MAX == pTempOne.ACCnt),errorCode,0x04000000u);
		}
		else
		{
			/** 无需拆分 */
		}

		/** 处理pTempTwo的起点和终点 */
		if (0u < pTempTwo.trianCnt)
		{
			if (ELM_DIR_SAME == dirCheck)
			{
				(void)elm_PrepareMaxSafeHeadLoc(pMid->trainID[0u],&pTempTwo.startPos);
			}
			else
			{
				(void)elm_PrepareMinSafeTailLoc(pMid->trainID[0u],&pTempTwo.startPos);
			}

			cDirChangeNum = elm_PrepareDirChangNum(&pBase->startPos, &pTempTwo.startPos);
			cTempElmDir = elm_PrepareDirByChangeNum(pBase->startPos.Dir, cDirChangeNum);  /*确定拆分后的前方包络的起点方向*/
			ASSER_ERROR(0U == cTempElmDir, errorCode, 0x00200000u);

			pTempTwo.startPos.Dir = cTempElmDir;
			pTempTwo.endPos = pBase->endPos;
			pTempTwo.headTrainID = pBase->headTrainID;
			pTempTwo.tailTrainID = 0u;

			/** 查询包络范围的计轴区段 */
			pTempTwo.envelopeType = TYPE_UCT_ENVELOPE;
			pTempTwo.ACCnt = elm_PrepareACBtwPoints(pTempTwo.startPos,pTempTwo.endPos,&(pTempTwo.ACID[0]));
			ASSER_ERROR((0u == pTempTwo.ACCnt) || (SECTION_IN_ENVELOPE_SUM_MAX == pTempTwo.ACCnt),errorCode,0x02000000u);

		}
		else
		{
			/** 无需拆分 */
		}
	}
	else
	{
		/** 包络方向无法比较 */
	}

	/** 设置拆分后的前向UCT包络、后向UCT包络及CT的前/后向列车ID*/
	if (0u == errorCode)
	{
		if (pTempOne.trianCnt > 0U)
		{
			funRtn = CommonMemCpy(pBack, (UINT32)sizeof(EnvelopeStruct) ,  &pTempOne , (UINT32)sizeof(EnvelopeStruct));
			ASSER_ERROR(0u == funRtn,errorCode,0x01000000u);
			pBack->exitFlag = ENVELOPE_EXIT;

			if (ELM_DIR_SAME == dirCheck)
			{   
				pMid->tailTrainID = pBack->trainID[pBack->trianCnt - 1u];
			}
			else
			{
				pMid->headTrainID = pBack->trainID[pBack->trianCnt - 1u];
			}
		}
		else
		{
			if (ELM_DIR_SAME == dirCheck)
			{   
				pMid->tailTrainID = pBase->tailTrainID;
			}
			else
			{
				pMid->headTrainID = pBase->tailTrainID;
			}
		}

		if (pTempTwo.trianCnt > 0U)
		{
			funRtn = CommonMemCpy(pPre, (UINT32)sizeof(EnvelopeStruct),&pTempTwo, (UINT32)sizeof(EnvelopeStruct));
			ASSER_ERROR(0u == funRtn,errorCode,0x00800000u);
			pPre->exitFlag = ENVELOPE_EXIT;

			if (ELM_DIR_SAME == dirCheck)
			{   
				pMid->headTrainID = pBase->trainID[0u];
			}
			else
			{
				pMid->tailTrainID = pBack->trainID[0u];
			}
		}	
		else
		{
			if (ELM_DIR_SAME == dirCheck)
			{   
				pMid->headTrainID = pBase->headTrainID;
			}
			else
			{
				pMid->tailTrainID = pBase->headTrainID;
			}
		}
	}
	else
	{
		/** 拆分失败*/
	}

	/** 设置函数返回值 */
	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 Split to UCT error!",errorCode,pBase->id));

	return ret;
}


/**
 * @brief 删除拆分前的UCT包络
 * @param[in] IN const EnvelopeStruct *pBase
 * @param[out] 无
 * @return 无
 * @note 处理失败，包络重置
 */
static void elm_ClearFormerUCTEnvelope(IN const EnvelopeStruct *pBase)
{
	UINT8 cycleAC = 0u;
	UINT8 cycleTrain = 0u;
	UINT32 errorCode = 0u;
	UINT8 funRet = CI_ERROR;
	UINT16 tmpACindex = 0u;

	if (NULL != pBase)
	{
		/** 车身范围内的计轴，清除映射关系，并添加UKT包络（占用且无其他包络则添加）*/
		for (cycleAC = 0u; cycleAC < pBase->ACCnt;cycleAC++)
		{
			/** 获取计轴索引 */
			tmpACindex = elm_PrepareACIndex(pBase->ACID[cycleAC]);

			/** 清除映射关系 */
			funRet = elm_SetACRelEnvelopeMap(OP_DEL,tmpACindex,pBase->id);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x40000000u);

			/** 清除计轴上包络的进入信息 */
			for (cycleTrain = 0u; cycleTrain < pBase->trianCnt;cycleTrain++)
			{
				aam_ClearACEnvelopeEnterInfo(pBase->ACID[cycleAC],pBase->trainID[cycleTrain]);
			}
		}

		/** 清除列车映射关系*/
		for (cycleTrain = 0u; cycleTrain < pBase->trianCnt;cycleTrain++)
		{
			/** 清除列车关联的包络ID */
			funRet = elm_SetTrainRelEnvelopeMap(OP_DEL,pBase->trainID[cycleTrain], pBase->id);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x20000000u);
		}

		/** 清空包络空间 */
		funRet = elm_ClearEnvelope(pBase->id);
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x10000000u);
	}
	else
	{
		errorCode += 0x80000000u;
	}

	if (0u == errorCode)
	{
		/** 处理正确*/
	}
	else
	{
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:Clear Former UCT%d error!",errorCode);
	}
}

/**
 * @brief 添加包络到包络存储区
 * @param[in] EnvelopeStruct *pTemp 包络信息
 * @param[in] UINT8 cutFlag  截取标志位 
 * @param[out] 无
 * @return 无
 * @note 处理失败，包络重置
 */
static void elm_AddSplitEnvelopToRAM(IN EnvelopeStruct *pTemp,UINT8 cutFlag)
{
	UINT32 errorCode = 0u;
	UINT8 funRet = CI_ERROR;
	UINT8 cycle = 0u;
	UINT16 buffIndex = ENVELOPE_UNVAILD_INDEX;    /** 包络缓存地址 */
	UINT16 tmpACIndex = 0u;

	/** 入口参数校验 */
	ASSER_ERROR((NULL == pTemp) || (ENVELOPE_EXIT != pTemp->exitFlag) || ((TYPE_UCT_ENVELOPE != pTemp->envelopeType) && (TYPE_CT_ENVELOPE != pTemp->envelopeType)),errorCode,0x80000000u);
	ASSER_ERROR((ELM_HEAD_CUT != cutFlag) && (ELM_TAIL_CUT != cutFlag) && (ELM_NO_CUT != cutFlag),errorCode,0x40000000u);

	/** 获取可用的包络存储位置 */
	buffIndex = elm_GetEnvelopeValidIndex();
	ASSER_ERROR(ENVELOPE_UNVAILD_INDEX == buffIndex,errorCode,0x10000000u);

	/** 判断包络索引位置是否正确*/
	if (0u == errorCode)
	{
		/** 设置包络唯一标识*/
		pTemp->id = buffIndex;

		/** 添加到存储区*/
		funRet = elm_SetEnvelopeByIndex(pTemp,buffIndex);
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x08000000u);

		/** 从车尾开始遍历*/
		for (cycle = 0u; cycle < pTemp->ACCnt; cycle++)
		{
			/** 通过计轴ID获取计轴数组索引 */
			tmpACIndex = elm_PrepareACIndex(pTemp->ACID[cycle]);

			/** 创建计轴到包络的映射关系 */
			funRet = elm_SetACRelEnvelopeMap(OP_ADD,tmpACIndex,buffIndex);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x04000000u);
		}

		/** 处理包络进入计轴区段信息*/
		if (TYPE_UCT_ENVELOPE == pTemp->envelopeType)
		{
			funRet = elm_RefreshACseqInfoForUCT(pTemp);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x02000000u);
		}
		else
		{
			funRet = elm_RefreshACseqInfoForCT(pTemp,pTemp->ACID,pTemp->ACCnt,cutFlag);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x02000000u);
		}

		/** 创建列车到包络的索引 */
		for (cycle = 0;cycle < pTemp->trianCnt;cycle++)
		{
			funRet = elm_SetTrainRelEnvelopeMap(OP_ADD,pTemp->trainID[cycle],buffIndex);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x01000000u);
		}
	}
	else
	{
		/** 无可用的包络存储空间，不可能分支，设置包络处理模块异常  */
	}

	if (0u == errorCode)
	{
		/** 处理正确*/
	}
	else
	{
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Add Split Envelop To RAM error.",errorCode);
	}
}


/**
 * @brief 当通信车恢复时，UCT包络拆分
 * @param[in] UINT16 trainId 列车ID
 * @param[in] const EnvelopeStruct* pBase 基准包络
 * @param[out] 无
 * @return CI_ERROR 拆分失败
           CI_SUCCESS 拆分成功
 * @note 
 *       当包络头/尾车恢复，则会裂变成一个UCT包络和一个CT包络
 *       当包络中间有车恢复，则会裂变成两个UCT包络和一个CT包络
 */
static UINT8 elm_UCTEnvelopeSplit(UINT16 trainId, IN const EnvelopeStruct* pBase)
{
	UINT8 ret = CI_ERROR; 
	UINT8 funRtn = 0;
	UINT32 errorCode = 0u;
	UINT8 cutFlag = ELM_NO_CUT;
	UINT8 cycle = 0u;
	UINT8 acCnt = 0u;
	UINT16 acIdBuff[SECTION_IN_ENVELOPE_SUM_MAX] = {0u};
	EnvelopeStruct preUCTELM = {0u};     /** 拆分前方UCT包络 */
	EnvelopeStruct backUCTELM = {0u};     /** 拆分后方UCT包络 */
	EnvelopeStruct midCTELM = {0u};     /** 通信恢复的CT包络 */

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == pBase,ret,0x80000000u);

	/** 基于恢复通信列车拆分出CT包络 */
	funRtn = elm_CreateRevoverEnvelope(trainId,&midCTELM,&cutFlag);
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x40000000u);

	/** 基于拆分的CT包络进行前方UCT的拆分 */
	funRtn = elm_SplitByUCTRevover(pBase,&midCTELM,&preUCTELM,&backUCTELM);
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);

	if (0u == errorCode)
	{	
		/** 先备份拆分前的UCT包络计轴序列 */
		for (cycle = 0u; cycle < pBase->ACCnt;cycle++)
		{
			acIdBuff[acCnt++] = pBase->ACID[cycle];
		}

		elm_ClearFormerUCTEnvelope(pBase);
		elm_AddSplitEnvelopToRAM(&midCTELM,cutFlag);

		if (ENVELOPE_EXIT == preUCTELM.exitFlag)
		{
			elm_AddSplitEnvelopToRAM(&preUCTELM,cutFlag);
		}
		else
		{
			/** 不处理*/
		}

		if (ENVELOPE_EXIT == backUCTELM.exitFlag)
		{
			elm_AddSplitEnvelopToRAM(&backUCTELM,cutFlag);
		}
		else
		{
			/** 不处理 */
		}

		/** 将出清的计轴无好车通过、且状态为占用的计轴添加UKT包络 */
		elm_ProcessByELMLeave(UCT_LEAVE_SPLIT, acCnt,acIdBuff);

		ELM_LOG(ELM_LOG_FATAL,"info:UCT%d split to CT:%d-%02x,pre_UCT:%d-%02x,back_UCT:%d-%02x.\n",pBase->id,midCTELM.id,midCTELM.exitFlag,\
			preUCTELM.id,preUCTELM.exitFlag,backUCTELM.id,backUCTELM.exitFlag);
	}
	else
	{
		/** 克隆失败 */
	}

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	return ret;
}

/**
 * @brief 刷新UCT包络计轴映射表
 * @param[in] const EnvelopeStruct *ptemp，包络
 * @param[out] 无
 * @return 无
 * @note 无
 */
static void elm_RefreshUCTofACMapInfo(IN const EnvelopeStruct *ptemp)
{
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT16 tmpACIndex = 0u;
	UINT8 cycle = 0u;
	UINT8 tmpCnt = 0u;
	UINT8 acCnt = 0u;
	UINT16 acIdBuff[SECTION_IN_ENVELOPE_SUM_MAX] = {0u};
	UINT8 tmpSearchACCnt;          /*缓存计轴数量*/
	UINT16 tmpSearchACID[SECTION_IN_ENVELOPE_SUM_MAX] = {0u};      /*缓存计轴ID*/

	/** 入口参数校验 */
	ASSERT_RET_NO_VALUE((NULL == ptemp) || (0u == ptemp->ACCnt),0x80000000u);

	/*- 获取安全包络范围的计轴区段*/
	tmpSearchACCnt = elm_PrepareACBtwPoints(ptemp->startPos,ptemp->endPos, tmpSearchACID);
	ASSER_ERROR((0u == tmpSearchACCnt) || (SECTION_IN_ENVELOPE_SUM_MAX == tmpSearchACCnt),errorCode,0x40000000u);   /*设置错误码*/

	if (0u == errorCode)
	{
		/** 先备份拆分前的UCT包络计轴序列 */
		for (cycle = 0u; cycle < ptemp->ACCnt;cycle++)
		{
			acIdBuff[acCnt++] = ptemp->ACID[cycle];
		}

		/** 先删除计轴映射信息 */
		tmpCnt = ptemp->ACCnt;
		for (cycle = tmpCnt; 0u != cycle; cycle--)
		{
			/** 删除计轴到包络的映射 */
			tmpACIndex = elm_PrepareACIndex(ptemp->ACID[cycle - 1u]);
			funRtn = elm_SetACRelEnvelopeMap(OP_DEL,tmpACIndex,ptemp->id);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);

			/** 删除包络内的计轴区段 */
			funRtn = elm_PopEnvelopACSeq(ELM_HEAD,ptemp->id);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x10000000u);
		}

		/** 在添加映射关系 */
		tmpCnt = tmpSearchACCnt;
		for (cycle = 0u; cycle < tmpCnt; cycle++)
		{
			/** 包络前延*/
			funRtn = elm_PushEnvelopeACSeq(ELM_HEAD,ptemp->id,tmpSearchACID[cycle]);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x08000000u);

			/** 添加包络到计轴的映射 */
			tmpACIndex = elm_PrepareACIndex(tmpSearchACID[cycle]);
			funRtn = elm_SetACRelEnvelopeMap(OP_ADD,tmpACIndex,ptemp->id);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x04000000u);
		}
	}
	else
	{
		/** 处理错误 */
	}

	/** 此函数出错，是不可饶恕的 */
	if (0u != errorCode)
	{
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Refresh UCT%d of ACMap Info error.",errorCode,ptemp->id);
	}
	else
	{
		/** 处理正确，处理出清计轴区段 */
		elm_ProcessByELMLeave(UCT_LEAVE_REFRESH, acCnt,acIdBuff);
	}
}

/**
 * @brief UCT包络头部有接近包络的处理
 * @param[in] UINT8 endlineFlag 尽头线标识
 *            const EnvelopeStruct *ptemp, 待处理UCT包络
 *            UINT16 headACId， 前方计轴
 *            UINT16 preEnvelopeId， 前方包络
 *            UINT8 cDirChangedFlag 方向变化点标志
 * @param[out] 无
 * @return CI_ERROR 执行错误
           0x55u,执行正确，包络无法再继续往后延申
		   0xaau,执行正确，包络可继续往后延申
 * @note 
 */
static UINT8 elm_UCTEnvelopeHeadHandle(UINT8 endlineFlag, IN const EnvelopeStruct *ptemp, UINT16 headACId, UINT16 preEnvelopeId, UINT8 cDirChangedFlag)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 dirCheck = 0u;
	UINT16 tmpACIndex = 0u;
	LOD_STRU trainLoc = { 0u };
	UINT8 selfFlag = 0u;
	UINT8 ocid = 0u;
	UINT16 LocACId = 0u;
	UINT8 OccStatus = ELM_AC_OCC;
	UINT8 pointBelong = ELM_BELONG_OWNER;
	const EnvelopeStruct *pPretemp = NULL;
	ELM_TrainSafeLocStruct safeLoc = { 0U };
	UINT16 wLinkId = 0U;
	UINT16 * pLinkBuf = NULL;
	UINT8 chBgUtSwitch = FUNC_SWITCH_OFF;
	UINT16 wNextLinkId = 0U;
	UINT8 chBgAtt = 0U;
	UINT16 wAgLink = 0U;
	UINT16 wSwitchId = 0U;
	UINT8 cDirectionPointFlag = 0U;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == ptemp, ret, 0x80000000u);
	ASSERT_RET_VALUE(((DIRECTIONPOINT_FLAG_VALID != cDirChangedFlag) && (DIRECTIONPOINT_FLAG_INVALID != cDirChangedFlag)), ret, 0x80000000u);
	pPretemp = elm_GetEnvelopeInfoPtr(preEnvelopeId);

	if (CI_SUCCESS == endlineFlag)
	{
		/** 前方为线路尽头，不处理*/
	}
	else
	{
		/** 判断前方计轴是否属于本OC*/
		pointBelong = elm_PrepareACIsSelf(headACId, &ocid);

		/** 获取计轴状态 */
		OccStatus = elm_PrepareACStatus(headACId);
	}

	/** 前方为非本OC计轴 */
	if (ELM_BELONG_OTHER == pointBelong)
	{
		/** 前方为非本OC计轴*/
		if (NULL == pPretemp)
		{
			/** 则更新车头位置 */
			funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD, ptemp->ACID[ptemp->ACCnt - 1u], ptemp);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);
		}
		else if (TYPE_UKT_ENVELOPE == pPretemp->envelopeType)
		{
			/** 则更新车头位置 */
			funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD, ptemp->ACID[ptemp->ACCnt - 1u], ptemp);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

			funRtn = elm_SetEnvelopeHeadTrainID(ptemp->id, LINE_MAX_TRAIN);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00010000u);
		}
		else if (TYPE_CT_ENVELOPE == pPretemp->envelopeType)
		{
			/** 获取两个包络的方向是否一致 */
			dirCheck = elm_DirIsSameELMWithELM(pPretemp, ptemp);

			/** 获取包络是否属于本OC */
			selfFlag = elm_PrepareEnvelopeIsSelf(pPretemp);

			/** 前端监控 */
			if (ELM_DIR_SAME == dirCheck)
			{
				/** 位置处理  */
				if (ELM_BELONG_OTHER == selfFlag)
				{
					/** 则更新车头位置 */
					funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD, ptemp->ACID[ptemp->ACCnt - 1u], ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);
				}
				else
				{
					/*获取列车安全位置*/
					funRtn = elm_PrepareTrainSafeLoc(pPretemp->trainID[0U], &safeLoc);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00200000u);
					trainLoc = safeLoc.startPos;

					/*UCT追CT，从小后改为追安全车尾*/
					/** 属于本OC，则更新包络位置*/
					funRtn = elm_SetEnvelopeLoc(ptemp->id, ptemp->startPos, trainLoc);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00020000u);
				}

				/** 前端监控 */
				if (0u != pPretemp->tailTrainID)
				{
					if (ptemp->trainID[ptemp->trianCnt - 1u] == pPretemp->trainID[0u])
					{
						/** 说明UCT头车和前方通信车是同一个车，此场景只能在分界点处产生,UCT染前方通信车的前方列车ID */
						funRtn = elm_SetEnvelopeHeadTrainID(ptemp->id, pPretemp->headTrainID);
					}
					else if (ptemp->trainID[ptemp->trianCnt - 1u] == pPretemp->tailTrainID)
					{
						/** 无需处理*/
					}
					else
					{
						/** UCT染上前端可疑 */
						funRtn = elm_SetEnvelopeHeadTrainID(ptemp->id, LINE_MAX_TRAIN);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
					}
				}
				else
				{
					/** 无需增加可疑 */
					funRtn = elm_SetEnvelopeTailTrainID(pPretemp->id, ptemp->trainID[ptemp->trianCnt - 1u]);	/*UCT延申，方向一致，为前车设置后可疑*/
				}
			}
			else
			{
				/** 包络位置处理 */
				if (ELM_BELONG_OTHER == selfFlag)
				{
					/** 则更新车头位置 */
					funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD, ptemp->ACID[ptemp->ACCnt - 1u], ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);
				}
				else
				{
					/*获取列车安全位置*/
					funRtn = elm_PrepareTrainSafeLoc(pPretemp->trainID[0U], &safeLoc);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00080000u);
					trainLoc = safeLoc.endPos;

					/*UCT追CT，从大前改为追安全车尾*/
					/** 属于本OC，则更新包络位置*/
					trainLoc.Dir = ~trainLoc.Dir;
					funRtn = elm_SetEnvelopeLoc(ptemp->id, ptemp->startPos, trainLoc);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00020000u);
				}

				/** 前后监控 */
				if (0u != pPretemp->headTrainID)
				{
					if (ptemp->trainID[ptemp->trianCnt - 1u] == pPretemp->trainID[0u])
					{
						/** 说明UCT头车和前方通信车是同一个车，此场景只能在分界点处产生 */
						funRtn = elm_SetEnvelopeHeadTrainID(ptemp->id, pPretemp->tailTrainID);
					}
					else if (ptemp->trainID[ptemp->trianCnt - 1u] == pPretemp->headTrainID)
					{
						/** 无需处理*/
					}
					else
					{
						/** UCT染前端可疑 */
						funRtn = elm_SetEnvelopeHeadTrainID(ptemp->id, LINE_MAX_TRAIN);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00004000u);
					}
				}
				else
				{
					/** 无需增加可疑 */
					funRtn = elm_SetEnvelopeHeadTrainID(pPretemp->id, ptemp->trainID[ptemp->trianCnt - 1u]);	/*UCT延申，方向相反，为前车设置前可疑*/
				}
			}
		}
		else
		{
			/** 判断两包络是否为同一UCT，如果是则不添加前端可疑 */
			funRtn = elm_CheckEnvelopeMergeValid(ELM_HEAD, ptemp, pPretemp);
			if (0x55u == funRtn)
			{
				/** 不添加前端可疑 */
				funRtn = elm_SetEnvelopeHeadTrainID(ptemp->id, pPretemp->headTrainID);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00002000u);
				/** 则更新车头位置 */
				funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD, ptemp->ACID[ptemp->ACCnt - 1u], ptemp);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00000800u);
			}
			else
			{
				funRtn = elm_DeleteCTOrUCTEnvelope(ptemp->id);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00000400u);
			}
		}
		ret = 0x55u;
	}
	else
	{
		if ((NULL == pPretemp) || (TYPE_UKT_ENVELOPE == pPretemp->envelopeType))
		{
			if (NULL == pPretemp)
			{
				if ((ELM_AC_FREE == OccStatus) || (CI_SUCCESS == endlineFlag))
				{
					/** 则更新车头位置 */
					funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD, ptemp->ACID[ptemp->ACCnt - 1u], ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

					/** 说明仅更新包络尾包络，不需要继续处理 */
					ret = 0x55u;
				}
				else
				{
					if (ptemp->ACCnt < (SECTION_IN_ENVELOPE_SUM_MAX - 1u))
					{
						/** 包络前延*/
						funRtn = elm_PushEnvelopeACSeq(ELM_HEAD, ptemp->id, headACId);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x40000000u);

						/** 添加包络到计轴的映射 */
						tmpACIndex = elm_PrepareACIndex(headACId);
						funRtn = elm_SetACRelEnvelopeMap(OP_ADD, tmpACIndex, ptemp->id);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);

						/*判断包络头方向是否需要变化*/
						if (DIRECTIONPOINT_FLAG_VALID == cDirChangedFlag)
						{
							/*存在方向变化点，设置包络终点方向反向*/
							funRtn = elm_SetEnvelopeEndDir(ptemp->id, ~ptemp->endPos.Dir);
							ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
						}
						else
						{
							/*不处理*/
						}

						/** 则更新车头位置 */
						funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD, ptemp->ACID[ptemp->ACCnt - 1u], ptemp);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

						/** 需要继续判断前方计轴 */
						ret = 0xaau;
					}
					else
					{
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
					}
				}
			}
			else
			{
				if (ptemp->ACCnt < (SECTION_IN_ENVELOPE_SUM_MAX - 1u))
				{
					/** 包络前延*/
					funRtn = elm_PushEnvelopeACSeq(ELM_HEAD, ptemp->id, headACId);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x40000000u);

					/** 添加包络到计轴的映射 */
					tmpACIndex = elm_PrepareACIndex(headACId);
					funRtn = elm_SetACRelEnvelopeMap(OP_ADD, tmpACIndex, ptemp->id);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);

					/*判断包络头方向是否需要变化*/
					if (DIRECTIONPOINT_FLAG_VALID == cDirChangedFlag)
					{
						/*存在方向变化点，设置包络终点方向反向*/
						funRtn = elm_SetEnvelopeEndDir(ptemp->id, ~ptemp->endPos.Dir);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
					}
					else
					{
						/*不处理*/
					}

					/** 则更新车头位置 */
					funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD, ptemp->ACID[ptemp->ACCnt - 1u], ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

					/** UCT染上前端可疑 */
					funRtn = elm_SetEnvelopeHeadTrainID(ptemp->id, LINE_MAX_TRAIN);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x08000000u);

					/** UKT包络被CT包络吃掉 */
					funRtn = elm_DeleteUKTEnvelope(pPretemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x04000000u);

					/** 需要继续判断前方计轴 */
					ret = 0xaau;
				}
				else
				{
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
				}
			}

			/** 设置计轴上包络进出过程 */
			funRtn = elm_RefreshACseqInfoForUCT(ptemp);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x02000000u);

		}
		else if (TYPE_CT_ENVELOPE == pPretemp->envelopeType)
		{
			pLinkBuf = GetAxisLinkIdBuf(ptemp->ACID[0]);
			wLinkId = pLinkBuf[0];
			chBgAtt = GetLinkRelPhySecAGorBGAttr(wLinkId);
			wAgLink = GetBGLinkRelAGLinkId(wLinkId);
			chBgUtSwitch = GetNoCGFollowUtSwitch();
			wNextLinkId = FindAdjacentLinkIDSafe(wLinkId, ptemp->endPos.Dir, &wSwitchId, &cDirectionPointFlag);
			if ((FUNC_SWITCH_ON == chBgUtSwitch) && (LINK_REL_PHYSEC_BG == chBgAtt) && (wNextLinkId == wAgLink) 
				&& ((pPretemp->startPos.Lnk == wAgLink) || (pPretemp->endPos.Lnk == wAgLink))
				&& (1U == ptemp->ACCnt))
			{/* B轨UT可追踪开关打开，UCT仅处于B轨，相邻区段是A轨，CT包络在A轨，此场景不延伸 */
				ret = 0x55u;
			}
			else
			{
				/** 获取两个包络的方向是否一致 */
				dirCheck = elm_DirIsSameELMWithELM(pPretemp, ptemp);

				if (0u == dirCheck)
				{
					/** 两包络方向比较失败 */
					errorCode += 0x01000000u;
				}
				else
				{
					/** 则更新位置 */
					if (ELM_DIR_SAME == dirCheck)
					{
						/** 缓存包络起点计轴 */
						LocACId = pPretemp->ACID[0u];

						/*获取列车安全位置*/
						funRtn = elm_PrepareTrainSafeLoc(pPretemp->trainID[0U], &safeLoc);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00200000u);
						/*UCT追CT，从小后改为追安全车尾*/
						trainLoc = safeLoc.startPos;

						if (0u != pPretemp->tailTrainID)
						{
							if (ptemp->trainID[ptemp->trianCnt - 1u] == pPretemp->tailTrainID)
							{
								/** 无需处理*/
							}
							else
							{
								/** UCT染上前端可疑 */
								funRtn = elm_SetEnvelopeHeadTrainID(ptemp->id, LINE_MAX_TRAIN);
								ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00100000u);
							}
						}
						else
						{
							/** 无需增加可疑 */
							funRtn = elm_SetEnvelopeTailTrainID(pPretemp->id, ptemp->trainID[ptemp->trianCnt - 1u]);	/*UCT延申，方向一致，为前车设置后可疑*/
						}
					}
					else
					{
						/** 缓存包络终点计轴 */
						LocACId = pPretemp->ACID[pPretemp->ACCnt - 1u];

						/*获取列车安全位置*/
						funRtn = elm_PrepareTrainSafeLoc(pPretemp->trainID[0U], &safeLoc);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00200000u);
						/*UCT追CT，从大前改为追安全车头*/
						trainLoc = safeLoc.endPos;
						trainLoc.Dir = ~trainLoc.Dir;
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00080000u);

						if (0u != pPretemp->headTrainID)
						{
							if (ptemp->trainID[ptemp->trianCnt - 1u] == pPretemp->headTrainID)
							{
								/** 无需处理*/
							}
							else
							{
								/** UCT染前端可疑 */
								funRtn = elm_SetEnvelopeHeadTrainID(ptemp->id, LINE_MAX_TRAIN);
								ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00040000u);
							}
						}
						else
						{
							/** 无需增加可疑 */
							funRtn = elm_SetEnvelopeHeadTrainID(pPretemp->id, ptemp->trainID[ptemp->trianCnt - 1u]);	/*UCT延申，方向相反，为前车设置前可疑*/
						}
					}

					/** 补丁：避免UCT跳过空闲计轴，染到前方CT包络车载位置所在计轴 */
					if ((LocACId == headACId) && (ELM_AC_FREE == OccStatus))
					{
						/** 则更新车头位置 */
						funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD, ptemp->ACID[ptemp->ACCnt - 1u], ptemp);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00020000u);
					}
					else
					{
						/** 属于本OC，则更新包络位置*/
						funRtn = elm_SetEnvelopeLoc(ptemp->id, ptemp->startPos, trainLoc);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00020000u);
					}

					/** 更新计轴映射关系 */
					elm_RefreshUCTofACMapInfo(ptemp);

					/** 设置计轴上包络进出过程 */
					funRtn = elm_RefreshACseqInfoForUCT(ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00010000u);

					ret = 0x55u;
				}
			}
		}
		else
		{
			/** UCT包络合并 */
			funRtn = elm_UCTEnvelopeMerge(ELM_HEAD, ptemp, pPretemp);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00010000u);
			ret = 0x55u;
		}
	}

	/** 设置函数返回值 */
	ASSER_DEBUG(0u != errorCode, ELM_LOG_LOC(ELM_LOG_ERROR, "errorCode:0x%08x info:UCT%d head ELM track error!", errorCode, ptemp->id));
	ASSERT_SETRET(0u == errorCode, ret, ret, CI_ERROR);

	return ret;
}

/**
 * @brief UCT包络头部移动
 * @param[in] const EnvelopeStruct *ptemp UCT包络
 * @return CI_ERROR 执行错误
           0x55u,执行正确，包络无法再继续往后延申
           0xaau,执行正确，包络可继续往后延申
 * @note UCT包络创建后，UCT包络头进行延申：
 *      1、如果UCT包络相邻计轴区段占用且不存在UKT包络，则UCT包络进行延申，包络头设置为该计轴远端端点处。
        2、如果UCT包络尾处存在计轴区段空闲，则UCT包络进行回缩，包络头设置为该计轴远端端点处
        3、如果UCT包络相邻计轴区段占用且存在UKT包络，则UCT包络进行延申，包络头设置为该计轴远端端点处，并新增可疑标志
        4、如果UCT包络相邻计轴区段占用且存在CT包络，则UCT包络进行延申，包络头不越过CT包络最大安全后围成的范围内
 */
static UINT8 elm_UCTEnvelopeHeadMoving(const EnvelopeStruct *ptemp)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 endLineFlag = CI_ERROR;
	UINT8 funRtn = CI_ERROR;
	UINT8 cycle = 0u;
	UINT8 cycleAC = 0u;
	UINT8 OccStatus = ELM_AC_OCC;
	UINT8 tmpACCnt = 0u;
	UINT16 tmpACIndex = 0u;
	UINT16 preEnvelope = 0u;
	UINT16 backEnvelope = 0u;
	UINT8 acSameCnt = 0u;
	UINT16 acSameID[AC_MAXCNT_IN_SWITCH] = {0u};
	UINT8 envelopeCnt = 0u;     /* 包络数量 */
	UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] = {0u};  /*包络ID数组*/
	UINT16 mergeACIndex = 0u;
	UINT16 mergeACID[SECTION_IN_ENVELOPE_SUM_MAX + AC_MAXCNT_IN_SWITCH] = {0u};
	UINT16 mergeACCntMax = (SECTION_IN_ENVELOPE_SUM_MAX + AC_MAXCNT_IN_SWITCH);
	UINT8 includeCnt = 0u;
	UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] = {0u};  /** 重合的包络id */
	UINT8 cHeadDirChangeFlag = DIRECTIONPOINT_FLAG_INVALID;  /*包络头方向变化点标志*/
	const EnvelopeStruct* pPretemp = NULL;
	UINT16 wInputAcId = 0U;
	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == ptemp,ret,0x80000000u);

	/** 根据占用回缩车头，至少保留一个计轴，交给后续UCT全空闲处理 */
	tmpACCnt = ptemp->ACCnt;

	for (cycle = tmpACCnt; 1u != cycle; cycle--)
	{
		/** 获取计轴的占用状态 */
		OccStatus = elm_PrepareACStatus(ptemp->ACID[cycle - 1u]);

		if (ELM_AC_FREE == OccStatus)
		{
			/** 删除计轴到包络的映射 */
			tmpACIndex = elm_PrepareACIndex(ptemp->ACID[cycle - 1u]);
			funRtn = elm_SetACRelEnvelopeMap(OP_DEL,tmpACIndex,ptemp->id);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x40000000u);

			/** 设置车头出清*/
			funRtn = elm_UCTEnvelopeLeaveAC(ELM_HEAD,ptemp,ptemp->ACID[cycle - 1u]);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);

			acSameCnt = elm_PrepareAdjacentAC(ptemp->ACID[ptemp->ACCnt - 1u], ~ptemp->endPos.Dir, acSameID, &cHeadDirChangeFlag);
			/*包络头回撤时，及时更新包络终点方向*/
			if (DIRECTIONPOINT_FLAG_VALID == cHeadDirChangeFlag)
			{
				/*存在方向变化点，设置包络终点方向反向*/
				funRtn = elm_SetEnvelopeEndDir(ptemp->id, ~ptemp->endPos.Dir);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00100000u);
			}
			else
			{
				/*不存在方向变化点，不处理*/
			}

			/** 计轴空闲,回缩车头,对包络计轴进行了操作，所以需要放到最后*/
			funRtn = elm_PopEnvelopACSeq(ELM_HEAD,ptemp->id);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x10000000u);
		}
		else
		{
			break;
		}
	}

	if (tmpACCnt != cycle)
	{
		/** 说明UCT包络前方存在空闲计轴，则更新车头位置 */
		funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD,ptemp->ACID[ptemp->ACCnt - 1u],ptemp);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00400000u);
		ret = 0x55;
	}
	else
	{
		/** 查询包络终点前方计轴 */
		acSameCnt = elm_PrepareAdjacentAC(ptemp->ACID[ptemp->ACCnt - 1u], ptemp->endPos.Dir, acSameID, &cHeadDirChangeFlag);
		ASSER_ERROR(UINT8_MAX == acSameCnt,errorCode,0x04000000u);

		if (UINT8_MAX != acSameCnt)
		{
			/** 判断前方计轴是否空闲 */
			for (cycleAC = 0u; cycleAC < acSameCnt; cycleAC++)
			{
				/** 获取计轴状态 */
				OccStatus = elm_PrepareACStatus(acSameID[cycleAC]);

				/** 如果计轴状态占用，则跳出循环 */
				ASSERT_BREAK(ELM_AC_OCC == OccStatus,errorCode,0u);
			}

			/** 当前方计轴空闲的时候，需要调整包络头位置*/
			if(1u >= acSameCnt)
			{
				/** 合并包络包含的计轴区段 */
				mergeACIndex = elm_PrepareMergeUINT16Array(mergeACID,mergeACCntMax,mergeACIndex,ptemp->ACID,SECTION_IN_ENVELOPE_SUM_MAX,ptemp->ACCnt);

				/** 合并车头前方的计轴 */
				mergeACIndex = elm_PrepareMergeUINT16Array(mergeACID,mergeACCntMax,mergeACIndex,acSameID,(AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH),acSameCnt);

				/** 设置错误码*/
				ASSER_ERROR(mergeACIndex > mergeACCntMax,errorCode,0x04000000u);

				if (0u == errorCode)
				{
					/** 获取计轴内包含的包络 */
					envelopeCnt = elm_MergeEnvelope(mergeACID,(UINT8)mergeACIndex,arEnvelopID);

					/** 查询前方最接近本包络的包络*/
					funRtn = elm_SearchNearestEnvelope(ptemp,arEnvelopID,envelopeCnt,&preEnvelope,&backEnvelope,&includeCnt,includeELMid);
					ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x02000000u);

					/** 补丁，当UCT具有后端可疑时，有隐藏车恢复通信，需要进一步处理 */
					if ((0xffu == funRtn) && (LINE_MAX_TRAIN == ptemp->headTrainID) && (0u == preEnvelope) && (0u != includeCnt))
					{
						funRtn = elm_SearchNearstEnvInInclude(ELM_TAIL,ptemp,includeCnt,includeELMid,&preEnvelope);
						ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x01000000u);
					}
					else if ((0xffu == funRtn) && (LINE_MAX_TRAIN == ptemp->tailTrainID))
					{
						/** 隐藏车在后方恢复，此处不处理 */
					}
					else
					{
						/** 无需处理 */
						ASSER_ERROR(CI_SUCCESS != funRtn,errorCode,0x00800000u);
					}

					/** 如果查询成功 */
					if (0u == errorCode)
					{
						endLineFlag = (0u == acSameCnt) ? CI_SUCCESS : CI_ERROR;
						wInputAcId = acSameID[0U];
						pPretemp = elm_GetEnvelopeInfoPtr(preEnvelope);
						if (NULL != pPretemp)
						{
							for (cycle = 0U; cycle < pPretemp->ACCnt; cycle++)
							{
								if (ptemp->ACID[ptemp->ACCnt - 1U] == pPretemp->ACID[cycle])
								{
									wInputAcId = ptemp->ACID[ptemp->ACCnt - 1U];
									break;  /*前方包络与本包络终点处于同一计轴区段，停止遍历*/
								}
								else
								{
									/*继续遍历查找*/
								}
							}
						}
						else
						{
							/*不处理*/
						}

						/*若前方包络位于本包络终点计轴区段，则使用本包络终点计轴区段作为入参，否则使用本包络终点前方计轴区段作为入参*/
						funRtn = elm_UCTEnvelopeHeadHandle(endLineFlag,ptemp, wInputAcId,preEnvelope, cHeadDirChangeFlag);
						ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00400000u);

						if (CI_ERROR != funRtn)
						{
							/** 则设置返回值为函数返回值 */
							ret = funRtn;
						}
						else
						{
							/** 处理失败 */
							ret = CI_ERROR;
						}

					}
					else
					{
						/** 查询后方包络失败 */
					}	
				}
				else
				{
					/** 不可能分支，合并后的计轴数量超限 */
				}

				if (0u == acSameCnt)
				{
					/** 查询到尽头线 */
					ret = 0x55u;
				}
				else
				{
					/** */
				}
			}
			else
			{
				if (cycleAC == acSameCnt)
				{
					/** 前方岔区四开且空闲，无需延伸 */
					ret = 0x55u;
				}
				else
				{
					/** 前方道岔占用且四开，UCT无法处理*/
					ASSER_ERROR(acSameCnt > 1u,errorCode,0x00200000u);
				}				
			}
		}
		else
		{
			/** 查询失败 */
		}
	}

	/** 设置函数返回值 */
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT%d Head Moving error!",errorCode,ptemp->id));
	ASSERT_SETRET(0u == errorCode,ret,ret,CI_ERROR);

	return ret;
}



/**
 * @brief UCT包络尾部有接近包络的处理
 * @param[in] UINT8 endlineFlag 尽头线标识
 *            const EnvelopeStruct *ptemp, 待处理UCT包络
 *            UINT16 tailACId， 后方计轴
 *            UINT16 backEnvelopeId， 后方包络
 *            UINT8 cDirChangedFlag 方向变化点标志
 * @param[out] 无
 * @return CI_ERROR 执行错误
           0x55u,执行正确，包络无法再继续往后延申
		   0xaau,执行正确，包络可继续往后延申
 * @note 
 */
static UINT8 elm_UCTEnvelopeTailHandle(UINT8 endlineFlag, const EnvelopeStruct *ptemp, UINT16 tailACId, UINT16 backEnvelopeId, UINT8 cDirChangedFlag)
{
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = CI_ERROR;
	UINT8 dirCheck = 0u;
	UINT16 tmpACIndex = 0u;
	UINT8 pointBelong = ELM_BELONG_OWNER;
	UINT8 selfFlag = 0u;
	UINT8 ocid = 0u;
	UINT16 LocACId = 0u;
	UINT8 OccStatus = ELM_AC_OCC;
	LOD_STRU trainLoc = { 0u };
	const EnvelopeStruct *pBacktemp = NULL;
	UINT32 errorCode = 0u;
	ELM_TrainSafeLocStruct safeLoc = { 0u }; /*列车安全位置*/
	UINT16 wLinkId = 0U;
	UINT16 * pLinkBuf = NULL;
	UINT8 chBgUtSwitch = FUNC_SWITCH_OFF;
	UINT16 wNextLinkId = 0U;
	UINT8 chBgAtt = 0U;
	UINT16 wAgLink = 0U;
	UINT16 wSwitchId = 0U;
	UINT8 cDirectionPointFlag = 0U;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == ptemp, ret, 0x80000000u);
	ASSERT_RET_VALUE(((DIRECTIONPOINT_FLAG_VALID != cDirChangedFlag) && (DIRECTIONPOINT_FLAG_INVALID != cDirChangedFlag)), ret, 0x80000000u);
	pBacktemp = elm_GetEnvelopeInfoPtr(backEnvelopeId);

	if (CI_SUCCESS == endlineFlag)
	{
		/** 尽头线不处理 */
	}
	else
	{
		/** 判断后方计轴是否属于本OC*/
		pointBelong = elm_PrepareACIsSelf(tailACId, &ocid);

		/** 获取计轴状态 */
		OccStatus = elm_PrepareACStatus(tailACId);
	}


	if (ELM_BELONG_OTHER == pointBelong)
	{
		/** 前方为非本OC计轴*/
		if (NULL == pBacktemp)
		{
			/** 则更新车尾位置 */
			funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL, ptemp->ACID[0u], ptemp);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);
		}
		else if (TYPE_UKT_ENVELOPE == pBacktemp->envelopeType)
		{
			/** 则更新车尾位置 */
			funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL, ptemp->ACID[0u], ptemp);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

			funRtn = elm_SetEnvelopeTailTrainID(ptemp->id, LINE_MAX_TRAIN);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00010000u);
		}
		else if (TYPE_CT_ENVELOPE == pBacktemp->envelopeType)
		{
			/** 获取两个包络的方向是否一致 */
			dirCheck = elm_DirIsSameELMWithELM(pBacktemp, ptemp);

			/** 获取包络是否属于本OC */
			selfFlag = elm_PrepareEnvelopeIsSelf(pBacktemp);

			/** 后端监控 */
			if (ELM_DIR_SAME == dirCheck)
			{
				/** 位置处理  */
				if (ELM_BELONG_OTHER == selfFlag)
				{
					/** 则更新车尾位置 */
					funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL, ptemp->ACID[0u], ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);
				}
				else
				{
					/*获取列车安全位置*/
					funRtn = elm_PrepareTrainSafeLoc(pBacktemp->trainID[0u], &safeLoc);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00400000u);
					trainLoc = safeLoc.endPos;

					/*UCT追CT，从大前改为追安全车头*/
					/** 属于本OC，则更新包络位置*/
					funRtn = elm_SetEnvelopeLoc(ptemp->id, trainLoc, ptemp->endPos);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00040000u);
				}

				/** 后端监控 */
				if (0u != pBacktemp->headTrainID)
				{
					if (ptemp->trainID[0u] == pBacktemp->trainID[0u])
					{
						/** UCT包络尾车与CT包络同一个车，UCT染上CT的后方列车ID，此场景只会在分界点出*/
						funRtn = elm_SetEnvelopeTailTrainID(ptemp->id, pBacktemp->tailTrainID);
					}
					if (ptemp->trainID[0u] == pBacktemp->headTrainID)
					{
						/** 无需处理*/
					}
					else
					{
						/** UCT染上后端可疑 */
						funRtn = elm_SetEnvelopeTailTrainID(ptemp->id, LINE_MAX_TRAIN);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
					}
				}
				else
				{
					/** 无需增加可疑 */
					funRtn = elm_SetEnvelopeHeadTrainID(pBacktemp->id, ptemp->trainID[0u]);		/*方向相同，CT车作为后车，设置前可疑*/
				}
			}
			else
			{
				/** 位置处理  */
				if (ELM_BELONG_OTHER == selfFlag)
				{
					/** 则更新车尾位置 */
					funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL, ptemp->ACID[0u], ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);
				}
				else
				{
					/*获取列车安全位置*/
					funRtn = elm_PrepareTrainSafeLoc(pBacktemp->trainID[0u], &safeLoc);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00100000u);
					trainLoc = safeLoc.startPos;

					/*UCT追CT，从小后改为追安全车尾*/
					/** 属于本OC，则更新包络位置*/
					trainLoc.Dir = ~trainLoc.Dir;
					funRtn = elm_SetEnvelopeLoc(ptemp->id, trainLoc, ptemp->endPos);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00040000u);
				}

				/** 后端监控*/
				if (0u != pBacktemp->tailTrainID)
				{
					if (ptemp->trainID[0u] == pBacktemp->trainID[0u])
					{
						/** UCT包络尾车与CT包络同一个车，UCT染上CT的后方列车ID，此场景只会在分界点出*/
						funRtn = elm_SetEnvelopeTailTrainID(ptemp->id, pBacktemp->headTrainID);
					}
					if (ptemp->trainID[0u] == pBacktemp->tailTrainID)
					{
						/** 无需处理*/
					}
					else
					{
						/** UCT染上后端可疑 */
						funRtn = elm_SetEnvelopeTailTrainID(pBacktemp->id, LINE_MAX_TRAIN);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00004000u);
					}
				}
				else
				{
					/** 无需增加可疑 */
					funRtn = elm_SetEnvelopeTailTrainID(pBacktemp->id, ptemp->trainID[0u]);		/*方向相反，CT车与UCT背离，设置后可疑*/
				}
			}

		}
		else
		{
			/** 判断两包络是否为同一UCT，如果是则不添加前端可疑 */
			funRtn = elm_CheckEnvelopeMergeValid(ELM_TAIL, ptemp, pBacktemp);

			if (0x55u == funRtn)
			{
				funRtn = elm_SetEnvelopeTailTrainID(ptemp->id, pBacktemp->tailTrainID);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00002000u);
				/** 则更新车尾位置 */
				funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL, ptemp->ACID[0u], ptemp);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00001000u);
			}
			else
			{
				funRtn = elm_DeleteCTOrUCTEnvelope(ptemp->id);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00000800u);
			}
		}
		ret = 0x55u;
	}
	else
	{
		if ((NULL == pBacktemp) || (TYPE_UKT_ENVELOPE == pBacktemp->envelopeType))
		{
			if (NULL == pBacktemp)
			{
				if ((ELM_AC_FREE == OccStatus) || (CI_SUCCESS == endlineFlag))
				{
					/** 则更新车尾位置 */
					funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL, ptemp->ACID[0u], ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

					/** 说明仅更新包络尾包络，不需要继续处理 */
					ret = 0x55u;
				}
				else
				{
					if (ptemp->ACCnt < (SECTION_IN_ENVELOPE_SUM_MAX - 1u))
					{
						/** 包络后延*/
						funRtn = elm_PushEnvelopeACSeq(ELM_TAIL, ptemp->id, tailACId);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x40000000u);

						/** 添加包络到计轴的映射 */
						tmpACIndex = elm_PrepareACIndex(tailACId);
						funRtn = elm_SetACRelEnvelopeMap(OP_ADD, tmpACIndex, ptemp->id);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);

						/*判断是否更新包络起点方向*/
						if (DIRECTIONPOINT_FLAG_VALID == cDirChangedFlag)
						{
							/*存在方向变化点，设置包络起点方向反向*/
							funRtn = elm_SetEnvelopeStartDir(ptemp->id, ~ptemp->startPos.Dir);
							ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
						}
						else
						{
							/*不处理*/
						}

						/** 则更新车尾位置 */
						funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL, ptemp->ACID[0u], ptemp);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

						/** 需要看前方是否还存在占用计轴*/
						ret = 0xaau;
					}
					else
					{
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
					}
				}
			}
			else
			{
				if (ptemp->ACCnt < (SECTION_IN_ENVELOPE_SUM_MAX - 1u))
				{
					/** 包络后延*/
					funRtn = elm_PushEnvelopeACSeq(ELM_TAIL, ptemp->id, tailACId);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x40000000u);

					/** 添加包络到计轴的映射 */
					tmpACIndex = elm_PrepareACIndex(tailACId);
					funRtn = elm_SetACRelEnvelopeMap(OP_ADD, tmpACIndex, ptemp->id);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);

					/*判断是否更新包络起点方向*/
					if (DIRECTIONPOINT_FLAG_VALID == cDirChangedFlag)
					{
						/*存在方向变化点，设置包络起点方向反向*/
						funRtn = elm_SetEnvelopeStartDir(ptemp->id, ~ptemp->startPos.Dir);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
					}
					else
					{
						/*不处理*/
					}

					/** 则更新车尾位置 */
					funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL, ptemp->ACID[0u], ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

					/** UCT染上后端可疑 */
					funRtn = elm_SetEnvelopeTailTrainID(ptemp->id, LINE_MAX_TRAIN);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x08000000u);

					/** UKT包络被CT包络吃掉 */
					funRtn = elm_DeleteUKTEnvelope(pBacktemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x04000000u);

					/** 需要看前方是否还存在占用计轴*/
					ret = 0xaau;
				}
				else
				{
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
				}
			}


			/** 设置计轴上包络进出过程 */
			funRtn = elm_RefreshACseqInfoForUCT(ptemp);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x02000000u);

		}
		else if (TYPE_CT_ENVELOPE == pBacktemp->envelopeType)
		{
			pLinkBuf = GetAxisLinkIdBuf(ptemp->ACID[0]);
			wLinkId = pLinkBuf[0];
			chBgAtt = GetLinkRelPhySecAGorBGAttr(wLinkId);
			wAgLink = GetBGLinkRelAGLinkId(wLinkId);
			chBgUtSwitch = GetNoCGFollowUtSwitch();
			wNextLinkId = FindAdjacentLinkIDSafe(wLinkId, ~ptemp->startPos.Dir, &wSwitchId, &cDirectionPointFlag);
			if ((FUNC_SWITCH_ON == chBgUtSwitch) && (LINK_REL_PHYSEC_BG == chBgAtt) && (wNextLinkId == wAgLink) 
				&& ((pBacktemp->startPos.Lnk == wAgLink) || (pBacktemp->endPos.Lnk == wAgLink))
				&& (1U == ptemp->ACCnt))
			{/* B轨UT可追踪开关打开，UCT仅处于B轨，相邻区段是A轨，CT包络在A轨，此场景不延伸 */
				ret = 0x55u;
			}
			else
			{
				/** 获取两个包络的方向是否一致 */
				dirCheck = elm_DirIsSameELMWithELM(pBacktemp, ptemp);

				if (0u == dirCheck)
				{
					/** 两个包络方向比较不一致 */
				}
				else
				{
					/** 则更新位置 */
					if (ELM_DIR_SAME == dirCheck)
					{
						/** 缓存包络终点计轴 */
						LocACId = pBacktemp->ACID[pBacktemp->ACCnt - 1u];

						/*获取列车安全位置*/
						funRtn = elm_PrepareTrainSafeLoc(pBacktemp->trainID[0u], &safeLoc);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00400000u);
						/*UCT追CT，从大前改为追安全车头*/
						trainLoc = safeLoc.endPos;

						if (0u != pBacktemp->headTrainID)
						{
							if (ptemp->trainID[0u] == pBacktemp->headTrainID)
							{
								/** 无需处理*/
							}
							else
							{
								/** UCT染上后端可疑 */
								funRtn = elm_SetEnvelopeTailTrainID(ptemp->id, LINE_MAX_TRAIN);
								ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00200000u);
							}
						}
						else
						{
							/** 无需增加可疑 */
							funRtn = elm_SetEnvelopeHeadTrainID(pBacktemp->id, ptemp->trainID[0u]);		/*方向相同，CT车作为后车，设置前可疑*/
						}
					}
					else
					{
						/** 缓存包络终点计轴 */
						LocACId = pBacktemp->ACID[0u];

						/*获取列车安全位置*/
						funRtn = elm_PrepareTrainSafeLoc(pBacktemp->trainID[0u], &safeLoc);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00100000u);
						/*UCT追CT，从小后改为追安全车尾*/
						trainLoc = safeLoc.startPos;
						trainLoc.Dir = ~trainLoc.Dir;

						if (0u != pBacktemp->tailTrainID)
						{
							if (ptemp->trainID[0u] == pBacktemp->tailTrainID)
							{
								/** 无需处理*/
							}
							else
							{
								/** UCT染上后端可疑 */
								funRtn = elm_SetEnvelopeTailTrainID(ptemp->id, LINE_MAX_TRAIN);
								ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00080000u);
							}
						}
						else
						{
							/** 无需增加可疑 */
							funRtn = elm_SetEnvelopeTailTrainID(pBacktemp->id, ptemp->trainID[0u]);		/*方向相反，CT车与UCT背离，设置后可疑*/
						}
					}

					/** 补丁：避免UCT跳过空闲计轴，染到前方CT包络车载位置所在计轴 */
					if ((LocACId == tailACId) && (ELM_AC_FREE == OccStatus))
					{
						/** 则更新车尾位置 */
						funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL, ptemp->ACID[0u], ptemp);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00040000u);
					}
					else
					{
						/** 属于本OC，则更新包络位置*/
						funRtn = elm_SetEnvelopeLoc(ptemp->id, trainLoc, ptemp->endPos);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00040000u);
					}

					/** 更新计轴映射关系 */
					elm_RefreshUCTofACMapInfo(ptemp);

					/** 设置计轴上包络进出过程 */
					funRtn = elm_RefreshACseqInfoForUCT(ptemp);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00020000u);

					ret = 0x55u;
				}
			}
		}
		else
		{
			/** UCT包络合并 */
			funRtn = elm_UCTEnvelopeMerge(ELM_TAIL, ptemp, pBacktemp);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00020000u);
			ret = 0x55u;
		}
	}

	/** 设置函数返回值 */
	ASSER_DEBUG(0u != errorCode, ELM_LOG_LOC(ELM_LOG_ERROR, "errorCode:0x%08x info:UCT%d tail ELM track error!", errorCode, ptemp->id));
	ASSERT_SETRET(0u == errorCode, ret, ret, CI_ERROR);

	return ret;
}


/**
 * @brief UCT包络尾部移动
 * @param[in] const EnvelopeStruct *ptemp UCT包络
 * @return CI_ERROR 执行错误
           0x55u,执行正确，包络无法再继续往后延申
           0xaau,执行正确，包络可继续往后延申
 * @note UCT包络创建后，UCT包络尾进行延申：
 *      1、如果UCT包络相邻计轴区段占用且不存在UKT包络，则UCT包络进行延申，包络尾设置为该计轴远端端点处。
        2、如果UCT包络尾处存在计轴区段空闲，则UCT包络进行回缩，包络尾设置为该计轴远端端点处
        3、如果UCT包络相邻计轴区段占用且存在UKT包络，则UCT包络进行延申，包络尾设置为该计轴远端端点处，并新增可疑标志
        4、如果UCT包络相邻计轴区段占用且存在CT包络，则UCT包络进行延申，包络尾不越过CT包络最小安全前围成的范围内
 */
static UINT8 elm_UCTEnvelopeTailMoving(const EnvelopeStruct *ptemp)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 endLineFlag = CI_ERROR;
	UINT8 cycle = 0u;
	UINT8 cycleAC = 0u;
	UINT8 OccStatus = ELM_AC_OCC;
	UINT8 tmpACCnt = 0u;
	UINT16 tmpACIndex = 0u;
	UINT16 preEnvelope = 0u;
	UINT16 backEnvelope = 0u;
	UINT8 acConvertCnt = 0u;
	UINT16 acConvertID[AC_MAXCNT_IN_SWITCH] = {0u};
	UINT8 envelopeCnt = 0u;     /* 包络数量 */
	UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] = {0u};  /*包络ID数组*/
	UINT16 mergeACIndex = 0u;
	UINT16 mergeACID[SECTION_IN_ENVELOPE_SUM_MAX + AC_MAXCNT_IN_SWITCH] = {0u};
	UINT16 mergeACCntMax = (SECTION_IN_ENVELOPE_SUM_MAX + AC_MAXCNT_IN_SWITCH);
	UINT8 includeCnt = 0u;
	UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] = {0u};  /** 重合的包络id */
	UINT8 cTailDirChangeFlag = DIRECTIONPOINT_FLAG_INVALID;  /*包络尾方向变化点标志*/
	const EnvelopeStruct* pBacktemp = NULL;
	UINT16 wInputAcId = 0U;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == ptemp,ret,0x80000000u);

	/** 根据占用回缩车尾,至少保留一个计轴，交给后续UCT全空闲处理 */
	tmpACCnt = ptemp->ACCnt;

	for (cycle = 0u; (0u != tmpACCnt) && (cycle < (tmpACCnt - 1u)); cycle++)
	{
		/** 获取计轴的占用状态 */
		OccStatus = elm_PrepareACStatus(ptemp->ACID[0u]);

		if (ELM_AC_FREE == OccStatus)
		{
			/** 删除计轴到包络的映射 */
			tmpACIndex = elm_PrepareACIndex(ptemp->ACID[0u]);
			funRtn = elm_SetACRelEnvelopeMap(OP_DEL,tmpACIndex,ptemp->id);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x40000000u);

			/** 设置车尾出清*/
			funRtn = elm_UCTEnvelopeLeaveAC(ELM_TAIL,ptemp,ptemp->ACID[0u]);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);

			acConvertCnt = elm_PrepareAdjacentAC(ptemp->ACID[0u], ptemp->startPos.Dir, acConvertID, &cTailDirChangeFlag);
			/*包络尾回撤时，及时更新包络起点方向*/
			if (DIRECTIONPOINT_FLAG_VALID == cTailDirChangeFlag)
			{
				/*存在方向变化点，设置包络起点方向反向*/
				funRtn = elm_SetEnvelopeStartDir(ptemp->id, ~ptemp->startPos.Dir);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00100000u);
			}
			else
			{
				/*不存在方向变化点，不处理*/
			}

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

	if (0u != cycle)
	{
		/** 说明UCT包络后方存在空闲计轴，则更新车尾位置 */
		funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL,ptemp->ACID[0u],ptemp);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x08000000u);
		ret = 0x55;
	}
	else
	{
		/** 查询包络起点后方计轴 */
		acConvertCnt = elm_PrepareAdjacentAC(ptemp->ACID[0u], ~ptemp->startPos.Dir, acConvertID, &cTailDirChangeFlag);
		ASSER_ERROR(UINT8_MAX == acConvertCnt,errorCode,0x04000000u);		

		if (UINT8_MAX != acConvertCnt)
		{
			/** 判断后方计轴是否空闲 */
			for (cycleAC = 0u; cycleAC < acConvertCnt; cycleAC++)
			{
				/** 获取计轴状态 */
				OccStatus = elm_PrepareACStatus(acConvertID[cycleAC]);

				/** 如果计轴状态占用，则跳出循环 */
				ASSERT_BREAK(ELM_AC_OCC == OccStatus,errorCode,0u);
			}

			/** 后方计轴空闲且位置正确，需要调整包络尾的位置 */
			if(1u >= acConvertCnt)
			{
				/** 合并车尾后方的计轴 */
				mergeACIndex = elm_PrepareMergeUINT16Array(mergeACID,mergeACCntMax,mergeACIndex,acConvertID,(AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH),acConvertCnt);

				/** 合并包络包含的计轴区段 */
				mergeACIndex = elm_PrepareMergeUINT16Array(mergeACID,mergeACCntMax,mergeACIndex,ptemp->ACID,SECTION_IN_ENVELOPE_SUM_MAX,ptemp->ACCnt);

				/** 设置错误码*/
				ASSER_ERROR(mergeACIndex > mergeACCntMax,errorCode,0x04000000u);

				if (0u == errorCode)
				{
					/** 获取计轴内包含的包络 */
					envelopeCnt = elm_MergeEnvelope(mergeACID,(UINT8)mergeACIndex,arEnvelopID);

					/** 查询后方最接近本包络的包络*/
					funRtn = elm_SearchNearestEnvelope(ptemp,arEnvelopID,envelopeCnt,&preEnvelope,&backEnvelope,&includeCnt,includeELMid);
					ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x02000000u);

					/** 补丁，当UCT具有后端可疑时，有隐藏车恢复通信，需要进一步处理 */
					if ((0xffu == funRtn) && (LINE_MAX_TRAIN == ptemp->tailTrainID) && (0u == backEnvelope) && (0u != includeCnt))
					{
						funRtn = elm_SearchNearstEnvInInclude(ELM_TAIL,ptemp,includeCnt,includeELMid,&backEnvelope);
						ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x01000000u);
					}
					else if ((0xffu == funRtn) && (LINE_MAX_TRAIN == ptemp->headTrainID))
					{
						/** 隐藏车在前方恢复，此处不处理 */
					}
					else
					{
						/** 无需处理 */
						ASSER_ERROR(CI_SUCCESS != funRtn,errorCode,0x00800000u);
					}

					/** 如果查询成功 */
					if (0u == errorCode)
					{
						endLineFlag = (0u == acConvertCnt) ? CI_SUCCESS : CI_ERROR;
						wInputAcId = acConvertID[0U];
						pBacktemp = elm_GetEnvelopeInfoPtr(backEnvelope);
						if (NULL != pBacktemp)
						{
							for (cycle = 0U; cycle < pBacktemp->ACCnt; cycle++)
							{
								if (ptemp->ACID[0U] == pBacktemp->ACID[cycle])
								{
									wInputAcId = ptemp->ACID[0U];
									break;  /*后方包络与本包络起点处于同一计轴区段，停止遍历*/
								}
								else
								{
									/*继续遍历查找*/
								}
							}
						}
						else
						{
							/*不处理*/
						}

						/*若后方包络位于本包络起点计轴区段，则使用本包络起点计轴区段作为入参，否则使用本包络起点后方计轴区段作为入参*/
						funRtn = elm_UCTEnvelopeTailHandle(endLineFlag, ptemp, wInputAcId, backEnvelope, cTailDirChangeFlag);

						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00400000u);

						if (CI_ERROR != funRtn)
						{
							/** 则设置返回值为函数返回值 */
							ret = funRtn;
						}
						else
						{
							/** 处理失败 */
							ret = CI_ERROR;
						}
					}
					else
					{
						/** 查询后方包络失败 */
					}	
				}
				else
				{
					/** 不可能分支，合并后的计轴数量超限 */
				}			
			}
			else
			{
				if (cycleAC == acConvertCnt)
				{
					/** 说明后方岔区空闲且四开，无需延伸*/
					ret = 0x55u;
				}
				else
				{
					/** 后方道岔占用且四开，UCT无法处理*/
					ASSER_ERROR(acConvertCnt > 1u,errorCode,0x00200000u);
				}
			}
		}
		else
		{
			/** 查询失败 */
		}
	}

	/** 设置函数返回值 */
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT%d tail Moving error!",errorCode,ptemp->id));
	ASSERT_SETRET(0u == errorCode,ret,ret,CI_ERROR);

	return ret;
}


/**
 * @brief UCT包络刷新
 * @param[in] const EnvelopeStruct* ptemp 包络信息指针
 * @param[out]
 * @return CI_ERROR 创建失败
 *         CI_SUCCESS 创建成功
 * @note 
 */
static UINT8 elm_UCTEnvelopeRefresh(const EnvelopeStruct* ptemp)
{
	UINT8 ret = CI_ERROR;
	UINT8 tailMovingFlag = CI_ERROR;
	UINT8 headMovingFlag = CI_ERROR;
	UINT8 isOwnFlag = ELM_BELONG_OWNER;
	UINT8 movedCnt = 0u;
	UINT32 errorCode = 0u;

	/** 入口参数合法性校验 */
	ASSERT_RET_VALUE(NULL == ptemp,ret,0x80000000u);

	/** 判断包络是否属于本OC */
	isOwnFlag = elm_PrepareEnvelopeIsSelf(ptemp);

	if (ELM_BELONG_OTHER == isOwnFlag)
	{
		/** 不属于本OC，无需处理 */
	}
	else
	{
		/** 包络尾的延申 */
		do 
		{
			tailMovingFlag = elm_UCTEnvelopeTailMoving(ptemp);
			movedCnt++;
		} while ((0xaaU == tailMovingFlag) && (movedCnt < SECTION_IN_ENVELOPE_SUM_MAX));

		/** 判断包络尾的延申 */
		ASSER_ERROR((CI_ERROR == tailMovingFlag) || (SECTION_IN_ENVELOPE_SUM_MAX == movedCnt),errorCode,0x40000000u);

		if (CI_ERROR != tailMovingFlag)
		{
			movedCnt = 0u;

			/** 包络头的延申 */
			do 
			{
				headMovingFlag = elm_UCTEnvelopeHeadMoving(ptemp);
				movedCnt++;
			} while ((0xaaU == headMovingFlag) && (movedCnt < SECTION_IN_ENVELOPE_SUM_MAX));

			/** 判断包络尾的延申 */
			ASSER_ERROR((CI_ERROR == headMovingFlag) || (SECTION_IN_ENVELOPE_SUM_MAX == movedCnt),errorCode,0x20000000u);
		}
		else
		{
			/** 延申错误*/
		}

		/** 如果跟踪后，UCT包络存在前后可疑，则删除UCT包络（否则无法确定非UCT列车序列中的列车恢复时，列车前后关系的无法进行比较） */
		if(((0u != ptemp->headTrainID) && (LINE_MAX_TRAIN != ptemp->headTrainID)) || 
			((0u != ptemp->tailTrainID) && (LINE_MAX_TRAIN != ptemp->tailTrainID)))
		{
			errorCode += 0x10000000u;
			ELM_LOG_LOC(ELM_LOG_FATAL,"errorCode:0x%08x info:UCT%d head and tail suspicious flag error!",errorCode,ptemp->id);
		}
		else if ((0u != ptemp->headTrainID) && (0u != ptemp->tailTrainID))
		{
			errorCode += 0x08000000u;
			ELM_LOG_LOC(ELM_LOG_FATAL,"errorCode:0x%08x info:UCT%d has head and tail suspicious!",errorCode,ptemp->id);
		}
		else
		{
			/** 无需处理 */
		}
	}
	
	if (0u == errorCode)
	{
		/** UCT跟踪没有问题 */
		ret = CI_SUCCESS;
	}
	else
	{
		/** UCT跟踪失败，导向安全侧*/
		ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT%d Refresh error,convert to UKT!",errorCode,ptemp->id);
		ret = elm_DeleteCTOrUCTEnvelope(ptemp->id);
		ASSER_ERROR(CI_ERROR == ret,errorCode,0x08000000u);
		ASSER_DEBUG(CI_ERROR == ret,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT convert to UKT error!",errorCode));
	}

	/** 函数返回值 */
	return ret;
}

/**
 * @brief UCT包络行进
 * @param[in] const EnvelopeStruct* ptemp 包络信息指针
 * @param[out]
 * @return CI_ERROR 创建失败
 *         CI_SUCCESS 创建成功
 * @note UCT包络创建后，如果相邻计轴占用，则UCT包络进行延申：
 *      1、如果UCT包络相邻计轴区段占用且不存在UKT包络，则UCT包络进行延申，包络头/尾设置为该计轴远端端点处。
        2、如果UCT包络头/尾处存在计轴区段空闲，则UCT包络进行回缩，包络头/尾设置为该计轴近端端点处
		3、如果UCT包络相邻计轴区段占用且存在UKT包络，则UCT包络进行延申，包络头/尾设置为该计轴远端端点处，并新增可疑标志
		4、如果UCT包络相邻计轴区段占用且存在CT包络，则UCT包络进行延申，包络头/尾不倾入CT包络最小安全后及最大安全前围成的范围内
 */
static UINT8 elm_UCTEnvelopeMoving(const EnvelopeStruct* ptemp)
{
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = SWITCH_ZONE_OCC_AND_ERROR;
	UINT32 errorCode = 0u;

	/** 检查包络内的道岔关系 */
	funRtn = elm_CheckSwitchInEnvelope(ptemp);
	
	if (SWITCH_ZONE_OK == funRtn)
	{
		/** 道岔位置符合拓扑关系，正常的行进 */
		funRtn = elm_UCTEnvelopeRefresh(ptemp);
		ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x80000000u);

		funRtn = elm_UCTToUKTCheck(ptemp);  /*根据全线通信车信息检查UCT包络是否需要转为UKT*/
		if (CI_SUCCESS == funRtn)
		{
			ELM_LOG(ELM_LOG_FATAL, "info:Delete UCT[%d] because of line comm train.\n", ptemp->id);
			funRtn = elm_DeleteCTOrUCTEnvelope(ptemp->id);  /*UCT包络中的列车存在于全线通信车中且超时，将UCT转为UKT*/
		}
		else
		{
			/*UCT包络中的列车不在全线通信车中或未超时，不处理*/
		}
	}
	else if (SWITCH_ZONE_OCC_AND_ERROR == funRtn)
	{
		/** 包络内道岔占用且四开，UCT包络需要进行裂变,目前先处理为删除成UKT */
		ELM_LOG(ELM_LOG_FATAL,"info:Delete UCT[%d] because of switch pos error and occ.\n",ptemp->id);
		funRtn = elm_DeleteCTOrUCTEnvelope(ptemp->id);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x40000000u);
	}
	else
	{
		/** 包络内道岔空闲且四开，将列车占压的计轴区段设置成UKT */
		ELM_LOG(ELM_LOG_FATAL,"info:Delete UCT[%d] because of switch pos error and free.\n",ptemp->id);
		funRtn = elm_DeleteCTOrUCTEnvelope(ptemp->id);
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);
	}

	/** 设置函数返回值 */
	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] Moving error!",errorCode,ptemp->id));

	return ret;
}


/**
 * @brief CT包络转换成UCT包络检查
 * @param[in] const EnvelopeStruct* ptemp
 * @param[out] 无
 * @return CI_ERROR 转换失败
 *         CI_SUCCESS 转换成功
 * @note CT包络转换成UCT时，需要满足：
	1，无前端可疑 
	2、包络内包含的道岔无四开且占用，
	3，不为休眠车,
	4、列车车长不小于两倍线路最小车长
* by cgh 20250915
 */
static UINT8 elm_ConvertToUCTCheck(const EnvelopeStruct* ptemp)
{
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = SWITCH_ZONE_OCC_AND_ERROR;
	UINT32 errorCode = 0U;
	UINT32 trainLength = 0U;
	UINT8 chCanUct = FLAG_SET;
	UINT32 minTrainLength = 0U;
	UINT32 dwTempLength = 0U;
	UINT8 chTrainNvramPosFlag = 0U;
	UINT8 chTrainIsIsFollowUtFlag = 0U;/*是否为列车可追踪UT*/

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == ptemp,ret,0x80000000U);

	if (LINE_MAX_TRAIN == ptemp->headTrainID)
	{
		/** 如果前方列车为故障车，则不可转换成UCT */
		ASSER_ERROR(LINE_MAX_TRAIN == ptemp->headTrainID,errorCode,0x40000000U);
	}
	else
	{
		funRtn = elm_CheckSwitchInEnvelope(ptemp);
		ASSER_ERROR(SWITCH_ZONE_OCC_AND_ERROR == funRtn,errorCode,0x20000000U);
	}
	
	if (0U == errorCode)
	{
		/** 获取列车是否能转为UCT */
		chCanUct = elm_PrePareTrainCanUct(ptemp->trainID[0U]);
		ASSER_ERROR(FLAG_SET == chCanUct, errorCode, 0x10000000U);
	}
	else
	{
		; /* 不满足转为UCT条件 */
	}

	if (0U == errorCode)
	{
		/* by cgh 20240111  UCT生成原则，需列车长度大于50m或两倍车长 */
		trainLength = elm_PrepareTrainLength(ptemp->trainID[0U]);
		minTrainLength = elm_PrepareTrainLength(LINE_MAX_TRAIN);

		dwTempLength = ((2U * minTrainLength) > 5000U) ? (2U * minTrainLength) : 5000U;

		ASSER_ERROR(trainLength <= dwTempLength, errorCode, 0x08000000U);
	}
	else
	{
		; /* 不满足转为UCT条件 */
	}

	if (0U == errorCode)
	{
		/** 获取列车是否使用NVRAM位置 */
		chTrainNvramPosFlag = GetTrainNvramPosFlag(ptemp->trainID[0U]);
		ASSER_ERROR(TRAIN_NVRAM_POS_FLAG_NO != chTrainNvramPosFlag, errorCode, 0x04000000U);
	}
	else
	{
		; /* 不满足转为UCT条件 */
	}

	if (0U == errorCode)
	{
		/** 获取列车是否处于可追踪UT场景 */
		chTrainIsIsFollowUtFlag = CheckTrainIsFollowUt(ptemp->id);
		ASSER_ERROR(CI_SUCCESS == chTrainIsIsFollowUtFlag, errorCode, 0x02000000U);
	}
	else
	{
		; /* 不满足转为UCT条件 */
	}
	
	/** 设置函数返回值 */
	ASSERT_SETRET(0U == errorCode,ret,CI_SUCCESS,CI_ERROR);
	ASSER_DEBUG(0U != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:ELM%d can't convert to UCT!",errorCode,ptemp->id));
	return ret;
}



/**
 * @brief UCT包络创建
 * @param[in] 
 * @param[out]
 * @return CI_ERROR 创建失败
 *         CI_SUCCESS 创建成功
 * @note UCT包络创建时，必然该车之前关联了CT包络
 *       1、UCT包络初始创建时，根据列车安全包络和计轴占用进行初始位置确定。特别的，如果安全车尾不为计轴端点，这包络尾位置即为安全车尾
 */
static UINT8 elm_UCTEnvelopeCreate(const EnvelopeStruct* ptemp)
{
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = CI_ERROR;
	UINT8 comstatus = ELM_COM_STATUS_ERROR;
	UINT8 zoneFlag = CI_ERROR;
	UINT8 UCTSwitch = CI_ERROR;
	UINT8 cycle = 0u;
	UINT8 OccStatus = ELM_AC_OCC;
	UINT8 tempACCnt = 0u;
	UINT16 tmpACIndex = 0u;
	UINT32 errorCode = 0u;
	UINT8 cNearAcNum = 0U;  /*相邻AC数量*/
	UINT16 cNearAcIdBuf[AC_MAXCNT_IN_SWITCH] = { 0U };  /*相邻AC的ID*/
	UINT8 cHeadDirChangeFlag = DIRECTIONPOINT_FLAG_INVALID;  /*包络头方向变化点标志*/
	UINT8 cTailDirChangeFlag = DIRECTIONPOINT_FLAG_INVALID;  /*包络尾方向变化点标志*/

	/** 获取包络所属TIOC范围 */
	zoneFlag = elm_PrepareEnvelopeIsSelf(ptemp);

	/** 入口参数判断 */
	ASSERT_RET_VALUE(CI_ERROR == zoneFlag,ret,0x80000000u);

	/** 获取列车的通信状态 */
	comstatus = elm_PrepareTrainCommStatus(ptemp->trainID[0u]);

	if ((ELM_COM_STATUS_OK == comstatus) || (ELM_BELONG_OTHER == zoneFlag))
	{
		/** 通信正常的列车，无需处理*/
	}
	else
	{
		/** 获取UCT功能开关 */
		UCTSwitch = elm_PrepareUCTSwitch();

		if (CI_ERROR == UCTSwitch)
		{
			/** 将列车占压的计轴区段设置成UKT */
			ELM_LOG(ELM_LOG_FATAL,"info:train%d loseCOmmon,process to UKT.\n",ptemp->trainID[0u]);
			funRtn = elm_DeleteCTOrUCTEnvelope(ptemp->id);
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x40000000u);
		}
		else
		{
			ELM_LOG(ELM_LOG_FATAL,"info:train%d loseCOmmon,process to UCT.\n",ptemp->trainID[0u]);

			/** CT包络转换成UCT包络条件检查 */
			funRtn = elm_ConvertToUCTCheck(ptemp);

			if (CI_ERROR == funRtn)
			{
				/** 将列车占压的计轴区段设置成UKT */
				funRtn = elm_DeleteCTOrUCTEnvelope(ptemp->id);
				ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);
			}
			else
			{
				/** 更改包络类型 */
				funRtn = elm_SetEnvelopeType(ptemp->id,TYPE_UCT_ENVELOPE);
				ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x10000000u);

				ELM_LOG(ELM_LOG_FATAL,"info:UCT:%d init S:%d-%d-%d E:%d-%d-%d.\n", ptemp->id, ptemp->startPos.Lnk, ptemp->startPos.Off, ptemp->startPos.Dir, \
				ptemp->endPos.Lnk, ptemp->endPos.Off, ptemp->endPos.Dir);

				/** 根据占用回缩车头 */
				tempACCnt = ptemp->ACCnt;
				for (cycle = tempACCnt; 1u != cycle; cycle--)
				{
					/** 获取计轴的占用状态 */
					OccStatus = elm_PrepareACStatus(ptemp->ACID[ptemp->ACCnt - 1u]);

					if (ELM_AC_OCC == OccStatus)
					{
						if (tempACCnt == cycle)
						{
							/** 说明车头计轴占用，无需处理，避免延申到计轴端点，导致包住其他通信车，后续由UCT移动处理延申场景 */
						}
						else
						{
							funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD,ptemp->ACID[ptemp->ACCnt - 1u],ptemp);
							ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x08000000u);
						}
						break;
					}
					else
					{
						/** 删除计轴到包络的映射 */
						tmpACIndex = elm_PrepareACIndex(ptemp->ACID[ptemp->ACCnt - 1u]);
						funRtn = elm_SetACRelEnvelopeMap(OP_DEL,tmpACIndex,ptemp->id);
						ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x04000000u);

						/** 设置车头出清*/
						funRtn = elm_UCTEnvelopeLeaveAC(ELM_HEAD,ptemp,ptemp->ACID[ptemp->ACCnt - 1u]);
						ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x02000000u);

						/*包络头回撤时，根据方向变化点更新包络终点方向*/
						cNearAcNum = elm_PrepareAdjacentAC(ptemp->ACID[ptemp->ACCnt - 1u], ~ptemp->endPos.Dir, cNearAcIdBuf, &cHeadDirChangeFlag);
						if (DIRECTIONPOINT_FLAG_VALID == cHeadDirChangeFlag)
						{
							/*存在方向变化点，设置包络终点方向反向*/
							funRtn = elm_SetEnvelopeEndDir(ptemp->id, ~ptemp->endPos.Dir);
							ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00010000u);
						}
						else
						{
							/*不存在方向变化点，不处理*/
						}

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

						/** 调整包络位置 */
						funRtn = elm_SetUCTEnvelopeDot(ELM_HEAD,ptemp->ACID[ptemp->ACCnt - 1u],ptemp);
						ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00800000u);
					}
				}

				/** 根据占用回缩车尾 */
				tempACCnt = ptemp->ACCnt;
				for (cycle = 0u; ((0u != tempACCnt) && (cycle < (tempACCnt - 1u))); cycle++)
				{
					/** 获取计轴的占用状态 */
					OccStatus = elm_PrepareACStatus(ptemp->ACID[0u]);

					if (ELM_AC_OCC == OccStatus)
					{
						if (0u == cycle)
						{
							/** 说明车尾计轴占用，无需处理，避免延申到计轴端点，导致包住其他通信车，后续由UCT移动处理延申场景 */
						}
						else
						{
							funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL,ptemp->ACID[0u],ptemp);
							ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00400000u);
						}
						break;
					}
					else
					{
						/** 删除计轴到包络的映射 */
						tmpACIndex = elm_PrepareACIndex(ptemp->ACID[0u]);
						funRtn = elm_SetACRelEnvelopeMap(OP_DEL,tmpACIndex,ptemp->id);
						ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00200000u);

						/** 设置车尾出清*/
						funRtn = elm_UCTEnvelopeLeaveAC(ELM_TAIL,ptemp,ptemp->ACID[0u]);
						ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00100000u);

						/*包络尾回撤时，根据方向变化点更新包络终点方向*/
						cNearAcNum = elm_PrepareAdjacentAC(ptemp->ACID[0u], ptemp->startPos.Dir, cNearAcIdBuf, &cTailDirChangeFlag);
						if (DIRECTIONPOINT_FLAG_VALID == cTailDirChangeFlag)
						{
							/*存在方向变化点，设置包络起点方向反向*/
							funRtn = elm_SetEnvelopeStartDir(ptemp->id, ~ptemp->startPos.Dir);
							ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00008000u);
						}
						else
						{
							/*不存在方向变化点，不处理*/
						}

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

						/** 调整包络位置 */
						funRtn = elm_SetUCTEnvelopeDot(ELM_TAIL,ptemp->ACID[0u],ptemp);
						ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00040000u);
					}
				}
			}

			if (0u == errorCode)
			{
				/** UCT包络跟踪处理 */
				funRtn = elm_UCTEnvelopeMoving(ptemp);
				ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x00020000u);
				ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT%d Moving error!",errorCode,ptemp->id));
			}
			else
			{
				/** UCT包络创建失败 */
			}
		}
	}

	/** 设置返回值 */
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	return ret;
}


/**
 * @brief UCT车包络跟踪处理
 * @note
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 *   2、2022年7月19日，实现UCT包络功能
 */
void elm_UCTEnvelopeTrack(void)
{
	/*- 局部变量定义 */
	UINT16 envelopeIndex = 0u;
	UINT8 vaildFlag = ENVELOPE_UNEXIT;
	UINT8 funRtn = CI_ERROR;
	const EnvelopeStruct* pTemp = NULL;
	UINT32 errorCode = 0u;

	/** 遍历所有包络，如果包络是通信车，则根据列车的通信状态进行处理 */
	for (envelopeIndex = 1u; envelopeIndex < ENVELOPE_SUM_MAX; envelopeIndex++)
	{
		/** 获取空间使用标志*/
		vaildFlag = elm_IsEnvelopeExit(envelopeIndex);

		/** 判断包络是否有效 */
		if (ENVELOPE_EXIT == vaildFlag)
		{
			/** 获取包络信息缓存地址 */
			pTemp = elm_GetEnvelopeInfoPtr(envelopeIndex);
			
			if (NULL == pTemp)
			{
				/** 不可能出现的场景 */
			}
			else
			{
				if (TYPE_CT_ENVELOPE == pTemp->envelopeType)
				{
					/** UCT包络创建处理*/
					funRtn = elm_UCTEnvelopeCreate(pTemp);
					ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x80000000u);
					ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:ELM%d Create UCT error!",errorCode,envelopeIndex));
				}
				else if (TYPE_UCT_ENVELOPE == pTemp->envelopeType)
				{
					/** UCT包络跟踪处理 */
					funRtn = elm_UCTEnvelopeMoving(pTemp);
					ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x40000000u);
					ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT%d Moving error!",errorCode,envelopeIndex));
				}
				else
				{
					/** 无需处理 */
				}
			}
		}
		else
		{
			/** 不存在包络，不需要处理*/
		}

		/** 判断是否执行是否错误 */
		ASSERT_BREAK(0u != errorCode,errorCode,0u);
	}

	/** 对分界点处理 */
	funRtn = elm_UCTEnvelopeCloneByHandOver();
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x20000000u);

	if(0u != errorCode)
	{
		/** UCT包络跟踪失败 */
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:elm_UCTEnvelopeTrack error，ELM need reset !",errorCode);
	}
	else
	{
		/** 处理正确*/
	}
}

/**
 * @brief UCT包络恢复
 * @param[in] UINT16 trainid 列车ID
 * @param[out] 无
 * @return 无
 * @note 目前由于拆分和合并都未实现，则UCT恢复时，只会关联一个UCT包络
 */
void elm_UCTEnvelopeRecover(UINT16 trainid)
{
	UINT8 funRtn = CI_ERROR;
	UINT8 cycle = 0;
	UINT16 tmpELMId = 0u;
	UINT8 relEnvelopeCnt = TRAIN_REL_ENVELOPE_SUM_MAX;    /*列车关联的包络数量*/
	UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] = {0u};  /*列车关联的包络索引*/
	const EnvelopeStruct* pRealUCTELM = NULL;                /* 与列车位置对应的包络 */
	
	UINT32 errorCode = 0u;           /* 错误码 */
	UINT8 szFlag[TRAIN_REL_ENVELOPE_SUM_MAX] = { 0u };
	
	/** 获取UCT包络关联的包络个数和Id */
	relEnvelopeCnt = elm_GetRelELIdByTrainIDAndType(TYPE_UCT_ENVELOPE,trainid,relEnvelopeID);

	/** 获取恢复通信的列车位置是否有效*/
	funRtn = elm_PrepareTrainPosValid(trainid);

	if ((0u == relEnvelopeCnt) || (TRAIN_REL_ENVELOPE_SUM_MAX == relEnvelopeCnt))
	{
		/** 不可能产生的场景*/
		errorCode += 0x80000000u;
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT%d recoveer error!",errorCode,trainid);
	}
	else if (CI_ERROR == funRtn)
	{
		/** 列车通信恢复，但是位置无效*/
		ELM_LOG(ELM_LOG_FATAL,"info:UCT%d recoveer error by Pos unvalid!.\n",trainid);
	}
	else
	{
		/** 从列车关联的包络中找到与位置对应的包络信息 */
		pRealUCTELM = elm_GetUCTRealEnvelope(trainid,relEnvelopeCnt,relEnvelopeID);
		ASSER_ERROR(NULL == pRealUCTELM,errorCode,0x40000000u);

		if (NULL != pRealUCTELM)
		{
			tmpELMId = pRealUCTELM->id;

			/** 将匹配的包络进行拆分 */
			funRtn = elm_UCTEnvelopeSplit(trainid,pRealUCTELM);
			ASSER_ERROR(NULL == pRealUCTELM,errorCode,0x20000000u);

			/** 将恢复车从其他UCT包络中删除 */
			for (cycle = 0u; cycle < relEnvelopeCnt; cycle++)
			{
				if (relEnvelopeID[cycle] != tmpELMId)
				{
					funRtn = elm_DeleteTrainFromSeq(relEnvelopeID[cycle],trainid);
					ASSERT_BREAK(CI_ERROR == funRtn,errorCode,0x10000000u);
				}
			}
		}
		else
		{
			/** 查询失败，导向安全侧，列车相关的UCT包络导向安全侧处理 */
			funRtn = elm_UCTRecoverCheckElmNear(trainid, szFlag, relEnvelopeCnt, relEnvelopeID);
		}
		
		if (0u == errorCode)
		{
			/** 处理正确*/
		}
		else
		{
			ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT%d recoveer error!",errorCode,trainid);

			for (cycle = 0u; cycle < relEnvelopeCnt; cycle++)
			{
				if ((CI_SUCCESS == funRtn) && (FLAG_SET == szFlag[cycle]))
				{/* 说明包络位置不包含列车位置，为跨控区包络越过分界点恢复场景，直接删除包络，不处理相邻包络。 */
					funRtn = elm_DeleteCTOrUCTUndoSuspic(relEnvelopeID[cycle]);
				}
				else
				{
					funRtn = elm_DeleteCTOrUCTEnvelope(relEnvelopeID[cycle]);
				}
				
				ASSERT_BREAK(CI_ERROR == funRtn,errorCode,0x08000000u);
			}

			if (cycle == relEnvelopeCnt)
			{
				/** 导向安全侧处理成功*/
			}
			else
			{
				/** 包络模块无法正常处理 */
				elm_SetELMWorkFlag(ELM_WORK_ERROR);
				ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:UCT%d recover error to reset!",errorCode,trainid);
			}
		}
	}
}

/**
* @brief UCT恢复时，判断相邻包络是否为本车包络。
* @param[in] const UINT16 trainId 恢复UCT列车ID
* @param[in] const UINT8 chEnvelopeCount 基准包络数量
* @param[in] const UINT16 szEnvelopeId[TRAIN_REL_ENVELOPE_SUM_MAX] 基准包络ID
* @param[out] OUT UINT8 szFlag[TRAIN_REL_ENVELOPE_SUM_MAX] 是否需要处理结果
* @param[out] 无
* @return CI_SUCCESS 处理成功
*         CI_ERROR 处理失败
* @note 无
*/
static UINT8 elm_UCTRecoverCheckElmNear(const UINT16 trainId, OUT UINT8 szFlag[TRAIN_REL_ENVELOPE_SUM_MAX], const UINT8 chEnvelopeCount, const UINT16 szEnvelopeId[TRAIN_REL_ENVELOPE_SUM_MAX])
{

	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRet = CI_ERROR;
	const EnvelopeStruct* pTempPre = NULL;
	const EnvelopeStruct* pTempBack = NULL;
	UINT16 preEnvelopeid = 0u;
	UINT16 backEnvelopeid = 0u;
	UINT8 ii = 0u;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == szFlag, ret, 0x80000000u);
	ASSERT_RET_VALUE(NULL == szEnvelopeId, ret, 0x40000000u);

	for (ii = 0u; ii < chEnvelopeCount; ii++)
	{
		/** 查询包络的前方和后方包络*/
		funRet = elm_GetNearestEnvelope(szEnvelopeId[ii], &preEnvelopeid, &backEnvelopeid);

		/** 判断否查询成功*/
		if (CI_SUCCESS == funRet)
		{
			/*- 相邻包络*/
			pTempPre = elm_GetEnvelopeInfoPtr(preEnvelopeid);
			
			/*- 相邻包络*/
			pTempBack = elm_GetEnvelopeInfoPtr(backEnvelopeid);

			if (((NULL != pTempPre) && (trainId == pTempPre->trainID[0]))
				|| ((NULL != pTempBack) && (trainId == pTempBack->trainID[0])))
			{
				szFlag[ii] = FLAG_SET;
			}
			else
			{
				; /** 无需处理 */
			}
		}
		else
		{
			/** 查询前后车错误 */
			ASSERT_BREAK(CI_ERROR == funRet, errorCode, 0x20000000u);
		}
	}
	ASSERT_SETRET(ii == chEnvelopeCount, ret, CI_SUCCESS, CI_ERROR);

	/**处理返回 */
	ASSER_DEBUG(0u != errorCode, ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:UCT Recover Check Envelope Near error.", errorCode));
	return ret;
}

/**
 * @brief 根据全线通信车信息检查UCT转UKT条件是否满足
 * @param[in] const EnvelopeStruct* ptemp 包络信息指针
 * @param[out] 无
 * @return CI_ERROR 0 条件不满足
 *         CI_SUCCESS 1 条件满足
 * @note Created By LQ 2024.07.14
 */
static UINT8 elm_UCTToUKTCheck(const EnvelopeStruct* ptemp)
{
	UINT8 cRetVal = CI_ERROR;
	UINT8 ii = 0U;
	UINT8 cIsOwnFlag = ELM_BELONG_OWNER;  /*包络属于本控区标志*/
	LineCommTrainStruct strLineCommTrain = { 0U };  /*全线通信车结构体*/
	UINT8 cTimeCheckFlag = CI_TIME_NO;
	UINT32 dwRcAndTmcTransBadEnsureCnt = 0U;  /*RC与TMC通信中断判断时间*/
	UINT32 dwCurCycNum = 0U;  /*当前系统周期号*/
	UINT8 cFunRtn = CI_ERROR;

	ASSERT_RET_VALUE(NULL == ptemp, cRetVal, 0x80000000U);

	cIsOwnFlag = elm_PrepareEnvelopeIsSelf(ptemp);

	if (ELM_BELONG_OTHER == cIsOwnFlag)
	{
		/*包络不属于本RC，无需处理*/
	}
	else
	{
		strLineCommTrain = GetLineCommTrainData();  /*获取全线通信车信息*/

		for (ii = 0U; ii < strLineCommTrain.cCommTrainNum; ii++)
		{
			if (strLineCommTrain.szCommTrainNumID[ii] == ptemp->trainID[0U])
			{
				dwRcAndTmcTransBadEnsureCnt = GetTiocAndTmcTransBadEnsureCnt();
				dwRcAndTmcTransBadEnsureCnt *= 2U;  /*使用两倍的通信中断时间*/
				cTimeCheckFlag = SystemOverTimeCheck(ptemp->dwUCTToUKTStartCycNum, dwRcAndTmcTransBadEnsureCnt);
				
				if (CI_TIME_NO == cTimeCheckFlag)
				{
					ELM_LOG(ELM_LOG_FATAL, "info:UCT[%d] To UKT Start.\n", ptemp->id);

					dwCurCycNum = Get2oo2CurCycleNum();
					cFunRtn = elm_SetUCTToUKTStartCycNum(ptemp->id, dwCurCycNum);  /*未计时，记录UCT转UKT起始周期为当前周期*/

					ASSER_DEBUG(CI_SUCCESS != cFunRtn, ELM_LOG_LOC(ELM_LOG_ERROR, "info:UCT[%d] To UKT Start Time[%d] Set Error!", ptemp->id, dwCurCycNum));
				}
				else if (CI_TIME_OUT == cTimeCheckFlag)
				{
					ELM_LOG(ELM_LOG_FATAL, "info:UCT[%d] To UKT TimeOut.\n", ptemp->id);
					cRetVal = CI_SUCCESS;  /*超时，可将UCT转为UKT，返回成功*/
				}
				else
				{
					/*未超时，不处理*/
				}
				break;
			}
			else
			{
				/*继续遍历*/
			}
		}

		/**** 检查计时过程中，UCT包络是否一直存在于全线通信车中 ****/
		if (0U != ptemp->dwUCTToUKTStartCycNum)
		{
			if ((0U != strLineCommTrain.cCommTrainNum) && (ii != strLineCommTrain.cCommTrainNum))
			{
				/*开始计时，且UCT包络存在于全线通信车中，不处理*/
			}
			else
			{
				cFunRtn = elm_SetUCTToUKTStartCycNum(ptemp->id, 0U);  /*开始计时，且UCT包络不存在于全线通信车中，清除UCT转UKT起始时间，返回失败*/
				ASSER_DEBUG(CI_SUCCESS != cFunRtn, ELM_LOG_LOC(ELM_LOG_ERROR, "info:UCT[%d] To UKT Start Time[%d] Set Error!", ptemp->id, 0U));
			}
		}
		else
		{
			/*未计时，不处理*/
		}
	}

	return cRetVal;
}

/**
* @brief 筛选删除UCT在筛选计轴部分后，UCT处理
* @param[in] const EnvelopeStruct* ptemp 包络信息指针
* @param[out] 无
* @return CI_ERROR 0 条件不满足
*         CI_SUCCESS 1 条件满足
* @note Created By LQ 2024.07.14
*/
UINT8 elm_ScreenUctCfpFreeProc(const EnvelopeStruct* ptemp)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 cycle = 0u;
	UINT8 cycleAC = 0u;
	UINT8 acCnt = 0u;
	UINT16 acIDBuff[CUTOFF_POINT_SUM_MAX] = { 0u };
	UINT8 acOccStatus = ELM_AC_OCC;
	UINT8 nextACCnt = 0u;
	UINT8 searchDir = 0u;
	UINT16 nextACIDBuff[AC_MAXCNT_IN_SWITCH] = { 0u };
	UINT16 OwnsideELMid = 0u;
	UINT16 OutsideELMid = 0u;
	UINT8 cDirChangePointFlag = DIRECTIONPOINT_FLAG_INVALID;

	/** 获取分界点处本OC范围的计轴区段*/
	acCnt = elm_PrepareCfpAc(acIDBuff);
	ASSER_ERROR(CUTOFF_POINT_SUM_MAX == acCnt, errorCode, 0x80000000u);

	for (cycle = 0u; cycle < acCnt; cycle++)
	{
		cDirChangePointFlag = DIRECTIONPOINT_FLAG_INVALID;  /*每遍历一次，清一次标志*/
		acOccStatus = elm_PrepareACStatus(acIDBuff[cycle]);
		if ((1U == ptemp->ACCnt) && (ptemp->ACID[0] == acIDBuff[cycle]) && (ELM_AC_FREE == acOccStatus))
		{/* UCT包络仅包含一个计轴区段，处在分界点，且分界点计轴区段空闲 */
			/** 查询分界点相邻OC的计轴区段，及查询到相邻OC区域计轴区段的方向 */
			nextACCnt = elm_PrepareCfpOtherTiocAc(acIDBuff[cycle], &searchDir, nextACIDBuff, &cDirChangePointFlag);
			ASSERT_BREAK(UINT8_MAX == nextACCnt, errorCode, 0x40000000u);

			/** 查询相邻计轴区段是否占用 */
			for (cycleAC = 0u; cycleAC < nextACCnt; cycleAC++)
			{
				/** 获取计轴的占用*/
				acOccStatus = elm_PrepareACStatus(nextACIDBuff[cycleAC]);
				ASSERT_BREAK(ELM_AC_OCC == acOccStatus, errorCode, 0x00000000u);
			}

			if (cycleAC == nextACCnt)
			{
				/** 相邻计轴空闲，无需处理 */
			}
			else
			{
				/** 查询分界点附近最接近的列车 */
				funRtn = elm_SearchNearstTrainInCutPoint(acIDBuff[cycle], searchDir, nextACCnt, nextACIDBuff, &OwnsideELMid, &OutsideELMid, cDirChangePointFlag);
				ASSERT_BREAK(CI_ERROR == funRtn, errorCode, 0x20000000u);

				if (CI_SUCCESS == funRtn)
				{
					/** UCT切换完成处理 */
					elm_HandleUCTHandoverFinished(acIDBuff[cycle], OwnsideELMid, OutsideELMid);
				}
				else
				{
					/** 相邻OC UCT跟踪失败，本OC暂时先处理成包络重置，后续再优化*/
				}
			}
		}
		else
		{
			; /* 不处理 */
		}
	}

	/** 设置函数返回值 */
	ASSERT_SETRET(0u == errorCode, ret, CI_SUCCESS, CI_ERROR);
	ASSER_DEBUG(0u != errorCode, ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:Screen UCT Envelope Cfp Process error.\n", errorCode));
	return ret;
}