/******************************************************************************
** 文件名:  EnvelopeLogicProcess.c
** 描 述:   实现包络逻辑处理（主要实现公用函数的定义）
*******************************************************************************/

#include "ELMDataPrepare.h"
#include "EnvelopeLogicProcess.h"
#include "AxisAssertManageAPI.h"
#include "dsuEmapDefine.h"
#include "DeviceDataManage.h"
#include "WholeLineScreenAPI.h"
#include "WLScreenDataManage.h"
#include "Convert.h"



/*================================静态函数声明区==============================*/
static UINT8 elm_UKTAdjacentSwProtect(void);     /** UKT包络相邻岔区防护 */ 
static UINT8 elm_UTLosingProtect(void);              /* UT车丢车防护*/
static UINT8 elm_ACRelEnvelopeCheck(void);     /** 计轴关联包络映射表合法性校验 */
static void elm_FlyingProtect(void);        /* UCT/CT车飞车防护*/

static UINT16 elm_GetEnvelopTailACIDs(IN const EnvelopeStruct* pEnvelop,OUT UINT16 acID[AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH]);   /* 获取包络尾后方计轴 */
static UINT16 elm_GetEnvelopHeadACIDs(IN const EnvelopeStruct* pEnvelop,OUT UINT16 acID[AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH]);   /* 获取包络尾前方计轴 */


/**
 * @brief 静态函数：UKT包络相邻岔区防护
 * @param[in] 无
 * @param[out] 无
 * @return CI_ERROR 处理错误，返回失败
           CI_SUCCESS 处理正确，返回成功
 * @note 
 */
