#include "AxisAssertManageAPI.h"
#include "AxisAssertManage.h"
#include "AxisAssertDataPrepare.h"
#include "EnvelopeManageAPI.h"
#include "dsuEmapDefine.h"
#include "DeviceDataManage.h"

/*================================静态函数声明区==============================*/
static UINT8 aam_CreatTempUKTEnvelope(UINT16 acID, UINT8 Dir ,EnvelopeStruct *pEnvelope);     /* 创建一个临时的UKT包络 */
static UINT8 aam_SearchNearestTrainInNextAC(UINT16 baseACID, UINT8 Dir, UINT8 envelpeCnt, const UINT16* envelopeIds);     /* 获取相邻计轴上的列车接近类型 */
static UINT8 aam_AxisErrorJudge(UINT16 acID,UINT16 acIndex);     /* 计轴故障判断 */
static void aam_ProessPassTrainFlag(UINT16 acid, UINT16 acIndex,UINT16 trainID,UINT16 supicTrainid);     /* 处理好车通过标志位*/
static void aam_InitEndLinePassFlag(void);     /* 尽头线ARB特殊处理*/

/**
 * @brief 创建一个临时的UKT包络
 * @param[in] UINT16 acID 计轴ID
 *            UINT8 Dir 包络方向
 * @param[out] EnvelopeStruct* pEnvelope 创建的包络
 * @return 1 创建成功
 *         0 创建失败
 */
static UINT8 aam_CreatTempUKTEnvelope(UINT16 acID, UINT8 Dir, EnvelopeStruct *pEnvelope)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == pEnvelope, ret, 0x80000000u);
	ASSERT_RET_VALUE((EMAP_SAME_DIR != Dir) && (EMAP_CONVER_DIR != Dir), ret, 0x40000000u);

	ret = elm_CreatTempUKTEnvelope(acID, Dir, pEnvelope);

	return ret;
}


/**
 * @brief 静态函数：获取相邻计轴上的列车接近类型
 * @param[in] 
 * @param[out]
 * @return 
 * @note 注：此函数不支持baseACID上存在包络，如果存在可能无法查询成功
 */
static UINT8 aam_SearchNearestTrainInNextAC(UINT16 baseACID, UINT8 Dir, UINT8 envelpeCnt, const UINT16* envelopeIds)
{
	/*- 局部变量定义 */
	UINT8 ret = AAM_BAD_NEAR;
	UINT8 funRtn = CI_ERROR;
	EnvelopeStruct tempEnvelope = {0u};
	UINT16 preEnvelope = 0u;
	UINT16 backEnvelope = 0u;
	UINT32 errorCode = 0u;
	const EnvelopeStruct* pTempEnvelope = NULL;
	ELM_AxisLocStruct tmpAcLoc = { 0u };
	UINT8 cSleepState = 0U; /*包络关联列车休眠状态*/
	UINT8 ii = 0U;
	UINT8 chNoSleepCheck = 0U;

	/*- 入口参数校验 */
	ASSERT_RET_VALUE(NULL == envelopeIds,ret,0x80000000u);
	ASSERT_RET_VALUE(SECTION_REL_ENVELOPE_SUM_MAX == envelpeCnt,ret,0x40000000u);
	ASSERT_RET_VALUE((EMAP_SAME_DIR != Dir) && ((UINT8)EMAP_CONVER_DIR != Dir),ret,0x20000000u);

	/** 在基准包络上创建*/
	funRtn = aam_CreatTempUKTEnvelope(baseACID,Dir,&tempEnvelope);

	/** 判断是否创建成功 */
	if (CI_SUCCESS == funRtn)
	{
		/** 查询包络前方包络 */
		funRtn = elm_GetNearestBaseOnEnvelope(&tempEnvelope,envelopeIds,envelpeCnt,&preEnvelope,&backEnvelope);

		if (CI_ERROR == funRtn)
		{
			ret = AAM_BAD_NEAR;
			ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x0800000u);
			AAM_LOG_LOC(AAM_LOG_ERROR,"errno:0x%08x info:Search NearestTrain InNextAC error.",errorCode);
		}
		else
		{
			/** 因为创建包络的时候修改了方向，故只需要关系前方包络*/
			if (0u == preEnvelope)
			{
				/** 说明无车*/
				ret = AAM_NO_TRAIN_NEAR;
			}
			else
			{
				/** 通过包络ID查询包络信息 */
				pTempEnvelope = elm_GetEnvelopeInfoByID(preEnvelope);
				funRtn = aam_PrepareACLoc(baseACID, Dir, &tmpAcLoc);
				if ((NULL != pTempEnvelope) && (CI_SUCCESS == funRtn))
				{
					funRtn = aam_PrepareTwoPointsSameDir(tmpAcLoc.endPos, pTempEnvelope->startPos);
				}
				else
				{
					; /* do nothing */
				}

				if ((NULL == pTempEnvelope) || (CI_ERROR == funRtn))
				{
					/** 查询包络数据错误，导向安全 */
					ret = AAM_BAD_NEAR;
					ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x10000000u);
					AAM_LOG_LOC(AAM_LOG_ERROR,"errno:0x%08x info:Search NearestTrain ELM%d,ELM info error.",errorCode,preEnvelope)
				}
				else 
				{
					chNoSleepCheck = CI_SUCCESS;
					for (ii = 0U; ii < pTempEnvelope->trianCnt; ii++)
					{
						cSleepState = GetTrainSleepState(pTempEnvelope->trainID[ii]);
						if (TRAIN_SLEEP_YES == cSleepState)
						{
							chNoSleepCheck = CI_ERROR;
							break;
						}
					}
					
					if (CI_ERROR == chNoSleepCheck)
					{
						/*相邻计轴存在休眠车*/
						ret = AAM_SLEEP_OCC;
					}
					else if (((TYPE_CT_ENVELOPE == pTempEnvelope->envelopeType) || (TYPE_UCT_ENVELOPE == pTempEnvelope->envelopeType)) &&
						(FLAG_SET == funRtn) && (0u == pTempEnvelope->tailTrainID))
					{
						/** 好车远离 */
						ret = AAM_GOOD_FAR_AWAY;

					}
					else if (((TYPE_CT_ENVELOPE == pTempEnvelope->envelopeType) || (TYPE_UCT_ENVELOPE == pTempEnvelope->envelopeType)) &&
						(FLAG_UNSET == funRtn) && (0u == pTempEnvelope->headTrainID))
					{
						/** 好车接近 */
						ret = AAM_GOOD_NEAR;
					}
					else
					{
						/** 坏车接近 */
						ret = AAM_BAD_NEAR;
					}
				}
				
			}
		}
	}
	else
	{
		/** 查询包络数据错误，导向安全 */
		ret = AAM_BAD_NEAR;
		ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x10000000u)
		AAM_LOG_LOC(AAM_LOG_ERROR,"errno:0x%08x info:Create AC%d of Temp UKT Envelope  error.",errorCode,baseACID)
	}

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


/**
 * @brief 查询计轴接近车类型
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 */
UINT8 aam_SearchNearbyTrainType(UINT16 baseACID, UINT8 Dir, UINT8 acCnt, UINT16 acID[AC_MAXCNT_IN_SWITCH])
{
	/*- 局部变量定义 */
	UINT8 ret = AAM_BAD_NEAR;
	UINT8 funRtn = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 cycle = 0u;
	UINT8 cycleELM = 0u;
	UINT8 cycleELMAC = 0u;
	UINT8 acStatus = ELM_AC_OCC;
	UINT16 tmpPhyid = 0u;
	UINT8 phyRelACCnt = 0u;
	const UINT16* phyRelACIDs = NULL;
	const EnvelopeStruct* pTempEnvelope = NULL;
	UINT8 acRelEnvelopeCnt = 0u;
	UINT16 envelopeIds[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};

	/** 查询基准计轴所属物理区段 */
	tmpPhyid = aam_PrepareACBelongPhyid(baseACID);
	phyRelACIDs = aam_PreparePhyRelACIds(tmpPhyid,&phyRelACCnt);

	/** 入口参数校验 */
	ASSERT_RET_VALUE(acCnt > AC_MAXCNT_IN_SWITCH,ret,0x80000000u);
	ASSERT_RET_VALUE(NULL == acID,ret,0x40000000u);
	ASSERT_RET_VALUE((EMAP_SAME_DIR != Dir) && ((UINT8)EMAP_CONVER_DIR != Dir),ret,0x20000000u);
	ASSERT_RET_VALUE((NULL == phyRelACIDs) || (0u == phyRelACCnt),ret,0x10000000u);



	if(0u == acCnt)
	{
		/** 说明为尽头线，设置为无车接近 */
	    ret = AAM_NO_TRAIN_NEAR;
	}
	else 
	{
		for (cycle = 0u;cycle < acCnt;cycle++)
		{
			/** 获取计轴状态 */
			acStatus = aam_PrepareACStatus(acID[cycle]);

			if (ELM_AC_FREE == acStatus)
			{
				/** 空闲则设置无车接近*/
				ret = AAM_NO_TRAIN_NEAR;
			}
			else
			{
				/** 获取计轴关联的包络数量 */
				acRelEnvelopeCnt = elm_GetEnvelopeIDsInAC(acID[cycle],envelopeIds);

				/** 根据列车包络数量进行处理 */
				if (0u == acRelEnvelopeCnt)
				{
					/** 说明无车接近且相邻计轴也需要判UT冗余 */
					ret = AAM_NO_TRAIN_NEAR;
				}
				else if (acRelEnvelopeCnt < SECTION_REL_ENVELOPE_SUM_MAX)
				{
					/** 判断所有的包络，如果有包络包含了基准计轴所属物理区段，则延迟处理，等车出清物理区段后再处理，避免包络前后关系查询失败导致错误 */
					for(cycleELM = 0u;cycleELM < acRelEnvelopeCnt;cycleELM++)
					{
						pTempEnvelope = elm_GetEnvelopeInfoByID(envelopeIds[cycleELM]);

						if ((NULL == pTempEnvelope) || 
							((TYPE_CT_ENVELOPE != pTempEnvelope->envelopeType) && (TYPE_UCT_ENVELOPE != pTempEnvelope->envelopeType)))
						{
							/** 查询错误*/
							ret = AAM_BAD_NEAR;
							break;
						}
						else
						{
							for (cycleELMAC = 0u; cycleELMAC < pTempEnvelope->ACCnt;cycleELMAC++)
							{
								funRtn = aam_PrepareInUINT16Array(pTempEnvelope->ACID[cycleELMAC],phyRelACIDs,phyRelACCnt);

								/** 如果包络计轴在基准计轴所属物理区段，返回好车占用，等车处理完后再处理*/
								ASSERT_BREAK(CI_SUCCESS == funRtn,errorCode,0x00000000u);
							}
							
							if (cycleELMAC == pTempEnvelope->ACCnt)
							{
								/** 包络不在基准计轴所属物理区段，继续遍历*/
							}
							else
							{
								/** 如果包络计轴在基准计轴所属物理区段，返回好车占用 */
								ret = AAM_GOOD_OCC;
								break;
							}
						}
					}

					if (cycleELM == acRelEnvelopeCnt)
					{
						/** 无包络计轴再基准计轴所属物理区段内，查询包络最近的一辆车类型 */
						ret = aam_SearchNearestTrainInNextAC(baseACID,Dir,acRelEnvelopeCnt,envelopeIds);
					}
					else
					{
						/* 包络计轴在基准计轴所属物理区段 */
					}
				}
				else
				{
					/** 查询错误，设置坏车通过 */
					ret = AAM_BAD_NEAR;
				}
			}

			/**说明计轴上有坏车，则设置为坏车接近，跳出循环，无需继续遍历其他计轴 */
			ASSERT_BREAK(AAM_BAD_NEAR == ret,errorCode,0x10000000u);	
		}
	}

	return ret;
}


/**
 * @brief 静态函数：计轴故障判断
 * @param[in] UINT16 acID,  计轴ID
 * @param[in]  UINT16 acIndex， 计轴ID内部索引
 * @param[out] 无
 * @return CI_ERROR 处理失败
           CI_SUCCESS 处理成功
 * @note 
 */
