#include "EvacuationAreaManage.h"
#include "LinkConfigDataManage.h"
#include "AxisConfigDataManage.h"
#include "AxisSectionConfigDataManage.h"
#include "LogicSectionConfigDataManage.h"
#include "TrainDataManage.h"
#include "ParsePackGateWayData.h"
#include "dquCIInterFace.h"
#include "ELMDataPrepare.h"

EaConfigStru g_szEaConfig[EA_CFG_SUM_MAX] = { 0u };			/* 防护区域配置数据 */
UINT16 g_eaConfigNum = 0u;
AxisSectionConfigDataStruct g_szEaAcConfig[AXIS_SECTION_SUM_MAX] = { 0u }; /* 全线计轴区段 */
UINT16 g_eaAcConfigNum = 0u;
static EaDataStru g_szEaData[EA_MAX_NUM] = { 0u };	/* 区间疏散区域数据 */
static UINT8 g_eaNum = 0u;									/* 正在建立和已建立的区间疏散防护区域数量 */

/**
* @brief 通信列车初次请求区间疏散区域建立
* @param
* @return
*/
static void EaCmdProc(void);

/**
* @brief 计算区间疏散区域
* @param chIndex 索引
* @param chType 类型
* @return CI_ERROR失败；CI_SUCCESS成功
* edit cgh 20250527
*/
static UINT8 EvacuationAreaCalcu(UINT8 chEaIndex, const UINT8 chType);

/**
* @brief 添加防护分区计轴区段
* @param chEaIndex 索引
* @param wAxisSecId 计轴区段ID
* @param chType 类型
* @param wTrainId 疏散列车ID
* @param chEaconfigId 防护分区编号
* @return CI_ERROR 失败
*         CI_SUCCESS 成功
* BY CGH 20250527
*/
static UINT8 AddEaAxisSec(UINT8 chEaIndex, UINT16 wAxisSecId, UINT8 chType, UINT16 wTrainId, UINT8 chEaconfigId);

/**
* @brief 检查是否添加特殊防护区域计轴区段
* @param const UINT16 wAcId 计轴区段编号
* @param const UINT16 wSpecialEaId 特殊防护区域编号
* @return UINT8_MAX 数据异常
*         CI_ERROR 不添加在补充区域
*         CI_SUCCESS 需要添加在补充区域
* by cgh 20250818
*/
static UINT8 CheckAddSpecialEaAxis(const UINT16 wAcId, const UINT16 wSpecialEaId);

/**
* @brief 获取所有通信车对某一疏散列车是否同意建立防护区域
* @param wEaTrainId 疏散列车ID
* @return CI_ERROR 不同意   CI_SUCCESS 同意
*/
static UINT8 GetAllCtTrainAgreeSetEva(UINT16 wEaTrainId);

/**
* @brief 计算疏散列车中轴线、疏散区域边缘公里标
* @param chType 类型
* @param wTrainId 疏散列车ID
* @param pMidLine 疏散列车中轴线公里标
* @param pMinEdge 疏散防护区域小公里标
* @param pMaxEdge 疏散防护区域大公里标
* @param pEaconfigId 疏散防护区域编号
* @param wSpecialEaId 特殊防护区域编号
* @return CI_ERROR 计算失败   CI_SUCCESS 计算成功
* edit cgh 20250310
*/
static UINT8 EaGetMidLineAndEdgeKm(const UINT8 chType, const UINT16 wTrainId, UINT8* pEaOut, UINT32* pMidLine, UINT32* pMinEdge, UINT32* pMaxEdge, UINT8* pEaconfigId, UINT16* wSpecialEaId);

/**
* @brief 查询两站一区间不含站台的防护区域相邻的站台防护公里标
* @param const UINT16 eaConfigIndex  防护区域索引
* @param const UINT32 wOrgnPointKmtemp 小端公里标
* @param const UINT32 wTmnlPointKmtemp 大端公里标
* @param UINT32* pMinEdge  输出防护区域最小公里标
* @param UINT32* pMaxEdge  输出防护区域最大公里标
* @return CI_ERROR 计算失败 CI_SUCCESS计算成功
* By LC 20231113
**/
UINT8 EaGetadjacentStationKM(const UINT16 eaConfigIndex, const UINT32 wOrgnPointKmtemp, const UINT32 wTmnlPointKmtemp, UINT32* pMinEdge, UINT32* pMaxEdge);

/**
* @brief 获取防护区域计轴区段索引
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段索引；AXIS_SECTION_SUM_MAX:查找失败
*/
static UINT16 EaGetAcIndex(const UINT16 wAcId);

/**
* @brief 获取防护区域计轴区段包含link数量
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含link数量；AXIS_INCLUDE_LINK_SUM_MAX:查找失败
*/
static UINT8 EaGetAcLinkNum(const UINT16 wAcId);

/**
* @brief 获取防护区域计轴区段包含起点计轴编号
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含link数量；AXIS_INCLUDE_LINK_SUM_MAX:查找失败
*/
static UINT16 EaGetAcOrgnAxisId(const UINT16 wAcId);

/**
* @brief 获取防护区域计轴区段包含终点计轴编号
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含link数量；AXIS_INCLUDE_LINK_SUM_MAX:查找失败
*/
static UINT16 EaGetAcTmnlAxisId(const UINT16 wAcId);

/**
* @brief 获取防护区域计轴区段包含link编号
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含link编号；NULL:查找失败
*/
static UINT16 * EaGetAcLinkId(const UINT16 wAcId);

/**
* @brief 获取防护区域计轴区段包含逻辑区段数量
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含逻辑区段数量；AXIS_INCLUDE_LOG_SUM_MAX:查找失败
*/
static UINT8 EaGetAcLgcNum(const UINT16 wAcId);

/**
* @brief 获取防护区域计轴区段包含逻辑区段编号
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含逻辑区段编号；NULL:查找失败
*/
static UINT16 * EaGetAcLgcId(const UINT16 wAcId);

/**
* @brief 区间疏散防护区域取消处理
* @param 无
* @return 无
*/
static void EaAtsCancleProc(void);

/**
* @brief 区间疏散防护区域首次取消处理
* @param 无
* @return 无
*/
static void EaAtsCancleFst(void);

/**
* @brief 区间疏散防护区域二次取消处理
* @param 无
* @return 无
*/
 static void EaAtsCancleSnd(void);

/**
* @brief 区间疏散防护区域取消执行
* @param 无
* @return 无
*/
static void EaAtsCancleExc(const UINT8 chEaIndex);

/**
* @brief 取消指定索引区间疏散防护区域
* @param const UINT8 chEaIndex 防护区域索引ID
* @return 无
* by cgh 20240321
*/
static void EaCancleExc(const UINT8 chEaIndex);

/*
* 功能描述： 判断区域所有区段均为本控区区段
* 参数说明： chEaIndex 疏散区域索引
* 返回值  ： CI_SUCCESS:全在本控区；CI_ERROR:不全在本控区
*/
static UINT8 EaIsLinkSeqAllLocal(UINT8 chEaIndex);

/**
* @brief 获取列车防护区域存储索引
* @param const UINT16 wTrainId
* @param const UINT8 chType
* @return 成功:索引，失败:g_eaNum
*/
static UINT8 PaGetIndex(const UINT16 wTrainId, const UINT8 chType);

/**
* @brief 计算防护分区是否完全在特殊防护区域
* @param wTrainId 疏散列车ID
* @param  UINT16* wSpecialEaId 特殊防护区域ID
* @return CI_ERROR 不完全在   CI_SUCCESS 完全在
* edit cgh 20250818
*/
static UINT8 CalcSpecialEa(const UINT16 wTrainId, UINT16* wSpecialEaId);

/**
* @brief 防护区域查询当前link的相邻link（目前仅用于出入段线特殊防护区域判断）
* @param struct_PathPoint pPoint 当前link信息
* @param UINT8 chDirection 查询方向
* @param UINT32 dwSearchLen	查询长度
* @return CI_SUCCESS 检查通过 CI_ERROR 检查失败
* BY CGH 20250818
*/
static UINT8 EaFindLinkAdjacentLinkID(struct_PathPoint pPoint, UINT8 chDirection, UINT32 dwSearchLen);

/**
* @brief 获取计轴区段特殊防护区域编号
* @param const UINT16 wAcId 计轴区段编号
* @return 特殊防护区域编号
* by cgh 20250826
*/
static UINT16 GetAxisSpecialEaId(const UINT16 wAcId);

/**
* @brief 初始化函数
* @param 无
* @return CI_ERROR 初始化失败   CI_SUCCESS 初始化成功
* by cgh 20250310
*/
UINT8 EaConfigInit(void)
{
	UINT16 wIndex = 0u;
	UINT16 wEaMode = 0u;
	UINT8 chRtn = CI_ERROR;
	UINT8 chPointIndex = 0u;
	UINT8 chStationFlag = CI_ERROR;
	UINT16 wPlatformEaMode = 0u;
	LOD_STRU pLODAStru = { 0U };/*起点位置*/
	LOD_STRU pLODBStru = { 0U };/*终点位置*/
	UINT16 wTempLinkSum = 0U;/*LINK数目*/
	UINT16 szTempLinkId[EA_SECTION_MAX_NUM] = { 0U };/*Link数组*/
	UINT8 chTempLinkIndex = 0U;/*临时LINK索引*/
	UINT8 chEndLinkIdIndex = 0U;/*终点LINK ID索引*/
	UINT8 chEaConfigLinkIndex = 0U;/*防护分区LINK索引*/
	UINT16 wAdjacentLinkId = 0U;/*相邻LINK ID*/

	/* 获取区间疏散防护区域建立方式 */
	wEaMode = GetSystemParaValue(EA_MODE_ID);
	wPlatformEaMode = GetSystemParaValue(EA_STATION_MODE_ID);

	if ((EA_MODE_PLATION != wEaMode) && (EA_MODE_SEC != wEaMode) && (EA_MODE_DIS != wEaMode))
	{
		; /* 配置区域计算方式不为两站一区间或者按距离计算时，TIOC初始化失败 */
	}
	else if ((EA_MODE_DIS == wEaMode) && (EA_STATION_MODE_DIS != wPlatformEaMode))
	{
		; /* 区间疏散按距离方式计算，站台疏散不为按距离计算时，TIOC初始化失败 */
	}
	else if ((EA_STATION_MODE_DIS != wPlatformEaMode) && (EA_STATION_MODE_PLAT != wPlatformEaMode))
	{
		; /* 站台疏散方式不为按距离或者仅站台，TIOC初始化失败 */
	}
	else
	{
		chRtn = CI_SUCCESS;
	}

	if (CI_SUCCESS == chRtn)
	{
		for (wIndex = 0U; wIndex < g_eaConfigNum; wIndex++)
		{
			if ((EA_MODE_PLATION == wEaMode) || (EA_MODE_SEC == wEaMode))
			{
				/* 两站一区间 计算区间LINK*/
				for (chPointIndex = 0U; chPointIndex < g_szEaConfig[wIndex].chStartLinkNum; chPointIndex++)
				{
					for (chEndLinkIdIndex = 0U; chEndLinkIdIndex < g_szEaConfig[wIndex].chEndLinkNum; chEndLinkIdIndex++)
					{
						pLODAStru.Lnk = g_szEaConfig[wIndex].szStartLinkId[chPointIndex];
						pLODAStru.Off = 0U;
						pLODAStru.Dir = g_szEaConfig[wIndex].szStartLinkDir[chPointIndex];

						pLODBStru.Lnk = g_szEaConfig[wIndex].szEndLinkId[chEndLinkIdIndex];
						pLODBStru.Off = 0U;
						pLODBStru.Dir = g_szEaConfig[wIndex].szEndLinkDir[chEndLinkIdIndex];

						/* 遍历起点，找出起点到终点路径*/
						chRtn = TwoPointPathSearch(&pLODAStru, &pLODBStru, &wTempLinkSum, szTempLinkId);


						if (CI_ERROR == chRtn)
						{
							break;
						}
						else
						{
							for (chTempLinkIndex = 0U; chTempLinkIndex < (UINT8)wTempLinkSum; chTempLinkIndex++)
							{
								/*去重，已经存在的LINK不再继续存储*/
								for (chEaConfigLinkIndex = 0U; chEaConfigLinkIndex < g_szEaConfig[wIndex].chEaConfigLinkSum; chEaConfigLinkIndex++)
								{
									if (szTempLinkId[chTempLinkIndex] == g_szEaConfig[wIndex].wSzEaConfigLinkId[chEaConfigLinkIndex])
									{
										/*已经存在该LINK数据*/
										break;
									}
									else
									{
										; /*继续检查*/
									}
								}

								if (chEaConfigLinkIndex == g_szEaConfig[wIndex].chEaConfigLinkSum)
								{
									if (EA_SECTION_MAX_NUM > g_szEaConfig[wIndex].chEaConfigLinkSum)
									{
										/*不存在，添加新的LINK*/
										g_szEaConfig[wIndex].wSzEaConfigLinkId[g_szEaConfig[wIndex].chEaConfigLinkSum] = szTempLinkId[chTempLinkIndex];
										g_szEaConfig[wIndex].chEaConfigLinkSum++;
									}
									else
									{
										/*数量超限*/
										chRtn = CI_ERROR;
										debug_infor_printf((const)" g_szEaConfig chEaConfigLinkSum more than Max.\r\n");
										break;
									}

								}
								else
								{
									;/*不添加*/
								}
							}
						}
					}
					if (CI_ERROR == chRtn)
					{
						break;
					}
					else
					{
						;
					}
				}
				if (CI_ERROR == chRtn)
				{
					;
				}
				else
				{
					if (0U == g_szEaConfig[wIndex].chEaConfigLinkSum)
					{
						debug_infor_printf((const)"wIndex:%d EaConfigInit chEaConfigLinkSum is zero\n", wIndex);
						chRtn = CI_ERROR;
					} 
					else
					{
						/*计算最终的区间相邻站台ID*/
						for (chPointIndex = 0U; chPointIndex < g_szEaConfig[wIndex].chStartLinkNum; chPointIndex++)
						{
							if (DIR_SAME == g_szEaConfig[wIndex].szStartLinkDir[chPointIndex])
							{
								/*起点和逻辑方向相同，取起点相邻LINK*/
								wAdjacentLinkId = GetLinkOrgnJointMainLkIdById(g_szEaConfig[wIndex].szStartLinkId[chPointIndex]);
							}
							else if (DIR_CONVERT == g_szEaConfig[wIndex].szStartLinkDir[chPointIndex])
							{
								/*起点和逻辑方向相反，取终点相邻LINK*/
								wAdjacentLinkId = GetLinkTmnlJointMainLkById(g_szEaConfig[wIndex].szStartLinkId[chPointIndex]);
							}
							else
							{
								chRtn = CI_ERROR;
							}

							if (CI_SUCCESS == chRtn)
							{
								chStationFlag = IsLinkPlatform(wAdjacentLinkId);
								if ((CI_SUCCESS == chStationFlag) && (EA_BD_LINK_SUM_MAX > g_szEaConfig[wIndex].chStartStationLinkSum))
								{
									/*不存在，添加新的LINK*/
									g_szEaConfig[wIndex].wSzStartStationLinkId[g_szEaConfig[wIndex].chStartStationLinkSum] = wAdjacentLinkId;
									g_szEaConfig[wIndex].chStartStationLinkSum++;
								}
								else
								{
									;
								}
							}
							else
							{
								debug_infor_printf((const)"EaConfigInit CalcStationStartLink fail.\r\n");
								break;
							}
						}

						if (CI_SUCCESS == chRtn)
						{
							for (chPointIndex = 0U; chPointIndex < g_szEaConfig[wIndex].chEndLinkNum; chPointIndex++)
							{
								if (DIR_SAME == g_szEaConfig[wIndex].szEndLinkDir[chPointIndex])
								{
									/*终点查询方向和逻辑方向相同，取起点相邻LINK*/
									wAdjacentLinkId = GetLinkOrgnJointMainLkIdById(g_szEaConfig[wIndex].szEndLinkId[chPointIndex]);
								}
								else if (DIR_CONVERT == g_szEaConfig[wIndex].szEndLinkDir[chPointIndex])
								{
									/*起点和逻辑方向相反，取终点相邻LINK*/
									wAdjacentLinkId = GetLinkTmnlJointMainLkById(g_szEaConfig[wIndex].szEndLinkId[chPointIndex]);
								}
								else
								{
									chRtn = CI_ERROR;
								}

								if (CI_SUCCESS == chRtn)
								{
									chStationFlag = IsLinkPlatform(wAdjacentLinkId);
									if((CI_SUCCESS == chStationFlag) && (EA_BD_LINK_SUM_MAX > g_szEaConfig[wIndex].chEndStationLinkSum))
									{
										g_szEaConfig[wIndex].wSzEndStationLinkId[g_szEaConfig[wIndex].chEndStationLinkSum] = wAdjacentLinkId;
										g_szEaConfig[wIndex].chEndStationLinkSum++;
									}
									else
									{
										;
									}
								}
								else
								{
									debug_infor_printf((const)"REaConfigInit CalcStationEndLink fail.\r\n");
									break;
								}
							}
						}
						else
						{
							; /*计算起点站台失败*/
						}
					}
				}
				
				if (CI_SUCCESS == chRtn)
				{
					debug_infor_printf((const)"wIndex:%d chEaConfigLinkSum = %d\n", wIndex, g_szEaConfig[wIndex].chEaConfigLinkSum);
					for (chPointIndex = 0U; chPointIndex < g_szEaConfig[wIndex].chEaConfigLinkSum; chPointIndex++)
					{
						debug_infor_printf((const)"%d/",g_szEaConfig[wIndex].wSzEaConfigLinkId[chPointIndex]);
					}
					debug_infor_printf((const)"\nwIndex:%x chStartStationLinkSum = %d\n", wIndex, g_szEaConfig[wIndex].chStartStationLinkSum);
					for (chPointIndex = 0U; chPointIndex < g_szEaConfig[wIndex].chStartStationLinkSum; chPointIndex++)
					{
						debug_infor_printf((const)"%d/", g_szEaConfig[wIndex].wSzStartStationLinkId[chPointIndex]);
					}

					debug_infor_printf((const)"\nwIndex:%x chEndStationLinkSum = %d\n", wIndex, g_szEaConfig[wIndex].chEndStationLinkSum);
					for (chPointIndex = 0U; chPointIndex < g_szEaConfig[wIndex].chEndStationLinkSum; chPointIndex++)
					{
						debug_infor_printf((const)"%d/",g_szEaConfig[wIndex].wSzEndStationLinkId[chPointIndex]);
					}
					debug_infor_printf((const)"\n");
				}
				else
				{
					break;
				}

			}
			else
			{
				; /*不是两站一区间不计算*/
			}
		}
	}
	else
	{
		; /* 初始化失败 */
	}
	return chRtn;
}