static UINT8 elm_UKTAdjacentSwProtect(void)
{
	UINT8 ret = CI_ERROR;
	UINT8 funRet = CI_ERROR;
	UINT16 cycleAc = 0u;  
	UINT8 OCId = 0u;
	UINT8 isSwitchZoneFlag = CI_SUCCESS;
	UINT8 passTrainFlag = AAM_CT_PASS;
	UINT16 acCnt = 0u;                             /*OC范围内所有的计轴区段数量*/
	const UINT16 *pACIdbuff = NULL;        /** 计轴ID数值缓存 */
	UINT32 errorCode = 0u;
	UINT8 acRelPhyOCC = SECTION_OCCUPY_YES;
	UINT8 nearTrainType = AAM_BAD_NEAR;
	UINT8 acSameCnt = 0u;
	UINT8 acConvertCnt = 0u;
	UINT16 acSameID[AC_MAXCNT_IN_SWITCH] = {0u};
	UINT16 acConvertID[AC_MAXCNT_IN_SWITCH] = {0u};
	UINT8 cDirectionPointFlag = 0U;			/*是否具有方向变化点标志*/


	/** 获取OC范围内所有的计轴区段数组索引 */
	acCnt = elm_PrepareACBuffIndexs(&pACIdbuff);
	ASSER_ERROR(NULL == pACIdbuff,errorCode,0x80000000u);

	if (NULL == pACIdbuff)
	{
		/** 不可能分支*/
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:AC search error.",errorCode);
	}
	else
	{
		for (cycleAc = 0u; cycleAc < acCnt;cycleAc++)
		{
			/** 判断计轴区段是否属于本OC */
			funRet = elm_PrepareACIsSelf(pACIdbuff[cycleAc],&OCId);

			if (ELM_BELONG_OTHER == funRet)
			{
				/** 不属于本OC，不处理 */
			}
			else
			{
				/** 计轴是否为岔区 */
				isSwitchZoneFlag = elm_PrepareACIsSwitchZone(pACIdbuff[cycleAc]);

				/** 获取好车通过标志位 */
				passTrainFlag = elm_PreparACRelPhyPasTrainFlag(pACIdbuff[cycleAc]);

				/** 查询计轴所属物理区段是否占用 */
				acRelPhyOCC = elm_PrepareACRelPhyStatus(pACIdbuff[cycleAc]);

				/** 如果计轴属于岔区且为好车通过 */
				if ((CI_SUCCESS == isSwitchZoneFlag) && (AAM_CT_PASS == passTrainFlag) && (SECTION_OCCUPY_YES == acRelPhyOCC)) 
				{
					/** 查询前方计轴*/
					acSameCnt = elm_PrepareAdjacentAC(pACIdbuff[cycleAc], EMAP_SAME_DIR, acSameID, &cDirectionPointFlag);

					/** 查询后方计轴 */
					acConvertCnt = elm_PrepareAdjacentAC(pACIdbuff[cycleAc], EMAP_CONVER_DIR, acConvertID, &cDirectionPointFlag);

					/** 判断是否查询成功 */
					ASSERT_SETRET((UINT8_MAX == acSameCnt) || (UINT8_MAX == acConvertCnt),errorCode,0x40000000u,0U);
					
					if (0u != errorCode)
					{
						nearTrainType = AAM_BAD_NEAR;
						errorCode = 0u;
					}
					else
					{
						/** 查询前方计轴接近车类型*/
						nearTrainType = aam_SearchNearbyTrainType(pACIdbuff[cycleAc], EMAP_SAME_DIR, acSameCnt, acSameID);
					}

					if ((AAM_BAD_NEAR == nearTrainType)|| (AAM_SLEEP_OCC == nearTrainType))
					{
						elm_PrepareClearSwPassTrainFlag(pACIdbuff[cycleAc]);
						ELM_LOG(ELM_LOG_FATAL,"info:Switch Zone AC%d Clear CT pass flag by PreAC UT.\n",pACIdbuff[cycleAc]);
					}
					else
					{
						/** 查询前方计轴接近车类型*/
						nearTrainType = aam_SearchNearbyTrainType(pACIdbuff[cycleAc],EMAP_CONVER_DIR,acConvertCnt,acConvertID);

						if ((AAM_BAD_NEAR == nearTrainType) || (AAM_SLEEP_OCC == nearTrainType))
						{
							elm_PrepareClearSwPassTrainFlag(pACIdbuff[cycleAc]);
							ELM_LOG(ELM_LOG_FATAL,"info:Switch Zone AC%d Clear CT pass flag by backAC UT.\n",pACIdbuff[cycleAc]);
						}
						else
						{
							/** 无坏车接近，不处理 */
						}
					}
				}
				else
				{
					/** 无需处理 */
				}
			}
		}

		/** 设置函数返回值*/
		ASSERT_SETRET(cycleAc == acCnt,ret,CI_SUCCESS,CI_ERROR);
		ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:AC%d search Adjacent AC info error.",errorCode,pACIdbuff[cycleAc]));
	}

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

/**
 * @brief 静态函数：UT车飞车或者丢车防护
 * @param[in] 无
 * @param[out] 无
 * @return CI_ERROR 处理错误，返回失败
           CI_SUCCESS 处理正确，返回成功
 * @note 
 */
static UINT8 elm_UTLosingProtect(void)
{
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 funRet = CI_ERROR;
	UINT8 checkFlag = CI_ERROR;
	UINT16 cycleAc = 0u;  
	UINT8 tmpACStatus = ELM_AC_FREE;
	UINT8 OCId = 0u;
	UINT16 acCnt = 0u;                             /*OC范围内所有的计轴区段数量*/
	UINT16 tmpAcIndex = 0u;
	const UINT16 *pACIdbuff = NULL;        /** 计轴ID数值缓存 */
	UINT8 acRelEnvelopeCnt = 0u;
	UINT8 acAssertStatus = AAM_API_AC_UT;
	UINT16 acRelEnvelopeID[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};

	/** 获取OC范围内所有的计轴区段数组索引 */
	acCnt = elm_PrepareACBuffIndexs(&pACIdbuff);
	ASSER_ERROR(NULL == pACIdbuff,errorCode,0x08000000u);

	if (NULL == pACIdbuff)
	{
		/** 不可能分支*/
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:AC search error.",errorCode);
	}
	else
	{
		for (cycleAc = 0u; cycleAc < acCnt;cycleAc++)
		{
			/** 判断计轴区段是否属于本OC */
			funRet = elm_PrepareACIsSelf(pACIdbuff[cycleAc],&OCId);

			if (ELM_BELONG_OTHER == funRet)
			{
				/** 不属于本OC，不处理 */
			}
			else
			{
				/** 获取计轴状态 */
				tmpACStatus = elm_PrepareACStatus(pACIdbuff[cycleAc]);

				if (ELM_AC_OCC == tmpACStatus)
				{
					/** 通过计轴数组索引查找计轴索引*/
					tmpAcIndex = elm_PrepareACIndex(pACIdbuff[cycleAc]);

					/** 通过计轴数组索引获取关联的包络个数 */
					acRelEnvelopeCnt = elm_GetACRelEnvelopeCnt(tmpAcIndex, acRelEnvelopeID);
					ASSERT_BREAK(SECTION_REL_ENVELOPE_SUM_MAX == acRelEnvelopeCnt,errorCode,0x04000000u);

					/** 获取计轴诊断状态 */
					acAssertStatus = elm_PrepareACAssertStatus(pACIdbuff[cycleAc]);

					if (acRelEnvelopeCnt > 0u)
					{
						/** 占用计轴存在包络，认为正确*/
					}
					else if ((AAM_API_AC_ARB == acAssertStatus) || (AAM_API_AC_REDUNARB == acAssertStatus) || (AAM_API_AC_REDUNUT == acAssertStatus))
					{
						/** 计轴ARB或者冗余期间，不处理*/
					}
					else
					{
						/** 判断计轴是否当周期占用无包络，尝试先进入冗余*/
						checkFlag = aam_CheckACEnterRedun(pACIdbuff[cycleAc]);

						if (CI_ERROR == checkFlag)
						{
							aam_SetACEnterRedun(pACIdbuff[cycleAc]);
							ELM_LOG(ELM_LOG_FATAL,"info:AC%d Enter Redun.",pACIdbuff[cycleAc]);
						}
						else
						{
							/** 如果计轴占用无包络且未冗余，则故障 */
							ASSERT_BREAK(ELM_AC_OCC == tmpACStatus,errorCode,0x02000000u);	
						}										
					}					
				}
				else
				{
					/** 计轴空闲，不处理*/
				}

			}
		}

		/** 设置函数返回值*/
		ASSERT_SETRET(cycleAc == acCnt,ret,CI_SUCCESS,CI_ERROR);
		ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:AC%d UKT ELM Lose.",errorCode,pACIdbuff[cycleAc]));
	}

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

/**
 * @brief 静态函数：计轴关联包络映射表合法性校验
 * @param[in] 无
 * @param[out] 无
 * @return CI_ERROR 处理错误，返回失败
           CI_SUCCESS 处理正确，返回成功
 * @note 
 */
static UINT8 elm_ACRelEnvelopeCheck(void)
{
	UINT8 ret = CI_ERROR;
	UINT8 funRet = CI_ERROR;
	UINT16 cycleAc = 0u;  
	UINT8 cycleElm = 0u;
	const EnvelopeStruct *pTemp = NULL;
	UINT8 OCId = 0u;
	UINT16 acCnt = 0u;                             /*OC范围内所有的计轴区段数量*/
	UINT16 tmpAcIndex = 0u;
	const UINT16 *pACIdbuff = NULL;        /** 计轴ID数值缓存 */
	UINT8 acRelEnvelopeCnt = 0u;
	UINT16 acRelEnvelopeID[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	UINT32 errorCode = 0u;

	/** 获取OC范围内所有的计轴区段数组索引 */
	acCnt = elm_PrepareACBuffIndexs(&pACIdbuff);
	ASSERT_RET_VALUE(NULL == pACIdbuff,ret,0x80000000u);

	for (cycleAc = 0u; cycleAc < acCnt;cycleAc++)
	{
		/** 判断计轴区段是否属于本OC */
		funRet = elm_PrepareACIsSelf(pACIdbuff[cycleAc],&OCId);

		if (ELM_BELONG_OTHER == funRet)
		{
			/** 不属于本OC，不处理 */
		}
		else
		{
			/** 通过计轴数组索引查找计轴索引*/
			tmpAcIndex = elm_PrepareACIndex(pACIdbuff[cycleAc]);

			/** 通过计轴数组索引获取关联的包络个数 */
			acRelEnvelopeCnt = elm_GetACRelEnvelopeCnt(tmpAcIndex, acRelEnvelopeID);
			ASSERT_BREAK(SECTION_REL_ENVELOPE_SUM_MAX <= acRelEnvelopeCnt,errorCode,0x40000000u);

			for(cycleElm = 0u; cycleElm < acRelEnvelopeCnt;cycleElm++)
			{
				pTemp = elm_GetEnvelopeInfoPtr(acRelEnvelopeID[cycleElm]);
				ASSERT_BREAK(NULL == pTemp,errorCode,0x00000000u);
			}

			/** 判断计轴上关联的包络是否都存在 */
			ASSERT_BREAK(cycleElm != acRelEnvelopeCnt,errorCode,0x40000000u);
		}
	}

	/** 设置函数返回值*/
	ASSERT_SETRET(cycleAc == acCnt,ret,CI_SUCCESS,CI_ERROR);
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:AC%d Rel ELM lose.",errorCode,pACIdbuff[cycleAc]));

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

/**
 * @brief 静态函数：CT车飞车防护
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 
 */
static void elm_FlyingProtect(void)
{
	/*- 局部变量定义 */
	UINT16 cycle = 0u;    /*循环变量*/
	UINT8 maxShutdownRedunTime = 0u;
	UINT8 chCTCheck = CI_ERROR; /*CT车检查结果*/
	UINT16 trainCnt = 0U; /*列车总数*/
	UINT16 ii = 0U;
	UINT32 dwCurCyc = Get2oo2CurCycleNum();
	UINT32 dwFlyStartCyc = 0U;
	UINT16 wTrainId = 0U;
	UINT8 chTimeCheck = 0u;
	UINT32 dwFlyOverCyc = 0U;
	UINT8 cNvramFlag = 0U;  /*列车使用NVRAM标志*/
	UINT8 cPosMonistorState = 0U;  /*列车位置监督状态*/
	UINT8 cFuncSwitch = 0U;  /*使用NVRAM位置且位置监督无效的列车飞车不宕机开关：0xAA-飞车不宕机 0x55-飞车宕机*/

	/*周期清除使用NVRAM位置且位置监督无效的飞车信息*/
	ClearNvramFlyingTrain();

	chCTCheck = elm_FlyingProtect_CT(); /*检查CT飞车*/
	elm_FlyingProtect_UCT();/*UCT包络飞车删除为UKT*/

	trainCnt = GetTrainSum();
	/** 飞车宕机防护 */
	if (CI_SUCCESS == chCTCheck)
	{
		/** 未飞车，清除飞车宕机冗余计时 */
	}
	else
	{
		/** 获取数据配置的飞车宕机最大冗余时间 */
		maxShutdownRedunTime = elm_PrepareCTFlyingRedunTime();
		cFuncSwitch = GetCiFunctionSwitchConfig(FUNC_NVRAM_TRAIN_FlYING_OVER);
		for (ii = 0U; ii < trainCnt; ii++)
		{
			wTrainId = GetTrainId(ii);
			if (0U != wTrainId)
			{
				dwFlyStartCyc = GetTrainStartFlyProtectCycNum(wTrainId);
				chTimeCheck = SystemOverTimeCheck(dwFlyStartCyc, (UINT32)maxShutdownRedunTime);

				if (CI_TIME_OUT== chTimeCheck)
				{
					cNvramFlag = GetTrainNvramPosFlag(wTrainId);
					cPosMonistorState = GetTrainPosMonitorState(wTrainId);
					if ((TRAIN_NVRAM_POS_FLAG_YES == cNvramFlag) && (TRAIN_POS_MONITOR_VALID != cPosMonistorState) && (FUNC_SWITCH_ON == cFuncSwitch))
					{
						/*使用NVRAM位置且位置监督无效的列车飞车后，若NVRAM列车飞车不宕机开关打开，RC仅向列车发飞车特控报文，不宕机*/
					}
					else
					{
						SetFlyProtectOverCyc(dwCurCyc); /*飞车标志*/
					}
				}
				else
				{
					; /*未超过冗余时间或列车通信中断*/
				}
			}
		}
	}

	dwFlyOverCyc = GetFlyProtectOverCyc();
	chTimeCheck = SystemOverTimeCheck(dwFlyOverCyc, SHUT_DOWN_ALARM_TIME);
	if (CI_TIME_NO != chTimeCheck)
	{
		debug_infor_printf((const)"\n GATEWAY_FLY_SHUT_DOWN . StartCyc_:%d _CurCyc_:%d\n", dwFlyOverCyc, dwCurCyc);
		if (CI_TIME_OUT == chTimeCheck)
		{
			SetPlatOverFlag();/*报警时间到 设置宕机标志*/
		}
	}
	else
	{
		; /*不宕机*/
	}
}

/**
 * @brief 静态函数：获取包络尾后方计轴
 * @param[in] 
 * @param[out]
 * @return 
 * @note 如果包络所在计轴区段为岔区，如果道岔四开，则车尾计轴可能为多个
 */
static UINT16 elm_GetEnvelopTailACIDs(IN const EnvelopeStruct* pEnvelop,OUT UINT16 acID[AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH])
{
	UINT16 ret = UINT16_MAX;
	UINT8 cycle = 0u;
	UINT16 tmpPhyId = 0u;
	UINT16 ACrelPhyId = 0;
	UINT16 tmpACCnt = 0u;
	UINT16 tmpACId[AC_MAXCNT_IN_SWITCH] = {0u};
	UINT16 tmpSearchACCnt = 0u;
	UINT16 tmpSearchACId[AC_MAXCNT_IN_SWITCH] = {0u};
	UINT16 mergeACIndex = 0u;
	UINT8 cDirectionPointFlag = 0U;			/*是否具有方向变化点标志*/

	/*_ 入口参数检查 */
	ASSERT_RET_VALUE(NULL == pEnvelop,ret,0x80000000u);
	ASSERT_RET_VALUE(NULL == acID,ret,0x40000000u);

	/** 查询包络尾所属物理区段ID*/
	ACrelPhyId = elm_PrepareACRelPhyId(pEnvelop->ACID[0u]);
	tmpACId[tmpACCnt++] = pEnvelop->ACID[0u];

	if (0u == ACrelPhyId)
	{
		/** 数据错误*/
	}
	else
	{
		/*_ 第一步，遍历包络尾同属同一物理区段的计轴区段*/
		for (cycle = 1u; cycle < pEnvelop->ACCnt; cycle++)
		{
			tmpPhyId = elm_PrepareACRelPhyId(pEnvelop->ACID[cycle]);

			if (ACrelPhyId == tmpPhyId)
			{
				tmpACId[tmpACCnt++] = pEnvelop->ACID[cycle];
			}
			else
			{
				/** 不同属于同一物理区段*/
				break;
			}
		}


		/*_ 第二步，查找车尾后方计轴 */
		for (cycle = 0u; cycle < tmpACCnt; cycle++)
		{
			/* 查询后方计轴*/
			tmpSearchACCnt = elm_PrepareAdjacentAC(tmpACId[cycle], (UINT8)(~(pEnvelop->startPos.Dir)), tmpSearchACId, &cDirectionPointFlag);

			if (AC_MAXCNT_IN_SWITCH >=  tmpSearchACCnt)
			{
				/** 合并车尾后方的计轴 */
				mergeACIndex = elm_PrepareMergeUINT16Array(acID,(UINT16)(AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH),mergeACIndex,tmpSearchACId,AC_MAXCNT_IN_SWITCH,tmpSearchACCnt);
			}
			else
			{
				break;
			}
		}


		/** 设置函数返回值*/
		if ((cycle == tmpACCnt) && ((UINT16)(AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH) >= mergeACIndex))
		{
			ret = mergeACIndex;
		}
		else
		{
			/** 处理错误*/
		}
	}
	
	return ret;
}

/**
 * @brief 静态函数：获取包络尾后方计轴
 * @param[in] 
 * @param[out]
 * @return 
 * @note 如果包络所在计轴区段为岔区，如果道岔四开，则车尾计轴可能为多个
 */
static UINT16 elm_GetEnvelopHeadACIDs(IN const EnvelopeStruct* pEnvelop,OUT UINT16 acID[AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH])
{
	UINT16 ret = UINT16_MAX;
	UINT8 cycle = 0u;
	UINT16 tmpPhyId = 0u;
	UINT16 ACrelPhyId = 0u;
	UINT16 tmpACCnt = 0u;
	UINT16 tmpACId[AC_MAXCNT_IN_SWITCH] = {0u};
	UINT16 tmpSearchACCnt = 0u;
	UINT16 tmpSearchACId[AC_MAXCNT_IN_SWITCH] = {0u};
	UINT16 mergeACIndex = 0u;
	UINT8 cDirectionPointFlag = 0U;			/*是否具有方向变化点标志*/

	/*_ 入口参数检查 */
	ASSERT_RET_VALUE(NULL == pEnvelop,ret,0x80000000u);
	ASSERT_RET_VALUE(NULL == acID,ret,0x40000000u);
	ASSERT_RET_VALUE(0u == pEnvelop->ACCnt,ret,0x20000000u);


	/** 查询包络尾所属物理区段ID*/
	ACrelPhyId = elm_PrepareACRelPhyId(pEnvelop->ACID[pEnvelop->ACCnt - 1u]);
	tmpACId[tmpACCnt++] = pEnvelop->ACID[pEnvelop->ACCnt - 1u];

	if (0u == ACrelPhyId)
	{
		/** 数据错误*/
	}
	else
	{
		/*_ 第一步，遍历包络头同属同一物理区段的计轴区段*/
		for (cycle = 1u; cycle < pEnvelop->ACCnt; cycle++)
		{
			tmpPhyId = elm_PrepareACRelPhyId(pEnvelop->ACID[pEnvelop->ACCnt - cycle - 1u]);

			if (ACrelPhyId == tmpPhyId)
			{
				tmpACId[tmpACCnt++] = pEnvelop->ACID[pEnvelop->ACCnt - cycle - 1u];
			}
			else
			{
				/** 不同属于同一物理区段*/
				break;
			}
		}


		/*_ 第二步，查找车头前方计轴 */
		for (cycle = 0u; cycle < tmpACCnt; cycle++)
		{
			/* 查询前方计轴*/
			tmpSearchACCnt = elm_PrepareAdjacentAC(tmpACId[cycle], pEnvelop->endPos.Dir, tmpSearchACId, &cDirectionPointFlag);

			if (AC_MAXCNT_IN_SWITCH >=  tmpSearchACCnt)
			{
				/** 合并车头前方的计轴 */
				mergeACIndex = elm_PrepareMergeUINT16Array(acID,AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH,mergeACIndex,tmpSearchACId,AC_MAXCNT_IN_SWITCH,tmpSearchACCnt);
			}
			else
			{
				break;
			}
		}


		/** 设置函数返回值*/
		if ((cycle == tmpACCnt) && ((AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH) >= mergeACIndex))
		{
			ret = mergeACIndex;
		}
		else
		{
			/** 处理错误*/
		}
	}
	
	return ret;
}

/**
 * @brief 获取指定计轴范围范围内的包络信息
 * @param[in] const UINT16 acID[] 计轴区段数组
 * @param[in] UINT8 acCnt 计轴区段数量
 * @param[out] UINT16 envelopeID[TRAIN_SUM_MAX_IN_OC] 包络ID存储区
 * @return TRAIN_SUM_MAX_IN_OC 执行错误
		   0 ~ TRAIN_SUM_MAX_IN_OC 执行成功
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_MergeEnvelope(IN const UINT16 acID[], UINT8 acCnt, INOUT UINT16 envelopeID[TRAIN_SUM_MAX_IN_OC])
{
	/*- 具备变量定义 */
	UINT8 ret = TRAIN_SUM_MAX_IN_OC;
	UINT8 cycle = 0u;
	UINT16 mergeIndex = 0u;
	UINT8 merCnt = 0u;
	UINT8 acRelEnvelopeCnt = 0u;
	UINT16 acRelEnvelopeID[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	UINT16 tempACIndex = 0u;
	UINT32 errorCode = 0u;                         /*错误码*/

	/** 入口参数校验 */
	if ((NULL == acID) || (NULL == envelopeID) || (0u == acCnt))
	{
		/** 入口参数错误*/
		errorCode += 0x08000000u;
	}
	else
	{
		/** 清空*/
		for (cycle = 0u;cycle < TRAIN_SUM_MAX_IN_OC;cycle++)
		{
			envelopeID[cycle] = ENVELOPE_UNVAILD_INDEX;
		}

		/** 遍历所有计轴 */
		for (cycle = 0u;cycle < acCnt; cycle++)
		{
			/** 通过计轴ID获取计轴索引 */
			tempACIndex = elm_PrepareACIndex(acID[cycle]);

			/** 获取计轴上关联的包络 */
			acRelEnvelopeCnt = elm_GetACRelEnvelopeCnt(tempACIndex,acRelEnvelopeID);

			/** 判断是否需要跳出循环 */
			ASSERT_BREAK(SECTION_REL_ENVELOPE_SUM_MAX == acRelEnvelopeCnt,errorCode,0x04000000u);

			/** 累加包络 */
			merCnt = merCnt + acRelEnvelopeCnt;

			/** 判断是否满足跳出循环*/
			ASSERT_BREAK(merCnt > TRAIN_SUM_MAX_IN_OC,errorCode,0x02000000u);

			/** 合并包络 */
			mergeIndex = elm_PrepareMergeUINT16Array(envelopeID,TRAIN_SUM_MAX_IN_OC,mergeIndex,acRelEnvelopeID,SECTION_REL_ENVELOPE_SUM_MAX,acRelEnvelopeCnt);

			/** 判断是否满足跳出循环*/
			ASSERT_BREAK(mergeIndex != merCnt,errorCode,0x01000000u);
		}

		/** 设置返回值 */
		ASSERT_SETRET(cycle == acCnt,ret,merCnt,TRAIN_SUM_MAX_IN_OC);
	}

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


/**
 * @brief 获取包络相邻的包络
 * @param[in] UINT16 envelopeId
 * @param[out] UINT16 *preEnvelope 包络前方id
 * @param[out] UINT16 *backEnvelope 包络后方id
 * @return CI_ERROR 查询失败
           CI_SUCCESS 查询成功
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码修改
 */
UINT8 elm_GetNearestEnvelope(UINT16 envelopeId,OUT UINT16 *preEnvelope,OUT UINT16 *backEnvelope)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 funRet = CI_ERROR;
	UINT32 errorCode = 0u;                         /*错误码*/
	const EnvelopeStruct* pEnvelop = NULL;
	UINT8 envelopeCnt = 0u;     /* 包络数量 */
	UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] = {0u};  /*包络ID数组*/
	UINT16 acCnt = 0u;   /** 前方计轴数量*/
	UINT16 acID[AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH] = {0u};
	UINT8 acStatus = ELM_AC_OCC;
	UINT16 mergeACIndex = 0u;
	UINT16 mergeACCntMax = (SECTION_IN_ENVELOPE_SUM_MAX + 2U * AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH);
	UINT16 mergeACID[SECTION_IN_ENVELOPE_SUM_MAX + 2U * AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH] = {0u};
	UINT8 includeCnt = 0u;
	UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] = {0u};  /** 重合的包络id */

	/** 获取列车包络 */
	pEnvelop = elm_GetEnvelopeInfoPtr(envelopeId);

	/** 判断包络是否正确*/
	if ((NULL == pEnvelop) || (NULL == preEnvelope) || (NULL == backEnvelope))
	{
		/** 设置错误码*/
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x08000000u);
	}
	else
	{
		/** 获取车尾包络计轴占用状态 */
		acStatus = elm_PrepareACStatus(pEnvelop->ACID[0]);

		/** 判断包络尾是否占用，如果占用，则需要查询下一个计轴*/
		if (ELM_AC_OCC == acStatus)
		{
			/* 查询后方计轴，车尾计轴占用，存在道岔四开，为了确保能然后后端，需要查询安全车尾所属计轴的相邻计轴区段*/
			acCnt = elm_GetEnvelopTailACIDs(pEnvelop,acID);

			/** 合并车尾后方的计轴 */
			mergeACIndex = elm_PrepareMergeUINT16Array(mergeACID,mergeACCntMax,mergeACIndex,acID,(AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH),acCnt);

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

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

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

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

		if (0u == errorCode)
		{
			/** 获取车头包络计轴占用状态 */
			acStatus = elm_PrepareACStatus(pEnvelop->ACID[pEnvelop->ACCnt -1U]);

			/** 判断包络头是否占用，如果占用，则需要查询下一个计轴 */
			if (ELM_AC_OCC == acStatus)
			{
				/* 查询前方计轴,此处查询四开道岔的相邻计轴其实属于一个冗余的处理，因为如果车头压入了岔区且占用，直接进行了删车，但是此处再这样处理一个是为了统一设计，另外做一个冗余防护*/
				acCnt = elm_GetEnvelopHeadACIDs(pEnvelop,acID);

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

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

			}
			else
			{
				/** 无需处理*/
			}

			/** 判断是否处理成功 */
			if (0u == errorCode)
			{
				/** 获取前方计轴包含的包络 */
				envelopeCnt = elm_MergeEnvelope(mergeACID,(UINT8)mergeACIndex,arEnvelopID);

				/** 获取包络前后包络*/
				funRet = elm_SearchNearestEnvelope(pEnvelop,arEnvelopID,envelopeCnt,preEnvelope,backEnvelope,&includeCnt,includeELMid);

				/** 设置错误码*/
				ASSER_ERROR(CI_SUCCESS != funRet,errorCode,0x08000000u);
			}
			else
			{
				/** 查询错误 */
			}
		}
		else
		{
			/** 查询错误 */
		}
	}

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


/**
 * @brief 增加UKT包络
 * @param[in] UINT16 ACIndex 计轴区段索引
 * @param[in] LOD_STRU startPoint 起点位置
 * @param[in] LOD_STRU endPoint 终点位置
 * @return CI_SUCCESS 需要操作的内存区正确，返回成功
 *         CI_ERROR   需要操作的内存区错误，返回失败
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_AddUKTEnvelope(UINT16 ACIndex, LOD_STRU startPoint, LOD_STRU endPoint)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;    /* 函数返回值 */
	UINT8 funRet = CI_ERROR;
	UINT32 errorCode = 0u;                         /*错误码*/
	UINT16 buffIndex = ENVELOPE_UNVAILD_INDEX;    /** 包络缓存地址 */
	EnvelopeStruct tmpEnvelope = {0u};    /*包络临时变量*/

	/** 第一步：创建包络 */
	funRet = elm_CreateEnveLope(TYPE_UKT_ENVELOPE,LINE_MAX_TRAIN,startPoint,endPoint,0u,0u,&tmpEnvelope);
	ASSER_ERROR(CI_ERROR == funRet,errorCode,0x80000000u);

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

	/** 判断包络索引位置是否正确*/
	if (ENVELOPE_UNVAILD_INDEX != buffIndex)
	{
		/** 设置包络唯一标识*/
		tmpEnvelope.id = buffIndex;

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

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

		/** 维护日志--错误级别 */
		ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:UKT Add error.\n",errorCode));
	}
	else
	{
		/** 维护日志--错误级别 */
		ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:UKT create error.\n",errorCode));
	}

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

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


/**
 * @brief 删除指定UKT包络
 * @param[in] const EnvelopeStruct* pEnvelope 待删除的包络
 * @return CI_SUCCESS 需要操作的内存区正确，返回成功
 *         CI_ERROR   需要操作的内存区错误，返回失败
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_DeleteUKTEnvelope(IN const EnvelopeStruct* pEnvelope)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 funRet = CI_ERROR;
	UINT16 tmpACIndex = 0u;
	UINT32 errorCode = 0u;

	if ((NULL == pEnvelope) || (1U != pEnvelope->ACCnt))
	{
		/** 入口参数错误*/
		errorCode = errorCode + 0x01000000u;
	}
	else
	{
		/** 通过计轴ID获取计轴数组索引 */
		tmpACIndex = elm_PrepareACIndex(pEnvelope->ACID[0]);

		/** 创建计轴到包络的映射关系 */
		funRet = elm_SetACRelEnvelopeMap(OP_DEL,tmpACIndex,pEnvelope->id);
		errorCode = (CI_ERROR == funRet) ? (errorCode + 0x08000000u) : ((errorCode + 0x00000000u));

		/** 清空包络空间 */
		funRet = elm_ClearEnvelope(pEnvelope->id);
		errorCode = (CI_ERROR == funRet) ? (errorCode + 0x02000000u) : ((errorCode + 0x00000000u));		
	}

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

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

/**
 * @brief 删除计轴上关联的包络
 * @param[in] UINT8 acBelongFlag 计轴所属OC标志
 * @param[in] UINT16 AcID 计轴ID
 * @return CI_ERROR 处理错误
           CI_SUCCESS 处理正确
 * @note 
 *   1、此函数只能接受删除非本OC范围的计轴区段，否则返回失败
 *   2、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_DeleteACRelEnvelope(UINT8 acBelongFlag,UINT16 AcID)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 acRelEnvelopeCnt = 0u;
	UINT8 cycle = 0u;
	UINT8 cycleAC = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT16 tmpACindex = 0u;
	UINT32 errorCode = 0u;
	const EnvelopeStruct *pEnvelope = NULL;
	EnvelopeStruct acRelEnvelopeInfo[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};

	/** 判断计轴是否属于本OC */
	if (ELM_BELONG_OTHER == acBelongFlag)
	{
		/** 查询计轴上关联的包络 */
		acRelEnvelopeCnt = elm_CopyEnvelopeInAC(AcID,acRelEnvelopeInfo);
		ASSER_ERROR(SECTION_REL_ENVELOPE_SUM_MAX == acRelEnvelopeCnt,errorCode,0x80000000u)

		/** 判读是否查询成功 */
		if (0u == errorCode)
		{
			/** 获取计轴上的包络 */
			for (cycle = 0u; cycle < acRelEnvelopeCnt; cycle++)
			{
				/** 获取包络信息 */
				pEnvelope = &acRelEnvelopeInfo[cycle];

				/** 判断是否查询失败 */
				ASSERT_BREAK(NULL == pEnvelope, errorCode, 0x40000000u);

				/** 判断包络类型 */
				if ((TYPE_UKT_ENVELOPE == pEnvelope->envelopeType) && (1u == acRelEnvelopeCnt))
				{
					funRtn = elm_DeleteUKTEnvelope(pEnvelope);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);
				}
				else if ((TYPE_UCT_ENVELOPE == pEnvelope->envelopeType) || (TYPE_CT_ENVELOPE == pEnvelope->envelopeType))
				{
					/** 车身范围内的计轴，清除映射关系，并添加UKT包络（占用且无其他包络则添加）*/
					for (cycleAC = 0u; cycleAC < pEnvelope->ACCnt;cycleAC++)
					{
						/** 获取计轴索引 */
						tmpACindex = elm_PrepareACIndex(pEnvelope->ACID[cycleAC]);

						/** 清除映射关系 */
						(void)elm_SetACRelEnvelopeMap(OP_DEL,tmpACindex,pEnvelope->id);
					}
					/** 清空包络空间 */
					(void)elm_ClearEnvelope(pEnvelope->id);
				}
				else
				{
					/** 不可能分支*/
					ASSER_ERROR(NULL == pEnvelope,errorCode,0x10000000u)
				}
			}

			/** 打印错误信息 */
			ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Delete Ac%d rel envelope error.",errorCode,AcID))
		}
		else
		{
			/** 查询错误*/
			ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Get ACID%d rel envelope info error!",errorCode,AcID)
		}
	}
	else
	{
		/** 不属于相邻OC，不处理 */
	}

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

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


/**
 * @brief 计轴上添加故障包络
 * @param[in] UINT16 acID
 * @param[out]
 * @return CI_ERROR 处理失败
           CI_SUCCESS 处理成功
 * @note 
 *   1、此函数实现在占用且无包络的计轴上添加故障包络
 *   2、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_AddUKTEnvelopeInAC(UINT16 acID)
{
	/*- 局部变量定义*/
	UINT8 ret = CI_ERROR;
	UINT8 funFlag = CI_ERROR;
	UINT16 tmpAcIndex = 0u; 
	UINT8 tmpStatus = ELM_AC_OCC;
	UINT8 acRelEnvelopeCnt = 0u;
	UINT16 acRelEnvelopeID[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	UINT32 errorCode = 0u;
	ELM_AxisLocStruct tmpLoc = {0u};

	/** 通过计轴区段ID获取计轴状态*/
	tmpStatus = elm_PrepareACStatus(acID);

	if (ELM_AC_OCC == tmpStatus)
	{
		/** 通过计轴数组索引查找计轴索引*/
		tmpAcIndex = elm_PrepareACIndex(acID);

		/** 通过计轴数组索引获取关联的包络个数 */
		acRelEnvelopeCnt = elm_GetACRelEnvelopeCnt(tmpAcIndex, acRelEnvelopeID);

		/** 查找包络是否正确*/
		if (SECTION_REL_ENVELOPE_SUM_MAX == acRelEnvelopeCnt)
		{
			errorCode = (CI_ERROR == funFlag) ? (errorCode + 0x80000000u) : ((errorCode + 0x00000000u));

			/** 维护日志--错误级别*/
			ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:ac%d rel envelope cnt error,acIndex:%d",errorCode,acID,tmpAcIndex))
		}
		else if (0u == acRelEnvelopeCnt)
		{
			/** 通过计轴区段ID查找计轴区段位置--目前不处理ARB和UCT包络，故直接有占用就UKT包络*/
			funFlag = elm_PrepareACLoc(acID,ELM_DIR_SAME,&tmpLoc);
			errorCode = (CI_ERROR == funFlag) ? (errorCode + 0x40000000u) : ((errorCode + 0x00000000u));

			/** 添加UKT包络*/
			funFlag = elm_AddUKTEnvelope(tmpAcIndex,tmpLoc.startPos,tmpLoc.endPos);
			errorCode = (CI_ERROR == funFlag) ? (errorCode + 0x20000000u) : ((errorCode + 0x00000000u));

			/** 清除计轴区段上的好车标志位 */
			aam_SetEnvelopeEnterFlag(AAM_ENVELOPE_ENTER_ERROR,LINE_MAX_TRAIN,acID,LINE_MAX_TRAIN);

			/** 维护日志--错误级别*/
			ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:ac%d add UKT error,acIndex:%d",errorCode,acID,tmpAcIndex))
		}
		else
		{
			/** 无需处理*/
		}
	}
	else
	{
		/** 清除计轴区段上的好车标志位 */
		aam_SetEnvelopeEnterFlag(AAM_ENVELOPE_ENTER_ERROR,LINE_MAX_TRAIN,acID,LINE_MAX_TRAIN);
	}

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

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

/**
 * @brief 清除UCT或者CT包络
 * @param[in] UINT8 Flag 是否添加故障 0xff：清除包络时无需添加故障包络；其他，清除包络时需添加故障包络
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out]
 * @return 
 * @note 
 *   1、只有在列车不属于本OC控制时才处理，清除时不会对前后端进行操作，只清除相关内存
 *   2、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 *   3、修复bug YF0083-100
 */
UINT8 elm_ClearCTOrUCTEnvelope(UINT8 Flag,UINT16 envelopeID)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 funRet = CI_ERROR;
	UINT8 cycle = 0u;
	const EnvelopeStruct* pEnvelop = NULL;
	UINT32 errorCode = 0u;
	UINT16 tmpACindex = 0u;
	UINT8 funcReturn = CI_ERROR;

	/** 获取包络信息 */
	pEnvelop = elm_GetEnvelopeInfoPtr(envelopeID);

	if (NULL == pEnvelop)
	{
		ASSER_ERROR(CI_ERROR == ret,errorCode,0x80000000u)
		ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:input error!",errorCode)
	}
	else if((TYPE_UCT_ENVELOPE == pEnvelop->envelopeType) || (TYPE_CT_ENVELOPE == pEnvelop->envelopeType))
	{
		/** 车身范围内的计轴，清除映射关系，并添加UKT包络（占用且无其他包络则添加）*/
		for (cycle = 0u; cycle < pEnvelop->ACCnt;cycle++)
		{
			/** 获取计轴索引 */
			tmpACindex = elm_PrepareACIndex(pEnvelop->ACID[cycle]);

			/** 清除映射关系 */
			funcReturn = elm_SetACRelEnvelopeMap(OP_DEL,tmpACindex,envelopeID);

			/** 获取是否添加故障包络标志位 */
			if (UINT8_MAX == Flag)
			{
				/** 无需添加故障包络*/
			}
			else
			{
				/** 添加故障包络*/
				funcReturn = elm_AddUKTEnvelopeInAC(pEnvelop->ACID[cycle]);
			}
		}

		if (TYPE_CT_ENVELOPE == pEnvelop->envelopeType)
		{
			/** 清除列车关联的包络ID */
			funRet = elm_SetTrainRelEnvelopeMap(OP_DEL,pEnvelop->trainID[0], pEnvelop->id);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x20000000u);
		}
		else
		{
			for (cycle = 0u; cycle < pEnvelop->trianCnt;cycle++)
			{
				/** 清除列车关联的包络ID */
				funRet = elm_SetTrainRelEnvelopeMap(OP_DEL,pEnvelop->trainID[cycle], pEnvelop->id);
				ASSER_ERROR(CI_ERROR == funRet,errorCode,0x10000000u);
			}
		}

		/** 清空包络空间 */
		funRet = elm_ClearEnvelope(pEnvelop->id);
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x40000000u);
	}
	else
	{
		/** 无需处理 */
	}

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