static UINT8 aam_AxisErrorJudge(UINT16 acID,UINT16 acIndex)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = CI_ERROR;
	UINT8 chNearbyCheck = CI_ERROR;
	UINT8 acSameCnt = 0U;
	UINT16 acSameID[AC_MAXCNT_IN_SWITCH] = { 0U };
	UINT8 acConvertCnt = 0U;
	UINT16 acConvertID[AC_MAXCNT_IN_SWITCH] = { 0U };
	UINT32 errorCode = 0U;
	UINT8 sameTrainType = AAM_BAD_NEAR;
	UINT8 convertTrainType = AAM_BAD_NEAR;
	UINT8 tmpRedunTime = 0U;
	UINT8 tmppassTrainType = 0U;
	UINT8 tmpACStatus = AAM_STATUS_OCC;
	UINT8 maxRedunTimes = 0u;
	UINT8 chSwitch = 0U;
	UINT32 dwArbCheckDistance = 0U; /*RC16.0： 系统配置ARB区段向外检查距离*/
	UINT8 chRedunArbFlag = REDUN_OVER_ARB_NO; /*判断冗余计时结束后可否ARB标志*/
	UINT8 cAxisCommBadArbFlag = AAM_COMM_BAD_ARB_NO;
	UINT8 chPhyTrainCheck = CI_SUCCESS;
	UINT8 cAcCbtcAttr = 0U;  /*计轴区段CBTC区域属性*/
	UINT8 cAcRelEnvelopeCnt = 0U;  /*计轴区段包络数量*/
	UINT32 dwOccupyStartCyc = 0U;/*计轴占用起始周期号*/
	UINT32 dwCurCyc = 0U;/*当前周期号*/
	UINT8 DirectionPointSameSide = DIRECTIONPOINT_FLAG_INVALID;
	UINT8 DirectionPointConvertSide = DIRECTIONPOINT_FLAG_INVALID;
	EnvelopeStruct strEnvelopeInfo[SECTION_REL_ENVELOPE_SUM_MAX] = { 0U };

	chSwitch = aam_PrepareArbSwitch();
	dwCurCyc = Get2oo2CurCycleNum(); 
	if (CI_SUCCESS == chSwitch)
	{
		;
	}
	else
	{
		funRtn=aam_ClearPassTrainFlag(acIndex);
	}
	dwArbCheckDistance = (UINT32)(GetArbCheckAxisLen()*100U);
	if (0U == dwArbCheckDistance)
	{
		debug_infor_printf((const)"aam_AxisErrorJudge  acID: %d Fail:  ArbCheckDistance =%d .\n", acID, dwArbCheckDistance);
	}
	else
	{
		/** 查询前方计轴*/
		acSameCnt = aam_PrepareAdjacentAC(acID, EMAP_SAME_DIR, acSameID, &DirectionPointSameSide);

		/** 查询后方计轴 */
		acConvertCnt = aam_PrepareAdjacentAC(acID, EMAP_CONVER_DIR, acConvertID,&DirectionPointConvertSide);

		/** 获取区段由占用变空闲持续时间 */
		maxRedunTimes = aam_PrepareRedunTimes();
		if ((UINT8_MAX == acSameCnt) || (UINT8_MAX == acConvertCnt))
		{
			/** 不可能查失败，除非数据错误 */
			/** 清除之前的好车通过标志位*/
			funRtn &= aam_ClearPassTrainFlag(acIndex);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x80000000u);

			/** 清除冗余计时位 */
			funRtn = aam_ClearRedunTime(acIndex);
			ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x40000000u);
			ASSER_DEBUG(0u != errorCode, AAM_LOG(AAM_LOG_FATAL, "info:Clear AC%d RedunTime becasue pre/back error.\n", acID));
		}
		else
		{
			/*仅在待判断计轴当周期由空闲变占用时检查*/
			dwOccupyStartCyc = GetAxisSecOccCyc(acID);
			if (dwCurCyc == dwOccupyStartCyc)
			{
				/** 检查附近区段状态*/
				chNearbyCheck = aam_CheckNearbyTrainType(acID);
			}
			else
			{
				chNearbyCheck = CI_SUCCESS;
			}

			/** 处理前方计轴车辆接近*/
			sameTrainType = aam_CheckNearbyTrainEnvelopeType(acID, EMAP_SAME_DIR, acSameCnt, acSameID, DirectionPointSameSide);

			/** 处理后方计轴车辆接近 */
			convertTrainType = aam_CheckNearbyTrainEnvelopeType(acID, EMAP_CONVER_DIR, acConvertCnt, acConvertID, DirectionPointConvertSide);

			/*检查所属物理区段有无故障车*/
			chPhyTrainCheck = aam_CheckPhyTrain(acID);
			cAcCbtcAttr = GetAxisSecCbtcProperty(acID);  /*获取计轴区段CBTC区域属性*/

			if ((CI_ERROR == chPhyTrainCheck) || (AXIS_SEC_CBTC_PROPERTY_YES != cAcCbtcAttr))
			{
				/** 计轴区段有故障车或非CBTC区域，清除之前的冗余计时位，设置占用 */
				funRtn = aam_ClearPassTrainFlag(acIndex);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);

				funRtn = aam_ClearRedunTime(acIndex);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

				aam_SetAxisStatus(acIndex, AAM_STATUS_OCC);
				AAM_LOG(AAM_LOG_FATAL, "info:AC%d  set UT,Physec has UKT\n ", acID);
			}
			else if ((AAM_SLEEP_OCC == sameTrainType) || (AAM_SLEEP_OCC == convertTrainType))
			{
				/** 清除好车通过标志，UT冗余 */
				funRtn = aam_ClearPassTrainFlag(acIndex);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);
			}
			else
			{
				; /*继续处理*/
			}
			
			/*有 坏车接近 或左右相邻计轴均无车接近 立即清除冗余计时*/
			if ((AAM_BAD_NEAR == sameTrainType) || (AAM_BAD_NEAR == convertTrainType))
			{
				/** 清除之前的冗余计时位 */
				funRtn = aam_ClearPassTrainFlag(acIndex);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);

				funRtn = aam_ClearRedunTime(acIndex);
				ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

				aam_SetAxisStatus(acIndex, AAM_STATUS_OCC);
				AAM_LOG(AAM_LOG_FATAL, "info:AC%d not match ARB  condition, NearByTrainCheck:%d.\n", acID, chNearbyCheck);
			}
			else if (CI_ERROR == chNearbyCheck)
			{
				/** 范围内坏车失败 UT冗余*/
				aam_AddRedunTime(acIndex, maxRedunTimes);

				/*置标志位*/
				aam_SetAxisRedunCanArbFlag(acIndex, REDUN_OVER_ARB_NO);
			}
			else
			{
				/** 冗余计时位加1*/
				aam_AddRedunTime(acIndex, maxRedunTimes);
			}

			/** 计轴故障的判断 */
			tmpRedunTime = aam_GetRedunTime(acIndex);
			tmppassTrainType = aam_GetPassTrainFlag(acIndex);
			tmpACStatus = aam_GetAxisStatus(acIndex);
			cAxisCommBadArbFlag = aam_GetAxisCommBadArbFlag(acIndex);  /*获取计轴区段计轴系统通信中断ARB标志*/

			/** ARB判断 */
			if ((AAM_CT_PASS == tmppassTrainType) || (AAM_COMM_BAD_ARB_YES == cAxisCommBadArbFlag))
			{
				if (AAM_STATUS_ARB == tmpACStatus)
				{
					/** 计轴已经ARB 不检查防护范围*/
					cAcRelEnvelopeCnt = elm_GetEnvelopeInAC(acID, strEnvelopeInfo);
					if ((0U < cAcRelEnvelopeCnt) && (SECTION_REL_ENVELOPE_SUM_MAX > cAcRelEnvelopeCnt))
					{
						/*ARB区段存在包络，不进行ARB连续占用判断*/
					}
					else
					{
						/*ARB计轴区段同向相邻计轴区段连续占用*/
						funRtn = aam_ArbContinuousOccCheck(acID, acSameCnt, acSameID);

						/*ARB计轴区段反向相邻计轴区段连续占用*/
						funRtn &= aam_ArbContinuousOccCheck(acID, acConvertCnt, acConvertID);

						if (CI_SUCCESS != funRtn)
						{
							/** 清除本计轴区段之前的冗余计时位 */
							funRtn = aam_ClearPassTrainFlag(acIndex);
							ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00800000U);

							funRtn = aam_ClearRedunTime(acIndex);
							ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x00400000U);

							aam_SetAxisStatus(acIndex, AAM_STATUS_OCC);
							AAM_LOG(AAM_LOG_FATAL, "info:AC%d  Keep ARB Fail Because Of Near Sec Continuous Occ\n", acID);
						}
						else
						{
							/*相邻区段占用检查通过，维持ARB状态*/
						}
					}
				}
				else if (tmpRedunTime >= maxRedunTimes)
				{
					/** 冗余时间到，检查相邻无好车包络 设置计轴状态为ARB*/
					if ((AAM_GOOD_OCC == sameTrainType) || (AAM_GOOD_OCC == convertTrainType))
					{
						/** 需要继续冗余计时，避免ARB闪烁*/
						funRtn = aam_ClearPassTrainFlag(acIndex);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x08000000u);

						aam_AddRedunTime(acIndex, maxRedunTimes);
						/** 岔区定位有包络车尾占用， 道岔四开，不能设置道岔反位为ARB，等车出清后再判断*/
						AAM_LOG(AAM_LOG_FATAL, "info:AC%d not ARB because of CT oCC,preTrainType:%d.tailTrainType:%d.\n", acID, sameTrainType, convertTrainType);
					}
					else
					{
						/*如果存在过ARB防护检查失败 则设置为UT*/
						chRedunArbFlag = aam_GetAxisRedunCanArbFlag(acIndex);
						
						if (REDUN_OVER_ARB_YES== chRedunArbFlag)
						{
							aam_SetAxisStatus(acIndex, AAM_STATUS_ARB);
							AAM_LOG(AAM_LOG_FATAL, "info:ac%d ARB Redun:ARB.\n", acID);
						}
						else
						{
							/*设置为UT 清除冗余计时*/
							funRtn = aam_ClearPassTrainFlag(acIndex);
							ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);

							funRtn = aam_ClearRedunTime(acIndex);
							ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);

							aam_SetAxisStatus(acIndex, AAM_STATUS_OCC);
							AAM_LOG(AAM_LOG_FATAL, "info:ac%d UT Redun:UT.\n", acID);
						}
					}
				}
				else
				{
					/** ARB 冗余*/
					AAM_LOG(AAM_LOG_FATAL, "info:ac%d ARB Redun:%d.\n", acID, tmpRedunTime);
				}
			}
			else
			{
				if (AAM_STATUS_OCC == tmpACStatus)
				{
					/** 计轴已设置为UT占用，不处理*/
				}
				else if (tmpRedunTime >= maxRedunTimes)
				{
					/** 冗余时间到，设置计轴状态非为ARB*/
					if ((AAM_GOOD_OCC == sameTrainType) ||(AAM_GOOD_OCC == convertTrainType) )
					{
						/** 需要继续冗余计时，避免UT闪烁*/
						funRtn = aam_ClearPassTrainFlag(acIndex);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x04000000u);

						aam_AddRedunTime(acIndex, maxRedunTimes);
						/** 岔区定位有包络车尾占用， 道岔四开，不能设置道岔反位为UT，等车出清后再判断*/
						AAM_LOG(AAM_LOG_FATAL, "info:AC%d not UT because of CT oCC,preTrainType:%d.tailTrainType:%d.\n", acID, sameTrainType, convertTrainType);
					}
					else
					{
						aam_SetAxisStatus(acIndex, AAM_STATUS_OCC);
						AAM_LOG(AAM_LOG_FATAL, "info:ac%d UT Redun:UT.\n", acID);
					}
				}
				else
				{
					/** UT 冗余*/
					AAM_LOG(AAM_LOG_FATAL, "info:ac%d UT Redun:%d.\n", acID, tmpRedunTime);
				}
			}
		}

		/** 设置函数返回值 */
		ASSERT_SETRET(0u == errorCode, ret, CI_SUCCESS, CI_ERROR);
		ASSER_DEBUG(0u != errorCode, AAM_LOG_LOC(AAM_LOG_ERROR, "errno:0x%08x info:Assert AC%d index%d error.", errorCode, acID, acIndex));
	}
	return ret;
}