/**
* @brief 区间疏散主处理函数
* @return 无
*/
void EvacuationAreaProcess(void)
{
	UINT8 index = 0u;
	UINT16 wTrainId = 0u;
	UINT8 chBuildedFlag = 0u;
	UINT8 chEaCmd = 0u;
	UINT8 chTrainAgreeFlag = CI_ERROR;
	UINT8 chEaNum = 0u;
	UINT8 chLocalId = GetSystemParaLocalCiId();
	UINT8 chSwitch = GetCiFunctionSwitchConfig(FUNC_EA_SWITCH);
	UINT8 chDaSwitch = GetCiFunctionSwitchConfig(FUNC_DA_SWITCH);
	UINT8 chPaType = 0u;

	chEaNum = GetEaNum();
	if (EA_MAX_NUM >= chEaNum)
	{
		for (index = 0u; index < chEaNum; index++)
		{
			wTrainId = GetEvacuatingTrainIdByIndex(index);
			chPaType = GetPaTypeByIndex(index);
			if (PA_TYPE_EA == chPaType)
				{/* 区间疏散需要列车同意 */
					if ((0u != wTrainId) && (g_szEaData[index].chSrcTiocId == chLocalId))
					{/* 本控区为源控区 */
						chBuildedFlag = GetEaBuildedFlag(index);
						if (EA_IS_BUILDED == chBuildedFlag)
						{
							/* 区间疏散防护区域已建立：不处理 */
							;
						}
						else if (EA_IS_NOT_BUILDED == chBuildedFlag)
						{
							/* 区间疏散防护区域未建立：
							1、等待所有通信车回复同意建立*/
							chTrainAgreeFlag = GetAllCtTrainAgreeSetEva(wTrainId);
							if (0u != g_szEaData[index].chDstTiocId)
							{
								if ((CI_SUCCESS == chTrainAgreeFlag) && (EA_DST_ALLOWED_YES == g_szEaData[index].chDstAllowed))
								{
									g_szEaData[index].chBuildedFlag = EA_IS_BUILDED;
								}
								else
								{
									;
								}
							}
							else
							{
								if (CI_SUCCESS == chTrainAgreeFlag)
								{
									g_szEaData[index].chBuildedFlag = EA_IS_BUILDED;
								}
								else
								{
									;
								}
							}
						}
						else
						{
							/* 非法状态：不处理 */
							;
						}
					}
					else if ((0u != wTrainId) && (g_szEaData[index].chDstTiocId == chLocalId))
					{/* 本控区为目标控区 */
						chTrainAgreeFlag = GetAllCtTrainAgreeSetEva(wTrainId);
						if (CI_SUCCESS == chTrainAgreeFlag)
						{
							g_szEaData[index].chDstAllowed = EA_DST_ALLOWED_YES;
						}
						else
						{
							g_szEaData[index].chDstAllowed = EA_DST_ALLOWED_NO;
						}
					}
					else
					{
						/*非法情况*/
						;
					}
				}
			else
			{
				;
			}
		}
		/*通信车请求建立防护区域处理*/
		EaCmdProc();

		if (FUNC_SWITCH_ON == chSwitch)
		{
			/* ATS取消处理 */
			EaAtsCancleProc();
		}
		else
		{
			;
		}

		if (FUNC_SWITCH_ON == chDaSwitch)
		{
			/* ATS取消脱轨防护去处理 */
			DaAtsCancleProc();
		}
		else
		{
			;
		}
	}
	else
	{
		;
	}
}
/**
* @brief 通信列车初次请求区间疏散区域建立
* @param
* @return
*/
static void EaCmdProc(void)
{
	UINT8 i = 0u;
	UINT8 j = 0u;
	UINT8 chTrainEaCmd = 0u;
	UINT16 wTrainId = 0u;
	UINT16 wEvaId = 0u;
	UINT8 chFunRtn = CI_ERROR;
	UINT32 chTempRtn = CI_ERROR;
	UINT8 chTransState = 0u;
	UINT8 chZeroSpd = 0u;
	UINT8 chTiocType = 0u;
	UINT8 chLocalId = 0u;
	UINT8 chEaSwitch = GetCiFunctionSwitchConfig(FUNC_EA_SWITCH);
	UINT8 chDaSwitch = GetCiFunctionSwitchConfig(FUNC_DA_SWITCH);
	UINT8 chDerailment = 0u;
	UINT16 wLinkId = 0u;
	UINT16 wLinkTioc = 0u;

	chTiocType = GetLocalCiType(); /* 获取TIOC类型 */
	chLocalId = GetSystemParaLocalCiId();

	if ((CI_TYPE_ZX == chTiocType) || (CI_TYPE_SCX == chTiocType))
	{
		for (i = 0u; i < TRAIN_SUM_MAX; i++)/*遍历所有车*/
		{/* 遍历所有列车处理区间疏散命令 */
			wTrainId = GetTrainId(i);
			chTransState = GetTrainTransitmitStat(wTrainId);
			chTrainEaCmd = GetTrainEaCmd(wTrainId);
			chZeroSpd = GetTrainZeroState(wTrainId);

			if (((TRAIN_COMM_STATE_GOOD == chTransState) && (EA_PROTECT_BUILD == chTrainEaCmd) && (TRAIN_SPEED_ZERO_YES == chZeroSpd) && (FUNC_SWITCH_ON == chEaSwitch)))
			{
				for (j = 0u; j < g_eaNum; j++)/*遍历所有疏散区*/
				{
					/*判断通信车请求是否已经处理*/
					if ((wTrainId == g_szEaData[j].wTrainId) && (PA_TYPE_EA == g_szEaData[j].chPaType))
					{
						SetTrainEaCmd(wTrainId, EA_PROTECT_DEFAULT);
						break;
					}
				}

				if (g_eaNum == j)
				{
					if (EA_MAX_NUM > g_eaNum)
					{
						SetTrainEaCmd(wTrainId, EA_PROTECT_DEFAULT);
						g_szEaData[g_eaNum].wTrainId = wTrainId;
						g_szEaData[g_eaNum].chBuildedFlag = EA_IS_NOT_BUILDED;
						g_szEaData[g_eaNum].chSrcTiocId = chLocalId;
						g_szEaData[g_eaNum].chDstTiocId = 0u;
						g_szEaData[g_eaNum].chDstAllowed = EA_DST_ALLOWED_NO;
						g_szEaData[g_eaNum].chPaType = PA_TYPE_EA;
						g_szEaData[g_eaNum].dwEaBuildCycNum = Get2oo2CurCycleNum();
						/*添加计算的LinkI序列*/
						chFunRtn = EvacuationAreaCalcu(g_eaNum, PA_TYPE_EA);
						if (CI_SUCCESS == chFunRtn)
						{
							g_eaNum++;
						}
						else
						{
							g_szEaData[g_eaNum].wTrainId = 0u;
							g_szEaData[g_eaNum].chBuildedFlag = 0u;
							g_szEaData[g_eaNum].chSrcTiocId = 0u;
							g_szEaData[g_eaNum].chDstTiocId = 0u;
							g_szEaData[g_eaNum].chDstAllowed = 0u;
							g_szEaData[g_eaNum].chPaType = 0u;
							g_szEaData[g_eaNum].dwEaBuildCycNum = 0U;
							SetPlatOverFlag();
							debug_infor_printf((const)"EaCmdProc is to shutdown,because build EA fail");
						}
					}
					else
					{
						SetPlatOverFlag();
						debug_infor_printf((const)"EaCmdProc is to shutdown,because the number of g_eaNum exceeds the limit");
					}
				}
				else
				{
					;
				}
			}
			else
			{
				;
			}
		}

		for (i = 0u; i < TRAIN_SUM_MAX; i++)/*遍历所有车*/
		{/* 遍历所有列车处理列车脱轨 */
			wTrainId = GetTrainId(i);
			chDerailment = GetTrainDerailment(wTrainId);
			wLinkId = GetTrainMaxHeadLink(wTrainId);
			wLinkTioc = GetLinkManageTiocById(wLinkId);

			if ((FUNC_SWITCH_ON == chDaSwitch) && (TRAIN_DERAIL_NO != chDerailment)
				&& (wLinkTioc == chLocalId))
			{
				for (j = 0u; j < g_eaNum; j++)/*遍历所有疏散区*/
				{
					/*判断通信车请求是否已经处理*/
					if ((wTrainId == g_szEaData[j].wTrainId) && (PA_TYPE_DA == g_szEaData[j].chPaType))
					{
						break;
					}
				}

				if (g_eaNum == j)
				{
					if (EA_MAX_NUM > g_eaNum)
					{
						g_szEaData[g_eaNum].wTrainId = wTrainId;
						g_szEaData[g_eaNum].chBuildedFlag = EA_IS_BUILDED;
						g_szEaData[g_eaNum].chSrcTiocId = chLocalId;
						g_szEaData[g_eaNum].chDstTiocId = 0u;
						g_szEaData[g_eaNum].chDstAllowed = EA_DST_ALLOWED_NO;
						g_szEaData[g_eaNum].chPaType = PA_TYPE_DA;
						g_szEaData[g_eaNum].dwEaBuildCycNum = Get2oo2CurCycleNum();
						/*添加计算的LinkI序列*/
						chFunRtn = EvacuationAreaCalcu(g_eaNum, PA_TYPE_DA);
						if (CI_SUCCESS == chFunRtn)
						{
							g_eaNum++;
						}
						else
						{
							g_szEaData[g_eaNum].wTrainId = 0u;
							g_szEaData[g_eaNum].chBuildedFlag = 0u;
							g_szEaData[g_eaNum].chSrcTiocId = 0u;
							g_szEaData[g_eaNum].chDstTiocId = 0u;
							g_szEaData[g_eaNum].chDstAllowed = 0u;
							g_szEaData[g_eaNum].chPaType = 0u;
							g_szEaData[g_eaNum].dwEaBuildCycNum = 0U;
							SetPlatOverFlag();
							debug_infor_printf((const)"EaCmdProc is to shutdown,because build EA fail");
						}
					}
					else
					{
						SetPlatOverFlag();
						debug_infor_printf((const)"EaCmdProc is to shutdown,because the number of g_eaNum exceeds the limit");
					}
				}
				else
				{
					;
				}
			}
			else
			{
				;
			}
		}
	}
	else
	{
		; /* 非正线或试车线，不处理区间疏散 */
	}


}