/**
 * @brief 删除UCT或者CT包络
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out] 无
 * @return CI_ERROR 处理失败
           CI_SUCCESS 处理成功
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_DeleteCTOrUCTEnvelope(UINT16 envelopeID)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 funRet = CI_ERROR;
	UINT8 cycle = 0u;
	const EnvelopeStruct* pEnvelop = NULL;
	UINT32 errorCode = 0u;
	UINT16 tmpACindex = 0u;

	/** 获取包络信息 */
	pEnvelop = elm_GetEnvelopeInfoPtr(envelopeID);

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

	if((TYPE_UCT_ENVELOPE == pEnvelop->envelopeType) || (TYPE_CT_ENVELOPE == pEnvelop->envelopeType))
	{
		/** 处理故障车前后方包络 */
		funRet = elm_ProcessFaultElmNear(envelopeID);
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x40000000u);
	
		/** 车身范围内的计轴，清除映射关系，并添加UKT包络（占用且无其他包络则添加）*/
		for (cycle = 0u; cycle < pEnvelop->ACCnt;cycle++)
		{
			/** 获取计轴索引 */
			tmpACindex = elm_PrepareACIndex(pEnvelop->ACID[cycle]);

			/** 清除映射关系 */
			funRet = elm_SetACRelEnvelopeMap(OP_DEL,tmpACindex,envelopeID);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x20000000u);

			/** 添加故障包络*/
			funRet = elm_AddUKTEnvelopeInAC(pEnvelop->ACID[cycle]);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x10000000u);
		}

		if (TYPE_CT_ENVELOPE == pEnvelop->envelopeType)
		{
			/** 清除列车关联的包络ID */
			funRet = elm_SetTrainRelEnvelopeMap(OP_DEL,pEnvelop->trainID[0], pEnvelop->id);
			ASSER_ERROR(CI_ERROR == funRet,errorCode,0x08000000u);
		}
		else
		{
			for (cycle = 0u; cycle < pEnvelop->trianCnt;cycle++)
			{
				/** 清除列车关联的包络ID */
				funRet = elm_SetTrainRelEnvelopeMap(OP_DEL,pEnvelop->trainID[cycle], pEnvelop->id);
				ASSER_ERROR(CI_ERROR == funRet,errorCode,0x04000000u);
			}
		}

		/** 清空包络空间 */
		funRet = elm_ClearEnvelope(pEnvelop->id);
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x02000000u);
	}
	else
	{
		/** 无需处理 */
    }

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

/**
 * @brief 将相邻OC发送的包络信息加入到内存中
 * @param[in] UINT8 OCid 相邻OC id
 * @param[out] 无
 * @return 无
 * @note 
 *   1、此函数只能接受删除非本OC范围的计轴区段，否则返回失败
 */
void elm_AddNextOCEnvelopetoBuff(UINT8 OCid)
{
	/*-局部变量定义*/
	UINT8 envelopeCnt = 0u;
	UINT8 funRet = CI_ERROR;
	UINT8 cycle = 0u;
	UINT8 cycleAC = 0u;
	UINT16 ACIndex = 0u;
	UINT16 buffIndex = ENVELOPE_UNVAILD_INDEX;
	UINT32 errorCode = 0u;
	EnvelopeStruct tempEnvelope = {0u};
	CfpEnvelopeStruct InfEnvelope[OTHER_RC_SEND_ENVELOPE_SUM_MAX * ONE_OTHER_CFP_SUM_MAX] = {0u};

	/** 获取OC发送的包络信息个数 */
	envelopeCnt = elm_PrepareNextOcInfEnvelope(OCid,InfEnvelope);
	
	/** 遍历所有的包络，添加到缓存中 */
	for (cycle = 0u;cycle < envelopeCnt;cycle++)
	{
		/** 清空缓存*/
		(void)CommonMemSet(&tempEnvelope, (UINT32)sizeof(EnvelopeStruct),0, (UINT32)sizeof(EnvelopeStruct));

		/** 复制包络信息.接口合法性校验保证字段不越界*/
		tempEnvelope.envelopeType = InfEnvelope[cycle].envelopeType;
		tempEnvelope.headTrainID = InfEnvelope[cycle].headTrainID;
		tempEnvelope.tailTrainID = InfEnvelope[cycle].tailTrainID;
		tempEnvelope.startPos = InfEnvelope[cycle].startPos;
		tempEnvelope.endPos = InfEnvelope[cycle].endPos;
		tempEnvelope.trianCnt = InfEnvelope[cycle].trianCnt;
		(void)CommonMemCpy(&tempEnvelope.trainID[0], (UINT32)(sizeof(UINT16)*tempEnvelope.trianCnt),&InfEnvelope[cycle].trainID[0], (UINT32)(sizeof(UINT16)*tempEnvelope.trianCnt));
		(void)CommonMemCpy(&tempEnvelope.ACTPort[0], (UINT32)(sizeof(UINT8) * tempEnvelope.trianCnt), &InfEnvelope[cycle].ACTPort[0], (UINT32)(sizeof(UINT8) * tempEnvelope.trianCnt));
		tempEnvelope.ACCnt = InfEnvelope[cycle].ACCnt;
		(void)CommonMemCpy(&tempEnvelope.ACID[0], (UINT32)(sizeof(UINT16)*tempEnvelope.ACCnt),&InfEnvelope[cycle].ACID[0], (UINT32)(sizeof(UINT16)*tempEnvelope.ACCnt));


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

		/** 判断包络索引位置是否正确*/
		if (ENVELOPE_UNVAILD_INDEX != buffIndex)
		{
			/** 设置包络唯一标识*/
			tempEnvelope.id = buffIndex;

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

			/** 创建计轴到包络的映射关系 */
			for (cycleAC = 0u; cycleAC < tempEnvelope.ACCnt; cycleAC++)
			{
				/** 获取计轴的索引 */
				ACIndex = elm_PrepareACIndex(tempEnvelope.ACID[cycleAC]);
				funRet = elm_SetACRelEnvelopeMap(OP_ADD,ACIndex,buffIndex);
				ASSER_ERROR(CI_ERROR == funRet,errorCode,0x20000000u);
			}
			
			/** 维护日志--错误级别 */
			ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:next oC ELM Add error.\n",errorCode))
		}
		else
		{
			/** 维护日志--错误级别 */
			ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:next oC ELM create error.\n",errorCode));
		}
	}

	/** 错误处理 */
	if (0u != errorCode)
	{
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Add NextOC Envelope to Buff error.\n",errorCode)
	}
	else
	{
		/** 处理正确 */
	}
}