/**
 * @brief 静态函数：处理好车通过标志位
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 */
static void aam_ProessPassTrainFlag(UINT16 acid, UINT16 acIndex,UINT16 trainID,UINT16 supicTrainid)
{
	/*-局部变量定义 */
	UINT8 headEnterFlag = CI_ERROR;
	UINT8 tailEnterFLag = CI_ERROR;
	UINT32 errorCode = 0u;
	UINT8 isLinkingAxle = CI_ERROR;
	UINT8 isUseNvram = CI_ERROR;

	/** 第一步：是否头进入过 */
	headEnterFlag = aam_GetHeadEnterFlag(acIndex,trainID);

	/** 第二步：是否尾进入过 */
	tailEnterFLag = aam_GetTailEnterFlag(acIndex,trainID);
	
	/** 判断计轴是否为联锁线 */
	isLinkingAxle = aam_PrepareACIsLinkingAxle(acid);

	/*判断列车未使用Nvram位置*/
	isUseNvram = GetTrainNvramPosFlag(trainID);

	/** 第三步：设置好车通过 */
	if ((CI_SUCCESS == headEnterFlag) && (CI_SUCCESS == tailEnterFLag)
		&& (0u == supicTrainid) && (CI_ERROR == isLinkingAxle)&&(TRAIN_NVRAM_POS_FLAG_NO == isUseNvram))
	{
		aam_SetPassTrainFlag(acIndex,trainID);
		AAM_LOG(AAM_LOG_FATAL,"info:Add acIndex:%d CT train%d pass flag.\n",acIndex,trainID);
	}
	else
	{
		/** 无法设置好车通过 */
		errorCode = errorCode + 0x80000000u;
		AAM_LOG_LOC(AAM_LOG_ERROR,"errno:0x%08x info:Add acIndex:%d CT train%d pass flag error,%d-%d-%d-%d.\n", \
			errorCode,acIndex,trainID,headEnterFlag,tailEnterFLag,supicTrainid,isLinkingAxle);
	}

	/** 第四步：清除计轴上该车信息 */
	aam_ClearHeadEnterIdForTrain(acIndex,trainID);
	aam_ClearTailEnterIdForTrain(acIndex,trainID);
}


/**
 * @brief 静态函数：尽头线ARB特殊处理
 * @param[in] 无 
 * @param[out] 无
 * @return 无
 * @note 
 */
static void aam_InitEndLinePassFlag(void)
{
	/*- 局部变量定义 */
	UINT8 switchFlag = CI_ERROR;
	UINT8 arbSwitch = CI_ERROR;
	UINT8 InitEndlineFlag = AAM_END_LINE_INIT;
	UINT16 acCnt = 0u;
	UINT16 cycle = 0u;
	const UINT16* pACIdBuff = NULL;
	UINT8 acStatus = ELM_AC_OCC;
	UINT8 OCId = 0u;
	UINT8 funRtn = ELM_BELONG_OWNER;
	UINT16 PrePhyid = 0u;
	UINT16 BackPhyid = 0u;
	UINT8 isLinkingAxle = CI_SUCCESS;
	UINT16 curPhyid = 0u;
	UINT8 NextPhyStatus = SECTION_OCCUPY_YES;
	UINT8 curPhyStatus = SECTION_OCCUPY_YES;
	UINT16 acIndex = 0u;
	UINT8 chObjNum = 0u;
	const UINT8 * pObjIdBuff = NULL;
	UINT8 chComStatus = AAM_COM_STATUS_ERROR;
	UINT8 chObjIndex = 0u;
	UINT32 errorCode = 0u;
	UINT8 chAsSwitch = 0u;

	/** 获取尽头线ARB标志 */
	switchFlag = aam_PrepareInitCTPassFlagSwitch();
	arbSwitch = aam_PrepareArbSwitch();

	if ((CI_ERROR == switchFlag) || (CI_ERROR == arbSwitch))
	{
		/** 功能开关未开，无需处理 */
	}
	else
	{
		/** 获取尽头线ARB特殊处理标志 */
		InitEndlineFlag = aam_GetInitEndlineFlag();
		chAsSwitch = aam_PrepareAsSwitch();
		if (CI_ERROR == chAsSwitch)
		{
			/* 计轴系统功能关闭，判断与所有OC全部通信，初始化尽头线 */
			chObjNum = aam_PrepareComOcId(&pObjIdBuff);
		}
		else
		{
			/* 计轴系统功能打开，判断与所有计轴系统通信，初始化尽头线 */
			chObjNum = aam_PrepareComAsId(&pObjIdBuff);
		}
		if ((0u == chObjNum) || (NULL == pObjIdBuff))
		{
			/** 不可能分支*/
			errorCode = errorCode + 0x10000000u;
		}
		else
		{
			for (chObjIndex = 0u; chObjIndex < chObjNum; chObjIndex++)
			{
				if (CI_ERROR == chAsSwitch)
				{
					chComStatus = aam_PrepareOcCommStatus(pObjIdBuff[chObjIndex]);
				}
				else
				{
					chComStatus = aam_PrepareAsCommStatus(pObjIdBuff[chObjIndex]);
				}
				ASSERT_BREAK(AAM_COM_STATUS_ERROR == chComStatus, errorCode, 0x20000000u);
			}
		}

		if ((AAM_END_LINE_UNINIT == InitEndlineFlag) && (0u == errorCode))
		{
			/** 获取计轴区段信息 */
			acCnt = aam_PrepareACBuffIndexs(&pACIdBuff);

			if (NULL == pACIdBuff)
			{
				/** 不可能分支*/                 
			}
			else
			{
				/** 判断是否进入尽头线ARB设置好车通过时机，即当控区范围内计轴区段非全占用时*/
				for (cycle = 0u; cycle < acCnt;cycle++)
				{
					/** 判断计轴区段是否属于本OC */
					funRtn = aam_PrepareACIsSelf(pACIdBuff[cycle],&OCId);

					/** 获取计轴状态 */
					acStatus = aam_PrepareACStatus(pACIdBuff[cycle]);

					if ((ELM_BELONG_OWNER == funRtn) && (ELM_AC_FREE == acStatus))
					{
						/** 找到空闲计轴，说明肯定采集到了区段占用*/
						break;
					}
					else
					{
						/** 继续遍历*/
					}
				}

				if (cycle == acCnt)
				{
					/** 说明计轴区段全占用，未到设置时机*/
				}
				else
				{

					/** 设置尽头线ARB特殊处理标志  */
					aam_SetInitEndlineFlag(AAM_END_LINE_INIT);

					for (cycle = 0u; cycle < acCnt;cycle++)
					{
						/** 判断计轴区段是否属于本OC */
						funRtn = aam_PrepareACIsSelf(pACIdBuff[cycle],&OCId);

						if (ELM_BELONG_OWNER == funRtn)
						{
							/** 查询计轴区段的相邻物理区段*/
							funRtn = aam_PreparePreAndBackPhySecOFAC(pACIdBuff[cycle],&PrePhyid,&BackPhyid);

							/** 判读计轴是否为尽头线 */
							if ((CI_SUCCESS == funRtn) && ((UINT16_MAX == PrePhyid) || (UINT16_MAX == BackPhyid)))
							{
								/** 判断计轴是否为联锁线 */
								isLinkingAxle = aam_PrepareACIsLinkingAxle(pACIdBuff[cycle]);

								if (CI_SUCCESS == isLinkingAxle)
								{
									/** 计轴为联锁线，不处理*/
								}
								else
								{
									/** 获取本计轴及相邻物理区段的状态*/
									curPhyid = aam_PrepareACBelongPhyid(pACIdBuff[cycle]);
									curPhyStatus = aam_PreparePhyOccStatus(curPhyid);
									NextPhyStatus = (UINT16_MAX == PrePhyid) ? aam_PreparePhyOccStatus(BackPhyid) : aam_PreparePhyOccStatus(PrePhyid);

									if ((SECTION_OCCUPY_NO == curPhyStatus) && (SECTION_OCCUPY_NO == NextPhyStatus))
									{
										/** 获取计轴数组索引 */
										acIndex = aam_PrepareACIndex(pACIdBuff[cycle]);
										aam_SetPassTrainFlag(acIndex,0u);
										AAM_LOG(AAM_LOG_FATAL,"info:Set AC%d CI pass Flag.\n",pACIdBuff[cycle]);
									}
									else
									{
										/** 不满足条件*/
										AAM_LOG(AAM_LOG_FATAL,"info:Can't Set AC%d CI pass Flag becasue %d-%d,%d-%d-%d.\n",pACIdBuff[cycle],curPhyid,curPhyStatus,PrePhyid,BackPhyid,NextPhyStatus);
									}									
								}
							}
							else
							{
								/** 非尽头线，不处理*/
							}
						}
						else
						{
							/** 非本OC计轴，不处理 */
						}
					}
				}				
			}
		}
		else
		{
			/** 尽头线ARB特殊处理标志已置位，或OC并未全部通信 */
		}
	}
}



/**
 * @brief 计轴故障诊断模块初始化
 * @return CI_ERROR 初始化成功
           CI_SUCCESS 初始化失败
 * @note 
 */
UINT8 aam_Init(void)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = CI_ERROR;
	UINT32 errorCode = 0u;

	/** 初始化计轴诊断信息*/
	funRtn = aam_InitAxisAssert();
	ASSER_ERROR(CI_ERROR == funRtn,errorCode,0x80000000u);

	/** 设置尽头线ARB特殊处理标志  */
	aam_SetInitEndlineFlag(AAM_END_LINE_UNINIT);

	/** 设置返回值 */
	ASSER_DEBUG(0u != errorCode,AAM_LOG_LOC(AAM_LOG_ERROR,"errno:0x%08x info:Axis Assert Init error.",errorCode));
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);
	return ret;
}


/**
 * @brief 计轴故障诊断模块处理主函数
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 */
void aam_MainProcess(void)
{
	/*- 局部变量定义*/
	UINT8 funRtn = ELM_BELONG_OWNER;
	UINT8 acStatus = ELM_AC_OCC;
	UINT16 acCnt = 0u;
	UINT16 cycle = 0u;
	UINT8 OCId = 0u;
	UINT16 acIndex = 0u;
	const UINT16* pACIdBuff = NULL;
	UINT32 errorCode = 0u;
	UINT8 acRelEnvelopeCnt = 0u;
	EnvelopeStruct envelopeInfo[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	UINT8 chPreAcStatus = ELM_AC_OCC;
	UINT8 ii = 0U;
	UINT8 chCTcheck = CI_ERROR;

	/** 获取计轴区段信息 */
	acCnt = aam_PrepareACBuffIndexs(&pACIdBuff);

	if (NULL == pACIdBuff)
	{
		ASSER_ERROR(NULL == pACIdBuff,errorCode,0x80000000u);
	}
	else
	{
		/** 尽头线ARB特殊处理*/
		aam_InitEndLinePassFlag();

		/*计轴子系统通信中断ARB特殊处理功能在RC20.0首版二回先注释掉（恢复时间待定）——By LQ 2025.05.07*/
#if 0
		/*计轴子系统通信中断ARB特殊处理*/
		aam_AxisCommBadArbPro();
#endif
		for (cycle = 0u; cycle < acCnt; cycle++)
		{
			/** 判断计轴区段是否属于本OC */
			funRtn = aam_PrepareACIsSelf(pACIdBuff[cycle], &OCId);

			if (ELM_BELONG_OWNER == funRtn)
			{
				/** 获取计轴状态 */
				acStatus = aam_PrepareACStatus(pACIdBuff[cycle]);

				/** 获取计轴关联的包络数量 */
				acRelEnvelopeCnt = elm_GetEnvelopeInAC(pACIdBuff[cycle], envelopeInfo);

				/** 获取计轴数组索引 */
				acIndex = aam_PrepareACIndex(pACIdBuff[cycle]);
				ASSERT_BREAK(UINT16_MAX == acIndex, errorCode, 0x40000000u);

				if ((ELM_AC_OCC == acStatus) && (0u != acRelEnvelopeCnt))
				{
					chPreAcStatus = aam_GetAxisStatus(acIndex);
					chCTcheck = CI_SUCCESS;
					for (ii = 0U; ii < acRelEnvelopeCnt; ii++)
					{
						if (((TYPE_UCT_ENVELOPE == envelopeInfo[ii].envelopeType) || (TYPE_UKT_ENVELOPE == envelopeInfo[ii].envelopeType))
							||(0U != envelopeInfo[ii].tailTrainID) || (0U != envelopeInfo[ii].headTrainID))
						{
							/*包络存在隐藏车或UCT 或前后任意端存在可疑*/
							chCTcheck = CI_ERROR;
							break;
						}
					}
					if ((AAM_STATUS_ARB != chPreAcStatus) || (CI_ERROR == chCTcheck))
					{
						/* 说明非ARB区段有车占用，或占用包络非CT 或CT包络可疑 清除之前的冗余计时位 */
						funRtn = aam_ClearRedunTime(acIndex);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x20000000u);
						aam_SetAxisStatus(acIndex, AAM_STATUS_OCC);
					}
					else
					{
						/*ARB区段 在无前后端可疑的CT列车驶入该计轴区段，计轴区段维持ARB状态*/
						funRtn = aam_AxisErrorJudge(pACIdBuff[cycle], acIndex);
						ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);
					}
				}
				else if ((ELM_AC_OCC == acStatus) && (0u == acRelEnvelopeCnt))
				{
					/** 说明占用无车，进行ARB判断*/
					funRtn = aam_AxisErrorJudge(pACIdBuff[cycle], acIndex);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);
				}
				else
				{
					/** 清除之前的冗余计时位，设置计轴空闲 */
					funRtn = aam_ClearRedunTime(acIndex);
					ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x08000000u);
					aam_SetAxisStatus(acIndex, AAM_STATUS_FREE_OR_REDUN);
					aam_SetAxisCommBadArbFlag(acIndex, AAM_COMM_BAD_ARB_NO);  /*计轴空闲，重置计轴通信中断ARB标志无效*/
				}
			}
			else
			{
				/** 不属于本OC，不处理 */
			}

			/** 判断是否满足跳出条件 */
			ASSERT_BREAK(0u != errorCode, errorCode, 0x00000000u);
		}
	}

	/** 处理错误 */
	if (0u != errorCode)
	{
		/** 处理错误，直接重新初始化*/
		funRtn = aam_Init();

		if (CI_ERROR == funRtn)
		{
			/** 宕机处理 */
			SetPlatOverFlag();
			ASSER_ERROR(NULL == pACIdBuff,errorCode,0x80000000u);
			AAM_LOG_LOC(AAM_LOG_ERROR,"errno:0x%08x info:Axis Assert Process error.",errorCode);
		}
		else
		{
			/** 处理正确，重新初始化后继续执行 */
		}

		AAM_LOG_LOC(AAM_LOG_ERROR,"errno:0x%08x info:Axis Assert Process error.",errorCode);
	}
	else
	{
		/** 处理无问题*/
	}
}