/**
* @brief 计算区间疏散区域
* @param chIndex 索引
* @param chType 类型
* @return CI_ERROR失败；CI_SUCCESS成功
* edit cgh 20250527
*/
static UINT8 EvacuationAreaCalcu(UINT8 chEaIndex, const UINT8 chType)
{
	UINT8 rtnValue = CI_ERROR;
	UINT16 wTrainId = 0u;
	UINT32 dwKm1 = 0u;
	UINT32 dwKm2 = 0u;
	UINT32 dwKmTemp = 0u;
	UINT8 chIndex = 0u;
	UINT16 wOrgnAxleId = 0u;
	UINT16 wTmnlAxleId = 0u;
	UINT16 wAcIndex = 0u;
	UINT8 chLinkNum = 0u;
	UINT16 * pLinkIdBuff = NULL;
	UINT8 chLgcNum = 0u;
	UINT16 * pLgcIdBuff = NULL;
	UINT8 chLinkIndex = 0u;
	UINT8 chLgcIndex = 0u;
	UINT8 chEaAcIndex = 0u;
	UINT32 dwOrgnAxleKm = 0u;
	UINT32 dwTmnlAxleKm = 0u;
	UINT8 chEaOut = 0u;
	UINT8 chCalFlag = 0u;
	UINT8 chPlatformFlag = 0u;
	UINT16 wLinkTioc = 0u;
	UINT8 chLocalId = 0u;
	UINT32 dwKmTmpMin = 0u;
	UINT32 dwKmTmpMax = 0u;
	UINT8 dwEaConfigId = 0u;
	UINT16 wAxisBelLinkId = 0U;/*计轴关联LINK ID*/
	UINT16 wEaConfigIndex = 0U;/*防护区域配置数据索引*/
	UINT8 chAxisBelCiIdCheck = 0U; /*计轴区段所属联锁检查*/
	UINT8 chAcBelongCiId = 0U; /*计轴区段所属联锁ID*/
	UINT8 chAxisSecAddFlag = CI_ERROR;/*计轴区段是否加入防护区域标志*/
	UINT16 wSpecialEaId = 0U;/*特殊防护区域编号*/

	chLocalId = GetSystemParaLocalCiId(); /* 获取本地ID */

	wTrainId = GetEvacuatingTrainIdByIndex(chEaIndex); /* 获取对应索引疏散列车ID */

	/* 计算中轴线、防护区域边界公里标 */
	rtnValue = EaGetMidLineAndEdgeKm(chType, wTrainId, &chEaOut, &dwKmTemp, &dwKm2, &dwKm1, &dwEaConfigId,&wSpecialEaId);

	if (CI_SUCCESS == rtnValue)
	{
		g_szEaData[chEaIndex].dwMidLine = dwKmTemp;
		wEaConfigIndex = GetEaIndex(dwEaConfigId);

		for (wAcIndex = 0u; wAcIndex < g_eaAcConfigNum; wAcIndex++)
		{
			wOrgnAxleId = g_szEaAcConfig[wAcIndex].wOrgnAxisId;
			wTmnlAxleId = g_szEaAcConfig[wAcIndex].wTmnlAxisId;
			dwOrgnAxleKm = GetAxisKmById(wOrgnAxleId);
			dwTmnlAxleKm = GetAxisKmById(wTmnlAxleId);

			/* 找出大公里标放终端 */
			dwKmTmpMax = dwOrgnAxleKm > dwTmnlAxleKm ? dwOrgnAxleKm : dwTmnlAxleKm;
			dwKmTmpMin = dwOrgnAxleKm < dwTmnlAxleKm ? dwOrgnAxleKm : dwTmnlAxleKm;
			dwOrgnAxleKm = dwKmTmpMin;
			dwTmnlAxleKm = dwKmTmpMax;


			if ((EA_OUT_ONE == chEaOut) && (((dwOrgnAxleKm > dwKm2) && (dwOrgnAxleKm < dwKm1))
				|| ((dwTmnlAxleKm > dwKm2) && (dwTmnlAxleKm < dwKm1))
				|| ((dwOrgnAxleKm <= dwKm2) && (dwTmnlAxleKm >= dwKm1))))
			{
				/* 计算方式为按距离计算，向上取整（单个计轴器在范围内或者防护区域在计轴区段范围内） */
				chCalFlag = FLAG_SET;
			}
			else if ((EA_OUT_TWO == chEaOut) && (((dwOrgnAxleKm > dwKm2) && (dwOrgnAxleKm < dwKm1))
				|| ((dwTmnlAxleKm > dwKm2) && (dwTmnlAxleKm < dwKm1))
				|| ((dwOrgnAxleKm <= dwKm2) && (dwTmnlAxleKm >= dwKm1))))
			{
				/* 计算方式为仅站台，只取站台计轴区段 */
				pLinkIdBuff = EaGetAcLinkId(g_szEaAcConfig[wAcIndex].AxisSectionId);
				if (NULL == pLinkIdBuff)
				{
					rtnValue = CI_ERROR;
					break;
				}
				else
				{
					;
				}

				chPlatformFlag = IsLinkPlatform(pLinkIdBuff[0]);
				if (CI_SUCCESS == chPlatformFlag)
				{
					chCalFlag = FLAG_SET;
				}
				else
				{
					chCalFlag = FLAG_UNSET;
				}
			}
			else if ((EA_OUT_FIVE == chEaOut) || (EA_OUT_THREE == chEaOut) || (EA_OUT_FOUR == chEaOut) || (EA_OUT_SIX == chEaOut))
			{
				chCalFlag = FLAG_UNSET;
				/*两站一区间方式区间需要全部建立*/
				wAxisBelLinkId = g_szEaAcConfig[wAcIndex].szLinkIdBuff[0U];

				for (chIndex = 0U; chIndex < g_szEaConfig[wEaConfigIndex].chEaConfigLinkSum; chIndex++)
				{
					if (wAxisBelLinkId == g_szEaConfig[wEaConfigIndex].wSzEaConfigLinkId[chIndex])
					{
						/*区间防护区域中存在该LINK，则添加*/
						break;
					} 
					else
					{
						;
					}
				}

				if (chIndex < g_szEaConfig[wEaConfigIndex].chEaConfigLinkSum)
				{
					chCalFlag = FLAG_SET;
				} 
				else
				{
					;
				}

				if ((EA_OUT_SIX == chEaOut) || (EA_OUT_THREE == chEaOut))
				{
					/*两站一区间包含站台或（不包含站台但是车头或者车尾在起点关联站台）*/
					for (chIndex = 0U; chIndex < g_szEaConfig[wEaConfigIndex].chStartStationLinkSum; chIndex++)
					{
						if (wAxisBelLinkId == g_szEaConfig[wEaConfigIndex].wSzStartStationLinkId[chIndex])
						{
							/*区间防护区域中存在该LINK，则添加*/
							break;
						}
						else
						{
							;
						}
					}

					if (chIndex < g_szEaConfig[wEaConfigIndex].chStartStationLinkSum)
					{
						chCalFlag = FLAG_SET;
					}
					else
					{
						;
					}
				}
				else
				{
					;
				}

				if ((EA_OUT_SIX == chEaOut) || (EA_OUT_FOUR == chEaOut))
				{
					/*两站一区间包含站台或（不包含站台但是车头或者车尾在终点站台）*/
					for (chIndex = 0U; chIndex < g_szEaConfig[wEaConfigIndex].chEndStationLinkSum; chIndex++)
					{
						if (wAxisBelLinkId == g_szEaConfig[wEaConfigIndex].wSzEndStationLinkId[chIndex])
						{
							/*区间防护区域中存在该LINK，则添加*/
							break;
						}
						else
						{
							;
						}
					}

					if (chIndex < g_szEaConfig[wEaConfigIndex].chEndStationLinkSum)
					{
						chCalFlag = FLAG_SET;
					}
					else
					{
						;
					}
				}
				else
				{
					; 
				}
				
			}
			else if (EA_OUT_SEVEN == chEaOut)
			{
				/*无实际处理*/
				;
			}
			else
			{
				chCalFlag = FLAG_UNSET;
			}

			if (FLAG_SET == chCalFlag)
			{
				/*添加公里标范围内的计轴区段*/
				rtnValue = AddEaAxisSec(chEaIndex, g_szEaAcConfig[wAcIndex].AxisSectionId, chType, wTrainId, dwEaConfigId);

				if (CI_ERROR == rtnValue)
				{
					break;
				}
				else
				{
					;
				}
			}
			else
			{
				;
			}
		}

		
	}

	if (CI_SUCCESS == rtnValue)
	{
		if (0U == wSpecialEaId)
		{
			/*可能完全在正线，需要补充建立防护区域*/
			/* 遍历计算出的计轴区段序列 */
			for (chEaAcIndex = 0u; chEaAcIndex < g_szEaData[chEaIndex].strAcInfo.chObjNum; chEaAcIndex++)
			{
				wSpecialEaId = GetAxisSpecialEaId(g_szEaData[chEaIndex].strAcInfo.szObjId[chEaAcIndex]);

				if (0U != wSpecialEaId)
				{
					break;
				}
				else
				{
					; /*继续查找*/
				}
			}
		}
		else
		{
			; /*已经算出来了特殊防护区域ID*/
		}

		if (0U != wSpecialEaId)
		{
			/*具备特殊区域属性才有可能为补充防护区域*/
			for (wAcIndex = 0U; wAcIndex < g_eaAcConfigNum; wAcIndex++)
			{
				chAxisSecAddFlag = CheckAddSpecialEaAxis(g_szEaAcConfig[wAcIndex].AxisSectionId, wSpecialEaId);

				if (CI_SUCCESS == chAxisSecAddFlag)
				{
					rtnValue = AddEaAxisSec(chEaIndex, g_szEaAcConfig[wAcIndex].AxisSectionId, chType, wTrainId, dwEaConfigId);
				}
				else if (CI_ERROR == chAxisSecAddFlag)
				{
					; /*不添加*/
				}
				else
				{
					rtnValue = CI_ERROR; /*数据异常*/
				}

				if (CI_ERROR == rtnValue)
				{
					break;
				}
				else
				{
					;
				}
			}
		}
		else
		{
			; /*不添加补充区域*/
		}
	}

	if (CI_SUCCESS == rtnValue)
	{
		/* 遍历计算出的计轴区段序列 */
		for (chEaAcIndex = 0u; chEaAcIndex < g_szEaData[chEaIndex].strAcInfo.chObjNum; chEaAcIndex++)
		{
			chLinkNum = EaGetAcLinkNum(g_szEaData[chEaIndex].strAcInfo.szObjId[chEaAcIndex]);
			pLinkIdBuff = EaGetAcLinkId(g_szEaData[chEaIndex].strAcInfo.szObjId[chEaAcIndex]);
			if ((0u == chLinkNum) || (NULL == pLinkIdBuff))
			{/* 计轴区段ID错误 */
				rtnValue = CI_ERROR;
				(void)CommonMemSet(g_szEaData[chEaIndex].strLinkInfo.szObjId, (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM), 0u, (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM));
				g_szEaData[chEaIndex].strLinkInfo.chObjNum = 0u;
				break;
			}
			else
			{/* 将计轴区段序列包含的所有link去重记录 */
				for (chLinkIndex = 0u; chLinkIndex < chLinkNum; chLinkIndex++)
				{
					for (chIndex = 0u; chIndex < g_szEaData[chEaIndex].strLinkInfo.chObjNum; chIndex++)
					{
						if (g_szEaData[chEaIndex].strLinkInfo.szObjId[chIndex] == pLinkIdBuff[chLinkIndex])
						{
							break;
						}
						else
						{
							;
						}
					}
					if (chIndex == g_szEaData[chEaIndex].strLinkInfo.chObjNum)
					{
						if (EA_SECTION_MAX_NUM > g_szEaData[chEaIndex].strLinkInfo.chObjNum)
						{
							g_szEaData[chEaIndex].strLinkInfo.szObjId[g_szEaData[chEaIndex].strLinkInfo.chObjNum] = pLinkIdBuff[chLinkIndex];
							g_szEaData[chEaIndex].strLinkInfo.chObjNum++;
							wLinkTioc = GetLinkManageTiocById(pLinkIdBuff[chLinkIndex]);
							if ((UINT8)wLinkTioc != chLocalId)
							{/* 疏散防护区域跨控区，找出目标TIOC编号 */
								g_szEaData[chEaIndex].chDstTiocId = (UINT8)wLinkTioc;
							}
							else
							{
								;
							}
						}
						else
						{
							;
						}
					}
					else
					{
						;
					}
				}
			}
		}
	}

	if (CI_SUCCESS == rtnValue)
	{
		/* 遍历计算出的计轴区段序列 */
		for (chEaAcIndex = 0u; chEaAcIndex < g_szEaData[chEaIndex].strAcInfo.chObjNum; chEaAcIndex++)
		{
			chLgcNum = EaGetAcLgcNum(g_szEaData[chEaIndex].strAcInfo.szObjId[chEaAcIndex]);
			pLgcIdBuff = EaGetAcLgcId(g_szEaData[chEaIndex].strAcInfo.szObjId[chEaAcIndex]);
			if ((0u == chLgcNum) || (NULL == pLgcIdBuff))
			{/* 计轴区段ID错误 */
				rtnValue = CI_ERROR;
				(void)CommonMemSet(g_szEaData[chEaIndex].strLgcInfo.szObjId, (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM), 0u, (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM));
				g_szEaData[chEaIndex].strLgcInfo.chObjNum = 0u;
				break;
			}
			else
			{/* 将计轴区段序列包含的所有逻辑区段去重记录 */
				for (chLgcIndex = 0u; chLgcIndex < chLgcNum; chLgcIndex++)
				{
					for (chIndex = 0u; chIndex < g_szEaData[chEaIndex].strLgcInfo.chObjNum; chIndex++)
					{
						if (g_szEaData[chEaIndex].strLgcInfo.szObjId[chIndex] == pLgcIdBuff[chLgcIndex])
						{
							break;
						}
						else
						{
							;
						}
					}
					if (chIndex == g_szEaData[chEaIndex].strLgcInfo.chObjNum)
					{
						if (EA_SECTION_MAX_NUM > g_szEaData[chEaIndex].strLgcInfo.chObjNum)
						{
							g_szEaData[chEaIndex].strLgcInfo.szObjId[g_szEaData[chEaIndex].strLgcInfo.chObjNum] = pLgcIdBuff[chLgcIndex];
							g_szEaData[chEaIndex].strLgcInfo.chObjNum++;
						}
						else
						{
							;
						}
					}
					else
					{
						;
					}
				}
			}

		}
	}

	if (CI_SUCCESS == rtnValue)
	{
		/*更新线路上下行属性*/
		RefreshEaLineType(chEaIndex);
	}

	if (CI_SUCCESS == rtnValue)
	{
		debug_infor_printf((const)"Train:%x PaType = %x\n", wTrainId, g_szEaData[chEaIndex].chPaType);

		debug_infor_printf((const)"Train:%x pMidLine = %u  pMinEdge = %u  pMaxEdge = %u\n", wTrainId,dwKmTemp,dwKm2,dwKm1);

		debug_infor_printf((const)"Train:%x PaAcSeq:num = %d\n", wTrainId, g_szEaData[chEaIndex].strAcInfo.chObjNum);
		for (chEaAcIndex = 0U; chEaAcIndex < g_szEaData[chEaIndex].strAcInfo.chObjNum; chEaAcIndex++)
		{
			debug_infor_printf((const)"%d/", g_szEaData[chEaIndex].strAcInfo.szObjId[chEaAcIndex]);
		}

		debug_infor_printf((const)"\nTrain:%x PaLinkSeq:num = %d\n", wTrainId, g_szEaData[chEaIndex].strLinkInfo.chObjNum);
		for (chEaAcIndex = 0U; chEaAcIndex < g_szEaData[chEaIndex].strLinkInfo.chObjNum; chEaAcIndex++)
		{
			debug_infor_printf((const)"%d/", g_szEaData[chEaIndex].strLinkInfo.szObjId[chEaAcIndex]);
		}

		debug_infor_printf((const)"\nTrain:%x PaLgcSeq:num = %d\n", wTrainId, g_szEaData[chEaIndex].strLgcInfo.chObjNum);
		for (chEaAcIndex = 0U; chEaAcIndex < g_szEaData[chEaIndex].strLgcInfo.chObjNum; chEaAcIndex++)
		{
			debug_infor_printf((const)"%d/", g_szEaData[chEaIndex].strLgcInfo.szObjId[chEaAcIndex]);
		}

		debug_infor_printf((const)"\n");
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 获取指定正在疏散的列车ID
* @param chIndex 下标
* @return 列车ID
*/
UINT16 GetEvacuatingTrainIdByIndex(UINT8 chIndex)
{
	UINT16 rtnValue = 0u;

	if (EA_MAX_NUM > chIndex)
	{
		rtnValue = g_szEaData[chIndex].wTrainId;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 获取区间疏散区域建立标志位
* @param chIndex 下标
* @return 0默认值；EA_IS_BUILDED已建立；EA_IS_NOT_BUILDED未建立
*/
UINT8 GetEaBuildedFlag(UINT8 chIndex)
{
	UINT8 rtnValue = 0u;

	if (EA_MAX_NUM > chIndex)
	{
		rtnValue = g_szEaData[chIndex].chBuildedFlag;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 获取区间疏散区域包含link数量
* @param chIndex 下标
* @return 区间疏散区域包含link数量
*/
UINT8 GetEaLinkNum(UINT8 chIndex)
{
	UINT8 rtnValue = 0u;

	if ((EA_MAX_NUM > chIndex) && (EA_SECTION_MAX_NUM >= g_szEaData[chIndex].strLinkInfo.chObjNum))
	{
		rtnValue = g_szEaData[chIndex].strLinkInfo.chObjNum;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 获取区间疏散区域包含link编号
* @param chIndex 下标
* @return 区间疏散区域包含link编号
*/
UINT16 * GetEaLinkBuff(UINT8 chIndex)
{
	UINT16 * rtnValue = NULL;

	if (EA_MAX_NUM > chIndex)
	{
		rtnValue = g_szEaData[chIndex].strLinkInfo.szObjId;
	}

	return rtnValue;
}

/**
* @brief 获取需要建立的区间疏散区域个数
* @param 无
* @return 需要建立的区间疏散区域个数
*/
UINT8 GetEaNum(void)
{
	UINT8 rtnValue = EA_MAX_NUM + 1U;/*输出为EA_MAX_NUM是正常个数*/
	if (EA_MAX_NUM >= g_eaNum)
	{
		rtnValue = g_eaNum;
	}
	return rtnValue;
}

/**
* @brief 获取所有通信车对某一疏散列车是否同意建立防护区域
* @param wEaTrainId 疏散列车ID
* @return CI_ERROR 不同意   CI_SUCCESS 同意
*/
static UINT8 GetAllCtTrainAgreeSetEva(UINT16 wEaTrainId)
{
	UINT8 rtnValue = CI_ERROR;
	UINT8 cRetVal = EA_PROTECT_BUILD_N;
	UINT8 i = 0u;
	UINT8 j = 0u;
	UINT8 chEaNum = 0u;
	UINT8 chNoFindNum = 0u;
	UINT8 chAllowFlag = 0u;
	UINT8 chComState = 0u;
	UINT16 wTrainId = 0u;
	TrainEaStru * pTrainEaInfo = NULL;
	UINT8 chMsgFromTiocId = 0u;
	UINT8 chLevel = 0u;
	UINT32 dwBuildCycNum = 0u; /*该列车疏散建立周期号*/
	UINT8 chEaIndex = 0U;
	cRetVal = EA_PROTECT_BUILD_Y;

	/*查找index 和建立周期*/
	for (chEaIndex = 0u; chEaIndex < g_eaNum; chEaIndex++)
	{
		if ((wEaTrainId == g_szEaData[chEaIndex].wTrainId) &&(PA_TYPE_EA == g_szEaData[chEaIndex].chPaType))
		{
			break;
		}
		else
		{
			; /* 继续遍历 */
		}
	}
	dwBuildCycNum = EaGetBuildCycNum(chEaIndex);

	for (i = 0u; i < TRAIN_SUM_MAX; i++)        /*遍历所有的通信车*/
	{
		wTrainId = GetTrainId(i);
		chComState = GetTrainTransitmitStat(wTrainId);
		chMsgFromTiocId = GetTrainMsgFromTiocId(wTrainId);
		chLevel = GetTrainLevel(wTrainId);
		if ((TRAIN_COMM_STATE_GOOD != chComState) || (0u != chMsgFromTiocId) || (TRAIN_LEVEL_VBTC != chLevel))/*非升级车不处理*/
		{
			;
		}
		else
		{
			chNoFindNum = 0u;
			chEaNum = GetTrainEaNum(wTrainId); /*获取通信车车载回复的区间疏散数量*/
			
			pTrainEaInfo = GetTrainEaInfo(wTrainId);
			if (NULL == pTrainEaInfo)
			{
				cRetVal = EA_PROTECT_BUILD_N;
			}
			else
			{
				for (j = 0u; j < chEaNum; j++)
				{
					if (pTrainEaInfo[j].wEaTrainId == wEaTrainId)
					{
						chAllowFlag = pTrainEaInfo[j].chAgreeState;
						if ((EA_PROTECT_BUILD_Y == chAllowFlag) &&(dwBuildCycNum == pTrainEaInfo[j].dwBuildCyc))
						{
							/*同意建立且周期号一致*/
							cRetVal = EA_PROTECT_BUILD_Y;
						}
						else
						{
							cRetVal = EA_PROTECT_BUILD_N;
							debug_infor_printf((const)"Train:%d Not allowe Tirain%d to buildEA, buildCyc：%d--answerCyc:%d\n", wTrainId, wEaTrainId, dwBuildCycNum, pTrainEaInfo[j].dwBuildCyc);
						}
						break;
					}
					else  /*记录没有找到对应ID的次数*/
					{
						chNoFindNum++;
					}
				}
			}

			if ((EA_PROTECT_BUILD_N == cRetVal) || (chEaNum == chNoFindNum))/*如果有一辆车没同意，或列车没收到对应的疏散列车ID*/
			{
				/* 不同意，跳出 */
				cRetVal = EA_PROTECT_BUILD_N;
				debug_infor_printf((const)"Train:%x not allowed to build %d\n", wTrainId, wEaTrainId);
				break;
			}
			else
			{
				; /* 本车同意继续遍历 */
			}
		}
	}

	if (EA_PROTECT_BUILD_Y == cRetVal)
	{
		rtnValue = CI_SUCCESS;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 计算疏散列车中轴线、疏散区域边缘公里标
* @param chType 类型
* @param wTrainId 疏散列车ID
* @param pMidLine 疏散列车中轴线公里标
* @param pMinEdge 疏散防护区域小公里标
* @param pMaxEdge 疏散防护区域大公里标
* @param pEaconfigId 疏散防护区域编号
* @param wSpecialEaId 特殊防护区域编号
* @return CI_ERROR 计算失败   CI_SUCCESS 计算成功
* edit cgh 20250310
*/
static UINT8 EaGetMidLineAndEdgeKm(const UINT8 chType, const UINT16 wTrainId, UINT8 * pEaOut, UINT32 * pMidLine, UINT32 * pMinEdge, UINT32 * pMaxEdge, UINT8 * pEaconfigId, UINT16* wSpecialEaId)
{
	UINT16 wMaxHeadLink = 0u;
	UINT32 dwMaxHeadOff = 0u;
	UINT16 wMinTailLink = 0u;
	UINT32 dwMinTailOff = 0u;
	UINT32 dwMaxHeadKm = 0u;
	UINT32 dwMinTailKm = 0u;
	UINT8 chRtn = CI_ERROR;
	UINT16 wEaMode = 0u;
	UINT16 wEaStationMode = 0u;
	UINT8 chTrainDir_Maxhead = 0u; /*以列车大前方向作为基准*/
	UINT8 chTrainDir_outTail = 0u;  /*车尾向外的方向，小后方向取反*/
	UINT32 dwFrontDis = 0u;
	UINT32 dwBehindDis = 0u;
	UINT32 dwKm1 = 0u;  /*车头疏散区域边缘公里标*/
	UINT32 dwKm2 = 0u;  /*车尾疏散区域边缘公里标*/
	UINT8 chPlatformFlag = CI_ERROR;
	UINT16 wIndex = 0u;
	UINT8 chTailPlatFlag = CI_ERROR;
	UINT16 wACOfMaxSafeHeadLoc = 0u;		/*列车最大安全前所属计轴ID*/
	UINT16 wACOfMinSafeTailLoc = 0u;		/*列车最小安全后所属计轴ID*/
	UINT16 wMaxHeadLinkOrgnPointID = 0u;		/*车头计轴区段起点端点ID*/
	UINT16 wMaxHeadLinkTmnlPointID = 0u;		/*车头计轴区段终点端点ID*/
	UINT16 wMinTailLinkOrgnPointID = 0u;        /*车尾计轴区段起点端点ID*/
	UINT16 wMinTailLinkTmnlPointID = 0u;		/*车尾计轴区段终点端点ID*/
	UINT32 wMaxHeadLinkOrgnPointKm = 0u;		/*车头计轴区段起点公里标*/
	UINT32 wMaxHeadLinkTmnlPointKm = 0u;		/*车头计轴区段终点公里标*/
	UINT32 wMinTailLinkOrgnPointKm = 0u;        /*车尾计轴区段起点公里标*/
	UINT32 wMinTailLinkTmnlPointKm = 0u;		/*车尾计轴区段终点公里标*/
	UINT16 wBasicLinkId = 0U;/*基准LINK ID*/
	UINT8 chConfigLinkIndex = 0U;/*配置数据中LINK索引*/
	UINT8 chCalcSpecialEa = 0U;/*特殊防护区域计算*/
	
	/* 获取列车位置 */
	wMaxHeadLink = GetTrainMaxHeadLink(wTrainId);
	dwMaxHeadOff = GetTrainMaxHeadOffset(wTrainId);
	wMinTailLink = GetTrainMinTailLink(wTrainId);
	dwMinTailOff = GetTrainMinTailOffset(wTrainId);
	chTrainDir_Maxhead = GetTrainDir_MaxHead(wTrainId);
	chTrainDir_outTail = GetTrainDir(wTrainId);

	wACOfMaxSafeHeadLoc = elm_PrepareACOfMaxSafeHeadLoc(wTrainId);		/*获取计轴ID*/
	wACOfMinSafeTailLoc = elm_PrepareACOfMinSafeTailLoc(wTrainId);

	/*获取列车位置计轴区段的起点终点ID*/
	wMaxHeadLinkOrgnPointID = EaGetAcOrgnAxisId(wACOfMaxSafeHeadLoc);		/*车头*/
	wMaxHeadLinkTmnlPointID = EaGetAcTmnlAxisId(wACOfMaxSafeHeadLoc);
	wMinTailLinkOrgnPointID = EaGetAcOrgnAxisId(wACOfMinSafeTailLoc);		/*车尾*/
	wMinTailLinkTmnlPointID = EaGetAcTmnlAxisId(wACOfMinSafeTailLoc);
	
	/* 判断列车位置有效性 */
	chRtn = CheckLinkValid(wMaxHeadLink, dwMaxHeadOff);
	chRtn &= CheckLinkValid(wMinTailLink, dwMinTailOff);

	if ((CI_ERROR == chRtn) || (NULL == pMidLine)
		|| (NULL == pMinEdge) || (NULL == pMaxEdge)
		|| ((DIR_SAME != chTrainDir_Maxhead) && (DIR_CONVERT != chTrainDir_Maxhead)))
	{/* 入参检查失败，返回失败  */
		chRtn = CI_ERROR;
	}
	else
	{
		dwMaxHeadKm = GetPointKm(wMaxHeadLink, dwMaxHeadOff);
		dwMinTailKm = GetPointKm(wMinTailLink, dwMinTailOff);
		/*获取车头尾起点终点计轴器的公里标*/
		wMaxHeadLinkOrgnPointKm = GetAxisKmById(wMaxHeadLinkOrgnPointID);		/*车头公里标*/
		wMaxHeadLinkTmnlPointKm = GetAxisKmById(wMaxHeadLinkTmnlPointID);
		wMinTailLinkOrgnPointKm = GetAxisKmById(wMinTailLinkOrgnPointID);		/*车尾公里标*/
		wMinTailLinkTmnlPointKm = GetAxisKmById(wMinTailLinkTmnlPointID);

		chPlatformFlag = IsLinkPlatform(wMaxHeadLink);
		chTailPlatFlag = IsLinkPlatform(wMinTailLink);
		if ((UINT32_MAX == dwMaxHeadKm) || (UINT32_MAX == dwMinTailKm))
		{
			chRtn = CI_ERROR;
		}
		else
		{
			;
		}

		if (CI_SUCCESS == chRtn)
		{
			*pMidLine = (dwMaxHeadKm + dwMinTailKm) / 2u; /* 中轴线公里标 */

			wEaMode = GetSystemParaValue(EA_MODE_ID);
			wEaStationMode = GetSystemParaValue(EA_STATION_MODE_ID);
			if ((PA_TYPE_DA == chType) || (EA_MODE_DIS == wEaMode) || ((EA_STATION_MODE_DIS == wEaStationMode) && (wMaxHeadLink == wMinTailLink) && (CI_SUCCESS == chPlatformFlag)))
			{
				chCalcSpecialEa = CalcSpecialEa(wTrainId,wSpecialEaId);
				if (CI_SUCCESS == chCalcSpecialEa)
				{
					*pEaOut = EA_OUT_SEVEN;
					*pMidLine = UINT32_MAX;
				}
				else
				{
					/* 获取区间疏散防护区域建立范围 */
					dwFrontDis = GetEaFrontDis();
					dwBehindDis = GetEaBehindDis();
					chTrainDir_outTail = ConvertTrainDir(chTrainDir_outTail); /*小后方向取反*/

					/*车头*/
					if (DIR_SAME == chTrainDir_Maxhead)
					{/*车头处公里标沿大前方向累加*/
						dwKm1 = dwMaxHeadKm + dwFrontDis;
					}
					else if (DIR_CONVERT == chTrainDir_Maxhead)
					{/*车头处公里标沿大前方向累减*/
						if (dwMaxHeadKm >= dwFrontDis)
						{
							dwKm1 = dwMaxHeadKm - dwFrontDis;
						}
						else
						{
							dwKm1 = 0u;
						}
					}
					else
					{
						chRtn = CI_ERROR;
					}

					/*车尾*/
					if (DIR_SAME == chTrainDir_outTail)
					{/*车尾处公里标沿车尾向外方向累加*/
						dwKm2 = dwMinTailKm + dwBehindDis;
					}
					else if (DIR_CONVERT == chTrainDir_outTail)
					{/*车尾处公里标沿车尾向外方向累减*/
						if (dwMinTailKm >= dwBehindDis)
						{
							dwKm2 = dwMinTailKm - dwBehindDis;
						}
						else
						{
							dwKm2 = 0u;
						}
					}
					else
					{
						chRtn = CI_ERROR;
					}

					*pMinEdge = (dwKm1 < dwKm2) ? dwKm1 : dwKm2;
					*pMaxEdge = (dwKm1 < dwKm2) ? dwKm2 : dwKm1;
					*pEaOut = EA_OUT_ONE;
				}
			}
			else if ((EA_STATION_MODE_PLAT == wEaStationMode) && (wMaxHeadLink == wMinTailLink) && (CI_SUCCESS == chPlatformFlag))
			{
				*pMinEdge = (dwMaxHeadKm < dwMinTailKm) ? dwMaxHeadKm : dwMinTailKm;
				*pMaxEdge = (dwMaxHeadKm < dwMinTailKm) ? dwMinTailKm : dwMaxHeadKm;
				*pEaOut = EA_OUT_TWO;
			}
			else if ((EA_MODE_SEC == wEaMode) || (EA_MODE_PLATION == wEaMode))
			{
				if (CI_ERROR == chPlatformFlag)
				{
					/* 车头不在站台，选取车头查询 */
					wBasicLinkId = wMaxHeadLink;
				}
				else if(CI_ERROR == chTailPlatFlag)
				{/* 车尾不在站台，选取车尾查询 */
					wBasicLinkId = wMinTailLink;
				}
				else
				{
					 /*不可能分支，以防护*/
				}

				for (wIndex = 0u; wIndex < g_eaConfigNum; wIndex++)
				{
					for (chConfigLinkIndex = 0U; chConfigLinkIndex < g_szEaConfig[wIndex].chEaConfigLinkSum; chConfigLinkIndex++)
					{
						if (wBasicLinkId == g_szEaConfig[wIndex].wSzEaConfigLinkId[chConfigLinkIndex])
						{
							break;
						} 
						else
						{
							;
						}
					}

					if (chConfigLinkIndex < g_szEaConfig[wIndex].chEaConfigLinkSum)
					{
						/*已经找到*/
						break;
					} 
					else
					{
						;
					}
				}

				if (wIndex < g_eaConfigNum)
				{
					/*若当前建立方式为两站一区间不含站台，但列车一端在防护区域外的站台区间，防护区间计算需要包括该站台区域*/
					if (EA_MODE_SEC == wEaMode)
					{
						/*车头处于站台车尾处于区间*/
						if ((CI_SUCCESS == chPlatformFlag) && (CI_ERROR == chTailPlatFlag))
						{
							for (chConfigLinkIndex = 0U; chConfigLinkIndex < g_szEaConfig[wIndex].chStartStationLinkSum; chConfigLinkIndex++)
							{
								if (wMaxHeadLink == g_szEaConfig[wIndex].wSzStartStationLinkId[chConfigLinkIndex])
								{
									break;
								}
								else
								{
									;
								}
							}

							/*先找是不是在区间起点站台*/
							if (chConfigLinkIndex < g_szEaConfig[wIndex].chStartStationLinkSum)
							{
								*pEaOut = EA_OUT_THREE;
							}
							else
							{
								for (chConfigLinkIndex = 0U; chConfigLinkIndex < g_szEaConfig[wIndex].chEndStationLinkSum; chConfigLinkIndex++)
								{
									if (wMaxHeadLink == g_szEaConfig[wIndex].wSzEndStationLinkId[chConfigLinkIndex])
									{
										break;
									}
									else
									{
										;
									}
								}
								if (chConfigLinkIndex < g_szEaConfig[wIndex].chEndStationLinkSum)
								{
									*pEaOut = EA_OUT_FOUR;
								}
								else
								{
									chRtn = CI_ERROR; /*起终点都找不到，错误*/
								}
							}
							
						}
						/*车头不处于站台 车尾处于站台*/
						else if ((CI_ERROR == chPlatformFlag) && (CI_SUCCESS == chTailPlatFlag))
						{
							{
								for (chConfigLinkIndex = 0U; chConfigLinkIndex < g_szEaConfig[wIndex].chStartStationLinkSum; chConfigLinkIndex++)
								{
									if (wMinTailLink == g_szEaConfig[wIndex].wSzStartStationLinkId[chConfigLinkIndex])
									{
										break;
									}
									else
									{
										;
									}
								}

								/*先找是不是在区间起点站台*/
								if (chConfigLinkIndex < g_szEaConfig[wIndex].chStartStationLinkSum)
								{
									*pEaOut = EA_OUT_THREE;
								}
								else
								{
									for (chConfigLinkIndex = 0U; chConfigLinkIndex < g_szEaConfig[wIndex].chEndStationLinkSum; chConfigLinkIndex++)
									{
										if (wMinTailLink == g_szEaConfig[wIndex].wSzEndStationLinkId[chConfigLinkIndex])
										{
											break;
										}
										else
										{
											;
										}
									}
									if (chConfigLinkIndex < g_szEaConfig[wIndex].chEndStationLinkSum)
									{
										*pEaOut = EA_OUT_FOUR;
									}
									else
									{
										chRtn = CI_ERROR; /*起终点都找不到，错误*/
									}
								}

							}
						}
						else if ((CI_ERROR == chPlatformFlag) && (CI_ERROR == chTailPlatFlag))
						{
							/*列车不占压站台轨*/
							*pEaOut = EA_OUT_FIVE;
						}
						else
						{
							chRtn = CI_ERROR;/*不可达分支*/
						}
						
						*pEaconfigId = (UINT8)g_szEaConfig[wIndex].wId;
					}
					else if (EA_MODE_PLATION == wEaMode)
					{
						*pEaOut = EA_OUT_SIX;
						*pEaconfigId = (UINT8)g_szEaConfig[wIndex].wId;
					}
					else
					{
						/*不可达分支*/
						chRtn = CI_ERROR;
					}


				}
				else
				{
					chRtn = CI_ERROR;
				}
			}
			else
			{
				; /* 不可能分支 */
			}
		}
		else
		{
			;
		}
	}

	return chRtn;
}

/**
* @brief 查询两站一区间不含站台的防护区域相邻的站台防护公里标
* @param const UINT16 eaConfigIndex  防护区域索引
* @param const UINT32 wOrgnPointKmtemp 小端公里标
* @param const UINT32 wTmnlPointKmtemp 大端公里标
* @param UINT32* pMinEdge  输出防护区域最小公里标
* @param UINT32* pMaxEdge  输出防护区域最大公里标
* @return CI_ERROR 计算失败 CI_SUCCESS计算成功
* By LC 20231113
**/
UINT8 EaGetadjacentStationKM(const UINT16 eaConfigIndex, const UINT32 wOrgnPointKmtemp, const UINT32 wTmnlPointKmtemp, UINT32* pMinEdge, UINT32* pMaxEdge)
{
	UINT8 chPointIndex = 0U;/*循环变量*/
	UINT8 chRtn = CI_ERROR;
	UINT16 trainAcId = 0U;

	UINT32 retvalStartKm = 0U;  /*返回防护始端公里标*/
	UINT32 retvalEndKm = 0U;  /*返回防护终端公里标*/

	UINT16 beforStartLink = 0U; /*防护区域始端相邻Link*/
	UINT16 afterEndLink = 0U;    /*防护区域终端相邻Link*/
	UINT8 chStationFlag = 0U; /*判断标志：link是否为站台*/
	UINT16 wSwitchId = 0U;
	UINT8 cDirectionPointFlag = 0U;
	UINT16 wAxleId = 0U;
	UINT32 dwKmTemp = 0U;


	retvalStartKm = g_szEaConfig[eaConfigIndex].dwMinKm;
	retvalEndKm = g_szEaConfig[eaConfigIndex].dwMaxKm;
	chRtn = CI_SUCCESS;
	/*输入公里标在防护区域始端外*/
	if ((wOrgnPointKmtemp < g_szEaConfig[eaConfigIndex].dwMinKm) || (wTmnlPointKmtemp < g_szEaConfig[eaConfigIndex].dwMinKm))
	{
		for (chPointIndex = 0u; chPointIndex < g_szEaConfig[eaConfigIndex].chStartLinkNum; chPointIndex++)
		{/* 遍历起点，找出起点边界最小公里标 */
			/* 含站台，需判断相邻是否为站台 */
			beforStartLink = FindAdjacentLinkIDSafe(g_szEaConfig[eaConfigIndex].szStartLinkId[chPointIndex], DIR_CONVERT, &wSwitchId, &cDirectionPointFlag);
			chStationFlag = IsLinkPlatform(beforStartLink);

			if (UINT16_MAX == beforStartLink)
			{
				chRtn = CI_ERROR;
				break;
			}
			else if (CI_SUCCESS == chStationFlag)
			{
				;
			}
			else
			{
				beforStartLink = g_szEaConfig[eaConfigIndex].szStartLinkId[chPointIndex];
			}

			wAxleId = GetLinkOrgnPointIdById(beforStartLink);
			dwKmTemp = GetAxisKmById(wAxleId);
			if (dwKmTemp < retvalStartKm)
			{
				retvalStartKm = dwKmTemp;
			}
			else
			{
				;/* 无需赋值 */
			}
		}
		
	}
	/*输入公里标在防护区域终端外*/
	else if ((wOrgnPointKmtemp > g_szEaConfig[eaConfigIndex].dwMaxKm) || (wTmnlPointKmtemp > g_szEaConfig[eaConfigIndex].dwMaxKm))
	{
		for (chPointIndex = 0u; chPointIndex < g_szEaConfig[eaConfigIndex].chEndLinkNum; chPointIndex++)
		{/* 遍历终点，找出终点边界最大公里标 */

			afterEndLink = FindAdjacentLinkIDSafe(g_szEaConfig[eaConfigIndex].szEndLinkId[chPointIndex], DIR_SAME, &wSwitchId, &cDirectionPointFlag);

			chStationFlag = IsLinkPlatform(afterEndLink);
			if (UINT16_MAX == afterEndLink)
			{
				chRtn = CI_ERROR;
				break;
			}
			else if (CI_SUCCESS == chStationFlag)
			{
				;
			}
			else
			{
				afterEndLink = g_szEaConfig[eaConfigIndex].szEndLinkId[chPointIndex];
			}
			wAxleId = GetLinkTmnlPointIdById(afterEndLink);
			dwKmTemp = GetAxisKmById(wAxleId);
			if (dwKmTemp > retvalEndKm)
			{
				retvalEndKm = dwKmTemp;
			}
			else
			{
				; /* 无需赋值 */
			}
		}
	}
	else
	{
		/*输入公里标不在防护区域外方，不向外增加站台区域*/
		chRtn = CI_ERROR;
	}
	*pMinEdge = retvalStartKm;
	*pMaxEdge = retvalEndKm;
	return chRtn;
}


/**
* @brief 获取防护区域计轴区段索引
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段索引；AXIS_SECTION_SUM_MAX:查找失败
*/
static UINT16 EaGetAcIndex(const UINT16 wAcId)
{
	UINT16 wRtn = AXIS_SECTION_SUM_MAX;
	UINT16 wIndex = 0u;

	for (wIndex = 0u; wIndex < g_eaAcConfigNum; wIndex++)
	{
		if (g_szEaAcConfig[wIndex].AxisSectionId == wAcId)
		{
			wRtn = wIndex;
			break;
		}
		else
		{
			;
		}
	}

	return wRtn;
}

/**
* @brief 获取防护区域计轴区段包含link数量
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含link数量；AXIS_INCLUDE_LINK_SUM_MAX:查找失败
*/
static UINT8 EaGetAcLinkNum(const UINT16 wAcId)
{
	UINT8 chRtn = (UINT8)AXIS_INCLUDE_LINK_SUM_MAX;
	UINT16 wIndex = AXIS_SECTION_SUM_MAX;

	wIndex = EaGetAcIndex(wAcId);
	if (wIndex < AXIS_SECTION_SUM_MAX)
	{
		chRtn = g_szEaAcConfig[wIndex].chLinkNum;
	}
	else
	{
		;
	}
	return chRtn;
}

/**
* @brief 获取防护区域计轴区段包含起点计轴编号
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含link数量；AXIS_INCLUDE_LINK_SUM_MAX:查找失败
*/
static UINT16 EaGetAcOrgnAxisId(const UINT16 wAcId)
{
	UINT16 chRtn = AXIS_INCLUDE_LINK_SUM_MAX;
	UINT16 wIndex = AXIS_SECTION_SUM_MAX;

	wIndex = EaGetAcIndex(wAcId);
	if (wIndex < AXIS_SECTION_SUM_MAX)
	{
		chRtn = g_szEaAcConfig[wIndex].wOrgnAxisId;
	}
	else
	{
		;
	}
	return chRtn;
}

/**
* @brief 获取防护区域计轴区段包含终点计轴编号
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含link数量；AXIS_INCLUDE_LINK_SUM_MAX:查找失败
*/
static UINT16 EaGetAcTmnlAxisId(const UINT16 wAcId)
{
	UINT16 chRtn = AXIS_INCLUDE_LINK_SUM_MAX;
	UINT16 wIndex = AXIS_SECTION_SUM_MAX;

	wIndex = EaGetAcIndex(wAcId);
	if (wIndex < AXIS_SECTION_SUM_MAX)
	{
		chRtn = g_szEaAcConfig[wIndex].wTmnlAxisId;
	}
	else
	{
		;
	}
	return chRtn;
}


/**
* @brief 获取防护区域计轴区段包含link编号
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含link编号；NULL:查找失败
*/
static UINT16 * EaGetAcLinkId(const UINT16 wAcId)
{
	UINT16 * pRtn = NULL;
	UINT16 wIndex = AXIS_SECTION_SUM_MAX;

	wIndex = EaGetAcIndex(wAcId);
	if (wIndex < AXIS_SECTION_SUM_MAX)
	{
		pRtn = g_szEaAcConfig[wIndex].szLinkIdBuff;
	}
	else
	{
		;
	}
	return pRtn;
}

/**
* @brief 获取防护区域计轴区段包含逻辑区段数量
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含逻辑区段数量；AXIS_INCLUDE_LOG_SUM_MAX:查找失败
*/
static UINT8 EaGetAcLgcNum(const UINT16 wAcId)
{
	UINT8 chRtn = (UINT8)AXIS_INCLUDE_LOG_SUM_MAX;
	UINT16 wIndex = AXIS_SECTION_SUM_MAX;

	wIndex = EaGetAcIndex(wAcId);
	if (wIndex < AXIS_SECTION_SUM_MAX)
	{
		chRtn = g_szEaAcConfig[wIndex].LogSectionSum;
	}
	else
	{
		;
	}
	return chRtn;
}

/**
* @brief 获取防护区域计轴区段包含逻辑区段编号
* @param const UINT16 wAcId 计轴区段编号
* @return 计轴区段包含逻辑区段编号；NULL:查找失败
*/
static UINT16 * EaGetAcLgcId(const UINT16 wAcId)
{
	UINT16 * pRtn = NULL;
	UINT16 wIndex = AXIS_SECTION_SUM_MAX;

	wIndex = EaGetAcIndex(wAcId);
	if (wIndex < AXIS_SECTION_SUM_MAX)
	{
		pRtn = g_szEaAcConfig[wIndex].LogSectionIdBuf;
	}
	else
	{
		;
	}
	return pRtn;
}

/**
* @brief 获取防护区域逻辑区段数量
* @param const UINT8 chIndex 防护区域索引
* @return 防护区域逻辑区段数量
*/
UINT8 EaGetLgcNum(const UINT8 chIndex)
{
	UINT8 chRtn = 0u;
	if (EA_MAX_NUM > chIndex)
	{
		chRtn = g_szEaData[chIndex].strLgcInfo.chObjNum;
	}
	else
	{
		;
	}
	return chRtn;
}

/**
* @brief 获取防护区域逻辑区段编号
* @param const UINT8 chIndex 防护区域索引
* @return 防护区域逻辑区段编号
*/
UINT16 * EaGetLgcId(const UINT8 chIndex)
{
	UINT16 * pRtn = NULL;
	if (EA_MAX_NUM > chIndex)
	{
		pRtn = g_szEaData[chIndex].strLgcInfo.szObjId;
	}
	else
	{
		;
	}
	return pRtn;
}

/**
* @brief 获取防护区域疏散列车中轴线公里标
* @param const UINT8 chIndex 防护区域索引
* @return 防护区域疏散列车中轴线公里标
*/
UINT32 EaGetMidLine(const UINT8 chIndex)
{
	UINT32 dwRtn = UINT32_MAX;
	if (EA_MAX_NUM > chIndex)
	{
		dwRtn = g_szEaData[chIndex].dwMidLine;
	}
	else
	{
		;
	}
	return dwRtn;
}

/**
* @brief 区间疏散防护区域取消处理
* @param 无
* @return 无
*/
static void EaAtsCancleProc(void)
{
	AtsEaMsgStru * strMsgFst = NULL;
	AtsEaMsgStru * strMsgSnd = NULL;
	strMsgFst = GetAtsEaMsgFst();
	strMsgSnd = GetAtsEaMsgSnd();/*不会返回NULL*/

	if ((strMsgFst->chFlag != FLAG_SET) && (strMsgSnd->chFlag != FLAG_SET))
	{
		; /* 没有消息，什么也不做 */
	}
	else if ((strMsgFst->chFlag == FLAG_SET) && (strMsgSnd->chFlag != FLAG_SET))
	{/* 取消区间疏散一次消息 */
		EaAtsCancleFst();
	}
	else
	{/* 取消区间疏散二次消息 */
		EaAtsCancleSnd();
	}

}

/**
* @brief 区间疏散防护区域首次取消处理
* @param 无
* @return 无
*/
static void EaAtsCancleFst(void)
{
	AtsEaMsgStru * strMsgFst = NULL;
	AtsMsgCfmStru * strCfmFst = NULL;
	UINT32 dwCycle = 0U;
	UINT8 chLocalId = 0U;
	UINT8 chRtn = CI_ERROR;
	UINT8 szCrcTmp[1024] = { 0U };
	UINT32 ii = 0U;
	UINT8 chFunRtn = CI_TIME_OUT;
	UINT16 wTrainId = 0U;
	UINT16 wTrainLgcId = 0U;
	UINT8 chEaIndex = 0U;
	UINT8 chEaAreaLinkType = 0U;/*本地存储的防护区域线路上下行属性*/
	UINT8 chEaCmdState = 0U;/*区间疏散命令状态*/

	chLocalId = GetSystemParaLocalCiId();
	dwCycle = Get2oo2CurCycleNum();

	/*以下消息获取不会返回NULL*/
	strMsgFst = GetAtsEaMsgFst();
	strCfmFst = GetAtsEaCfmFst();
	
	if (strMsgFst->dwCycle == dwCycle)
	{
		strCfmFst->chFlag = FLAG_SET;
		strCfmFst->chTiocId = chLocalId;
		strCfmFst->chStation = strMsgFst->chStation;
		strCfmFst->wIndex = strMsgFst->wIndex;
		strCfmFst->dwTime = dwCycle;

		chRtn = dquHlhtId2VobcName(strMsgFst->dwEaTrainId, &wTrainId, &wTrainLgcId);

		if (CI_ERROR == chRtn)
		{
			strCfmFst->chOpStatus = CONFIRM_UNKNOWN;
		}
		else
		{
			/* 获取防护区域存储索引 */
			chEaIndex = PaGetIndex(wTrainId, PA_TYPE_EA);
			if (chEaIndex == g_eaNum)
			{
				strCfmFst->chOpStatus = CONFIRM_FIRST_NOT_EA;
			}
			else
			{
				chEaCmdState = GetTrainEaCmdState(wTrainId);
				if (TRAIN_EA_CMD_STATE_INVALID != chEaCmdState)
				{
					/* 列车当前处于区间疏散故障状态 */
					strCfmFst->chOpStatus = CONFIRM_TRAIN_IN_EA;
				}
				else
				{
					chEaAreaLinkType = GetEaAreaLineType(chEaIndex);
					if ((EA_AREA_ALL != strMsgFst->chLine) && (EA_AREA_ALL != chEaAreaLinkType) && (chEaAreaLinkType != strMsgFst->chLine))
					{
						/*ATS下发的线路上下行属性和本地存储的线路上下行属性相反，此时需要向网关反馈错误*/
						strCfmFst->chOpStatus = CONFIRM_EALINE_DIFFERENT;
					}
					else
					{
						strCfmFst->chOpStatus = CONFIRM_FIRST_SUCCESS;
					}
				}
			}
		}

		szCrcTmp[ii] = strMsgFst->chAtsId;
		ii++;
		szCrcTmp[ii] = strMsgFst->chStation;
		ii++;
		ShortToChar(strMsgFst->wIndex, &szCrcTmp[ii]);
		ii += 2U;
		LongToChar(strMsgFst->dwEaTrainId, &szCrcTmp[ii]);
		ii += 4u;
		LongToChar(strMsgFst->dwTime, &szCrcTmp[ii]);
		ii += 4u;
		szCrcTmp[ii] = strMsgFst->chType;
		ii++;
		szCrcTmp[ii] = strMsgFst->chLine;
		ii++;
		strCfmFst->dwCrc32 = Tioc_CommonCrc32(szCrcTmp, ii);	/* ATS编号、车站编号、操作站编号、列车互联互通ID、下发时间、命令类型、区域计算CRC */

		if (CONFIRM_FIRST_SUCCESS != strCfmFst->chOpStatus)
		{
			ClearAtsEaMsgFirst();
		}
		else
		{
			;
		}
	}
	else
	{/* 接收到ATS取消区间疏散一次消息非本周期，超时判断 */
		chFunRtn = SystemOverTimeCheck(strMsgFst->dwCycle, CONFIRM_TIMEOUT_CC);
		if (CI_TIME_OUT == chFunRtn)
		{
			ClearAtsEaMsgFirst();
		}
		else
		{
			;
		}
	}
}

/**
* @brief 区间疏散防护区域二次取消处理
* @param 无
* @return 无
*/
static void EaAtsCancleSnd(void)
{
	AtsEaMsgStru * strMsgFst = NULL;
	AtsEaMsgStru * strMsgSnd = NULL;
	AtsMsgCfmStru * strCfmFst = NULL;
	AtsMsgCfmStru * strCfmSnd = NULL;
	UINT32 dwCycle = 0u;
	UINT8 chLocalId = 0u;
	UINT8 chFlag = FLAG_UNSET;
	UINT8 szCrcTmp[1024] = { 0u };
	UINT32 ii = 0u;
	UINT8 chFunRtn = CI_ERROR;
	UINT32 dwCrc = 0u;
	UINT16 wTrainId = 0u;
	UINT16 wTrainLgcId = 0u;
	UINT8 chEaIndex = 0u;
	UINT8 chEaCmdState = 0U;/*区间疏散命令状态*/

	chLocalId = GetSystemParaLocalCiId();
	dwCycle = Get2oo2CurCycleNum();

	/*以下消息获取不会返回NULL*/
	strMsgFst = GetAtsEaMsgFst();
	strMsgSnd = GetAtsEaMsgSnd();
	strCfmFst = GetAtsEaCfmFst();
	strCfmSnd = GetAtsEaCfmSnd();

	if (strMsgSnd->dwCycle == dwCycle)
	{
		strCfmSnd->chFlag = FLAG_SET;
		strCfmSnd->chTiocId = chLocalId;
		strCfmSnd->chStation = strMsgSnd->chStation;
		strCfmSnd->wIndex = strMsgSnd->wIndex;
		strCfmSnd->dwTime = dwCycle;

		if (FLAG_SET != strMsgFst->chFlag)
		{/* 未执行首次取消 */
			strCfmSnd->chOpStatus = CONFIRM_EA_SECOND_FIRST;
			chFlag = FLAG_SET;
		}
		else if (strMsgSnd->dwEaTrainId != strMsgFst->dwEaTrainId)
		{/* ATS两次输入列车ID不同 */
			strCfmSnd->chOpStatus = CONFIRM_SECOND_EA_TRAINID;
			chFlag = FLAG_SET;
		}
		else if ((strMsgSnd->chAtsId != strMsgFst->chAtsId)
			|| (strMsgSnd->chStation != strMsgFst->chStation)
			|| (strMsgSnd->wIndex != strMsgFst->wIndex)
			|| (strMsgSnd->chType != strMsgFst->chType))
		{
			/* ATS输入不一致，返回未知 */
			strCfmSnd->chOpStatus = CONFIRM_UNKNOWN;
			chFlag = FLAG_SET;
		}
		else if (strMsgSnd->chLine != strMsgFst->chLine)
		{
			/* 线路属性不一致 */
			strCfmSnd->chOpStatus = CONFIRM_EA_SND_LINE_DIFF;
			chFlag = FLAG_SET;
		}
		else
		{
			/*不处理*/
			;
		}

		if (FLAG_UNSET == chFlag)
		{
			chFunRtn = dquHlhtId2VobcName(strMsgSnd->dwEaTrainId, &wTrainId, &wTrainLgcId);
			chEaCmdState = GetTrainEaCmdState(wTrainId);
			if (TRAIN_EA_CMD_STATE_INVALID != chEaCmdState)
			{
				/* 列车当前处于疏散状态 */
				strCfmSnd->chOpStatus = CONFIRM_TRAIN_IN_EA;
				chFlag = FLAG_SET;
			}
			else
			{
				;
			}
		}
		else
		{
			;
		}

		if (FLAG_UNSET == chFlag)
		{
			szCrcTmp[ii] = strMsgSnd->chTiocId;
			ii++;
			LongToChar(strCfmFst->dwTime, &szCrcTmp[ii]);
			ii += 4u;
			szCrcTmp[ii] = strMsgSnd->chType;
			ii++;
			szCrcTmp[ii] = strMsgSnd->chLine;
			ii++;
			dwCrc = Tioc_CommonCrc32(szCrcTmp, ii);
			if (dwCrc != strMsgSnd->dwCrc32)
			{
				/* 计算的CRC32与ATS二次消息CRC32不一致 */
				strCfmSnd->chOpStatus = CONFIRM_EA_SECOND_CRC;
				chFlag = FLAG_SET;
			}
			else
			{
				;
			}
		}
		else
		{
			;
		}

		ii = 0u;
		szCrcTmp[ii++] = strMsgSnd->chAtsId;
		szCrcTmp[ii++] = strMsgSnd->chStation;
		ShortToChar(strMsgSnd->wIndex, &szCrcTmp[ii]);
		ii += 2U;
		LongToChar(strMsgSnd->dwEaTrainId, &szCrcTmp[ii]);
		ii += 4u;
		LongToChar(strMsgFst->dwTime, &szCrcTmp[ii]);
		ii += 4u;
		LongToChar(strMsgSnd->dwTime, &szCrcTmp[ii]);
		ii += 4u;
		szCrcTmp[ii++] = strMsgSnd->chType;
		szCrcTmp[ii++] = strMsgSnd->chLine;
		strCfmSnd->dwCrc32 = Tioc_CommonCrc32(szCrcTmp, ii);

		if (FLAG_UNSET == chFlag)
		{/* 检查通过，反馈确认成功 */
			chFunRtn = dquHlhtId2VobcName(strMsgSnd->dwEaTrainId, &wTrainId, &wTrainLgcId);
			if (CI_SUCCESS == chFunRtn)
			{
				chEaIndex = PaGetIndex(wTrainId, PA_TYPE_EA);
				strCfmSnd->chOpStatus = CONFIRM_SECOND_SUCCESS;
				EaAtsCancleExc(chEaIndex);
			}
			else
			{
				; /* 不处理 */
			}
		}
		else
		{
			;
		}
	}
	else
	{
		; /** 非本周期消息，不处理 */
	}
	ClearAtsEaMsgFirst();
	ClearAtsEaMsgSecond();

}

/**
* @brief 区间疏散防护区域取消执行
* @param const UINT8 chEaIndex 防护区域索引ID
* @return 无
* by cgh 20240321
*/
static void EaAtsCancleExc(const UINT8 chEaIndex)
{
	UINT8 chIndex = 0U;
	UINT8 chPaType = 0U;/*防护区域类型*/
	AtsEaMsgStru* strEaMsgSnd = NULL;/*ATS给RC的区间疏散二次取消消息*/
	AtsDaMsgStru* strDaMsgSnd = NULL;/*ATS给RC的脱轨二次取消消息*/
	UINT8 chAtsMsgLine = 0U;/*ATS给RC疏散二次取消消息的线路上下行属性*/
	UINT8 chEaAreaLineType = 0U;/*本地存储的区间疏散区域线路上下行属性*/
	UINT8 chEaLinkSum = 0U;/*防护区域包含LINK数目*/
	UINT16* szEaLinkIdBuf = NULL;/*防护区域包含LINK数组*/
	UINT8 ii = 0U;
	UINT16 wLinkLineType = 0U;/*LINK的线路上下行属性*/
	UINT16 szTempLinkId[EA_SECTION_MAX_NUM] = {0U};/*LINK临时数组*/
	UINT8 chTempLinkSum = 0U;/*LINK临时数目*/


	if ((EA_MAX_NUM > chEaIndex) && (0u < g_eaNum) && (chEaIndex < g_eaNum))
	{
		strEaMsgSnd = GetAtsEaMsgSnd();
		strDaMsgSnd = GetAtsDaMsgSnd();
		chEaAreaLineType = GetEaAreaLineType(chEaIndex);
		chPaType = GetPaTypeByIndex(chEaIndex);
		if (PA_TYPE_DA == chPaType)
		{
			chAtsMsgLine = strDaMsgSnd->chLine;
		}
		else if (PA_TYPE_EA == chPaType)
		{
			chAtsMsgLine = strEaMsgSnd->chLine;
		}
		else
		{
			; /*不然不赋值ATS取消线路上下行属性，此时为0，下面不会执行*/
		}

		if (0U != chAtsMsgLine)
		{
			if ((chAtsMsgLine == chEaAreaLineType) || (EA_AREA_ALL == chAtsMsgLine))
			{
				/*ATS下发的和本地存储的相同或ATS下发的为上下行均取消直接清除对应索引的防护区域*/
				for (chIndex = chEaIndex; chIndex < g_eaNum - 1u; chIndex++)
				{/* 后续成员往前挪 */
					g_szEaData[chIndex] = g_szEaData[chIndex + 1u];
				}

				(void)CommonMemSet((void*)&g_szEaData[chIndex], (UINT32)sizeof(EaDataStru), (UINT8)0U, (UINT32)sizeof(EaDataStru));/* 清零 */
				g_eaNum--;
			}
			else
			{
				/*到了此处，当前存储的线路上下行属性一定是FF，ATS发的一定是55/AA*/
				chEaLinkSum = EaGetLinkNum(chEaIndex);
				szEaLinkIdBuf = EaGetLinkId(chEaIndex);

				for (ii = 0U; ii < chEaLinkSum; ii++)
				{
					wLinkLineType = GetLinkLineById(szEaLinkIdBuf[ii]);
					if (chAtsMsgLine == wLinkLineType)
					{
						/*相等需要剔除，不在临时LINK数组添加*/
					}
					else
					{
						/*不相等则继续保留*/
						szTempLinkId[chTempLinkSum] = szEaLinkIdBuf[ii];
						chTempLinkSum++;
					}
				}
				/*将保留的数据赋值给本地防护分区存储*/
				g_szEaData[chEaIndex].strLinkInfo.chObjNum = chTempLinkSum;

				(void)CommonMemCpy((void*)(&g_szEaData[chEaIndex].strLinkInfo.szObjId), (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM), (void*)(&szTempLinkId), (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM));
				if (0U == chTempLinkSum)
				{
					(void)CommonMemSet((void*)&g_szEaData[chEaIndex], (UINT32)sizeof(EaDataStru), (UINT8)0U, (UINT32)sizeof(EaDataStru));/* 清零 */
					g_eaNum--;
				}
				else
				{
					/*当前还存在防护分区，清理区段信息更新线路上下行属性*/
					ClearEaSecData(chEaIndex);
				}

				debug_infor_printf((const)"EaAtsCancleExc after message:\n");

				debug_infor_printf((const)"PaLineType: %d\n", g_szEaData[chEaIndex].chEaAreaLinkType);

				debug_infor_printf((const)"PaAcSeq:num = %d",g_szEaData[chEaIndex].strAcInfo.chObjNum);
				debug_out_array(0xAA, g_szEaData[chEaIndex].strAcInfo.szObjId, g_szEaData[chEaIndex].strAcInfo.chObjNum * 2u);

				debug_infor_printf((const)"PaLinkSeq:num = %d",g_szEaData[chEaIndex].strLinkInfo.chObjNum);
				debug_out_array(0xAA, g_szEaData[chEaIndex].strLinkInfo.szObjId, g_szEaData[chEaIndex].strLinkInfo.chObjNum * 2u);

				debug_infor_printf((const)"PaLgcSeq:num = %d",g_szEaData[chEaIndex].strLgcInfo.chObjNum);
				debug_out_array(0xAA, g_szEaData[chEaIndex].strLgcInfo.szObjId, g_szEaData[chEaIndex].strLgcInfo.chObjNum * 2u);
			}
		}
		else
		{
			; /*不取消*/
		}
				
	}
	else
	{
		;
	}
}

/**
* @brief 取消指定索引区间疏散防护区域
* @param const UINT8 chEaIndex 防护区域索引ID
* @return 无
* by cgh 20240321
*/
static void EaCancleExc(const UINT8 chEaIndex)
{
	UINT8 chIndex = 0U;

	if ((EA_MAX_NUM > chEaIndex) && (0u < g_eaNum) && (chEaIndex < g_eaNum))
	{
		for (chIndex = chEaIndex; chIndex < g_eaNum - 1u; chIndex++)
		{/* 后续成员往前挪 */
			if (chIndex < EA_MAX_NUM - 1U)
			{
				g_szEaData[chIndex] = g_szEaData[chIndex + 1u];
			}
			else
			{
				; /*实际不会越界，因为g_eaNum最大值是20,这里是为了编码规范*/
			}
		}

		(void)CommonMemSet((void*)&g_szEaData[chIndex], (UINT32)sizeof(EaDataStru), (UINT8)0U, (UINT32)sizeof(EaDataStru));/* 清零 */
		g_eaNum--;
	}
	else
	{
		;
	}
}

/*
* 功能描述： 获取区间疏散跟随数据
* 参数说明： pData 数据地址
*			 dwIndex 数据索引
* 返回值  ： 写入后的数据索引
*/
UINT32 GetEaTransferData(UINT8* pData, UINT32 dwIndex)
{
	UINT32 dwRetVal = 0u;
	UINT8 ii = 0u;
	UINT8 jj = 0u;

	dwRetVal = dwIndex;

	if ((NULL != pData) && (UINT32_MAX >= dwIndex))
	{
		/* 限速数量 */
		pData[dwRetVal] = g_eaNum;
		dwRetVal++;

		for (ii = 0u; ii < g_eaNum; ii++)
		{
			/* 疏散列车ID */
			ShortToChar(g_szEaData[ii].wTrainId, &pData[dwRetVal]);
			dwRetVal += 2u;

			/* 建立标志 */
			pData[dwRetVal] = g_szEaData[ii].chBuildedFlag;
			dwRetVal++;

			/* 计轴区段数量 */
			pData[dwRetVal] = g_szEaData[ii].strAcInfo.chObjNum;
			dwRetVal++;
			for (jj = 0u; jj < g_szEaData[ii].strAcInfo.chObjNum; jj++)
			{/* 计轴区段ID */
				ShortToChar(g_szEaData[ii].strAcInfo.szObjId[jj], &pData[dwRetVal]);
				dwRetVal += 2u;
			}

			/* link数量 */
			pData[dwRetVal] = g_szEaData[ii].strLinkInfo.chObjNum;
			dwRetVal++;
			for (jj = 0u; jj < g_szEaData[ii].strLinkInfo.chObjNum; jj++)
			{/* linkID */
				ShortToChar(g_szEaData[ii].strLinkInfo.szObjId[jj], &pData[dwRetVal]);
				dwRetVal += 2u;
			}

			/* 逻辑区段数量 */
			pData[dwRetVal] = g_szEaData[ii].strLgcInfo.chObjNum;
			dwRetVal++;
			for (jj = 0u; jj < g_szEaData[ii].strLgcInfo.chObjNum; jj++)
			{/* 逻辑区段ID */
				ShortToChar(g_szEaData[ii].strLgcInfo.szObjId[jj], &pData[dwRetVal]);
				dwRetVal += 2u;
			}

			/* 中轴线 */
			LongToChar(g_szEaData[ii].dwMidLine, &pData[dwRetVal]);
			dwRetVal += 4u;

			/* 建立控区ID */
			pData[dwRetVal] = g_szEaData[ii].chSrcTiocId;
			dwRetVal++;

			/* 关联控区ID */
			pData[dwRetVal] = g_szEaData[ii].chDstTiocId;
			dwRetVal++;

			/* 关联控区同意状态 */
			pData[dwRetVal] = g_szEaData[ii].chDstAllowed;
			dwRetVal++;

			/* 防护区域类型 */
			pData[dwRetVal] = g_szEaData[ii].chPaType;
			dwRetVal++;

			/* 区间疏散方式为两站一区间时，对应的防护区间ID  不向相邻联锁与车发送 */
			pData[dwRetVal] = g_szEaData[ii].chEaConfigId;
			dwRetVal++;

			/* 防护区域上下行区域类型 */
			pData[dwRetVal] = g_szEaData[ii].chEaAreaLinkType;
			dwRetVal++;

			/* 周期号*/
			LongToChar(g_szEaData[ii].dwEaBuildCycNum, &pData[dwRetVal]);
			dwRetVal += 4u;
		}

	}
	else
	{
		;
	}

	return dwRetVal;
}

/*
* 功能描述： 设置区间疏散跟随数据
* 参数说明： pData 数据地址
*			 dwIndex 数据索引
* 返回值  ： 解析后的数据索引
*/
UINT32 SetEaTransferData(UINT8* pData, UINT32 dwIndex)
{
	UINT32 dwRetVal = 0u;
	UINT8 ii = 0u;
	UINT8 jj = 0u;

	dwRetVal = dwIndex;

	if ((NULL != pData) && (UINT32_MAX >= dwIndex))
	{
		/* 区间疏散区域数量 */
		g_eaNum = pData[dwRetVal];
		dwRetVal++;

		for (ii = 0u; ii < g_eaNum; ii++)
		{
			/* 疏散列车ID */
			g_szEaData[ii].wTrainId = ShortFromChar(&pData[dwRetVal]);
			dwRetVal += 2u;

			/* 建立标志 */
			g_szEaData[ii].chBuildedFlag = pData[dwRetVal];
			dwRetVal++;

			/* 计轴区段信息 */
			g_szEaData[ii].strAcInfo.chObjNum = pData[dwRetVal];
			dwRetVal++;
			for (jj = 0u; jj < g_szEaData[ii].strAcInfo.chObjNum; jj++)
			{
				g_szEaData[ii].strAcInfo.szObjId[jj] = ShortFromChar(&pData[dwRetVal]);
				dwRetVal += 2u;
			}

			/* link信息 */
			g_szEaData[ii].strLinkInfo.chObjNum = pData[dwRetVal];
			dwRetVal++;
			for (jj = 0u; jj < g_szEaData[ii].strLinkInfo.chObjNum; jj++)
			{
				g_szEaData[ii].strLinkInfo.szObjId[jj] = ShortFromChar(&pData[dwRetVal]);
				dwRetVal += 2u;
			}

			/* 逻辑区段信息 */
			g_szEaData[ii].strLgcInfo.chObjNum = pData[dwRetVal];
			dwRetVal++;
			for (jj = 0u; jj < g_szEaData[ii].strLgcInfo.chObjNum; jj++)
			{
				g_szEaData[ii].strLgcInfo.szObjId[jj] = ShortFromChar(&pData[dwRetVal]);
				dwRetVal += 2u;
			}

			/* 中轴线 */
			g_szEaData[ii].dwMidLine = LongFromChar(&pData[dwRetVal]);
			dwRetVal += 4u;

			/* 建立控区 */
			g_szEaData[ii].chSrcTiocId = pData[dwRetVal];
			dwRetVal++;

			/* 关联控区 */
			g_szEaData[ii].chDstTiocId = pData[dwRetVal];
			dwRetVal++;

			/* 关联控区同意状态 */
			g_szEaData[ii].chDstAllowed = pData[dwRetVal];
			dwRetVal++;

			/* 防护区域类型 */
			g_szEaData[ii].chPaType = pData[dwRetVal];
			dwRetVal++;

			/* 区间疏散方式为两站一区间时，对应的防护区间ID  不向相邻联锁与车发送 */
			g_szEaData[ii].chEaConfigId = pData[dwRetVal];
			dwRetVal++;

			/* 防护区域上下行区域类型 */
			g_szEaData[ii].chEaAreaLinkType = pData[dwRetVal];
			dwRetVal++;

			/* 防护区域建立周期号 */
			g_szEaData[ii].dwEaBuildCycNum = LongFromChar(&pData[dwRetVal]);
			dwRetVal += 4u;
		}
	}
	else
	{
		;
	}

	return dwRetVal;
}

/*
* 功能描述： 判断区域所有区段均为本控区区段
* 参数说明： chEaIndex 疏散区域索引
* 返回值  ： CI_SUCCESS:全在本控区；CI_ERROR:不全在本控区
*/
static UINT8 EaIsLinkSeqAllLocal(UINT8 chEaIndex)
{
	UINT8 chLocalId = 0u;
	UINT16 wLinkTiocId = 0u;
	UINT8 chLinkIndex = 0u;
	UINT8 chRtn = CI_ERROR;

	chLocalId = GetSystemParaLocalCiId();
	for (chLinkIndex = 0u; chLinkIndex < g_szEaData[chEaIndex].strLinkInfo.chObjNum; chLinkIndex++)
	{
		wLinkTiocId = GetLinkManageTiocById(g_szEaData[chEaIndex].strLinkInfo.szObjId[chLinkIndex]);
		if (wLinkTiocId != chLocalId)
		{
			break;
		}
		else
		{
			;
		}
	}

	if (chLinkIndex == g_szEaData[chEaIndex].strLinkInfo.chObjNum)
	{
		chRtn = CI_SUCCESS;
	}
	else
	{
		chRtn = CI_ERROR;
	}

	return chRtn;
}

/**
* @brief 获取指定索引防护区域建立TIOC编号
* @param chIndex 下标
* @return 防护区域建立TIOC编号
*/
UINT8 GetEaSrcTiocByIndex(UINT8 chIndex)
{
	UINT8 rtnValue = 0u;

	if (EA_MAX_NUM > chIndex)
	{
		rtnValue = g_szEaData[chIndex].chSrcTiocId;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 获取指定索引防护区域目标TIOC编号
* @param chIndex 下标
* @return 防护区域目标TIOC编号
*/
UINT8 GetEaDstTiocByIndex(UINT8 chIndex)
{
	UINT8 rtnValue = 0u;

	if (EA_MAX_NUM > chIndex)
	{
		rtnValue = g_szEaData[chIndex].chDstTiocId;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 获取指定索引防护区域目标TIOC同意标识
* @param chIndex 下标
* @return 防护区域目标TIOC同意标识
*/
UINT8 GetEaDstAllowedByIndex(UINT8 chIndex)
{
	UINT8 rtnValue = 0u;

	if (EA_MAX_NUM > chIndex)
	{
		rtnValue = g_szEaData[chIndex].chDstAllowed;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 相邻控区输入的防护区域更新
* @param EaDataStru * pEaData 相邻控区输入的防护区域
* @return 无
*/
void EaNeighborUpdata(EaDataStru * pEaDataSt)
{
	UINT8 chEaIndex = 0u;
	if (NULL != pEaDataSt)
	{
		for (chEaIndex = 0u; chEaIndex < g_eaNum; chEaIndex++)
		{/* 遍历本控区当前存在的防护区域 */
			if ((g_szEaData[chEaIndex].wTrainId == pEaDataSt->wTrainId) && (g_szEaData[chEaIndex].chPaType == pEaDataSt->chPaType)
				&& (g_szEaData[chEaIndex].chSrcTiocId == pEaDataSt->chSrcTiocId))
			{
				break;
			}
		}

		if (EA_MAX_NUM > g_eaNum)
		{
			/* 更新相邻控区输入 */
			g_szEaData[chEaIndex].wTrainId = pEaDataSt->wTrainId;
			g_szEaData[chEaIndex].strLgcInfo.chObjNum = pEaDataSt->strLgcInfo.chObjNum;
			if (EA_SECTION_MAX_NUM >= g_szEaData[chEaIndex].strLgcInfo.chObjNum)
			{
				(void)CommonMemCpy(g_szEaData[chEaIndex].strLgcInfo.szObjId, (UINT32)(sizeof(UINT16) * g_szEaData[chEaIndex].strLgcInfo.chObjNum), pEaDataSt->strLgcInfo.szObjId, (UINT32)(sizeof(UINT16) * g_szEaData[chEaIndex].strLgcInfo.chObjNum));
			}
			else
			{
				/*拷贝信息大于拷贝空间，不进行拷贝,宕机处理*/
				SetPlatOverFlag();
				debug_infor_printf((const)"EaNeighborUpdata is to shutdown,because the number of strLgcInfo chObjNum exceeds the limit");
			}
			g_szEaData[chEaIndex].chBuildedFlag = pEaDataSt->chBuildedFlag;
			g_szEaData[chEaIndex].dwMidLine = pEaDataSt->dwMidLine;
			g_szEaData[chEaIndex].chSrcTiocId = pEaDataSt->chSrcTiocId;
			g_szEaData[chEaIndex].chDstTiocId = pEaDataSt->chDstTiocId;
			g_szEaData[chEaIndex].chPaType = pEaDataSt->chPaType;
			g_szEaData[chEaIndex].dwEaBuildCycNum = pEaDataSt->dwEaBuildCycNum;
			g_szEaData[chEaIndex].chDstAllowed = EA_DST_ALLOWED_NO;

			if (chEaIndex < g_eaNum)
			{
				;
			}
			else
			{
				g_eaNum++;
			}
		}
		else
		{
			SetPlatOverFlag();
			debug_infor_printf((const)"EaNeighborUpdata is to shutdown,because the number of g_eaNum exceeds the limit");
		}
	}
	else
	{
		;
	}
}

/**
* @brief 相邻控区输入的防护区域更新
* @param EaDataStru * pEaData 相邻控区输入的防护区域
* @return 无
*/
void EaSetNeighborAllowFlag(UINT16 wTrainId, UINT8 chSrcTioc, UINT8 chDstTioc, UINT8 chFlag, UINT32 dwBuildCyc)
{
	UINT8 chEaIndex = 0u;
	UINT32 dwLocalEaBuildCyc = 0U;
	for (chEaIndex = 0u; chEaIndex < g_eaNum; chEaIndex++)
	{/* 找出指定疏散列车索引 */
		if ((wTrainId == g_szEaData[chEaIndex].wTrainId) && (PA_TYPE_EA == g_szEaData[chEaIndex].chPaType))
		{
			break;
		}
	}
	dwLocalEaBuildCyc = EaGetBuildCycNum(chEaIndex);
	if (chEaIndex < g_eaNum)
	{/* 找到对应疏散列车 */
		if ((g_szEaData[chEaIndex].chSrcTiocId == chSrcTioc) && (g_szEaData[chEaIndex].chDstTiocId == chDstTioc)
			&&(dwLocalEaBuildCyc == dwBuildCyc)&& (0U != dwBuildCyc))
		{/* 建立和目标TIOC与本控区存储一致 周期号正确*/
			g_szEaData[chEaIndex].chDstAllowed = chFlag;
		}
		else if ((g_szEaData[chEaIndex].chSrcTiocId == chSrcTioc) && (g_szEaData[chEaIndex].chDstTiocId == chDstTioc)
			&& (dwLocalEaBuildCyc != dwBuildCyc))
		{
			g_szEaData[chEaIndex].chDstAllowed = EA_DST_ALLOWED_NO;
			debug_infor_printf((const)"Train:%d not allowe build, localBuildCyc：%d--desTiocAnsewerCyc:%d\n", wTrainId, dwLocalEaBuildCyc, dwBuildCyc);
		}
		else
		{
			; /*不操作*/
		}
	}
	else
	{
		;
	}
}

/*
* 功能描述： 相邻TIOC通信良好，疏散防护区域处理
* 参数说明： UINT8 chTiocId 相邻TIOC编号
* 返回值  ： 无
*/
void NeighborGoodEaProc(UINT8 chTiocId)
{
	UINT8 chEaIndex = 0u;
	UINT8 chTransNum = 0u;
	UINT16 *pTransIds = NULL;
	UINT8 chTransIndex = 0u;
	UINT8 *pTransTypes = NULL;
	UINT32 *pTransCyc = NULL;

	/* 获取从对应TIOC获取到的防护区域信息 */
	chTransNum = GetTiocTransmitEaNum(chTiocId);
	pTransIds = GetTiocTransmitEaIds(chTiocId);
	pTransTypes = GetTiocTransmitPaTypes(chTiocId);
	pTransCyc = GetTiocTransmitPaBuildCyc(chTiocId);
	if (0u != g_eaNum)
	{
		for (chEaIndex = g_eaNum - 1u; 0u <= chEaIndex; chEaIndex--)
		{/* 遍历本地防护区域 */
			if (g_szEaData[chEaIndex].chSrcTiocId == chTiocId)
			{/* 建立TIOC为查询TIOC */
				for (chTransIndex = 0u; chTransIndex < chTransNum; chTransIndex++)
				{
					if ((g_szEaData[chEaIndex].wTrainId == pTransIds[chTransIndex])
						&& (g_szEaData[chEaIndex].chPaType == pTransTypes[chTransIndex])
						&&(g_szEaData[chEaIndex].dwEaBuildCycNum == pTransCyc[chTransIndex]))
					{
						break;
					}
					else
					{
						;
					}
				}

				if (chTransIndex == chTransNum)
				{/* 未在接口中找到，清除防护区域 */
					EaCancleExc(chEaIndex);
				}
				else
				{
					;
				}
			}
			else
			{
				;
			}

			if (0u == chEaIndex)
			{
				break;
			}
			else
			{
				;
			}
		}
	}
	else
	{
		;
	}
}

/**
* @brief 判断link是否处于防护区域内
* @param const UINT16 wLinkId link编号
* @return CI_ERROR:link处于防护区域内；CI_SUCCESS:link不处于防护区域内
*/
UINT8 IsLinkInEa(const UINT16 wLinkId)
{
	UINT8 chEaIndex = 0u;
	UINT8 chLinkIndex = 0u;
	UINT8 chRtn = CI_ERROR;
	for (chEaIndex = 0u; chEaIndex < g_eaNum; chEaIndex++)
	{
		for (chLinkIndex = 0u; chLinkIndex < g_szEaData[chEaIndex].strLinkInfo.chObjNum; chLinkIndex++)
		{
			if (wLinkId == g_szEaData[chEaIndex].strLinkInfo.szObjId[chLinkIndex])
			{
				break;
			}
		}
		if (chLinkIndex < g_szEaData[chEaIndex].strLinkInfo.chObjNum)
		{
			break;
		}
	}

	if (chEaIndex < g_eaNum)
	{
		chRtn = CI_ERROR;
	}
	else
	{
		chRtn = CI_SUCCESS;
	}

	return chRtn;
}

/**
* @brief 脱轨防护区域取消处理
* @param 无
* @return 无
*/
void DaAtsCancleProc(void)
{
	AtsDaMsgStru * strMsgFst = NULL;
	AtsDaMsgStru * strMsgSnd = NULL;
	strMsgFst = GetAtsDaMsgFst();
	strMsgSnd = GetAtsDaMsgSnd();

	if ((NULL == strMsgFst) || (NULL == strMsgSnd))
	{
		;
	}
	else
	{
		if ((strMsgFst->chFlag != FLAG_SET) && (strMsgSnd->chFlag != FLAG_SET))
		{
			; /* 没有消息，什么也不做 */
		}
		else if ((strMsgFst->chFlag == FLAG_SET) && (strMsgSnd->chFlag != FLAG_SET))
		{/* 取消脱轨防护区一次消息 */
			DaAtsCancleFst();
		}
		else
		{/* 取消脱轨防护区二次消息 */
			DaAtsCancleSnd();
		}
	}
}

/**
* @brief 取消脱轨防护区首次处理
* @param 无
* @return 无
*/
void DaAtsCancleFst(void)
{
	AtsDaMsgStru * strMsgFst = NULL;
	AtsMsgCfmStru * strCfmFst = NULL;
	UINT32 dwCycle = 0U;
	UINT8 chLocalId = 0U;
	UINT8 chRtn = CI_ERROR;
	UINT8 szCrcTmp[1024] = { 0U };
	UINT32 ii = 0U;
	UINT8 chFunRtn = CI_TIME_OUT;
	UINT16 wTrainId = 0U;
	UINT16 wTrainLgcId = 0U;
	UINT8 chPaIndex = 0U;
	UINT8 chDerailment = 0U;
	UINT8 chEaAreaLinkType = 0U;/*防护区域线路上下行属性*/

	chLocalId = GetSystemParaLocalCiId();
	dwCycle = Get2oo2CurCycleNum();

	/*以下消息获取不会返回NULL*/
	strMsgFst = GetAtsDaMsgFst();
	strCfmFst = GetAtsDaCfmFst();

	if (strMsgFst->dwCycle == dwCycle)
	{
		strCfmFst->chFlag = FLAG_SET;
		strCfmFst->chTiocId = chLocalId;
		strCfmFst->chStation = strMsgFst->chStation;
		strCfmFst->wIndex = strMsgFst->wIndex;
		strCfmFst->dwTime = dwCycle;

		chRtn = dquHlhtId2VobcName(strMsgFst->dwDaTrainId, &wTrainId, &wTrainLgcId);

		if (CI_ERROR == chRtn)
		{/* 获取列车ID出错，返回未知 */
			strCfmFst->chOpStatus = CONFIRM_DA_FST_UNKNOWN;
			ClearAtsDaMsgFirst();
		}
		else
		{
			chPaIndex = PaGetIndex(wTrainId, PA_TYPE_DA);
			if (chPaIndex == g_eaNum)
			{/* 脱轨防护区域未设置 */
				strCfmFst->chOpStatus = CONFIRM_DA_FST_UNSET;
			}
			else
			{
				chDerailment = GetTrainDerailment(wTrainId);
				if (TRAIN_DERAIL_NO != chDerailment)
				{/* 列车当前处于脱轨状态 */
					strCfmFst->chOpStatus = CONFIRM_DA_FST_DERAIL;
				}
				else
				{
					chEaAreaLinkType = GetEaAreaLineType(chPaIndex);
					if ((EA_AREA_ALL != strMsgFst->chLine) && (EA_AREA_ALL != chEaAreaLinkType) && (chEaAreaLinkType != strMsgFst->chLine))
					{
						/*ATS下发的线路上下行属性和本地存储的线路上下行属性相反，此时需要向网关反馈错误*/
						strCfmFst->chOpStatus = CONFIRM_EALINE_DIFFERENT;
					}
					else
					{
						strCfmFst->chOpStatus = CONFIRM_DA_FST_SUCCESS;
					}
				}
			}
		}

		szCrcTmp[ii] = strMsgFst->chAtsId;
		ii++;
		szCrcTmp[ii] = strMsgFst->chStation;
		ii++;
		ShortToChar(strMsgFst->wIndex, &szCrcTmp[ii]);
		ii += 2U;
		LongToChar(strMsgFst->dwDaTrainId, &szCrcTmp[ii]);
		ii += 4u;
		LongToChar(strMsgFst->dwTime, &szCrcTmp[ii]);
		ii += 4u;
		szCrcTmp[ii] = strMsgFst->chType;
		ii++;
		szCrcTmp[ii] = strMsgFst->chLine;
		ii++;
		strCfmFst->dwCrc32 = Tioc_CommonCrc32(szCrcTmp, ii);	/* ATS编号、车站编号、操作站编号、列车互联互通ID、下发时间、命令类型、区域计算CRC */

		if (CONFIRM_DA_FST_SUCCESS != strCfmFst->chOpStatus)
		{
			ClearAtsDaMsgFirst();
		}
		else
		{
			;
		}
	}
	else
	{/* 接收到ATS取消区间疏散一次消息非本周期，超时判断 */
		chFunRtn = SystemOverTimeCheck(strMsgFst->dwCycle, CONFIRM_TIMEOUT_CC);
		if (CI_TIME_OUT == chFunRtn)
		{
			ClearAtsDaMsgFirst();
		}
		else
		{
			;
		}
	}

}

/**
* @brief 取消脱轨防护区二次处理
* @param 无
* @return 无
*/
void DaAtsCancleSnd(void)
{
	AtsDaMsgStru * strMsgFst = NULL;
	AtsDaMsgStru * strMsgSnd = NULL;
	AtsMsgCfmStru * strCfmFst = NULL;
	AtsMsgCfmStru * strCfmSnd = NULL;
	UINT32 dwCycle = 0u;
	UINT8 chLocalId = 0u;
	UINT8 chFlag = FLAG_UNSET;
	UINT8 szCrcTmp[1024] = { 0u };
	UINT32 ii = 0u;
	UINT8 chFunRtn = CI_ERROR;
	UINT32 dwCrc = 0u;
	UINT16 wTrainId = 0u;
	UINT16 wTrainLgcId = 0u;
	UINT8 chPaIndex = 0u;
	UINT8 chDerailment = 0u;

	chLocalId = GetSystemParaLocalCiId();
	dwCycle = Get2oo2CurCycleNum();

	/*以下消息获取不会返回NULL*/
	strMsgFst = GetAtsDaMsgFst();
	strMsgSnd = GetAtsDaMsgSnd();
	strCfmFst = GetAtsDaCfmFst();
	strCfmSnd = GetAtsDaCfmSnd();

	if (strMsgSnd->dwCycle == dwCycle)
	{
		strCfmSnd->chFlag = FLAG_SET;
		strCfmSnd->chTiocId = chLocalId;
		strCfmSnd->chStation = strMsgSnd->chStation;
		strCfmSnd->wIndex = strMsgSnd->wIndex;
		strCfmSnd->dwTime = dwCycle;

		if (FLAG_SET != strMsgFst->chFlag)
		{/* 未执行首次取消 */
			strCfmSnd->chOpStatus = CONFIRM_DA_SND_FIRST;
			chFlag = FLAG_SET;
		}
		else if (strMsgSnd->dwDaTrainId != strMsgFst->dwDaTrainId)
		{/* ATS两次输入列车ID不同 */
			strCfmSnd->chOpStatus = CONFIRM_DA_SND_DIFF;
			chFlag = FLAG_SET;
		}
		else if ((strMsgSnd->chAtsId != strMsgFst->chAtsId)
			|| (strMsgSnd->chStation != strMsgFst->chStation)
			|| (strMsgSnd->wIndex != strMsgFst->wIndex)
			|| (strMsgSnd->chType != strMsgFst->chType))
		{/* ATS输入不一致，返回未知 */
			strCfmSnd->chOpStatus = CONFIRM_DA_SND_UNKNOWN;
			chFlag = FLAG_SET;
		}
		else if (strMsgSnd->chLine != strMsgFst->chLine)
		{
			/* 线路属性不一致 */
			strCfmSnd->chOpStatus = CONFIRM_DA_SND_LINE_DIFF;
			chFlag = FLAG_SET;
		}
		else
		{
			/*不处理*/
			;
		}

		if (FLAG_UNSET == chFlag)
		{
			chFunRtn = dquHlhtId2VobcName(strMsgSnd->dwDaTrainId, &wTrainId, &wTrainLgcId);
			chDerailment = GetTrainDerailment(wTrainId);
			if (TRAIN_DERAIL_NO != chDerailment)
			{
				/* 列车当前处于脱轨状态 */
				strCfmSnd->chOpStatus = CONFIRM_DA_SND_DERAIL;
				chFlag = FLAG_SET;
			}
			else
			{
				;
			}
		}
		else
		{
			;
		}

		if (FLAG_UNSET == chFlag)
		{
			szCrcTmp[ii] = strMsgSnd->chTiocId;
			ii++;
			LongToChar(strCfmFst->dwTime, &szCrcTmp[ii]);
			ii += 4u;
			szCrcTmp[ii] = strMsgSnd->chType;
			ii++;
			szCrcTmp[ii] = strMsgSnd->chLine;
			ii++;
			dwCrc = Tioc_CommonCrc32(szCrcTmp, ii);
			if (dwCrc != strMsgSnd->dwCrc32)
			{
				/* 计算的CRC32与ATS二次消息CRC32不一致 */
				strCfmSnd->chOpStatus = CONFIRM_DA_SND_CRC;
				chFlag = FLAG_SET;
			}
			else
			{
				;
			}
		}
		else
		{
			;
		}

		ii = 0u;
		szCrcTmp[ii++] = strMsgSnd->chAtsId;
		szCrcTmp[ii++] = strMsgSnd->chStation;
		ShortToChar(strMsgSnd->wIndex, &szCrcTmp[ii]);
		ii += 2U;
		LongToChar(strMsgSnd->dwDaTrainId, &szCrcTmp[ii]);
		ii += 4u;
		LongToChar(strMsgFst->dwTime, &szCrcTmp[ii]);
		ii += 4u;
		LongToChar(strMsgSnd->dwTime, &szCrcTmp[ii]);
		ii += 4u;
		szCrcTmp[ii++] = strMsgSnd->chType;
		szCrcTmp[ii++] = strMsgSnd->chLine;
		strCfmSnd->dwCrc32 = Tioc_CommonCrc32(szCrcTmp, ii);
		if (FLAG_UNSET == chFlag)
		{/* 检查通过，反馈确认成功 */
			strCfmSnd->chOpStatus = CONFIRM_DA_SND_SUCCESS;
			chPaIndex = PaGetIndex(wTrainId, PA_TYPE_DA);
			EaAtsCancleExc(chPaIndex);
		}
		else
		{
			;
		}
	}
	else
	{
		; /** 非本周期消息，不处理 */
	}
	ClearAtsDaMsgFirst();
	ClearAtsDaMsgSecond();

}

/**
* @brief 获取指定防护区域类型
* @param chIndex 下标
* @return 防护区域类型
*/
UINT8 GetPaTypeByIndex(UINT8 chIndex)
{
	UINT8 rtnValue = 0u;

	if (EA_MAX_NUM > chIndex)
	{
		rtnValue = g_szEaData[chIndex].chPaType;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 获取防护区域对应数据表的ID
* @param chIndex 下标
* @return 防护区域ID
*/
UINT8 GetEaConfigID(UINT8 chIndex)
{
	UINT8 rtnValue = 0u;

	if (EA_MAX_NUM > chIndex)
	{
		rtnValue = g_szEaData[chIndex].chEaConfigId;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 获取防护区域link数量
* @param const UINT8 chIndex 防护区域索引
* @return 防护区域link数量
*/
UINT8 EaGetLinkNum(const UINT8 chIndex)
{
	UINT8 chRtn = 0u;
	if (EA_MAX_NUM > chIndex)
	{
		chRtn = g_szEaData[chIndex].strLinkInfo.chObjNum;
	}
	else
	{
		;
	}
	return chRtn;
}

/**
* @brief 获取防护区域link编号
* @param const UINT8 chIndex 防护区域索引
* @return 防护区域link编号
*/
UINT16 * EaGetLinkId(const UINT8 chIndex)
{
	UINT16 * pRtn = NULL;
	if (EA_MAX_NUM > chIndex)
	{
		pRtn = g_szEaData[chIndex].strLinkInfo.szObjId;
	}
	else
	{
		;
	}
	return pRtn;
}

/**
* @brief 获取防护区域计轴区段数量
* @param const UINT8 chIndex 防护区域索引
* @return 防护区域计轴区段数量
*/
UINT8 EaGetAcNum(const UINT8 chIndex)
{
	UINT8 chRtn = 0u;
	if (EA_MAX_NUM > chIndex)
	{
		chRtn = g_szEaData[chIndex].strAcInfo.chObjNum;
	}
	else
	{
		;
	}
	return chRtn;
}

/**
* @brief 获取防护区域计轴区段编号
* @param const UINT8 chIndex 防护区域索引
* @return 防护区域计轴区段编号
*/
UINT16 * EaGetAcId(const UINT8 chIndex)
{
	UINT16 * pRtn = NULL;
	if (EA_MAX_NUM > chIndex)
	{
		pRtn = g_szEaData[chIndex].strAcInfo.szObjId;
	}
	else
	{
		;
	}
	return pRtn;
}

/**
* @brief 判断逻辑区段是否处于防护区域内
* @param const UINT16 wLgcId 逻辑区段编号
* @return CI_ERROR:逻辑区段处于防护区域内；CI_SUCCESS:逻辑区段不处于防护区域内
*/
UINT8 IsLgcInEa(const UINT16 wLgcId)
{
	UINT8 chEaIndex = 0u;
	UINT8 chLgcIndex = 0u;
	UINT8 chRtn = CI_ERROR;
	for (chEaIndex = 0u; chEaIndex < g_eaNum; chEaIndex++)
	{
		for (chLgcIndex = 0u; chLgcIndex < g_szEaData[chEaIndex].strLgcInfo.chObjNum; chLgcIndex++)
		{
			if (wLgcId == g_szEaData[chEaIndex].strLgcInfo.szObjId[chLgcIndex])
			{
				break;
			}
		}
		if (chLgcIndex < g_szEaData[chEaIndex].strLgcInfo.chObjNum)
		{
			break;
		}
	}

	if (chEaIndex < g_eaNum)
	{
		chRtn = CI_ERROR;
	}
	else
	{
		chRtn = CI_SUCCESS;
	}

	return chRtn;
}

/**
* @brief 获取列车防护区域存储索引
* @param const UINT16 wTrainId
* @param const UINT8 chType
* @return 成功:索引，失败:g_eaNum
*/
static UINT8 PaGetIndex(const UINT16 wTrainId, const UINT8 chType)
{
	UINT8 chIndex = 0u;
	UINT8 chLocalId = GetSystemParaLocalCiId();
	for (chIndex = 0u; chIndex < g_eaNum; chIndex++)
	{
		if ((wTrainId == g_szEaData[chIndex].wTrainId) && (g_szEaData[chIndex].chSrcTiocId == chLocalId)
			&& (chType == g_szEaData[chIndex].chPaType))
		{
			break;
		}
		else
		{
			; /* 继续遍历 */
		}
	}

	return chIndex;
}


/*
* 功能描述： 计轴区段是否为防护区域检查
* 参数说明：const UINT16 wAxisSecId 计轴区段ID
*           const UINT8 chSetAreaType 防护区域建立类型
*           const UINT16 wTrainId 列车ID
* 返回值  ： CI_ERROR 检查不通过
*            CI_SUCCESS 检查通过
* by cgh 20240105
*/
UINT8 AxisSecAddProAreaCheck(const UINT16 wAxisSecId,const UINT8 chSetAreaType,const UINT16 wTrainId)
{
	UINT8 chReval = CI_SUCCESS;/*安全侧是要建立，检查通过*/
	UINT8 chEvacuateRelDirSwitch = 0U;/*区间疏散防护区域区分上下行开关*/
	UINT8 chTgRelDirSwitch = 0U;      /*脱轨防护区域区分上下行开关*/
	UINT16 wMaxHeadLink = 0U;/*列车大前所在LINK*/
	UINT8 chTrainLinkLine = 0U;/*列车所在LINK线路上下行属性*/
	UINT8 chAxisLinkTgEvacuateDir = 0U;/*计轴区段LINK脱轨及区间疏散防护线路上下行属性*/
	UINT16* wAxisIncLinkBuf = NULL;/*计轴区段包含LINK*/

	if ((0U < wAxisSecId) && (AXIS_SECTION_SUM_MAX > wAxisSecId)
		&& ((PA_TYPE_DA == chSetAreaType) || (PA_TYPE_EA == chSetAreaType))
		&& (((0U < wTrainId) && (TRAIN_SUM_MAX > wTrainId)) || ((TRAIN_ID_MIN < wTrainId) && (TRAIN_ID_MAX > wTrainId))))
	{
		wAxisIncLinkBuf = EaGetAcLinkId(wAxisSecId);

		if (NULL != wAxisIncLinkBuf)
		{
			chAxisLinkTgEvacuateDir = GetLinkTgEvacuateDir(wAxisIncLinkBuf[0]);

			if (LINK_TGEVACUATEDIR_ALL == chAxisLinkTgEvacuateDir)
			{
				/*计轴区段对应LINK的脱轨及区间疏散防护线路上下行属性为上下行均防护，直接添加此计轴区段,不再进行防护区域类型及开关判断*/
				chReval = CI_SUCCESS;
			}
			else if((LINK_TGEVACUATEDIR_UP == chAxisLinkTgEvacuateDir) || (LINK_TGEVACUATEDIR_DOWN == chAxisLinkTgEvacuateDir))
			{
				chEvacuateRelDirSwitch = GetCiFunctionSwitchConfig(FUNC_EVACUATE_RELATE_DIR_SWITCH);
				chTgRelDirSwitch = GetCiFunctionSwitchConfig(FUNC_TG_RELATE_DIR_SWITCH);

				if ((FUNC_SWITCH_OFF == chEvacuateRelDirSwitch) && (FUNC_SWITCH_OFF == chTgRelDirSwitch))
				{
					/*2个开关均为关闭，则直接添加此计轴区段,不再进行防护区域类型判断*/
					chReval = CI_SUCCESS;
				}
				else
				{
					wMaxHeadLink = GetTrainMaxHeadLink(wTrainId);
					chTrainLinkLine = GetLinkTgEvacuateDir(wMaxHeadLink);

					if (((PA_TYPE_EA == chSetAreaType) && (FUNC_SWITCH_ON == chEvacuateRelDirSwitch))
						|| ((PA_TYPE_DA == chSetAreaType) && (FUNC_SWITCH_ON == chTgRelDirSwitch)))
					{
						if (LINK_TGEVACUATEDIR_ALL == chTrainLinkLine)
						{
							/*列车大前所在LINK脱轨及区间疏散上下行属性为均防护，直接添加*/
							chReval = CI_SUCCESS;
						}
						else if ((LINK_TGEVACUATEDIR_UP == chTrainLinkLine) || (LINK_TGEVACUATEDIR_DOWN == chTrainLinkLine))
						{
							/*区间疏散需要区分上下行*/
							if (chAxisLinkTgEvacuateDir == chTrainLinkLine)
							{
								/*计轴区段对应LINK的脱轨及区间疏散防护线路上下行属性与列车大前所在LINK的线路上下行属性相同*/
								chReval = CI_SUCCESS;
							}
							else
							{
								chReval = CI_ERROR;/*属性不同不添加*/
							}
						}
						else
						{
							chReval = CI_SUCCESS; /*数据非法*/
						}
					}
					else
					{
						chReval = CI_SUCCESS;
					}
				}
			}
			else
			{
				chReval = CI_SUCCESS; /*数据非法*/
			}
		}
		else
		{
			chReval = CI_SUCCESS; /*数据非法*/
		}
	}
	else
	{
		chReval = CI_SUCCESS; /*入参校验不通过*/
	}

	return chReval;
}

/**
* @brief 获取防护区域上下行区域类型
* @param chIndex 下标
* @return EA_AREA_UP	  上行区域
*		  EA_AREA_DOWN	  下行区域
*		  EA_AREA_ALL	  上行和下行区域
* by cgh 20240321
*/
UINT8 GetEaAreaLineType(UINT8 chIndex)
{
	UINT8 rtnValue = EA_AREA_ALL;

	if (EA_MAX_NUM > chIndex)
	{
		rtnValue = g_szEaData[chIndex].chEaAreaLinkType;
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief 清理防护区域内被取消的区段信息
* @param const UINT8 chEaIndex 防护区域索引ID
* @return 无
* by cgh 20240326
*/
void ClearEaSecData(const UINT8 chEaIndex)
{
	UINT8 chEaSecIndex = 0U;/*区段循环索引*/
	UINT8 chEaTempIndex = 0U;/*防护区域临时循环索引*/
	UINT8 chLgcIndex = 0U;/*逻辑区段索引*/
	UINT16 szTempAxisSecId[EA_SECTION_MAX_NUM] = { 0U };/*计轴区段临时数组*/
	UINT8 chTempAxisSecSum = 0U;/*计轴区段区段临时数目*/
	UINT16 szTempLogSecId[EA_SECTION_MAX_NUM] = { 0U };/*逻辑区段临时数组*/
	UINT8 chTempLogSecSum = 0U;/*逻辑区段临时数目*/
	UINT8 chLinkNum = 0U;/*LINK数目*/
	UINT16* pLinkIdBuff = NULL;/*LINK数组*/
	UINT8 chLgcNum = 0U;/*逻辑区段数目*/
	UINT16* pLgcIdBuff =NULL;/*逻辑区段数组*/
	UINT8 ii = 0U;
	UINT8 chFindFlag = CI_ERROR;
	UINT8 chCheckFlag = CI_ERROR;
	UINT16 wTempLinkLineType = 0U;/*临时LINK线路上下行属性*/
	UINT16 wLinkLineType = 0U;/*LINK线路上下行属性*/

	if ((EA_MAX_NUM > chEaIndex) && (0U < g_eaNum) && (chEaIndex < g_eaNum))
	{
		chCheckFlag = CI_SUCCESS;
		for (chEaSecIndex = 0U; chEaSecIndex < g_szEaData[chEaIndex].strAcInfo.chObjNum; chEaSecIndex++)
		{
			chFindFlag = CI_ERROR;
			chLinkNum = EaGetAcLinkNum(g_szEaData[chEaIndex].strAcInfo.szObjId[chEaSecIndex]);
			pLinkIdBuff = EaGetAcLinkId(g_szEaData[chEaIndex].strAcInfo.szObjId[chEaSecIndex]);
			if ((0U == chLinkNum) || (NULL == pLinkIdBuff))
			{
				szTempAxisSecId[chTempAxisSecSum] = g_szEaData[chEaIndex].strAcInfo.szObjId[chEaSecIndex];
				chTempAxisSecSum++;
			}
			else
			{
				for (ii = 0U; ii < chLinkNum; ii++)
				{
					for (chEaTempIndex = 0U; chEaTempIndex < g_szEaData[chEaIndex].strLinkInfo.chObjNum; chEaTempIndex++)
					{
						if (pLinkIdBuff[ii] == g_szEaData[chEaIndex].strLinkInfo.szObjId[chEaTempIndex])
						{
							/*计轴对应的LINK目前在防护分区中存在，保留此计轴区段*/
							chFindFlag = CI_SUCCESS;
							break;
						}
						else
						{
							;
						}
					}
					if (CI_SUCCESS == chFindFlag)
					{
						break;
					}
				}

				if (CI_SUCCESS == chFindFlag)
				{
					szTempAxisSecId[chTempAxisSecSum] = g_szEaData[chEaIndex].strAcInfo.szObjId[chEaSecIndex];
					chTempAxisSecSum++;
				}
				else
				{
					; /*说明已被取消*/
				}
			}
		}

		/* 遍历计算出的计轴区段序列 */
		for (chEaSecIndex = 0U; chEaSecIndex < chTempAxisSecSum; chEaSecIndex++)
		{
			chLgcNum = EaGetAcLgcNum(szTempAxisSecId[chEaSecIndex]);
			pLgcIdBuff = EaGetAcLgcId(szTempAxisSecId[chEaSecIndex]);

			if ((0U == chLgcNum) || (NULL == pLgcIdBuff))
			{
				chCheckFlag = CI_ERROR;
			}
			else
			{/* 将计轴区段序列包含的所有逻辑区段去重记录 */
				for (chEaTempIndex = 0U; chEaTempIndex < chLgcNum; chEaTempIndex++)
				{
					for (chLgcIndex = 0U; chLgcIndex < chTempLogSecSum; chLgcIndex++)
					{
						if (pLgcIdBuff[chEaTempIndex] == szTempLogSecId[chLgcIndex])
						{
							break;
						}
						else
						{
							;
						}
					}
					if (chLgcIndex == chTempLogSecSum)
					{
						if (EA_SECTION_MAX_NUM > chTempLogSecSum)
						{
							szTempLogSecId[chTempLogSecSum] = pLgcIdBuff[chEaTempIndex];
							chTempLogSecSum++;
						}
						else
						{
							;
						}
					}
					else
					{
						;
					}
				}
			}

		}
		if (CI_SUCCESS == chCheckFlag)
		{
			/*计轴区段对应逻辑区段有非法，不改变逻辑区段，维持不变*/

			g_szEaData[chEaIndex].strAcInfo.chObjNum = chTempAxisSecSum;
			(void)CommonMemCpy((void*)(&g_szEaData[chEaIndex].strAcInfo.szObjId), (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM), (void*)(&szTempAxisSecId), (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM));

			g_szEaData[chEaIndex].strLgcInfo.chObjNum = chTempLogSecSum;
			(void)CommonMemCpy((void*)(&g_szEaData[chEaIndex].strLgcInfo.szObjId), (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM), (void*)(&szTempLogSecId), (UINT32)(sizeof(UINT16) * EA_SECTION_MAX_NUM));

			/*更新LINK的线路上下行属性*/
			RefreshEaLineType(chEaIndex);
		}
		else
		{
			; /*不改变，维持不变*/
		}
	}
	else
	{

	}
}

/**
* @brief 更新防护区域的线路上下行属性
* @param const UINT8 chEaIndex 防护区域索引ID
* @return 无
* by cgh 20240402
*/
void RefreshEaLineType(const UINT8 chEaIndex)
{
	UINT8 chEaTempIndex = 0U;
	UINT16 wTempLinkLineType = 0U;/*临时LINK线路上下行属性*/
	UINT16 wLinkLineType = 0U;/*LINK线路上下行属性*/

	if (EA_MAX_NUM > chEaIndex)
	{
		wTempLinkLineType = GetLinkLineById(g_szEaData[chEaIndex].strLinkInfo.szObjId[0]);
		/* 遍历计算出的LINK序列,确定防护区域的上下行属性 */
		for (chEaTempIndex = 0u; chEaTempIndex < g_szEaData[chEaIndex].strLinkInfo.chObjNum; chEaTempIndex++)
		{
			wLinkLineType = GetLinkLineById(g_szEaData[chEaIndex].strLinkInfo.szObjId[chEaTempIndex]);
			/*查询已建立防护区域对应LINK的上下行线路属性*/

			if (wTempLinkLineType == wLinkLineType)
			{
				;
			}
			else
			{
				/*只要有一个LINK的线路上下行属性和基准LINK的线路上下行属性不一致，就跳出*/
				break;
			}
		}
		if (g_szEaData[chEaIndex].strLinkInfo.chObjNum == chEaTempIndex)
		{
			/*所有LINK的线路上下行属性均和基准LINK一致，则取基准LINK的上下行属性为防护区域上下行属性*/
			if (EMAP_LINK_LINE_UP == wLinkLineType)
			{
				g_szEaData[chEaIndex].chEaAreaLinkType = EA_AREA_UP;
			}
			else if (EMAP_LINK_LINE_DOWN == wLinkLineType)
			{
				g_szEaData[chEaIndex].chEaAreaLinkType = EA_AREA_DOWN;
			}
			else
			{
				g_szEaData[chEaIndex].chEaAreaLinkType = EA_AREA_ALL;
			}
		}
		else
		{
			g_szEaData[chEaIndex].chEaAreaLinkType = EA_AREA_ALL;
		}
	}
	else
	{

	}
}

/*
* 功能描述： 获取指定ID计轴区段所属TIOC编号（可查询全线计轴）
* 参数说明： const UINT16 axisSectionId, 计轴区段ID
* 返回值  ： 0: 获取数据失败
*			>0: 计轴区段所属TIOC编号
*/
UINT16 GetAxisBelongTiocAllLine(const UINT16 wAcId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT16 retVal = CI_ERROR;
	UINT16 wLinkId = 0u;
	UINT16 i = 0U;

	if (wAcId < AXIS_SECTION_SUM_MAX)
	{
		for (i = 0; i < AXIS_SECTION_SUM_MAX; i++)
		{
			if (wAcId == g_szEaAcConfig[i].AxisSectionId)
			{
				wLinkId = g_szEaAcConfig[i].szLinkIdBuff[0];
				retVal = GetLinkManageTiocById(wLinkId);
				break;
			}
			else
			{
				/*继续遍历*/
			}
		}
	}
	else
	{
		retVal = CI_ERROR;
	}
	return retVal;
}

/*
* 功能描述：获取防护区域的建立周期号
* 参数说明：UINT8 chIndex 防护区域索引
* 返回值  ： UINT32 建立Tioc的周期号
*/
UINT32 EaGetBuildCycNum(const UINT8 chIndex)
{
	UINT32 retCycNum = 0U;
	if (EA_MAX_NUM > chIndex)
	{
		retCycNum = g_szEaData[chIndex].dwEaBuildCycNum;
	}
	else
	{
		;
	}
	return retCycNum;
}

/*
* 功能描述：根据防护区域编号获取防护区域的索引
* 参数说明：UINT16 wEaId 防护区域编号
* 返回值  ： 0< 防护区域的索引
*	         0  数据获取失败
* by cgh 20250311
*/
UINT16 GetEaIndex(const UINT16 wEaId)
{
	UINT16 wReval = 0U;
	UINT16 wEaIndex = 0U;

	if (EA_CFG_SUM_MAX > wEaId)
	{
		for (wEaIndex = 0U; wEaIndex < g_eaConfigNum; wEaIndex++)
		{
			if (wEaId == g_szEaConfig[wEaIndex].wId)
			{
				wReval = wEaIndex;
				break;
			} 
			else
			{
				;
			}
		}
	}
	else
	{
		;
	}
	return wReval;
}

/**
* @brief 添加防护分区计轴区段
* @param chEaIndex 索引
* @param wAxisSecId 计轴区段ID
* @param chType 类型
* @param wTrainId 疏散列车ID
* @param chEaconfigId 防护分区编号
* @return CI_ERROR 失败
*         CI_SUCCESS 成功
* BY CGH 20250527
*/
static UINT8 AddEaAxisSec(UINT8 chEaIndex, UINT16 wAxisSecId, UINT8 chType, UINT16 wTrainId, UINT8 chEaconfigId)
{
	UINT8 chReval = CI_ERROR;
	UINT8 chIndex = 0U;
	UINT8 chAcBelongCiId = 0; /*计轴区段所属联锁ID*/
	UINT8 chAcBelongCiType = 0; /*计轴区段所属联锁类型*/
	UINT8 chAxisSecAddFlag = CI_ERROR;/*计轴区段是否加入防护区域标志*/

	if ((0U < wAxisSecId) && (AXIS_SECTION_SUM_MAX > wAxisSecId))
	{
		chReval = CI_SUCCESS;
		/*去重*/
		for (chIndex = 0u; chIndex < g_szEaData[chEaIndex].strAcInfo.chObjNum; chIndex++)
		{
			/*检查是否已经记录过*/
			if (g_szEaData[chEaIndex].strAcInfo.szObjId[chIndex] == wAxisSecId)
			{
				break;
			}
			else
			{
				;
			}
		}
		/*没有记录过*/
		if (g_szEaData[chEaIndex].strAcInfo.chObjNum == chIndex)
		{
			/*判断该计轴是否属于正线联锁或试车线联锁*/
			chAcBelongCiId = (UINT8)GetAxisBelongTiocAllLine(wAxisSecId);
			chAcBelongCiType = GetCiType(chAcBelongCiId);/*获取当前计轴所属联锁类型*/
			/*需要根据功能开关判断是否根据上下行建立防护区域*/
			chAxisSecAddFlag = AxisSecAddProAreaCheck(wAxisSecId, chType, wTrainId);

			if (((CI_TYPE_ZX == chAcBelongCiType) || (CI_TYPE_SCX == chAcBelongCiType))
				&& (CI_SUCCESS == chAxisSecAddFlag))
			{

				if (EA_SECTION_MAX_NUM > g_szEaData[chEaIndex].strAcInfo.chObjNum)
				{
					g_szEaData[chEaIndex].strAcInfo.szObjId[g_szEaData[chEaIndex].strAcInfo.chObjNum] = wAxisSecId;
					g_szEaData[chEaIndex].strAcInfo.chObjNum++;
					g_szEaData[chEaIndex].chEaConfigId = chEaconfigId;
				}
				else
				{
					chReval = CI_ERROR;
				}
			}
			else
			{
				/*非正线或试车线联锁，不添加计轴*/
			}
		}
		else
		{
			;
		}

		
	}
	else
	{
		;
	}

	return chReval;
}

/**
* @brief 检查是否添加特殊防护区域计轴区段
* @param const UINT16 wAcId 计轴区段编号
* @param const UINT16 wSpecialEaId 特殊防护区域编号
* @return UINT8_MAX 数据异常
*         CI_ERROR 不添加在补充区域 
*         CI_SUCCESS 需要添加在补充区域 
* by cgh 20250818
*/
static UINT8 CheckAddSpecialEaAxis(const UINT16 wAcId,const UINT16 wSpecialEaId)
{
	UINT8 chRtn = CI_ERROR;
	UINT8 chLinkNum = 0U;
	UINT16* pLinkIdBuff = NULL;
	UINT8 ii = 0U;
	UINT16 wLinkSpecialEa = 0U; /*特殊防护区域属性*/

	if ((0U < wAcId) && (AXIS_SECTION_SUM_MAX > wAcId) && (0U < wSpecialEaId))
	{
		chLinkNum = EaGetAcLinkNum(wAcId);
		pLinkIdBuff = EaGetAcLinkId(wAcId);

		if (NULL != pLinkIdBuff)
		{
			for (ii = 0U; ii < chLinkNum; ii++)
			{
				wLinkSpecialEa = GetLinkSpecialEaAttr(pLinkIdBuff[ii]);

				if (wSpecialEaId == wLinkSpecialEa)
				{
					chRtn = CI_SUCCESS;
					break;
				}
				else
				{
					; 
				}
			}
		}
		else
		{
			chRtn = UINT8_MAX; /*返回异常*/
		}
	}
	else
	{
		chRtn = UINT8_MAX; /*返回异常*/
	}
	
	return chRtn;
}

/**
* @brief 计算防护分区是否完全在特殊防护区域
* @param wTrainId 疏散列车ID
* @param  UINT16* wSpecialEaId 特殊防护区域ID
* @return CI_ERROR 不完全在   CI_SUCCESS 完全在
* edit cgh 20250818
*/
static UINT8 CalcSpecialEa(const UINT16 wTrainId, UINT16* wSpecialEaId)
{
	UINT8 chRtn = CI_ERROR;
	UINT16 wMaxHeadLinkId = 0U; /*大前LINK ID*/
	UINT16 wMinTailLinkId = 0U; /*小后LINK ID*/
	UINT8 chTrainDir_Maxhead = 0u; /*以列车大前方向作为基准*/
	UINT8 chTrainDir_outTail = 0u;  /*车尾向外的方向，小后方向取反*/
	UINT16 wMaxHeadLinkSpecialEa = 0U; /*大前特殊防护区域属性*/
	UINT16 wMinTailLinkSpecialEa = 0U; /*小后特殊防护区域属性*/
	UINT16 wMaxHeadLinkBelCiId = 0U; /*大前LINK所属联锁ID*/
	UINT16 wMinTailLinkBelCiId = 0U; /*小后LINK所属联锁ID*/
	UINT8 chMaxHeadLinkBelCiType = 0U; /*大前LINK所属联锁类型*/
	UINT8 chMinTailLinkBelCiType = 0U; /*小后LINK所属联锁类型*/
	UINT32 dwSearchLen = 0U;/*查询距离*/
	UINT32 errorCode = 0U;
	struct_PathPoint pPoint = { 0U }; /*位置信息*/

	wMaxHeadLinkId = GetTrainMaxHeadLink(wTrainId);
	wMinTailLinkId = GetTrainMinTailLink(wTrainId);

	if ((0U < wMaxHeadLinkId) && (LINK_SUM_MAX > wMaxHeadLinkId) && (0U < wMinTailLinkId) && (LINK_SUM_MAX > wMinTailLinkId) && (NULL != wSpecialEaId))
	{
		wMaxHeadLinkSpecialEa = GetLinkSpecialEaAttr(wMaxHeadLinkId);
		wMinTailLinkSpecialEa = GetLinkSpecialEaAttr(wMinTailLinkId);
		wMaxHeadLinkBelCiId = GetLinkManageTiocById(wMaxHeadLinkId);
		wMinTailLinkBelCiId = GetLinkManageTiocById(wMinTailLinkId);
		chMaxHeadLinkBelCiType = GetCiType(wMaxHeadLinkBelCiId);
		chMinTailLinkBelCiType = GetCiType(wMinTailLinkBelCiId);

		if (((0U != wMaxHeadLinkSpecialEa) || (CI_TYPE_CLD == chMaxHeadLinkBelCiType))
			&& ((0U != wMinTailLinkSpecialEa) || (CI_TYPE_CLD == chMinTailLinkBelCiType)))
		{
			/*大前小后均在出入段线特殊防护区域（在车辆段认为也是在特殊区域）*/

			/*车在防护区域，只要不查出特殊防护区域，就认为列车最终的防护区域为对应出入段线*/
			chRtn = CI_SUCCESS;

			if (0U != wMaxHeadLinkSpecialEa)
			{
				*wSpecialEaId = wMaxHeadLinkSpecialEa;
				chTrainDir_Maxhead = GetTrainDir_MaxHead(wTrainId);
				dwSearchLen = GetLinkSpecialEaFrontDis(wMaxHeadLinkId);
				pPoint.wLinkId = wMaxHeadLinkId;
				pPoint.dwOffset = GetTrainMaxHeadOffset(wTrainId);
				chRtn = EaFindLinkAdjacentLinkID(pPoint, chTrainDir_Maxhead, dwSearchLen);
			}
			else
			{
				
			}
			
			if (CI_SUCCESS == chRtn)
			{
				if (0U != wMinTailLinkSpecialEa)
				{
					*wSpecialEaId = wMinTailLinkSpecialEa;
					chTrainDir_outTail = GetTrainDir(wTrainId);
					chTrainDir_outTail = ConvertTrainDir(chTrainDir_outTail); /*小后方向取反*/
					dwSearchLen = GetLinkSpecialEaBehindDis(wMinTailLinkId);
					pPoint.wLinkId = wMinTailLinkId;
					pPoint.dwOffset = GetTrainMinTailOffset(wTrainId);
					chRtn = EaFindLinkAdjacentLinkID(pPoint, chTrainDir_outTail, dwSearchLen);
				}
				else
				{
					; 
				}

				if (CI_SUCCESS != chRtn)
				{
					errorCode += 0x04000000U;
				}
				else
				{
					; 
				}
			}
			else
			{
				errorCode += 0x08000000U;
			}	
		}
		else
		{
			if (0U != wMaxHeadLinkSpecialEa)
			{
				*wSpecialEaId = wMaxHeadLinkSpecialEa;
				errorCode += 0x40000000U;
			}
			else
			{
				if (0U != wMinTailLinkSpecialEa)
				{
					*wSpecialEaId = wMinTailLinkSpecialEa;
					errorCode += 0x20000000U;
				}
				else
				{
					errorCode += 0x10000000U;
				}
			}
		}
	}
	else
	{
		errorCode += 0x80000000U;
	}

	debug_infor_printf((const)"\CalcSpecialEa Error errorCode:0x%08x\n", errorCode);
	return chRtn;
}

/**
* @brief 防护区域查询当前link的相邻link（目前仅用于出入段线特殊防护区域判断）
* @param struct_PathPoint pPoint 当前link信息
* @param UINT8 chDirection 查询方向
* @param UINT32 dwSearchLen	查询长度
* @return CI_SUCCESS 检查通过 CI_ERROR 检查失败 
* BY CGH 20250818
*/
static UINT8 EaFindLinkAdjacentLinkID(struct_PathPoint pPoint, UINT8 chDirection, UINT32 dwSearchLen)
{
	UINT16 wFindLinkId = 0U;/*函数返回值*/
	UINT8 chReturn = CI_ERROR;
	LinkPointDataStru pathTreeTemp = { 0U };/*端点信息*/
	UINT8 chDirectionPointfirst = 0U;			/*方向变化点1*/
	UINT8 chDirectionPointsecond = 0U;			/*方向变化点2*/
	UINT8 chTempDir = 0U; /*临时方向*/
	UINT32 dwAddSearchLen = 0U;/*累加长度*/
	UINT16 wLinkBelCiId = 0U; /*LINK所属联锁ID*/
	UINT8 chLinkBelCiType = 0U; /*LINK所属联锁类型*/
	UINT16 wLinkSpecialEa = 0U; /*特殊防护区域属性*/
	UINT8 chCheckFinishFlag = CI_FALSE; /*检查结束标志*/
	UINT16 wCurrentLinkId = 0U;
	
	if ((DIR_SAME == chDirection) || (DIR_CONVERT == chDirection))
	{
		chReturn = CI_SUCCESS;
		chTempDir = chDirection;
		dwAddSearchLen = GetRelDirLinkOffset(pPoint, chTempDir);
		wCurrentLinkId = pPoint.wLinkId;
		while ((dwAddSearchLen < dwSearchLen) && (CI_FALSE == chCheckFinishFlag))
		{
			/*查询link端点信息*/
			chReturn = GetLinkPointInfo(chTempDir, wCurrentLinkId, &pathTreeTemp);
			if (CI_SUCCESS != chReturn)
			{
				/*返回查询失败*/
				chReturn = CI_ERROR;
				chCheckFinishFlag = CI_TRUE;
			}
			else
			{
				if (UINT16_MAX == pathTreeTemp.wMainLinkId)
				{
					/*无相邻link，查询失败*/
					chReturn = CI_ERROR;
					chCheckFinishFlag = CI_TRUE;
				}
				else
				{
					if (EMAP_AXLE_DOT == pathTreeTemp.wPointType)
					{
						/* 获取下一linkID*/
						wFindLinkId = pathTreeTemp.wMainLinkId;
						dwAddSearchLen += GetLinkLengthById(wFindLinkId);
						wLinkSpecialEa = GetLinkSpecialEaAttr(wFindLinkId);
						wLinkBelCiId = GetLinkManageTiocById(wFindLinkId);
						chLinkBelCiType = GetCiType(wLinkBelCiId);

						if (CI_TYPE_CLD == chLinkBelCiType)
						{
							chCheckFinishFlag = CI_TRUE;
						}
						else if(0U != wLinkSpecialEa)
						{
							/*若端点为计轴点，查询本link和下一linkID是否具有方向变化点，且两个link方向变化点为对顶点，则直接返回linkID，并反馈方向变化点信息*/
							chDirectionPointfirst = GetLinkLogicDirChangedById(wCurrentLinkId);
							chDirectionPointsecond = GetLinkLogicDirChangedById(wFindLinkId);
							if (((LINK_DIRCHANGE_BEGIN == chDirectionPointfirst) || (LINK_DIRCHANGE_END == chDirectionPointfirst))
								&& (chDirectionPointsecond == chDirectionPointfirst))
							{
								chTempDir = ConvertTrainDir(chTempDir);
							}
							else
							{
								;	/*没方向变化点，继续运行*/
							}

							wCurrentLinkId = wFindLinkId;
						}
						else
						{
							/*不是车辆段且不具备特殊区域属性，说明超出了特殊防护区域*/
							chReturn = CI_ERROR;
							chCheckFinishFlag = CI_TRUE;
						}


					}
					else if (EMAP_POINT_DOT == pathTreeTemp.wPointType)
					{
						wFindLinkId = pathTreeTemp.wMainLinkId;
						dwAddSearchLen += GetLinkLengthById(wFindLinkId);
						wLinkBelCiId = GetLinkManageTiocById(wFindLinkId);
						chLinkBelCiType = GetCiType(wLinkBelCiId);
						if (CI_TYPE_CLD == chLinkBelCiType)
						{
							chCheckFinishFlag  = CI_TRUE;
						}
						else
						{
							/*找到有道岔的LINK，但是不是车辆段的，说明超出了特殊防护区域*/
							chReturn = CI_ERROR;
							chCheckFinishFlag = CI_TRUE;
						}
					}
					else
					{
						/*无相邻link，查询失败*/
						chReturn = CI_ERROR;
						chCheckFinishFlag = CI_TRUE;
					}
				}
			}
		}
	}
	else
	{
		; 
	}

	return chReturn;
}

/**
* @brief 获取计轴区段特殊防护区域编号
* @param const UINT16 wAcId 计轴区段编号
* @return 特殊防护区域编号
* by cgh 20250826
*/
static UINT16 GetAxisSpecialEaId(const UINT16 wAcId)
{
	UINT16 wRtn = CI_ERROR;
	UINT8 chLinkNum = 0U;
	UINT16* pLinkIdBuff = NULL;
	UINT8 ii = 0U;

	if ((0U < wAcId) && (AXIS_SECTION_SUM_MAX > wAcId))
	{
		chLinkNum = EaGetAcLinkNum(wAcId);
		pLinkIdBuff = EaGetAcLinkId(wAcId);

		if (NULL != pLinkIdBuff)
		{
			for (ii = 0U; ii < chLinkNum; ii++)
			{
				wRtn = GetLinkSpecialEaAttr(pLinkIdBuff[ii]);

				if (0U != wRtn)
				{
					break;
				}
				else
				{
					;
				}
			}
		}
		else
		{
			;
		}
	}
	else
	{
		;
	}

	return wRtn;
}