/**
 * @brief 刷新相邻OC范围内的包络信息
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_RefreshNextOCEnvelope(void)
{
	/*- 局部变量定义 */
	UINT16 acCnt = 0u;                             /*OC范围内所有的计轴区段数量*/
	const UINT16 *pACIdbuff = NULL;        /** 计轴ID数值缓存 */
	UINT8 comOCCnt = 0u;        /* 通信OC数量 */
	const UINT8 *pOCIdbuff = NULL; 
	UINT32 errorCode = 0u;
	UINT16 cycleAc = 0u;
	UINT8 cycleOC = 0u;
	UINT8 acBelongFlag = ELM_BELONG_OTHER;
	UINT8 acBelongOCid = 0u;
	UINT8 funRtn = CI_ERROR;
	UINT8 commStatusFlag = ELM_COM_STATUS_ERROR;

	/** 获取OC范围内所有的计轴区段数组索引 */
	acCnt = elm_PrepareACBuffIndexs(&pACIdbuff);

	/** 获取本OC通信的所有OC */
	comOCCnt = elm_PrepareComOCID(&pOCIdbuff);

	if ((NULL == pACIdbuff) || ((0u != comOCCnt) && (NULL == pOCIdbuff)))
	{
		/** 不可能分支*/
		errorCode = errorCode + 0x80000000u;
		ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:Get ACID and Comoc Buff error!", errorCode)
	}
	else
	{
		if (0u != comOCCnt)
		{
			/** 第一步：遍历所有计轴，删除非本OC范围的包络*/
			for (cycleAc = 0u; cycleAc < acCnt; cycleAc++)
			{
				/** 获取计轴所属OC*/
				acBelongFlag = elm_PrepareACIsSelf(pACIdbuff[cycleAc], &acBelongOCid);

				/** 判断查询是否正确 */
				if (0u == acBelongFlag)
				{
					/** 不可能分支*/
					ELM_LOG_LOC(ELM_LOG_FATAL, "info:Get ACID%d belong OCid%d error!", pACIdbuff[cycleAc], acBelongOCid)
						ASSERT_BREAK(0u == acBelongFlag, errorCode, 0x40000000u)
				}
				else if (ELM_BELONG_OWNER == acBelongFlag)
				{
					/** 属于本方OC，不进行处理 */
				}
				else
				{
					/** 删除计轴上的包络信息 */
					funRtn = elm_DeleteACRelEnvelope(acBelongFlag, pACIdbuff[cycleAc]);
					ASSERT_BREAK(CI_ERROR == funRtn, errorCode, 0x20000000u)
				}
			}

			/** 如果处理成功，则进行刷新*/
			if (0u == errorCode)
			{
				/** 第二步，遍历所有计轴，计轴所属OC通信错误，添加故障包络 */
				for (cycleAc = 0u; cycleAc < acCnt; cycleAc++)
				{
					/** 获取计轴所属OC*/
					acBelongFlag = elm_PrepareACIsSelf(pACIdbuff[cycleAc], &acBelongOCid);

					/** 判断查询是否正确 */
					if (0u == acBelongFlag)
					{
						/** 不可能分支*/
						ELM_LOG_LOC(ELM_LOG_FATAL, "info:Get ACID%d belong OCid%d error!", pACIdbuff[cycleAc], acBelongOCid)
							ASSERT_BREAK(0u == acBelongFlag, errorCode, 0x10000000u)
					}
					else if (ELM_BELONG_OWNER == acBelongFlag)
					{
						/** 属于本方OC，不进行处理 */
					}
					else
					{
						/** 获取通信状态 */
						commStatusFlag = elm_PrepareOCCommStatus(acBelongOCid);

						/** 判断通信状态 */
						if (ELM_COM_STATUS_OK == commStatusFlag)
						{
							/** 通信正常，后续刷新相邻OC信息 */
						}
						else
						{
							/** 添加故障包络 */
							(void)elm_AddUKTEnvelopeInAC(pACIdbuff[cycleAc]);
						}
					}
				}


				/** 第三步，获取相邻OC的包络信息 */
				for (cycleOC = 0u; cycleOC < comOCCnt; cycleOC++)
				{
					/** 获取通信状态 */
					commStatusFlag = elm_PrepareOCCommStatus(pOCIdbuff[cycleOC]);

					/** 判断通信状态 */
					if (ELM_COM_STATUS_OK == commStatusFlag)
					{
						/** 通信正常，获取相邻OC包络信息进行刷新 */
						elm_AddNextOCEnvelopetoBuff(pOCIdbuff[cycleOC]);
					}
					else
					{
						/** 无需处理 */
					}
				}

			}
			else
			{
				/** 不可能分支*/
			}
		}
		else
		{
			;
		}
	}


	/** 错误处理 */
	if (0u != errorCode)
	{
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Set Envelope from NextOC error!",errorCode)
	}
	else
	{
		/** 处理正确 */
	}
}

/**
 * @brief 维护信息打印
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
void elm_MaintenanceInfo(void)
{
	/*- 局部变量定义 */
	UINT16 cycle = 0u;
	UINT8 funRet = ENVELOPE_UNEXIT;
	const EnvelopeStruct* pTemp = NULL;
	UINT16 acCnt = 0u;
	const UINT16 *pACIdbuff = NULL;        /** 计轴ID数值缓存 */
	UINT16 tmpAcIndex = 0u;
	UINT8 tmpACStatus = ELM_AC_OCC;
	UINT8 acRelEnvelopeCnt = 0u;
	UINT8 OcID = 0u;
	UINT16 acRelEnvelopeID[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	UINT8 cycleEnvelope = 0u;
	UINT8 cycleTrain = 0u;
	UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] = {0u};  /*列车关联的包络索引*/
	UINT8 relEnvelopeCnt = TRAIN_REL_ENVELOPE_SUM_MAX;    /*列车关联的包络数量*/
	const AxisAsserStruct* pAcAssertInfo = NULL;
	UINT8 isSelfFlag = ELM_BELONG_OWNER;
	UINT8 outString[MAX_ENVELOPE_LOG_NUM] = { 0U };
	UINT16 outStringLength = 0U;

	ELM_LOG(ELM_LOG_DEBUG,"MaintenanceInfo:\n");

	/** 打印全线免筛相关维护信息 */
	wls_PrintfWLScreenInfo();

	/*- 打印所有包络信息*/
	for (cycle = 1u; cycle < ENVELOPE_SUM_MAX; cycle++)
	{
		funRet = elm_IsEnvelopeExit(cycle);
		if (ENVELOPE_EXIT == funRet)
		{
			pTemp = elm_GetEnvelopeInfoPtr(cycle);
			elm_PrintfEnvelope(pTemp);
		}
		else
		{
			/** 不处理 */
		}
	}

	if (0U == OutEnvelopeStrLen)
	{
		;
	}
	else
	{
#ifdef PLATFORM_2OO2

		debug_infor_printf((const)"\nEnvelopeLogData:%d\nEnvelpeid(2)-envelopeType-PEnvelpeheadTrainID(2)-PEnvelpetailTrainID(2)-PEnvelpetrianCnt-PEnvelpetrainID(2)-[PEnvelpetrainID(2)-rrmRequst-curAct-nextSta(2)-runDir-lastAct-rrmReply-rrmReason]-startPosLnk(2)-startPosOff(4)-startPosDir-endPosLnk(2)-endPosOff(4)-endPosDir-PEnvelpeACCnt-PEnvelpeACID-UCTToUKTStartCycNum(4)", OutEnvelopeStrLen);
		debug_out_array(0xAA, OutEnvelopeStr, OutEnvelopeStrLen);

#endif

#ifdef PLATFORM_LABVIEW_DEBUG

		Out_Array_Buffer(0, "\nEnvelopeLogData:%d", OutEnvelopeStrLen);
		Out_Array_Buffer(0, "\nPEnvelpeid(2)-envelopeType-PEnvelpeheadTrainID(2)-PEnvelpetailTrainID(2)-PEnvelpetrianCnt-PEnvelpetrainID(2)-[PEnvelpetrainID(2)-rrmRequst-curAct-nextSta(2)-runDir-lastAct-rrmReply-rrmReason]-startPosLnk(2)-startPosOff(4)-startPosDir-endPosLnk(2)-endPosOff(4)-endPosDir-PEnvelpeACCnt-PEnvelpeACID-UCTToUKTStartCycNum(4):%d", OutEnvelopeStrLen);
		Out_Array_Buffer(16, OutEnvelopeStr, OutEnvelopeStrLen);

#endif

		CleanString(OutEnvelopeStr);
		OutEnvelopeStrLen = 0U;
	}

	/*- 打印所有计轴的映射关系 */
	acCnt = elm_PrepareACBuffIndexs(&pACIdbuff);
	for (cycle = 0u; cycle < acCnt; cycle++)
	{
		tmpAcIndex = elm_PrepareACIndex(pACIdbuff[cycle]);
		acRelEnvelopeCnt = elm_GetACRelEnvelopeCnt(tmpAcIndex, acRelEnvelopeID);
		tmpACStatus = elm_PrepareACStatus(pACIdbuff[cycle]);
		pAcAssertInfo = elm_PrepareAxisAssertInfoPtr(pACIdbuff[cycle]);
		isSelfFlag = elm_PrepareACIsSelf(pACIdbuff[cycle],&OcID);

#if ELM_DEBUG
		if (isSelfFlag == ELM_BELONG_OWNER)
		{
#else
		if ((NULL != pAcAssertInfo) && (((acRelEnvelopeCnt > 0u) && (acRelEnvelopeCnt < SECTION_REL_ENVELOPE_SUM_MAX)) ||
			(ELM_AC_OCC == tmpACStatus)))
		{
#endif
			
			ShortToChar(pACIdbuff[cycle], &outString[outStringLength]);  /*计轴区段ID*/
			outStringLength += 2U;
			ShortToChar(tmpAcIndex, &outString[outStringLength]);  /*计轴区段ID索引*/
			outStringLength += 2U;
			outString[outStringLength] = OcID;  /*联锁ID*/
			outStringLength++;
			outString[outStringLength] = acRelEnvelopeCnt;  /*计轴区段关联的包络数量*/
			outStringLength++;

			for (cycleEnvelope = 0u; cycleEnvelope < acRelEnvelopeCnt; cycleEnvelope++)
			{
				ShortToChar(acRelEnvelopeID[cycleEnvelope], &outString[outStringLength]);  /*计轴区段关联的包络ID*/
				outStringLength += 2U;
			}
			
			outString[outStringLength] = tmpACStatus;  /*计轴区段占用状态*/
			outStringLength++;
			outString[outStringLength] = pAcAssertInfo->acAssertStatus;  /*计轴区段ARB状态*/
			outStringLength++;
			outString[outStringLength] = pAcAssertInfo->redunOverCanArb;  /*冗余结束可判ARB标志*/
			outStringLength++;
			outString[outStringLength] = pAcAssertInfo->AxisCommBadArbFlag;  /*计轴通信中断可判ARB标志*/
			outStringLength++;
			outString[outStringLength] = pAcAssertInfo->passTrainFlag;  /*计轴区段好车通过标志*/
			outStringLength++;
			ShortToChar(pAcAssertInfo->passTrainID, &outString[outStringLength]);  /*计轴区段好车通过的列车ID*/
			outStringLength += 2U;
			outString[outStringLength] = pAcAssertInfo->redunTime;  /*计轴区段占用冗余时间*/
			outStringLength++;
			outString[outStringLength] = pAcAssertInfo->headEnterTrainCnt;  /*计轴区段进入的列车头数量*/
			outStringLength++;

			for (cycleTrain = 0u; cycleTrain < pAcAssertInfo->headEnterTrainCnt; cycleTrain++)
			{
				ShortToChar(pAcAssertInfo->headEnterTrainId[cycleTrain], &outString[outStringLength]);  /*计轴区段车头进入的列车ID*/
				outStringLength += 2U;
			}

			outString[outStringLength] = pAcAssertInfo->tailEnterTrainCnt;  /*计轴区段进入的列车尾数量*/
			outStringLength++;
			for (cycleTrain = 0u; cycleTrain < pAcAssertInfo->tailEnterTrainCnt; cycleTrain++)
			{
				ShortToChar(pAcAssertInfo->tailEnterTrainId[cycleTrain], &outString[outStringLength]);  /*计轴区段车尾进入的列车ID*/
				outStringLength += 2U;
			}
		}
		else
		{
			/** 不处理 */
		}
	}

	if (0u == outStringLength)
	{
		;
	}
	else
	{
#ifdef PLATFORM_2OO2

		debug_infor_printf((const)"\nACData:%d\nACId(2)-ACIdIndex(2)-CiId-ACRelEnvelopeCnt-ACRelEnvelopeID(2)-ACOccStatus-ACARBStatus-redunOverCanArb-AxisCommBadArbFlag-PassCtFlag-PassCtId(2)-OccRedunTime-HeadEnterTrainCnt-HeadEnterTrainId(2)-TailEnterTrainCnt-TailEnterTrainId(2)", outStringLength);
		debug_out_array(0xAA, outString, outStringLength);

#endif

#ifdef PLATFORM_LABVIEW_DEBUG

		Out_Array_Buffer(0, "\nACData:%d", outStringLength);
		Out_Array_Buffer(0, "\nACId(2)-ACIdIndex(2)-CiId-ACRelEnvelopeCnt-ACRelEnvelopeID(2)-ACOccStatus-ACARBStatus-PassCtFlag-PassCtId(2)-OccRedunTime-HeadEnterTrainCnt-HeadEnterTrainId(2)-TailEnterTrainCnt-TailEnterTrainId(2):%d", outStringLength);
		Out_Array_Buffer(16, outString, outStringLength);

#endif

		CleanString(outString);
		outStringLength = 0U;
	}

	/*- 打印所有车的映射关系 */
	for (cycle = 1u; cycle < LINE_MAX_TRAIN; cycle++)
	{
		relEnvelopeCnt = elm_GetRelELIdByTrainID(cycle,relEnvelopeID);

		if (0U != relEnvelopeCnt)
		{
			ShortToChar(cycle, &outString[outStringLength]);  /*列车ID*/
			outStringLength += 2U;
			outString[outStringLength] = relEnvelopeCnt;		 /*列车关联的包络数量*/
			outStringLength += 1U;

			for (cycleTrain = 0u; cycleTrain < relEnvelopeCnt;cycleTrain++)
			{
				ShortToChar(relEnvelopeID[cycleTrain], &outString[outStringLength]);  /*列车关联的包络ID*/
				outStringLength += 2U;
			}
		}		
	}

	if (0u == outStringLength)
	{
		;
	}
	else
	{
#ifdef PLATFORM_2OO2

		debug_infor_printf((const)"\nTrainEnvelopData:%d\nTrainCnt-TrainId(2)-RelEnvelopeCnt(2)-RelEnvelopeId(2)", outStringLength);
		debug_out_array(0xAA, outString, outStringLength);

#endif

#ifdef PLATFORM_LABVIEW_DEBUG

		Out_Array_Buffer(0, "\nTrainEnvelopData:%d", outStringLength);
		Out_Array_Buffer(0, "\nTrainCnt-TrainId(2)-RelEnvelopeCnt(2)-RelEnvelopeId(2):%d", outStringLength);
		Out_Array_Buffer(16, outString, outStringLength);

#endif
	}
}