/**
 * @brief 对外接口：设置计轴区段包络进入类型
 * @param[in] UINT8 flag 包络进入类型
 * @param[in] UINT16 envelopeId 包络ID
 * @return 无
 * @note 无
 */
void aam_SetEnvelopeEnterFlag(UINT8 flag,UINT16 supicTrainid, UINT16 acID,UINT16 trainId)
{
	/*- 获取通过计轴id获取计轴索引 */
	UINT16 acIndex = 0u;
	UINT8 ocid = 0u;
	UINT8 isSelfFlag = 0u;
	UINT32 errorCode = 0u;

	UINT8 acStatus = ELM_AC_OCC;
	UINT8 passFlag = AAM_UT_PASS;

	/** 获取计轴数组索引 */
	acIndex = aam_PrepareACIndex(acID);
	isSelfFlag = aam_PrepareACIsSelf(acID,&ocid);
	acStatus = aam_PrepareACStatus(acID);
	passFlag = aam_GetPassTrainFlag(acIndex);

	if (ELM_BELONG_OWNER == isSelfFlag)
	{
		if (AAM_ENVELOPE_ENTER_ERROR == flag)
		{
			/** 说明计轴区段出现了UKT,清除好车通过标志位 */
			aam_ResetAxisAssertByACIndex(acIndex);

			/** 打印维护日志*/
			AAM_LOG(AAM_LOG_FATAL,"info:Init assertInfo for ac%d.\n",acID);
		}
		else if ((AAM_ENVELOPE_HEAD_ENTER == flag) || (AAM_ENVELOPE_TAIL_ENTER == flag))
		{
			if ((AAM_CT_PASS == passFlag) && (ELM_AC_OCC == acStatus) && (0u != supicTrainid))
			{
				/** 带前端或者后端可疑的包络进入且占用，清除之前的好车通过标志位 */
				(void)aam_ClearPassTrainFlag(acIndex);
				AAM_LOG(AAM_LOG_FATAL,"info:clear acIndex:%d CT pass flag by suspic.\n",acIndex);
			}
			else
			{
				/** 无需处理 */
			}
			/** 添加车头/车尾进入标志*/
			aam_SetEnvelopeEnterType(acIndex,flag,trainId);
		}
		else if (AAM_ENVELOPE_TAIL_EXIT == flag)
		{
			/** 车尾出清处理*/
			aam_ProessPassTrainFlag(acID,acIndex,trainId,supicTrainid);
		}
		else if (AAM_ENVELOPE_HEAD_EXIT == flag)
		{
			/** 车头出清处理*/
			aam_ClearHeadEnterIdForTrain(acIndex,trainId);
		}
		else
		{
			/** 不处理 */
		}
	}
	else 
	{
		/** 打印维护日志*/
		ASSER_ERROR(0u == isSelfFlag,errorCode,0x80000000u);
		ASSER_DEBUG(0u == isSelfFlag,AAM_LOG_LOC(AAM_LOG_FATAL,"errorCode:0x%08x info:Clear PassTrainFlag for ac%d.\n",errorCode,acID));
		/** 不属于本OC或者查询错误 */
		aam_ResetAxisAssertByACIndex(acIndex);
	}
}

/**
 * @brief 对外接口：获取计轴诊断状态
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 */
UINT8 aam_GetACAssertStatus(UINT16 ACID)
{
	/*- 局部变量定义 */
	UINT8 ret = AAM_API_AC_UT;
	UINT8 tmpRedunTime = 0u;
	UINT8 tmppassTrainType = AAM_UT_PASS;
	UINT8 tmpACStatus = AAM_STATUS_OCC;
	UINT16 acIndex = 0u;
	UINT8 acRelEnvelopeCnt = 0u;
	EnvelopeStruct envelopeInfo[SECTION_REL_ENVELOPE_SUM_MAX] = { 0u };
	UINT8 chRedunArbFlag = REDUN_OVER_ARB_NO;

	/** 获取计轴数组索引 */
	acIndex = aam_PrepareACIndex(ACID);

	/** 计轴故障的判断 */
	tmpRedunTime = aam_GetRedunTime(acIndex);
	tmppassTrainType = aam_GetPassTrainFlag(acIndex);
	tmpACStatus = aam_GetAxisStatus(acIndex);

	/** 获取计轴区段关联的包络 */
	acRelEnvelopeCnt = elm_GetEnvelopeInAC(ACID, envelopeInfo);

	if (0u != acRelEnvelopeCnt)
	{
		ret = AAM_API_AC_UT;
	}
	else if (AAM_STATUS_FREE_OR_REDUN == tmpACStatus)
	{
		if (0u != tmpRedunTime)
		{
			/** 此处特殊处理的目的是：冗余期间，计轴占用，但是计轴诊断成空闲，只有计轴前状态是空闲，本周周期占用且无车时才会进入该if分支 */
			chRedunArbFlag = aam_GetAxisRedunCanArbFlag(acIndex);
			if ((AAM_CT_PASS == tmppassTrainType)&&(REDUN_OVER_ARB_YES == chRedunArbFlag))
			{
				ret = AAM_API_AC_REDUNARB;
			}
			else
			{
				ret = AAM_API_AC_REDUNUT;
			}
	    }
		else
		{
			ret = AAM_API_AC_UT;
		}
	}
	else if(AAM_STATUS_ARB == tmpACStatus)
	{
		ret = AAM_API_AC_ARB;
	}
	else if ((AAM_STATUS_OCC == tmpACStatus) && (0u != tmpRedunTime) && (AAM_CT_PASS == tmppassTrainType) )
	{
		/** 此处特殊处理的目的是：UT计轴清扫，CT车驶过UT计轴后，计轴的诊断状态不会立马为ARB,而是ARB冗余，此处处理为了防止计轴添加UKT包络，从而实现清扫功能*/
		ret = AAM_API_AC_REDUNARB;
	}
	else
	{
		ret = AAM_API_AC_UT;
	}

	return ret;
}

/**
 * @brief 对外接口：获取计轴关联的物理区段的故障诊断状态
 * @param[in] UINT16 phyID 
 * @param[out]
 * @return AAM_API_AC_ARB 物理区段ARB
           UINT8_MAX 物理区段非ARB
 * @note 物理区段关联的计轴区段占用且都为ARB时，则返回ARB，否则返回UT
 */
UINT8 aam_GetPhyIsARB(UINT16 phyID)
{
	UINT8 ret = UINT8_MAX;
	UINT8 cycle = 0u;
	UINT8 acCnt = 0u;    /* 计轴关联的物理区段包含的计轴区段数量 */
	const UINT16* acIDBuff = NULL;   /* 计轴关联的物理区段包含的计轴区段ID */
	UINT8 ocid = 0u;
	UINT8 isSelfFlag = 0u;
	UINT8 ACOCCStatus = ELM_AC_OCC;
	UINT8 ACAssertStatus = AAM_API_AC_UT;
	UINT8 PhyOCCStatus = SECTION_OCCUPY_YES;
	UINT32 errorCode = 0u;


	isSelfFlag = aam_PreparePhyIsSelf(phyID,&ocid);

	if (ELM_BELONG_OWNER == isSelfFlag)
	{
		/** 获取物理区段占用状态 */
		PhyOCCStatus = aam_PreparePhyOccStatus(phyID);

		if (SECTION_OCCUPY_YES == PhyOCCStatus)
		{
			/** 获取物理区段包含的计轴区段*/
			acIDBuff = aam_PreparePhyRelACIds(phyID,&acCnt);
			ASSER_ERROR((NULL == acIDBuff) || (0u == acCnt),errorCode,0x80000000u);

			if (0u == errorCode)
			{
				/** 查询正确，遍历所有的计轴区段，如果计轴区段占用且都为ARB时，则返回ARB，否则返回UT */
				for (cycle = 0u; cycle < acCnt;cycle++)
				{					
					ACOCCStatus = aam_PrepareACStatus(acIDBuff[cycle]);
					ACAssertStatus = aam_GetACAssertStatus(acIDBuff[cycle]);

					if (ELM_AC_FREE == ACOCCStatus)
					{
						/** 计轴空闲,不设置计轴状态，保持上次设置值，则继续遍历*/
					}
					else if ((ELM_AC_OCC == ACOCCStatus) && (AAM_API_AC_ARB == ACAssertStatus))
					{
						/** 计轴区段占用且为ARB时,设置计轴状态为ARB，继续遍历*/
						ret = AAM_API_AC_ARB;
					}
					else if ((ELM_AC_OCC == ACOCCStatus) && (AAM_API_AC_REDUNARB == ACAssertStatus))
					{
						/** 计轴区段占用且为ARB冗余 不处理*/
					}
					else
					{
						/** 计轴区段占用且为不ARB时,停止遍历*/
						ret = UINT8_MAX;
						break;
					}
				}
			}
		}
		else
		{
			/** 物理区段非ARB */
		}
	}
	else
	{
		/** 非本OC所属计轴，不应该被调用，返回物理区段非ARB  */
	}

	return ret;
}

/**
 * @brief 对外接口：获取计轴好车通过标志
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 */
UINT8 aam_GetACPassTrainFlag(UINT16 ACID)
{
	UINT16 acIndex = 0u;

	/** 获取计轴数组索引 */
	acIndex = aam_PrepareACIndex(ACID);

	return aam_GetPassTrainFlag(acIndex);
}

/**
 * @brief 对外接口：获取计轴对应的诊断信息地址
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 */
const AxisAsserStruct* aam_GetAxisAssertInfoPtr(UINT16 ACID)
{
	/*- 局部变量定义 */
	UINT16 acIndex = 0u;
	/** 获取计轴数组索引 */
	acIndex = aam_PrepareACIndex(ACID);
	return aam_GetAxisAssertInfo(acIndex);
}


/**
 * @brief 对外接口：跟随计轴诊断模块数据
 * @param[out] UINT8 *pDataBuff 跟随数据的存储地址指针
 * @param[in] UINT32 curIndex 跟随数据的索引地址
 * @return 跟随数据的长度
 * @note 无
 */