/**
 * @brief 根据已知条件创建包络
 * @param[in] UINT8 envelopeType 包络类型
 * @param[in] UINT16 TrainID 包络ID
 * @param[in] LOD_STRU startPoint 包络起始位置
 * @param[in] LOD_STRU endPoint 包络终止位置
 * @param[in] UINT16 headTrainID 包络前端列车ID
 * @param[in] UINT16 tailTrainID 包络后端列车ID
 * @param[out] EnvelopeStruct *pEnvelope 包络
 * @return CI_SUCCESS 包络创建正确，返回成功
 *         CI_ERROR   包络创建失败，返回失败
 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_CreateEnveLope(UINT8 envelopeType,UINT16 TrainID, LOD_STRU startPoint,LOD_STRU endPoint,UINT16 headTrainID,UINT16 tailTrainID, \
	INOUT EnvelopeStruct *pEnvelope)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;

	/** 入口参数校验*/
	if (NULL == pEnvelope)
	{
		/** pEnvelope参数不合法*/
	}
	else if ((TYPE_CT_ENVELOPE != envelopeType) && (TYPE_UCT_ENVELOPE != envelopeType) && (TYPE_UKT_ENVELOPE != envelopeType))
	{
		/** envelopeType参数不合法 */
	}
	else if ((TrainID > LINE_MAX_TRAIN)||(headTrainID > LINE_MAX_TRAIN) ||  (tailTrainID > LINE_MAX_TRAIN))
	{
		/** headTrainID、tailTrainID参数不合法 */
	}
	else
	{
		/*- 创建包络 */
		pEnvelope->envelopeType = envelopeType;
		pEnvelope->startPos = startPoint;
		pEnvelope->endPos = endPoint;
		pEnvelope->headTrainID = headTrainID;
		pEnvelope->tailTrainID = tailTrainID;
		pEnvelope->trainID[pEnvelope->trianCnt] = TrainID;
		pEnvelope->ACTPort[pEnvelope->trianCnt] = elm_PrepareTrainACT(TrainID);
		pEnvelope->trianCnt++;

		/** 根据两点查询之间包含的计轴区段*/
		pEnvelope->ACCnt = elm_PrepareACBtwPoints(startPoint,endPoint,&(pEnvelope->ACID[0]));

		/** 设置返回值*/
		ret = ((0u == pEnvelope->ACCnt) || (SECTION_IN_ENVELOPE_SUM_MAX == pEnvelope->ACCnt)) ? CI_ERROR: CI_SUCCESS;
	}

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


/**
 * @brief 查询基准包络前方最近的包络
 * @param[in] const EnvelopeStruct* pEnvelop 基准包络
 * @param[in] const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] 待比较的包络
 * @param[in] UINT8 envelopeCnt 待比较的包络数量
 * @param[out] UINT16 *preEnvelope 包络前方id
 * @param[out] UINT16 *backEnvelope 包络后方id
 * @param[out] UINT8 *includeCnt 包含的包络数量
 * @param[out] UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] 包含的包络ID
 * @return CI_ERROR 查询失败
           CI_SUCCESS 查询成功
		   0xffu 包络存在重合包络

 * @note 
 *   1、从EnvelopeManageAPI.c拆分到此文件中，代码未修改
 */
UINT8 elm_SearchNearestEnvelope(IN const EnvelopeStruct* pEnvelop, IN const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC], UINT8 envelopeCnt, OUT UINT16 *preEnvelope, OUT UINT16 *backEnvelope, OUT UINT8 *includeCnt, OUT UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC])
{

	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;
	const EnvelopeStruct* pHead = NULL;
	const EnvelopeStruct* pTail = NULL;
	const EnvelopeStruct* pTemp = NULL;
	UINT8 cycle = 0u;
	UINT8 funRet = 0u;

	/** 入口参数判断 */
	if ((NULL == pEnvelop) || (NULL == arEnvelopID) || (NULL == preEnvelope) || (NULL == backEnvelope) || (NULL == includeCnt) || (NULL == includeELMid))
	{
		/** 入口参数校验 */
		errorCode = errorCode + 0x80000000u;
		ELM_LOG_LOC(ELM_LOG_ERROR, "errorCode:0x%08x info:input error!", errorCode)
	}
	else
	{
		/** 依次遍包络，查找前方包络 */
		for (cycle = 0u; cycle < envelopeCnt; cycle++)
		{
			/** 通过包络ID查找包络信息 */
			pTemp = elm_GetEnvelopeInfoPtr(arEnvelopID[cycle]);

			/** 判断是否满足退出条件 */
			ASSERT_BREAK(NULL == pTemp, errorCode, 0x04000000U);

			/** 判断包络是否为本包络*/
			if (pTemp->id == pEnvelop->id)
			{
				/** 本包络跳过 */
			}
			else if ((TYPE_CT_ENVELOPE == pTemp->envelopeType) && (TYPE_CT_ENVELOPE == pEnvelop->envelopeType) &&
				(pTemp->trainID[0] == pEnvelop->trainID[0]))
			{
				/** 分界点处本车 */
			}
			else
			{
				/** 比较两个包络的位置关系 */ 
				funRet = elm_PrepareRelationBtwEnvelope(pEnvelop, pEnvelop->startPos, pTemp);

				/** 判断是否满足退出条件 */
				ASSERT_BREAK(0x00u == funRet, errorCode, 0x02000000u);

				if (0x02u == funRet)
				{
					if (NULL == pHead)
					{
						pHead = pTemp;
					}
					else if (pTemp->id == pHead->id)
					{
						/** 本包络跳过 */
					}
					else
					{
						funRet = elm_PrepareRelationBtwEnvelope(pHead, pEnvelop->startPos, pTemp);
						/** 判断是否满足退出条件 */
						ASSERT_BREAK(0x00u == funRet, errorCode, 0x01000000u);

						/** 判断是否需要更新前车包络*/
						if (0x01u == funRet)
						{
							pHead = pTemp;
						}
						else
						{
							/** 不需要处理*/
						}
					}
				}
				else if (0x01u == funRet)
				{
					if (NULL == pTail)
					{
						pTail = pTemp;
					}
					else if (pTemp->id == pTail->id)
					{
						/** 本包络跳过 */
					}
					else
					{
						funRet = elm_PrepareRelationBtwEnvelope(pTail, pEnvelop->startPos, pTemp);
						/** 判断是否满足退出条件 */
						ASSERT_BREAK(0x00u == funRet, errorCode, 0x00800000u);

						/** 判断是否需要更新前车包络*/
						if (0x02u == funRet)
						{
							pTail = pTemp;
						}
						else
						{
							/** 不需要处理*/
						}
					}
				}
				else if ((TRAIN_SUM_MAX_IN_OC > (*includeCnt)) && ((0x03u == funRet) || (0x04u == funRet)))
				{
					includeELMid[(*includeCnt)] = pTemp->id;
					(*includeCnt) += 1u;
				}
				else
				{
					/** 比较不出来，导向安全侧*/
					ret = CI_ERROR;
					break;
				}
			}
		}

		/** 设置函数返回值*/
		if ((cycle == envelopeCnt) && (0u == (*includeCnt)))
		{
			(*preEnvelope) = (NULL == pHead) ? 0u : pHead->id;
			(*backEnvelope) = (NULL == pTail) ? 0u : pTail->id;
			ret = CI_SUCCESS;
		}
		else if ((cycle == envelopeCnt) && (0u != (*includeCnt)))
		{
			(*preEnvelope) = (NULL == pHead) ? 0u : pHead->id;
			(*backEnvelope) = (NULL == pTail) ? 0u : pTail->id;
			ret = 0xffu;
		}
		else
		{
			/** 函数处理错误*/
		}
	}

	return ret;
}


/**
 * @brief 拷贝计轴区段上的包络信息
 * @param[in] UINT16 acID
 * @param[out] EnvelopeStruct envelopeInfo[] 计轴区段上的包络信息
 * @return 0 计轴区段上不存在包络
           非0且小于SECTION_REL_ENVELOPE_SUM_MAX 计轴区段上包络数量
		   SECTION_REL_ENVELOPE_SUM_MAX，函数执行错误
 * @note 无
 */
UINT8 elm_CopyEnvelopeInAC(UINT16 acID,INOUT EnvelopeStruct envelopeInfo[SECTION_REL_ENVELOPE_SUM_MAX])
{
	/*- 局部变量定义 */
	UINT8 ret = SECTION_REL_ENVELOPE_SUM_MAX;
	UINT8 cycle = 0u;
	UINT8 tempCnt = 0u;
	UINT16 tmpACIndex = 0u;
	UINT16 tmpEnvelopID[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	const EnvelopeStruct* tmpEnvelope = NULL;

	/** 入口参数合法性校验*/
	if (NULL == envelopeInfo)
	{
		/** 入口参数错误*/
	}
	else
	{
		/** 通过计轴ID获取计轴索引 */
		tmpACIndex = elm_PrepareACIndex(acID);

		/** 获取计轴关联的包络信息*/
		tempCnt = elm_GetACRelEnvelopeCnt(tmpACIndex,tmpEnvelopID);

		if (SECTION_REL_ENVELOPE_SUM_MAX == tempCnt)
		{
			/** 查询出错*/
		}
		else
		{
			for (cycle = 0u; cycle < tempCnt; cycle++)
			{				
				tmpEnvelope = elm_GetEnvelopeInfoPtr(tmpEnvelopID[cycle]);
				(void)CommonMemCpy(&envelopeInfo[cycle], (UINT32)sizeof(EnvelopeStruct),tmpEnvelope, (UINT32)sizeof(EnvelopeStruct));
			}
			ret = tempCnt;
		}
		
	}

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


/**
 * @brief 获取计轴区段属于包络的位置
 * @param[in] UINT16 ACid 待判计轴（待判计轴必须为包络范围内的计轴区段）
 * @param[in] const UINT16 newACID[SECTION_IN_ENVELOPE_SUM_MAX]   本周期占用的包络计轴序列（序列从包络尾指向包络头）
 * @param[in] UINT8 newACCnt  本周期占用的包络计轴数量 
 * @param[out] 无
 * @return UINT8_MAX 处理错误
           ELM_HEAD_AND_TAIL   属于包络头且属于包络尾
           ELM_HEAD 属于包络头
		   ELM_TAIL 属于包络尾
		   ELM_BODY 属于包络体
 * @note 
 *    1、新建，2022年4月21日
 */
UINT8 elm_GetACOfEnvelopePos(UINT16 ACid, IN const UINT16 newACID[SECTION_IN_ENVELOPE_SUM_MAX],UINT8 newACCnt)
{
	/*- 局部变量定义 */
	UINT8 ret = (UINT8)UINT8_MAX;
	UINT16 tmpPhyId = 0u;
	UINT16 tmpHeadPhyId = 0u;
	UINT16 tmpTailPhyId = 0u;

	/*- 入口参数判断 */
	ASSERT_RET_VALUE(NULL == newACID,ret,0x80000000u);
	ASSERT_RET_VALUE(((UINT8)SECTION_IN_ENVELOPE_SUM_MAX < newACCnt) || (0u == newACCnt),ret,0x40000000u);

	/** 获取待判计轴所属物理区段 */
	tmpPhyId = elm_PrepareACRelPhyId(ACid);
	tmpHeadPhyId = elm_PrepareACRelPhyId(newACID[newACCnt - 1u]);
	tmpTailPhyId = elm_PrepareACRelPhyId(newACID[0u]);

	if ((0u == tmpPhyId) || (0u == tmpHeadPhyId) || (0u == tmpTailPhyId))
	{
		/** 数据错误 */
	}
	else if((tmpPhyId == tmpHeadPhyId) && (tmpPhyId == tmpTailPhyId))
	{
		/** 属于包络头并且属于包络尾*/
		ret = (UINT8)ELM_HEAD_AND_TAIL;
	}
	else if (tmpPhyId == tmpHeadPhyId)
	{
		/** 属于包络头并且属于包络尾*/
		ret = (UINT8)ELM_HEAD;
	}
	else if (tmpPhyId == tmpTailPhyId)
	{
		/** 属于包络尾*/
		ret = (UINT8)ELM_TAIL;
	}
	else
	{
		/** 属于包络体 */
		ret = (UINT8)ELM_BODY;
	}

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


/**
 * @brief 删除切换完成的包络信息
 * @param[in] const EnvelopeStruct* pEnvelop 包络
 * @param[in] UINT16 trainid 列车ID
 * @param[in] UINT8 cutFlag 包络截取标识
 * @param[out] 无
 * @return CI_ERROR 查询失败
 *         CI_SUCCESS 查询成功
 * @note 
 */
UINT8 elm_ClearHanderOverEnvelope(IN const EnvelopeStruct* pEnvelop,UINT16 trainid)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 funRet = CI_ERROR;
	UINT8 cycle = 0u;
	UINT32 errorCode = 0u;
	UINT32 toHeadDis = UINT32_MAX;
	UINT32 toTailDIs = UINT32_MAX;
	ELM_TrainSafeLocStruct tmpSafeLoc = { 0u };    /* 安全位置临时存储 */

	/** 获取列车的安全位置*/
	funRet = elm_PrepareTrainSafeLoc(trainid, &tmpSafeLoc);

	/*- 入口参数校验 */
	ASSERT_RET_VALUE(NULL == pEnvelop,ret,0x80000000u);
	/** 查询车头车尾到上周期包络终点的距离*/
	toHeadDis = elm_PrepareDistanceBtwPoints(pEnvelop->endPos,tmpSafeLoc.endPos);
	toTailDIs = elm_PrepareDistanceBtwPoints(pEnvelop->endPos,tmpSafeLoc.startPos);
	ASSERT_RET_VALUE((UINT32_MAX == toHeadDis) || (UINT32_MAX == toTailDIs),ret,0x40000000u);
	
	for (cycle = 0u; cycle < pEnvelop->ACCnt; cycle++)
	{
		/** 如果是车尾，需要判断是否有后端 */
		if (toTailDIs < toHeadDis)
		{
			/** 设置车尾出清*/
			aam_SetEnvelopeEnterFlag(AAM_ENVELOPE_TAIL_EXIT,pEnvelop->tailTrainID,pEnvelop->ACID[cycle],trainid);
		}
		else if(toTailDIs > toHeadDis) 
		{
			/** 设置车头出清*/
			aam_SetEnvelopeEnterFlag(AAM_ENVELOPE_HEAD_EXIT,pEnvelop->headTrainID,pEnvelop->ACID[cycle],trainid);
		}
		else
		{
			/** 切换列车不可能未进行截取包络 */
			aam_SetEnvelopeEnterFlag(AAM_ENVELOPE_ENTER_ERROR,LINE_MAX_TRAIN,pEnvelop->ACID[cycle],trainid);
		}
	}

	if (0u == errorCode)
	{
		if ((toTailDIs < toHeadDis) && (0u == pEnvelop->tailTrainID))
		{
			/** 无后端车尾出清，无需添加故障包络*/
			funRet = elm_ClearCTOrUCTEnvelope(UINT8_MAX, pEnvelop->id);
		}
		else if ((toTailDIs > toHeadDis) && (0u == pEnvelop->headTrainID))
		{
			/** 无前端车尾出清，无需添加故障包络*/
			funRet = elm_ClearCTOrUCTEnvelope(UINT8_MAX, pEnvelop->id);
		}
		else
		{
			/** 需添加故障包络*/
			funRet = elm_ClearCTOrUCTEnvelope(0u, pEnvelop->id);
		}

		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x20000000u);    /*设置错误码*/
	}
	else
	{
		/** 处理失败，返回错误 */
	}

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



/**
 * @brief 包络管理安全防护
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 1、如果包络管理模块处理错误，导向安全侧，所有占用计轴都设置成UKT，计轴诊断信息重置。
         2、如果包络管理模块处理正确，CT包络范围内计轴不能全空闲（CT飞车防护）
		 3、如果包络管理模块处理正确，控区范围内CT必然存在包络（CT丢车防护）
		 4、如果包络管理模块处理正确，控区范围内占用计轴必然存在包络或者UT/CT冗余（UT丢车防护）
 */
void elm_SafeProtectProcess(void)
{
	/*- 局部变量定义 */
	UINT8 workFlag = ELM_WORK_ERROR;
	UINT8 funRet = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 localCiType = 0U;
	UINT8 ciTrainTestState = 0U;

	/** 包络管理模块可正常处理标志位 */
	workFlag = elm_GetELMWorkFlag();

	/** 如果包络管理模块不可正常处理，包络模块重新初始化 */
	if (ELM_WORK_ERROR == workFlag)
	{
		/** 包络已经无法正常处理， 无需再进行防护 */
	}
	else
	{
		/** UKT包络相邻岔区防护 */ 
		funRet = elm_UKTAdjacentSwProtect();     
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x80000000u);

		/** UT车丢车防护*/
		funRet = elm_UTLosingProtect();     
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x40000000u);

		localCiType = GetLocalCiType();
		ciTrainTestState = GetCiTrainTestStatus();
		if ((CI_TYPE_SCX == localCiType) && ((CI_TRAIN_TEST_OFF == ciTrainTestState) || (CI_TRAIN_TEST_STOP == ciTrainTestState)))
		{
			ScxClearFlyProtectInfo();  /*试车线在未试车期间，不进行飞车宕机防护处理，同时清除之前的飞车信息，修复CT驶出试车线导致飞车宕机问题*/
		}
		else
		{
			/** CT/UCT车飞车防护--宕机防护*/
			elm_FlyingProtect();
		}

		/** 本OC范围内的计轴映射表合法性校验 */
		funRet = elm_ACRelEnvelopeCheck();
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x20000000u);

		if (0u != errorCode)
		{
			/** 设置包络不能正确处理 */
			elm_SetELMWorkFlag(ELM_WORK_ERROR);
			ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:ELM is treated with safety protection.",errorCode);
		}
		else
		{
			/** 包络处理正确 */
		}
	}
}