UINT32 aam_GetTransferData(OUT UINT8 *pDataBuff,UINT32 curIndex)
{
	/*- 局部变量定义 */
	UINT32 ret = curIndex;
	UINT32 copyIndex = curIndex;
	UINT16 cycle = 0u;
	UINT16 acCnt = 0u;
	UINT8 endLineInitFlag = 0u;
	const UINT16* pACIdBuff = NULL;
	const AxisAsserStruct* pACAssertInfo = NULL;
	UINT32 errorCode = 0u;


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

	/** 获取计轴区段信息 */
	acCnt = aam_PrepareACBuffIndexs(&pACIdBuff);

	/** 判断计轴区段信息是否获取成功 */
	ASSERT_RET_VALUE(NULL == pACIdBuff,ret,0x40000000u);

	/** 设置模块标识 */
	pDataBuff[copyIndex++] = (UINT8)'A';
	pDataBuff[copyIndex++] = (UINT8)'A';
	pDataBuff[copyIndex++] = (UINT8)'M';

	/** 设置计轴诊断信息个数 */
	(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(UINT16),&acCnt, (UINT32)sizeof(UINT16));
	copyIndex += (UINT32)sizeof(UINT16);

	/** 遍历所有计轴 */
	for (cycle = 0u; cycle < acCnt;cycle++)
	{
		/** 获取计轴诊断信息 */
		pACAssertInfo = aam_GetAxisAssertInfoPtr(pACIdBuff[cycle]);

		/** 判断是否处理正确*/
		ASSERT_BREAK(NULL == pACAssertInfo,errorCode,0x40000000u);

		/** 拷贝计轴ID*/
		(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(UINT16),&(pACIdBuff[cycle]), (UINT32)sizeof(UINT16));
		copyIndex += (UINT32)sizeof(UINT16);

		/** 拷贝诊断信息*/
		(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(AxisAsserStruct),pACAssertInfo, (UINT32)sizeof(AxisAsserStruct));
		copyIndex += (UINT32)sizeof(AxisAsserStruct);
	}

	/*- 判断是否处理成功*/
	if (cycle == acCnt)
	{
		/** 获取尽头线ARB特殊处理标志*/
		endLineInitFlag = aam_GetInitEndlineFlag();
		pDataBuff[copyIndex++] = endLineInitFlag;

		/** 处理正确*/
		ret = copyIndex;
	}
	else
	{
		/** 不设置*/
	}

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


/**
 * @brief 对外接口：拷贝计轴诊断模块数据
 * @param[in] const UINT8 *pDatabuff 跟随数据的存储地址指针
 * @param[in] UINT32 curIndex 跟随数据的索引地址
 * @param[in] UINT32 len 跟随数据的长度
 * @return CI_ERROR 拷贝失败
           CI_SUCCESS 拷贝成功
 * @note 
 */
UINT32 aam_SetTransferData(IN const UINT8 *pDatabuff,UINT32 curIndex,UINT32 len)
{
	UINT32 ret = curIndex;
	UINT8 funRtn = CI_ERROR;
	UINT8 endLineInitFlag = 0u;
	UINT32 setIndex = curIndex;
	UINT16 cycle = 0u;
	UINT16 acCnt = 0u;
	UINT16 tempID = 0u;
	UINT16 acIndex = 0u;
	AxisAsserStruct tmpAssertInfo = {0u};
	UINT32 errorCode = 0u;

	/** 入口参数判断 */
	ASSERT_RET_VALUE(NULL == pDatabuff,ret,0x80000000u);
	ASSERT_RET_VALUE(curIndex >= len,ret,0x40000000u);


	/** 开始设置 */
	if ((UINT8)'A' == pDatabuff[setIndex])
	{
		setIndex++;
		if ((UINT8)'A' == pDatabuff[setIndex])
		{
			setIndex++;
			if ((UINT8)'M' == pDatabuff[setIndex])
			{
				setIndex++;
				/** 获取计轴诊断信息个数 */
				(void)CommonMemCpy(&acCnt, (UINT32)sizeof(UINT16), &pDatabuff[setIndex], (UINT32)sizeof(UINT16));
				setIndex += (UINT32) sizeof(UINT16);

				for (cycle = 0u; cycle < acCnt; cycle++)
				{
					/** 获取计轴ID */
					(void)CommonMemCpy(&tempID, (UINT32)sizeof(UINT16), &pDatabuff[setIndex], (UINT32)sizeof(UINT16));
					setIndex += (UINT32)sizeof(UINT16);

					/** 通过计轴ID获取计轴索引*/
					acIndex = aam_PrepareACIndex(tempID);
					/** 判断是否处理正确*/
					ASSERT_BREAK(UINT16_MAX == acIndex, errorCode, 0x20000000u);

					/** 获取计轴诊断信息 */
					(void)CommonMemSet(&tmpAssertInfo, (UINT32) sizeof(AxisAsserStruct), 0, (UINT32)sizeof(AxisAsserStruct));
					(void)CommonMemCpy(&tmpAssertInfo, (UINT32)sizeof(AxisAsserStruct), &pDatabuff[setIndex], (UINT32)sizeof(AxisAsserStruct));
					setIndex += (UINT32)sizeof(AxisAsserStruct);

					funRtn = aam_SetAxisAssert(acIndex, &tmpAssertInfo);
					/** 判断是否处理正确*/
					ASSERT_BREAK(UINT16_MAX == acIndex, errorCode, 0x10000000u);
				}

				/** 获取尽头线ARB特殊处理标志 */
				endLineInitFlag = pDatabuff[setIndex++];
				aam_SetInitEndlineFlag(endLineInitFlag);

				/** 设置返回值 */
				ASSERT_SETRET((0u == errorCode) && (setIndex <= len), ret, setIndex, ret);
				ASSER_DEBUG(0u != errorCode, ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:ELM Set dataIndex%d.dataLen:%d.\n", errorCode, setIndex, len));
			}
			else
         	{
	        	/** 跟随数据类型错误 */
	        	ASSER_ERROR(CI_ERROR == ret,errorCode,0x20000000u);
		        ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:TransferData type:%c%c%c error.",errorCode,pDatabuff[curIndex],pDatabuff[curIndex+1U],pDatabuff[curIndex+2U])
	        }
		}
		else
	    {
		    /** 跟随数据类型错误 */
		    ASSER_ERROR(CI_ERROR == ret,errorCode,0x20000000u);
		    ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:TransferData type:%c%c%c error.",errorCode,pDatabuff[curIndex],pDatabuff[curIndex+1U],pDatabuff[curIndex+2U])
	    }
	}
	else
	{
		/** 跟随数据类型错误 */
		ASSER_ERROR(CI_ERROR == ret,errorCode,0x20000000u);
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:TransferData type:%c%c%c error.",errorCode,pDatabuff[curIndex],pDatabuff[curIndex+1U],pDatabuff[curIndex+2U])

	}
	return ret;
}


/**
 * @brief 对外接口：清除计轴好车通过标志
 * @param[in] 
 * @param[out]
 * @return 
 * @note 
 */
UINT8 aam_ClearACPassTrainFlag(UINT16 ACID)
{
	/*- 局部变量定义 */
	UINT16 acIndex = 0u;
	/** 获取计轴数组索引 */
	acIndex = aam_PrepareACIndex(ACID);
	return aam_ClearPassTrainFlag(acIndex);
}

/**
 * @brief 对外接口：清除计轴好车通过信息
 * @param[in] UINT16 ACID 计轴ID
 * @param[in] UINT16 trainID 列车ID
 * @param[out] 无
 * @return 无
 * @note 无
 */
void aam_ClearACEnvelopeEnterInfo(UINT16 ACID,UINT16 trainID)
{
	/*- 局部变量定义 */
	UINT16 acIndex = 0u;
	/** 获取计轴数组索引 */
	acIndex = aam_PrepareACIndex(ACID);

	aam_ClearHeadEnterIdForTrain(acIndex,trainID);
	aam_ClearTailEnterIdForTrain(acIndex,trainID);

}

/**
* @brief 对外接口：获取计轴关联的物理区段是否存在好车通过计轴区段
* @param[in] UINT16 acID
* @param[out] 无
* @return AAM_CT_PASS 物理区段好车通过
AAM_UT_PASS 物理区段坏车通过
* @note 物理区段关联的计轴区段有好车通过标志则认为该物理区段好车通过
*所有区段均无好车通过标志，则物理区段坏车通过
*/
UINT8 aam_GetACRelPhyPassTrainFlag(UINT16 acID)
{
	UINT8 ret = AAM_UT_PASS;
	UINT8 cycle = 0u;
	UINT8 acCnt = 0u;    /* 计轴关联的物理区段包含的计轴区段数量 */
	const UINT16* acIDBuff = NULL;   /* 计轴关联的物理区段包含的计轴区段ID */
	UINT8 ocid = 0u;
	UINT8 isSelfFlag = 0u;
	UINT32 errorCode = 0u;
	UINT16 phyID = 0u;
	UINT8 passTrainFlag = AAM_UT_PASS;

	phyID = aam_PrepareACBelongPhyid(acID);

	isSelfFlag = aam_PreparePhyIsSelf(phyID, &ocid);

	if (ELM_BELONG_OWNER == isSelfFlag)
	{
		/** 获取物理区段包含的计轴区段*/
		acIDBuff = aam_PreparePhyRelACIds(phyID, &acCnt);
		ASSER_ERROR((NULL == acIDBuff) || (0u == acCnt), errorCode, 0x80000000u);

		if (0u == errorCode)
		{
			/** 查询正确，遍历所有的计轴区段，如果所有计轴区段都无好车通过标志，物理区段坏车通过 */
			for (cycle = 0u; cycle < acCnt; cycle++)
			{
				passTrainFlag = aam_GetACPassTrainFlag(acIDBuff[cycle]);
				if (AAM_CT_PASS == passTrainFlag)
				{
					ret = AAM_CT_PASS;
					break;
				}
				else
				{
					; /* 继续遍历 */
				}
			}
		}
	}
	else
	{
		/** 非本OC所属计轴，不应该被调用，返回物理区段坏车通过  */
	}

	return ret;
}


/**
 * @brief 对外接口：设置计轴进入冗余状态
 * @param[in] UINT16 ACID 计轴ID
 * @param[out] 无
 * @return  无
 * @note 此函数需要保证调用处通过触发方式调用，并且冗余计时位的累加只能在计轴诊断模块中进行，此函数尽量别扩展使用。
         调用登记：
		 1、elm_UCTEnvelopeSplit  避免UCT恢复后，好车通过的计轴因为未进入冗余状态，导致触发UT丢车防护
 */
void aam_SetACEnterRedun(UINT16 ACID)
{
	UINT16 acIndex = 0u;
	UINT8 maxRedunTimes = 0u;
	UINT8 redunTime = 0u;

	/** 获取计轴数组索引 */
	acIndex = aam_PrepareACIndex(ACID);
	/** 获取区段由占用变空闲持续时间 */
	maxRedunTimes = aam_PrepareRedunTimes();

	if (UINT16_MAX == acIndex)
	{
		/** 不处理 */
	}
	else
	{
		/** 获取当前冗余时间 */
		redunTime = aam_GetRedunTime(acIndex);

		if (0u == redunTime)
		{
			/** 启动冗余*/
			aam_AddRedunTime(acIndex,maxRedunTimes);
		}
		else
		{
			/** 已启动冗余计时，不处理 */
		}		
	}
}
	

/**
* @brief 对外接口：检查是否为当周期计轴进入冗余状态
* @param[in] UINT16 ACID 计轴ID
* @param[out] 无
* @return  CI_ERROR 未进入冗余
           CI_SUCCESS 已进入冗余
* @note 
*/
UINT8 aam_CheckACEnterRedun(UINT16 ACID)
{
	UINT8 ret = CI_ERROR;
	UINT16 acIndex = 0u;
	UINT8 redunTime = 0u;

	/** 获取计轴数组索引 */
	acIndex = aam_PrepareACIndex(ACID);

	if (UINT16_MAX != acIndex)
	{
		/** 获取当前冗余时间 */
		redunTime = aam_GetRedunTime(acIndex);

		/** 设置函数返回值 */
		ASSERT_SETRET(0u != redunTime,ret,CI_SUCCESS,CI_ERROR);
	}
	else
	{
		/** 查询错误，设置计轴已进入冗余状态 */
		ret = CI_ERROR;
	}
	return ret;
}
/**
* 功能：查询计轴区段邻近范围内无坏车占用
* 输入参数：UINT16 ACID 计轴区段
* 返回值：CI_ERROR 判断时间和距离范围内有坏车   CI_SUCCESS 检查通过
* Create:  fan 2024/08/22
*/
UINT8 aam_CheckNearbyTrainType(UINT16 ACID)
{
	UINT8 retVal = CI_ERROR;
	UINT8 phyAcNum = 0u;
	UINT16*  pACBuff = NULL;
	UINT16 wBasePhyid = 0U;/*基准物理区段*/
	UINT8 jj = 0U;
	UINT8 ii = 0U;
	UINT8 chKeepcheck = CI_SUCCESS; /*继续检查标志*/
	UINT8 chTimeFlag = 0U; /*单个计轴坏车上次通过超时标志*/
	UINT32 cyCheckUtCyc = 0U; /*检查周期数*/
	UINT32 dwRecentUtCyc = 0U; /*最近坏车占用周期号*/
	UINT16 wCheckPhySec = 0U; /*待检查区段*/
	UINT16* pAdjacentPhyBuf = NULL; /*直接相连区段数组*/
	UINT8 chAdjacentPhyNum = 0U; /*直接相连区段数量*/
	UINT8 chNearSecNum = 0U; /*间接相邻数量*/
	UINT16* pNearSecBuf = NULL; /*间接相连区段数组*/
	UINT8 chSwitchPosCheck = CI_ERROR;/*当前道岔检查结果*/
	UINT8 chTransitAcNum = 0U; /*跳转计轴数量*/
	UINT16* pTransitAcBuf = NULL; /*跳转计轴数组*/
	cyCheckUtCyc = GetArbProtectCheckTime();
	wBasePhyid = aam_PrepareACBelongPhyid(ACID);
	
	chKeepcheck = GetPhyPossibleArbTag(wBasePhyid);
	if (CI_SUCCESS == chKeepcheck)
	{
		/*Step1 :当前物理区段所有计轴无坏车*/
		phyAcNum = GetPAxisSectionSum(wBasePhyid);
		pACBuff = GetPAxisSectionIdBuf(wBasePhyid);
		/*遍历计轴上最近坏车占用周期*/
		if ((0U != phyAcNum) && (NULL != pACBuff))
		{
			for (jj = 0; jj < phyAcNum; jj++)
			{
				dwRecentUtCyc = GetAxisRecentUtOccupyCyc(pACBuff[jj]);
				chTimeFlag = SystemOverTimeCheck(dwRecentUtCyc, cyCheckUtCyc);
				if (CI_TIME_IN == chTimeFlag)
				{
					/*还在时间范围内 认为坏车接近*/
					chKeepcheck = CI_ERROR;
					retVal = CI_ERROR;
					debug_infor_printf((const)"ACid: %d , ArbNearSecCheck fail step1, PhySec = %d\n", ACID, wBasePhyid);
					break;
				}
			}
		}
		else
		{
			chKeepcheck = CI_ERROR;
		}
	}

	if(CI_SUCCESS == chKeepcheck)
	{
		/*Step2 :当前物理区段直接相邻物理区段所有计轴无坏车*/
		chAdjacentPhyNum = GetAdjacentPhySecNum(wBasePhyid);
		pAdjacentPhyBuf = GetAdjacentPhySecBuf(wBasePhyid);
		if ((0U != chAdjacentPhyNum) && (NULL != pAdjacentPhyBuf))
		{
			for (ii = 0; ii < chAdjacentPhyNum; ii++)
			{
				wCheckPhySec = pAdjacentPhyBuf[ii];
				chSwitchPosCheck = GetAdjacentPhySecAcCheck(wBasePhyid, wCheckPhySec);
				if (CI_SUCCESS == chSwitchPosCheck)
				{	
					/* 邻近区段有坏车曾占用再取消，认为坏车接近*/
					phyAcNum = GetPAxisSectionSum(wCheckPhySec);
					pACBuff = GetPAxisSectionIdBuf(wCheckPhySec);			
					/*遍历计轴上最近坏车占用周期*/
					if ((0U != phyAcNum) && (NULL != pACBuff))
					{
						for (jj = 0; jj < phyAcNum; jj++)
						{
							dwRecentUtCyc = GetAxisRecentUtOccupyCyc(pACBuff[jj]);
							chTimeFlag = SystemOverTimeCheck(dwRecentUtCyc, cyCheckUtCyc);							
							if (CI_TIME_IN == chTimeFlag)
							{
								/*还在时间范围内*/
								chKeepcheck = CI_ERROR;
								retVal = CI_ERROR;
								debug_infor_printf((const)"ACid: %d , ArbNearSecCheck fail step2, PhySec = %d\n", ACID, wCheckPhySec);
								break;
							}
						}
					}
					else
					{
						chKeepcheck = CI_ERROR;
					}
				}
				else
				{
					;/*不处理*/
					debug_infor_printf((const)"ACid: %d ,AdjacentSec Skip PhySec = %d\n", ACID, wCheckPhySec);
				}
			}
		}
		else
		{
			chKeepcheck = CI_ERROR;
		}
	}

	if (CI_SUCCESS == chKeepcheck)
	{
		/*Step3 :当前物理区段间接相邻物理区段所有计轴无坏车*/
		chNearSecNum = GetNearPhySecNum(wBasePhyid);
		pNearSecBuf = GetIndirectNearPhySecBuf(wBasePhyid);
		for (ii = 0; ii < chNearSecNum; ii++)
		{
			wCheckPhySec = pNearSecBuf[ii];
			chTransitAcNum = GetPhySecNearSecTransitAcNum(wBasePhyid, wCheckPhySec);
			pTransitAcBuf = GetPhySecNearSecTransitAcBuf(wBasePhyid, wCheckPhySec);
			chSwitchPosCheck = CI_ERROR;
			if (NULL != pTransitAcBuf)
			{
				for (jj = 0; jj < chTransitAcNum; jj++)
				{
					chSwitchPosCheck = GetTransitPhySecAcCheck(wBasePhyid, pTransitAcBuf[jj]);
					if (CI_SUCCESS == chSwitchPosCheck)
					{		
						break;
					}
				}
			}
					
			if (CI_SUCCESS == chSwitchPosCheck) 
			{
				/* 邻近可达区段有坏车曾占用再取消，认为坏车接近*/
				phyAcNum = GetPAxisSectionSum(wCheckPhySec);
				pACBuff = GetPAxisSectionIdBuf(wCheckPhySec);
				/*遍历计轴上最近坏车占用周期*/
				if ((0U != phyAcNum) && (NULL != pACBuff))
				{
					for (jj = 0; jj < phyAcNum; jj++)
					{
						dwRecentUtCyc = GetAxisRecentUtOccupyCyc(pACBuff[jj]);
						chTimeFlag = SystemOverTimeCheck(dwRecentUtCyc, cyCheckUtCyc);
						if (CI_TIME_IN == chTimeFlag)
						{
							/*还在时间范围内 认为坏车接近*/
							chKeepcheck = CI_ERROR;
							retVal = CI_ERROR;
							debug_infor_printf((const)"ACid: %d , ArbNearSecCheck fail step3, PhySec = %d\n", ACID, wCheckPhySec);
							break;
						}
					}
				}
				else
				{
					chKeepcheck = CI_ERROR;
				}
			}
			else
			{
				;/*不可达状态 坏车占用不影响*/
				debug_infor_printf((const)"ACid: %d ,NearSec Skip PhySec = %d\n", ACID, wCheckPhySec);
			}
			if (CI_SUCCESS != chKeepcheck)
			{
				break;
			}
		}
	}
	if (CI_SUCCESS == chKeepcheck)
	{
		retVal = CI_SUCCESS;/*全部检查通过*/
	}
	return retVal;
}

/**
* 函数功能：计轴子系统通信中断ARB处理
* 输入参数：无
* 返回值：无
* Create By LQ 2025.02.23
*/
void aam_AxisCommBadArbPro(void)
{
	UINT8 cFuncRetVal = CI_ERROR;
	UINT8 cLocalWorkMode = RC_WORK_MODE_CI;
	UINT8 cFuncSwitch = FUNC_SWITCH_OFF;
	UINT8 cLocalCiType = 0U;
	UINT8 cLocalRcLinkLineAttr = 0U;  /*联络线属性*/
	UINT8 cCommAxisNum = 0U;  /*具有通信关系的计轴子系统数量*/
	UINT8* pAxisSysIdBuf = NULL;
	UINT8 cCommState = TRANSMIT_2OO2_STATE_BAD;  /*通信状态*/
	
	cLocalWorkMode = GetLocalRcWorkMode();
	cFuncSwitch = GetCiFunctionSwitchConfig(FUNC_AXIS_COMM_BAD_KEEP_CBTC);
	if ((RC_WORK_MODE_TIOC == cLocalWorkMode) && (FUNC_SWITCH_ON == cFuncSwitch))
	{
		cLocalCiType = GetLocalCiType();
		cLocalRcLinkLineAttr = GetLocalRcLinkLineAttr();
		if (((CI_TYPE_ZX == cLocalCiType) || (CI_TYPE_SCX == cLocalCiType)) && (RC_LINK_LINE_NO == cLocalRcLinkLineAttr))
		{
			cCommAxisNum = GetCiTransmitSpecifySysDevSum(CI_SYSTEM_TYPE_AXIS);
			pAxisSysIdBuf = GetCiTransmitSpecifySysDevBuf(CI_SYSTEM_TYPE_AXIS);

			if ((1U == cCommAxisNum) && (NULL != pAxisSysIdBuf))
			{
				cCommState = GetCiTransmitState(CI_SYSTEM_TYPE_AXIS, pAxisSysIdBuf[0U]);
				if (TRANSMIT_STATE_BAD == cCommState)
				{
					/*1.列车条件检查：无UT/UCT/可疑CT，无休眠车，列车NVRAM标志无效*/
					cFuncRetVal = aam_AxisCommBadArbTrainCheck();

					/*2.区段条件检查：本控区边界计轴区段ARB防护范围内、ARB防护时间内没出现过故障车，相邻控区边界计轴区段未ARB*/
					cFuncRetVal &= aam_AxisCommBadArbSecCheck();

					if (CI_SUCCESS == cFuncRetVal)
					{
						SetRcAxleArb();  /*设置集中区计轴区段ARB*/
						debug_infor_printf((const)"aam_AxisCommBadArbPro Success\n");
					}
					else
					{
						;
					}
				}
				else
				{
					/*通信正常，不处理*/
				}
			}
			else
			{
				/*存在多个通信的计轴子系统，不处理*/
			}
		}
		else
		{
			/*场段或入口RC，不处理*/
		}
	}
	else
	{
		/*非RC模式或“计轴系统通信中断后是否能够维持CBTC运行”开关关闭，不处理*/
	}
}

/**
* 函数功能：计轴子系统通信中断ARB处理——列车条件检查
* 输入参数：无
* 返回值：CI_SUCCESS 1 成功
*         CI_ERROR 0 失败
* Create By LQ 2025.02.23
*/
UINT8 aam_AxisCommBadArbTrainCheck(void)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 wAcNum = 0u;                             /*OC范围内所有的计轴区段数量*/
	const UINT16* pACIdbuff = NULL;        /** 计轴ID数值缓存 */
	UINT8 cLocalCiId = 0U;
	UINT16 ii = 0U;
	UINT8 cAcBelongCiId = 0U;
	UINT8 cEnvelopeNum = SECTION_REL_ENVELOPE_SUM_MAX;  /*包络数量*/
	UINT16 szEnvelopeID[SECTION_REL_ENVELOPE_SUM_MAX] = { 0U };  /*包络ID*/
	UINT8 jj = 0U;
	const EnvelopeStruct* pELMInfo = NULL;  /*包络数据*/
	UINT8 cSleepState = TRAIN_SLEEP_YES;  /*列车休眠状态*/
	UINT8 cNvramFlag = TRAIN_NVRAM_POS_FLAG_YES;  /*列车NVRAM标志*/

	wAcNum = elm_PrepareACBuffIndexs(&pACIdbuff);  /*获取计轴区段数量及ID*/
	cLocalCiId = GetSystemParaLocalCiId();
	if ((0U < wAcNum) && (AXIS_SECTION_SUM_MAX > wAcNum ) && (NULL != pACIdbuff) && (0U != cLocalCiId))
	{
		cRetVal = CI_SUCCESS;
		for (ii = 0U; ii < wAcNum; ii++)
		{
			cAcBelongCiId = (UINT8)GetAxisBelongTioc(pACIdbuff[ii]);
			if (cLocalCiId == cAcBelongCiId)
			{
				cEnvelopeNum = elm_GetEnvelopeIDsInAC(pACIdbuff[ii], szEnvelopeID);
				if (0U == cEnvelopeNum)
				{
					/*无包络，检查通过*/
				}
				else if(SECTION_REL_ENVELOPE_SUM_MAX > cEnvelopeNum)
				{
					for (jj = 0U; jj < cEnvelopeNum; jj++)
					{
						pELMInfo = elm_GetEnvelopeInfoByID(szEnvelopeID[jj]);

						if ((NULL != pELMInfo) && (TYPE_CT_ENVELOPE == pELMInfo->envelopeType) &&
							(0U == pELMInfo->headTrainID) && (0U == pELMInfo->tailTrainID))
						{
							/*未有隐藏车进入*/
							if (1U == pELMInfo->trianCnt)
							{
								cSleepState = GetTrainSleepState(pELMInfo->trainID[0]);
								cNvramFlag = GetTrainNvramPosFlag(pELMInfo->trainID[0]);
								if ((TRAIN_SLEEP_NO == cSleepState) && (TRAIN_NVRAM_POS_FLAG_NO == cNvramFlag))
								{
									/*无休眠车且列车不使用NVRAM，继续检查*/
								}
								else
								{
									debug_infor_printf((const)"aam_AxisCommBadArbTrainCheck Error: Sleep Train Or Nvram Valid\n");
									cRetVal = CI_ERROR;  /*存在休眠车或者使用NVRAM的通信车，检查失败，返回失败*/
								}
							}
							else
							{
								debug_infor_printf((const)"aam_AxisCommBadArbTrainCheck Error: Envelope Train Num Invalid\n");
								cRetVal = CI_ERROR;  /*异常场景，检查失败，返回失败*/
							}
						}
						else
						{
							debug_infor_printf((const)"aam_AxisCommBadArbTrainCheck Error: Exist UT\n");
							cRetVal = CI_ERROR;  /*存在隐藏车，停止检查，返回失败*/
						}

						if (CI_SUCCESS != cRetVal)
						{
							cRetVal = CI_ERROR;
							break;  /*检查失败，停止遍历，返回失败*/
						}
						else
						{
							/*继续检查*/
						}
					}
				}
				else
				{
					cRetVal = CI_ERROR;
				}

				if (CI_SUCCESS != cRetVal)
				{
					cRetVal = CI_ERROR;
					break;  /*检查失败，停止遍历，返回失败*/
				}
				else
				{
					/*继续检查*/
				}
			}
			else
			{
				/*非本控区计轴区段，不处理*/
			}
		}
	}
	else
	{
		/*入参检查失败，返回失败*/
	}

	return cRetVal;
}

/**
* 函数功能：计轴子系统通信中断ARB处理——区段条件检查
* 输入参数：无
* 返回值：CI_SUCCESS 1 成功
*         CI_ERROR 0 失败
* Create By LQ 2025.02.23
*/
UINT8 aam_AxisCommBadArbSecCheck(void)
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 wAcNum = 0u;                             /*OC范围内所有的计轴区段数量*/
	const UINT16* pACIdbuff = NULL;        /** 计轴ID数值缓存 */
	UINT8 cLocalCiId = 0U;
	UINT16 ii = 0U;
	UINT8 cAxleBorderAttr = AXIS_BORDER_AXLE_YES;
	UINT8 cAcBelongCiId = 0U;
	UINT16 wRelPhySecId = 0U;  /*计轴区段关联物理区段ID*/
	UINT8 cPhySecArbState = 0U;

	wAcNum = elm_PrepareACBuffIndexs(&pACIdbuff);  /*获取计轴区段数量及ID*/
	cLocalCiId = GetSystemParaLocalCiId();
	if ((0U < wAcNum) && (AXIS_SECTION_SUM_MAX > wAcNum) && (NULL != pACIdbuff) && (0U != cLocalCiId))
	{
		cRetVal = CI_SUCCESS;
		for (ii = 0U; ii < wAcNum; ii++)
		{
			cAxleBorderAttr = GetAxisSecBorderProperty(pACIdbuff[ii]);
			if (AXIS_BORDER_AXLE_NO == cAxleBorderAttr)
			{
				/*非边界计轴区段，不处理*/
			}
			else if (AXIS_BORDER_AXLE_YES == cAxleBorderAttr)
			{
				cAcBelongCiId = (UINT8)GetAxisBelongTioc(pACIdbuff[ii]);
				if (cLocalCiId == cAcBelongCiId)
				{
					/*本控区边界计轴区段，需ARB防护范围内、ARB防护时间内没出现过故障车*/
					cRetVal = aam_CheckNearbyTrainType(pACIdbuff[ii]);
					if (CI_SUCCESS != cRetVal)
					{
						debug_infor_printf((const)"aam_AxisCommBadArbSecCheck Error: Near Sec Exist UT\n");
						cRetVal = CI_ERROR;  /*检查失败，停止遍历，返回失败*/
					}
					else
					{
						/*继续检查*/
					}
				}
				else
				{
					/*非本控区边界计轴区段，需未ARB*/
					wRelPhySecId = GetAxisSecRelativePhySecId(pACIdbuff[ii]);
					cPhySecArbState = GetPhySecArbState(wRelPhySecId);
					if (AXIS_SECTION_ARB_NO == cPhySecArbState)
					{
						/*未ARB，继续遍历检查*/
					}
					else
					{
						debug_infor_printf((const)"aam_AxisCommBadArbSecCheck Error: Other Rc Cfp ARB\n");
						cRetVal = CI_ERROR;  /*相邻控区边界计轴区段ARB，返回失败*/
					}
				}
			}
			else
			{
				cRetVal = CI_ERROR;
			}

			if (CI_SUCCESS != cRetVal)
			{
				cRetVal = CI_ERROR;
				break;
			}
			else
			{
				/*继续遍历检查*/
			}
		}
	}
	else
	{
		/*入参检查失败，返回失败*/
	}

	return cRetVal;
}