/**
 * @brief 检查计轴区段是否UT占用（冗余期间不算UT占用）
 * @param[in] UINT16 ACID 计轴ID
 * @param[out] 无
 * @return CI_ERROR UT占用
           CI_SUCCESS 非UT占用
 * @note 
 */
UINT8 elm_CheckACIsUTOcc(UINT16 ACID)
{
	/*- 局部*/
	UINT8 ret = CI_ERROR;
	UINT16 tmpAcIndex = 0u;
	UINT8 cycle = 0u;
	UINT8 acRelEnvelopeCnt = 0u;
	UINT16 acRelEnvelopeID[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	const EnvelopeStruct* pEnvelop = NULL;
	UINT32 errorCode = 0u;

	/** 通过计轴数组索引查找计轴索引*/
	tmpAcIndex = elm_PrepareACIndex(ACID);

	/** 通过计轴数组索引获取关联的包络个数 */
	acRelEnvelopeCnt = elm_GetACRelEnvelopeCnt(tmpAcIndex, acRelEnvelopeID);

	if (SECTION_REL_ENVELOPE_SUM_MAX == acRelEnvelopeCnt)
	{
		/** 查询错误*/
		errorCode += 0x80000000u;
	}
	else
	{
		/** 遍历计轴包含的包络 */
		for (cycle = 0u; cycle < acRelEnvelopeCnt; cycle++)
		{
			/** 获取列车包络 */
			pEnvelop = elm_GetEnvelopeInfoPtr(acRelEnvelopeID[cycle]);

			/** 获取列车包络错误，退出循环*/
			ASSERT_BREAK(NULL == pEnvelop,errorCode,0x40000000u);

			/** 如果计轴存在UKT包络则为UT占用，退出循环 */
			ASSERT_BREAK(TYPE_UKT_ENVELOPE == pEnvelop->envelopeType,errorCode,0x00000000u);
		}

		/** 设置函数返回值 */
		ASSERT_SETRET(cycle == acRelEnvelopeCnt,ret,CI_SUCCESS,CI_ERROR);
	}

	/** 函数返回 */
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Check Ac%d UT occ error",errorCode,ACID));
	return ret;
}

/**
 * @brief 处理UCT/CT故障包络的前后包络
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out] 无
 * @return CI_SUCCESS 处理成功
 *         CI_ERROR 处理失败
 * @note 无
 */
UINT8 elm_ProcessFaultElmNear(UINT16 envelopeID)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 funRet = CI_ERROR;
	const EnvelopeStruct* pEnvelop = NULL;
	const EnvelopeStruct* pTemp = NULL;
	UINT16 preEnvelopeid = 0u;
	UINT16 backEnvelopeid = 0u;
	UINT32 errorCode = 0u;
	UINT8 cDir = 0U;  /*两包络方向*/

	/** 获取包络信息 */
	pEnvelop = elm_GetEnvelopeInfoPtr(envelopeID);

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

	/** 查询包络的前方和后方包络*/
	funRet = elm_GetNearestEnvelope(envelopeID,&preEnvelopeid,&backEnvelopeid);

	/** 判断否查询成功*/
	if (CI_SUCCESS == funRet)
	{
		/*- 监控包络前方*/
		pTemp = elm_GetEnvelopeInfoPtr(preEnvelopeid);
		if ((NULL != pTemp) && (TYPE_UKT_ENVELOPE != pTemp->envelopeType))/*UKT包络无前后端可疑，不进入处理*/
		{
			cDir = elm_DirIsSameELMWithELM(pTemp, pEnvelop);  /*比较两包络方向*/

			if (ELM_DIR_SAME == cDir)
			{
				(void)elm_SetEnvelopeTailTrainID(pTemp->id, LINE_MAX_TRAIN);
			}
			else if (ELM_DIR_CONVERT == cDir)
			{
				(void)elm_SetEnvelopeHeadTrainID(pTemp->id, LINE_MAX_TRAIN);
			}
			else
			{
				; /*不处理*/
			}
		}
		else
		{
			/** 无需处理 */
		}

		/*- 监控包络后方*/
		pTemp = elm_GetEnvelopeInfoPtr(backEnvelopeid);

		if ((NULL != pTemp) && (TYPE_UKT_ENVELOPE != pTemp->envelopeType))/*扩大条件，UKT包络不能进入处理*/
		{
			cDir = elm_DirIsSameELMWithELM(pTemp, pEnvelop);  /*比较两包络方向*/

			if (ELM_DIR_SAME == cDir)
			{
				(void)elm_SetEnvelopeHeadTrainID(pTemp->id, LINE_MAX_TRAIN);
			}
			else if (ELM_DIR_CONVERT == cDir)
			{
				(void)elm_SetEnvelopeTailTrainID(pTemp->id, LINE_MAX_TRAIN);
			}
			else
			{
				; /*不处理*/
			}
		}
		else
		{
			/** 无需处理 */
		}

		/** 处理成功，设置返回值 */
		ret = CI_SUCCESS;
	}
	else
	{
		/** 查询前后车错误 */
		ASSER_ERROR(CI_ERROR == funRet,errorCode,0x40000000u);
	}
	
	/**处理返回 */
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Search NearBy train error.",errorCode));
	return ret;
}


/**
 * @brief 判断包络A的运行方向是否与包络B的运行方向相同
 * @param[in] const EnvelopeStruct* pEnvelopA  包络A
 * @param[in] const EnvelopeStruct* pEnvelopB  包络B
 * @param[out] 无
 * @return ELM_DIR_SAME 处理成功
 *         ELM_DIR_CONVERT 处理失败
           其他，非法
 * @note 无，目前该函数未考虑方向变化点
 */
UINT8 elm_DirIsSameELMWithELM(const EnvelopeStruct* pEnvelopA, const EnvelopeStruct* pEnvelopB)
{
	UINT8 ret = 0u;
	UINT8 cDirChangeNum = 0U;
	UINT8 cResidue = 0U;

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

	cDirChangeNum = elm_PrepareDirChangNum(&(pEnvelopA->startPos), &(pEnvelopB->startPos));
	if (UINT8_MAX != cDirChangeNum)
	{
		/*根据方向变化点设置返回值*/
		cResidue = cDirChangeNum % 2U;
		if (0U == cResidue)
		{
			/*不存在或存在偶数个方向变化点*/
			ASSERT_SETRET(pEnvelopA->startPos.Dir == pEnvelopB->startPos.Dir, ret, ELM_DIR_SAME, ELM_DIR_CONVERT);
		}
		else
		{
			/*存在奇数个方向变化点*/
			ASSERT_SETRET(pEnvelopA->startPos.Dir == pEnvelopB->startPos.Dir, ret, ELM_DIR_CONVERT, ELM_DIR_SAME);
		}
	}
	else
	{
		/*不处理*/
	}
	
	return ret;
}

/**
 * @brief 静态函数：更新计轴上的列车序列信息
 * @param[in] IN const EnvelopeStruct* pEnvelop 包络信息    
 * @param[in] const UINT16 newACID[SECTION_IN_ENVELOPE_SUM_MAX]   本周期占用的包络计轴序列（序列从包络尾指向包络头）
 * @param[in] UINT8 newACCnt  本周期占用的包络计轴数量      
 * @param[in] UINT8 cutFlag  截取标志位  
 * @return CI_SUCCESS 处理正确，返回成功
 *         CI_ERROR   处理错误，返回失败
 * @note 
 *   1、新建，2022年4月21日,只能给CT包络使用
 */
UINT8 elm_RefreshACseqInfoForCT(IN const EnvelopeStruct* pEnvelop,IN const UINT16 newACID[SECTION_IN_ENVELOPE_SUM_MAX],UINT8 newACCnt,UINT8 cutFlag)
{
	/*- 局部变量定义 */
	UINT8 ret = (UINT8)CI_ERROR;
	UINT8 cycle = 0u;
	UINT8 funValid = CI_ERROR;
	UINT8 posFlag = (UINT8)UINT8_MAX;
	UINT16 trainid = (UINT16)LINE_MAX_TRAIN;
	UINT32 errorCode = 0u;

	/*- 入口参数校验 */
	ASSERT_RET_VALUE(NULL == pEnvelop,ret,0x80000000u);
	ASSERT_RET_VALUE(0u == newACCnt,ret,0x40000000u);
	ASSERT_RET_VALUE((0u == pEnvelop->trainID[0]) || ((UINT16)LINE_MAX_TRAIN == pEnvelop->trainID[0]),ret,0x20000000u);
	ASSERT_RET_VALUE((ELM_HEAD_CUT != cutFlag) && (ELM_TAIL_CUT != cutFlag) && (ELM_NO_CUT != cutFlag),ret,0x10000000u);

	/** 缓存通信车ID */
	trainid = pEnvelop->trainID[0];


	for (cycle = 0u; cycle < newACCnt;cycle++)
	{
		/** 初始函数可执行*/
		funValid = CI_SUCCESS;

		/** 获取计轴属于包络中的位置 */
		posFlag = elm_GetACOfEnvelopePos(newACID[cycle],newACID,newACCnt);

		switch(posFlag)
		{
			case ELM_HEAD_AND_TAIL:
				{
					if (ELM_HEAD_CUT == cutFlag)
					{
						/** 车尾部分：车尾进入*/
						aam_SetEnvelopeEnterFlag((UINT8)AAM_ENVELOPE_TAIL_ENTER,pEnvelop->tailTrainID,newACID[cycle],trainid);
					}
					else if (ELM_TAIL_CUT == cutFlag)
					{
						/** 车头部分：车头进入*/
						aam_SetEnvelopeEnterFlag((UINT8)AAM_ENVELOPE_HEAD_ENTER,pEnvelop->tailTrainID,newACID[cycle],trainid);
					}
					else
					{
						/** 车头部分：车头进入*/
						aam_SetEnvelopeEnterFlag((UINT8)AAM_ENVELOPE_HEAD_ENTER,pEnvelop->headTrainID,newACID[cycle],trainid);
						/** 车尾部分：车尾进入*/
						aam_SetEnvelopeEnterFlag((UINT8)AAM_ENVELOPE_TAIL_ENTER,pEnvelop->tailTrainID,newACID[cycle],trainid);
					}				

					break;
				}
			case ELM_HEAD:
				{
					/** 车身部分：车头进入*/
					aam_SetEnvelopeEnterFlag((UINT8)AAM_ENVELOPE_HEAD_ENTER,pEnvelop->headTrainID,newACID[cycle],trainid);
					break;
				}
			case ELM_TAIL:
				{
					/** 车尾部分：车尾进入*/
					aam_SetEnvelopeEnterFlag((UINT8)AAM_ENVELOPE_TAIL_ENTER,pEnvelop->tailTrainID,newACID[cycle],trainid);
					break;
				}
			case ELM_BODY:
				{
					/** 车身部分：车头进入*/
					aam_SetEnvelopeEnterFlag((UINT8)AAM_ENVELOPE_HEAD_ENTER,pEnvelop->headTrainID,newACID[cycle],trainid);
					break;
				}
			default:
				{
					/** 不可能分支 */
					funValid = CI_ERROR;
					break;
				}
		}

		/** 判断是否需要跳出循环 */
		ASSERT_BREAK(CI_ERROR == funValid,errorCode,0x08000000u);		
	}

	/*_ 设置函数返回值 */
	ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errorCode:0x%08x info:Refresh elm_seq In ac%d error,posFlag %d.",errorCode,pEnvelop->ACID[cycle],posFlag));
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	return ret;
}


/**
 * @brief 更新计轴上的UCT包络进入信息
 * @param[in] IN const EnvelopeStruct* pEnvelop 包络信息    
 * @return CI_SUCCESS 处理正确，返回成功
 *         CI_ERROR   处理错误，返回失败
 * @note 无
 */
UINT8 elm_RefreshACseqInfoForUCT(IN const EnvelopeStruct* pEnvelop)
{
	UINT8 ret = CI_ERROR;
	UINT8 cylceAC = 0u;
	UINT8 cycleTrain = 0u;

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

	/** UCT包络范围内所有列车车头和车身都进入计轴区段，如果将UCT用统一列车ID标识，会更简单，但有可能会因为少删除计轴上的列车包络信息，导致误判好车通过*/
	for (cylceAC = 0u; cylceAC < pEnvelop->ACCnt;cylceAC++)
	{
		for (cycleTrain = 0u; cycleTrain < pEnvelop->trianCnt;cycleTrain++)
		{
			/** 车头部分：车头进入*/
			aam_SetEnvelopeEnterFlag((UINT8)AAM_ENVELOPE_HEAD_ENTER,pEnvelop->headTrainID,pEnvelop->ACID[cylceAC],pEnvelop->trainID[cycleTrain]);
			/** 车尾部分：车尾进入*/
			aam_SetEnvelopeEnterFlag((UINT8)AAM_ENVELOPE_TAIL_ENTER,pEnvelop->tailTrainID,pEnvelop->ACID[cylceAC],pEnvelop->trainID[cycleTrain]);
		}
	}

	/** 设置函数返回值 */
	ret = CI_SUCCESS;

	return ret;
}