/*
* 功能描述：设置集中区内计轴区段ARB
* 参数说明：无
* 返 回 值：无
*/
void SetRcAxleArb(void)
{	
	UINT16 wAcNum = 0U;
	UINT16* pACBuff = NULL;
	UINT8 cLocalCiId = 0U;
	UINT16 ii = 0U;
	UINT8 cAcBelongCiId = 0U;
	UINT16 wACindex = 0U;
	UINT8 cAcOccStatus = ELM_AC_FREE;  /*计轴区段占用状态*/
	
	wAcNum = GetLocalCiAxisSectionIdBuf(&pACBuff);  /*获取计轴信息*/
	cLocalCiId = GetSystemParaLocalCiId();
	if ((0U < wAcNum) && (NULL != pACBuff) && (0U != cLocalCiId))
	{
		for (ii = 0U; ii < wAcNum; ii++)
		{
			cAcBelongCiId = (UINT8)GetAxisBelongTioc(pACBuff[ii]);
			wACindex = aam_PrepareACIndex(pACBuff[ii]);
			if ((cLocalCiId == cAcBelongCiId) && (UINT16_MAX != wACindex))
			{
				cAcOccStatus = aam_PrepareACStatus(pACBuff[ii]);
				if (ELM_AC_OCC == cAcOccStatus)
				{
					aam_SetAxisStatus(wACindex, AAM_STATUS_ARB);
					aam_SetAxisCommBadArbFlag(wACindex, AAM_COMM_BAD_ARB_YES);
				}
				else
				{
					/*计轴区段未占用，不处理*/
				}
			}
			else
			{
				/*非本控区计轴区段，不处理*/
			}
		}
	}
	else
	{
		;
	}
}