/**
 * @brief UCT包络出清计轴处理 
 * @param[in] UINT8 flag 出清方式
 * @param[in] const EnvelopeStruct* pEnvelope 包络信息
 * @param[in] UINT16 acID 计轴区段Id
 * @param[out]
 * @return CI_SUCCESS 处理正确，返回成功
 *         CI_ERROR   处理错误，返回失败
 * @note 无
 */
UINT8 elm_UCTEnvelopeLeaveAC(UINT8 flag,IN const EnvelopeStruct* pEnvelope,UINT16 acID)
{
	UINT8 ret = CI_ERROR;
	UINT8 cycle = 0u;

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

	if (ELM_HEAD == flag)
	{
		for (cycle = 0u; cycle < pEnvelope->trianCnt; cycle++)
		{
			/** 清除列车进出信息 */
			aam_ClearACEnvelopeEnterInfo(acID,pEnvelope->trainID[cycle]);
		}

		(void)aam_ClearACPassTrainFlag(acID);
		ELM_LOG_LOC(ELM_LOG_FATAL,"info:Clear AC%d CT Pass Flag because UCT%d",acID,pEnvelope->id);
	}
	else
	{
		for (cycle = pEnvelope->trianCnt; 0u != cycle; cycle--)
		{
			/** 清除列车进出信息 */
			aam_ClearACEnvelopeEnterInfo(acID,pEnvelope->trainID[cycle - 1u]);
		}

		(void)aam_ClearACPassTrainFlag(acID);
		ELM_LOG_LOC(ELM_LOG_FATAL,"info:Clear AC%d CT Pass Flag because UCT%d",acID,pEnvelope->id);
	}

	/** 设置函数返回值，并返回*/
	ret = CI_SUCCESS;
	return ret;
}


/**
 * @brief 设置UCT包络端点为计轴的端点
 * @param[in] UINT8 headorTail 包络头还是包络尾
 * @param[in] UINT16 acId 计轴ID
 * @param[in] EnvelopeStruct* ptemp 包络地址指针
 * @param[out] 无
 * @return CI_ERROR 处理错误
 *         CI_SUCCESS 处理正确
 * @note 无
 */
 UINT8 elm_SetUCTEnvelopeDot(UINT8 headorTail,UINT16 acId,IN const EnvelopeStruct* ptemp)
{
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = CI_ERROR;
	ELM_AxisLocStruct acpos = {0u};
	UINT8 cDir = 0U;

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

	/** 根据输入设置头/尾，选择使用的方向 */
	cDir = ELM_HEAD == headorTail ? ptemp->endPos.Dir : ptemp->startPos.Dir;

	/** 获取计轴的端点位置 */
	funRtn = elm_PrepareACLoc(acId, cDir, &acpos);

	if (CI_SUCCESS == funRtn)
	{
		if (ELM_HEAD == headorTail)
		{
			ret = elm_SetEnvelopeLoc(ptemp->id,ptemp->startPos,acpos.endPos);
		}
		else
		{
			ret = elm_SetEnvelopeLoc(ptemp->id,acpos.startPos,ptemp->endPos);
		}
	}
	else
	{
		/** 查询错误 */
	}

	return ret;
 }


 /**
 * @brief 查询包络内包含的包络离指定端点最近的包络
 * @param[in] UINT8 flag，包络头还是包络尾
 * @param[in] const EnvelopeStruct* pBase 基准包络
 * @param[in] UINT8 includeCnt 包络内包含的包络数量
 * @param[in] UINT16 includeELM[TRAIN_SUM_MAX_IN_OC] 包络内包含的包络id
 * @param[out] UINT16 *pEnvelopeid,找到的包络ID
 * @return CI_ERROR 查询失败
           CI_SUCCESS，查询正确
 * @note 无
 */
 UINT8 elm_SearchNearstEnvInInclude(UINT8 flag,IN const EnvelopeStruct* pBase,UINT8 includeCnt,UINT16 includeELM[TRAIN_SUM_MAX_IN_OC],OUT UINT16 *pEnvelopeid)
 {
	 UINT8 ret = CI_ERROR;
	 UINT32 errorCode = 0u;
	 UINT8 cycle = 0u;
	 UINT32 disHead = 0u;
	 UINT32 disTail = 0u;
	 UINT32 maxDisBtwHeadAndTail = 0u;
	 UINT32 maxDis = 0u;
	 const EnvelopeStruct *pTemp = NULL;
	 const EnvelopeStruct *pOut = NULL;


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

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

		 if (ELM_HEAD == flag)
		 {
			 /** 获取包络起终点离基准包络头的距离 */
			 disHead = elm_PrepareDistanceBtwPoints(pTemp->endPos,pBase->endPos);
			 disTail = elm_PrepareDistanceBtwPoints(pTemp->startPos,pBase->endPos);
		 }
		 else
		 {
			 /** 获取包络起终点离基准包络尾的距离 */
			 disHead = elm_PrepareDistanceBtwPoints(pTemp->endPos,pBase->startPos);
			 disTail = elm_PrepareDistanceBtwPoints(pTemp->startPos,pBase->startPos);
		 }

		 /** 获取最大值 */
		 maxDisBtwHeadAndTail = disHead > disTail ? disHead : disTail;

		 if (maxDis <= maxDisBtwHeadAndTail)
		 {
			 pOut = pTemp;
			 maxDis = maxDisBtwHeadAndTail;
		 }
		 else
		 {
			 /** 不处理 */
		 }			 
	 }

	 if ((0u == errorCode) && (NULL != pOut))
	 {
		 *pEnvelopeid = pOut->id;
	 }
	 else
	 {
		 /** 无需处理 */
	 }
	 /** 设置函数返回值 */
	 ASSER_DEBUG(0u != errorCode,ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Search Nearest Train In Base%d error.\n",errorCode,pBase->id));
	 ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	 return ret;
 }

 /**
 * @brief 刷新所有的列车 
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 无
 */
 void elm_RefreshTrainConstrolStatus(void)
 {
	 UINT32 errorCode = 0u;
	 UINT16 cycle = 0u;
	 UINT8 cFunRetVal = CI_ERROR;
	 UINT8 headNeedScreen = NEED_SCREEN;
	 UINT8 tailNeedScreen = NEED_SCREEN;
	 UINT8 trainStatus = OFFLINE_CONFIRM_STATUS;
	 UINT8 relEnvelopeCnt= TRAIN_REL_ENVELOPE_SUM_MAX;    /*列车关联的包络数量*/
	 UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] = {0u};  /*列车关联的包络索引*/
	 const EnvelopeStruct *pEnvelopeInfo = NULL;
	 const WLTrainStatusInfoStruct* pTemp = NULL;
	 UINT8 chTrainNvramPosFlag = 0U; /*列车NVRAM位置标识*/

	 /* 将本周期的的状态设置成上周期的状态 */
	 for (cycle = 1u; cycle < LINE_MAX_TRAIN; cycle++)
	 {
		 pTemp = wls_GetCurTrainStatusInfo(cycle);
		 ASSER_ERROR(NULL == pTemp,errorCode,0x80000000u);

		 if (NULL != pTemp)
		 {
			 cFunRetVal = wls_SetLastTrainStatusInfo(cycle, pTemp);
			 ASSER_ERROR(CI_ERROR == cFunRetVal,errorCode,0x40000000u);
		 }
		 else
		 {
			 /** 继续遍历 */
		 }
	 }

	 /** 刷新本周期列车状态信息 */
	 for (cycle = 1u; cycle < LINE_MAX_TRAIN; cycle++)
	 {
		 trainStatus = wls_GetTrainControlStatus(cycle);

		 if (OFFLINE_CONFIRM_STATUS != trainStatus)
		 {
			 wls_SetTrainControlStatus(cycle,OUT_CONTROL_STATUS,NEED_SCREEN,NEED_SCREEN);
		 }
		 else
		 {
			 /* 不处理 */
		 }
	 }

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

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

			 if ((NULL != pEnvelopeInfo) && 
				 ((TYPE_CT_ENVELOPE == pEnvelopeInfo->envelopeType) || (TYPE_UCT_ENVELOPE == pEnvelopeInfo->envelopeType)))
			 {
				 chTrainNvramPosFlag = GetTrainNvramPosFlag(cycle);

				 if (TRAIN_NVRAM_POS_FLAG_NO == chTrainNvramPosFlag)
				 {
					 headNeedScreen = LINE_MAX_TRAIN == pEnvelopeInfo->headTrainID ? NEED_SCREEN : UNNEED_SCREEN;
					 tailNeedScreen = LINE_MAX_TRAIN == pEnvelopeInfo->tailTrainID ? NEED_SCREEN : UNNEED_SCREEN;

					 wls_SetTrainControlStatus(cycle, IN_CONTROL_STATUS, headNeedScreen, tailNeedScreen);
				 }
				 else
				 {
					 ELM_LOG(ELM_LOG_FATAL, " not Add In Control Train,Because UseNvram Pos\n");
				 }		
			 }
			 else
			 {
				 /* 无需处理 */
			 }
		 }
		 else
		 {
			 /* 无需处理 */
		 }
	 }
 }


  /**
  * @brief 判断列车是否为下线车
  * @param[in] UINT16 trainID,列车ID
  * @param[in] UINT8 headNeedScreen, 需要前筛标志
  * @param[in] UINT8 tailNeedScreen, 需要尾筛标志
  * @param[out] 无
  * @return 无
  * @note 当最大安全前和最小安全后所属OC都不属于全线免筛区域，则认为是下线车
  */
 void elm_JudgeTrainOffline(UINT16 trainID, UINT8 headNeedScreen,UINT8 tailNeedScreen)
 {
	 UINT8 funRtn = CI_ERROR;

	 /** 获取列车位置是否在免筛区域 */
	 funRtn = elm_PrePareTrainLOCAreaType(trainID);

	 if (ELM_TRAIN_OUT_WLS_AREA == funRtn)
	 {
		 wls_SetTrainControlStatus(trainID,OFFLINE_CONFIRM_STATUS,headNeedScreen,tailNeedScreen);
	 }
	 else
	 {
		 /** 无须处理 */
	 }
 }

 /**
 * @brief 删除UCT或者CT包络不额外处理前后车前/后端
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out] 无
 * @return CI_ERROR 处理失败
 CI_SUCCESS 处理成功
 * @note
 */
 UINT8 elm_DeleteCTOrUCTUndoSuspic(UINT16 envelopeID)
 {
	 /*- 局部变量定义 */
	 UINT8 ret = CI_ERROR;
	 UINT8 funRet = CI_ERROR;
	 UINT8 cycle = 0u;
	 const EnvelopeStruct* pEnvelop = NULL;
	 UINT32 errorCode = 0u;
	 UINT16 tmpACindex = 0u;

	 /** 获取包络信息 */
	 pEnvelop = elm_GetEnvelopeInfoPtr(envelopeID);

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

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

			 /** 清除映射关系 */
			 funRet = elm_SetACRelEnvelopeMap(OP_DEL, tmpACindex, envelopeID);
			 ASSER_ERROR(CI_ERROR == funRet, errorCode, 0x20000000u);

			 /** 添加故障包络*/
			 funRet = elm_AddUKTEnvelopeInAC(pEnvelop->ACID[cycle]);
			 ASSER_ERROR(CI_ERROR == funRet, errorCode, 0x10000000u);
		 }

		 if (TYPE_CT_ENVELOPE == pEnvelop->envelopeType)
		 {
			 /** 清除列车关联的包络ID */
			 funRet = elm_SetTrainRelEnvelopeMap(OP_DEL, pEnvelop->trainID[0], pEnvelop->id);
			 ASSER_ERROR(CI_ERROR == funRet, errorCode, 0x08000000u);
		 }
		 else
		 {
			 for (cycle = 0u; cycle < pEnvelop->trianCnt; cycle++)
			 {
				 /** 清除列车关联的包络ID */
				 funRet = elm_SetTrainRelEnvelopeMap(OP_DEL, pEnvelop->trainID[cycle], pEnvelop->id);
				 ASSER_ERROR(CI_ERROR == funRet, errorCode, 0x04000000u);
			 }
		 }

		 /** 清空包络空间 */
		 funRet = elm_ClearEnvelope(pEnvelop->id);
		 ASSER_ERROR(CI_ERROR == funRet, errorCode, 0x02000000u);
	 }
	 else
	 {
		 /** 无需处理 */
	 }

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

 /**
 * @brief 获取包络相邻的本列车的其它包络
 * @param[in] UINT16 envelopeId
 * @param[out] UINT16 *preEnvelope 包络前方id
 * @param[out] UINT16 *backEnvelope 包络后方id
 * @return CI_ERROR 查询失败
		   CI_SUCCESS 查询成功
 * @note
 *  edit cgh 20250724 目前只用于RRM
 */
 UINT8 elm_GetNearEnvelopRelSameTra(UINT16 envelopeId, OUT UINT16* preEnvelope, OUT UINT16* backEnvelope)
 {
	 /*- 局部变量定义 */
	 UINT8 ret = CI_ERROR;
	 UINT8 funRet = CI_ERROR;
	 UINT32 errorCode = 0U;                         /*错误码*/
	 const EnvelopeStruct* pEnvelop = NULL;
	 UINT8 envelopeCnt = 0U;     /* 包络数量 */
	 UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] = { 0U };  /*包络ID数组*/
	 UINT16 acCnt = 0U;   /** 前方计轴数量*/
	 UINT16 acID[AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH] = { 0U };
	 UINT16 mergeACIndex = 0U;
	 UINT16 mergeACCntMax = (SECTION_IN_ENVELOPE_SUM_MAX + 2U * AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH);
	 UINT16 mergeACID[SECTION_IN_ENVELOPE_SUM_MAX + 2U * AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH] = { 0U };
	 UINT8 includeCnt = 0U;
	 UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] = { 0U };  /** 重合的包络id */

	 /** 获取列车包络 */
	 pEnvelop = elm_GetEnvelopeInfoPtr(envelopeId);

	 /** 判断包络是否正确*/
	 if ((NULL == pEnvelop) || (NULL == preEnvelope) || (NULL == backEnvelope))
	 {
		 /** 设置错误码*/
		 ASSER_ERROR(CI_ERROR == funRet, errorCode, 0x80000000U);
	 }
	 else
	 {
		 /* 查询后方计轴区段*/
		 acCnt = elm_GetEnvelopTailACIDs(pEnvelop, acID);

		 /** 合并车尾后方的计轴 */
		 mergeACIndex = elm_PrepareMergeUINT16Array(mergeACID, mergeACCntMax, mergeACIndex, acID, (AC_MAXCNT_IN_SWITCH * AC_MAXCNT_IN_SWITCH), acCnt);

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

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

		 if (0U == errorCode)
		 {
			 (void)CommonMemSet(&acID, (UINT32)((AC_MAXCNT_IN_SWITCH*AC_MAXCNT_IN_SWITCH)*sizeof(UINT16)),0U, (UINT32)((AC_MAXCNT_IN_SWITCH*AC_MAXCNT_IN_SWITCH)*sizeof(UINT16)));/*先清空数组防止脏数据*/
			 /* 查询前方计轴*/
			 acCnt = elm_GetEnvelopHeadACIDs(pEnvelop, acID);

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

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

			 /** 判断是否处理成功 */
			 if (0U == errorCode)
			 {
				 /** 获取前方计轴包含的包络 */
				 envelopeCnt = elm_MergeEnvelope(mergeACID, (UINT8)mergeACIndex, arEnvelopID);

				 /** 获取包络前后包络*/
				 funRet = elm_FindNearSameTrainEnvelop(pEnvelop, arEnvelopID, envelopeCnt, preEnvelope, backEnvelope, &includeCnt, includeELMid);

				 /** 设置错误码*/
				 ASSER_ERROR(CI_SUCCESS != funRet, errorCode, 0x10000000U);
			 }
			 else
			 {
				 /** 查询错误 */
			 }
		 }
		 else
		 {
			 /** 查询错误 */
		 }
	 }

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

 /**
 * @brief 查询基准包络前方最近的本车包络
 * @param[in] const EnvelopeStruct* pEnvelop 基准包络
 * @param[in] const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] 待比较的包络
 * @param[in] UINT8 envelopeCnt 待比较的包络数量
 * @param[out] UINT16 *preEnvelope 包络前方id
 * @param[out] UINT16 *backEnvelope 包络后方id
 * @param[out] UINT8 *includeCnt 包含的包络数量
 * @param[out] UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] 包含的包络ID
 * @return CI_ERROR 查询失败
		   CI_SUCCESS 查询成功
		   0xffu 包络存在重合包络

 * @note
 *  by cgh 20240514 目前只用于RRM
 */
 UINT8 elm_FindNearSameTrainEnvelop(IN const EnvelopeStruct* pEnvelop, IN const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC], UINT8 envelopeCnt, OUT UINT16* preEnvelope, OUT UINT16* backEnvelope, OUT UINT8* includeCnt, OUT UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC])
 {

	 /*- 局部变量定义 */
	 UINT8 ret = CI_ERROR;
	 UINT32 errorCode = 0u;
	 const EnvelopeStruct* pHead = NULL;
	 const EnvelopeStruct* pTail = NULL;
	 const EnvelopeStruct* pTemp = NULL;
	 UINT8 cycle = 0u;
	 UINT8 funRet = 0u;

	 /** 入口参数判断 */
	 if ((NULL == pEnvelop) || (NULL == arEnvelopID) || (NULL == preEnvelope) || (NULL == backEnvelope) || (NULL == includeCnt) || (NULL == includeELMid))
	 {
		 /** 入口参数校验 */
		 errorCode = errorCode + 0x80000000u;
		 ELM_LOG_LOC(ELM_LOG_ERROR, "errorCode:0x%08x info:input error!", errorCode)
	 }
	 else
	 {
		 /** 依次遍包络，查找前方包络 */
		 for (cycle = 0u; cycle < envelopeCnt; cycle++)
		 {
			 /** 通过包络ID查找包络信息 */
			 pTemp = elm_GetEnvelopeInfoPtr(arEnvelopID[cycle]);

			 /** 判断是否满足退出条件 */
			 ASSERT_BREAK(NULL == pTemp, errorCode, 0x04000000U);

			 /** 判断包络是否为本包络*/
			 if (pTemp->id == pEnvelop->id)
			 {
				 /** 本包络跳过 */
			 }
			 else if (pTemp->trainID[0] != pEnvelop->trainID[0])
			 {
				 /**非本车包络跳过 */
			 }
			 else
			 {
				 /** 比较两个包络的位置关系 */
				 funRet = elm_PrepareRelationBtwEnvelope(pEnvelop, pEnvelop->startPos, pTemp);

				 /** 判断是否满足退出条件 */
				 ASSERT_BREAK(0x00u == funRet, errorCode, 0x02000000u);

				 if (0x02u == funRet)
				 {
					 if (NULL == pHead)
					 {
						 pHead = pTemp;
					 }
					 else if (pTemp->id == pHead->id)
					 {
						 /** 本包络跳过 */
					 }
					 else
					 {
						 funRet = elm_PrepareRelationBtwEnvelope(pHead, pEnvelop->startPos, pTemp);
						 /** 判断是否满足退出条件 */
						 ASSERT_BREAK(0x00u == funRet, errorCode, 0x01000000u);

						 /** 判断是否需要更新前车包络*/
						 if (0x01u == funRet)
						 {
							 pHead = pTemp;
						 }
						 else
						 {
							 /** 不需要处理*/
						 }
					 }
				 }
				 else if (0x01u == funRet)
				 {
					 if (NULL == pTail)
					 {
						 pTail = pTemp;
					 }
					 else if (pTemp->id == pTail->id)
					 {
						 /** 本包络跳过 */
					 }
					 else
					 {
						 funRet = elm_PrepareRelationBtwEnvelope(pTail, pEnvelop->startPos, pTemp);
						 /** 判断是否满足退出条件 */
						 ASSERT_BREAK(0x00u == funRet, errorCode, 0x00800000u);

						 /** 判断是否需要更新前车包络*/
						 if (0x02u == funRet)
						 {
							 pTail = pTemp;
						 }
						 else
						 {
							 /** 不需要处理*/
						 }
					 }
				 }
				 else if ((TRAIN_SUM_MAX_IN_OC > (*includeCnt)) && ((0x03u == funRet) || (0x04u == funRet)))
				 {
					 includeELMid[(*includeCnt)] = pTemp->id;
					 (*includeCnt) += 1u;
				 }
				 else
				 {
					 /** 比较不出来，导向安全侧*/
					 ret = CI_ERROR;
					 break;
				 }
			 }
		 }

		 /** 设置函数返回值*/
		 if ((cycle == envelopeCnt) && (0u == (*includeCnt)))
		 {
			 (*preEnvelope) = (NULL == pHead) ? 0u : pHead->id;
			 (*backEnvelope) = (NULL == pTail) ? 0u : pTail->id;
			 ret = CI_SUCCESS;
		 }
		 else if ((cycle == envelopeCnt) && (0u != (*includeCnt)))
		 {
			 (*preEnvelope) = (NULL == pHead) ? 0u : pHead->id;
			 (*backEnvelope) = (NULL == pTail) ? 0u : pTail->id;
			 ret = 0xffu;
		 }
		 else
		 {
			 /** 函数处理错误*/
		 }
	 }

	 return ret;
 }

 /**
 * 功能描述： CT包络飞车检查
 * 参数说明：无
 * 返回值  ： CI_ERROR 存在飞车 CI_SUCCESS  不存在
 * BY fan 20241017
 */
 UINT8 elm_FlyingProtect_CT(void)
 {
	 /*- 局部变量定义 */
	 UINT8 ret = CI_ERROR;
	 UINT16 cycle = 0u;    /*循环变量*/
	 UINT16 cycleAc = 0u;
	 UINT8 trainCnt = 0u;		/*通信车数量*/
	 UINT16 trainID[TRAIN_SUM_MAX_IN_OC] = { 0u };   /*通信车ID*/
	 UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] = { 0u };  /*列车关联的包络索引*/
	 UINT16 relEnvelopeCnt = TRAIN_REL_ENVELOPE_SUM_MAX;    /*列车关联的包络数量*/
	 UINT16 tmpHeadAc = 0u;
	 UINT16 tmpTailAC = 0u;
	 UINT8 tmpHeadACStatus = ELM_AC_FREE;
	 UINT8 tmpTailACStatus = ELM_AC_FREE;
	 UINT8 tmpACStatus = ELM_AC_FREE;
	 const EnvelopeStruct* pEnvelop = NULL;
	 UINT32 errorCode = 0u;
	 UINT32 dwCurCyc = Get2oo2CurCycleNum();
	 UINT32 maxShutdownRedunTime = (UINT32)elm_PrepareCTFlyingRedunTime();
	 UINT32 dwFlyStartCyc = 0U;
	 UINT8 chTimeCheck = 0U;
	 UINT8 flyCheck = 0U;
	 UINT8 cNvramFlag = 0U;  /*列车使用NVRAM标志*/
	 UINT8 cPosMonistorState = 0U;  /*列车位置监督状态*/
	 UINT8 cFuncSwitch = 0U;  /*使用NVRAM位置且位置监督无效的列车飞车不宕机开关：0xAA-飞车不宕机 0x55-飞车宕机*/

	 /** CT飞车防护*/
	 trainCnt = elm_PrepareCommTrainID(trainID);
	 cFuncSwitch = GetCiFunctionSwitchConfig(FUNC_NVRAM_TRAIN_FlYING_OVER);
	 /** 遍历所有的通信车 */
	 for (cycle = 0u; cycle < trainCnt; cycle++)
	 {
		 /** 获取通信车对应的包络id */
		 relEnvelopeCnt = elm_GetRelELIdByTrainIDAndType(TYPE_CT_ENVELOPE, trainID[cycle], relEnvelopeID);

		 /** 获取列车包络 */
		 pEnvelop = elm_GetEnvelopeInfoPtr(relEnvelopeID[0u]);

		 /** 如果包络存在，则检查*/
		 if (NULL != pEnvelop)
		 {
			 /** 继续判断是否飞车 */
			 for (cycleAc = 0u; cycleAc < pEnvelop->ACCnt; cycleAc++)
			 {
				 /** 获取计轴状态 */
				 tmpACStatus = elm_PrepareACStatus(pEnvelop->ACID[cycleAc]);

				 /** 如果计轴占用，则正常跳出循环 */
				 ASSERT_BREAK(ELM_AC_OCC == tmpACStatus, errorCode, 0x00000000u);
			 }

			 if (cycleAc != pEnvelop->ACCnt)
			 {
				 /*CT包络存在占用计轴 */
				 SetTrainStartFlyProtectCycNum(trainID[cycle], 0U);
			 }
			 else
			 {
				 /** 可能是分界点出的包络，只有包络进入，实际轮对未进入，则获取最小安全前和最大安全后所属计轴*/
				 errorCode = 0u;

				 tmpHeadAc = elm_PrepareACOfMaxSafeTailLoc(trainID[cycle]);
				 tmpTailAC = elm_PrepareACOfMinSafeHeadLoc(trainID[cycle]);
				 ASSER_ERROR((0u == tmpHeadAc) || (0u == tmpTailAC), errorCode, 0x10000000u);

				 tmpHeadACStatus = elm_PrepareACStatus(tmpHeadAc);
				 tmpTailACStatus = elm_PrepareACStatus(tmpTailAC);
				 ASSER_ERROR((ELM_AC_FREE == tmpHeadACStatus) && (ELM_AC_FREE == tmpTailACStatus), errorCode, 0x08000000u);
				 if (0U != errorCode)
				 {
					 SetTrainStartFlyProtectCycNum(trainID[cycle], dwCurCyc);
					 dwFlyStartCyc = GetTrainStartFlyProtectCycNum(trainID[cycle]);
					 chTimeCheck = SystemOverTimeCheck(dwFlyStartCyc, (UINT32)maxShutdownRedunTime);
					 if (CI_TIME_OUT == chTimeCheck)
					 {
						 cNvramFlag = GetTrainNvramPosFlag(trainID[cycle]);
						 cPosMonistorState = GetTrainPosMonitorState(trainID[cycle]);
						 if ((TRAIN_NVRAM_POS_FLAG_YES == cNvramFlag) && (TRAIN_POS_MONITOR_VALID != cPosMonistorState) && (FUNC_SWITCH_ON == cFuncSwitch))
						 {
							 /*使用NVRAM位置且位置监督无效的列车飞车后，若NVRAM列车飞车不宕机开关打开，RC仅向列车发飞车特控报文，不宕机*/
							 AddNvramFlyingTrain(trainID[cycle]);
						 }
						 else
						 {
							 elm_AddFlyingTrain(trainID[cycle], pEnvelop->id);
						 }
					 }
					 flyCheck++;
				 }
				 else
				 {
					 SetTrainStartFlyProtectCycNum(trainID[cycle], 0U);
				 }
			 }
		 }
		 else
		 {
			 /** 由CT管理模块进行防护 */
		 }
	 }
	 if (0U == flyCheck)
	 {
		 ret = CI_SUCCESS;
	 }
	 else
	 {
		 ret = CI_ERROR;
	 }
	 return ret;
 }

 /**
 * 功能描述： UCT包络飞车检查
 * 参数说明：无
 * 返回值  ：无
 * edit cgh 20241028
 */
 void elm_FlyingProtect_UCT(void)
 {
	 UINT16 cycleAc = 0u;
	 UINT16 cycleELM = 0u;
	 UINT8 tmpACStatus = ELM_AC_FREE;
	 const EnvelopeStruct* pEnvelop = NULL;
	 UINT8 IsOwnFlag = ELM_BELONG_OWNER;
	 UINT32 errorCode = 0u;
	 UINT32 dwCurCyc = Get2oo2CurCycleNum();
	 UINT32 maxShutdownRedunTime = (UINT32)elm_PrepareCTFlyingRedunTime();
	 UINT32 dwFlyStartCyc = 0U;
	 UINT8 chTimeCheck = 0U;

	 /** 遍历所有的UCT包络 */
	 for (cycleELM = 1u; cycleELM < ENVELOPE_SUM_MAX; cycleELM++)
	 {
		 /** 获取包络信息缓存地址 */
		 pEnvelop = elm_GetEnvelopeInfoPtr(cycleELM);

		 if ((NULL == pEnvelop) || (TYPE_UCT_ENVELOPE != pEnvelop->envelopeType))
		 {
			 /** 包络不存在或者非UCT，不处理*/
		 }
		 else
		 {
			 /** 判断包络是否属于本OC */
			 IsOwnFlag = elm_PrepareEnvelopeIsSelf(pEnvelop);

			 if (ELM_BELONG_OTHER == IsOwnFlag)
			 {
				 /** 非本OC范围内的包络，无需处理 */
			 }
			 else
			 {
				 /** 继续判断是否飞车 */
				 for (cycleAc = 0u; cycleAc < pEnvelop->ACCnt; cycleAc++)
				 {
					 /** 获取计轴状态 */
					 tmpACStatus = elm_PrepareACStatus(pEnvelop->ACID[cycleAc]);

					 /** 如果计轴占用，则正常跳出循环 */
					 ASSERT_BREAK(ELM_AC_OCC == tmpACStatus, errorCode, 0x00000000u);

				 }
				 if (cycleAc != pEnvelop->ACCnt)
				 {
					 /** 说明UCT包络存在占用计轴 */
					 SetTrainFlyProStartCycNum(pEnvelop->trainID[0], 0U);
				 }
				 else
				 {
					 SetTrainFlyProStartCycNum(pEnvelop->trainID[0], dwCurCyc);
					 dwFlyStartCyc = GetTrainStartFlyProtectCycNum(pEnvelop->trainID[0]);
					 chTimeCheck = SystemOverTimeCheck(dwFlyStartCyc, (UINT32)maxShutdownRedunTime);
					 if (CI_TIME_OUT == chTimeCheck) 
					 {
						 SetTrainFlyProStartCycNum(pEnvelop->trainID[0], 0U);
						 /*清除好车通过、UCT删除为UKT，清除飞车防护周期号*/
						 elm_DeleteUctPassFlag(pEnvelop->id);
						 (void)elm_DeleteCTOrUCTEnvelope(pEnvelop->id);

						 debug_infor_printf((const)"\n UCT_FlyingProtect DeleteCTOrUCTEnvelope\n");
					 }
				 }
			 }
		 }
	 }
 }

 /**
* 功能描述： 删除UCT好车通过标志
* 参数说明：UINT16 envelopeId 包络id
* 返回值  ： 无
* by cgh 20241028
*/
void elm_DeleteUctPassFlag(UINT16 envelopeId)
{
	UINT8 jj = 0U;
	const EnvelopeStruct* pEnvelop = NULL;

	/** 获取包络信息缓存地址 */
	pEnvelop = elm_GetEnvelopeInfoPtr(envelopeId);
	if (NULL != pEnvelop)
	{
		for (jj = 0U; jj < pEnvelop->ACCnt; jj++)
		{
			(void)aam_ClearACPassTrainFlag(pEnvelop->ACID[jj]);
		}
	}
	else
	{
		; /*不处理*/
	}
	
}