/**
* @brief 对外接口：获取计轴诊断状态接口
* @param[in] UINT16 计轴ID
* @param[out]
* @return UINT8 计轴诊断状态 0占用 0x55ARB 0xaa冗余或空闲
* Creat fan 20250310
*/
UINT8 aam_GetAxisStatusAPI(UINT16 ACID)
{
	UINT8 reVal = AAM_STATUS_OCC;
	UINT16 acIndex = 0U; 

	/** 获取计轴数组索引 */
	acIndex = aam_PrepareACIndex(ACID);
	reVal = aam_GetAxisStatus(acIndex);
	return reVal;
}

/**
* 函数功能：检查计轴所在物理区段均无故障车
* 输入参数：UINT16 ACID 计轴区段id
* 返回值：CI_SUCCESS 无故障车
*         CI_ERROR 存在故障车
* Create By fan 2025.06 18
*/
UINT8 aam_CheckPhyTrain(UINT16 ACID)
{
	UINT8 reVal = CI_ERROR;
	UINT16 wPhySecId = 0U; /*计轴所属物理区段*/
	UINT8 phyAcNum = 0u; /*物理区段关联计轴数*/
	UINT16*  pACBuff = NULL;
	UINT16 wAxisSecId = 0U; /*计轴区段id*/
	UINT8 linkNum = 0U; /*ilnk数量*/
	UINT16* pLinkBuf = NULL; /*link数组*/
	UINT8 jj = 0U;
	UINT8 ii = 0U;
	UINT8 k = 0U;
	TRAIN_SEQUANCE_s linkInctrainList[SIZE_MAX_TRAINOFAC] = { 0u };  /*link上的列车序列*/
	UINT8 cLinkIncTrainSum = 0u; /*link列车数量*/
	wPhySecId = aam_PrepareACBelongPhyid(ACID);
	phyAcNum = GetPAxisSectionSum(wPhySecId);
	pACBuff = GetPAxisSectionIdBuf(wPhySecId);
	if ((0U != phyAcNum) && (NULL != pACBuff))
	{
		reVal = CI_SUCCESS;
		for (ii = 0; ii < phyAcNum; ii++)
		{
			/*检查计轴上link有隐藏车*/
			wAxisSecId = pACBuff[ii];
			linkNum = GetAxisLinkSum(wAxisSecId);
			pLinkBuf = GetAxisLinkIdBuf(wAxisSecId);
			if ((0U != linkNum) && (NULL != pLinkBuf))
			{
				for (jj = 0; jj < linkNum; jj++)
				{
					cLinkIncTrainSum = as_GetLinkTrainList(pLinkBuf[jj], linkInctrainList, SIZE_MAX_TRAINOFAC);
					for (k = 0U; k < cLinkIncTrainSum; k++)
					{

						if (NAME_FAILUREAREA != linkInctrainList[k].u16TrainID)
						{
							; /*继续*/
						}
						else
						{
							reVal = CI_ERROR;    /*存在故障车，停止检查。返回失败*/
							break;
						}
					}
					if (CI_ERROR == reVal)
					{
						break;
					}
				}
			}
			else
			{
				/*获取失败 */
				reVal = CI_ERROR;
			}
			if (CI_ERROR == reVal)
			{
				break;
			}
		}
	}
	else
	{
		reVal = CI_ERROR;
	}
	return reVal;
}

/*
* 函数功能：ARB区段连续占用检查
* 输入参数：UINT16 wAcId 计轴区段ID
*           UINT8 cNearAcNum 相邻计轴区段数量
*           UINT16 pNearAcId[AC_MAXCNT_IN_SWITCH] 相邻计轴区段ID
* 返 回 值：CI_SUCCESS 1 成功
*           CI_ERROR 0 失败
* Created By LQ 2025.08.07
*/
UINT8 aam_ArbContinuousOccCheck(UINT16 wAcId, UINT8 cNearAcNum, UINT16 pNearAcId[AC_MAXCNT_IN_SWITCH])
{
	UINT8 cRetVal = CI_ERROR;
	UINT16 wBufIndex = 0U;
	UINT16 wCurRelPhySecId = 0U;  /*本计轴区段所属物理区段ID*/
	UINT32 dwCiAndAxleTransBadEnsureCnt = 0U;  /*判断与计轴通信中断周期数*/
	UINT32 dwCurAxleOccStartCycNum = 0U;  /*本计轴区段占用起始周期*/
	UINT8 ii = 0U;
	UINT16 wNearRelPhySecId = 0U;  /*相邻计轴区段所属物理区段ID*/
	UINT8 cAcRelEnvelopeCnt = 0U;  /*计轴区段包络数量*/
	EnvelopeStruct strEnvelopeInfo[SECTION_REL_ENVELOPE_SUM_MAX] = { 0U };
	UINT32 dwNearAxleOccStartCycNum = 0U;  /*相邻计轴区段占用起始周期*/
	UINT8 cRcId = 0U;
	UINT8 cFunRtn = 0U;
	UINT16 wNearAcIndex = 0U;
	UINT8 cPhySecPreOccState = 0U;  /*区段上周期占用状态*/
	UINT8 cAxisSecTXSafeLocFlag = 0U;  /*计轴区段列车安全位置覆盖标志*/

	wBufIndex = GetAxisSecConfigBufIndex(wAcId);  /*获取区段数组下标*/

	if ((AXIS_SECTION_SUM_MAX > wBufIndex) && (AC_MAXCNT_IN_SWITCH > cNearAcNum) && (NULL != pNearAcId))
	{		
		wCurRelPhySecId = GetAxisSecRelativePhySecId(wAcId);
		if (0U != wCurRelPhySecId)
		{
			cRetVal = CI_SUCCESS;
			dwCiAndAxleTransBadEnsureCnt = GetCiAndAxleTransBadEnsureCnt();  /*获取判断与计轴通信中断超时周期数*/
			dwCurAxleOccStartCycNum = GetSecColOccupyStartCycNum(wCurRelPhySecId);
			for (ii = 0U; ii < cNearAcNum; ii++)
			{
				wNearRelPhySecId = GetAxisSecRelativePhySecId(pNearAcId[ii]);
				if (0U != wNearRelPhySecId)
				{
					cAcRelEnvelopeCnt = elm_GetEnvelopeInAC(pNearAcId[ii], strEnvelopeInfo);  /*获取相邻计轴区段的包络信息*/
					dwNearAxleOccStartCycNum = GetSecColOccupyStartCycNum(wNearRelPhySecId);  /*获取相邻计轴区段采集占用起始周期*/
					cPhySecPreOccState = GetPhySecPreOccupyState(wNearRelPhySecId);  /*获取相邻计轴区段上周期采集占用状态*/
					cAxisSecTXSafeLocFlag =GetAxisTXSafeLocFlag(pNearAcId[ii]);  /*获取相邻计轴区段列车安全位置覆盖标志*/

					if (((0U == cAcRelEnvelopeCnt) || (SECTION_REL_ENVELOPE_SUM_MAX == cAcRelEnvelopeCnt))
						&& ((dwCurAxleOccStartCycNum + dwCiAndAxleTransBadEnsureCnt) < dwNearAxleOccStartCycNum)
						&& (SECTION_OCCUPY_NO == cPhySecPreOccState)
						&& (AXIS_SECTION_SAFELOC_YES != cAxisSecTXSafeLocFlag))
					{
						/*相邻计轴区段无包络&&占用起始时间超过了“与计轴通信中断超时判断时间”&&相邻计轴区段上周期采集为空闲&&相邻计轴区段无列车安全位置覆盖*/
						cRetVal = CI_ERROR;

						cFunRtn = aam_PrepareACIsSelf(pNearAcId[ii], &cRcId);  /*判断相邻区段是否为本控区区段*/

						if (ELM_BELONG_OWNER == cFunRtn)
						{
							wNearAcIndex = aam_PrepareACIndex(pNearAcId[ii]);
							(void)aam_ClearPassTrainFlag(wNearAcIndex);  /*清除好车通过标志*/
							(void)aam_ClearRedunTime(wNearAcIndex);  /*清除冗余计时*/
							aam_SetAxisStatus(wNearAcIndex, AAM_STATUS_OCC);  /*设置占用*/

							AAM_LOG(AAM_LOG_FATAL, "info:AC%d  Set Occ Because Of Near Sec%d Keep Arb Fail\n", pNearAcId[ii], wAcId);
						}
						else
						{
							/*非本控区区段，不处理*/
						}
					}
					else
					{
						/*继续检查*/
					}
				}
				else
				{
					cRetVal = CI_ERROR;  /*异常场景，返回失败*/
				}
			}
		}
		else
		{
			cRetVal = CI_ERROR;  /*异常场景，返回失败*/
		}
	}
	else
	{
		cRetVal = CI_ERROR;  /*入参非法，返回失败*/
	}

	return cRetVal;
}

/**
* 功能：查询计轴区段邻近范围内包络类型
*  @param[in] UINT16 ACID 基准计轴ID
 * @param[in] UINT8 dir 查询方向
 * @param[in] UINT16 arACID[AC_MAXCNT_IN_SWITCH] 相邻计轴ID
 * @param[in] UINT8 DirectionPointFlag  是否有方向变化点 DIRECTIONPOINT_FLAG_VALID
* 返回值：
		AAM_NO_TRAIN_NEAR 无车接近
		AAM_BAD_NEAR 坏车
		AAM_GOOD_OCC 好车占用
		AAM_SLEEP_OCC 休眠车
		AAM_GOOD_FAR_AWAY 好车远离
		AAM_GOOD_NEAR 好车接近
* Create:  fan 2026/04/11
*/
UINT8 aam_CheckNearbyTrainEnvelopeType(UINT16 baseACID, UINT8 Dir, UINT8 acCnt, UINT16 acID[AC_MAXCNT_IN_SWITCH], UINT8 DirectionPointFlag)
{
	UINT8 chAdjacentTrainType = AAM_BAD_NEAR;
	UINT8 chFirstStepTrainType = AAM_BAD_NEAR;
	UINT8 chSndStepTrainType = AAM_BAD_NEAR;
	UINT8 ii = 0U;
	UINT8 jj = 0U;
	UINT8 kk = 0U;
	UINT8 chRetTrainType = AAM_BAD_NEAR;
	UINT16 wTempAcList[AC_MAXCNT_IN_SWITCH] = { 0U };
	UINT8 chFirstStepAcCnt = 0U;
	UINT16 wFirstStepID[AC_MAXCNT_IN_SWITCH] = { 0U };
	UINT8 chSndStepAcCnt = 0U;
	UINT16 wSndStepID[AC_MAXCNT_IN_SWITCH] = { 0U };
	UINT32 dwArbProtectLen = 0U;/*ARB防护距离*/
	UINT16 wArbProtectDis = GetSystemParaValue(ARB_CHECK_ALXE_SEC_LEN);
	UINT32 dwCheckAcLen = 0U; /*找到计轴长度*/
	UINT32 dwTempAcLen = 0U; /*计轴长度*/
	UINT8 chChangePoitFlag = DIRECTIONPOINT_FLAG_INVALID;
	UINT8 chTemp = 0U;
	UINT8 chChangePoitCnt = 0U;
	UINT8 chFirstDir = Dir;
	UINT8 chSndDir = Dir;
	UINT8 chLocalId = 0U;/*本联锁ID*/
	UINT8 chAcBelongCi = 0U;
	UINT8 chRelEnvelopeCnt = 0u;
	UINT16 envelopeIds[SECTION_REL_ENVELOPE_SUM_MAX] = { 0u };
	EnvelopeStruct* pTempEnvelope = NULL;/*包络信息*/
	UINT8 chUseNvram = 0U;
	dwArbProtectLen = (UINT32)(wArbProtectDis * 100U);
	chLocalId = GetSystemParaLocalCiId();
	if (0U == acCnt)
	{
		/*失败返回MAX 尽头线为0*/
		chRetTrainType = AAM_NO_TRAIN_NEAR;
	}
	else if(AC_MAXCNT_IN_SWITCH >= acCnt)
	{
		for (ii = 0U; ii < acCnt; ii++)
		{
			wTempAcList[0] = acID[ii];
			dwCheckAcLen = GetAxisSecTotalLen(acID[ii]);
			chAdjacentTrainType = aam_SearchNearbyTrainType(baseACID, Dir, 1U, wTempAcList);
			chAcBelongCi = GetAxisSectionBelongCiId(acID[ii]);

			if (chAcBelongCi == chLocalId)
			{
				/*额外检查属于本联锁的直接相邻区段 无NVRAM车 */
				chRelEnvelopeCnt = elm_GetEnvelopeIDsInAC(acID[ii], envelopeIds);
				if (0u != chRelEnvelopeCnt)
				{
					for (jj = 0u; jj < chRelEnvelopeCnt; jj++)
					{
						pTempEnvelope = elm_GetEnvelopeInfoByID(envelopeIds[jj]);
						for (kk = 0u; kk < pTempEnvelope->trianCnt; kk++)
						{
							chUseNvram = GetTrainNvramPosFlag(pTempEnvelope->trainID[kk]);
							if (TRAIN_NVRAM_POS_FLAG_NO != chUseNvram)
							{
								chAdjacentTrainType = AAM_BAD_NEAR;
								break;
							}
						}
					}
				}
			}
			/** 根据列车包络数量进行处理 */
			if ((0U == ii) || (AAM_BAD_NEAR == chAdjacentTrainType))
			{
				chRetTrainType = chAdjacentTrainType;/*记录第一个结果 或更新为最坏结果*/
			}
			if ((AAM_NO_TRAIN_NEAR == chAdjacentTrainType) && (dwArbProtectLen > dwCheckAcLen))
			{
				/*路径无车 继续查找*/
				chFirstDir = TransDirectionPointDir(DirectionPointFlag, Dir, &chChangePoitCnt);
				chFirstStepAcCnt = aam_PrepareAdjacentAC(acID[ii], chFirstDir, wFirstStepID, &chChangePoitFlag);
				if (UINT8_MAX != chFirstStepAcCnt)
				{
					for (jj = 0U; jj < chFirstStepAcCnt; jj++)
					{
						wTempAcList[0] = wFirstStepID[jj];

						chFirstStepTrainType = aam_SearchNearbyTrainType(acID[ii], chFirstDir, 1U, wTempAcList);
						dwTempAcLen = GetAxisSecTotalLen(wFirstStepID[jj]);
						if ((AAM_NO_TRAIN_NEAR == chFirstStepTrainType) && (dwArbProtectLen >(dwCheckAcLen + dwTempAcLen)))
						{
							/*路径无车 继续查找*/
							chSndDir = TransDirectionPointDir(chChangePoitFlag, chFirstDir, &chChangePoitCnt);
							chSndStepAcCnt = aam_PrepareAdjacentAC(wFirstStepID[jj], chSndDir, wSndStepID, &chTemp);
							if (UINT8_MAX != chSndStepAcCnt)
							{
								for (kk = 0U; kk < chSndStepAcCnt; kk++)
								{
									wTempAcList[0] = wSndStepID[kk];
									chSndStepTrainType = aam_SearchNearbyTrainType(wFirstStepID[jj], chSndDir, 1U, wTempAcList);
									/*更新最坏结果*/
									chFirstStepTrainType = GetWorseNearbyTrainType(chFirstStepTrainType, chSndStepTrainType);
									if (AAM_BAD_NEAR == chFirstStepTrainType)
									{
										/*可以停止遍历其他计轴*/
										break;
									}
								}
							}
							else
							{
								/*异常防护*/
								chFirstStepTrainType = AAM_BAD_NEAR;
								break;
							}
						}
						else
						{
							;/*停止当前路线*/
						}
						/*更新最坏结果*/
						chAdjacentTrainType = GetWorseNearbyTrainType(chAdjacentTrainType, chFirstStepTrainType);
						if (AAM_BAD_NEAR == chAdjacentTrainType)
						{
							/*可以停止遍历其他计轴*/
							break;
						}
					}
				}
				else
				{
					/*异常防护*/
					chAdjacentTrainType = AAM_BAD_NEAR;
					break;
				}
			}
			else
			{
				;/*停止当前路线*/
			}
			/*更新最坏结果*/
			chRetTrainType = GetWorseNearbyTrainType(chRetTrainType, chAdjacentTrainType);
			if (AAM_BAD_NEAR == chRetTrainType)
			{
				/*可以停止遍历其他计轴*/
				break;
			}
		}
	}
	else
	{
		;/*返回坏车*/
	}
	return chRetTrainType;
}


/**
* 功能：更新路线上更有风险的结果
* 输入参数：UINT8 chPreType当前记录类型  UINT8 chAfterType比较的更新列车类型 
* 返回值：
AAM_NO_TRAIN_NEAR 无车接近
AAM_BAD_NEAR 坏车
AAM_GOOD_OCC 好车占用
AAM_SLEEP_OCC 休眠车
AAM_GOOD_FAR_AWAY 好车远离
AAM_GOOD_NEAR 好车接近
* Create:  fan 2026/04/11
*/
UINT8 GetWorseNearbyTrainType(UINT8 chPreType, UINT8 chAfterType)
{
	/*定义结果严重程度： 坏车接近>休眠车>好车占用>其他>无车*/
	UINT8 chRetval = AAM_BAD_NEAR;
	if ((AAM_BAD_NEAR == chPreType)||(AAM_BAD_NEAR == chAfterType))
	{
		chRetval = AAM_BAD_NEAR;
	}
	else if ((AAM_SLEEP_OCC == chPreType) || (AAM_SLEEP_OCC == chAfterType))
	{
		chRetval = AAM_SLEEP_OCC;
	}
	else if ((AAM_GOOD_OCC == chPreType) || (AAM_GOOD_OCC == chAfterType))
	{
		chRetval = AAM_GOOD_OCC;
	}
	else if(AAM_NO_TRAIN_NEAR == chPreType)
	{
		chRetval = chAfterType;
	}
	else
	{
		chRetval = chPreType;
	}
	return chRetval;
}